This commit is contained in:
li tong bao 2022-06-23 16:59:10 +08:00
commit 5f9a72e20e
83 changed files with 3305 additions and 889 deletions

View File

@ -55,3 +55,14 @@ export const GetLabProductApi = () => {
method: "get", method: "get",
}) })
} }
/**
*
* @returns
*/
// export const GetProductDetailApi = () => {
// return useRequest({
// url: `/v1/mall/product`,
// method: "get",
// })
// }

View File

@ -0,0 +1,62 @@
import { useRequest } from "@/use/useHttp"
/**
*
*/
export const GetSaleOrderListApi = () => {
return useRequest({
url: `/v1/mall/returnApplyOrder/list`,
method: "get",
})
}
/**
*
*/
export const ReturnApplyOrderApi = () => {
return useRequest({
url: `/v1/mall/returnApplyOrder`,
method: "post",
})
}
/**
* 退
*/
export const ReturnApplyOrderCancelApi = () => {
return useRequest({
url: `/v1/mall/returnApplyOrder/cancel`,
method: "post",
})
}
/**
*
*/
export const SaleOrderOrderDetailApi = () => {
return useRequest({
url: `/v1/mall/returnApplyOrder`,
method: "get",
})
}
/**
*
*/
export const ReturnApplyLogisticsApi = () => {
return useRequest({
url: `/v1/mall/returnApplyOrder/upload`,
method: "put",
})
}
/**
*
*/
export const ReturnGoodsStatusApi = () => {
return useRequest({
url: `/v1/mall/enum/return/goodsStatus`,
method: "get",
})
}

View File

@ -32,3 +32,14 @@ export const DelShoppingCartApi = () => {
method: "delete", method: "delete",
}) })
} }
/**
*
* @returns
*/
export const UpdateShoppingCartApi = () => {
return useRequest({
url: `/v1/mall/shoppingCart/productColor`,
method: "put",
})
}

View File

@ -60,3 +60,12 @@ import { useRequest } from "@/use/useHttp"
}) })
} }
/**
*
*/
export const BindingCompanyApi = () => {
return useRequest({
url: `/v1/mall/user/binding/company`,
method: "put",
})
}

View File

@ -171,6 +171,12 @@ export default {
pages: [ pages: [
"index", "index",
] ]
},
{
root: "pages/collection",
pages: [
"index",
]
} }
] ]
} }

View File

@ -5,13 +5,13 @@
// export const BASE_URL = `http://192.168.0.89:40001/lymarket` // export const BASE_URL = `http://192.168.0.89:40001/lymarket`
// export const BASE_URL = `http://192.168.1.165:40001/lymarket` // 王霞 // export const BASE_URL = `http://192.168.1.165:40001/lymarket` // 王霞
// export const BASE_URL = `https://test.zzfzyc.com/lymarket` // 测试环境 // export const BASE_URL = `https://test.zzfzyc.com/lymarket` // 测试环境
export const BASE_URL = `http://192.168.1.30:40001/lymarket` // 发 // export const BASE_URL = `http://192.168.1.30:40001/lymarket` // 发
// export const BASE_URL = `http://192.168.1.30:50001/lymarket` // 发 // export const BASE_URL = `http://192.168.1.30:50001/lymarket` // 发
// export const BASE_URL = `https://dev.zzfzyc.com/lymarket` // 开发环境 // export const BASE_URL = `https://dev.zzfzyc.com/lymarket` // 开发环境
// export const BASE_URL = `https://www.zzfzyc.com/lymarket` // 正式环境 // export const BASE_URL = `https://www.zzfzyc.com/lymarket` // 正式环境
// export const BASE_URL = `http://192.168.1.5:40001/lymarket` // 王霞 // export const BASE_URL = `http://192.168.1.5:40001/lymarket` // 王霞
// export const BASE_URL = `http://192.168.1.224:50001/lymarket` // 添 // export const BASE_URL = `http://192.168.1.224:50002/lymarket` // 添
// export const BASE_URL = `http://192.168.1.15:50001/lymarket` // 杰 export const BASE_URL = `http://192.168.1.15:50001/lymarket` // 杰
// CDN // CDN
// 生成密钥 // 生成密钥
@ -21,8 +21,6 @@ export const UPLOAD_CDN_URL = `https://v0.api.upyun.com/`
// cdn // cdn
export const IMG_CND_Prefix = CURRENT_ENV.includes('development')? "https://test.cdn.zzfzyc.com":"https://cdn.zzfzyc.com" export const IMG_CND_Prefix = CURRENT_ENV.includes('development')? "https://test.cdn.zzfzyc.com":"https://cdn.zzfzyc.com"
// 上传图片视频 // 上传图片视频
export const CDN_UPLOAD_IMG = `${UPLOAD_CDN_URL || ''}`; export const CDN_UPLOAD_IMG = `${UPLOAD_CDN_URL || ''}`;

View File

@ -0,0 +1,202 @@
import { CancelOrderApi, ReceiveOrderApi } from "@/api/order"
import { alert } from "@/common/common"
import { ORDER_STATUS, SALE_MODE } from "@/common/enum"
import { ScrollView, Text, View } from "@tarojs/components"
import Taro from "@tarojs/taro"
import { useCallback, useRef, memo, useState, useEffect, useMemo } from "react"
import styles from './index.module.scss'
type Param = {
orderInfo: {
status: number, //订单状态
orderId: number, //订单id
actual_amount: number, //实付金额
wait_pay_amount: number, //待付金额
sale_mode: number //订单类型
}|null,
onClick?: (val: number) => void //点击后触发的事件,返回订单状态
}
export default memo(({orderInfo, onClick}:Param) => {
//订单状态枚举
const {
SaleOrderStatusBooking,
SaleOrderStatusArranging,
SaleOrderStatusArranged,
SaleOrderStatusWaitingDelivery,
SaleOrderStatusComplete,
SaleOrderStatusRefund,
SaleOrderStatusWaitingPayment,
SaleOrderStatusWaitingReceipt,
SaleOrderStatusAlreadyReceipt,
SaleorderstatusWaitingPrePayment
} = ORDER_STATUS
//订单类型
const {
SaLeModeBulk,
SaleModeLengthCut,
SaLeModeWeightCut,
} = SALE_MODE
//订单按钮按订单状态归类, value是该订单状态可能该按钮会出现
const orderBtnsList = useRef([
{
id: 1,
value: [SaleOrderStatusBooking.value,
SaleOrderStatusArranging.value,
SaleOrderStatusArranged.value,
SaleOrderStatusWaitingPayment.value,
SaleOrderStatusWaitingDelivery.value], //取消订单按钮对应: 待接单,配布中,已配布, 待付款, 待发货
label: '取消订单'
},
{
id: 2,
value: [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value], //去付款按钮对应:待付款, 待发货, 待收货, 已收货, 已完成
label: '去付款'
},
{
id: 3,
value: [SaleOrderStatusWaitingDelivery.value], //申请退款按钮对应: 待发货
label: '申请退款'
},
{
id: 4,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value], //取消订单按钮对应: 待收货, 已收货, 已完成, 已退款
label: '查看物流'
},
{
id: 5,
value: [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusRefund.value], //申请退货按钮对应: 待收货, 已收货, 已退款
label: '申请退货'
},
{
id: 6,
value: [SaleOrderStatusWaitingReceipt.value], //确认收货按钮对应: 待收货
label: '确认收货'
},
{
id: 7,
value: [SaleOrderStatusWaitingReceipt.value,SaleOrderStatusAlreadyReceipt.value,SaleOrderStatusComplete.value,SaleOrderStatusRefund.value], //再次购买按钮对应: 待收货,已收货,已完成, 已退款
label: '再次购买'
},
{
id: 8,
value: [SaleOrderStatusBooking.value], //按钮对应: 待接单
label: '退款'
},
])
//判断是否显示该按钮
const orderBtnsShow = (item) => {
if(orderInfo) {
if(item.id == 1) {
//取消订单按钮
return( orderInfo.actual_amount == 0 && item.value.includes(orderInfo.status)) //在待发货之前没有付过款
} else if (item.id == 2) {
//去付款按钮
return( orderInfo.wait_pay_amount != 0 && item.value.includes(orderInfo.status)) //只要没有付完款就显示
} else if(item.id == 3 ) {
//申请退款, 只有大货才有
return (orderInfo.sale_mode == SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) //大货在待发货付过款
} else if( item.id == 8) {
//退款按钮(直接退款不用申请), 只有散剪和剪板有
return (orderInfo.sale_mode != SaLeModeBulk.value && orderInfo.actual_amount != 0 && item.value.includes(orderInfo.status)) //散剪和剪板在待接单时付过款
}
else {
//其他按钮
return item.value.includes(orderInfo.status)
}
}
}
//显示的按钮数组
const orderBtnsShowList: {id: number, value: any, label: string}[] = useMemo(() => {
return orderBtnsList.current.filter(item => {
return orderBtnsShow(item)
})
}, [orderInfo])
//点击按钮操作
const submitBtns = (val, index) => {
(val == 1)&&cancelOrder(); //取消订单按钮
(val == 2)&&onClick?.(2); //去付款按钮
(val == 6)&&receiveOrder(); //确认收货
}
//取消订单
const {fetchData: cancelFetchData} = CancelOrderApi()
const cancelOrder = () => {
Taro.showModal({
title: '要取消该订单吗?',
success: async function (res) {
if (res.confirm) {
let res = await cancelFetchData({id: orderInfo?.orderId})
if(res.success) {
alert.success('取消成功')
onClick?.(1)
} else {
alert.none(res.msg)
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
//确认订单
const {fetchData: receiveOrderFetchData} = ReceiveOrderApi()
const receiveOrder = async () => {
console.log('123456')
Taro.showModal({
title: '确定收货?',
success: async function (res) {
if (res.confirm) {
let res = await receiveOrderFetchData({sale_order_id: orderInfo?.orderId})
if(res.success){
onClick?.(6)
alert.success('收货成功')
} else {
alert.error('收货失败')
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
//显示更多按钮
const [showMore, setShowMore] = useState(false)
const styleTop = useMemo(() => {
return {top:`-${(orderBtnsShowList.length - 3)*70 + 10}rpx`, left: `-${10}rpx`}
}, [orderBtnsShowList])
return (
<View className={styles.btns_list}>
{(orderBtnsShowList.length > 3)&&<View className={styles.more}>
<Text onClick={() => setShowMore(true)}></Text>
{showMore&&<View className={styles.more_con}>
<View className={styles.more_list} style={styleTop}>
{orderBtnsShowList.map((item, index) => {
return ((index >= 3) &&<View className={styles.more_item} key={item.id} onClick={() => submitBtns(item.id, index)}>{item.label}</View>)
})}
</View>
<View className={styles.more_bg} catchMove onClick={() => setShowMore(false)}></View>
</View>}
</View>}
<View className={styles.list_scroll}>
{orderBtnsShowList.map((item, index) =>
(index < 3)&&<View key={item.id} className={styles.btns_item} onClick={() => submitBtns(item.id, index)}>{item.label}</View>
)}
</View>
</View>
)
})

View File

@ -0,0 +1,87 @@
.btns_list{
width: 100%;
// margin-top: 30px;
display: flex;
align-content: center;
.more{
font-size: 28px;
width: 143px;
display: flex;
align-items: center;
color: $color_font_two;
padding-left: 20px;
position: relative;
.more_list{
position: absolute;
background-color: #fff;
width: 226px;
box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.06);
border-radius: 10px;
padding: 0 20px;
box-sizing: border-box;
z-index:999;
&::before{
z-index: 1;
position: absolute;
bottom: -7px;
left: 50px;
width: 15px;
height: 15px;
content: " ";
transform: rotate(45deg);
background: #fff;
box-sizing: border-box;
box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.1);
}
.more_item{
font-size: 28px;
height: 70px;
line-height: 70px;
text-align: center;
&:nth-last-child(n+2) {
border-bottom: 1PX solid #F0F0F0;
}
}
}
.more_bg{
position:fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
}
}
.scroll{
white-space: nowrap;
width: 100%;
}
.list_scroll{
white-space: nowrap;
width: 100%;
text-align: right;
}
.btns_item{
padding: 0 15px;
width: 130px;
border: 2px solid #dddddd;
border-radius: 38px;
text-align: center;
line-height: 60px;
font-size: $font_size;
color: $color_font_three;
display:inline-block;
&:nth-child(n+2) {
margin-left: 32px;
}
&:nth-last-child(1) {
border: 2px solid $color_main;
color: $color_main;
}
}
.end_btn{
border: 2px solid $color_main;
color: $color_main;
}
}

View File

@ -0,0 +1,193 @@
import { CancelOrderApi, ReceiveOrderApi } from "@/api/order"
import { alert } from "@/common/common"
import { AFTER_ORDER_STATUS, ORDER_STATUS, SALE_MODE } from "@/common/enum"
import {Text, View } from "@tarojs/components"
import Taro from "@tarojs/taro"
import {useRef, memo, useState, useMemo } from "react"
import classnames from "classnames";
import styles from './index.module.scss'
import { ReturnApplyOrderCancelApi } from "@/api/salesAfterOrder"
type Param = {
orderInfo: {
stage: number, //售后状态
orderId: number, //订单id
sale_mode: number //订单类型
type: number //1退货2退款
},
onClick?: (val: number) => void //点击后触发的事件,返回订单状态
}
export default memo(({orderInfo, onClick}:Param) => {
//售后订单状态
const {
ReturnStageApplying,
ReturnStageWaitCheck,
ReturnStageChecked,
ReturnStageReturned,
ReturnStageCancel,
ReturnStageQualityCheckPendingRefund,
ReturnStageServiceOrderPendingRefund,
ReturnStageRejected
} = AFTER_ORDER_STATUS
//订单类型
const {
SaLeModeBulk,
SaleModeLengthCut,
SaLeModeWeightCut,
} = SALE_MODE
//售后按钮按售后状态归类, value是该订单状态可能该按钮会出现
const orderBtnsList = useRef([
{
id: 1,
value: [ReturnStageApplying.value, ReturnStageWaitCheck.value],
label: '取消退货'
},
{
id: 2,
value: [ReturnStageWaitCheck.value],
label: '退货物流'
},
{
id: 3,
value: [ReturnStageChecked.value, ReturnStageQualityCheckPendingRefund.value],
label: '查看物流'
},
{
id: 4,
value: [ReturnStageQualityCheckPendingRefund.value, ReturnStageServiceOrderPendingRefund.value, ReturnStageReturned.value],
label: '质检结果'
},
{
id: 5,
value: [ReturnStageServiceOrderPendingRefund.value, ReturnStageReturned.value],
label: '退货码单'
},
{
id: 6,
value: [ReturnStageApplying.value, ReturnStageServiceOrderPendingRefund.value],
label: '取消退款'
},
{
id: 7,
value: [ReturnStageServiceOrderPendingRefund.value, ReturnStageReturned.value],
label: '退款码单'
},
{
id: 8,
value: [],
label: '申请记录'
},
])
//判断是否显示该按钮
const orderBtnsShow = (item) => {
if(!orderInfo) return false
if(item.id == 1) {
//取消退货
return (orderInfo.type == 1)&&item.value.includes(orderInfo.stage)
} else if (item.id == 6) {
//取消退款
return (orderInfo.type == 2)&&item.value.includes(orderInfo.stage)
} else {
return item.value.includes(orderInfo.stage)
}
}
//显示的按钮数组
const orderBtnsShowList: {id: number, value: any, label: string}[] = useMemo(() => {
return orderBtnsList.current.filter(item => {
return orderBtnsShow(item)
})
}, [orderInfo])
//点击按钮操作
const submitBtns = (val, index) => {
if (val == 1) {
cancelOrder()
} else if (val == 6) {
receiveOrder()
} else {
onClick?.(val)
}
}
//取消退货
const {fetchData: returnApplyOrderCancelFetchData} = ReturnApplyOrderCancelApi()
const cancelOrder = () => {
Taro.showModal({
title: '要取消退货吗?',
success: async function (res) {
if (res.confirm) {
let res = await returnApplyOrderCancelFetchData({id: orderInfo?.orderId})
if(res.success) {
alert.success('取消成功')
onClick?.(1)
} else {
alert.none(res.msg)
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
//确认订单
const {fetchData: receiveOrderFetchData} = ReceiveOrderApi()
const receiveOrder = async () => {
console.log('123456')
Taro.showModal({
title: '确定收货?',
success: async function (res) {
if (res.confirm) {
let res = await receiveOrderFetchData({sale_order_id: orderInfo?.orderId})
if(res.success){
onClick?.(6)
alert.success('收货成功')
} else {
alert.error('收货失败')
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
//显示更多按钮
const [showMore, setShowMore] = useState(false)
const styleTop = useMemo(() => {
return {top:`-${(orderBtnsShowList.length - 3)*70 + 10}rpx`, left: `-${10}rpx`}
}, [orderBtnsShowList])
return (
<View className={styles.btns_list}>
{(orderBtnsShowList.length > 3)&&<View className={styles.more}>
<Text onClick={() => setShowMore(true)}></Text>
{showMore&&<View className={styles.more_con}>
<View className={styles.more_list} style={styleTop}>
{orderBtnsShowList.map((item, index) => {
return ((index >= 3) &&<View className={styles.more_item} key={item.id} onClick={() => submitBtns(item.id, index)}>{item.label}</View>)
})}
</View>
<View className={styles.more_bg} catchMove onClick={() => setShowMore(false)}></View>
</View>}
</View>}
<View className={styles.list_scroll}>
{orderBtnsShowList.map((item, index) =>
(index < 3)&&<View key={item.id} className={classnames(styles.btns_item)} onClick={() => submitBtns(item.id, index)}>{item.label}</View>
)}
</View>
</View>
)
})

View File

@ -4,19 +4,25 @@
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
.reduce, .plus{ .plus{
font-size: $font_size_big;
color: $color_main; color: $color_main;
width: 46px; width: 46px;
height: 46px; height: 46px;
display: flex; text-align: center;
align-items: center; line-height: 43px;
justify-content:center;
font-size: 50px; font-size: 50px;
background-color: $color_main; background-color: $color_main;
color: #fff; color: #fff;
border-radius: 8px; border-radius: 8px;
} }
.reduce {
font-size: 50px;
width: 46px;
height: 46px;
text-align: center;
line-height: 43px;
color:#007AFF;
}
.input{ .input{
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
@ -25,10 +31,13 @@
box-sizing: border-box; box-sizing: border-box;
width: 106px; width: 106px;
border-radius: 10px; border-radius: 10px;
}
input{ input{
font-size: $font_size_medium; font-size: $font_size_medium;
text-align: right;
padding-right: 10px;
} }
}
.unit{ .unit{
font-size: $font_size_min; font-size: $font_size_min;
color: $color_font_two; color: $color_font_two;

View File

@ -11,12 +11,14 @@ type params = {
onChange?:(val:number) => void, onChange?:(val:number) => void,
onBlue?:(val:number) => void, //失去焦点触发 onBlue?:(val:number) => void, //失去焦点触发
onClickBtn?:(val:number) => void, onClickBtn?:(val:number) => void,
unit?: string unit?: string,
disable?: true|false, //是否禁用
} }
export default ({minNum = 0, maxNum = 100, step=1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = ''}: params) => { export default ({minNum = 0, maxNum = 10000, step=1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disable = false}: params) => {
const [value, setValue] = useState<any>({count:defaultNum}) const [value, setValue] = useState<any>({count:defaultNum})
const onPlus = () => { const onPlus = () => {
if(disable) return false
let {count} = value let {count} = value
let num_res = Big(count).add(step).toNumber() let num_res = Big(count).add(step).toNumber()
num_res = num_res >= maxNum?maxNum:num_res num_res = num_res >= maxNum?maxNum:num_res
@ -26,9 +28,10 @@ export default ({minNum = 0, maxNum = 100, step=1, digits = 0, defaultNum = 0, o
onClickBtn?.(parseFloat(num_res)) onClickBtn?.(parseFloat(num_res))
} }
const minus = () => { const minus = () => {
if(disable) return false
let {count} = value let {count} = value
let num_res = Big(count).minus(step).toNumber() let num_res = Big(count).minus(step).toNumber()
num_res = num_res < minNum?0:num_res num_res = num_res < minNum?minNum:num_res
setValue({...value, count:num_res}) setValue({...value, count:num_res})
onChange?.(parseFloat(num_res)) onChange?.(parseFloat(num_res))
onClickBtn?.(parseFloat(num_res)) onClickBtn?.(parseFloat(num_res))
@ -102,6 +105,7 @@ export default ({minNum = 0, maxNum = 100, step=1, digits = 0, defaultNum = 0, o
onInput={onInputEven} onInput={onInputEven}
onBlur={onBluerEven} onBlur={onBluerEven}
type='digit' type='digit'
disabled={disable}
/> />
<View className={styles.unit}>{unit}</View> <View className={styles.unit}>{unit}</View>
</View> </View>

View File

@ -0,0 +1,37 @@
.main{
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.reduce, .plus{
font-size: $font_size_big;
color: $color_main;
width: 46px;
height: 46px;
display: flex;
align-items: center;
justify-content:center;
font-size: 50px;
background-color: $color_main;
color: #fff;
border-radius: 8px;
}
.input{
display: flex;
align-items: flex-end;
background-color: #fff;
padding: 5px 10px;
box-sizing: border-box;
width: 106px;
border-radius: 10px;
}
input{
font-size: $font_size_medium;
}
.unit{
font-size: $font_size_min;
color: $color_font_two;
}
}

View File

@ -0,0 +1,111 @@
import { Input, View } from "@tarojs/components"
import { useEffect, useMemo, useRef, useState } from "react"
import Big from 'big.js'
import styles from "./index.module.scss"
type params = {
minNum?: number, //最小值
maxNum?: number, //最大值
step?: number, //步长
defaultNum?: number, //默认值
digits?: number //多少位小数
onChange?:(val:number) => void,
onBlue?:(val:number) => void, //失去焦点触发
onClickBtn?:(val:number) => void,
unit?: string
}
export default ({minNum = 0, maxNum = 100, step=1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = ''}: params) => {
const [value, setValue] = useState<any>({count:defaultNum})
const onPlus = () => {
let {count} = value
let num_res = Big(count).add(step).toNumber()
num_res = num_res >= maxNum?maxNum:num_res
num_res = formatDigits(num_res)
setValue({...value, count:num_res})
onChange?.(parseFloat(num_res))
onClickBtn?.(parseFloat(num_res))
}
const minus = () => {
let {count} = value
let num_res = Big(count).minus(step).toNumber()
num_res = num_res < minNum?0:num_res
setValue({...value, count:num_res})
onChange?.(parseFloat(num_res))
onClickBtn?.(parseFloat(num_res))
}
//保留小数
const formatDigits = (num) => {
num = num + ''
if(num.includes('.')&&digits > 0) {
console.log('num::',num.includes('.'))
let res = num.split('.')
let last_num = res[1].substr(0, digits)
return res[0] + '.' + last_num
}
return parseFloat(num)
}
//检查数据
const checkData = (val) => {
let num = parseFloat(val)
if(num > maxNum) return maxNum
if(num < minNum) return minNum
return val
}
const onInputEven = (e) => {
let res = e.detail.value
if(res === '') {
setValue({...value, count:minNum})
onChange?.(minNum)
}
else if(!isNaN(Number(res))) {
let count = formatDigits(res)
count = checkData(count)
setValue({...value, count})
onChange?.(parseFloat(count as string))
} else {
let num = parseFloat(res)
if(!isNaN(num)) {
let count = formatDigits(num)
count = checkData(count)
setValue({...value, count})
onChange?.(count as number)
} else {
setValue({...value, count:defaultNum})
onChange?.(defaultNum)
}
}
}
const onBluerEven = () => {
let num = parseFloat(value.count)
if(!isNaN(num)) {
let count = formatDigits(num)
count = checkData(count)
setValue({...value, count})
onBlue?.(count as number)
} else {
setValue({...value, count:defaultNum})
onBlue?.(defaultNum)
}
}
return (
<View className={styles.main}>
<View className={styles.reduce} onClick={() => minus()}>-</View>
<View className={styles.input}>
<Input
value={String(value.count)}
onInput={onInputEven}
onBlur={onBluerEven}
type='digit'
/>
<View className={styles.unit}>{unit}</View>
</View>
<View className={styles.plus} onClick={() => onPlus()}>+</View>
</View>
)
}

View File

@ -74,6 +74,11 @@
&:nth-child(n+2) { &:nth-child(n+2) {
margin-left: 32px; margin-left: 32px;
} }
&:nth-last-child(1) {
border: 2px solid $color_main;
color: $color_main;
}
} }
.end_btn{ .end_btn{
border: 2px solid $color_main; border: 2px solid $color_main;

View File

@ -1,10 +1,12 @@
import { CancelOrderApi, ReceiveOrderApi } from "@/api/order" import { CancelOrderApi, ReceiveOrderApi } from "@/api/order"
import { alert } from "@/common/common" import { alert, goLink } from "@/common/common"
import { ORDER_STATUS, SALE_MODE } from "@/common/enum" import { ORDER_STATUS, SALE_MODE } from "@/common/enum"
import { ScrollView, Text, View } from "@tarojs/components" import {Text, View } from "@tarojs/components"
import Taro from "@tarojs/taro" import Taro from "@tarojs/taro"
import { useCallback, useRef, memo, useState, useEffect, useMemo } from "react" import {useRef, memo, useState, useMemo } from "react"
import classnames from "classnames";
import styles from './index.module.scss' import styles from './index.module.scss'
import { AddShoppingCartApi } from "@/api/shopCart"
type Param = { type Param = {
orderInfo: { orderInfo: {
@ -29,7 +31,8 @@ export default memo(({orderInfo, onClick}:Param) => {
SaleOrderStatusWaitingPayment, SaleOrderStatusWaitingPayment,
SaleOrderStatusWaitingReceipt, SaleOrderStatusWaitingReceipt,
SaleOrderStatusAlreadyReceipt, SaleOrderStatusAlreadyReceipt,
SaleorderstatusWaitingPrePayment SaleorderstatusWaitingPrePayment,
SaleOrderStatusTaking
} = ORDER_STATUS } = ORDER_STATUS
//订单类型 //订单类型
@ -41,6 +44,7 @@ export default memo(({orderInfo, onClick}:Param) => {
//订单按钮按订单状态归类, value是该订单状态可能该按钮会出现 //订单按钮按订单状态归类, value是该订单状态可能该按钮会出现
const orderBtnsList = useRef([ const orderBtnsList = useRef([
{ {
id: 1, id: 1,
value: [SaleOrderStatusBooking.value, value: [SaleOrderStatusBooking.value,
@ -50,14 +54,9 @@ export default memo(({orderInfo, onClick}:Param) => {
SaleOrderStatusWaitingDelivery.value], //取消订单按钮对应: 待接单,配布中,已配布, 待付款, 待发货 SaleOrderStatusWaitingDelivery.value], //取消订单按钮对应: 待接单,配布中,已配布, 待付款, 待发货
label: '取消订单' label: '取消订单'
}, },
{
id: 2,
value: [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value], //去付款按钮对应:待付款, 待发货, 待收货, 已收货, 已完成
label: '去付款'
},
{ {
id: 3, id: 3,
value: [SaleOrderStatusWaitingDelivery.value], //申请退款按钮对应: 待发货 value: [SaleOrderStatusWaitingDelivery.value, SaleOrderStatusTaking.value], //申请退款按钮对应: 待发货, 提货中
label: '申请退款' label: '申请退款'
}, },
// { // {
@ -85,6 +84,11 @@ export default memo(({orderInfo, onClick}:Param) => {
value: [SaleOrderStatusBooking.value], //按钮对应: 待接单 value: [SaleOrderStatusBooking.value], //按钮对应: 待接单
label: '退款' label: '退款'
}, },
{
id: 2,
value: [SaleOrderStatusTaking.value, SaleorderstatusWaitingPrePayment.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value], //去付款按钮对应:待付款, 待发货, 待收货, 已收货, 已完成
label: '去付款'
},
]) ])
@ -123,10 +127,15 @@ export default memo(({orderInfo, onClick}:Param) => {
//点击按钮操作 //点击按钮操作
const submitBtns = (val, index) => { const submitBtns = (val, index) => {
(val == 1)&&cancelOrder(); //取消订单按钮 if (val == 1) {
(val == 2)&&onClick?.(2); //去付款按钮 cancelOrder()
(val == 6)&&receiveOrder(); //确认收货 } else if (val == 6) {
receiveOrder()
} else if(val == 5) {
goLink('/pages/applyAfterSales/index',{id:orderInfo?.orderId})
} else {
onClick?.(val)
}
} }
//取消订单 //取消订单
@ -172,6 +181,7 @@ export default memo(({orderInfo, onClick}:Param) => {
}) })
} }
//显示更多按钮 //显示更多按钮
const [showMore, setShowMore] = useState(false) const [showMore, setShowMore] = useState(false)
const styleTop = useMemo(() => { const styleTop = useMemo(() => {
@ -194,7 +204,7 @@ export default memo(({orderInfo, onClick}:Param) => {
<View className={styles.list_scroll}> <View className={styles.list_scroll}>
{orderBtnsShowList.map((item, index) => {orderBtnsShowList.map((item, index) =>
(index < 3)&&<View key={item.id} className={styles.btns_item} onClick={() => submitBtns(item.id, index)}>{item.label}</View> (index < 3)&&<View key={item.id} className={classnames(styles.btns_item)} onClick={() => submitBtns(item.id, index)}>{item.label}</View>
)} )}
</View> </View>

View File

@ -25,7 +25,7 @@
border-radius: 10px; border-radius: 10px;
} }
.num{ .num{
padding: 5px 10px; padding: 5px 10px 5px 20px;
font-size: $font_size_min; font-size: $font_size_min;
position: absolute; position: absolute;
right:0; right:0;
@ -51,7 +51,7 @@
.tag_list{ .tag_list{
display: flex; display: flex;
margin-top: 16px; margin-top: 16px;
.tag{ .tag, .tag_g{
padding: 3px 10px; padding: 3px 10px;
background-color: #CDE5FF; background-color: #CDE5FF;
font-size: $font_size_min; font-size: $font_size_min;
@ -61,6 +61,10 @@
margin-left: 10px; margin-left: 10px;
} }
} }
.tag_g{
background-color: #FFE6CE;
color: #EE7500;
}
} }
.introduce{ .introduce{
font-size: $font_size_medium; font-size: $font_size_medium;

View File

@ -22,7 +22,7 @@ export default ({desStatus = true, productList = []}:Params) => {
<View className={styles.title}><text>{formatHashTag(item.code, '')} </text>{item.name}</View> <View className={styles.title}><text>{formatHashTag(item.code, '')} </text>{item.name}</View>
<View className={styles.tag_list}> <View className={styles.tag_list}>
<View className={styles.tag}>{item.width}</View> <View className={styles.tag}>{item.width}</View>
<View className={styles.tag}>{item.weight_density}</View> <View className={styles.tag_g}>{item.weight_density}</View>
</View> </View>
<View className={styles.introduce}>{item.component}</View> <View className={styles.introduce}>{item.component}</View>
{desStatus&&<View className={styles.des}>{item.describe}</View>} {desStatus&&<View className={styles.des}>{item.describe}</View>}

View File

@ -17,6 +17,11 @@
margin-right: 10px; margin-right: 10px;
} }
} }
.count_all{
font-size: 22px;
color: #ABABAB;
padding: 30px 20px;
}
.search{ .search{
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -104,6 +109,15 @@
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
align-items: flex-end; align-items: flex-end;
.btn_count{
width: 235px;
height: 64px;
background-color: #ECF5FF;
border-radius: 40px 0px 16px 0px;
padding: 0 20px;
display: flex;
align-items: center;
}
.price{ .price{
font-size: $font_size; font-size: $font_size;
font-weight: 700; font-weight: 700;
@ -150,6 +164,7 @@
justify-content: center; justify-content: center;
padding-bottom: constant(safe-area-inset-bottom); padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);
z-index: 999;
.buy_con{ .buy_con{
width: 702px; width: 702px;
height: 95px; height: 95px;

View File

@ -8,10 +8,11 @@ import styles from "./index.module.scss"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import { alert, goLink } from "@/common/common"; import { alert, goLink } from "@/common/common";
import {GetShoppingCartApi, DelShoppingCartApi} from "@/api/shopCart" import {GetShoppingCartApi, DelShoppingCartApi, UpdateShoppingCartApi} from "@/api/shopCart"
import { formatHashTag, formatImgUrl, formatPriceDiv } from "@/common/fotmat"; import { formatHashTag, formatImgUrl, formatPriceDiv } from "@/common/fotmat";
import { setParam } from "@/common/system"; import { setParam } from "@/common/system";
import { debounce } from "@/common/util"; import { debounce } from "@/common/util";
import Counter from "../counter";
type param = { type param = {
show?: true|false, show?: true|false,
@ -19,11 +20,9 @@ type param = {
} }
export default ({show = false, onClose}: param) => { export default ({show = false, onClose}: param) => {
const selectList = [ const selectList = [
// {value:-1, title:'不限', unit:'', eunit:''}, {value:0, title:'大货', unit:'条', eunit:'kg', step:1, digits:0, minNum:1, maxNum:100000, defaultNum:1},
{value:0, title:'大货', unit:'件', eunit:'kg'}, {value:1,title:'剪板', unit:'米', eunit:'m', step:1, digits:2, minNum:0.5, maxNum:9.99, defaultNum:1},
{value:1,title:'剪板', unit:'米', eunit:'m'}, {value:2,title:'散剪', unit:'米', eunit:'kg', step:1, digits:2, minNum:5, maxNum:100000, defaultNum:10},
{value:2,title:'散剪', unit:'米', eunit:'kg'},
] ]
const [selectIndex, setSelectIndex] = useState(0) const [selectIndex, setSelectIndex] = useState(0)
@ -53,7 +52,6 @@ export default ({show = false, onClose}: param) => {
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const {fetchData} = GetShoppingCartApi() const {fetchData} = GetShoppingCartApi()
const getShoppingCart = async () => { const getShoppingCart = async () => {
setLoading(true)
const {data} = await fetchData() const {data} = await fetchData()
let color_list = data.color_list||[] let color_list = data.color_list||[]
initList(color_list) initList(color_list)
@ -65,6 +63,7 @@ export default ({show = false, onClose}: param) => {
const initList = (color_list) => { const initList = (color_list) => {
color_list?.map(item => { color_list?.map(item => {
if(selectIndex == item.sale_mode) item.select = true if(selectIndex == item.sale_mode) item.select = true
item.count = formatCount(item)
}) })
} }
@ -74,6 +73,7 @@ export default ({show = false, onClose}: param) => {
setList([]) setList([])
setSelectIndex(0) setSelectIndex(0)
} else { } else {
setLoading(true)
getShoppingCart() getShoppingCart()
} }
}, [show]) }, [show])
@ -136,11 +136,13 @@ export default ({show = false, onClose}: param) => {
//删除购物车内容 //删除购物车内容
const {fetchData:delShopFetchData} = DelShoppingCartApi() const {fetchData:delShopFetchData} = DelShoppingCartApi()
const delSelect = () => { const delSelect = () => {
getSelectId()
if(selectIds.current.length <= 0) return alert.none('请选择要删除的面料!')
Taro.showModal({ Taro.showModal({
content: '删除所选商品?', content: '删除所选商品?',
success: async function (res) { success: async function (res) {
if (res.confirm) { if (res.confirm) {
getSelectId()
const res = await delShopFetchData({id:selectIds.current}) const res = await delShopFetchData({id:selectIds.current})
if(res.success) { if(res.success) {
getShoppingCart() getShoppingCart()
@ -180,18 +182,34 @@ export default ({show = false, onClose}: param) => {
//格式化数量 //格式化数量
const formatCount = useCallback((item) => { const formatCount = useCallback((item) => {
return item.sale_mode == 0? item.roll + '件': (item.length/100) + 'm' console.log('item:::',item)
return item.sale_mode == 0? item.roll : (item.length/100)
}, []) }, [])
//预估金额 //格式化单位
const formatUnit = useCallback((item) => {
return item.sale_mode == 0? '条':'米'
}, [])
//预估金额和总条数
const estimatePrice = useMemo(() => { const estimatePrice = useMemo(() => {
let count = 0 let estimate_amount = 0
let product_list = new Set() //面料
let color_count = 0 //颜色数量
let all_count = 0 //总数量
list.map(item => { list.map(item => {
if(item.select) count += item.estimate_amount if(item.select) {
estimate_amount += item.estimate_amount
product_list.add(item.product_id)
color_count++
all_count += item.sale_mode == 0?item.roll: (item.length)
}
}) })
return Number(formatPriceDiv(count)) let all_count_text = selectIndex == 0?all_count + '条': (all_count/100) + '米'
return {price: Number(formatPriceDiv(estimate_amount)).toFixed(2), countText: `已选${product_list.size}种面料,${color_count}个颜色,共${all_count_text}`, color_count}
},[list]) },[list])
//去结算 //去结算
const orderDetail = debounce(() => { const orderDetail = debounce(() => {
getSelectId() getSelectId()
@ -199,12 +217,26 @@ export default ({show = false, onClose}: param) => {
alert.error('请选择面料') alert.error('请选择面料')
} else { } else {
let ids = selectIds.current.join('-') let ids = selectIds.current.join('-')
setParam({ids, sale_mode:selectIndex}) setParam({ids, sale_mode:selectIndex}) //临时存储
closePopup() closePopup()
goLink('/pages/order/comfirm') goLink('/pages/order/comfirm')
} }
}, 500) }, 500)
//计数组件-当后端修改完成才修改前端显示
const {fetchData: fetchDataUpdateShoppingCart} = UpdateShoppingCartApi()
const [UpdateShoppingCartLoading, setUpdateShoppingCartLoading] = useState(false)
const getInputValue = debounce(async (num, item) => {
let roll = item.sale_mode == 0?parseFloat(num):0
let length = item.sale_mode != 0?(parseFloat(num)*100):0
setUpdateShoppingCartLoading(() => true)
let res = await fetchDataUpdateShoppingCart({id: item.id, roll, length})
setUpdateShoppingCartLoading(() => false)
if(res.success) {
getShoppingCart()
}
}, 300)
return ( return (
<View className={styles.shop_cart_main}> <View className={styles.shop_cart_main}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()} > <Popup showTitle={false} show={showPopup} onClose={() => closePopup()} >
@ -216,6 +248,7 @@ export default ({show = false, onClose}: param) => {
</View> </View>
</View> </View>
<View className={styles.count_all}>{estimatePrice.countText}</View>
<View className={styles.search}> <View className={styles.search}>
{selectList.map((item) => { {selectList.map((item) => {
return <View key={item.value} onClick={() => selectProduct(item.value)} className={classnames(styles.search_item, (selectIndex==item.value)&&styles.search_item_select)}>{item.title}</View> return <View key={item.value} onClick={() => selectProduct(item.value)} className={classnames(styles.search_item, (selectIndex==item.value)&&styles.search_item_select)}>{item.title}</View>
@ -240,7 +273,20 @@ export default ({show = false, onClose}: param) => {
</View> </View>
<View className={styles.count}> <View className={styles.count}>
<View className={styles.price}><text></text>{formatPirce(item.sale_price)}<text>/{selectList[selectIndex].eunit}</text></View> <View className={styles.price}><text></text>{formatPirce(item.sale_price)}<text>/{selectList[selectIndex].eunit}</text></View>
<View className={styles.long}>×{formatCount(item)}</View> {/* <View className={styles.long}>×{formatCount(item)}{selectList[selectIndex].unit}</View> */}
<View className={styles.btn_count}>
<Counter
onBlue={(e) => getInputValue(e, item)}
defaultNum={item.count}
step={selectList[selectIndex].step}
digits={selectList[selectIndex].digits}
onClickBtn={(e) => getInputValue(e, item)}
unit={formatUnit(item)}
minNum={selectList[selectIndex].minNum}
maxNum={selectList[selectIndex].maxNum}
disable={UpdateShoppingCartLoading}
/>
</View>
</View> </View>
</View> </View>
})} })}
@ -258,11 +304,11 @@ export default ({show = false, onClose}: param) => {
<View className={classnames('iconfont', 'icon-gouwuche', styles.miconfont)}></View> <View className={classnames('iconfont', 'icon-gouwuche', styles.miconfont)}></View>
</View> </View>
<View className={styles.price_con}> <View className={styles.price_con}>
<View className={styles.price_real}><text></text>{estimatePrice}</View> <View className={styles.price_real}><text></text>{estimatePrice.price}</View>
<View className={styles.price_forecast}></View> <View className={styles.price_forecast}></View>
</View> </View>
<View className={styles.goPay} onClick={() => orderDetail()}> <View className={styles.goPay} onClick={() => orderDetail()}>
({estimatePrice.color_count})
</View> </View>
</View> </View>
</View> </View>

View File

@ -29,8 +29,9 @@
} }
.sideBar_select_title_select{ .sideBar_select_title_select{
background-color: $color_bg_one; background-color: #007AFF;
color: $color_font_one; color: #fff;
border-radius: 0px 14px 14px 0px;
} }
} }
.sideBar_con{ .sideBar_con{

View File

@ -104,7 +104,6 @@ export default memo(({list = [],
) )
}) })
} }
<View className="common_safe_area_y"></View>
</ScrollView> </ScrollView>
<View className={styles.sideBar_con}> <View className={styles.sideBar_con}>
<InfiniteScroll statusMore={statusMore} hasMore={hasMore} selfonScrollToLower={() => selfOnScrolltolower?.()} refresherTriggered={refresherTriggered} refresherEnabled={true} selfOnRefresherRefresh={() => selfOnRefresherRefresh?.()}> <InfiniteScroll statusMore={statusMore} hasMore={hasMore} selfonScrollToLower={() => selfOnScrolltolower?.()} refresherTriggered={refresherTriggered} refresherEnabled={true} selfOnRefresherRefresh={() => selfOnRefresherRefresh?.()}>

View File

@ -0,0 +1,36 @@
.other_desc{
// padding: 0 20px;
box-sizing: border-box;
.title{
font-size: $font_size;
font-weight: 700;
}
.textarea{
position: relative;
height: 165.4px;
.descDataNum{
position: absolute;
right: 10px;
bottom: 10px;
font-size: 22px;
color: #ABABAB;
}
}
.textarea_con, .textarea_con_pretend{
background-color: #f3f3f3;
border: 2px solid #e6e6e6;
border-radius: 10px;
width: 100%;
font-size: 25px;
height: 165.4px;
padding: 20px 20px 30px 20px;
box-sizing: border-box;
margin-top: 20px;
}
.textarea_con_pretend{
color: $color_font_two;
}
.textarea_con_pretend_ed{
color: #000;
}
}

View File

@ -0,0 +1,43 @@
import {Textarea, View } from "@tarojs/components";
import { memo, useMemo, useState } from "react";
import styles from './index.module.scss'
import classnames from "classnames";
//其他说明
type Param = {
title?: string,
onChange?: (val: string) => void,
placeholder?: string
}
export default memo(({onChange, title = '', placeholder = '请输入'}:Param) => {
const [descData, setDescData] = useState({
number: 0,
value: '',
count: 200,
show: false
})
const getDesc = (e) => {
let value = e.detail.value
let res = value
if(value.length > descData.count) {
res = value.slice(0, descData.count)
}
setDescData({...descData, number:res.length, value: res})
onChange?.(res)
}
const toggleShowRealTextarea = (show) => {
setDescData({...descData, show:show})
}
return (
<View className={styles.other_desc}>
<View className={styles.title}>{title}</View>
<View className={styles.textarea}>
{descData.show&&<Textarea autoFocus value={descData.value} onBlur={() => toggleShowRealTextarea(false)} className={styles.textarea_con} cursorSpacing={100} maxlength={descData.count} onInput={(e) => getDesc(e)}></Textarea>||
<View className={classnames(styles.textarea_con_pretend, descData.value&&styles.textarea_con_pretend_ed)} onClick={() => toggleShowRealTextarea(true)}>{descData.value||placeholder}</View>
}
<View className={styles.descDataNum}>{descData.number +'/'+ descData.count}</View>
</View>
</View>
)
})

View File

@ -0,0 +1,55 @@
.image_main{
display: flex;
align-items: center;
flex-wrap: wrap;
.uploadImg{
width: 202px;
height: 150px;
background: #f0f0f0;
border: 2px dashed #cccccc;
border-radius: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
margin: 0 0 20px 20px;
position: relative;
.miconfont{
font-size: 50px;
}
.uploadText{
font-size: 26px;
color: $color_font_three;
}
}
.ImgItem{
width: 202px;
height: 150px;
background: #f0f0f0;
margin-left: 20px;
margin-bottom: 20px;
position: relative;
border-radius: 10px;
image{
width: 100%;
height: 100%;
border-radius: 10px;
}
.miconfont_close{
width: 43px;
height: 43px;
background-color: #ccc;
border-radius: 50%;
position: absolute;
right: -10px;
top: -10px;
text-align: center;
line-height: 43px;
color: #fff;
font-size: 30px;
}
}
}

View File

@ -0,0 +1,59 @@
import Taro, { FC } from "@tarojs/taro"
import { memo, useEffect, useState } from "react"
import useUploadCDNImg from "@/use/useUploadImage";
import { Image, Text, View } from "@tarojs/components";
import { formatImgUrl } from "@/common/fotmat";
import classnames from "classnames";
import styles from './index.module.scss'
//图片列表
type ImageParam = {
onChange?:(val: string[]) => void
}
const PictureItem:FC<ImageParam> = memo(({onChange}) => {
const {getWxPhoto} = useUploadCDNImg()
const [imageList, setImageLise] = useState<string[]>([])
//上传图片
const uploadImage = async () => {
let res:any = await getWxPhoto('after-sale')
if(res.code == 200) {
setImageLise([...imageList, res.url])
}
}
//删除图片
const delImage = (index) => {
imageList.splice(index,1)
setImageLise(() => [...imageList])
}
//监听上传的图片变化
useEffect(() => {
onChange?.(imageList||[])
}, [imageList])
//预览图片
const showImage = () => {
let list = imageList.map(item => {
return formatImgUrl(item)
})
Taro.previewImage({
current: list[0], // 当前显示
urls: list // 需要预览的图片http链接列表
})
}
return (
<View className={styles.image_main}>
{imageList.map((item, index) =>
<View className={styles.ImgItem}>
<Image mode="aspectFill" src={formatImgUrl(item)} onClick={showImage}></Image>
<View onClick={() => delImage(index)} className={classnames(styles.miconfont_close, 'iconfont icon-qingkong')}></View>
</View>)}
<View className={styles.uploadImg } onClick={uploadImage}>
<Text className={classnames(styles.miconfont, 'iconfont icon-saomazhifu')}></Text>
<Text className={styles.uploadText}></Text>
</View>
</View>
)
})
export default PictureItem

View File

@ -0,0 +1,64 @@
.apply_after_sales_list{
padding: 0 20px;
.apply_after_sales_item{
margin-bottom: 50px;
.apply_after_sales_title{
display: flex;
align-items: center;
.tag{
font-size: $font_size_min;
background-color: #CDE5FF;
padding: 5px 10px;
border-radius: 6px;
color: $color_main;
}
.title{
font-weight: 700;
font-size: $font_size;
margin-left: 20px;
flex:1;
}
}
.color_list {
.color_item{
display: flex;
align-items: center;
margin: 30px 0;
}
.image{
width: 70px;
height: 70px;
image{
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.name_and_number{
padding-left: 30px;
flex:1;
text{
&:nth-child(1) {
font-weight: 700;
font-size: $font_size;
}
&:nth-child(2) {
color: $color_font_two;
font-size: $font_size;
margin-left: 20px;
}
}
}
.btn_count{
width: 216px;
height: 64px;
background-color: #ECF5FF;
border-radius: 40px 0px 16px 0px;
padding: 0 20px;
display: flex;
align-items: center;
}
}
}
}

View File

@ -0,0 +1,71 @@
import { formatHashTag, formatImgUrl } from "@/common/fotmat";
import Counter from "@/components/counter";
import MCheckbox from "@/components/checkbox";
import { Image, Text, View } from "@tarojs/components";
import { FC, memo, useCallback } from "react";
import styles from './index.module.scss'
type OrderParam = {
list?: any[],
sale_mode?: number,
sale_mode_name?: string,
unit?: string,
total_colors?: number,
total_fabrics?: number,
total_number?: number,
status?: number, //订单状态
}
type Param = {
order: OrderParam,
onNumChange?: (val:any) => void
onSelectChange?: (val: {color_id:number, length: number, status: true|false}) => void
}
const kindeList:FC<Param> = memo(({order, onNumChange, onSelectChange}) => {
//对应数量
const formatCount = useCallback((item) => {
return (order?.sale_mode == 0? item.roll : Number(item.length / 100)) + order?.unit
}, [order])
//计步器失返回值
const getCounterChange = useCallback((colorItem) => {
return (number) => {
onNumChange?.({number, color_id: colorItem.id})
}
}, [])
//checkbox选中回调
const selectCallBack = (colorItem) => {
console.log('colorItem::',colorItem)
onSelectChange?.({color_id:colorItem.id, length:colorItem.length, status: true})
}
//checkbox关闭回调
const colseCallBack = (colorItem) => {
onSelectChange?.({color_id:colorItem.id, length:colorItem.length, status: false})
}
return (
<View className={styles.apply_after_sales_list}>
{order?.list?.map(item => <View className={styles.apply_after_sales_item}>
<View className={styles.apply_after_sales_title}>
<View className={styles.tag}>{order.sale_mode_name}</View>
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
</View>
<View className={styles.color_list}>
{item.product_colors.map(colorItem => <View className={styles.color_item}>
<View className={styles.image}><Image src={formatImgUrl('')}/></View>
<View className={styles.name_and_number}><Text>{colorItem.code + ' ' + colorItem.name}</Text><Text>x {formatCount(colorItem)}</Text></View>
{(order.sale_mode == 0)&&<View className={styles.btn_count}>
<Counter maxNum={colorItem.roll} onChange={getCounterChange(colorItem)}/>
</View>||
<MCheckbox status={item.select} onSelect={() => selectCallBack(colorItem)} onClose={() => colseCallBack(colorItem)}/>}
</View>)}
</View>
</View>)}
</View>
)
})
export default kindeList

View File

@ -4,7 +4,10 @@ import styles from './index.module.scss'
import classnames from "classnames"; import classnames from "classnames";
//其他说明 //其他说明
export default memo(() => { type Param = {
onChange: (val: string) => void
}
export default memo(({onChange}:Param) => {
const [descData, setDescData] = useState({ const [descData, setDescData] = useState({
number: 0, number: 0,
value: '', value: '',
@ -18,6 +21,7 @@ export default memo(() => {
res = value.slice(0, descData.count) res = value.slice(0, descData.count)
} }
setDescData({...descData, number:res.length, value: res}) setDescData({...descData, number:res.length, value: res})
onChange?.(res)
} }
const toggleShowRealTextarea = (show) => { const toggleShowRealTextarea = (show) => {

View File

@ -3,39 +3,22 @@ import { ScrollView, Text, View } from "@tarojs/components";
import { memo, useMemo } from "react"; import { memo, useMemo } from "react";
import styles from './index.module.scss' import styles from './index.module.scss'
type ReasonParam = 1|2|3 //1 退货原因 2 货物状况 3 退货说明
//原因选择 //原因选择
type ReasonInfoParam = { type ReasonInfoParam = {
show?: boolean, show?: boolean,
onClose?: () => void, onClose?: () => void,
status: ReasonParam title?: string,
list?: {id:number, name:string}[]
} }
export default memo(({show = false, onClose, status}: ReasonInfoParam) => { export default memo(({show = false, onClose, title = '', list= []}: ReasonInfoParam) => {
const title = useMemo(() => {
if(status == 1) return '退货原因'
if(status == 2) return '货物状况'
if(status == 3) return '退货说明'
},[status])
return ( return (
<Popup showIconButton={false} show={show} title="申请退货" onClose={onClose} > <Popup showIconButton={false} show={show} title={title} onClose={onClose} >
<View className={styles.reason_return_con}> <View className={styles.reason_return_con}>
<View className={styles.reason_title}><Text>{title}</Text></View> <View className={styles.reason_title}><Text>{title}</Text></View>
<ScrollView scrollY className={styles.reason_scroll}> <ScrollView scrollY className={styles.reason_scroll}>
<View className={styles.reason_list}> <View className={styles.reason_list}>
<View className={styles.reason_item}></View> {list.map(item => <View key={item.id} className={styles.reason_item}>{item.name}</View> )}
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
</View> </View>
</ScrollView> </ScrollView>
</View> </View>

View File

@ -36,7 +36,7 @@
.returnSaleInput_item{ .returnSaleInput_item{
display: flex; display: flex;
align-items: center; align-items: center;
padding-bottom: 20px; padding-bottom: 30px;
flex-wrap: wrap; flex-wrap: wrap;
.title{ .title{
font-size: $font_size; font-size: $font_size;
@ -59,122 +59,10 @@
font-size: 30px; font-size: 30px;
} }
} }
.upload_image{
.uploadImg{
width: 202px;
height: 150px;
background: #f0f0f0;
border: 2px dashed #cccccc;
margin-left: 20px;
border-radius: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
margin-bottom: 20px;
position: relative;
.miconfont{
font-size: 50px;
}
.uploadText{
font-size: 26px;
color: $color_font_three;
}
}
.ImgItem{
width: 202px;
height: 150px;
background: #f0f0f0;
margin-left: 20px;
margin-bottom: 20px;
position: relative;
border-radius: 10px;
image{
width: 100%;
height: 100%;
border-radius: 10px;
}
.miconfont_close{
width: 30px;
height: 30px;
background-color: #ccc;
border-radius: 50%;
position: absolute;
right: -10px;
top: -10px;
text-align: center;
line-height: 30px;
color: #fff;
}
}
}
}
}
.apply_after_sales_list{
padding: 0 20px;
.apply_after_sales_item{
margin-bottom: 50px;
.apply_after_sales_title{
display: flex;
align-items: center;
.tag{
font-size: $font_size_min;
background-color: #CDE5FF;
padding: 5px 10px;
border-radius: 6px;
color: $color_main;
}
.title{
font-weight: 700;
font-size: $font_size;
margin-left: 20px;
flex:1; flex:1;
} }
} }
.color_list {
.color_item{
display: flex;
align-items: center;
margin: 20px 0;
}
.image{
width: 70px;
height: 70px;
image{
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.name_and_number{
padding-left: 30px;
flex:1;
text{
&:nth-child(1) {
font-weight: 700;
font-size: $font_size;
}
&:nth-child(2) {
color: $color_font_two;
font-size: $font_size;
margin-left: 20px;
}
}
}
.btn_count{
width: 235px;
height: 64px;
background-color: #ECF5FF;
border-radius: 40px 0px 16px 0px;
padding: 0 20px;
display: flex;
align-items: center;
}
}
} }
} }

View File

@ -1,61 +1,169 @@
import { Image, ScrollView, Text, Textarea, View } from "@tarojs/components"; import { Image, ScrollView, Text, View } from "@tarojs/components";
import { memo, useCallback, useMemo, useState } from "react"; import { FC, memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import classnames from "classnames"; import classnames from "classnames";
import styles from './index.module.scss' import styles from './index.module.scss'
import { formatImgUrl } from "@/common/fotmat";
import Counter from "@/components/counter";
import ReasonPopup from "./components/reasonPopup"; import ReasonPopup from "./components/reasonPopup";
import OtherReason from "./components/otherReason"; import OtherReason from "./components/otherReason";
import Taro from "@tarojs/taro"; import { useDidShow, useRouter } from "@tarojs/taro";
import useUploadCDNImg from "@/use/useUploadImage"; import { GetSaleOrderDetailApi } from "@/api/order";
import KindList from "./components/kindList"
import { ReturnApplyOrderApi, ReturnGoodsStatusApi } from "@/api/salesAfterOrder";
import { alert, goLink } from "@/common/common";
import UploadImage from "@/components/uploadImage"
import TextareaEnhance from "@/components/textareaEnhance";
type ReasonParam = 1|2|3 //1 退货原因 2 货物状况 3 退货说明 type ReasonParam = 1|2|3 //1 退货原因 2 货物状况 3 退货说明
export default () => { export default () => {
const [showDesc, setShowDesc] = useState(true)
useDidShow(() => {
getSaleOrderPreView()
})
const router = useRouter()
const orderId = useRef<number>(Number(router.params.id))
//需要提交的数据
const [submitData, setSubmitData] = useState<any>({
fabric_piece_accessory_url: [],
goods_status: 0,
reason_describe: '',
return_explain: 0,
return_reason: 1,
roll: 0,
roll_list: [],
sale_order_id: orderId.current
})
//获取订单数据
const [orderDetail, setOrderDetail] = useState<any>() //获取到的原始数据
const {fetchData: getOrderFetchData} = GetSaleOrderDetailApi()
const getSaleOrderPreView = async () => {
if(orderId.current) {
let res = await getOrderFetchData({id: orderId.current})
setOrderDetail(res.data)
}
}
//监听获取到的数据
useEffect(() => {
if(orderDetail) {
formatData()
}
}, [orderDetail])
//格式化数据格式
const [formatDetailOrder, setFormatDetailOrder] = useState<any>() //格式化后的数据
const formatData = () => {
setFormatDetailOrder({
sale_mode: orderDetail.sale_mode,
sale_mode_name: orderDetail.sale_mode_name,
total_colors: orderDetail.total_colors, //总颜色数量
total_number: orderDetail.total_number, //总数量
total_fabrics: orderDetail.total_fabrics, //面料数量
unit: orderDetail.sale_mode == 0?'条':'m', //单位
list: orderDetail.product_list,
status: orderDetail.status, //订单状态
})
}
//数据总量
const dataCount = useMemo(() => {
if(formatDetailOrder) {
return `${formatDetailOrder.total_fabrics}种面料,${formatDetailOrder.total_colors}种颜色,共${formatDetailOrder.total_number}`
}
}, [formatDetailOrder])
//退货选择弹窗 //退货选择弹窗
const [showReason, setShowReason] = useState<{show:true|false, status:ReasonParam}>({show:false, status:1}) const [showReason, setShowReason] = useState<{show:true|false, title: string}>({show:false, title: ''})
const closeReason = useCallback(() => setShowReason({...showReason, show:false}), []) const closeReason = useCallback(() => setShowReason({...showReason, show:false}), [])
const onShowReason = (status) => setShowReason({...showReason, status, show:true}) const onShowReason = (status) => {
setShowReason({...showReason, show:true})
}
//面料数据
let roll_list = useRef({})
//大货时获取计步器数据
const getNumChange = useCallback((val) => {
if(parseInt(val.number) > 0) {
roll_list.current[val.color_id] = {product_color_id: val.color_id, product_roll: val.number}
} else {
delete roll_list.current[val.color_id]
}
let count = 0
Object.values(roll_list.current).map((item: any) => {
count += item.product_roll
})
setSubmitData((e) => ({...e, roll_list:Object.values(roll_list.current), roll: count}))
}, [])
//散剪和剪板
const getSelectChange = useCallback((val) => {
console.log('val::', val)
if(val.status) {
roll_list.current[val.color_id] = {product_color_id: val.color_id, product_roll: val.length}
} else {
delete roll_list.current[val.color_id]
}
let count = 0
Object.values(roll_list.current).map((item: any) => {
count += item.product_roll
})
setSubmitData((e) => ({...e, roll_list:Object.values(roll_list.current), roll: count}))
}, [])
//获取图片列表
const getImageList = useCallback((list) => {
setSubmitData((e) => ({...e, fabric_piece_accessory_url:list}))
}, [])
//其他说明
const getOtherReason = useCallback((val) => {
setSubmitData((e) => ({...e, reason_describe: val}))
}, [])
//提交数据
const {fetchData: fetchDataReturnApply} = ReturnApplyOrderApi()
const onSubmitData = async () => {
if(submitData.roll_list.length <= 0) return alert.error('请选择退货颜色')
let res = await fetchDataReturnApply(submitData)
if(res.success) {
alert.success('申请成功')
goLink('/pages/salesAfterList/index',{}, 'reLaunch')
} else {
alert.error('申请失败')
}
console.log('提交::',submitData)
}
//底部按钮 //底部按钮
const onSubmit = (val) => { const onSubmit = (val) => {
if(val == 2) {
onSubmitData()
} }
}
const [returnGoodsInfo, setReturnGoodsInfo] = useState<{title:string, list: any[]}>({title:'', list:[]})
//售后货物状况
const {fetchData: fetchDataGoodsStatus} = ReturnGoodsStatusApi()
const getReturnGoodsStatus = async () => {
let res = await fetchDataGoodsStatus()
setReturnGoodsInfo((e) => ({...e, title: '售后货物状况', list:res.data?.list||[]}))
}
useEffect(() => {
getReturnGoodsStatus()
}, [])
return ( return (
<View className={styles.apply_after_sales_main}> <View className={styles.apply_after_sales_main}>
<View className={styles.apply_after_sales_con}> <View className={styles.apply_after_sales_con}>
<View className={styles.kind_number}><Text>236</Text></View> <View className={styles.kind_number}><Text>{dataCount}</Text></View>
<ScrollView scrollY className={styles.scroll}> <ScrollView scrollY className={styles.scroll}>
<View className={styles.scroll_con}> <View className={styles.scroll_con}>
<View className={styles.apply_after_sales_list}> <KindList order={formatDetailOrder} onNumChange={getNumChange} onSelectChange={getSelectChange}/>
{new Array(5).fill(5).map(item => <View className={styles.apply_after_sales_item}>
<View className={styles.apply_after_sales_title}>
<View className={styles.tag}></View>
<View className={styles.title}>0770# 21S单面平纹()</View>
</View>
<View className={styles.color_list}>
<View className={styles.color_item}>
<View className={styles.image}><Image src={formatImgUrl('')}/></View>
<View className={styles.name_and_number}><Text>1# 绿</Text><Text>x1</Text></View>
<View className={styles.btn_count}>
<Counter/>
</View>
</View>
<View className={styles.color_item}>
<View className={styles.image}><Image src={formatImgUrl('')}/></View>
<View className={styles.name_and_number}><Text>1# 绿</Text><Text>x1</Text></View>
<View className={styles.btn_count}>
<Counter/>
</View>
</View>
</View>
</View>)}
</View>
<View className={styles.returnSaleInput}> <View className={styles.returnSaleInput}>
<View className={styles.returnSaleInput_item}> <View className={styles.returnSaleInput_item}>
<View className={styles.title}>退</View> <View className={styles.title}>退</View>
@ -80,12 +188,14 @@ export default () => {
</View> </View>
<View className={styles.returnSaleInput_item}> <View className={styles.returnSaleInput_item}>
<View className={styles.title}></View> <View className={styles.title}></View>
<PictureItem/> <View className={styles.upload_image}>
<UploadImage onChange={getImageList}/>
</View>
</View>
<TextareaEnhance onChange={getOtherReason} title='其他说明'/>
</View>
</View> </View>
</View>
<OtherReason/>
</View>
</ScrollView> </ScrollView>
<View className="common_safe_area_y"></View> <View className="common_safe_area_y"></View>
</View> </View>
@ -95,28 +205,7 @@ export default () => {
<View className={styles.verify_btn } onClick={() => onSubmit(2)}></View> <View className={styles.verify_btn } onClick={() => onSubmit(2)}></View>
</View > </View >
</View > </View >
<ReasonPopup show={showReason.show} onClose={closeReason} status={showReason.status}/> <ReasonPopup show={showReason.show} onClose={closeReason} title={returnGoodsInfo.title} list={returnGoodsInfo.list}/>
</View> </View>
) )
} }
//图片列表
const PictureItem = memo(() => {
const {getWxPhoto} = useUploadCDNImg()
//图片
const uploadImage = async () => {
let res = await getWxPhoto('after-sale')
}
return (
<>
<View className={styles.ImgItem}>
<Image mode="aspectFill" src={formatImgUrl('')} ></Image>
<View className={classnames(styles.miconfont_close, 'iconfont icon-qingkong')}></View>
</View>
<View className={styles.uploadImg } onClick={uploadImage}>
<Text className={classnames(styles.miconfont, 'iconfont icon-saomazhifu')}></Text>
<Text className={styles.uploadText}></Text>
</View>
</>
)
})

View File

@ -0,0 +1,4 @@
export default {
navigationBarTitleText: '我的收藏',
enableShareAppMessage: true,
}

View File

View File

@ -0,0 +1,12 @@
import Search from "@/components/search"
import { View } from "@tarojs/components"
import styles from './index.module.scss'
export default () => {
return (
<View className={styles.main}>
<View className={styles.search}>
<Search style={{width: '100%'}} debounceTime={300} changeOnSearch={(e) => console.log(e)} placeholder="请输入面料关键词" placeIcon="out" showBtn={true} />
</View>
</View>
)
}

View File

@ -4,19 +4,25 @@
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
.reduce, .plus{ .plus{
font-size: $font_size_big;
color: $color_main; color: $color_main;
width: 46px; width: 46px;
height: 46px; height: 46px;
display: flex; text-align: center;
align-items: center; line-height: 43px;
justify-content:center;
font-size: 50px; font-size: 50px;
background-color: $color_main; background-color: $color_main;
color: #fff; color: #fff;
border-radius: 8px; border-radius: 8px;
} }
.reduce {
font-size: 50px;
width: 46px;
height: 46px;
text-align: center;
line-height: 43px;
color:#007AFF;
}
.input{ .input{
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
@ -25,10 +31,13 @@
box-sizing: border-box; box-sizing: border-box;
width: 106px; width: 106px;
border-radius: 10px; border-radius: 10px;
}
input{ input{
font-size: $font_size_medium; font-size: $font_size_medium;
text-align: right;
padding-right: 10px;
} }
}
.unit{ .unit{
font-size: $font_size_min; font-size: $font_size_min;
color: $color_font_two; color: $color_font_two;

View File

@ -72,6 +72,9 @@
padding-bottom:151px; padding-bottom:151px;
} }
.color_con{ .color_con{
.virtual_list{
padding-bottom: 300px;
}
.item { .item {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@ -16,6 +16,7 @@ import UseLogin from "@/use/useLogin"
import { formatHashTag, formatPriceDiv } from "@/common/fotmat"; import { formatHashTag, formatPriceDiv } from "@/common/fotmat";
import { debounce, getFilterData } from "@/common/util"; import { debounce, getFilterData } from "@/common/util";
import LabAndImg from "@/components/LabAndImg"; import LabAndImg from "@/components/LabAndImg";
import VirtualList from '@tarojs/components/virtual-list'
@ -49,20 +50,14 @@ export default memo(({show = false, onClose, title = '', productId = 0}: param)
//获取面料颜色列表 //获取面料颜色列表
const {fetchData:colorFetchData, state: colorState} = GetColorList() const {fetchData:colorFetchData, state: colorState} = GetColorList()
const [list, setList] = useState<any[]>([]) const [list, setList] = useState<any[]>([])
const [loading, setLoading] = useState(false)
const condition = useRef({physical_warehouse:adminUserInfo?.physical_warehouse, sale_mode:selectIndex, product_id:0, code_or_name:null}) const condition = useRef({physical_warehouse:adminUserInfo?.physical_warehouse, sale_mode:selectIndex, product_id:0, code_or_name:null})
const getColorList = async () => { const getColorList = async () => {
setLoading(() => true)
let {data} = await colorFetchData(getFilterData(condition.current)) let {data} = await colorFetchData(getFilterData(condition.current))
let lists = initList(data.list) let lists = initList(data.list)
setList(() => [...lists]) setList(() => [...lists])
setLoading(() => false)
} }
const [showPopup, setShowPopup] = useState(false) const [showPopup, setShowPopup] = useState(false)
useEffect(() => {
console.log('colorState::',colorState)
}, [colorState])
//显示获取 //显示获取
useEffect(() => { useEffect(() => {
@ -127,7 +122,10 @@ export default memo(({show = false, onClose, title = '', productId = 0}: param)
if(num == 0) item.show = false if(num == 0) item.show = false
setList([...list]) setList([...list])
console.log(num) console.log(num)
} }
const onAdd = (item) => { const onAdd = (item) => {
item.show = true item.show = true
item.count = selectList[selectIndex].defaultNum item.count = selectList[selectIndex].defaultNum
@ -198,10 +196,44 @@ export default memo(({show = false, onClose, title = '', productId = 0}: param)
return <View className={styles.priceText}><Text>¥</Text>{price}<Text> /{selectList[selectIndex].eunit}</Text></View> return <View className={styles.priceText}><Text>¥</Text>{price}<Text> /{selectList[selectIndex].eunit}</Text></View>
}, [selectIndex]) }, [selectIndex])
//虚拟滚动
const Rows = memo(({id, index, style, data}:any) => {
let item = data[index]
return (
<>
{item&&<View className={styles.item} key={item.id}>
<View className={styles.item_color}>
<LabAndImg value={{lab:item.lab,rgb:item.rgb,texture_url:item.texture_url}}/>
</View>
<View className={styles.item_con}>
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
<View className={styles.num}>
{formatPrice(item)}
</View>
</View>
<View className={styles.btn_con}>
{!item.show&&<View className={styles.btn} onClick={() => onAdd(item)}></View>
||<View className={styles.btn_count}>
<Counter
onBlue={(e) => getInputValue(e, item)}
defaultNum={item.count}
step={selectList[selectIndex].step}
digits={selectList[selectIndex].digits}
onClickBtn={(e) => getInputValue(e, item)}
unit={selectList[selectIndex].unit}
minNum={selectList[selectIndex].minNum}
maxNum={selectList[selectIndex].maxNum}
/>
</View>}
</View>
</View>||<View className={styles.item}></View>
}
</>
)
})
return ( return (
<View className={styles.shop_cart_main}> <View className={styles.shop_cart_main}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()} > <Popup showTitle={false} show={showPopup} onClose={() => closePopup()} >
<View className={styles.popup_con}> <View className={styles.popup_con}>
<View className={styles.header}>{title}</View> <View className={styles.header}>{title}</View>
@ -227,39 +259,53 @@ export default memo(({show = false, onClose, title = '', productId = 0}: param)
<View className={styles.product_color_con}> <View className={styles.product_color_con}>
{(list.length <= 0 && colorState.loading)&&<LoadingCard/>} {(list.length <= 0 && colorState.loading)&&<LoadingCard/>}
{(list.length > 0&& !colorState.loading)&& {(list.length > 0&& !colorState.loading)&&
// <InfiniteScroll moreStatus={false}>
<InfiniteScroll moreStatus={false}> // <View className={styles.color_con}>
// {list.map(item => {
// return <View className={styles.item} key={item.id}>
// <View className={styles.item_color}>
// <LabAndImg value={{lab:item.lab,rgb:item.rgb,texture_url:item.texture_url}}/>
// </View>
// <View className={styles.item_con}>
// <View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
// <View className={styles.num}>
// {formatPrice(item)}
// </View>
// </View>
// <View className={styles.btn_con}>
// {!item.show&&<View className={styles.btn} onClick={() => onAdd(item)}>添加</View>
// ||<View className={styles.btn_count}>
// <Counter
// onBlue={(e) => getInputValue(e, item)}
// defaultNum={item.count}
// step={selectList[selectIndex].step}
// digits={selectList[selectIndex].digits}
// onClickBtn={(e) => getInputValue(e, item)}
// unit={selectList[selectIndex].unit}
// minNum={selectList[selectIndex].minNum}
// maxNum={selectList[selectIndex].maxNum}
// />
// </View>}
// </View>
// </View>
// })}
// </View>
// </InfiniteScroll>}
<View className={styles.color_con}> <View className={styles.color_con}>
{list.map(item => { <VirtualList
return <View className={styles.item} key={item.id}> className={styles.virtual_list}
<View className={styles.item_color}> height={400} /* 列表的高度 */
<LabAndImg value={{lab:item.lab,rgb:item.rgb,texture_url:item.texture_url}}/> width='100%' /* 列表的宽度 */
</View> itemData={list} /* 渲染列表的数据 */
<View className={styles.item_con}> itemCount={list.length + 1} /* 渲染列表的长度 */
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View> itemSize={100} /* 列表单项的高度 */
<View className={styles.num}> overscanCount={1}
{formatPrice(item)} >
</View> {Rows}
</View> </VirtualList>
<View className={styles.btn_con}> <View className="common_safe_area_y"></View>
{!item.show&&<View className={styles.btn} onClick={() => onAdd(item)}></View>
||<View className={styles.btn_count}>
<Counter
onBlue={(e) => getInputValue(e, item)}
defaultNum={item.count}
step={selectList[selectIndex].step}
digits={selectList[selectIndex].digits}
onClickBtn={(e) => getInputValue(e, item)}
unit={selectList[selectIndex].unit}
minNum={selectList[selectIndex].minNum}
maxNum={selectList[selectIndex].maxNum}
/>
</View>} </View>}
</View>
</View>
})}
</View>
</InfiniteScroll>}
{(list.length <= 0 && !colorState.loading)&&<View className={styles.noData}></View>} {(list.length <= 0 && !colorState.loading)&&<View className={styles.noData}></View>}
</View> </View>
<View className={styles.buy_btn}> <View className={styles.buy_btn}>

View File

@ -80,9 +80,10 @@ export default (props:Params) => {
const [showCart, setShowCart] = useState(false) const [showCart, setShowCart] = useState(false)
const [showOrderCount, setShowOrderCount] = useState(false) const [showOrderCount, setShowOrderCount] = useState(false)
const html = ` // const html = `
<img style="width:100%" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic24.nipic.com%2F20121021%2F10910884_100200815001_2.jpg&refer=http%3A%2F%2Fpic24.nipic.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652257920&t=9353dda34f18ae2fe6803f3da35954bb"> // <img style="width:100%" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic24.nipic.com%2F20121021%2F10910884_100200815001_2.jpg&refer=http%3A%2F%2Fpic24.nipic.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652257920&t=9353dda34f18ae2fe6803f3da35954bb">
` // `
const html = ``
//弹窗提示 //弹窗提示
const [colorInfo, setColorInfo] = useState<colorItem>() const [colorInfo, setColorInfo] = useState<colorItem>()
@ -117,6 +118,7 @@ export default (props:Params) => {
//授权手机号和下单 //授权手机号和下单
const placeOrder = async (status = 'to_phone',e:any = {}) => { const placeOrder = async (status = 'to_phone',e:any = {}) => {
if(!productInfo.id) return false
if(status == 'to_phone') { if(status == 'to_phone') {
if(!e.detail.code) return alert.error('请授权手机号') if(!e.detail.code) return alert.error('请授权手机号')
try { try {

View File

@ -80,6 +80,9 @@
box-sizing: border-box; box-sizing: border-box;
padding-bottom: constant(safe-area-inset-bottom); padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);
.submit_order_number{
padding: 20px 0;
}
.order_btn { .order_btn {
width: 250px; width: 250px;
height: 90px; height: 90px;

View File

@ -1,15 +1,12 @@
import { SaleOrderPreViewApi, SaleOrderApi } from "@/api/order"; import { SaleOrderPreViewApi, SaleOrderApi } from "@/api/order";
import { formatPriceDiv } from "@/common/fotmat"; import { formatPriceDiv } from "@/common/fotmat";
import Popup from "@/components/popup"; import Popup from "@/components/popup";
import SearchInput from "@/components/searchInput"; import { View } from "@tarojs/components"
import { Text, Textarea, View } from "@tarojs/components" import Taro, { useDidShow, usePullDownRefresh} from "@tarojs/taro";
import Taro, { useDidShow, useRouter } from "@tarojs/taro";
import classnames from "classnames"; import classnames from "classnames";
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import AddressInfo,{AddressInfoParam} from "./components/addressInfo"; import AddressInfo from "./components/addressInfo";
import EstimatedAmount from "./components/estimatedAmount";
import KindList from "./components/kindList"; import KindList from "./components/kindList";
import OrderState from "./components/orderState";
import Remark from "./components/remark"; import Remark from "./components/remark";
import styles from './comfirm.module.scss' import styles from './comfirm.module.scss'
import { getParam } from "@/common/system"; import { getParam } from "@/common/system";
@ -17,9 +14,9 @@ import useLogin from "@/use/useLogin";
import { alert, goLink } from "@/common/common"; import { alert, goLink } from "@/common/common";
import ShipmentMode from "../editOrder/components/shipmentMode"; import ShipmentMode from "../editOrder/components/shipmentMode";
import SubmitOrderBtn from "./components/submitOrderBtn"; import SubmitOrderBtn from "./components/submitOrderBtn";
import AddressInfoDetail from "./components/addressInfoDetail";
export default () => { export default () => {
const {checkLogin} = useLogin()
const [showDesc, setShowDesc] = useState(false) const [showDesc, setShowDesc] = useState(false)
//下单信息 //下单信息
@ -57,8 +54,7 @@ import SubmitOrderBtn from "./components/submitOrderBtn";
if(preViewOrder) { if(preViewOrder) {
formatData() formatData()
getDataList() getDataList()
//当有默认地址时设置默认地址id setSubmitOrderData((val) => ({...val, address_id:preViewOrder.default_address.id, shipment_mode:preViewOrder.shipment_mode||2}))
preViewOrder.default_address&&setSubmitOrderData((val) => ({...val, address_id:preViewOrder.default_address.id}))
} }
}, [preViewOrder]) }, [preViewOrder])
@ -74,7 +70,8 @@ import SubmitOrderBtn from "./components/submitOrderBtn";
total_fabrics: preViewOrder.total_fabrics, //面料数量 total_fabrics: preViewOrder.total_fabrics, //面料数量
unit: preViewOrder.sale_mode == 0?'条':'m', //单位 unit: preViewOrder.sale_mode == 0?'条':'m', //单位
list: preViewOrder.product_list, list: preViewOrder.product_list,
total_should_collect_money: preViewOrder.total_should_collect_money //应收金额 total_should_collect_money: preViewOrder.total_should_collect_money, //应收金额
total_sale_price: preViewOrder.total_sale_price //合计金额
}) })
} }
const formatPreViewOrderMemo = useMemo(() => { const formatPreViewOrderMemo = useMemo(() => {
@ -84,18 +81,16 @@ import SubmitOrderBtn from "./components/submitOrderBtn";
//格式化初始地址 //格式化初始地址
const defaultAddress = useMemo(() => { const defaultAddress = useMemo(() => {
const address = preViewOrder?.default_address const address = preViewOrder?.default_address
if(address) {
return { return {
province_name: address.province_name, province_name: address?.province_name,
city_name: address.city_name, city_name: address?.city_name,
district_name: address.district_name, district_name: address?.district_name,
address_detail: address.address_detail, address_detail: address?.address_detail,
id: address.id, id: address?.id,
name: address.name, name: address?.name,
phone: address.phone phone: address?.phone,
shipment_mode: address?.shipment_mode
} }
}
return null
}, [preViewOrder]) }, [preViewOrder])
//获取提交格式数据列表 //获取提交格式数据列表
@ -126,24 +121,29 @@ import SubmitOrderBtn from "./components/submitOrderBtn";
//提交按钮是否可用 //提交按钮是否可用
const btnStatus = useMemo(() => { const btnStatus = useMemo(() => {
if( submitOrderData?.list?.length == 0 || !submitOrderData?.shipment_mode || (submitOrderData?.shipment_mode == 2 && !submitOrderData?.address_id)) { return submitOrderData?.shipment_mode == 1 || (submitOrderData?.shipment_mode == 2 && submitOrderData?.address_id)
return false
} else {
return true
}
}, [submitOrderData]) }, [submitOrderData])
//数量格式
const numText = useMemo(() => {
if(formatPreViewOrder) {
let total_number = formatPreViewOrder?.sale_mode == 0?formatPreViewOrder?.total_number:(formatPreViewOrder?.total_number/100)
return `${formatPreViewOrder?.total_fabrics}种面料,${formatPreViewOrder?.total_colors}种颜色,共${total_number}${formatPreViewOrder?.unit}`
}
}, [formatPreViewOrder])
//提交订单 //提交订单
const {fetchData: saleOrderFetchData} = SaleOrderApi() const {fetchData: saleOrderFetchData} = SaleOrderApi()
const submitOrderEven = () => { const submitOrderEven = () => {
if(!submitOrderData?.address_id) {
alert.error('请选择地址')
return false
}
if(!submitOrderData?.shipment_mode) { if(!submitOrderData?.shipment_mode) {
alert.error('请选择收货方式') alert.error('请选择收货方式')
return false return false
} }
if(!submitOrderData?.address_id&&submitOrderData?.shipment_mode == 2) {
alert.error('请选择地址')
return false
}
Taro.showModal({ Taro.showModal({
title: '确定提交?', title: '确定提交?',
success: async function (res) { success: async function (res) {
@ -160,10 +160,14 @@ import SubmitOrderBtn from "./components/submitOrderBtn";
} }
}) })
} }
//页面下拉刷新
usePullDownRefresh(() => {
getSaleOrderPreView()
})
return ( return (
<View className={styles.order_main}> <View className={styles.order_main}>
<ShipmentMode onSelect={selectShipmentMode}/> <AddressInfoDetail orderInfo={defaultAddress} onSelect={getAddress} onChangeShipmentMode={selectShipmentMode} status={1}/>
<AddressInfo onSelect={(e) => getAddress(e)} defaultValue={defaultAddress}/>
<KindList order={formatPreViewOrderMemo} comfirm={true}/> <KindList order={formatPreViewOrderMemo} comfirm={true}/>
<View className={styles.order_desc} onClick={() => setShowDesc(true)}> <View className={styles.order_desc} onClick={() => setShowDesc(true)}>
<View className={styles.order_desc_con}></View> <View className={styles.order_desc_con}></View>
@ -176,7 +180,7 @@ import SubmitOrderBtn from "./components/submitOrderBtn";
<View className={styles.submit_order}> <View className={styles.submit_order}>
<View className={styles.submit_order_number}> <View className={styles.submit_order_number}>
<SubmitOrderBtn style={{color:'#007AFF'}} number={formatPriceDiv(preViewOrder?.sale_mode == 1?formatPreViewOrder?.total_should_collect_money:formatPreViewOrder?.estimate_amount)} priceTitle={preViewOrder?.sale_mode == 1?'合计金额':'预估金额'}/> <SubmitOrderBtn style={{color:'#007AFF'}} number={formatPriceDiv(preViewOrder?.sale_mode == 1?formatPreViewOrder?.total_should_collect_money:formatPreViewOrder?.estimate_amount)} priceTitle={preViewOrder?.sale_mode == 1?'合计金额':'预估金额'}/>
<View className={styles.order_number_desc}>{`${formatPreViewOrder?.total_fabrics}种面料,${formatPreViewOrder?.total_colors}种颜色,共${formatPreViewOrder?.total_number + formatPreViewOrder?.unit}`}</View> <View className={styles.order_number_desc}>{numText}</View>
</View> </View>
<View className={classnames(styles.order_btn, btnStatus&&styles.ok_order_btn)} onClick={() => submitOrderEven()}></View> <View className={classnames(styles.order_btn, btnStatus&&styles.ok_order_btn)} onClick={() => submitOrderEven()}></View>
</View> </View>

View File

@ -0,0 +1,163 @@
import { EditSaleOrderAddressApi, EditSaleOrderShipmentModeApi } from "@/api/order";
import { alert } from "@/common/common";
import { ORDER_STATUS } from "@/common/enum";
import { debounce } from "@/common/util";
import AddressList from "@/components/AddressList";
import Popup from "@/components/popup";
import { Text, View } from "@tarojs/components"
import classnames from "classnames";
import { forwardRef, memo, useEffect, useImperativeHandle, useMemo, useState } from "react";
import styles from './index.module.scss'
export type AddressInfoParam = {
province_name: string,
city_name: string,
district_name: string,
address_detail: string,
id?: number,
name: string,
phone: string,
}
type Param = {
onSelect?: (val:any) => void, //选择地址
defaultValue?: AddressInfoParam|null, //默认值
disabled?: false|true, //true禁用后只用于展示
onChangeShipmentMode?: (val: number) => void, //返回收货方式
status?: 1|2, //1确认订单时使用 2订单流程
orderInfo?: {
orderId: number //订单id
shipment_mode: 1|2, //1自提 2物流
status: number //订单状态
}
}
export default memo(forwardRef(({onSelect, onChangeShipmentMode, defaultValue = null, orderInfo, status = 2}: Param, ref) => {
const [showAddressList, setShowAddressList] = useState(false)
useEffect(() => {
setUserInfo(() => defaultValue)
}, [defaultValue])
const [userInfo, setUserInfo] = useState<any>()
//地址格式
const formatAddress = useMemo(() => {
if(userInfo)
return userInfo.province_name + userInfo.city_name + userInfo.district_name + userInfo.address_detail
}, [userInfo])
const changeShow = () => {
if(receivingStatus == 2 && !logisticsShow)
setShowAddressList(() => true)
}
useEffect(() => {
if(orderInfo)
setReceivingStatus(() => orderInfo.shipment_mode||2)
}, [orderInfo])
//把内部方法提供给外部
useImperativeHandle(ref, () => ({
changeShow
}))
//收货方法,1:自提2物流
const [receivingStatus, setReceivingStatus] = useState(2)
const {fetchData: shipmentModeFetchData} = EditSaleOrderShipmentModeApi()
const onReceivingStatus = (value, e) => {
e.stopPropagation()
changeReceivingStatus(value)
}
const changeReceivingStatus = debounce(async (value) => {
if(!orderInfo) return false
if(status == 1) {
onChangeShipmentMode?.(value)
setReceivingStatus(value)
return false
}
alert.loading('正在修改')
const res = await shipmentModeFetchData({id: orderInfo.orderId, shipment_mode:value})
if(res.success) {
alert.success('收货方式修改成功')
onChangeShipmentMode?.(value)
setReceivingStatus(value)
} else {
alert.none(res.msg)
}
}, 10)
//修改地址
const [addressId, setAddressId] = useState(0)
const {fetchData: addressFetchData} = EditSaleOrderAddressApi()
const getAddress = async (value) => {
if(!orderInfo) return false
if(status == 1) {
setShowAddressList(() => false)
setAddressId(value.id)
setUserInfo(() => value)
return false
}
alert.loading('正在修改')
const res = await addressFetchData({id: orderInfo.orderId, address_id: value.id})
if(res.success) {
alert.success('地址修改成功')
onSelect?.(value)
setShowAddressList(() => false)
setAddressId(value.id)
setUserInfo(() => value)
} else {
alert.none(res.msg)
}
}
//订单状态
const {
SaleOrderStatusWaitingReceipt,
SaleOrderStatusAlreadyReceipt,
SaleOrderStatusComplete,
SaleOrderStatusRefund,
SaleOrderStatusCancel
} = ORDER_STATUS
//根据订单状态判断是否显示物流
const logisticsShowList = [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value]
const logisticsShow = useMemo(() => {
return logisticsShowList.includes(orderInfo?.status as number)
}, [orderInfo])
return (
<View>
<View className={styles.order_address} onClick={() => changeShow()}>
<View className={classnames(styles.order_address_icon, 'iconfont', receivingStatus == 2?'icon-daohang':'icon-fahuo')}></View>
<View className={styles.order_address_text_con}>
<View className={styles.order_address_text_title}>
<Text className={styles.address_text}>{formatAddress}</Text>
{(receivingStatus == 2 && !logisticsShow)&&<Text className={classnames(styles.moreIconfont,'iconfont icon-a-moreback')}></Text>}
</View>
<View className={styles.order_address_text_name}>
<Text>{userInfo?.name}</Text>
<Text>{userInfo?.phone}</Text>
</View>
</View>
{!logisticsShow&&<View className={styles.updateBtn}>
<View className={styles.updateBtn_list}>
<View className={classnames(styles.updateBtn_item, receivingStatus==1&&styles.updateBtn_item_select)} onClick={(e) => onReceivingStatus(1,e)}></View>
<View className={classnames(styles.updateBtn_item, receivingStatus==2&&styles.updateBtn_item_select)} onClick={(e) => onReceivingStatus(2,e)}></View>
</View>
<View style={{transform: receivingStatus==1?'translateX(0)':'translateX(100%)'}} className={classnames(styles.updateBtn_select)}></View>
</View>||
<View className={styles.logisticsBtn}>
</View>}
</View>
<Popup show={showAddressList} showTitle={false} onClose={() => setShowAddressList(false)}>
<View className={styles.order_address_list}>
<View className={styles.order_address_title}></View>
<View className={styles.addressList_con}>
<AddressList onSelect={getAddress} id={addressId}/>
</View>
</View>
</Popup>
</View>
)
}))

View File

@ -33,6 +33,11 @@
} }
.address_text{ .address_text{
word-break:break-all; word-break:break-all;
}
.address_text_no{
font-weight: 700;
padding-left: 20px;
} }
} }
.order_address_text_name{ .order_address_text_name{

View File

@ -20,48 +20,55 @@ export type AddressInfoParam = {
} }
type Param = { type Param = {
onSelect?: (val:any) => void, //选择地址 onSelect?: (val:any) => void, //选择地址
defaultValue?: AddressInfoParam|null, //默认值
disabled?: false|true, //true禁用后只用于展示 disabled?: false|true, //true禁用后只用于展示
onChangeShipmentMode?: (val: number) => void, //返回收货方式 onChangeShipmentMode?: (val: number) => void, //返回收货方式
onLogistics?: () => void, //查看物流
status?: 1|2, //1确认订单时使用 2订单流程
orderInfo?: { orderInfo?: {
orderId: number //订单id id?: number //订单id
shipment_mode: 1|2, //1自提 2物流 shipment_mode?: 1|2, //1自提 2物流
status: number //订单状态 status?: number //订单状态
province_name: string,
city_name: string,
district_name: string,
address_detail: string
} }
} }
export default memo(forwardRef(({onSelect, onChangeShipmentMode, defaultValue = null, orderInfo}: Param, ref) => { export default memo(forwardRef(({onSelect, onChangeShipmentMode, orderInfo, status = 2, disabled = false, onLogistics}: Param, ref) => {
const [showAddressList, setShowAddressList] = useState(false)
const [addressInfo, setAddressInfo] = useState<any>()
useEffect(() => { useEffect(() => {
setUserInfo(() => defaultValue) if(orderInfo) {
}, [defaultValue]) setReceivingStatus(() => orderInfo.shipment_mode||2)
setAddressInfo(() => orderInfo)
}
}, [orderInfo])
const [userInfo, setUserInfo] = useState<any>()
//地址格式 //地址格式
const formatAddress = useMemo(() => { const formatAddress = useMemo(() => {
if(userInfo) if(addressInfo?.province_name) {
return userInfo.province_name + userInfo.city_name + userInfo.district_name + userInfo.address_detail return addressInfo.province_name + addressInfo.city_name + addressInfo.district_name + addressInfo.address_detail
}, [userInfo]) } else {
return ''
}
}, [addressInfo])
//打开地址列表
const [showAddressList, setShowAddressList] = useState(false)
const changeShow = () => { const changeShow = () => {
if(receivingStatus == 2 && !logisticsShow) if(receivingStatus == 2 && !logisticsShow)
setShowAddressList(() => true) setShowAddressList(() => true)
} }
useEffect(() => {
if(orderInfo)
setReceivingStatus(() => orderInfo.shipment_mode)
}, [orderInfo])
//把内部方法提供给外部 //把内部方法提供给外部
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
changeShow changeShow
})) }))
//收货方法,1:自提2物流 //收货方法,1:自提2物流
const [receivingStatus, setReceivingStatus] = useState(1) const [receivingStatus, setReceivingStatus] = useState(2)
const {fetchData: shipmentModeFetchData} = EditSaleOrderShipmentModeApi() const {fetchData: shipmentModeFetchData} = EditSaleOrderShipmentModeApi()
const onReceivingStatus = (value, e) => { const onReceivingStatus = (value, e) => {
e.stopPropagation() e.stopPropagation()
@ -69,8 +76,13 @@ export default memo(forwardRef(({onSelect, onChangeShipmentMode, defaultValue =
} }
const changeReceivingStatus = debounce(async (value) => { const changeReceivingStatus = debounce(async (value) => {
if(!orderInfo) return false if(!orderInfo) return false
if(status == 1) {
onChangeShipmentMode?.(value)
setReceivingStatus(value)
return false
}
alert.loading('正在修改') alert.loading('正在修改')
const res = await shipmentModeFetchData({id: orderInfo.orderId, shipment_mode:value}) const res = await shipmentModeFetchData({id: orderInfo.id, shipment_mode:value})
if(res.success) { if(res.success) {
alert.success('收货方式修改成功') alert.success('收货方式修改成功')
onChangeShipmentMode?.(value) onChangeShipmentMode?.(value)
@ -85,14 +97,21 @@ export default memo(forwardRef(({onSelect, onChangeShipmentMode, defaultValue =
const {fetchData: addressFetchData} = EditSaleOrderAddressApi() const {fetchData: addressFetchData} = EditSaleOrderAddressApi()
const getAddress = async (value) => { const getAddress = async (value) => {
if(!orderInfo) return false if(!orderInfo) return false
if(status == 1) {
setShowAddressList(() => false)
setAddressId(value.id)
setAddressInfo(() => value)
onSelect?.(value)
return false
}
alert.loading('正在修改') alert.loading('正在修改')
const res = await addressFetchData({id: orderInfo.orderId, address_id: value.id}) const res = await addressFetchData({id: orderInfo.id, address_id: value.id})
if(res.success) { if(res.success) {
alert.success('地址修改成功') alert.success('地址修改成功')
onSelect?.(value) onSelect?.(value)
setShowAddressList(() => false) setShowAddressList(() => false)
setAddressId(value.id) setAddressId(value.id)
setUserInfo(() => value) setAddressInfo(() => value)
} else { } else {
alert.none(res.msg) alert.none(res.msg)
} }
@ -104,12 +123,14 @@ export default memo(forwardRef(({onSelect, onChangeShipmentMode, defaultValue =
SaleOrderStatusAlreadyReceipt, SaleOrderStatusAlreadyReceipt,
SaleOrderStatusComplete, SaleOrderStatusComplete,
SaleOrderStatusRefund, SaleOrderStatusRefund,
SaleOrderStatusCancel SaleOrderStatusCancel,
} = ORDER_STATUS } = ORDER_STATUS
//根据订单状态判断是否显示物流 //根据订单状态判断是否显示物流
const logisticsShowList = [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value] const logisticsShowList = [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value]
const logisticsShow = useMemo(() => { const logisticsShow = useMemo(() => {
console.log('aa:',orderInfo?.status)
return logisticsShowList.includes(orderInfo?.status as number) return logisticsShowList.includes(orderInfo?.status as number)
}, [orderInfo]) }, [orderInfo])
@ -119,12 +140,12 @@ export default memo(forwardRef(({onSelect, onChangeShipmentMode, defaultValue =
<View className={classnames(styles.order_address_icon, 'iconfont', receivingStatus == 2?'icon-daohang':'icon-fahuo')}></View> <View className={classnames(styles.order_address_icon, 'iconfont', receivingStatus == 2?'icon-daohang':'icon-fahuo')}></View>
<View className={styles.order_address_text_con}> <View className={styles.order_address_text_con}>
<View className={styles.order_address_text_title}> <View className={styles.order_address_text_title}>
<Text className={styles.address_text}>{formatAddress}</Text> <Text className={classnames(styles.address_text, styles.address_text_no)}>{formatAddress||'请选择收货地址及信息'}</Text>
{(receivingStatus == 2 && !logisticsShow)&&<Text className={classnames(styles.moreIconfont,'iconfont icon-a-moreback')}></Text>} {(receivingStatus == 2 && !logisticsShow)&&<Text className={classnames(styles.moreIconfont,'iconfont icon-a-moreback')}></Text>}
</View> </View>
<View className={styles.order_address_text_name}> <View className={styles.order_address_text_name}>
<Text>{userInfo?.name}</Text> <Text>{addressInfo?.name}</Text>
<Text>{userInfo?.phone}</Text> <Text>{addressInfo?.phone}</Text>
</View> </View>
</View> </View>
{!logisticsShow&&<View className={styles.updateBtn}> {!logisticsShow&&<View className={styles.updateBtn}>
@ -134,7 +155,7 @@ export default memo(forwardRef(({onSelect, onChangeShipmentMode, defaultValue =
</View> </View>
<View style={{transform: receivingStatus==1?'translateX(0)':'translateX(100%)'}} className={classnames(styles.updateBtn_select)}></View> <View style={{transform: receivingStatus==1?'translateX(0)':'translateX(100%)'}} className={classnames(styles.updateBtn_select)}></View>
</View>|| </View>||
<View className={styles.logisticsBtn}> <View className={styles.logisticsBtn} onClick={onLogistics}>
</View>} </View>}
</View> </View>

View File

@ -0,0 +1,66 @@
.apply_after_sales_con{
padding: 20px;
.returnSaleInput_item{
display: flex;
align-items: center;
padding-bottom: 50px;
flex-wrap: wrap;
.title{
font-size: $font_size;
font-weight: 700;
width: 119px;
}
.select{
flex:1;
height: 60px;
border: 2px solid #e6e6e6;
border-radius: 10px;
margin-left: 20px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
font-size: 26px;
color: $color_font_two;
.miconfont{
font-size: 30px;
}
}
.upload_image{
flex:1;
}
}
.btns_con{
width: 100%;
bottom:0;
box-sizing: border-box;
margin-top: 50px;
.btns_two{
display: flex;
height: 82px;
// border: 1PX solid #007aff;
font-size: $font_size_big;
border-radius: 40px;
margin-bottom: 20px;
.rest_btn{
flex:1;
border: 1PX solid #007aff;
border-radius: 40px 0 0 40px;
text-align: center;
line-height: 82px;
color: $color_main;
background-color: #fff;
}
.verify_btn{
flex:1;
border-radius: 0 40px 40px 0;
background: #007aff;
text-align: center;
line-height: 82px;
color: #fff;
}
}
}
}

View File

@ -0,0 +1,57 @@
import Popup from "@/components/popup";
import TextareaEnhance from "@/components/textareaEnhance";
import { ScrollView, Text, View } from "@tarojs/components";
import { memo, useCallback, useState } from "react";
import ReasonPopup from "../reasonPopup";
import styles from './index.module.scss'
import classnames from "classnames";
type Param = {
show?: true|false,
onClose?: () => void
}
export default memo(({show, onClose}:Param) => {
const getOtherReason = useCallback(() => {
}, [])
const onSubmit = (val) => {
}
//显示说明
const [showReason, setShowReason] = useState(false)
const closeReason = useCallback(() => {
setShowReason(false)
}, [])
const onShowReason = () => {
setShowReason(true)
}
return (
<>
<Popup show={show} title="申请退款" onClose={onClose} >
<View className={styles.apply_after_sales_con}>
<View className={styles.returnSaleInput_item}>
<View className={styles.title}>退</View>
<View className={styles.select} onClick={() => onShowReason()}>
<Text></Text>
<Text className={classnames(styles.miconfont, 'iconfont icon-a-moreback')}></Text>
</View>
</View>
<TextareaEnhance onChange={getOtherReason} title='备注' placeholder="请输入退款备注"/>
<View className={styles.btns_con}>
<View className={styles.btns_two}>
<View className={styles.rest_btn} onClick={() => onSubmit(1)}></View>
<View className={styles.verify_btn } onClick={() => onSubmit(2)}></View>
</View >
</View>
</View>
</Popup>
<ReasonPopup show={showReason} onClose={closeReason} />
</>
)
})

View File

@ -0,0 +1,190 @@
import { ORDER_STATUS } from "@/common/enum"
import { formatHashTag, formatPriceDiv } from "@/common/fotmat"
import LabAndImg from "@/components/LabAndImg"
import { View } from "@tarojs/components"
import { memo, useCallback, useMemo } from "react"
import EstimatedAmount from "../estimatedAmount"
import styles from './index.module.scss'
type OrderParam = {
estimate_amount: number, //预估金额
list: any[],
sale_mode: number,
sale_mode_name: string,
unit: string,
total_colors: number,
total_fabrics: number,
total_number: number,
status: number, //订单状态
total_sale_price: number, //销售金额
total_should_collect_money: number, //应收金额
total_weight_error_discount: number, //空差优惠
the_previous_status: number, //取消订单时的订单状态
actual_amount: number //实付金额
}
type Param = {
order: OrderParam,
comfirm?: boolean //是否是确认订单页面使用
}
export default memo(({order, comfirm = false}:Param) => {
//对应数量
const formatCount = useCallback((item) => {
return order?.sale_mode == 0? item.roll : Number(item.length / 100)
}, [order])
//对应单价
const standardPrice = useCallback(price => {
return formatPriceDiv(price).toLocaleString() + '/' + (order?.sale_mode == 1?'m':'kg')
}, [order])
//数量格式
const numText = useMemo(() => {
if(order) {
let total_number = order?.sale_mode == 0?order?.total_number:(order?.total_number/100)
return `${order?.total_fabrics}种面料,${order?.total_colors}种颜色,共${total_number}${order?.unit}`
}
}, [order])
const {
SaleOrderStatusBooking, // 待接单
SaleOrderStatusArranging, // 配布中
SaleOrderStatusArranged, // 已配布
SaleOrderStatusWaitingPayment, // 待付款
SaleOrderStatusWaitingDelivery, // 待发货
SaleOrderStatusWaitingReceipt, // 待收货
SaleOrderStatusAlreadyReceipt, // 已收货
SaleOrderStatusComplete, // 已完成
SaleOrderStatusRefund, // 已退款
SaleOrderStatusCancel, // 已取消
SaleorderstatusWaitingPrePayment // 预付款
} = ORDER_STATUS
//金额列表枚举
const priceList = [
{
id:1,
value:[SaleorderstatusWaitingPrePayment.value, SaleOrderStatusBooking.value, SaleOrderStatusArranging.value, ],
label:'预估金额',
field: 'estimate_amount'
},
{
id:2,
value:[SaleorderstatusWaitingPrePayment.value, SaleOrderStatusArranged.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value],
label:'合计金额',
field: 'total_sale_price'
},
{
id:3,
value:[SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value],
label:'空差优惠',
field: 'total_weight_error_discount'
},
{
id:4,
value:[ SaleOrderStatusWaitingPayment.value],
label:'应付金额',
field: 'total_should_collect_money'
},
{
id:5,
value:[SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value],
label:'实付金额',
field: 'actual_amount'
}
]
//是否显示价格
const showPrice = useCallback((priceInfo, status) => {
return priceInfo.value.includes(status)
}, [order])
//金额展示大货
const priceConDom = useMemo(() => {
if(!order) return
if(comfirm == true) {
//确认订单时
return <EstimatedAmount number={formatPriceDiv(order.estimate_amount)} title="预估金额" />
}
if(order?.status == SaleOrderStatusCancel.value) {
//订单状态为取消订单时
return (
<>
{
priceList.map(item => {
return <>{showPrice(item, order?.the_previous_status)&&<EstimatedAmount key={item.id} number={formatPriceDiv(order[item.field])} title={item.label} />}</>
})
}
</>
)
} else {
//其他订单状态
return (
<>
{
priceList.map(item => {
return <>{showPrice(item, order?.status)&&<EstimatedAmount key={item.id} number={formatPriceDiv(order[item.field])} title={item.label} />}</>
})
}
</>
)
}
}, [order])
//金额展示剪板
const cutPriceConDom = useMemo(() => {
if(!order) return
return <EstimatedAmount number={formatPriceDiv(order.total_should_collect_money)} title="合计金额" />
}, [order])
const showPriceAll = useMemo(() => {
if(order?.sale_mode == 1) {
return cutPriceConDom //剪板
} else {
return priceConDom //大货
}
}, [order])
return (
<>
<View className={styles.orders_list_title}>{numText}</View>
<View className={styles.orders_list_con}>
{
order?.list?.map(item => {
return <View key={item.product_code} className={styles.order_list}>
<View className={styles.order_list_title}>
<View className={styles.tag}>{order.sale_mode_name}</View>
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
<View className={styles.num}>{item?.product_colors.length}</View>
</View>
<View className={styles.order_list_scroll}>
{item?.product_colors?.map(colorItem => {
return <View key={colorItem.id} className={styles.order_list_item}>
<View className={styles.order_list_item_img}>
<LabAndImg value={{lab:item.lab,rgb:item.rgb,texture_url:item.texture_url}}/>
</View>
<View className={styles.order_list_item_con}>
<View className={styles.order_list_item_des}>
<View className={styles.order_list_item_title}>{colorItem.code + ' ' + colorItem.name}</View>
<View className={styles.order_list_item_price}>¥{standardPrice(colorItem.sale_price)}</View>
</View>
<View className={styles.order_list_item_count}>
<View className={styles.count_num}>×{formatCount(colorItem)}<text>{order.unit}</text></View>
<View className={styles.count_price}><text>¥</text>{formatPriceDiv(colorItem.estimate_amount).toLocaleString()}</View>
</View>
</View>
</View>
})}
</View>
</View>
})
}
<View className={styles.order_estimated_amount}>
{showPriceAll}
</View>
</View>
</>
)
})

View File

@ -66,9 +66,14 @@
font-size: $font_size; font-size: $font_size;
margin-bottom: 15px; margin-bottom: 15px;
} }
.order_list_item_price{ .order_list_item_price, .order_list_item_price_dg{
font-size: 26px; font-size: 26px;
color: $color_font_three; color: $color_font_three;
display: flex;
align-items: center;
Text{
padding-left: 13px;
}
} }
} }
.order_list_item_count{ .order_list_item_count{

View File

@ -1,7 +1,7 @@
import { ORDER_STATUS } from "@/common/enum" import { ORDER_STATUS } from "@/common/enum"
import { formatHashTag, formatPriceDiv } from "@/common/fotmat" import { formatHashTag, formatPriceDiv, formatWeightDiv } from "@/common/fotmat"
import LabAndImg from "@/components/LabAndImg" import LabAndImg from "@/components/LabAndImg"
import { View } from "@tarojs/components" import { Text, View } from "@tarojs/components"
import { memo, useCallback, useMemo } from "react" import { memo, useCallback, useMemo } from "react"
import EstimatedAmount from "../estimatedAmount" import EstimatedAmount from "../estimatedAmount"
import styles from './index.module.scss' import styles from './index.module.scss'
@ -16,7 +16,7 @@ type OrderParam = {
total_fabrics: number, total_fabrics: number,
total_number: number, total_number: number,
status: number, //订单状态 status: number, //订单状态
total_sale_price: number, //销售金额 total_sale_price: number, //合计金额
total_should_collect_money: number, //应收金额 total_should_collect_money: number, //应收金额
total_weight_error_discount: number, //空差优惠 total_weight_error_discount: number, //空差优惠
the_previous_status: number, //取消订单时的订单状态 the_previous_status: number, //取消订单时的订单状态
@ -57,20 +57,21 @@ export default memo(({order, comfirm = false}:Param) => {
SaleOrderStatusComplete, // 已完成 SaleOrderStatusComplete, // 已完成
SaleOrderStatusRefund, // 已退款 SaleOrderStatusRefund, // 已退款
SaleOrderStatusCancel, // 已取消 SaleOrderStatusCancel, // 已取消
SaleorderstatusWaitingPrePayment // 预付款 SaleorderstatusWaitingPrePayment, // 预付款
SaleOrderStatusTaking //提货
} = ORDER_STATUS } = ORDER_STATUS
//金额列表枚举 //金额列表枚举
const priceList = [ const priceList = [
{ {
id:1, id:1,
value:[SaleOrderStatusBooking.value, SaleOrderStatusArranging.value], value:[SaleorderstatusWaitingPrePayment.value, SaleOrderStatusBooking.value, SaleOrderStatusArranging.value],
label:'预估金额', label:'预估金额',
field: 'estimate_amount' field: 'estimate_amount'
}, },
{ {
id:2, id:2,
value:[SaleorderstatusWaitingPrePayment.value, SaleOrderStatusArranged.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value], value:[SaleOrderStatusTaking.value, SaleOrderStatusArranged.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value],
label:'合计金额', label:'合计金额',
field: 'total_sale_price' field: 'total_sale_price'
}, },
@ -88,64 +89,62 @@ export default memo(({order, comfirm = false}:Param) => {
}, },
{ {
id:5, id:5,
value:[SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value], value:[SaleOrderStatusTaking.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value],
label:'实付金额', label:'实付金额',
field: 'actual_amount' field: 'actual_amount'
} }
] ]
//是否显示价格 //订单流程是否显示价格
const showPrice = useCallback((priceInfo, status) => { const showPrice = (item) => {
return priceInfo.value.includes(status) if (item.id == 2) {
}, [order]) //合计金额 (剪板特殊请情况)
return (item.value.includes(order.status)|| order.sale_mode == 1)
} else if (item.id == 3) {
//空差优惠只有大货才有
return (item.value.includes(order.status) && order.sale_mode == 1 )
} else {
return (item.value.includes(order.status) && order.sale_mode != 1 )
}
//金额展示大货 }
//订单流程金额展示
const priceConDom = useMemo(() => { const priceConDom = useMemo(() => {
if(!order) return if(!order) return
if(comfirm == true) {
//确认订单时
return <EstimatedAmount number={formatPriceDiv(order.estimate_amount)} title="预估金额" />
} else if(order?.status == SaleOrderStatusCancel.value) {
//订单状态为取消订单时
return ( return (
<> <>
{ {
priceList.map(item => { priceList.map(item => {
return <>{showPrice(item, order?.the_previous_status)&&<EstimatedAmount key={item.id} number={formatPriceDiv(order[item.field])} title={item.label} />}</> return <>{showPrice(item)&&<EstimatedAmount key={item.id} number={formatPriceDiv(order[item.field])} title={item.label} />}</>
}) })
} }
</> </>
) )
} else {
//其他订单状态
return (
<>
{
priceList.map(item => {
return <>{showPrice(item, order?.status)&&<EstimatedAmount key={item.id} number={formatPriceDiv(order[item.field])} title={item.label} />}</>
})
}
</>
)
}
}, [order]) }, [order])
//金额展示剪板 //确认订单金额展示
const cutPriceConDom = useMemo(() => { const comfirmPriceConDom = useMemo(() => {
if(!order) return if(!order) return
return <EstimatedAmount number={formatPriceDiv(order.total_should_collect_money)} title="合计金额" /> let item = order.sale_mode == 1?priceList[1]:priceList[0]
return<EstimatedAmount key={item.id} number={formatPriceDiv(order[item.field])} title={item.label} />
}, [order]) }, [order])
const showPriceAll = useMemo(() => { //金额展示
if(order?.sale_mode == 1) { const showPriceConDom = useMemo(() => {
return cutPriceConDom //剪板 return comfirm?comfirmPriceConDom:priceConDom
} else { }, [order])
return priceConDom //大货
//散剪大约重量
const aboutWeight = useCallback((weight) => {
if(order.sale_mode == 2 ) {
let showWeight = [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusBooking.value, SaleOrderStatusArranging.value].includes(order.status)
return showWeight?<View className={styles.order_list_item_price_dg}>; <Text>{formatWeightDiv(weight)}kg</Text></View>:<></>
} }
return <></>
}, [order]) }, [order])
return ( return (
<> <>
<View className={styles.orders_list_title}>{numText}</View> <View className={styles.orders_list_title}>{numText}</View>
@ -167,7 +166,11 @@ export default memo(({order, comfirm = false}:Param) => {
<View className={styles.order_list_item_con}> <View className={styles.order_list_item_con}>
<View className={styles.order_list_item_des}> <View className={styles.order_list_item_des}>
<View className={styles.order_list_item_title}>{colorItem.code + ' ' + colorItem.name}</View> <View className={styles.order_list_item_title}>{colorItem.code + ' ' + colorItem.name}</View>
<View className={styles.order_list_item_price}>¥{standardPrice(colorItem.sale_price)}</View> <View className={styles.order_list_item_price}>
¥{standardPrice(colorItem.sale_price)}
{aboutWeight(colorItem.estimate_weight)}
</View>
</View> </View>
<View className={styles.order_list_item_count}> <View className={styles.order_list_item_count}>
<View className={styles.count_num}>×{formatCount(colorItem)}<text>{order.unit}</text></View> <View className={styles.count_num}>×{formatCount(colorItem)}<text>{order.unit}</text></View>
@ -181,7 +184,7 @@ export default memo(({order, comfirm = false}:Param) => {
}) })
} }
<View className={styles.order_estimated_amount}> <View className={styles.order_estimated_amount}>
{showPriceAll} {showPriceConDom}
</View> </View>
</View> </View>
</> </>

View File

@ -15,7 +15,6 @@
} }
.order_status_item{ .order_status_item{
position: relative; position: relative;
// padding-left: 50px;
&:nth-last-child(n+2) { &:nth-last-child(n+2) {
padding-bottom: 30px; padding-bottom: 30px;
} }

View File

@ -10,7 +10,8 @@ type List = {
status: string, status: string,
time: string, time: string,
tag: string, tag: string,
desc: string desc: string,
expire_time: string
} }
type Param = { type Param = {
@ -19,13 +20,12 @@ type Param = {
logistics_details:List[], //订单状态列表 logistics_details:List[], //订单状态列表
payment_method: 0|PAYMENT_METHOD_PARAM, //支付方式 payment_method: 0|PAYMENT_METHOD_PARAM, //支付方式
status: number, //订单状态 status: number, //订单状态
expire_time: number
} }
} }
export default memo(({orderInfo = {logistics_details: [],payment_method: 0, status: 0, expire_time:0}, onRefresh}:Param) => { export default memo(({orderInfo = {logistics_details: [],payment_method: 0, status: 0}, onRefresh}:Param) => {
const [showMore, setShowMore] = useState(false) const [showMore, setShowMore] = useState(false)
const changeMore = () => { const changeMore = () => {
@ -44,36 +44,13 @@ export default memo(({orderInfo = {logistics_details: [],payment_method: 0, stat
PaymentMethodCashOnDelivery, PaymentMethodCashOnDelivery,
} = PAYMENT_METHOD } = PAYMENT_METHOD
//获取预付款最后时间
//倒计时 const endTime = useMemo(() => {
const timeObj:any = useRef() if(orderInfo.status == SaleorderstatusWaitingPrePayment.value && orderInfo.logistics_details.length > 0) {
useEffect(() => { return orderInfo.logistics_details[0].expire_time
if(orderInfo.expire_time) {
timeObj.current = setInterval(() => {
count_down()
}, 1000)
} }
return () => { return ''
clearInterval(timeObj.current) }, [orderInfo])
}
}, [orderInfo.expire_time])
const count_down = () => {
var startData = dayjs();
var endDate = dayjs(orderInfo.expire_time);
console.log('endDate::', endDate.format('YYYY-MM-DD HH:mm'))
var _dd = endDate.diff(startData,'day');
var _hh = endDate.diff(startData,'hour');
var _mm = endDate.diff(startData,'minute');
var _ss = endDate.diff(startData,'second');
// 转换
var hh = _hh - (_dd*24);
var mm = _mm - (_hh*60);
var ss = _ss - (_mm*60);
console.log(`${_dd} ${hh} ${mm} ${ss}`)
}
return ( return (
<> <>
{(dataList?.length > 0)&&<View className={styles.order_flow_state}> {(dataList?.length > 0)&&<View className={styles.order_flow_state}>
@ -84,12 +61,9 @@ export default memo(({orderInfo = {logistics_details: [],payment_method: 0, stat
<View className={styles.order_status_content}> <View className={styles.order_status_content}>
<View className={classnames(styles.order_status_title, (index == 0)&&styles.order_status_select)}>{item.status}</View> <View className={classnames(styles.order_status_title, (index == 0)&&styles.order_status_select)}>{item.status}</View>
<View className={classnames(styles.order_status_time, (index == 0)&&styles.order_status_select)}>{formatDateTime(item.time)}</View> <View className={classnames(styles.order_status_time, (index == 0)&&styles.order_status_select)}>{formatDateTime(item.time)}</View>
{/* <View className={classnames(styles.order_status_tag, (index == 0)&&styles.order_status_tag_select)}>{item.tag}</View> */}
</View> </View>
<Text className={classnames(styles.order_status_des, (index == 0)&&styles.order_status_des_select)}>{item.desc}</Text> <Text className={classnames(styles.order_status_des, (index == 0)&&styles.order_status_des_select)}>{item.desc}</Text>
{(orderInfo.status == SaleorderstatusWaitingPrePayment.value)&&<View className={styles.pay_time}> {(orderInfo.status == SaleorderstatusWaitingPrePayment.value)&&<CountDown onFinish={onRefresh} endTime={endTime}/>}
<Text>23:58:55</Text>
</View>}
</View>)} </View>)}
</View> </View>
{(dataList.length > 2) && <View className={styles.more} onClick={() => changeMore()}> {(dataList.length > 2) && <View className={styles.more} onClick={() => changeMore()}>
@ -108,3 +82,51 @@ export default memo(({orderInfo = {logistics_details: [],payment_method: 0, stat
</> </>
) )
}) })
//倒计时
const CountDown = ({endTime = '', onFinish}:{endTime:string, onFinish?:() => void}) => {
const [showTime, setShowTime] = useState('')
const timeObj:any = useRef()
useEffect(() => {
if(endTime) {
clearInterval(timeObj.current)
timeObj.current = setInterval(() => {
count_down()
}, 1000)
}
return () => {
clearInterval(timeObj.current)
}
}, [endTime])
const count_down = () => {
var startData = dayjs();
var endDate = dayjs(endTime);
if(startData >= endDate) {
clearInterval(timeObj.current)
onFinish?.()
setShowTime(() => '00:00:00')
return false
}
var _dd = endDate.diff(startData,'day');
var _hh = endDate.diff(startData,'hour');
var _mm = endDate.diff(startData,'minute');
var _ss = endDate.diff(startData,'second');
// 转换
var hh = _hh - (_dd*24);
var mm = _mm - (_hh*60);
var ss = _ss - (_mm*60);
// 格式化
var DD = ('00'+_dd).slice(-2);
var HH = ('00'+hh).slice(-2);
var MM = ('00'+mm).slice(-2);
var SS = ('00'+ss).slice(-2);
setShowTime(() => ` ${HH}:${MM}:${SS}`)
}
return (
<>
<View className={styles.pay_time}>
<Text>{showTime||'--:--:--'}</Text>
</View>
</>
)
}

View File

@ -35,9 +35,9 @@ $top:190px;
border-radius: 10px; border-radius: 10px;
padding-bottom: 100px; padding-bottom: 100px;
position: relative; position: relative;
background: radial-gradient(circle 20px at left $top, transparent 20px, #fff 20px + 3px) left 0px/60% no-repeat , // background: radial-gradient(circle 20px at left $top, transparent 20px, #fff 20px + 3px) left 0px/60% no-repeat ,
radial-gradient(circle 20px at right $top, transparent 20px, #fff 20px + 3px) right 0px/60% no-repeat; // radial-gradient(circle 20px at right $top, transparent 20px, #fff 20px + 3px) right 0px/60% no-repeat;
filter: drop-shadow(2px 2px 6px rgba(0, 0, 0, .16)); // filter: drop-shadow(2px 2px 6px rgba(0, 0, 0, .16));
position: relative; position: relative;
&::before{ &::before{
content: ''; content: '';

View File

@ -25,6 +25,7 @@ type OrderInfo = {
pre_collect_order_id?: number, //预付单id pre_collect_order_id?: number, //预付单id
status?: number, //订单状态 status?: number, //订单状态
payment_method?: 0|PAYMENT_METHOD_PARAM //支付方式 payment_method?: 0|PAYMENT_METHOD_PARAM //支付方式
sale_mode?: number //订单类型 0大货 1剪板 2散剪
} }
type PayStatus = 1|2|3|4|5|null //1:预存款, 2:账期3线下汇款 4扫码支付, 5:货到付款 type PayStatus = 1|2|3|4|5|null //1:预存款, 2:账期3线下汇款 4扫码支付, 5:货到付款
@ -122,6 +123,8 @@ export default memo(({show = false, onClose, orderInfo, onSubmitSuccess}:Param)
//是否显示七天账期 //是否显示七天账期
const show_account_payment = useMemo(() => { const show_account_payment = useMemo(() => {
console.log('orderInfo?.status::',orderInfo) console.log('orderInfo?.status::',orderInfo)
//剪板合散剪不显示
if(orderInfo?.sale_mode != 0) return false
//支付方式是账期支付,不显示 //支付方式是账期支付,不显示
if(orderInfo?.payment_method == PaymentMethodAccountPeriod.value) return false if(orderInfo?.payment_method == PaymentMethodAccountPeriod.value) return false
//支付方式是货到付款,不显示 //支付方式是货到付款,不显示
@ -139,6 +142,10 @@ export default memo(({show = false, onClose, orderInfo, onSubmitSuccess}:Param)
) )
}, [payInfo]) }, [payInfo])
//选择改变
const changeSelect = () => {
}
return ( return (
<View className={styles.payment_main}> <View className={styles.payment_main}>
<Popup show={show} showTitle={false} onClose={onClose} > <Popup show={show} showTitle={false} onClose={onClose} >
@ -164,7 +171,7 @@ export default memo(({show = false, onClose, orderInfo, onSubmitSuccess}:Param)
</View> </View>
</View> </View>
<View className={styles.payment_list_con}> <View className={styles.payment_list_con}>
<View className={styles.payment_list_item}> <View className={styles.payment_list_item} onClick={changeSelect}>
<View className={styles.payment_list_item_left}> <View className={styles.payment_list_item_left}>
<View className={styles.payment_list_item_left_name}> <View className={styles.payment_list_item_left_name}>
<View className={classnames('iconfont icon-a-tuikuanshouhou', styles.miconfont)}></View> <View className={classnames('iconfont icon-a-tuikuanshouhou', styles.miconfont)}></View>

View File

@ -0,0 +1,27 @@
.reason_return_con{
height: 50vh;
.reason_title{
padding: 10px 20px 0 20px;
height: 60px;
border-bottom: 1PX solid #F3F3F3;
box-sizing: border-box;
Text{
font-size: 26px;
border-bottom: 3px solid #000;
padding: 10px;
font-weight: 400;
}
}
.reason_scroll{
height: calc(100% - 70px);
.reason_list{
font-size: 26px;
padding: 30px 20px 0 20px;
color: #707070;
.reason_item{
margin-bottom: 36px;
}
}
}
}

View File

@ -0,0 +1,37 @@
import Popup from "@/components/popup";
import { ScrollView, Text, View } from "@tarojs/components";
import { memo, useMemo } from "react";
import styles from './index.module.scss'
//原因选择
type ReasonInfoParam = {
show?: boolean,
onClose?: () => void,
}
export default memo(({show = false, onClose}: ReasonInfoParam) => {
return (
<Popup showIconButton={false} show={show} title="退款说明" onClose={onClose} >
<View className={styles.reason_return_con}>
<View className={styles.reason_title}><Text>退</Text></View>
<ScrollView scrollY className={styles.reason_scroll}>
<View className={styles.reason_list}>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
<View className={styles.reason_item}></View>
</View>
</ScrollView>
</View>
</Popup>
)
})

View File

@ -1,20 +1,25 @@
import Popup from "@/components/popup" import Popup from "@/components/popup"
import { Textarea, View } from "@tarojs/components" import { Textarea, View } from "@tarojs/components"
import { useCallback, useState } from "react" import { useCallback, useEffect, useState } from "react"
import styles from './index.module.scss' import styles from './index.module.scss'
type Param = { type Param = {
onBlur?: (val:any) => void onBlur?: (val:any) => void
onSave?: (val: string) => void onSave?: (val: string) => void
defaultValue?: string
} }
export default ({onBlur, onSave}:Param) => { export default ({onBlur, onSave, defaultValue = ''}:Param) => {
const [descData, setDescData] = useState({ const [descData, setDescData] = useState({
number: 0, number: 0,
value: '', value: '',
count: 200 count: 200
}) })
const getDesc = useCallback((e) => {
let value = e.detail.value useEffect(() => {
getDesc(defaultValue)
}, [defaultValue])
const getDesc = useCallback((value) => {
let res = value let res = value
if(value.length > descData.count) { if(value.length > descData.count) {
res = value.slice(0, descData.count) res = value.slice(0, descData.count)
@ -29,7 +34,7 @@ export default ({onBlur, onSave}:Param) => {
<View className={styles.order_popup}> <View className={styles.order_popup}>
<View className={styles.order_popup_title}></View> <View className={styles.order_popup_title}></View>
<View className={styles.order_popup_input}> <View className={styles.order_popup_input}>
<Textarea placeholder="请添加备注" maxlength={descData.count} cursorSpacing={100} onInput={(e) => getDesc(e)} onBlur={(e) => onBlur?.(e)}></Textarea> <Textarea placeholder="请添加备注" maxlength={descData.count} cursorSpacing={100} onInput={(e) => getDesc(e.detail.value)} onBlur={(e) => onBlur?.(e)}></Textarea>
<View className={styles.descDataNum}>{descData.number}/{descData.count}</View> <View className={styles.descDataNum}>{descData.number}/{descData.count}</View>
</View> </View>
<View className={styles.order_save_address} onClick={() => setSave()}></View> <View className={styles.order_save_address} onClick={() => setSave()}></View>

View File

@ -1,11 +1,9 @@
.order_price{ .order_price{
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; // justify-content: space-between;
width: 100%; width: 100%;
&:nth-last-child(n+2) {
margin-bottom: 30px;
}
.order_price_text{ .order_price_text{
font-size: $font_size_medium; font-size: $font_size_medium;
// margin-right: 10px; // margin-right: 10px;
@ -41,7 +39,7 @@
} }
} }
.emphasis{ .emphasis{
font-weight: 700; // font-weight: 700;
} }
.order_price_num{ .order_price_num{
color: $color_main; color: $color_main;
@ -51,7 +49,7 @@
font-size: $font_size_min; font-size: $font_size_min;
} }
&:nth-child(2) { &:nth-child(2) {
font-size: 26px; font-size: 44px;
} }
&:nth-child(3) { &:nth-child(3) {
font-size: $font_size_medium; font-size: $font_size_medium;
@ -61,7 +59,7 @@
.emphasis_num{ .emphasis_num{
text{ text{
&:nth-child(2) { &:nth-child(2) {
font-size: $font_size_big; font-size: 44px;
} }
} }
} }

View File

@ -26,11 +26,7 @@ export default memo(({style, number = 0, priceTitle = ''}:Param) => {
<> <>
<View className={styles.order_price}> <View className={styles.order_price}>
<View className={classnames(styles.order_price_text, styles.emphasis)}> <View className={classnames(styles.order_price_text, styles.emphasis)}>
<Text>{priceTitle}</Text> <Text>{priceTitle}</Text>
<View className={styles.iconfont_msg}>
<Text className={classnames(styles.miconfont, 'iconfont icon-a-tuikuanshouhou')}></Text>
{/* <View className={classnames(styles.message)}>123123123121212312312312312</View> */}
</View>
</View> </View>
<View className={classnames(styles.order_price_num, styles.emphasis_num)} style={style}> <View className={classnames(styles.order_price_num, styles.emphasis_num)} style={style}>
{priceDom()} {priceDom()}

View File

@ -62,18 +62,15 @@
color: $color_font_two; color: $color_font_two;
} }
} }
.submit_order{ .submit_order_con{
position: fixed; position: fixed;
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
align-items: center;
background-color: #fff; background-color: #fff;
box-shadow: 6px 0px 12px 0px rgba(0,0,0,0.16); box-shadow: 6px 0px 12px 0px rgba(0,0,0,0.16);
padding: 20px 20px; padding: 20px 20px;
box-sizing: border-box; box-sizing: border-box;
// padding-bottom: constant(safe-area-inset-bottom);
// padding-bottom: env(safe-area-inset-bottom);
.order_btn { .order_btn {
width: 152px; width: 152px;
height: 72px; height: 72px;

View File

@ -4,17 +4,20 @@ import {
CancelOrderApi CancelOrderApi
} from "@/api/order"; } from "@/api/order";
import { GetOrderPayApi } from "@/api/orderPay"; import { GetOrderPayApi } from "@/api/orderPay";
import { AddShoppingCartApi } from "@/api/shopCart";
import { alert, goLink } from "@/common/common"; import { alert, goLink } from "@/common/common";
import { ORDER_STATUS } from "@/common/enum"; import { ORDER_STATUS } from "@/common/enum";
import { formatDateTime, formatPriceDiv } from "@/common/fotmat"; import { formatDateTime, formatImgUrl, formatPriceDiv } from "@/common/fotmat";
import OrderBtns from "@/components/orderBtns"; import OrderBtns from "@/components/orderBtns";
import Popup from "@/components/popup"; import Popup from "@/components/popup";
import SearchInput from "@/components/searchInput"; import SearchInput from "@/components/searchInput";
import ShopCart from "@/components/shopCart";
import { Text, Textarea, View } from "@tarojs/components" import { Text, Textarea, View } from "@tarojs/components"
import Taro, { useDidShow, usePullDownRefresh, useRouter } from "@tarojs/taro"; import Taro, { useDidShow, usePullDownRefresh, useRouter } from "@tarojs/taro";
import classnames from "classnames"; import classnames from "classnames";
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import AddressInfoDetail from "./components/addressInfoDetail"; import AddressInfoDetail from "./components/addressInfoDetail";
import ApplyRefund from "./components/applyRefund";
import KindList from "./components/kindList"; import KindList from "./components/kindList";
import OrderState from "./components/orderState"; import OrderState from "./components/orderState";
import Payment from "./components/payment"; import Payment from "./components/payment";
@ -39,6 +42,7 @@ import styles from './index.module.scss'
setOrderRemark(res.data.remark) setOrderRemark(res.data.remark)
} }
Taro.stopPullDownRefresh() Taro.stopPullDownRefresh()
Taro.hideToast()
} }
//监听获取到的数据 //监听获取到的数据
@ -85,16 +89,19 @@ import styles from './index.module.scss'
}) })
} }
//格式化初始地址 //初始地址数据
const defaultAddress = useMemo(() => { const defaultAddress = useMemo(() => {
return { return {
province_name: orderDetail?.province_name, province_name: orderDetail?.province_name,
city_name: orderDetail?.city_name, city_name: orderDetail?.city_name,
district_name: orderDetail?.district_name, district_name: orderDetail?.district_name,
address_detail: orderDetail?.address_detail, address_detail: orderDetail?.address_detail,
// id: address.id,
name: orderDetail?.target_user_name, name: orderDetail?.target_user_name,
phone: orderDetail?.target_user_phone phone: orderDetail?.target_user_phone,
shipment_mode: orderDetail?.shipment_mode,
id: orderDetail?.id,
sale_mode: orderDetail?.sale_mode,
status: orderDetail?.status
} }
}, [orderDetail]) }, [orderDetail])
@ -114,12 +121,6 @@ import styles from './index.module.scss'
setShowDesc(() => false) setShowDesc(() => false)
}, []) }, [])
//支付所需数据
// const payOrderInfo = useMemo(() => {
// if(orderDetail)
// return {should_collect_order_id: orderDetail.should_collect_order_id, payment_method:orderDetail.payment_method, pre_collect_order_id:orderDetail.pre_collect_order_id}
// }, [orderDetail])
//去付款 //去付款
const [payMentShow, setPayMentShow] = useState(false) const [payMentShow, setPayMentShow] = useState(false)
const toPay = () => { const toPay = () => {
@ -146,13 +147,20 @@ import styles from './index.module.scss'
//获取底部按钮点击, 获取按钮状态 //获取底部按钮点击, 获取按钮状态
const orderStateClick = useCallback((val) => { const orderStateClick = useCallback((val) => {
console.log('123456789',val)
if(val == 1 || val == 6) { if(val == 1 || val == 6) {
//取消订单 //取消订单
getSaleOrderPreView() getSaleOrderPreView()
}else if(val == 2) { }else if(val == 2) {
//待付款 //待付款
toPay() toPay()
} else if(val == 3) {
setRefundShow(true)
} else if(val == 7) {
//再购
addShopCart()
} }
}, [orderDetail]) }, [orderDetail])
//页面下拉刷新 //页面下拉刷新
@ -186,13 +194,66 @@ import styles from './index.module.scss'
//订单状态枚举 //订单状态枚举
const {SaleOrderStatusCancel} = ORDER_STATUS const {SaleOrderStatusCancel} = ORDER_STATUS
//刷新页面
const refresh = useCallback(() => {
alert.loading('刷新中')
getSaleOrderPreView()
}, [orderDetail])
//退款申请
const [refundShow, setRefundShow] = useState(false)
const applyRefundClose = useCallback(() => {
setRefundShow(false)
}, [])
//查看物流
const getLogistics = useCallback(() => {
const list = orderDetail?.delivery_appendix_url.map(item => {
return formatImgUrl(item)
})
Taro.previewImage({
current: list[0], // 当前显示
urls: list // 需要预览的图片http链接列表
})
}, [orderDetail])
//添加购物车
const [showCart, setShowCart] = useState(false)
const {fetchData:addFetchData} = AddShoppingCartApi()
const addShopCart = async () => {
let color_list:{product_color_id: number, roll?: number, length?: number}[] = []
orderDetail?.product_list.map(pitem => {
pitem?.product_colors.map(citem => {
if(orderDetail?.sale_mode == 0) {
return color_list.push({product_color_id: citem.id, roll: citem.roll})
} else {
return color_list.push({product_color_id: citem.id, length: citem.length})
}
})
})
const state = await addFetchData({
sale_mode: orderDetail?.sale_mode,
color_list
})
if(state.success) {
Taro.showToast({
title:'已加入购物车'
})
setShowCart(true)
} else {
Taro.showToast({
icon:'none',
title: state.msg
})
}
}
return ( return (
<View className={styles.order_main}> <View className={styles.order_main}>
<OrderState orderInfo={{logistics_details:orderDetail?.logistics_details, payment_method: orderDetail?.payment_method, status:orderDetail?.status, expire_time:orderDetail?.expire_time}}/> <OrderState orderInfo={orderDetail} onRefresh={refresh}/>
<View > <View>
<AddressInfoDetail orderInfo={addressInfoDetailData} onSelect={getAddress} onChangeShipmentMode={getShipmentMode} ref={addressRef} defaultValue={defaultAddress} /> <AddressInfoDetail orderInfo={defaultAddress} onLogistics={getLogistics} onSelect={getAddress} onChangeShipmentMode={getShipmentMode} ref={addressRef} />
</View> </View>
<KindList order={formatPreViewOrderMemo}/> <KindList order={formatPreViewOrderMemo}/>
<View className={styles.order_info} > <View className={styles.order_info} >
@ -218,14 +279,16 @@ import styles from './index.module.scss'
} }
<View className={classnames(styles.miconfont, 'iconfont icon-a-moreback')}></View> <View className={classnames(styles.miconfont, 'iconfont icon-a-moreback')}></View>
</View> </View>
{(orderDetail?.status != SaleOrderStatusCancel.value)&&<View className={styles.submit_order}> {(orderDetail?.status != SaleOrderStatusCancel.value)&&<View className={styles.submit_order_con}>
<OrderBtns orderInfo={orderInfo} onClick={orderStateClick}/> <OrderBtns orderInfo={orderInfo} onClick={orderStateClick}/>
<View className="common_safe_area_y"></View> <View className="common_safe_area_y"></View>
</View> } </View> }
<Popup show={showDesc} showTitle={false} onClose={() => setShowDesc(false)}> <Popup show={showDesc} showTitle={false} onClose={() => setShowDesc(false)}>
<Remark onSave={(e) => getRemark(e)}/> <Remark onSave={(e) => getRemark(e)} defaultValue={orderDetail?.remark}/>
</Popup> </Popup>
<Payment onSubmitSuccess={onPaySuccess} show={payMentShow} onClose={closePayShow} orderInfo={orderDetail} /> <Payment onSubmitSuccess={onPaySuccess} show={payMentShow} onClose={closePayShow} orderInfo={orderDetail} />
<ApplyRefund show={refundShow} onClose={applyRefundClose}/>
<ShopCart show={showCart} onClose={() => setShowCart(false)}/>
<View className="common_safe_area_y"></View> <View className="common_safe_area_y"></View>
</View> </View>
) )

View File

@ -12,6 +12,8 @@ import { dataLoadingStatus, getFilterData } from "@/common/util"
import OrderStatusList from "./components/orderStatusList" import OrderStatusList from "./components/orderStatusList"
import Payment from "../order/components/payment" import Payment from "../order/components/payment"
import { ORDER_STATUS } from "@/common/enum" import { ORDER_STATUS } from "@/common/enum"
import { AddShoppingCartApi } from "@/api/shopCart"
import ShopCart from "@/components/shopCart"
export default () => { export default () => {
const {checkLogin} = useLogin() const {checkLogin} = useLogin()
@ -108,6 +110,9 @@ export default () => {
payment_method: orderInfo.payment_method //支付方式 payment_method: orderInfo.payment_method //支付方式
}) })
toPay() toPay()
} else if (status == 7) {
//购买
addShopCart(orderInfo)
} }
}, [orderData]) }, [orderData])
@ -128,6 +133,38 @@ export default () => {
closePayShow() closePayShow()
}, []) }, [])
//添加购物车
const [showCart, setShowCart] = useState(false)
const {fetchData:addFetchData} = AddShoppingCartApi()
const addShopCart = async (item) => {
let color_list:{product_color_id: number, roll?: number, length?: number}[] = []
item?.product_list.map(pitem => {
pitem?.product_colors.map(citem => {
if(item?.sale_mode == 0) {
return color_list.push({product_color_id: citem.id, roll: citem.roll})
} else {
return color_list.push({product_color_id: citem.id, length: citem.length})
}
})
})
const state = await addFetchData({
sale_mode: item?.sale_mode,
color_list
})
if(state.success) {
Taro.showToast({
title:'已加入购物车'
})
setShowCart(true)
} else {
Taro.showToast({
icon:'none',
title: state.msg
})
}
}
return ( return (
<View className={styles.order_list_main}> <View className={styles.order_list_main}>
@ -142,6 +179,7 @@ export default () => {
})} })}
</InfiniteScroll> </InfiniteScroll>
</View> </View>
<ShopCart show={showCart} onClose={() => setShowCart(false)}/>
<Payment onSubmitSuccess={onPaySuccess} show={payMentShow} onClose={closePayShow} orderInfo={payOrderInfo}/> <Payment onSubmitSuccess={onPaySuccess} show={payMentShow} onClose={closePayShow} orderInfo={payOrderInfo}/>
</View> </View>
) )

View File

@ -1,12 +1,31 @@
.address_main{
margin-top: 20px;
}
.address_title_tag{
font-size: 24px;
color: #EE7500;
background: rgba(255,230,206,0.36);
border-radius: 20px 20px 0px 0px;
height: 56px;
display: flex;
align-items: center;
position: relative;
z-index: 999;
.miconfont {
font-size: 30px;
padding: 0 20px;
}
}
.order_address{ .order_address{
height: 178px; height: 178px;
background: #ffffff; background: #ffffff;
border-radius: 20px; border-radius: 0 0 20px 20px;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 30px; padding: 30px;
box-sizing: border-box; box-sizing: border-box;
margin-top: 20px;
position: relative; position: relative;
.order_address_icon{ .order_address_icon{
font-size: 50px; font-size: 50px;
@ -26,87 +45,46 @@
.order_address_text_title{ .order_address_text_title{
font-size: $font_size_medium; font-size: $font_size_medium;
margin-top: 10px; margin-top: 10px;
@include common_ellipsis;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
.moreIconfont{ .moreIconfont{
font-size: 20px; font-size: 20px;
} }
.address_text{
word-break:break-all;
font-size: 28px;
font-weight: 700;
}
} }
.order_address_text_name{ .order_address_text_name{
color: #707070;
align-items: center; align-items: center;
display: flex;
margin-top: 20px;
text{ text{
&:nth-child(1) { &:nth-child(1) {
color: #000; font-size: $font_size_medium;
font-weight: 700;
font-size: $color_font_one;
margin-right: 40px; margin-right: 40px;
} }
&:nth-child(2) { &:nth-child(2) {
color: $color_font_one; flex:1;
font-size: $font_size_medium; font-size: $font_size_medium;
} }
} }
} }
} }
.updateBtn{ .updateBtn{
width:200px; width:152px;
font-size: $font_size_min; font-size: 28px;
background-color: #F0F0F0; height: 60px;
height: 64px;
border-radius: 24px;
color: $color_font_two; color: $color_font_two;
position: absolute;
bottom: 10px;
right: 10px;
z-index: 999; z-index: 999;
.updateBtn_list{ border: 2px solid #dddddd;
position: absolute; border-radius: 36px;
display: flex;
z-index: 5;
width: 100%;
.updateBtn_item_select{
color: #fff;
}
}
.updateBtn_item{
flex:1;
text-align: center; text-align: center;
line-height: 64px; line-height: 60px;
}
.updateBtn_select{
color: #fff;
background-color: $color_main;
border-radius: 24px;
position: absolute;
width: 100px;
height: 61px;
z-index: 1;
transition: all 0.3s ease-in-out;
}
} }
.order_address_text_no{
flex: 1;
font-size: $font_size;
font-weight: 700;
margin-left: 30px;
}
.order_address_more_icon{
color: $color_font_three;
font-size: $font_size;
}
} }
.order_address_list {
height: 900px;
.order_address_title{
font-size: $font_size;
font-weight: 700;
width: 100%;
text-align: center;
padding: 20px 0 30px 0;
}
}

View File

@ -1,122 +1,69 @@
import { EditSaleOrderAddressApi, EditSaleOrderShipmentModeApi } from "@/api/order"; import { AFTER_ORDER_STATUS } from "@/common/enum";
import { alert } from "@/common/common";
import { debounce } from "@/common/util";
import AddressList from "@/components/AddressList";
import Popup from "@/components/popup";
import { Text, View } from "@tarojs/components" import { Text, View } from "@tarojs/components"
import classnames from "classnames"; import classnames from "classnames";
import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useState } from "react"; import {memo, useMemo} from "react";
import styles from './index.module.scss' import styles from './index.module.scss'
export type AddressInfoParam = {
province_name: string,
city_name: string,
district_name: string,
address_detail: string,
id?: number,
name: string,
phone: string,
}
type Param = { type Param = {
onSelect?: (val:any) => void, //选择 return_address?:string,
defaultValue?: AddressInfoParam|null, //默认值 return_phone?: string,
disabled?: false|true, //true禁用后只用于展示 onLogistics?: (val: number) => void,
shipment_mode?: 1|2, //1自提 2物流 stage?: number
onChangeShipmentMode?: (val: number) => void, //返回收货方式
orderId?: number //订单id
} }
export default memo(({return_address = '', return_phone = '', onLogistics, stage}:Param) => {
const {
ReturnStageApplying,
ReturnStageWaitCheck,
ReturnStageChecked,
ReturnStageReturned,
ReturnStageCancel,
ReturnStageQualityCheckPendingRefund,
ReturnStageServiceOrderPendingRefund,
ReturnStageRejected
} = AFTER_ORDER_STATUS
export default memo(forwardRef(({onSelect, onChangeShipmentMode, defaultValue = null, orderId = 0, shipment_mode = 1}: Param, ref) => { //是否显示地址
const [showAddressList, setShowAddressList] = useState(false) const showAddress = useMemo(() => {
return stage != ReturnStageApplying.value
}, [stage])
useEffect(() => { //上传物流
setUserInfo(() => defaultValue) const upLogistics = useMemo(() => {
}, [defaultValue]) return stage == ReturnStageWaitCheck.value
}, [stage])
const [userInfo, setUserInfo] = useState<any>() //查看物流
const showLogistics = useMemo(() => {
return (stage == ReturnStageChecked.value || stage == ReturnStageQualityCheckPendingRefund.value)
}, [stage])
//地址格式
const formatAddress = useMemo(() => {
if(userInfo)
return userInfo.province_name + userInfo.city_name + userInfo.district_name + userInfo.address_detail
}, [userInfo])
const changeShow = () => {
if(receivingStatus == 2)
setShowAddressList(() => true)
}
useEffect(() => {
setReceivingStatus(() => shipment_mode)
}, [shipment_mode])
//把内部方法提供给外部
useImperativeHandle(ref, () => ({
changeShow
}))
//收货方法,1:自提2物流
const [receivingStatus, setReceivingStatus] = useState(1)
const {fetchData: shipmentModeFetchData} = EditSaleOrderShipmentModeApi()
const onReceivingStatus = (value, e) => {
e.stopPropagation()
changeReceivingStatus(value)
}
const changeReceivingStatus = debounce(async (value) => {
alert.loading('正在修改')
const res = await shipmentModeFetchData({id: orderId, shipment_mode:value})
if(res.success) {
alert.success('收货方式修改成功')
onChangeShipmentMode?.(value)
setReceivingStatus(value)
} else {
alert.none(res.msg)
}
}, 10)
//修改地址
const {fetchData: addressFetchData} = EditSaleOrderAddressApi()
const getAddress = async (value) => {
alert.loading('正在修改')
const res = await addressFetchData({id: orderId, address_id: value.id})
if(res.success) {
alert.success('地址修改成功')
onSelect?.(value)
setShowAddressList(() => false)
setUserInfo(() => value)
} else {
alert.none(res.msg)
}
}
return ( return (
<View> <>
<View className={styles.order_address} onClick={() => changeShow()}> {showAddress&&<View className={styles.address_main}>
<View className={classnames(styles.order_address_icon, 'iconfont', receivingStatus == 2?'icon-daohang':'icon-fahuo')}></View> <View className={styles.address_title_tag}>
<Text className={classnames(styles.miconfont, 'iconfont icon-zhuyi')}></Text>
退退
</View>
<View className={styles.order_address} >
<View className={classnames(styles.order_address_icon, 'iconfont','icon-fahuo')}></View>
<View className={styles.order_address_text_con}> <View className={styles.order_address_text_con}>
<View className={styles.order_address_text_title}> <View className={styles.order_address_text_title}>
<Text>{formatAddress}</Text> <Text className={classnames(styles.address_text, styles.address_text_no)}>{return_address}</Text>
{(receivingStatus == 2)&&<Text className={classnames(styles.moreIconfont,'iconfont icon-a-moreback')}></Text>}
</View> </View>
<View className={styles.order_address_text_name}> <View className={styles.order_address_text_name}>
<Text>{userInfo?.name}</Text> <Text></Text>
<Text>{userInfo?.phone}</Text> <Text>{return_phone}</Text>
{upLogistics&&<View className={styles.updateBtn} onClick={() => onLogistics?.(1)}>
</View>}
{showLogistics&&<View className={styles.updateBtn} onClick={() => onLogistics?.(2)}>
</View>}
</View> </View>
</View> </View>
<View className={styles.updateBtn}>
<View className={styles.updateBtn_list}>
<View className={classnames(styles.updateBtn_item, receivingStatus==1&&styles.updateBtn_item_select)} onClick={(e) => onReceivingStatus(1,e)}></View>
<View className={classnames(styles.updateBtn_item, receivingStatus==2&&styles.updateBtn_item_select)} onClick={(e) => onReceivingStatus(2,e)}></View>
</View>
<View style={{transform: receivingStatus==1?'translateX(0)':'translateX(100%)'}} className={classnames(styles.updateBtn_select)}></View>
</View>
</View>
<Popup show={showAddressList} showTitle={false} onClose={() => setShowAddressList(false)}>
<View className={styles.order_address_list}>
<View className={styles.order_address_title}></View>
<AddressList onSelect={getAddress}/>
</View>
</Popup>
</View> </View>
</View>}
</>
) )
})) })

View File

@ -0,0 +1,146 @@
.apply_record_scroll{
height: 70vh;
}
.apply_record_main{
margin-top: 20px;
padding: 0 30px;
.kind_number{
width: 100%;
padding: 20px;
box-sizing: border-box;
text{
background-color: #F6F6F6;
border-radius: 10px;
font-size: $font_size_medium;
padding: 5px 0;
text-align: center;
width: 100%;
display: block;
color: $color_font_three;
}
}
.orders_list_con{
background-color: #fff;
border-radius: 20px;
padding: 20px;
.orders_return_title{
font-size: 28px;
font-weight: 700;
padding-bottom: 20px;
}
.order_list{
&:nth-child(n+2) {
margin-top: 45px;
}
.order_list_title{
display: flex;
align-items: center;
.tag{
font-size: $font_size_min;
background-color: #CDE5FF;
padding: 5px 10px;
border-radius: 6px;
color: $color_main;
}
.title{
font-weight: 700;
font-size: $font_size;
margin-left: 20px;
flex:1;
}
.num{
color: $color_font_two;
font-size: $font_size_min;
}
}
}
.order_list_scroll{
margin-top: 30px;
.order_list_item {
display: flex;
&:nth-child(2) {
margin-top: 30px;
}
.order_list_item_img{
width: 126px;
height: 126px;
border-radius: 20px;
}
.order_list_item_con{
display: flex;
width: 100%;
flex:1;
border-bottom: 1px solid #f0f0f0;
height: 150px;
padding-top: 20px;
box-sizing: border-box;
}
.order_list_item_des{
flex:1;
box-sizing: border-box;
padding-left: 30px;
.order_list_item_title{
font-weight: 700;
font-size: $font_size;
margin-bottom: 15px;
}
.order_list_item_price{
font-size: 26px;
color: $color_font_three;
}
}
.order_list_item_count{
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-end;
.count_num{
color: $color_main;
font-size: $font_size;
margin-bottom: 15px;
font-weight: 400;
text{
font-size: $font_size_min;
}
}
.count_price {
font-size: $font_size;
font-weight: 700;
text{
font-size: $font_size_min;
}
}
}
}
}
.order_total{
padding-top: 30px;
display: flex;
justify-content: space-between;
text{
&:nth-child(1) {
font-size: 28px;
font-weight: 700;
}
&:nth-child(2) {
font-size: 32px;
font-weight: 700;
color: #007AFF;
}
}
}
.order_estimated_amount{
display: flex;
align-items: flex-end;
flex-direction: column;
padding: 30px 0;
.order_price_des{
font-size: $font_size_medium;
color: $color_font_two;
}
}
}
}

View File

@ -0,0 +1,124 @@
import { SaleOrderOrderDetailApi } from "@/api/salesAfterOrder";
import { formatHashTag, formatPriceDiv } from "@/common/fotmat";
import LabAndImg from "@/components/LabAndImg";
import Popup from "@/components/popup";
import { ScrollView, Text, View } from "@tarojs/components";
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import styles from './index.module.scss'
type Param = {
show?: true|false,
onClose?: () => void,
onSubmit?: () => void,
id?: number
}
export default memo(({show, onClose, onSubmit, id}:Param) => {
useEffect(() => {
if(show && id) getSaleOrderPreView()
}, [show, id])
//获取订单详情
const [orderDetail, setOrderDetail] = useState<any>() //获取到的原始数据
const {fetchData: saleOrderOrderDetailData} = SaleOrderOrderDetailApi()
const getSaleOrderPreView = async () => {
if(id) {
let res = await saleOrderOrderDetailData({id: id})
setOrderDetail(res.data)
}
Taro.stopPullDownRefresh()
}
//格式化数据格式
const [formatDetailOrder, setFormatDetailOrder] = useState<any>() //格式化后的数据
const formatData = () => {
setFormatDetailOrder({
estimate_amount: orderDetail.estimate_amount, //预估金额
sale_mode: orderDetail.sale_mode,
sale_mode_name: orderDetail.sale_mode_name,
total_colors: orderDetail.total_colors, //总颜色数量
total_number: orderDetail.total_number, //总数量
total_fabrics: orderDetail.total_fabrics, //面料数量
unit: orderDetail.sale_mode == 0?'条':'m', //单位
list: orderDetail.product_list,
stage: orderDetail.stage, //订单状态
type: orderDetail.type, //退货or退款
total_sale_price: orderDetail.total_sale_price, //销售金额
total_should_collect_money: orderDetail.total_should_collect_money, //应收金额
total_weight_error_discount: orderDetail.total_weight_error_discount, //空差优惠
actual_amount: orderDetail.actual_amount, //实付金额
the_previous_status: orderDetail.the_previous_status, //取消订单时的订单状态
})
}
//监听获取到的数据
useEffect(() => {
if(orderDetail)
formatData()
}, [orderDetail])
//对应数量
const formatCount = useCallback((item) => {
return formatDetailOrder?.sale_mode == 0? item.roll : Number(item.length / 100)
}, [formatDetailOrder])
//对应单价
const standardPrice = useCallback(price => {
return formatPriceDiv(price).toLocaleString() + '/' + (formatDetailOrder?.sale_mode == 1?'m':'kg')
}, [formatDetailOrder])
//数量格式
const numText = useMemo(() => {
if(formatDetailOrder)
return `${formatDetailOrder?.total_fabrics}种面料,${formatDetailOrder?.total_colors}种颜色,共${formatDetailOrder?.total_number}${formatDetailOrder?.unit}`
}, [formatDetailOrder])
//整理颜色
const labAndRgbAndUrl = useCallback((item) => {
return {lab:{...item?.lab}, rgb:{...item?.rgb}, texturl_url: item?.texturl_url}
}, [])
return (
<>
<Popup show={show} title="申请记录" onClose={onClose}>
{formatDetailOrder&&<View className={styles.apply_record_main}>
<View className={styles.kind_number}><Text>{numText}</Text></View>
<ScrollView scrollY className={styles.apply_record_scroll}>
<View className={styles.orders_list_con}>
{
formatDetailOrder?.list?.map(item => {
return <View key={item.product_code} className={styles.order_list}>
<View className={styles.order_list_title}>
<View className={styles.tag}>{formatDetailOrder.sale_mode_name}</View>
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
<View className={styles.num}>{item?.product_colors.length}</View>
</View>
<View className={styles.order_list_scroll}>
{item?.product_colors?.map(colorItem => {
return <View key={colorItem.id} className={styles.order_list_item}>
<View className={styles.order_list_item_img}>
<LabAndImg value={labAndRgbAndUrl(colorItem)}/>
</View>
<View className={styles.order_list_item_con}>
<View className={styles.order_list_item_des}>
<View className={styles.order_list_item_title}>{colorItem.code + ' ' + colorItem.name}</View>
<View className={styles.order_list_item_price}>¥{standardPrice(colorItem.sale_price)}</View>
</View>
<View className={styles.order_list_item_count}>
<View className={styles.count_num}>×{formatCount(colorItem)}<text>{formatDetailOrder.unit}</text></View>
<View className={styles.count_price}><text>¥</text>{formatPriceDiv(colorItem.estimate_amount).toLocaleString()}</View>
</View>
</View>
</View>
})}
</View>
</View>
})
}
<View className={styles.order_total}>
<Text></Text>
<Text>×{orderDetail?.total_number}</Text>
</View>
</View>
</ScrollView>
</View>}
</Popup>
</>
)
})

View File

@ -1,14 +1,17 @@
.orders_list_title{ .kindsList_main{
padding: 20px 20px 10px 20px; margin-top: 20px;
color: $color_font_two;
font-size: $font_size_medium;
} }
.orders_list_con{ .orders_list_con{
background-color: #fff; background-color: #fff;
border-radius: 20px; border-radius: 20px;
padding: 20px; padding: 20px;
.orders_return_title{
font-size: 28px;
font-weight: 700;
padding-bottom: 20px;
}
.order_list{ .order_list{
&:nth-child(n+2) { &:nth-child(n+2) {
margin-top: 30px; margin-top: 30px;
@ -47,7 +50,6 @@
width: 126px; width: 126px;
height: 126px; height: 126px;
border-radius: 20px; border-radius: 20px;
background-color: red;
} }
.order_list_item_con{ .order_list_item_con{
display: flex; display: flex;
@ -96,6 +98,21 @@
} }
} }
} }
.order_total{
padding-top: 20px;
display: flex;
justify-content: space-between;
text{
&:nth-child(1) {
font-size: 28px;
font-weight: 700;
}
&:nth-child(2) {
font-size: 24px;
font-weight: 700;
}
}
}
.order_estimated_amount{ .order_estimated_amount{
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;

View File

@ -1,6 +1,7 @@
import { ORDER_STATUS } from "@/common/enum" import { ORDER_STATUS } from "@/common/enum"
import { formatHashTag, formatPriceDiv } from "@/common/fotmat" import { formatHashTag, formatPriceDiv } from "@/common/fotmat"
import { View } from "@tarojs/components" import LabAndImg from "@/components/LabAndImg"
import { Text, View } from "@tarojs/components"
import { memo, useCallback, useMemo } from "react" import { memo, useCallback, useMemo } from "react"
import EstimatedAmount from "../estimatedAmount" import EstimatedAmount from "../estimatedAmount"
import styles from './index.module.scss' import styles from './index.module.scss'
@ -14,7 +15,8 @@ type OrderParam = {
total_colors: number, total_colors: number,
total_fabrics: number, total_fabrics: number,
total_number: number, total_number: number,
status: number, //订单状态 stage: number, //订单状态
type: 1|2, //1退货 2退款
total_sale_price: number, //销售金额 total_sale_price: number, //销售金额
total_should_collect_money: number, //应收金额 total_should_collect_money: number, //应收金额
total_weight_error_discount: number, //空差优惠 total_weight_error_discount: number, //空差优惠
@ -43,48 +45,60 @@ export default memo(({order, comfirm = false}:Param) => {
return `${order?.total_fabrics}种面料,${order?.total_colors}种颜色,共${order?.total_number}${order?.unit}` return `${order?.total_fabrics}种面料,${order?.total_colors}种颜色,共${order?.total_number}${order?.unit}`
}, [order]) }, [order])
const { // const {
SaleOrderStatusBooking, // 待接单 // SaleOrderStatusBooking, // 待接单
SaleOrderStatusArranging, // 配布中 // SaleOrderStatusArranging, // 配布中
SaleOrderStatusArranged, // 已配布 // SaleOrderStatusArranged, // 已配布
SaleOrderStatusWaitingPayment, // 待付款 // SaleOrderStatusWaitingPayment, // 待付款
SaleOrderStatusWaitingDelivery, // 待发货 // SaleOrderStatusWaitingDelivery, // 待发货
SaleOrderStatusWaitingReceipt, // 待收货 // SaleOrderStatusWaitingReceipt, // 待收货
SaleOrderStatusAlreadyReceipt, // 已收货 // SaleOrderStatusAlreadyReceipt, // 已收货
SaleOrderStatusComplete, // 已完成 // SaleOrderStatusComplete, // 已完成
SaleOrderStatusRefund, // 已退款 // SaleOrderStatusRefund, // 已退款
SaleOrderStatusCancel, // 已取消 // SaleOrderStatusCancel, // 已取消
} = ORDER_STATUS // } = ORDER_STATUS
//金额列表枚举 //金额列表枚举
const priceList = [ const priceList = [
{ {
id:1, id:1,
value:[SaleOrderStatusBooking.value, SaleOrderStatusArranging.value], value:[],
label:'预估金额', label:'退货条数',
field: 'estimate_amount' field: 'estimate_amount'
}, },
{ {
id:2, id:2,
value:[SaleOrderStatusArranged.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value], value:[],
label:'合计金额', label:'扣款金额',
field: 'total_sale_price' field: 'total_sale_price'
}, },
{ {
id:3, id:3,
value:[SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value], value:[],
label:'空差优惠', label:'其他扣款',
field: 'total_weight_error_discount' field: 'total_weight_error_discount'
}, },
{ {
id:4, id:4,
value:[ SaleOrderStatusWaitingPayment.value], value:[],
label:'应金额', label:'应退金额',
field: 'total_should_collect_money' field: 'total_should_collect_money'
}, },
{ {
id:5, id:5,
value:[SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value, SaleOrderStatusCancel.value], value:[],
label:'退款金额',
field: 'total_should_collect_money'
},
{
id:6,
value:[],
label:'退款去向',
field: 'actual_amount'
},
{
id:7,
value:[],
label:'实付金额', label:'实付金额',
field: 'actual_amount' field: 'actual_amount'
} }
@ -97,38 +111,26 @@ export default memo(({order, comfirm = false}:Param) => {
const priceConDom = useMemo(() => { const priceConDom = useMemo(() => {
if(!order) return if(!order) return
//确认订单
if(comfirm == true) {
return <EstimatedAmount number={formatPriceDiv(order.estimate_amount)} title="预估金额" />
}
//订单为取消订单状态
if(order?.status == SaleOrderStatusCancel.value) {
return ( return (
<> <>
{ {
priceList.map(item => { priceList.map(item => {
return <>{showPrice(item, order?.the_previous_status)&&<EstimatedAmount key={item.id} number={formatPriceDiv(order[item.field])} title={item.label} />}</> return <>{showPrice(item, order?.stage)&&<EstimatedAmount key={item.id} number={formatPriceDiv(order[item.field])} title={item.label} />}</>
}) })
} }
</> </>
) )
} else {
return (
<>
{
priceList.map(item => {
return <>{showPrice(item, order?.status)&&<EstimatedAmount key={item.id} number={formatPriceDiv(order[item.field])} title={item.label} />}</>
})
}
</>
)
}
}, [order]) }, [order])
//整理颜色
const labAndRgbAndUrl = useCallback((item) => {
return {lab:{...item?.lab}, rgb:{...item?.rgb}, texturl_url: item?.texturl_url}
}, [])
return ( return (
<> <View className={styles.kindsList_main}>
<View className={styles.orders_list_title}>{numText}</View>
<View className={styles.orders_list_con}> <View className={styles.orders_list_con}>
<View className={styles.orders_return_title}>{order?.type == 1?'退货信息':'退款信息'}</View>
{ {
order?.list?.map(item => { order?.list?.map(item => {
return <View key={item.product_code} className={styles.order_list}> return <View key={item.product_code} className={styles.order_list}>
@ -140,7 +142,9 @@ export default memo(({order, comfirm = false}:Param) => {
<View className={styles.order_list_scroll}> <View className={styles.order_list_scroll}>
{item?.product_colors?.map(colorItem => { {item?.product_colors?.map(colorItem => {
return <View key={colorItem.id} className={styles.order_list_item}> return <View key={colorItem.id} className={styles.order_list_item}>
<View className={styles.order_list_item_img}></View> <View className={styles.order_list_item_img}>
<LabAndImg value={labAndRgbAndUrl(colorItem)}/>
</View>
<View className={styles.order_list_item_con}> <View className={styles.order_list_item_con}>
<View className={styles.order_list_item_des}> <View className={styles.order_list_item_des}>
<View className={styles.order_list_item_title}>{colorItem.code + ' ' + colorItem.name}</View> <View className={styles.order_list_item_title}>{colorItem.code + ' ' + colorItem.name}</View>
@ -157,10 +161,11 @@ export default memo(({order, comfirm = false}:Param) => {
</View> </View>
}) })
} }
<View className={styles.order_total}><Text></Text><Text>{numText}</Text></View>
<View className={styles.order_estimated_amount}> <View className={styles.order_estimated_amount}>
{priceConDom} {priceConDom}
</View> </View>
</View> </View>
</> </View>
) )
}) })

View File

@ -1,18 +0,0 @@
.order_flow_state{
display: flex;
align-items: center;
padding: 0 30px;
height: 116px;
background-color: #fff;
border-radius: 20px;
.order_flow_state_text{
color: $color_main;
font-size:$font_size;
font-weight: 700;
}
.order_flow_state_desc{
color: $color_font_three;
font-size: $font_size_medium;
margin-left: 50px;
}
}

View File

@ -1,14 +0,0 @@
import { View } from "@tarojs/components"
import styles from './index.module.scss'
export default ({
state = '',
desc = ''
}) => {
return (
<View className={styles.order_flow_state}>
<View className={styles.order_flow_state_text}>{state}</View>
<View className={styles.order_flow_state_desc}>{desc}</View>
</View>
)
}

View File

@ -15,7 +15,6 @@
} }
.order_status_item{ .order_status_item{
position: relative; position: relative;
padding-left: 50px;
&:nth-last-child(n+2) { &:nth-last-child(n+2) {
padding-bottom: 30px; padding-bottom: 30px;
} }
@ -44,6 +43,7 @@
.order_status_content{ .order_status_content{
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 30px;
.order_status_title{ .order_status_title{
color: $color_font_two; color: $color_font_two;
font-size: $font_size; font-size: $font_size;
@ -75,6 +75,24 @@
.order_status_des_select{ .order_status_des_select{
color: $color_font_one; color: $color_font_one;
} }
.pay_time{
height: 56px;
background: #f6f6f6;
border-radius: 20px;
color: #3C3C3C;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
margin-top: 20px;
text{
font-size: 28px;
color: $color_main;
padding: 0 10px;
}
}
} }
.more{ .more{
width: 100%; width: 100%;
@ -102,4 +120,20 @@
top: -10px; top: -10px;
right: -10px; right: -10px;
} }
.refresh{
position: absolute;
top: 23px;
right: 20px;
display: flex;
color: #707070;
display: flex;
align-items: center;
.mconfont{
font-size: 30px;
}
.refresh_text{
font-size: 23px;
}
}
} }

View File

@ -1,42 +1,59 @@
import { Image, Text, View } from "@tarojs/components" import { Image, Text, View } from "@tarojs/components"
import { memo, useMemo, useState } from "react" import { memo, useEffect, useMemo, useRef, useState } from "react"
import styles from './index.module.scss' import styles from './index.module.scss'
import classnames from "classnames"; import classnames from "classnames";
import { formatDateTime, formatImgUrl } from "@/common/fotmat"; import { formatDateTime, formatImgUrl } from "@/common/fotmat";
import { PAYMENT_METHOD, PAYMENT_METHOD_PARAM } from "@/common/enum"; import { ORDER_STATUS, PAYMENT_METHOD, PAYMENT_METHOD_PARAM } from "@/common/enum";
import * as dayjs from 'dayjs'
type List = {
type Param = {
list: {
status: string, status: string,
time: string, time: string,
tag: string, tag: string,
desc: string desc: string,
}[], expire_time: string
payment_method: 0|PAYMENT_METHOD_PARAM,
} }
//支付方式枚举 type Param = {
const { onRefresh?: () => void,
PaymentMethodAccountPeriod, orderInfo?: {
PaymentMethodCashOnDelivery, logistics_details:List[], //订单状态列表
} = PAYMENT_METHOD payment_method: 0|PAYMENT_METHOD_PARAM, //支付方式
status: number, //订单状态
}
}
export default memo(({list = [], payment_method = 0}:Param) => {
export default memo(({orderInfo = {logistics_details: [],payment_method: 0, status: 0}, onRefresh}:Param) => {
const [showMore, setShowMore] = useState(false) const [showMore, setShowMore] = useState(false)
const changeMore = () => { const changeMore = () => {
setShowMore(() => !showMore) setShowMore(() => !showMore)
} }
const dataList = useMemo(() => { const dataList = useMemo(() => {
return list.reverse() return orderInfo.logistics_details?orderInfo?.logistics_details.reverse():[]
}, [list]) }, [orderInfo.logistics_details])
//订单状态枚举
const {SaleorderstatusWaitingPrePayment} = ORDER_STATUS
//支付方式枚举
const {
PaymentMethodAccountPeriod,
PaymentMethodCashOnDelivery,
} = PAYMENT_METHOD
//获取预付款最后时间
const endTime = useMemo(() => {
if(orderInfo.status == SaleorderstatusWaitingPrePayment.value && orderInfo.logistics_details.length > 0) {
return orderInfo.logistics_details[0].expire_time
}
return ''
}, [orderInfo])
return ( return (
<> <>
{(dataList.length > 0)&&<View className={styles.order_flow_state}> {(dataList?.length > 0)&&<View className={styles.order_flow_state}>
<View className={classnames(styles.order_status_list, showMore&&styles.order_status_list_show)}> <View className={classnames(styles.order_status_list, showMore&&styles.order_status_list_show)}>
{dataList.map((item, index) => <View className={styles.order_status_item}> {dataList.map((item, index) => <View className={styles.order_status_item}>
{(dataList.length > 1)&&<View className={classnames(styles.order_status_tail, (index == 0)&&styles.order_status_tail_end)}></View>} {(dataList.length > 1)&&<View className={classnames(styles.order_status_tail, (index == 0)&&styles.order_status_tail_end)}></View>}
@ -44,9 +61,9 @@ export default memo(({list = [], payment_method = 0}:Param) => {
<View className={styles.order_status_content}> <View className={styles.order_status_content}>
<View className={classnames(styles.order_status_title, (index == 0)&&styles.order_status_select)}>{item.status}</View> <View className={classnames(styles.order_status_title, (index == 0)&&styles.order_status_select)}>{item.status}</View>
<View className={classnames(styles.order_status_time, (index == 0)&&styles.order_status_select)}>{formatDateTime(item.time)}</View> <View className={classnames(styles.order_status_time, (index == 0)&&styles.order_status_select)}>{formatDateTime(item.time)}</View>
{/* <View className={classnames(styles.order_status_tag, (index == 0)&&styles.order_status_tag_select)}>{item.tag}</View> */}
</View> </View>
<Text className={classnames(styles.order_status_des, (index == 0)&&styles.order_status_des_select)}>{item.desc}</Text> <Text className={classnames(styles.order_status_des, (index == 0)&&styles.order_status_des_select)}>{item.desc}</Text>
{(orderInfo.status == SaleorderstatusWaitingPrePayment.value)&&<CountDown onFinish={onRefresh} endTime={endTime}/>}
</View>)} </View>)}
</View> </View>
{(dataList.length > 2) && <View className={styles.more} onClick={() => changeMore()}> {(dataList.length > 2) && <View className={styles.more} onClick={() => changeMore()}>
@ -54,10 +71,62 @@ export default memo(({list = [], payment_method = 0}:Param) => {
<Text className={classnames('iconfont icon-a-moreback', styles.miconfonts, showMore&&styles.open_miconfonts)}></Text> <Text className={classnames('iconfont icon-a-moreback', styles.miconfonts, showMore&&styles.open_miconfonts)}></Text>
</View>} </View>}
<View className={styles.image_tag}> <View className={styles.image_tag}>
{(payment_method == PaymentMethodAccountPeriod.value)&&<Image mode="aspectFit" src={formatImgUrl('/mall/order_pay_status.png')} className={styles.image}/>} {(orderInfo.payment_method == PaymentMethodCashOnDelivery.value)&&<Image mode="aspectFit" src={formatImgUrl('/mall/order_pay_status.png')} className={styles.image}/>}
{(payment_method == PaymentMethodCashOnDelivery.value)&&<Image mode="aspectFit" src={formatImgUrl('/mall/order_pay_status_7day.png')} className={styles.image}/>} {(orderInfo.payment_method == PaymentMethodAccountPeriod.value)&&<Image mode="aspectFit" src={formatImgUrl('/mall/order_pay_status_7day.png')} className={styles.image}/>}
</View> </View>
{(orderInfo.status == SaleorderstatusWaitingPrePayment.value)&&<View className={styles.refresh} onClick={onRefresh}>
<Text className={classnames(styles.mconfont, 'iconfont icon-xianxiahuikuan')}></Text>
<Text className={classnames(styles.refresh_text)}></Text>
</View>}
</View>} </View>}
</> </>
) )
}) })
//倒计时
const CountDown = ({endTime = '', onFinish}:{endTime:string, onFinish?:() => void}) => {
const [showTime, setShowTime] = useState('')
const timeObj:any = useRef()
useEffect(() => {
if(endTime) {
clearInterval(timeObj.current)
timeObj.current = setInterval(() => {
count_down()
}, 1000)
}
return () => {
clearInterval(timeObj.current)
}
}, [endTime])
const count_down = () => {
var startData = dayjs();
var endDate = dayjs(endTime);
if(startData >= endDate) {
clearInterval(timeObj.current)
onFinish?.()
setShowTime(() => '00:00:00')
return false
}
var _dd = endDate.diff(startData,'day');
var _hh = endDate.diff(startData,'hour');
var _mm = endDate.diff(startData,'minute');
var _ss = endDate.diff(startData,'second');
// 转换
var hh = _hh - (_dd*24);
var mm = _mm - (_hh*60);
var ss = _ss - (_mm*60);
// 格式化
var DD = ('00'+_dd).slice(-2);
var HH = ('00'+hh).slice(-2);
var MM = ('00'+mm).slice(-2);
var SS = ('00'+ss).slice(-2);
setShowTime(() => ` ${HH}:${MM}:${SS}`)
}
return (
<>
<View className={styles.pay_time}>
<Text>{showTime||'--:--:--'}</Text>
</View>
</>
)
}

View File

@ -0,0 +1,35 @@
.logistics_main{
padding: 20px 30px;
box-sizing: border-box;
.logistics_image{
display: flex;
.title_desc{
font-size: 28px;
font-weight: 700;
padding-top: 50px;
box-sizing: border-box;
}
.upload_image{
flex:1;
}
}
.logistics_desc{
margin-top: 50px;
}
.btns_two{
display: flex;
height: 82px;
font-size: $font_size_big;
border-radius: 40px;
margin-top: 50px;
.verify_btn{
flex:1;
border-radius: 40px;
background: #007aff;
text-align: center;
line-height: 82px;
color: #fff;
}
}
}

View File

@ -0,0 +1,70 @@
import Popup from "@/components/popup";
import { Text, View } from "@tarojs/components";
import { memo, useCallback, useEffect, useRef, useState } from "react";
import UploadImage from "@/components/uploadImage"
import styles from './index.module.scss'
import TextareaEnhance from "@/components/textareaEnhance";
import { ReturnApplyLogisticsApi } from "@/api/salesAfterOrder";
import { alert } from "@/common/common";
type Param = {
show?: true|false,
onClose?: () => void,
onSubmit?: () => void,
id?: number //订单id
}
export default memo(({show = false, onClose, onSubmit, id = 0}: Param) => {
//需要提交的数据
const submitData = useRef({
accessory_url: [],
remark: '',
id: 0
})
useEffect(() => {
if(id) submitData.current.id = id
}, [id])
//获取图片列表
const getImageList = useCallback((list) => {
submitData.current.accessory_url = list
}, [])
//备注
const getOtherReason = useCallback((val) => {
submitData.current.remark = val
}, [])
//确定
const {fetchData} = ReturnApplyLogisticsApi()
const onSubmitEven = async () => {
if(!id) return alert.error('参数有误')
if(submitData.current.accessory_url.length <= 0) return alert.error('请上传附件')
let res = await fetchData(submitData.current)
if(res.success) {
alert.success('上传成功')
} else {
alert.error('上传失败')
}
}
return (
<>
<Popup show={show} title="上传物流" onClose={onClose}>
<View className={styles.logistics_main}>
<View className={styles.logistics_image}>
<Text className={styles.title_desc}></Text>
<View className={styles.upload_image}>
<UploadImage onChange={getImageList}/>
</View>
</View>
<View className={styles.logistics_desc}>
<TextareaEnhance onChange={getOtherReason} title="备注:" placeholder="请输入备注信息"/>
</View>
<View className={styles.btns_two}>
<View className={styles.verify_btn } onClick={() => onSubmitEven()}></View>
</View >
</View>
</Popup>
</>
)
})

View File

@ -3,18 +3,23 @@ import {
EditSaleOrderRemarkApi, EditSaleOrderRemarkApi,
} from "@/api/order"; } from "@/api/order";
import { GetOrderPayApi } from "@/api/orderPay"; import { GetOrderPayApi } from "@/api/orderPay";
import { SaleOrderOrderDetailApi } from "@/api/salesAfterOrder";
import { alert, goLink } from "@/common/common"; import { alert, goLink } from "@/common/common";
import { ORDER_STATUS } from "@/common/enum"; import { ORDER_STATUS } from "@/common/enum";
import { formatDateTime, formatImgUrl, formatPriceDiv } from "@/common/fotmat"; import { formatDateTime, formatImgUrl, formatPriceDiv } from "@/common/fotmat";
import AfterOrderBtns from "@/components/afterOrderBtns";
import OrderBtns from "@/components/orderBtns"; import OrderBtns from "@/components/orderBtns";
import SearchInput from "@/components/searchInput"; import SearchInput from "@/components/searchInput";
import { Image, Text, Textarea, View } from "@tarojs/components" import { Image, Text, Textarea, View } from "@tarojs/components"
import Taro, {useDidShow, usePullDownRefresh, useRouter } from "@tarojs/taro"; import Taro, {useDidShow, usePullDownRefresh, useRouter } from "@tarojs/taro";
import classnames from "classnames"; import classnames from "classnames";
import { useCallback, useEffect, useMemo, useRef, useState, memo } from "react"; import { useCallback, useEffect, useMemo, useRef, useState, memo } from "react";
import AddressInfoDetail from "./components/addressInfoDetail";
import ApplyRecord from "./components/applyRecord";
import ContentBox from "./components/contentBox"; import ContentBox from "./components/contentBox";
import KindList from "./components/kindList"; import KindList from "./components/kindList";
import OrderState from "./components/orderState"; import OrderState from "./components/orderState";
import ReturnLogistics from "./components/returnLogistics";
import styles from './index.module.scss' import styles from './index.module.scss'
export default () => { export default () => {
@ -27,10 +32,10 @@ import styles from './index.module.scss'
//获取订单详情 //获取订单详情
const [orderDetail, setOrderDetail] = useState<any>() //获取到的原始数据 const [orderDetail, setOrderDetail] = useState<any>() //获取到的原始数据
const {fetchData: getOrderFetchData} = GetSaleOrderDetailApi() const {fetchData: saleOrderOrderDetailData} = SaleOrderOrderDetailApi()
const getSaleOrderPreView = async () => { const getSaleOrderPreView = async () => {
if(orderId.current) { if(orderId.current) {
let res = await getOrderFetchData({id: orderId.current}) let res = await saleOrderOrderDetailData({id: orderId.current})
setOrderDetail(res.data) setOrderDetail(res.data)
} }
Taro.stopPullDownRefresh() Taro.stopPullDownRefresh()
@ -54,7 +59,8 @@ import styles from './index.module.scss'
total_fabrics: orderDetail.total_fabrics, //面料数量 total_fabrics: orderDetail.total_fabrics, //面料数量
unit: orderDetail.sale_mode == 0?'条':'m', //单位 unit: orderDetail.sale_mode == 0?'条':'m', //单位
list: orderDetail.product_list, list: orderDetail.product_list,
status: orderDetail.status, //订单状态 stage: orderDetail.stage, //订单状态
type: orderDetail.type, //退货or退款
total_sale_price: orderDetail.total_sale_price, //销售金额 total_sale_price: orderDetail.total_sale_price, //销售金额
total_should_collect_money: orderDetail.total_should_collect_money, //应收金额 total_should_collect_money: orderDetail.total_should_collect_money, //应收金额
total_weight_error_discount: orderDetail.total_weight_error_discount, //空差优惠 total_weight_error_discount: orderDetail.total_weight_error_discount, //空差优惠
@ -69,13 +75,7 @@ import styles from './index.module.scss'
//获取底部按钮点击, 获取按钮状态 //获取底部按钮点击, 获取按钮状态
const orderStateClick = useCallback((val) => { const orderStateClick = useCallback((val) => {
if(val == 1) {
//取消订单
getSaleOrderPreView()
}
if(val == 2) {
}
}, [orderDetail]) }, [orderDetail])
//页面下拉刷新 //页面下拉刷新
@ -87,34 +87,61 @@ import styles from './index.module.scss'
//按钮所需数据 //按钮所需数据
const orderInfo = useMemo(() => { const orderInfo = useMemo(() => {
return { return {
status: orderDetail?.status, //订单状态 stage: orderDetail?.stage, //售后订单状态
orderId: orderDetail?.id, orderId: orderDetail?.id,
settle_mode: orderDetail?.settle_mode, settle_mode: orderDetail?.settle_mode,
actual_amount: orderDetail?.actual_amount, //实付金额 type: orderDetail?.type, //退货or退款
wait_pay_amount: orderDetail?.wait_pay_amount, //待付金额 sale_mode: orderDetail?.sale_model, //订单类型
} }
}, [orderDetail]) }, [orderDetail])
//订单状态枚举 //订单状态枚举
const {SaleOrderStatusCancel} = ORDER_STATUS const {SaleOrderStatusCancel} = ORDER_STATUS
//物流显示
const [logisticsShow, setLogisticsShow] = useState(false)
const onShowLogistics = useCallback((val) => {
if(val == 1) {
setLogisticsShow(true)
} else {
const list = orderDetail?.fabric_piece_accessory_url.map(item => {
return formatImgUrl(item)
})
Taro.previewImage({
current: list[0], // 当前显示
urls: list // 需要预览的图片http链接列表
})
}
}, [orderDetail])
const onCloseLogistics = useCallback(() => setLogisticsShow(false), [])
//物流成功上传
const logisticsSuccess = useCallback(() => {
getSaleOrderPreView()
}, [])
//显示生气记录
const [applyRecord, setApplyRecord] = useState(false)
return ( return (
<View className={styles.order_main}> <View className={styles.order_main}>
<OrderState list={orderDetail?.logistics_details} payment_method={orderDetail?.payment_method}/> <OrderState orderInfo={orderDetail}/>
<AddressInfoDetail return_address={orderDetail?.return_address} return_phone={orderDetail?.return_phone} stage={orderDetail?.stage} onLogistics={onShowLogistics}/>
<KindList order={formatPreViewOrderMemo}/> <KindList order={formatPreViewOrderMemo}/>
<OrderDes/> <OrderDes orderInfo={orderDetail}/>
{(orderDetail?.status != SaleOrderStatusCancel.value)&&<View className={styles.submit_order}> {(orderDetail?.status != SaleOrderStatusCancel.value)&&<View className={styles.submit_order}>
<OrderBtns orderInfo={orderInfo} onClick={orderStateClick}/> <AfterOrderBtns orderInfo={orderInfo} onClick={orderStateClick}/>
</View>} </View>}
<AfterSalePricture/> <AfterSalePricture urls={orderDetail?.fabric_piece_accessory_url}/>
<ReturnLogistics show={logisticsShow} id={orderDetail?.return_apply_order_id} onClose={onCloseLogistics} onSubmit={logisticsSuccess}/>
<ApplyRecord show={applyRecord} id={orderDetail?.id} onClose={() => setApplyRecord(false)}/>
<View className="common_safe_area_y"></View> <View className="common_safe_area_y"></View>
</View> </View>
) )
} }
const OrderDes = memo(({val = ''}:{val?:string}) => { const OrderDes = memo(({orderInfo}:{orderInfo?:any}) => {
//复制功能 //复制功能
const clipboardData = () => { const clipboardData = (val) => {
Taro.setClipboardData({ Taro.setClipboardData({
data: val, data: val,
success: function (res) { success: function (res) {
@ -130,58 +157,57 @@ import styles from './index.module.scss'
<View className={styles.order_info_title}></View> <View className={styles.order_info_title}></View>
<SearchInput showBorder={false} title='售后单号' height={50}> <SearchInput showBorder={false} title='售后单号' height={50}>
<View className={styles.order_num}> <View className={styles.order_num}>
<Text>RA-LY-2204240002</Text> <Text>{orderInfo?.return_order_no}</Text>
<View className={styles.order_num_btn} onClick={() => clipboardData()}></View> <View className={styles.order_num_btn} onClick={() => clipboardData(orderInfo?.return_order_no)}></View>
</View> </View>
</SearchInput> </SearchInput>
<SearchInput showBorder={false} title='订单号' height={50}> <SearchInput showBorder={false} title='订单号' height={50}>
<View className={styles.order_num}> <View className={styles.order_num}>
<Text>XS-LY-2204210002</Text> <Text>{orderInfo?.order_no}</Text>
<View className={styles.order_num_btn} onClick={() => clipboardData()}></View> <View className={styles.order_num_btn} onClick={() => clipboardData(orderInfo?.order_no)}></View>
</View> </View>
</SearchInput> </SearchInput>
<SearchInput showBorder={false} title='退款说明' height={50}> <SearchInput showBorder={false} title='退货原因' height={50}>
<Text></Text> <Text>{orderInfo?.return_reason_name}</Text>
</SearchInput>
<SearchInput showBorder={false} title='退货说明' height={50}>
<Text>{orderInfo?.return_explain_name}</Text>
</SearchInput> </SearchInput>
<SearchInput showBorder={false} title='其它说明' height={50}> <SearchInput showBorder={false} title='其它说明' height={50}>
<Text></Text> <Text>{orderInfo?.return_remark}</Text>
</SearchInput>
<SearchInput showBorder={false} title='货物状况' height={50}>
<Text>{orderInfo?.goods_status_name}</Text>
</SearchInput> </SearchInput>
<SearchInput showBorder={false} title='申请时间' height={50}> <SearchInput showBorder={false} title='申请时间' height={50}>
<Text>2022-04-24 08:32:39</Text> <Text>{formatDateTime(orderInfo?.apply_time)}</Text>
</SearchInput> </SearchInput>
</View> </View>
) )
}) })
const AfterSalePricture = memo(() => { const AfterSalePricture = memo(({urls = []}:{urls: string[]}) => {
const showList = useMemo(() => {
let res = urls.map(item => {
return formatImgUrl(item)
})
return res
}, [urls])
//预览图片 //预览图片
const showImage = () => { const showImage = () => {
Taro.previewImage({ Taro.previewImage({
current: formatImgUrl(''), // 当前显示 current: showList[0], // 当前显示
urls: [formatImgUrl('')] // 需要预览的图片http链接列表 urls: showList // 需要预览的图片http链接列表
}) })
} }
return ( return (
<ContentBox title="售后图片"> <ContentBox title="售后图片">
<View className={styles.after_sale_picture_list}> <View className={styles.after_sale_picture_list}>
<View className={styles.after_sale_picture_item} onClick={showImage}> {urls?.map(item=> <View className={styles.after_sale_picture_item} onClick={showImage}>
<Image src={formatImgUrl('')} /> <Image src={formatImgUrl(item)} />
</View> </View>)}
<View className={styles.after_sale_picture_item} onClick={showImage}>
<Image src={formatImgUrl('')}/>
</View>
<View className={styles.after_sale_picture_item}>
<Image src={formatImgUrl('')}/>
</View>
<View className={styles.after_sale_picture_item}>
<Image src={formatImgUrl('')}/>
</View>
<View className={styles.after_sale_picture_item}>
<Image src={formatImgUrl('')}/>
</View>
<View className={styles.after_sale_picture_item}>
<Image src={formatImgUrl('')}/>
</View>
</View> </View>
</ContentBox> </ContentBox>
) )

View File

@ -14,6 +14,8 @@
font-weight: 700; font-weight: 700;
margin-left: 15px; margin-left: 15px;
font-size: $font_size; font-size: $font_size;
width: 100px;
@include common_ellipsis();
} }
image{ image{
width: 70px; width: 70px;
@ -26,7 +28,7 @@
font-size: $font_size_medium; font-size: $font_size_medium;
color: $color_font_one; color: $color_font_one;
text-align: right; text-align: right;
padding-right: 30px; padding-right: 10px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
@ -69,23 +71,22 @@
.image{ .image{
width: 126px; width: 126px;
height: 126px; height: 126px;
background: #e5ad3a; border-radius: 20px ;
border-radius: 20px 20px 0px 0px;
position: relative; position: relative;
image{ image{
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 20px 20px 0px 0px; border-radius: 20px ;
} }
.color_num { .color_num {
background: rgba(0,0,0, 0.5); background: rgba(0,0,0, 0.5);
border-radius: 50px 0px 0px 0px; border-radius: 36px 0px 20px 0px;
font-size: $font_size_min; font-size: $font_size_min;
color: #fff; color: #fff;
position: absolute; position: absolute;
right:0; right:0;
bottom:0; bottom:0;
padding: 5px 10px; padding: 5px 10px 5px 15px;
box-sizing: border-box; box-sizing: border-box;
} }
} }
@ -123,7 +124,7 @@
display: flex; display: flex;
background-color: #F6F6F6; background-color: #F6F6F6;
padding: 20px; padding: 20px;
margin-top: 20px; margin: 20px 0;
align-items: center; align-items: center;
font-size: $font_size_medium; font-size: $font_size_medium;
border-radius: 10px; border-radius: 10px;

View File

@ -1,6 +1,7 @@
import { goLink } from "@/common/common"; import { goLink } from "@/common/common";
import { formatHashTag, formatImgUrl, formatPriceDiv } from "@/common/fotmat"; import { formatHashTag, formatImgUrl, formatPriceDiv } from "@/common/fotmat";
import OrderBtns from "@/components/orderBtns"; import AfterOrderBtns from "@/components/afterOrderBtns";
import LabAndImg from "@/components/LabAndImg";
import { useSelector } from "@/reducers/hooks"; import { useSelector } from "@/reducers/hooks";
import { Image, Text, View } from "@tarojs/components" import { Image, Text, View } from "@tarojs/components"
import classnames from "classnames"; import classnames from "classnames";
@ -11,20 +12,21 @@ import styles from './index.module.scss'
type Param = { type Param = {
value: { value: {
order_no: string, order_no: string,
return_order_no: string,
sale_mode: number, sale_mode: number,
sale_mode_name: string, sale_mode_name: string,
status_name: string, stage_name: string,
shipment_mode_name: string, shipment_mode_name: string,
product_list: any[], product_list: any[],
total_fabrics: number, total_fabrics: number,
total_colors: number, total_colors: number,
total_number: number, total_number: number,
status: 0, stage: 0,
id: number, id: number,
payment_method: number, //支付方式 lab: {l:number, a:number, b:number},
actual_amount: number, //实付金额 rgb: {r:number, g:number, b:number},
wait_pay_amount: number //待付金额 texturl_url: string,
should_collect_order_id: number //应付单id type: number //1 退货 2退款
}, },
onClickBtn?: (val:{status:number, orderInfo:Param['value']}) => void onClickBtn?: (val:{status:number, orderInfo:Param['value']}) => void
} }
@ -47,13 +49,18 @@ export default memo(({value, onClickBtn}: Param) => {
//按钮所需数据 //按钮所需数据
const orderInfo = useMemo(() => { const orderInfo = useMemo(() => {
return { return {
status: value?.status, //订单状态 stage: value?.stage, //订单状态
orderId: value?.id, orderId: value?.id,
actual_amount: value?.actual_amount, //实付金额 sale_mode: value?.sale_mode, //订单类型
wait_pay_amount: value?.wait_pay_amount, //待付金额 type: value?.type //退货or退款
} }
}, [value]) }, [value])
//整理颜色
const labAndRgbAndUrl = useMemo(() => {
return {lab:{...value?.lab}, rgb:{...value?.rgb}, texturl_url: value?.texturl_url}
}, [value])
return ( return (
<View className={styles.order_item}> <View className={styles.order_item}>
<View className={styles.header} onClick={() => goLink('/pages/salesAfter/index', {id: value?.id})}> <View className={styles.header} onClick={() => goLink('/pages/salesAfter/index', {id: value?.id})}>
@ -62,20 +69,20 @@ export default memo(({value, onClickBtn}: Param) => {
<Text className={styles.name}>{userInfo?.adminUserInfo?.user_name}</Text> <Text className={styles.name}>{userInfo?.adminUserInfo?.user_name}</Text>
</View> </View>
<View className={styles.order_num}> <View className={styles.order_num}>
<Text>{value?.order_no}</Text> <Text>{value?.return_order_no}</Text>
<Text className={classnames(styles.miconfont, 'iconfont, icon-a-moreback')}></Text> <Text className={classnames(styles.miconfont, 'iconfont, icon-a-moreback')}></Text>
</View> </View>
<OrderStatusTag status={1}/> <OrderStatusTag status={value?.type}/>
</View> </View>
<View className={styles.product_con} onClick={() => goLink('/pages/salesAfter/index', {id: value?.id})}> <View className={styles.product_con} onClick={() => goLink('/pages/salesAfter/index', {id: value?.id})}>
<View className={styles.product_title}> <View className={styles.product_title}>
<View className={styles.product_tag}>{value?.sale_mode_name}</View> <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_name}>{formatHashTag(value?.product_list[0].code, value?.product_list[0].name)}</View>
<View className={styles.product_status}>{value?.status_name}</View> <View className={styles.product_status}>{value?.stage_name}</View>
</View> </View>
<View className={styles.product_list}> <View className={styles.product_list}>
<View className={styles.image}> <View className={styles.image}>
<Image src={formatImgUrl(value?.product_list[0].product_colors[0].texture_url)}/> <LabAndImg value={labAndRgbAndUrl}/>
<View className={styles.color_num}>{value?.product_list[0].product_colors[0].code}</View> <View className={styles.color_num}>{value?.product_list[0].product_colors[0].code}</View>
</View> </View>
<View className={styles.color_list}> <View className={styles.color_list}>
@ -98,11 +105,11 @@ export default memo(({value, onClickBtn}: Param) => {
</View> </View>
<View className={styles.color_count_num}>{`${value?.total_fabrics}种面料,${value?.total_colors}种颜色,共${value?.total_number}`}</View> <View className={styles.color_count_num}>{`${value?.total_fabrics}种面料,${value?.total_colors}种颜色,共${value?.total_number}`}</View>
<View className={styles.order_number}> <View className={styles.order_number}>
<Text>退</Text> <Text>{value?.type == 1?'已申请退货':'已申请退款'}</Text>
<Text>LY2278204399678</Text> <Text>{value?.order_no}</Text>
</View> </View>
</View> </View>
<OrderBtns orderInfo={orderInfo} onClick={orderBtnsClick}/> <AfterOrderBtns orderInfo={orderInfo} onClick={orderBtnsClick}/>
</View> </View>
) )
}) })

View File

@ -5,14 +5,14 @@ import styles from './index.module.scss'
type Param = { type Param = {
status?: 0|1|2 //0默认不处理, 1退2退货 status?: 0|1|2 //0默认不处理, 1退2退款
} }
export default memo(({status = 0}:Param) => { export default memo(({status = 0}:Param) => {
return ( return (
<> <>
{(status !== 0)&&<View className={classnames(styles.tag, status == 1?styles.refund_tag :styles.saleReturn_tag)}> {(status !== 0)&&<View className={classnames(styles.tag, status == 2?styles.refund_tag :styles.saleReturn_tag)}>
<View className={classnames(styles.miconfont, 'iconfont icon-yucunkuan')}></View> <View className={classnames(styles.miconfont, 'iconfont icon-yucunkuan')}></View>
<Text>{ status == 1?'退款':'退货'}</Text> <Text>{ status == 1?'退货':'退款'}</Text>
</View>} </View>}
</> </>
) )

View File

@ -0,0 +1,35 @@
.logistics_main{
padding: 20px 30px;
box-sizing: border-box;
.logistics_image{
display: flex;
.title_desc{
font-size: 28px;
font-weight: 700;
padding-top: 50px;
box-sizing: border-box;
}
.upload_image{
flex:1;
}
}
.logistics_desc{
margin-top: 50px;
}
.btns_two{
display: flex;
height: 82px;
font-size: $font_size_big;
border-radius: 40px;
margin-top: 50px;
.verify_btn{
flex:1;
border-radius: 40px;
background: #007aff;
text-align: center;
line-height: 82px;
color: #fff;
}
}
}

View File

@ -0,0 +1,70 @@
import Popup from "@/components/popup";
import { Text, View } from "@tarojs/components";
import { memo, useCallback, useEffect, useRef, useState } from "react";
import UploadImage from "@/components/uploadImage"
import styles from './index.module.scss'
import TextareaEnhance from "@/components/textareaEnhance";
import { ReturnApplyLogisticsApi } from "@/api/salesAfterOrder";
import { alert } from "@/common/common";
type Param = {
show?: true|false,
onClose?: () => void,
onSubmit?: () => void,
id?: number //订单id
}
export default memo(({show = false, onClose, onSubmit, id = 0}: Param) => {
//需要提交的数据
const submitData = useRef({
accessory_url: [],
remark: '',
id: 0
})
useEffect(() => {
if(id) submitData.current.id = id
}, [id])
//获取图片列表
const getImageList = useCallback((list) => {
submitData.current.accessory_url = list
}, [])
//备注
const getOtherReason = useCallback((val) => {
submitData.current.remark = val
}, [])
//确定
const {fetchData} = ReturnApplyLogisticsApi()
const onSubmitEven = async () => {
if(!id) return alert.error('参数有误')
if(submitData.current.accessory_url.length <= 0) return alert.error('请上传附件')
let res = await fetchData(submitData.current)
if(res.success) {
alert.success('上传成功')
} else {
alert.error('上传失败')
}
}
return (
<>
<Popup show={show} title="上传物流" onClose={onClose}>
<View className={styles.logistics_main}>
<View className={styles.logistics_image}>
<Text className={styles.title_desc}></Text>
<View className={styles.upload_image}>
<UploadImage onChange={getImageList}/>
</View>
</View>
<View className={styles.logistics_desc}>
<TextareaEnhance onChange={getOtherReason} title="备注:" placeholder="请输入备注信息"/>
</View>
<View className={styles.btns_two}>
<View className={styles.verify_btn } onClick={() => onSubmitEven()}></View>
</View >
</View>
</Popup>
</>
)
})

View File

@ -12,6 +12,8 @@ import { dataLoadingStatus, getFilterData } from "@/common/util"
import OrderStatusList from "./components/orderStatusList" import OrderStatusList from "./components/orderStatusList"
import Payment from "../order/components/payment" import Payment from "../order/components/payment"
import { AFTER_ORDER_STATUS } from "@/common/enum" import { AFTER_ORDER_STATUS } from "@/common/enum"
import { GetSaleOrderListApi } from "@/api/salesAfterOrder"
import ReturnLogistics from "./components/returnLogistics"
export default () => { export default () => {
const {checkLogin} = useLogin() const {checkLogin} = useLogin()
@ -40,7 +42,7 @@ export default () => {
}, []) }, [])
//获取订单列表 //获取订单列表
const {fetchData: listFetchData, state:orderState} = GetOrderListApi() const {fetchData: listFetchData, state:orderState} = GetSaleOrderListApi()
const [orderData, setOrderData] = useState<{list:any[], total:number}>({list:[], total:0}) const [orderData, setOrderData] = useState<{list:any[], total:number}>({list:[], total:0})
const getOrderList = async () => { const getOrderList = async () => {
let res = await listFetchData(getFilterData(searchField)) let res = await listFetchData(getFilterData(searchField))
@ -96,28 +98,14 @@ export default () => {
//监听点击的按钮 //监听点击的按钮
const clickOrderBtn = useCallback(({status, orderInfo}) => { const clickOrderBtn = useCallback(({status, orderInfo}) => {
if(status == 2) { if(status == 2) {
//去支付 //退货物流
setPayOrderInfo({orderId:orderInfo.should_collect_order_id, payment_method:orderInfo.payment_method})
toPay()
} }
}, [orderData]) }, [orderData])
//物流显示
//去付款 const [logisticsShow, setLogisticsShow] = useState(false)
const [payOrderInfo, setPayOrderInfo] = useState<any>() const onCloseLogistics = useCallback(() => setLogisticsShow(false), [])
const [payMentShow, setPayMentShow] = useState(false)
const toPay = () => {
setPayMentShow(true)
}
//关闭支付弹窗
const closePayShow = useCallback(() => {
setPayMentShow(() => false)
}, [])
//支付成功
const onPaySuccess = useCallback(() => {
getOrderList()
closePayShow()
}, [])
return ( return (
@ -132,8 +120,8 @@ export default () => {
return <View key={item.id} className={styles.order_item_con}> <Order value={item} onClickBtn={clickOrderBtn}/></View> return <View key={item.id} className={styles.order_item_con}> <Order value={item} onClickBtn={clickOrderBtn}/></View>
})} })}
</InfiniteScroll> </InfiniteScroll>
<ReturnLogistics show={logisticsShow} onClose={onCloseLogistics}/>
</View> </View>
<Payment onSubmitSuccess={onPaySuccess} show={payMentShow} onClose={closePayShow} orderInfo={payOrderInfo}/>
</View> </View>
) )
} }

View File

@ -67,7 +67,7 @@ const Header = memo((props:any) => {
const {data} = props; const {data} = props;
let menu = [{ text: "待配布", icon: "icon-daipeibu", url: "/pages/orderList/index" }, { text: "待付款", icon: "icon-daifukuan", url: "/pages/orderList/index" }, let menu = [{ text: "待配布", icon: "icon-daipeibu", url: "/pages/orderList/index" }, { text: "待付款", icon: "icon-daifukuan", url: "/pages/orderList/index" },
{ text: "待发货", icon: "icon-daifahuo", url: "/pages/orderList/index" }, { text: "已发货", icon: "icon-yifahuo", url: "/pages/orderList/index" }, { text: "待发货", icon: "icon-daifahuo", url: "/pages/orderList/index" }, { text: "已发货", icon: "icon-yifahuo", url: "/pages/orderList/index" },
{ text: "退款/售后", icon: "icon-a-tuikuanshouhou", url: "/pages/orderList/index" }]; { text: "退款/售后", icon: "icon-a-tuikuanshouhou", url: "/pages/salesAfterList/index" }];
const { getPhoneNumber } = useLogin(); const { getPhoneNumber } = useLogin();
const mGetPhoneNumber = (ev)=>{ const mGetPhoneNumber = (ev)=>{
if(ev.detail?.code){ if(ev.detail?.code){

View File

@ -110,7 +110,7 @@ export const useRequest = (options:option = {
success: false, // 请求是否成功 success: false, // 请求是否成功
data: {}, data: {},
msg: '', msg: '',
loading: true, loading: false,
error: null, error: null,
query: {}, query: {},
filter: null, filter: null,
@ -127,7 +127,7 @@ export const useRequest = (options:option = {
const {login} = useLoginRequest() const {login} = useLoginRequest()
useEffect(() => { useEffect(() => {
console.log('变化::', state.loading) console.log('变化1::', state.loading)
}, [state.loading]) }, [state.loading])
// 请求函数 // 请求函数
const fetchData = async (sub_options?:any) => { const fetchData = async (sub_options?:any) => {

View File

@ -1,6 +1,6 @@
import useUserInfo from "./useUserInfo" import useUserInfo from "./useUserInfo"
import Taro, { useRouter } from "@tarojs/taro" import Taro, { useRouter } from "@tarojs/taro"
import { GetWxUserInfoApi, GetAdminUserInfoApi, GetPhoneNumberApi } from "@/api/user" import { GetWxUserInfoApi, GetAdminUserInfoApi, GetPhoneNumberApi, BindingCompanyApi } from "@/api/user"
import useLoginRequest from "./useLoginRequest" import useLoginRequest from "./useLoginRequest"
import { SHARE_SCENE } from "@/common/enum" import { SHARE_SCENE } from "@/common/enum"
import { GetShortCodeApi } from "@/api/share" import { GetShortCodeApi } from "@/api/share"
@ -93,6 +93,7 @@ export default () => {
//获取手机号码 //获取手机号码
const {fetchData: fetchDataUserPhone} = GetPhoneNumberApi() const {fetchData: fetchDataUserPhone} = GetPhoneNumberApi()
const {fetchData: fetchBindingCompany} = BindingCompanyApi()
const getPhoneNumber = (code) => { const getPhoneNumber = (code) => {
return new Promise( async (reslove, reject) => { return new Promise( async (reslove, reject) => {
if(userInfo.adminUserInfo?.is_authorize_phone) { if(userInfo.adminUserInfo?.is_authorize_phone) {
@ -102,6 +103,7 @@ export default () => {
const res = await fetchDataUserPhone({code}) const res = await fetchDataUserPhone({code})
if(res.success) { if(res.success) {
setUserInfo({...userInfo.userInfo, phone:res.data.phone_number}) setUserInfo({...userInfo.userInfo, phone:res.data.phone_number})
await fetchBindingCompany()
getAdminUserInfo() getAdminUserInfo()
reslove(res.data) reslove(res.data)
} else { } else {

View File

@ -126,7 +126,7 @@ export default () => {
const getWxPhoto = (cdn_upload_type: cdn_upload_type_Param) => { const getWxPhoto = (cdn_upload_type: cdn_upload_type_Param) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Taro.chooseImage({ Taro.chooseImage({
count: 1, // 默认9 count: 1,
sizeType: ['original', 'compressed'], sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'], sourceType: ['album', 'camera'],
success: async function (res) { success: async function (res) {