订单支付完善

This commit is contained in:
2022-06-06 20:32:35 +08:00
parent 52008e153f
commit a552a023f8
18 changed files with 603 additions and 40 deletions
@@ -0,0 +1,121 @@
.order_item{
background-color: #fff;
border-radius: 20px;
padding: 20px;
box-sizing: border-box;
.header{
display: flex;
align-items: center;
.user{
display: flex;
align-items: center;
.name {
color: #000;
font-weight: 700;
margin-left: 15px;
font-size: $font_size;
}
image{
width: 70px;
height: 70px;
border-radius: 50%;
}
}
.order_num {
flex: 1;
font-size: $font_size_medium;
color: $color_font_one;
text-align: right;
padding-right: 30px;
display: flex;
justify-content: flex-end;
align-items: center;
.miconfont {
font-size: 20px;
}
}
.tag{
font-size: $font_size_min;
padding: 5px 15px;
background-color: $color_main;
color: #fff;
border-radius: 0px 20px 0px 20px;
}
}
.product_title{
display: flex;
align-items: center;
padding: 35px 0;
.product_tag{
background-color: #CDE5FF;
font-size: $font_size_min;
padding: 5px 10px;
color: $color_main;
border-radius: 6px;
}
.product_name{
flex:1;
font-size: $font_size;
font-weight: 700;
padding-left: 20px;
}
.product_status{
font-size: $font_size;
color: $color_main;
}
}
.product_list{
display: flex;
.image{
width: 126px;
height: 126px;
background: #e5ad3a;
border-radius: 20px 20px 0px 0px;
position: relative;
image{
width: 100%;
height: 100%;
border-radius: 20px 20px 0px 0px;
}
.color_num {
background: rgba(0,0,0, 0.5);
border-radius: 50px 0px 0px 0px;
font-size: $font_size_min;
color: #fff;
position: absolute;
right:0;
bottom:0;
padding: 5px 10px;
box-sizing: border-box;
}
}
.color_list{
flex:1;
padding-left: 30px;
.color_item{
display: flex;
justify-content: space-between;
font-size: $font_size_min;
color: $color_font_three;
align-items: center;
margin-bottom: 20px;
.color_title{
font-weight: 700;
font-size: $font_size;
color: #000;
}
.color_more{
color: $color_font_three;
}
}
}
}
.color_count_num{
font-size: $font_size_min;
color: $color_font_two;
background-color: #F6F6F6;
border-radius: 10px;
padding: 10px 22px;
}
}
@@ -0,0 +1,106 @@
import { goLink } from "@/common/common";
import { formatHashTag, formatImgUrl, formatPriceDiv } from "@/common/fotmat";
import OrderBtns from "@/components/orderBtns";
import { useSelector } from "@/reducers/hooks";
import { Image, Text, View } from "@tarojs/components"
import classnames from "classnames";
import { memo, useCallback, useMemo, useRef, useState } from "react";
import OrderStatusTag from "../orderStatusTag";
import styles from './index.module.scss'
type Param = {
value: {
order_no: string,
sale_mode: number,
sale_mode_name: string,
status_name: string,
shipment_mode_name: string,
product_list: any[],
total_fabrics: number,
total_colors: number,
total_number: number,
status: 0,
id: number,
payment_method: number, //支付方式
actual_amount: number, //实付金额
wait_pay_amount: number //待付金额
should_collect_order_id: number //应付单id
},
onClickBtn?: (val:{status:number, orderInfo:Param['value']}) => void
}
export default memo(({value, onClickBtn}: Param) => {
const userInfo = useSelector(state => state.userInfo)
//对应数量
const formatCount = useCallback((item, sale_mode) => {
return sale_mode == 0? item.roll : Number(item.length / 100)
}, [value])
//对应单价
const standardPrice = useCallback((price, sale_mode) => {
return formatPriceDiv(price).toLocaleString() + '/' + (sale_mode == 1?'m':'kg')
}, [value])
//点击订单按钮
const orderBtnsClick = useCallback((status) => {
onClickBtn?.({status, orderInfo:value})
}, [value])
//按钮所需数据
const orderInfo = useMemo(() => {
return {
status: value?.status, //订单状态
orderId: value?.id,
actual_amount: value?.actual_amount, //实付金额
wait_pay_amount: value?.wait_pay_amount, //待付金额
}
}, [value])
return (
<View className={styles.order_item}>
<View className={styles.header} onClick={() => goLink('/pages/order/index', {id: value?.id})}>
<View className={styles.user}>
<Image src={`${userInfo?.adminUserInfo?.avatar_url}`}/>
<Text className={styles.name}>{userInfo?.adminUserInfo?.user_name}</Text>
</View>
<View className={styles.order_num}>
<Text>订单号:{value?.order_no}</Text>
<Text className={classnames(styles.miconfont, 'iconfont, icon-a-moreback')}></Text>
</View>
<OrderStatusTag/>
</View>
<View className={styles.product_con} onClick={() => goLink('/pages/order/index', {id: value?.id})}>
<View className={styles.product_title}>
<View className={styles.product_tag}>{value?.sale_mode_name}</View>
<View className={styles.product_name}>{formatHashTag(value?.product_list[0].code, value?.product_list[0].name)}</View>
<View className={styles.product_status}>{value?.status_name}</View>
</View>
<View className={styles.product_list}>
<View className={styles.image}>
<Image src={formatImgUrl(value?.product_list[0].product_colors[0].texture_url)}/>
<View className={styles.color_num}>{value?.product_list[0].product_colors[0].code}</View>
</View>
<View className={styles.color_list}>
{value?.product_list[0].product_colors.map((itemColor, index) => {
return (
(index <= 1)&&<View className={styles.color_item}>
<View className={styles.color_title}>{formatHashTag(itemColor.code, itemColor.name)}</View>
<View className={styles.color_price}>{standardPrice(itemColor.sale_price, value.sale_mode)}</View>
<View className={styles.color_num}>×{formatCount(itemColor, value.sale_mode)}条</View>
</View>
)
})
}
<View className={styles.color_item}>
<View className={styles.color_more}>……</View>
<View className={styles.color_more}>……</View>
<View className={styles.color_more}>……</View>
</View>
</View>
</View>
<View className={styles.color_count_num}>{`${value?.total_fabrics}种面料,${value?.total_colors}种颜色,共${value?.total_number}条`}</View>
</View>
<OrderBtns orderInfo={orderInfo} onClick={orderBtnsClick}/>
</View>
)
})
@@ -0,0 +1,18 @@
.order_status_list{
font-size: $font_size;
color: #9E9E9E;
margin-top: 20px;
.order_status_item{
padding: 20px;
box-sizing: border-box;
}
.selected{
font-weight: 700;
color: #000;
border-bottom: 4px solid #707070;
}
.order_list_scroll{
white-space: nowrap;
display: flex;
}
}
@@ -0,0 +1,46 @@
import { ScrollView, View } from "@tarojs/components"
import { memo, useEffect, useState } from "react"
import styles from './index.module.scss'
import classnames from "classnames";
type Param = {
list: {id: number, name: string}[],
defaultId?: number|null,
onSelect?: (val: number) => void
}
export default memo(({list = [], defaultId = null, onSelect}: Param) => {
const [selectInfo, setSelectInfo] = useState({
selected: -1, //当前选中的id
tabId: '', //需要滚动到的id
})
useEffect(() => {
if(defaultId) {
const index = list?.findIndex(item => {
console.log(item.id, defaultId)
return item.id == defaultId
})
if(index !== -1) {
const num = index > 0?( index - 1) : 0
setSelectInfo((e) => ({...e, tabId:list[num].id.toString()}))
}
}
}, [defaultId])
const clickEvent = ({item, index}: {item:any, index:number}) => {
const num = index > 0?( index - 1) : 0
setSelectInfo((e) => ({...e, tabId:list[num].id.toString(), selected: item.id}))
onSelect?.(item.id)
}
return (
<View className={styles.order_status_list}>
<ScrollView scrollX scrollIntoView={`tabs_${selectInfo.tabId}`} scrollWithAnimation={true}>
<View className={styles.order_list_scroll}>
{list.map((item, index) => {
return <View key={item.id} id={`tabs_${item.id}`} onClick={() => clickEvent({item, index})} className={classnames(styles.order_status_item, (selectInfo.selected==item.id)&&styles.selected)}>{item.name}</View>
})}
</View>
</ScrollView>
</View>
)
})
@@ -0,0 +1,21 @@
.tag{
font-size: $font_size_min;
padding: 5px 15px;
background-color: $color_main;
color: #fff;
border-radius: 0px 20px 0px 20px;
display: flex;
align-items: center;
.miconfont{
font-size: 30px;
}
}
.saleReturn_tag{
background-color: #FFE6CE;
color: #EE7500;
}
.priceReturn_tag {
background-color: #E4E4FF;
color: #1818B4;
}
@@ -0,0 +1,20 @@
import { Text, View } from "@tarojs/components"
import { memo } from "react"
import classnames from "classnames";
import styles from './index.module.scss'
type Param = {
status: ''
}
export default memo(({status}:Param) => {
status
return (
<>
<View className={classnames(styles.tag, styles.saleReturn_tag)}>
<View className={classnames(styles.miconfont, 'iconfont, icon-yucunkuan')}></View>
<Text>退货</Text>
</View>
</>
)
})
+4
View File
@@ -0,0 +1,4 @@
export default {
navigationBarTitleText: '退货/售后',
enableShareAppMessage: true,
}
@@ -0,0 +1,38 @@
.order_list_main{
height: 100vh;
background-color: $color_bg_one;
display: flex;
flex-direction: column;
.title{
padding: 0 20px;
background-color: #fff;
box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.16);
border-bottom: 2px solid #e2e2e2;
height: 160px;
.order_status_list{
font-size: $font_size;
color: #9E9E9E;
margin-top: 20px;
.order_status_item{
padding: 20px;
box-sizing: border-box;
}
.selected{
font-weight: 700;
color: #000;
border-bottom: 4px solid #707070;
}
.order_list_scroll{
white-space: nowrap;
display: flex;
}
}
}
.order_list{
height: calc(100vh - 160px);
.order_item_con{
margin-top: 20px;
padding: 0 20px;
}
}
}
+139
View File
@@ -0,0 +1,139 @@
import Search from "@/components/search"
import useLogin from "@/use/useLogin"
import { Image, ScrollView, Text, View } from "@tarojs/components"
import Taro, { useDidShow, usePullDownRefresh, useRouter } from "@tarojs/taro"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import styles from './index.module.scss'
import classnames from "classnames";
import Order from "./components/order"
import InfiniteScroll from "@/components/infiniteScroll"
import {GetOrderStatusListApi, GetOrderListApi} from '@/api/order'
import { dataLoadingStatus, getFilterData } from "@/common/util"
import OrderStatusList from "./components/orderStatusList"
import Payment from "../order/components/payment"
import { AFTER_ORDER_STATUS } from "@/common/enum"
export default () => {
const {checkLogin} = useLogin()
useDidShow(async () => {
await checkLogin()
})
//搜索参数
const [searchField, setSearchField] = useState({
status: -1,
page : 1,
size : 10,
Name:''
})
//获取订单状态
const [statusList, setStatusList] = useState<any[]>([{id: -1, name: '全部'}])
const getOrderStatusList = () => {
const status = Object.values(AFTER_ORDER_STATUS).map(item => {
return {id: item.value, name: item.label}
})
setStatusList((e) => [...e, ...status])
}
useEffect(() => {
getOrderStatusList()
}, [])
//获取订单列表
const {fetchData: listFetchData, state:orderState} = GetOrderListApi()
const [orderData, setOrderData] = useState<{list:any[], total:number}>({list:[], total:0})
const getOrderList = async () => {
let res = await listFetchData(getFilterData(searchField))
setOrderData({list: res.data.list, total: res.data.total})
setRefresherTriggeredStatus(() => false)
}
//监听筛选条件变化
useEffect(() => {
getOrderList()
}, [searchField])
//上拉加载数据
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 changeStatus = useCallback((e) => {
pageNum.current.page = 1
setSearchField((value) => ({...value, status:e, size:10}))
setOrderData(() => ({list:[], total:0}))
}, [])
//数据加载状态
const statusMore = useMemo(() => {
return dataLoadingStatus({list:orderData.list, total: orderData.total, status: orderState.loading})
}, [orderData, orderState])
//输入了搜索关键字
const getSearchData = useCallback((e) => {
pageNum.current.page = 1
setOrderData(() => ({list:[], total:0}))
setSearchField((val) => ({...val, name:e, size:10}))
}, [])
//列表下拉刷新
const [refresherTriggeredStatus, setRefresherTriggeredStatus] = useState(false)
const getRefresherRefresh = async () => {
pageNum.current.size = 1
setRefresherTriggeredStatus(true)
setSearchField((val) => ({...val, size:10}))
}
//监听点击的按钮
const clickOrderBtn = useCallback(({status, orderInfo}) => {
if(status == 2) {
//去支付
setPayOrderInfo({orderId:orderInfo.should_collect_order_id, payment_method:orderInfo.payment_method})
toPay()
}
}, [orderData])
//去付款
const [payOrderInfo, setPayOrderInfo] = useState<any>()
const [payMentShow, setPayMentShow] = useState(false)
const toPay = () => {
setPayMentShow(true)
}
//关闭支付弹窗
const closePayShow = useCallback(() => {
setPayMentShow(() => false)
}, [])
//支付成功
const onPaySuccess = useCallback(() => {
getOrderList()
closePayShow()
}, [])
return (
<View className={styles.order_list_main}>
<View className={styles.title}>
<Search placeIcon="out" placeholder="搜索商品/名称/颜色/订单号" showBtn={true} changeOnSearch={getSearchData} debounceTime={300}/>
<OrderStatusList list={statusList} onSelect={changeStatus} defaultId={1}/>
</View>
<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}> <Order value={item} onClickBtn={clickOrderBtn}/></View>
})}
</InfiniteScroll>
</View>
<Payment onSubmitSuccess={onPaySuccess} show={payMentShow} onClose={closePayShow} orderInfo={payOrderInfo}/>
</View>
)
}