299 lines
13 KiB
TypeScript
299 lines
13 KiB
TypeScript
import { Text, View } from '@tarojs/components'
|
||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||
import classnames from 'classnames'
|
||
import AmountShow from '../amountShow'
|
||
import OfflinePay from '../offlinePay'
|
||
import ScanPay from '../scanPay'
|
||
import styles from './index.module.scss'
|
||
import MCheckbox from '@/components/checkbox'
|
||
import Popup from '@/components/popup'
|
||
import { GetOrderPayApi, GetPrepayOrderPayApi, SubmitOrderPayApi, SubmitPrepayOrderPayApi, SubmitTradeOrderPayApi } from '@/api/orderPay'
|
||
import { formatPriceDiv } from '@/common/fotmat'
|
||
import { alert } from '@/common/common'
|
||
import { ORDER_STATUS, PAYMENT_METHOD, SUBSCRIPTION_MESSAGE_SCENE } from '@/common/enum'
|
||
import { UseSubscriptionMessage } from '@/use/useCommon'
|
||
import { throttle } from '@/common/util'
|
||
import IconFont from '@/components/iconfont/iconfont'
|
||
import usePayBank from '@/use/usePayBank'
|
||
|
||
interface Param {
|
||
show?: true | false
|
||
onClose?: () => void
|
||
onSubmitSuccess?: () => void // 支付成功
|
||
orderInfo?: OrderInfo
|
||
}
|
||
|
||
interface OrderInfo {
|
||
id?: number // 销售单id
|
||
should_collect_order_id?: number // 应付单id
|
||
pre_collect_order_id?: number // 预付单id
|
||
status?: number // 订单状态
|
||
payment_method?: number // 支付方式
|
||
sale_mode?: number // 订单类型 0:大货 1剪板 2散剪
|
||
actual_weight?: number // 实际重量
|
||
estimate_weight?: number // 预估重量
|
||
[val: string]: any
|
||
}
|
||
|
||
type PayStatus = 1 | 2 | 3 | 4 | 5 | null // 1:预存款, 2:账期,3:线下汇款, 4:扫码支付, 5:货到付款
|
||
const Payment = ({ show = false, onClose, orderInfo, onSubmitSuccess }: Param) => {
|
||
// 支付方式枚举
|
||
const { PaymentMethodPreDeposit, PaymentMethodAccountPeriod, PaymentMethodCashOnDelivery } = PAYMENT_METHOD
|
||
// 订单状态枚举
|
||
const { SaleorderstatusWaitingPrePayment } = ORDER_STATUS
|
||
|
||
// 提交参数
|
||
const [submitData, setSubmitData] = useState<{ id: number; payment_method: PayStatus }>({
|
||
id: 0,
|
||
payment_method: null,
|
||
})
|
||
|
||
// 线下付款
|
||
const [offlinePayShow, setofflinePayShow] = useState(false)
|
||
const onShowOfflinePay = () => {
|
||
setofflinePayShow(true)
|
||
// onClose?.()
|
||
}
|
||
|
||
// 扫码支付
|
||
const [scanPayShow, setScanPayShow] = useState(false)
|
||
const onShowScanPay = () => {
|
||
setScanPayShow(true)
|
||
onClose?.()
|
||
}
|
||
|
||
// 获取支付方式数据
|
||
const [payInfo, setPayInfo] = useState<any>()
|
||
const { fetchData: orderFetchData } = GetOrderPayApi()
|
||
const { fetchData: prepayOrderFetchData } = GetPrepayOrderPayApi()
|
||
const getOrderPay = async() => {
|
||
if (orderInfo && orderInfo.should_collect_order_id) {
|
||
// 有应收单id时用应收单获取数据
|
||
const { data } = await orderFetchData({ id: orderInfo?.should_collect_order_id })
|
||
setPayInfo(() => data)
|
||
}
|
||
else {
|
||
// 用预付单id获取支付信息
|
||
const { data } = await prepayOrderFetchData({ id: orderInfo?.pre_collect_order_id })
|
||
setPayInfo(() => data)
|
||
}
|
||
}
|
||
useEffect(() => {
|
||
if (show && orderInfo && (orderInfo?.should_collect_order_id || orderInfo?.pre_collect_order_id)) {
|
||
const id = orderInfo.should_collect_order_id || orderInfo.pre_collect_order_id
|
||
setSubmitData(val => ({ ...val, id: id as number }))
|
||
getOrderPay()
|
||
}
|
||
}, [show, orderInfo])
|
||
|
||
// 预存款选择
|
||
const advanceRef = useRef<any>(null)
|
||
const advanceSelectData = useCallback((val) => {
|
||
setSubmitData(e => ({ ...e, payment_method: val }))
|
||
}, [])
|
||
const changeSelect = () => {
|
||
advanceRef.current.onSelectEven()
|
||
}
|
||
|
||
// 账期选择
|
||
const accountPeriodRef = useRef<any>(null)
|
||
const periodSelectData = (val) => {
|
||
setSubmitData(e => ({ ...e, payment_method: val }))
|
||
}
|
||
const accountPeriodSelect = () => {
|
||
accountPeriodRef.current.onSelectEven()
|
||
}
|
||
|
||
// 订阅消息
|
||
const { ToPay } = SUBSCRIPTION_MESSAGE_SCENE
|
||
const { openSubscriptionMessage } = UseSubscriptionMessage()
|
||
|
||
// 提交支付
|
||
const { fetchData: submitFetchData } = SubmitOrderPayApi() // 应收单提交
|
||
const { fetchData: submitPrepayOrderFetchData } = SubmitPrepayOrderPayApi() // 预付单提交
|
||
const submitPay = throttle(async() => {
|
||
if (submitData.payment_method === null) {
|
||
alert.error('请选择支付方式')
|
||
return false
|
||
}
|
||
// 账期支付,或预付款并且不是剪板才会订阅
|
||
if (
|
||
(submitData.payment_method == PaymentMethodAccountPeriod.value || orderInfo?.status == SaleorderstatusWaitingPrePayment.value)
|
||
&& orderInfo?.sale_mode != 1
|
||
) {
|
||
await openSubscriptionMessage({ orderId: orderInfo?.id, scenes: ToPay.value })
|
||
}
|
||
alert.showLoading('正在支付')
|
||
let res: any = null
|
||
if (orderInfo?.should_collect_order_id) {
|
||
res = await submitFetchData(submitData)
|
||
}
|
||
else {
|
||
res = await submitPrepayOrderFetchData(submitData)
|
||
}
|
||
if (res.success) {
|
||
alert.success('支付成功')
|
||
onSubmitSuccess?.()
|
||
}
|
||
else {
|
||
alert.none(res.msg)
|
||
}
|
||
alert.hideLoading()
|
||
}, 800)
|
||
|
||
// 预付款
|
||
const advance_payment = useMemo(() => {
|
||
const price = payInfo?.should_collect_money - payInfo?.amount_paid
|
||
return (
|
||
<View className={styles.payment_list_item_left_price}>
|
||
{payInfo?.advance_deposit_balance < price && '余额不足,'}剩余 ¥{formatPriceDiv(payInfo?.advance_deposit_balance)}
|
||
</View>
|
||
)
|
||
}, [payInfo])
|
||
|
||
// 是否显示七天账期
|
||
const show_account_payment = useMemo(() => {
|
||
// 剪板和散剪不显示
|
||
if (orderInfo?.sale_mode != 0) { return false }
|
||
// 支付方式是账期支付,不显示
|
||
if (orderInfo?.payment_method == PaymentMethodAccountPeriod.value) { return false }
|
||
// 支付方式是货到付款,不显示
|
||
if (orderInfo?.payment_method == PaymentMethodCashOnDelivery.value) { return false }
|
||
// 订单状态是预付款,不显示
|
||
if (orderInfo?.status == SaleorderstatusWaitingPrePayment.value) { return false }
|
||
return true
|
||
}, [orderInfo])
|
||
|
||
// 账期
|
||
const account_peyment = useMemo(() => {
|
||
const price = payInfo?.should_collect_money - payInfo?.amount_paid
|
||
return (
|
||
<View className={styles.payment_list_item_left_price}>
|
||
{payInfo?.account_period_credit_available_line < price && '额度不足, '}剩余 ¥{formatPriceDiv(payInfo?.account_period_credit_available_line)}
|
||
</View>
|
||
)
|
||
}, [payInfo])
|
||
|
||
// 在线支付所需数据
|
||
const onlinePayData = useMemo(() => {
|
||
return { ...orderInfo, ...payInfo }
|
||
}, [orderInfo, payInfo])
|
||
|
||
// 直接微信支付事件
|
||
const { pullBank, payStatus } = usePayBank()
|
||
const onBankPay = useCallback(() => {
|
||
pullBank({ merchId: payInfo.merch_id, custMerchId: payInfo.pay_no })
|
||
}, [payInfo])
|
||
|
||
const { fetchData: SubmitTradeOrderPayData } = SubmitTradeOrderPayApi()
|
||
useEffect(() => {
|
||
if (payStatus) {
|
||
(async() => {
|
||
const res = await SubmitTradeOrderPayData()
|
||
if (res.success) {
|
||
onSubmitSuccess?.()
|
||
}
|
||
})()
|
||
}
|
||
}, [payStatus])
|
||
|
||
return (
|
||
<View className={styles.payment_main}>
|
||
<Popup show={show} showTitle={false} onClose={onClose}>
|
||
<View className={styles.payment_con}>
|
||
{/* <View className={classnames('iconfont icon-a-moreback', styles.miconfont_title)} onClick={onClose}></View> */}
|
||
<View className={styles.title}>待支付款项</View>
|
||
|
||
{payInfo?.delivery_payment_name && <View className={styles.playMode}>已使用{payInfo?.delivery_payment_name}方式付款</View>}
|
||
<View className={styles.payment_list}>
|
||
<View className={styles.amount}>
|
||
<AmountShow status={2} number={formatPriceDiv(payInfo?.amount_to_be_paid) as number} />
|
||
</View>
|
||
<View className={styles.payment_list_top_border}></View>
|
||
<View className={styles.payment_list_title}>
|
||
{/* <Text>向商家发起支付</Text> */}
|
||
<View className={styles.payment_list_title_price}>
|
||
<View className={styles.payment_list_title_price_item}>
|
||
<Text>订单金额</Text>
|
||
<Text>¥{formatPriceDiv(payInfo?.should_collect_money)}</Text>
|
||
</View>
|
||
<View className={styles.payment_list_title_price_item}>
|
||
<Text>已付金额</Text>
|
||
<Text>¥{formatPriceDiv(payInfo?.amount_paid)}</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
<View className={styles.payment_list_con}>
|
||
<View className={styles.payment_list_item} onClick={changeSelect}>
|
||
<View className={styles.payment_list_item_left}>
|
||
<View className={classnames(styles.miconfont)}><IconFont name="icon-yufukuan" size={70} /></View>
|
||
<View className={styles.payment_list_item_left_name}>
|
||
<View className={styles.payment_list_item_left_text}>预存款</View>
|
||
{advance_payment}
|
||
</View>
|
||
</View>
|
||
<MCheckbox
|
||
ref={advanceRef}
|
||
status={submitData.payment_method == PaymentMethodPreDeposit.value}
|
||
onSelect={() => advanceSelectData(PaymentMethodPreDeposit.value)}
|
||
onClose={() => advanceSelectData(null)}
|
||
/>
|
||
</View>
|
||
<View className={styles.payment_list_item} onClick={onBankPay}>
|
||
<View className={styles.payment_list_item_left}>
|
||
<View className={classnames(styles.miconfont)}><IconFont name="icon-weixin" size={70} /></View>
|
||
<View className={styles.payment_list_item_left_name}>
|
||
<View className={styles.payment_list_item_left_text}>微信支付</View>
|
||
</View>
|
||
</View>
|
||
<View className={classnames('iconfont icon-a-moreback', styles.miconfont_more)}></View>
|
||
</View>
|
||
{show_account_payment && (
|
||
<View className={styles.payment_list_item} onClick={accountPeriodSelect}>
|
||
<View className={styles.payment_list_item_left}>
|
||
<View className={classnames(styles.miconfont)}><IconFont name="icon-huozhuziti" size={70} /></View>
|
||
<View className={styles.payment_list_item_left_name}>
|
||
<View className={styles.payment_list_item_left_text}>{payInfo?.account_period}天账期</View>
|
||
</View>
|
||
{account_peyment}
|
||
</View>
|
||
<MCheckbox
|
||
ref={accountPeriodRef}
|
||
status={submitData.payment_method == PaymentMethodAccountPeriod.value}
|
||
onSelect={() => periodSelectData(PaymentMethodAccountPeriod.value)}
|
||
onClose={() => periodSelectData(null)}
|
||
/>
|
||
</View>
|
||
)}
|
||
<View className={styles.payment_list_item} onClick={onShowOfflinePay}>
|
||
<View className={styles.payment_list_item_left}>
|
||
<View className={classnames(styles.miconfont)}><IconFont name="icon-xianxiahuikuan" size={70} /></View>
|
||
<View className={styles.payment_list_item_left_name}>
|
||
<View className={styles.payment_list_item_left_text}>线下汇款</View>
|
||
</View>
|
||
</View>
|
||
<View className={classnames('iconfont icon-a-moreback', styles.miconfont_more)}></View>
|
||
</View>
|
||
<View className={styles.payment_list_item} onClick={onShowScanPay}>
|
||
<View className={styles.payment_list_item_left}>
|
||
<View className={classnames(styles.miconfont)}><IconFont name="icon-saomazhifu" size={70} /></View>
|
||
<View className={styles.payment_list_item_left_name}>
|
||
<View className={styles.payment_list_item_left_text}>保存码单支付</View>
|
||
</View>
|
||
</View>
|
||
<View className={classnames('iconfont icon-a-moreback', styles.miconfont_more)}></View>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
<View className={styles.btns} onClick={submitPay}>
|
||
确认交易
|
||
</View>
|
||
</View>
|
||
</Popup>
|
||
<OfflinePay show={offlinePayShow} onClose={() => setofflinePayShow(false)} offlineInfo={payInfo?.offline_remittance_information} />
|
||
<ScanPay orderInfo={onlinePayData} show={scanPayShow} onClose={() => setScanPayShow(false)} />
|
||
</View>
|
||
)
|
||
}
|
||
export default memo(Payment)
|