Merge branch 'dev' of http://git.online.zzfzyc.com/mp/EShop into dev
This commit is contained in:
@@ -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>
|
||||
)
|
||||
})
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
})
|
||||
@@ -4,19 +4,25 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
.reduce, .plus{
|
||||
font-size: $font_size_big;
|
||||
.plus{
|
||||
color: $color_main;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content:center;
|
||||
text-align: center;
|
||||
line-height: 43px;
|
||||
font-size: 50px;
|
||||
background-color: $color_main;
|
||||
color: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.reduce {
|
||||
font-size: 50px;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
text-align: center;
|
||||
line-height: 43px;
|
||||
color:#007AFF;
|
||||
}
|
||||
.input{
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
@@ -25,10 +31,13 @@
|
||||
box-sizing: border-box;
|
||||
width: 106px;
|
||||
border-radius: 10px;
|
||||
input{
|
||||
font-size: $font_size_medium;
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
input{
|
||||
font-size: $font_size_medium;
|
||||
}
|
||||
|
||||
.unit{
|
||||
font-size: $font_size_min;
|
||||
color: $color_font_two;
|
||||
|
||||
@@ -11,12 +11,14 @@ type params = {
|
||||
onChange?:(val:number) => void,
|
||||
onBlue?:(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 onPlus = () => {
|
||||
if(disable) return false
|
||||
let {count} = value
|
||||
let num_res = Big(count).add(step).toNumber()
|
||||
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))
|
||||
}
|
||||
const minus = () => {
|
||||
if(disable) return false
|
||||
let {count} = value
|
||||
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})
|
||||
onChange?.(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}
|
||||
onBlur={onBluerEven}
|
||||
type='digit'
|
||||
disabled={disable}
|
||||
/>
|
||||
<View className={styles.unit}>{unit}</View>
|
||||
</View>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -74,6 +74,11 @@
|
||||
&: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;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
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 { ScrollView, Text, View } from "@tarojs/components"
|
||||
import {Text, View } from "@tarojs/components"
|
||||
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 { AddShoppingCartApi } from "@/api/shopCart"
|
||||
|
||||
type Param = {
|
||||
orderInfo: {
|
||||
@@ -29,7 +31,8 @@ export default memo(({orderInfo, onClick}:Param) => {
|
||||
SaleOrderStatusWaitingPayment,
|
||||
SaleOrderStatusWaitingReceipt,
|
||||
SaleOrderStatusAlreadyReceipt,
|
||||
SaleorderstatusWaitingPrePayment
|
||||
SaleorderstatusWaitingPrePayment,
|
||||
SaleOrderStatusTaking
|
||||
} = ORDER_STATUS
|
||||
|
||||
//订单类型
|
||||
@@ -41,6 +44,7 @@ export default memo(({orderInfo, onClick}:Param) => {
|
||||
|
||||
//订单按钮按订单状态归类, value是该订单状态,可能该按钮会出现
|
||||
const orderBtnsList = useRef([
|
||||
|
||||
{
|
||||
id: 1,
|
||||
value: [SaleOrderStatusBooking.value,
|
||||
@@ -50,14 +54,9 @@ export default memo(({orderInfo, onClick}:Param) => {
|
||||
SaleOrderStatusWaitingDelivery.value], //取消订单按钮对应: 待接单,配布中,已配布, 待付款, 待发货
|
||||
label: '取消订单'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
value: [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusWaitingPayment.value, SaleOrderStatusWaitingDelivery.value, SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value], //去付款按钮对应:待付款, 待发货, 待收货, 已收货, 已完成
|
||||
label: '去付款'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
value: [SaleOrderStatusWaitingDelivery.value], //申请退款按钮对应: 待发货
|
||||
value: [SaleOrderStatusWaitingDelivery.value, SaleOrderStatusTaking.value], //申请退款按钮对应: 待发货, 提货中
|
||||
label: '申请退款'
|
||||
},
|
||||
// {
|
||||
@@ -85,6 +84,11 @@ export default memo(({orderInfo, onClick}:Param) => {
|
||||
value: [SaleOrderStatusBooking.value], //按钮对应: 待接单
|
||||
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) => {
|
||||
(val == 1)&&cancelOrder(); //取消订单按钮
|
||||
(val == 2)&&onClick?.(2); //去付款按钮
|
||||
(val == 6)&&receiveOrder(); //确认收货
|
||||
|
||||
if (val == 1) {
|
||||
cancelOrder()
|
||||
} 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 styleTop = useMemo(() => {
|
||||
@@ -194,7 +204,7 @@ export default memo(({orderInfo, onClick}:Param) => {
|
||||
|
||||
<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>
|
||||
(index < 3)&&<View key={item.id} className={classnames(styles.btns_item)} onClick={() => submitBtns(item.id, index)}>{item.label}</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
border-radius: 10px;
|
||||
}
|
||||
.num{
|
||||
padding: 5px 10px;
|
||||
padding: 5px 10px 5px 20px;
|
||||
font-size: $font_size_min;
|
||||
position: absolute;
|
||||
right:0;
|
||||
@@ -51,7 +51,7 @@
|
||||
.tag_list{
|
||||
display: flex;
|
||||
margin-top: 16px;
|
||||
.tag{
|
||||
.tag, .tag_g{
|
||||
padding: 3px 10px;
|
||||
background-color: #CDE5FF;
|
||||
font-size: $font_size_min;
|
||||
@@ -61,6 +61,10 @@
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.tag_g{
|
||||
background-color: #FFE6CE;
|
||||
color: #EE7500;
|
||||
}
|
||||
}
|
||||
.introduce{
|
||||
font-size: $font_size_medium;
|
||||
|
||||
@@ -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.tag_list}>
|
||||
<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 className={styles.introduce}>{item.component}</View>
|
||||
{desStatus&&<View className={styles.des}>{item.describe}</View>}
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.count_all{
|
||||
font-size: 22px;
|
||||
color: #ABABAB;
|
||||
padding: 30px 20px;
|
||||
}
|
||||
.search{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -104,6 +109,15 @@
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
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{
|
||||
font-size: $font_size;
|
||||
font-weight: 700;
|
||||
@@ -150,6 +164,7 @@
|
||||
justify-content: center;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
z-index: 999;
|
||||
.buy_con{
|
||||
width: 702px;
|
||||
height: 95px;
|
||||
|
||||
@@ -8,10 +8,11 @@ import styles from "./index.module.scss"
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import Taro from "@tarojs/taro";
|
||||
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 { setParam } from "@/common/system";
|
||||
import { debounce } from "@/common/util";
|
||||
import Counter from "../counter";
|
||||
|
||||
type param = {
|
||||
show?: true|false,
|
||||
@@ -19,11 +20,9 @@ type param = {
|
||||
}
|
||||
export default ({show = false, onClose}: param) => {
|
||||
const selectList = [
|
||||
// {value:-1, title:'不限', unit:'', eunit:''},
|
||||
{value:0, title:'大货', unit:'件', eunit:'kg'},
|
||||
{value:1,title:'剪板', unit:'米', eunit:'m'},
|
||||
{value:2,title:'散剪', unit:'米', eunit:'kg'},
|
||||
|
||||
{value:0, title:'大货', unit:'条', eunit:'kg', step:1, digits:0, minNum:1, maxNum:100000, defaultNum:1},
|
||||
{value:1,title:'剪板', unit:'米', eunit:'m', step:1, digits:2, minNum:0.5, maxNum:9.99, defaultNum:1},
|
||||
{value:2,title:'散剪', unit:'米', eunit:'kg', step:1, digits:2, minNum:5, maxNum:100000, defaultNum:10},
|
||||
]
|
||||
|
||||
const [selectIndex, setSelectIndex] = useState(0)
|
||||
@@ -53,7 +52,6 @@ export default ({show = false, onClose}: param) => {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const {fetchData} = GetShoppingCartApi()
|
||||
const getShoppingCart = async () => {
|
||||
setLoading(true)
|
||||
const {data} = await fetchData()
|
||||
let color_list = data.color_list||[]
|
||||
initList(color_list)
|
||||
@@ -65,6 +63,7 @@ export default ({show = false, onClose}: param) => {
|
||||
const initList = (color_list) => {
|
||||
color_list?.map(item => {
|
||||
if(selectIndex == item.sale_mode) item.select = true
|
||||
item.count = formatCount(item)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -74,6 +73,7 @@ export default ({show = false, onClose}: param) => {
|
||||
setList([])
|
||||
setSelectIndex(0)
|
||||
} else {
|
||||
setLoading(true)
|
||||
getShoppingCart()
|
||||
}
|
||||
}, [show])
|
||||
@@ -136,11 +136,13 @@ export default ({show = false, onClose}: param) => {
|
||||
//删除购物车内容
|
||||
const {fetchData:delShopFetchData} = DelShoppingCartApi()
|
||||
const delSelect = () => {
|
||||
getSelectId()
|
||||
if(selectIds.current.length <= 0) return alert.none('请选择要删除的面料!')
|
||||
Taro.showModal({
|
||||
content: '删除所选商品?',
|
||||
success: async function (res) {
|
||||
if (res.confirm) {
|
||||
getSelectId()
|
||||
|
||||
const res = await delShopFetchData({id:selectIds.current})
|
||||
if(res.success) {
|
||||
getShoppingCart()
|
||||
@@ -180,17 +182,33 @@ export default ({show = false, onClose}: param) => {
|
||||
|
||||
//格式化数量
|
||||
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(() => {
|
||||
let count = 0
|
||||
let estimate_amount = 0
|
||||
let product_list = new Set() //面料
|
||||
let color_count = 0 //颜色数量
|
||||
let all_count = 0 //总数量
|
||||
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])
|
||||
|
||||
|
||||
//去结算
|
||||
const orderDetail = debounce(() => {
|
||||
@@ -199,11 +217,25 @@ export default ({show = false, onClose}: param) => {
|
||||
alert.error('请选择面料')
|
||||
} else {
|
||||
let ids = selectIds.current.join('-')
|
||||
setParam({ids, sale_mode:selectIndex})
|
||||
setParam({ids, sale_mode:selectIndex}) //临时存储
|
||||
closePopup()
|
||||
goLink('/pages/order/comfirm')
|
||||
}
|
||||
}, 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 (
|
||||
<View className={styles.shop_cart_main}>
|
||||
@@ -216,6 +248,7 @@ export default ({show = false, onClose}: param) => {
|
||||
删除所选
|
||||
</View>
|
||||
</View>
|
||||
<View className={styles.count_all}>{estimatePrice.countText}</View>
|
||||
<View className={styles.search}>
|
||||
{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>
|
||||
@@ -240,7 +273,20 @@ export default ({show = false, onClose}: param) => {
|
||||
</View>
|
||||
<View className={styles.count}>
|
||||
<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>
|
||||
})}
|
||||
@@ -258,11 +304,11 @@ export default ({show = false, onClose}: param) => {
|
||||
<View className={classnames('iconfont', 'icon-gouwuche', styles.miconfont)}></View>
|
||||
</View>
|
||||
<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>
|
||||
<View className={styles.goPay} onClick={() => orderDetail()}>
|
||||
去结算
|
||||
去结算({estimatePrice.color_count})
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -29,8 +29,9 @@
|
||||
|
||||
}
|
||||
.sideBar_select_title_select{
|
||||
background-color: $color_bg_one;
|
||||
color: $color_font_one;
|
||||
background-color: #007AFF;
|
||||
color: #fff;
|
||||
border-radius: 0px 14px 14px 0px;
|
||||
}
|
||||
}
|
||||
.sideBar_con{
|
||||
|
||||
@@ -104,7 +104,6 @@ export default memo(({list = [],
|
||||
)
|
||||
})
|
||||
}
|
||||
<View className="common_safe_area_y"></View>
|
||||
</ScrollView>
|
||||
<View className={styles.sideBar_con}>
|
||||
<InfiniteScroll statusMore={statusMore} hasMore={hasMore} selfonScrollToLower={() => selfOnScrolltolower?.()} refresherTriggered={refresherTriggered} refresherEnabled={true} selfOnRefresherRefresh={() => selfOnRefresherRefresh?.()}>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
})
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user