| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- import {
- Button,
- Cell,
- CellGroup,
- Icon,
- RadioGroup,
- Radio,
- Dialog,
- Toast
- } from 'vant'
- import { computed, defineComponent, reactive } from 'vue'
- import styles from './index.module.less'
- import { browser, moneyFormat } from '@/helpers/utils'
- import { useEventTracking } from '@/helpers/hooks'
- import request from '@/helpers/request'
- import { useRouter } from 'vue-router'
- import { state as baseState } from '@/state'
- import activeButtonIcon from '@common/images/icon_checkbox.png'
- import inactiveButtonIcon from '@common/images/icon_checkbox_default.png'
- import activeButtonIconTenant from '@common/images/icon_checkbox-tenant.png'
- import iconWechat from '@common/images/icon-wechat.png'
- import iconAlipay from '@common/images/icon-alipay.png'
- import {
- listenerMessage,
- postMessage,
- removeListenerMessage
- } from '@/helpers/native-message'
- const urlFix =
- baseState.platformType === 'TEACHER' ? '/api-teacher' : '/api-student'
- export default defineComponent({
- name: 'payment',
- props: {
- modelValue: {
- type: Boolean,
- default: false
- },
- paymentConfig: {
- type: Object,
- default: () => ({})
- },
- paymentVendor: {
- type: String,
- default: ''
- },
- paymentChannels: {
- type: Array,
- default: () => []
- }
- },
- emits: ['backOut', 'close', 'confirm', 'update:modelValue'],
- setup(props, { emit }) {
- const router = useRouter()
- const state = reactive({
- payType: 'wx',
- pay_channel: ''
- })
- const onClose = () => {
- // 继续支付则直接关闭弹窗就可
- Dialog.confirm({
- message: '是否放弃本次付款',
- confirmButtonText: '继续付款',
- cancelButtonText: '放弃'
- })
- .then(() => {
- //
- })
- .catch(async () => {
- // this.onCancel()
- useEventTracking('取消支付')
- await onCancel()
- emit('close')
- useEventTracking('取消支付')
- })
- }
- const isWxPay = computed(() => {
- if (
- props.paymentVendor === 'yeepay' ||
- props.paymentVendor === 'adapay'
- ) {
- return true
- }
- const channelStr = props.paymentChannels?.join(',')
- if (channelStr && channelStr.indexOf('wxpay') !== -1) {
- return true
- }
- return false
- })
- const isAliPay = computed(() => {
- if (
- props.paymentVendor === 'yeepay' ||
- props.paymentVendor === 'adapay'
- ) {
- return true
- }
- const channelStr = props.paymentChannels?.join(',')
- if (channelStr && channelStr.indexOf('alipay') !== -1) {
- return true
- }
- return false
- })
- // 需要关闭订单
- // orderPay: {
- // cancelUrl: urlFix + '/userOrder/orderCancel',
- // payUrl: urlFix + '/userOrder/orderPay'
- // }
- const onCancel = async (noBack?: boolean) => {
- try {
- await request.post(urlFix + '/userOrder/orderCancel', {
- data: {
- orderNo: props.paymentConfig.orderNo
- }
- })
- } catch {
- //
- }
- // 不管接口是否报错,都返回
- emit('update:modelValue', false)
- !noBack && router.go(-1)
- emit('backOut')
- }
- const onSubmit = async () => {
- if (
- props.paymentVendor &&
- (props.paymentVendor.indexOf('wxpay') > -1 ||
- props.paymentVendor.indexOf('alipay') > -1)
- ) {
- submitNativePay()
- } else {
- submitQrCodePay()
- }
- }
- // 支付方式,使用原生支付
- const submitNativePay = async () => {
- // 支付...
- try {
- const payChannel = state.payType === 'zfb' ? 'ali_app' : 'wx_app'
- console.log(props.paymentConfig, 'paymentConfig')
- let paymentType = props.paymentVendor
- props.paymentChannels.forEach((item: any) => {
- if (state.payType === 'zfb' && item.indexOf('alipay') !== -1) {
- paymentType = item
- }
- if (state.payType === 'wx' && item.indexOf('wxpay') !== -1) {
- paymentType = item
- }
- })
- const params = {
- // orderNo: props.paymentConfig.orderNo,
- merOrderNo: props.paymentConfig.orderNo,
- paymentChannel: payChannel,
- paymentVendor: paymentType
- }
- const res = await request.post(
- urlFix + '/userOrder/executePayment/v2',
- {
- data: {
- ...params
- }
- }
- )
- postMessage({
- api: 'paymentOrder',
- content: {
- orderNo: props.paymentConfig.orderNo,
- payChannel,
- // payInfo: `alipays://platformapi/startapp?saId=10000007&qrcode=${res.data.pay_info}`
- payInfo: res.data.pay_info
- }
- })
- Toast.loading({
- message: '支付中...',
- forbidClick: true,
- duration: 3000,
- loadingType: 'spinner'
- })
- Toast.clear()
- emit('update:modelValue', false)
- // 唤起支付时状态
- listenerMessage('paymentOperation', result => {
- console.log(result, 'init paymentOperation')
- paymentOperation(result?.content)
- })
- } catch (e: any) {
- console.log(e)
- }
- }
- const paymentOperation = (res: any) => {
- console.log(res, 'paymentOperation')
- // 支付状态
- // paymentOperation 支付成功:success 支付失败:error 支付取消:cancel 未安装:fail
- // error 只有安卓端有
- if (res.status === 'success' || res.status === 'error') {
- Toast.clear()
- emit('update:modelValue', false)
- router.replace({
- path: '/tradeDetail',
- query: {
- orderNo: props.paymentConfig.orderNo
- }
- })
- } else if (res.status === 'cancel') {
- Toast.clear()
- emit('update:modelValue', false)
- } else if (res.status === 'fail') {
- const message =
- state.payType === 'zfb' ? '您尚未安装支付宝' : '您尚未安装微信'
- Dialog.alert({
- title: '提示',
- message
- }).then(() => {
- Toast.clear()
- emit('update:modelValue', false)
- })
- }
- }
- // 支付方式,汇付,易宝支付
- const submitQrCodePay = () => {
- // 支付...
- const pt = state.payType
- // 判断当前浏览器
- if (browser().weixin) {
- // 微信浏览器
- if (pt == 'zfb') {
- state.pay_channel = 'alipay_qr'
- getCodePay('qrCode')
- } else if (pt == 'wx') {
- state.pay_channel = 'wx_pub'
- getCodePay('pay')
- }
- } else if (browser().alipay) {
- // 支付宝浏览器
- if (pt == 'zfb') {
- state.pay_channel = 'alipay_wap'
- // 支付宝 H5 支付
- getCodePay('pay')
- } else if (pt == 'wx') {
- state.pay_channel = 'wx_pub'
- getCodePay('qrCode')
- }
- } else {
- if (pt == 'zfb') {
- state.pay_channel = 'alipay_qr'
- } else if (pt == 'wx') {
- state.pay_channel = 'wx_pub'
- }
- getCodePay('qrCode')
- }
- }
- const getCodePay = (code: any) => {
- // 二维码页面, 唤起支付页面
- const payCode = code == 'qrCode' ? 'payCenter' : 'payResult'
- emit('confirm', {
- payCode,
- pay_channel: state.pay_channel
- })
- }
- return () => (
- <div class={styles.payment}>
- <Icon onClick={onClose} name="cross" size={20} />
- <div class={[styles.title]}>选择支付方式</div>
- <div class={styles.payAmount}>
- <p>应付金额</p>
- <div class={styles.amount}>
- <span>¥</span>
- {moneyFormat(props.paymentConfig.actualPrice)}
- </div>
- </div>
- <RadioGroup v-model={state.payType}>
- <CellGroup border={false}>
- {isWxPay.value && (
- <Cell
- border={true}
- center
- onClick={() => {
- state.payType = 'wx'
- }}
- v-slots={{
- icon: () => <Icon name={iconWechat} size={18} />,
- 'right-icon': () => (
- <Radio
- name="wx"
- v-slots={{
- icon: (props: any) => (
- <Icon
- class={styles.boxStyle}
- name={
- props.checked
- ? baseState.projectType === 'tenant'
- ? activeButtonIconTenant
- : activeButtonIcon
- : inactiveButtonIcon
- }
- />
- )
- }}
- />
- ),
- title: () => (
- <div class={styles.payTypeRe}>
- 微信支付 <span class={styles.recommend}>推荐</span>
- </div>
- )
- }}
- ></Cell>
- )}
- {isAliPay.value && (
- <Cell
- title="支付宝支付"
- border={true}
- center
- onClick={() => {
- state.payType = 'zfb'
- }}
- v-slots={{
- icon: () => <Icon name={iconAlipay} size={18} />,
- 'right-icon': () => (
- <Radio
- name="zfb"
- v-slots={{
- icon: (props: any) => (
- <Icon
- class={styles.boxStyle}
- name={
- props.checked
- ? baseState.projectType === 'tenant'
- ? activeButtonIconTenant
- : activeButtonIcon
- : inactiveButtonIcon
- }
- />
- )
- }}
- />
- )
- }}
- ></Cell>
- )}
- </CellGroup>
- </RadioGroup>
- <div class={styles.blank}></div>
- <Button
- type="primary"
- class={[
- styles.payBtn,
- baseState.projectType === 'tenant' && styles.tenantPayBtn
- ]}
- block
- round
- onClick={onSubmit}
- >
- 确认支付
- </Button>
- </div>
- )
- }
- })
|