🦄 refactor(订单重构):订单重构

This commit is contained in:
Haiyi 2022-09-01 14:14:18 +08:00
parent b5bd2e1b21
commit 34dd4722c9
8 changed files with 13780 additions and 206 deletions

View File

@ -4,4 +4,26 @@ export const mpenumsaleorderstatus = () => {
url: `/v1/mp/enum/sale/order/status`, url: `/v1/mp/enum/sale/order/status`,
method: "get", method: "get",
}) })
}
/**
*
* @returns
*/
export const OrderListApi = () => {
return useRequest({
url: `/v1/mp/saleOrder/list`,
method: "get",
})
}
/**
*
* @returns
*/
export const ClientListApi = () => {
return useRequest({
url: `/v1/mp/purchaser/list`,
method: "get"
})
} }

View File

@ -3,21 +3,22 @@ import styles from "./index.module.scss"
import CloseBtn from "@/components/closeBtn" import CloseBtn from "@/components/closeBtn"
import classnames from "classnames"; import classnames from "classnames";
import { debounce } from "@/common/util"; import { debounce } from "@/common/util";
import { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from "react"; import { Children, forwardRef, memo, ReactElement, ReactNode, useEffect, useImperativeHandle, useRef, useState } from "react";
type Params = { type Params = {
clickOnSearch?: (val: string) => void clickOnSearch?: (val: string) => void
disabled?: false|true, disabled?: false | true,
placeholder?: string, placeholder?: string,
changeOnSearch?:(any) => void, changeOnSearch?: (any) => void,
showIcon?: false|true, showIcon?: false | true,
placeIcon?: 'out'|'inner', placeIcon?: 'out' | 'inner',
style?: Object, style?: Object,
showBtn?: false|true, showBtn?: false | true,
btnStyle?: Object, btnStyle?: Object,
btnTitle?: string, btnTitle?: string,
debounceTime?: number //防抖时间,不设默认为零 debounceTime?: number //防抖时间,不设默认为零
defaultValue?: string defaultValue?: string,
children?: ReactNode
} }
export default memo(forwardRef(({ export default memo(forwardRef(({
@ -27,13 +28,14 @@ export default memo(forwardRef(({
placeholder = '输入搜索内容', placeholder = '输入搜索内容',
showIcon = true, //是否显示关闭图标 showIcon = true, //是否显示关闭图标
showBtn = false, //是否显示搜索按钮 showBtn = false, //是否显示搜索按钮
btnStyle = {}, btnStyle = {},
placeIcon = 'inner', //搜索图标位置inner在里面out在外面 placeIcon = 'inner', //搜索图标位置inner在里面out在外面
btnTitle = '搜索', //搜索文字 btnTitle = '搜索', //搜索文字
debounceTime = 0, //防抖时间,不设默认为零 debounceTime = 0, //防抖时间,不设默认为零
defaultValue = '' //默认值 defaultValue = '',//默认值
}:Params, ref) => { children
const [inputCon , setInputCon] = useState('') }: Params, ref) => {
const [inputCon, setInputCon] = useState('')
const debounceTimeRef = useRef(0) const debounceTimeRef = useRef(0)
useEffect(() => { useEffect(() => {
setInputCon(defaultValue) setInputCon(defaultValue)
@ -68,15 +70,16 @@ export default memo(forwardRef(({
return ( return (
<> <>
<View className={styles.search_main} > <View className={styles.search_main}>
<View className={styles.search_con}> <View className={styles.search_con}>
{showIcon&&<View className={classnames('iconfont', 'icon-sousuo', styles.icon_a_sousuo1_self, placeIcon=='inner'?styles.icon_inner:styles.icon_out)}></View>} {showIcon && <View className={classnames('iconfont', 'icon-a-sousuo1', styles.icon_a_sousuo1_self, placeIcon == 'inner' ? styles.icon_inner : styles.icon_out)}></View>}
<Input placeholderStyle='color:#ABABAB; font-size:26rpx' onConfirm={onSearch} className={classnames(placeIcon=='out'&&styles.input_out)} disabled={disabled} value={inputCon} placeholder={placeholder} onInput={(e) => onInputEven(e)}></Input> <Input placeholderStyle='color:#ABABAB; font-size:26rpx' onConfirm={onSearch} className={classnames(placeIcon == 'out' && styles.input_out)} disabled={disabled} value={inputCon} placeholder={placeholder} onInput={(e) => onInputEven(e)}></Input>
{!!inputCon&&<View className={styles.search_closeBtn}> {!!inputCon && <View className={styles.search_closeBtn}>
<CloseBtn onClose={() => clearInput()} styleObj={{width: '20rpx', height:'20rpx', backgroundColor:'#fff', border:'0'}}/> <CloseBtn onClose={() => clearInput()} styleObj={{ width: '20rpx', height: '20rpx', backgroundColor: '#fff', border: '0' }} />
</View>} </View>}
</View> </View>
{showBtn&&<View style={btnStyle} className={styles.btn} onClick = {onSearch}>{btnTitle}</View>} {showBtn && <View style={btnStyle} className={styles.btn} onClick={onSearch}>{btnTitle}</View>}
{children}
</View> </View>
</> </>
) )

View File

@ -1,6 +1,6 @@
.order_status_list{ .order_status_list{
font-size: $font_size; font-size: $font_size;
color: #9E9E9E; color: #000;
margin-top: 20px; margin-top: 20px;
.order_status_item{ .order_status_item{
padding: 20px; padding: 20px;
@ -8,8 +8,8 @@
} }
.selected{ .selected{
font-weight: 700; font-weight: 700;
color: #000; color: #337FFF;
border-bottom: 4px solid #707070; border-bottom: 4px solid #337FFF;
} }
.order_list_scroll{ .order_list_scroll{
white-space: nowrap; white-space: nowrap;

View File

@ -0,0 +1,129 @@
.flexBox {
display: flex;
width: 200px;
align-items: center;
justify-content: flex-end;
}
.icon_shaixuan {
color: #000;
font-size: 35px;
margin-right: 10px;
}
.shaixuan {
margin-right: 32px;
font-size: 28px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #000000;
}
.popupBox {
.topBox {
display: flex;
padding-left: 48px;
.leftTop {
.lefttopTitle {
font-size: 28px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
margin-bottom: 24px;
}
.lefttopSelectBox {
display: flex;
align-items: center;
width: 319px;
height: 68px;
background: #E9E9E9;
border-radius: 8px;
opacity: 0.4;
justify-content: space-between;
margin-right: 16px;
.lefttopSelectName {
font-size: 28px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #000000;
margin-left: 24px;
}
.icon_more {
margin-right: 24px;
font-size: 30px;
}
}
}
}
}
.popupTwobox {
padding-left: 40px;
padding-right: 40px;
.scrollview {
height: 400px;
.btnBox {
margin-top: 40px;
display: flex;
flex-wrap: wrap;
.itemBox {
width: 213px;
height: 80px;
background: #f5f5f5;
border-radius: 8px;
font-size: 28px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #000;
line-height: 80px;
text-align: center;
margin-right: 16px;
box-sizing: border-box;
margin-bottom: 16px;
flex-shrink: 0;
}
.activeitemBox {
border-radius: 8px;
flex-shrink: 0;
font-family: PingFangSC-Regular, PingFang SC;
line-height: 80px;
text-align: center;
width: 213px;
height: 80px;
font-size: 28px;
color: #337FFF;
margin-right: 16px;
background: #e8effd;
border: 1px solid #337FFF;
margin-bottom: 16px;
box-sizing: border-box;
}
.activeitemBox:nth-child(3n-0) {
margin-right: 0px;
}
.itemBox:nth-child(3n-0) {
margin-right: 0px;
}
}
}
}
.order_list {
height: calc(100vh - 160px);
.bigBpx {
height: 200px;
}
}

View File

@ -1,48 +1,215 @@
// import { View } from '@tarojs/components' import { View, ScrollView } from '@tarojs/components'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useCallback, useEffect, useMemo, useRef, useState, } from 'react'
// import { mpenumsaleorderstatus } from '@/api/order' import { mpenumsaleorderstatus, OrderListApi, ClientListApi } from '@/api/order'
// import OrderStatusList from './components/orderStatusList' import OrderStatusList from './components/orderStatusList'
import Search from '@/components/search'
// //页码和页数 import { dataLoadingStatus, getFilterData } from '@/common/util'
// const [searchField, setSearchField] = useState<{ status: number | unknown; page: number; size: number; name: string }>({ import styles from "./index.module.scss"
// status: null, import classnames from "classnames";
// page: 1, import Popup from '@/components/popup'
// size: 10, import InfiniteScroll from '@/components/infiniteScroll'
// name: '', import { compose } from 'redux'
// })
// const pageNum = useRef({ size: searchField.size, page: searchField.page })
// //获取订单状态
// const { fetchData: orderStatusListFetchData } = mpenumsaleorderstatus()
const [statusList, setStatusList] = useState<any[]>([{ id: -1, name: '全部' }])
// const getOrderStatusList = async () => {
// let res = await orderStatusListFetchData()
// setStatusList((e) => [...e, ...res.data.list])
// }
// //状态改变
// const changeStatus = useCallback((e) => {
// pageNum.current.page = 1
// setSearchField((value) => ({ ...value, status: e, size: 10 }))
// // setOrderData(() => ({ list: [], total: 0 }))
// }, [])
// useEffect(() => {
// getOrderStatusList()
// }, [])
// export default () => {
// return (
// <View>
// {/* <OrderStatusList list={statusList} onSelect={changeStatus} defaultId={-1} /> */}
// 22
// </View>
// )
// }
export default () => { export default () => {
return (<>222</>) //页码和页数
} const [searchField, setSearchField] = useState<{ status: number | unknown; page: number; size: number; name: string }>({
status: -1,
page: 1,
size: 10,
name: '',
})
//获取订单列表
const { fetchData: listFetchData, state: orderState } = OrderListApi()
const [orderData, setOrderData] = useState<{ list: any[]; total: number }>({ list: [], total: 0 })
const getOrderList = async () => {
let res = await listFetchData(getFilterData(searchField))
setOrderData((e) => ({ ...e, list: res.data?.list, total: res.data?.total }))
setRefresherTriggeredStatus(() => false)
}
//列表下拉刷新
const [refresherTriggeredStatus, setRefresherTriggeredStatus] = useState(false)
const getRefresherRefresh = async () => {
pageNum.current.size = 1
setRefresherTriggeredStatus(true)
setSearchField((val) => ({ ...val, size: 10 }))
}
//数据加载状态
const statusMore = useMemo(() => {
console.log({ list: orderData.list, total: orderData.total, status: orderState.loading }, '{ list: orderData.list, total: orderData.total, status: orderState.loading }')
return dataLoadingStatus({ list: orderData.list, total: orderData.total, status: orderState.loading })
}, [orderData, orderState])
//上拉加载数据
const pageNum = useRef({ size: searchField.size, page: searchField.page })
const getScrolltolower = useCallback(() => {
if (orderData.list.length < orderData.total) {
pageNum.current.page++
const size = pageNum.current.size * pageNum.current.page
setSearchField({ ...searchField, size })
}
}, [orderData])
// //获取订单状态
const { fetchData: orderStatusListFetchData } = mpenumsaleorderstatus()
const [statusList, setStatusList] = useState<any[]>([{ id: -1, name: '全部' }])
const getOrderStatusList = async () => {
let res = await orderStatusListFetchData()
setStatusList((e) => [...e, ...res.data.list])
}
//监听筛选条件变化
useEffect(() => {
if (searchField.status != null) getOrderList()
}, [searchField])
// //状态改变
const changeStatus = useCallback((e) => {
pageNum.current.page = 1
setSearchField((value) => ({ ...value, status: e, size: 10 }))
console.log(e, '123123')
setOrderData(() => ({ list: [], total: 0 }))
}, [])
//输入了搜索关键字
const getSearchData = useCallback((e) => {
pageNum.current.page = 1
setOrderData(() => ({ list: [], total: 0 }))
setSearchField((val) => ({ ...val, name: e, size: 10 }))
}, [])
//筛选内容展示
const [showPopup, setshowPopup] = useState(false)
const showSelctPopup = () => {
setshowPopup(true)
}
//关闭筛选内容展示
const closePopup = () => {
setshowPopup(false)
}
//客户筛选内容展示
const [choseTitle, setChoseTitle] = useState('客户')
const [showPopupTwo, setshowPopupTwo] = useState(false)
const showPopupDesige = (index) => {
if (index === 1) {
setChoseTitle('客户')
} else {
setChoseTitle('业务员')
}
setshowPopupTwo(true)
}
//客户关闭筛选内容展示
const closePopupTwo = () => {
setshowPopupTwo(false)
}
//获取客户或者业务员数据
const { fetchData: purchaserFetch } = ClientListApi()
const [itemList, setItemList] = useState<any[]>([{ id: -100, name: '不限' }])
const getPurchaser = async () => {
let res = await purchaserFetch()
res.data.list.map(item => {
if (item.id === -100) {
item.checked = true
} else {
item.checked = false
return item
}
})
setItemList((e) => [...e, ...res.data.list])
}
//选择客户或者业务员
const choseUser = (it, index) => {
itemList.map(item => {
if (item.id === it.id) {
item.checked = true
} else {
item.checked = false
return item
}
})
setItemList(() => [...itemList])
console.log(itemList, 123)
}
//搜索客户或者业务员
const getSearchDataPurchaser = useCallback(async (e) => {
getPurchaser()
// let res = await purchaserFetch({ name: e })
// setItemList((e) => [...e, ...res.data.list])
}, [])
useEffect(() => {
getOrderStatusList()
getPurchaser()
}, [])
return (
<View>
<Search placeholder='搜索商品/名称/颜色/订单号' showBtn={false} changeOnSearch={getSearchData} debounceTime={300} >
<View className={styles.flexBox} onClick={() => showSelctPopup()}>
<View className={classnames('iconfont', 'icon-shaixuan', styles.icon_shaixuan)}></View>
<View className={styles.shaixuan}></View>
</View>
</Search>
<OrderStatusList list={statusList} onSelect={changeStatus} defaultId={-1} />
<View className={styles.order_list}>
<InfiniteScroll
statusMore={statusMore}
selfonScrollToLower={getScrolltolower}
refresherEnabled={true}
refresherTriggered={refresherTriggeredStatus}
selfOnRefresherRefresh={getRefresherRefresh}>
{orderData?.list?.map((item) => {
return (
<View key={item.id} className={styles.order_item_con}>
<View className={styles.bigBpx}>2222</View>
{/* <Order value={item} onClickBtn={clickOrderBtn} /> */}
</View>
)
})}
</InfiniteScroll>
</View>
<Popup title={'筛选订单'} show={showPopup} onClose={() => closePopup()}>
<View className={styles.popupBox}>
<View className={styles.topBox}>
<View className={styles.leftTop} onClick={() => showPopupDesige(1)}>
<View className={styles.lefttopTitle}></View>
<View className={styles.lefttopSelectBox}>
<View className={styles.lefttopSelectName}></View>
<View className={classnames('iconfont', 'icon-more', styles.icon_more)}></View>
</View>
</View>
<View className={styles.leftTop} onClick={() => showPopupDesige(2)}>
<View className={styles.lefttopTitle}></View>
<View className={styles.lefttopSelectBox}>
<View className={styles.lefttopSelectName}></View>
<View className={classnames('iconfont', 'icon-more', styles.icon_more)}></View>
</View>
</View>
</View>
</View>
</Popup>
<Popup title={choseTitle} show={showPopupTwo} onClose={() => closePopupTwo()}>
<View className={styles.popupTwobox}>
<Search placeholder={`请输入${choseTitle}名称`} showBtn={false} changeOnSearch={getSearchDataPurchaser} debounceTime={300} >
</Search>
<ScrollView
className={styles.scrollview}
scroll-y={true}
showScrollbar={false}
enhanced={true}
>
<View className={styles.btnBox}>
{itemList.map((item, index) => <View className={classnames(item.checked ? styles.activeitemBox : styles.itemBox)} key={index} onClick={() => choseUser(item, index)}>{item.name}</View>)}
</View>
</ScrollView>
</View>
</Popup>
</View>
)
}

View File

@ -1,6 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 2987621 */ font-family: "iconfont";
src: url('iconfont.ttf?t=1658997423433') format('truetype'); /* Project id 2987621 */
src: url('iconfont.ttf?t=1661926630273') format('truetype');
} }
.iconfont { .iconfont {
@ -11,100 +13,24 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-wodekefu:before { .icon-A:before {
content: "\e67a"; content: "\e6ea";
} }
.icon-yaoqingma:before { .icon-erweima:before {
content: "\e679"; content: "\e7b5";
}
.icon-gengduo:before {
content: "\e677";
}
.icon-shanchu-2:before {
content: "\e678";
}
.icon-shangchuanzhaopian:before {
content: "\e676";
}
.icon-zuzhiziliao:before {
content: "\e66e";
}
.icon-rili:before {
content: "\e66f";
}
.icon-yishoucang:before {
content: "\e670";
}
.icon-tongguorenzheng:before {
content: "\e671";
}
.icon-gerenziliao:before {
content: "\e672";
}
.icon-shuaxin:before {
content: "\e673";
}
.icon-piliangguanli:before {
content: "\e674";
}
.icon-xinzeng:before {
content: "\e675";
}
.icon-yucunkuan:before {
content: "\e66c";
}
.icon-xianxiahuikuan:before {
content: "\e669";
} }
.icon-xtianzhangqi:before { .icon-xtianzhangqi:before {
content: "\e66a"; content: "\e66a";
} }
.icon-saomazhifu:before { .icon-yucunkuan:before {
content: "\e66b"; content: "\e66c";
} }
.icon-fahuo:before { .icon-a-tuikuanshouhou:before {
content: "\e66d"; content: "\e65c";
}
.icon-zhuyi:before {
content: "\e668";
}
.icon-zhushi:before {
content: "\e667";
}
.icon-zidingyimadan:before {
content: "\e665";
}
.icon-a-yuanmadanmadanguanli:before {
content: "\e666";
}
.icon-daohang:before {
content: "\e664";
}
.icon-shanchu:before {
content: "\e663";
} }
.icon-yifahuo:before { .icon-yifahuo:before {
@ -115,111 +41,194 @@
content: "\e662"; content: "\e662";
} }
.icon-yaoqingtuandui:before { .icon-guanbi:before {
content: "\e65a"; content: "\e641";
} }
.icon-a-tuikuanshouhou:before { .icon-a-saoyisao2:before {
content: "\e65c"; content: "\e613";
} }
.icon-daifukuan:before { .icon-guanyuquse:before {
content: "\e65d"; content: "\e635";
} }
.icon-shezhi:before { .icon-yangpinduibi:before {
content: "\e65e"; content: "\e631";
} }
.icon-yanseduibi:before { .icon-lingquseka:before {
content: "\e65f"; content: "\e632";
} }
.icon-daifahuo:before { .icon-sehaochazhao:before {
content: "\e660"; content: "\e633";
} }
.icon-baoguo:before { .icon-jichuguanli:before {
content: "\e661"; content: "\e634";
} }
.icon-tick-pressed:before { .icon-yuncangkucun:before {
content: "\e652"; content: "\e630";
} }
.icon-wode-pressed:before { .icon-shangchuanzhaopian:before {
content: "\e655"; content: "\e62f";
} }
.icon-fenlei-pressed:before { .icon-zhushi:before {
content: "\e656"; content: "\e62d";
} }
.icon-sousuo:before { .icon-shenqingtuihuo:before {
content: "\e647"; content: "\e62e";
} }
.icon-fenxiang:before { .icon-quxiaodingdanxiao:before {
content: "\e648"; content: "\e62c";
}
.icon-tuihuo1:before {
content: "\e62a";
}
.icon-a-fenqishangchengyifahuo:before {
content: "\e62b";
}
.icon-peibu:before {
content: "\e626";
}
.icon-dingdanbishu:before {
content: "\e627";
}
.icon-guanyufahuo:before {
content: "\e628";
}
.icon-tuihuo:before {
content: "\e629";
}
.icon-rili:before {
content: "\e625";
}
.icon-jiangpai:before {
content: "\e624";
}
.icon-xiaoshou:before {
content: "\e623";
}
.icon-cangkuguanli:before {
content: "\e61f";
}
.icon-zhibiaoduizhang:before {
content: "\e620";
}
.icon-a-tongji1:before {
content: "\e621";
} }
.icon-shaixuan:before { .icon-shaixuan:before {
content: "\e649"; content: "\e622";
} }
.icon-gouwuche:before { .icon-xiangxiagengduo:before {
content: "\e64a"; content: "\e61e";
} }
.icon-qingkong:before { .icon-gongnengdingyi:before {
content: "\e64c"; content: "\e61a";
} }
.icon-jia:before { .icon-rukuguanli:before {
content: "\e64d"; content: "\e61b";
}
.icon-shenqing:before {
content: "\e61c";
}
.icon-kehuguanli:before {
content: "\e61d";
}
.icon-a-phone1:before {
content: "\e619";
}
.icon-a-saoyisao2:before {
content: "\e613";
}
.icon-ico_zhongyaofangguanli_zhongyaopandian:before {
content: "\e615";
}
.icon-seka:before {
content: "\e616";
}
.icon-xiaoshoutongji:before {
content: "\e617";
}
.icon-gengduo:before {
content: "\e618";
}
.icon-lajitong:before {
content: "\e60c";
} }
.icon-jian:before { .icon-jian:before {
content: "\e64e"; content: "\e60b";
} }
.icon-shoucang-pressed:before { .icon-jia:before {
content: "\e64f"; content: "\e60a";
} }
.icon-shoucang:before { .icon-a-tick1:before {
content: "\e650"; content: "\e609";
} }
.icon-phone:before { .icon-a-cuowuwrong:before {
content: "\e651"; content: "\e608";
} }
.icon-tick:before { .icon-more:before {
content: "\e653"; content: "\e606";
}
.icon-a-moreback:before {
content: "\e654";
}
.icon-fenlei:before {
content: "\e657";
} }
.icon-bianji:before { .icon-bianji:before {
content: "\e658"; content: "\e607";
} }
.icon-wode:before { .icon-wode:before {
content: "\e659"; content: "\e602";
} }
.icon-sort-up-full:before { .icon-shangpinguanli:before {
content: "\ea4c"; content: "\e603";
} }
.icon-sort-down-full:before { .icon-dingdan:before {
content: "\ea4d"; content: "\e604";
} }
.icon-fenlei:before {
content: "\e605";
}
.icon-a-sousuo1:before {
content: "\e601";
}

Binary file not shown.

13244
yarn.lock Normal file

File diff suppressed because it is too large Load Diff