邮储奶茶积分支付对接

This commit is contained in:
xiaogang 2024-10-29 10:02:45 +08:00
parent fd7f59740f
commit c656192050
13 changed files with 241 additions and 156 deletions

View File

@ -1,4 +1,5 @@
# 兴业优酷 # 兴业优酷
# VITE_BASE_URL = 'http://192.168.110.50:8083' # VITE_BASE_URL = 'http://192.168.110.50:8083'
# 邮储奶茶活动 # 邮储奶茶活动
VITE_BASE_URL = 'http://milk.api.test.86698.cn' # VITE_BASE_URL = 'http://milk.api.test.86698.cn'
VITE_BASE_URL = 'http://milk.test.api.cdlsxd.cn'

View File

@ -2,8 +2,9 @@
# VITE_BASE_URL = 'http://192.168.110.50:8083' # VITE_BASE_URL = 'http://192.168.110.50:8083'
# 邮储奶茶活动(测试环境) # 邮储奶茶活动(测试环境)
# VITE_BASE_URL = 'http://milk.api.test.86698.cn' VITE_BASE_URL = 'http://milk.test.api.cdlsxd.cn'
# VITE_YCNC_MERCH_CODE = '100610100019029' # VITE_YCNC_MERCH_CODE = '100310100018908'
VITE_YCNC_MERCH_CODE = '100610100019042'
# 邮储奶茶活动(正式环境) # 邮储奶茶活动(正式环境)
VITE_BASE_URL = 'https://milk.api.cdlsxd.cn' # VITE_BASE_URL = 'https://milk.api.cdlsxd.cn'
VITE_YCNC_MERCH_CODE = '100510102294138' # VITE_YCNC_MERCH_CODE = '100510102303326'

View File

@ -51,3 +51,10 @@ export const refundOrder = (params) => http({
}) })
//查询订单状态,主要针对短连接
export const queryOrderState = (params) => http({
url:'/api/v1/auth/order/state',
method:'POST',
...params
})

View File

@ -1,5 +1,5 @@
<template> <template>
<scroll-view scroll-y class="pro-container box-border" :style="{backgroundImage: 'url('+config[brandName].src+')',height:`${config[brandName].height}rpx`}"> <scroll-view scroll-y class="pro-container box-border" :style="{backgroundImage: 'url('+config[brandName]?.src+')',height:`${config[brandName].height}rpx`}">
<view class="pro-wrapper flex flex-wrap"> <view class="pro-wrapper flex flex-wrap">
<view v-for="(item,index) in products" :key="index" class="product-container"> <view v-for="(item,index) in products" :key="index" class="product-container">
<ProductItem :detail="item" :index="index"/> <ProductItem :detail="item" :index="index"/>

View File

@ -26,7 +26,7 @@
<view class="btns flex flex-justify-end"> <view class="btns flex flex-justify-end">
<view class="btn del" @click="goDel">删除订单</view> <view class="btn del" @click="goDel">删除订单</view>
<view class="btn pay" v-if="[1].includes(detail.state)" @click="goPay">立即付款</view> <view class="btn pay" v-if="[1].includes(detail.state)" @click="goPay">立即付款</view>
<view class="btn view" v-if="[3].includes(detail.state) && !!detail.voucher_link" @click="goPwd">查看卡</view> <view class="btn view" v-if="[3].includes(detail.state) && !!detail.voucher_link" @click="goPwd">查看卡</view>
<view class="btn pay" @click="goRefund" v-if="[4].includes(detail.state)">申请退款</view> <view class="btn pay" @click="goRefund" v-if="[4].includes(detail.state)">申请退款</view>
</view> </view>
</view> </view>

View File

@ -2,7 +2,7 @@
<view class="pro-item-wrapper flex flex-col box-border flex-justify-between" @click="toDetail"> <view class="pro-item-wrapper flex flex-col box-border flex-justify-between" @click="toDetail">
<view class="img-container"> <view class="img-container">
<image <image
:src="detail.voucherIcon" :src="detail?.voucherIcon"
mode="scaleToFill" mode="scaleToFill"
class="img" class="img"
/> />

View File

@ -22,7 +22,7 @@ const config = {
height:584, height:584,
}, },
"CoCo":{ "CoCo":{
name:'COCO', name:'CoCo',
src:CoCo, src:CoCo,
height:584, height:584,
}, },

View File

@ -82,9 +82,9 @@
product_id:unref(id) product_id:unref(id)
} }
goPay({params}).then(res => { goPay({params}).then(res => {
const {order_no,notify_url} = res; const {order_no,notify_url,sign,plain_text} = res;
const {payFunc} = usePay(); const {payFunc} = usePay();
payFunc({order_no,notify_url,TranAmt:detailObj.price}) payFunc({order_no,notify_url,TranAmt:detailObj.price,MerName:detailObj.brand,sign,plain_text})
}).catch(err => { }).catch(err => {
console.log(err); console.log(err);
}) })

View File

@ -1,5 +1,5 @@
import dayjs from "dayjs"; import dayjs from "dayjs";
import md5 from 'js-md5';
const handleParams = (obj) => Object.entries(obj).reduce((total,curr) => { const handleParams = (obj) => Object.entries(obj).reduce((total,curr) => {
if(!total){ if(!total){
total += `${curr[0]}=${curr[1]}` total += `${curr[0]}=${curr[1]}`
@ -12,20 +12,29 @@ const handleParams = (obj) => Object.entries(obj).reduce((total,curr) => {
export default function usePay(){ export default function usePay(){
const payFunc = (args) => { const payFunc = (args) => {
const {order_no,notify_url,TranAmt} = args; const {order_no,notify_url,TranAmt,MerName,sign,plain_text} = args;
const MercCode = import.meta.env.VITE_YCNC_MERCH_CODE
const tranAmt = Number(TranAmt).toFixed(2)
// const plainText = handleParams({MercCode,TranAmt:tranAmt,TermSsn:order_no})
const Plain = { const Plain = {
MercUrl:notify_url, MercUrl:notify_url,
TranAmt:Number(TranAmt).toFixed(2), TranAmt:tranAmt,
TermSsn:order_no, TermSsn:order_no,
BackLink:encodeURIComponent(`${window.location.origin}/#/pages/ycnc/orderDetail?order_no=${order_no}`), BackLink:encodeURIComponent(`${window.location.origin}/#/pages/ycnc/orderDetail?order_no=${order_no}&isPayBack=true`),
psbcmcc:'LSXD', psbcmcc:'LSXD',
TxnDt:dayjs(Date.now()).format('YYYY-MM-DD'), TxnDt:dayjs(Date.now()).format('YYYY-MM-DD'),
MercCode:import.meta.env.VITE_YCNC_MERCH_CODE MercCode:MercCode,
IsIntegral:'1',
MerName:MerName,
} }
const params = { const params = {
Plain:handleParams(Plain), Plain:handleParams(Plain),
plainText:plain_text,
sign:sign,
Signature: '',
} }
console.log('handCodePay-params',Plain); console.log('handCodePay-plain',Plain);
console.log('handCodePay-params',params);
Fw.device.api.handCodePay(params); Fw.device.api.handCodePay(params);
} }
return {payFunc} return {payFunc}

View File

@ -27,7 +27,7 @@
// import { getQueryString , isIOS, isAndroid } from '../../utils/utils'; // import { getQueryString , isIOS, isAndroid } from '../../utils/utils';
import useCode from './hooks/useCode'; import useCode from './hooks/useCode';
import usePay from './hooks/usePay'; import usePay from './hooks/usePay';
import config from './config';
const productList = ref([]); const productList = ref([]);
const authCode = ref(''); const authCode = ref('');
@ -43,15 +43,15 @@
} }
const pay = (productData) => { const pay = (productData) => {
const {ProductId,voucherAmount} = productData const {ProductId,voucherAmount,brandFlag} = productData
console.log('商品数据',productData); console.log('商品数据',productData);
const params = { const params = {
product_id:ProductId product_id:ProductId
} }
goPay({params}).then(res => { goPay({params}).then(res => {
const {order_no,notify_url} = res; const {order_no,notify_url,sign,plain_text} = res;
const {payFunc} = usePay(); const {payFunc} = usePay();
payFunc({order_no,notify_url,TranAmt:voucherAmount}) payFunc({order_no,notify_url,TranAmt:voucherAmount,MerName:config[brandFlag].name,sign,plain_text})
}).catch(err => { }).catch(err => {
console.log(err); console.log(err);
}) })

View File

@ -119,9 +119,9 @@
function pay(orderData){ function pay(orderData){
console.log(orderData); console.log(orderData);
const {order_no,notify_url,price} = orderData; const {order_no,notify_url,price,brand,sign,plain_text} = orderData;
const {payFunc} = usePay(); const {payFunc} = usePay();
payFunc({order_no,notify_url,TranAmt:price}) payFunc({order_no,notify_url,TranAmt:price,MerName:brand,sign,plain_text})
} }
function viewDetail(orderData){ function viewDetail(orderData){

View File

@ -10,14 +10,11 @@
<template> <template>
<view class="w-full h-full flex flex-col flex-items-center page"> <view class="w-full h-full flex flex-col flex-items-center page">
<view class="wrapper"> <view class="wrapper" v-if="pageType === 1">
<view class="pro-info"> <view class="pro-info">
<view class="title">订单详情</view> <view class="title">订单详情</view>
<view class="content flex"> <view class="content flex">
<image <image class="pro-img" :src="orderDetail.main_image" />
class="pro-img"
:src="orderDetail.main_image"
/>
<view class="flex flex-1 flex-col"> <view class="flex flex-1 flex-col">
<view class="flex flex-justify-between name" style="margin-bottom:12rpx"> <view class="flex flex-justify-between name" style="margin-bottom:12rpx">
<view class="text-over">{{ orderDetail.product_name }}</view> <view class="text-over">{{ orderDetail.product_name }}</view>
@ -32,13 +29,15 @@
</view> </view>
<view class="order-info"> <view class="order-info">
<view class="info-item">订单编号{{ orderDetail.order_no }}</view> <view class="info-item">订单编号{{ orderDetail.order_no }}</view>
<view class="info-item" v-if="!!orderDetail.exchange_time && ![9].includes(orderDetail.state)">支付时间{{ orderDetail.exchange_time }}</view> <view class="info-item" v-if="!!orderDetail.exchange_time && ![9].includes(orderDetail.state)">支付时间{{
orderDetail.exchange_time }}</view>
<view class="info-item">下单时间{{ orderDetail.create_time }}</view> <view class="info-item">下单时间{{ orderDetail.create_time }}</view>
<view class="info-item" style="margin-bottom: 24rpx;">订单金额{{ orderDetail.price }}</view> <view class="info-item" style="margin-bottom: 24rpx;">订单金额{{ orderDetail.price }}</view>
</view> </view>
</view> </view>
<view class="btns"> <view class="btns" v-if="pageType === 1">
<view class="btn pwd" @click="viewPwd(orderDetail)" v-if="[3].includes(orderDetail.state) && !!orderDetail.voucher_link">查看卡密</view> <view class="btn pwd" @click="viewPwd(orderDetail)"
v-if="[3].includes(orderDetail.state) && orderDetail.voucher_link">查看卡券</view>
<view class="btn pwd" @click="pay(orderDetail)" v-if="[1].includes(orderDetail.state)">立即付款</view> <view class="btn pwd" @click="pay(orderDetail)" v-if="[1].includes(orderDetail.state)">立即付款</view>
<view class="btn pwd" v-if="[4].includes(orderDetail.state)" @click="goRefund">申请退款</view> <view class="btn pwd" v-if="[4].includes(orderDetail.state)" @click="goRefund">申请退款</view>
<view class="btn back" @click="backIndex">返回首页</view> <view class="btn back" @click="backIndex">返回首页</view>
@ -47,14 +46,16 @@
</template> </template>
<script setup> <script setup>
import { onShow } from '@dcloudio/uni-app'; import { onShow, onHide, onUnload } from '@dcloudio/uni-app';
import { onMounted, reactive, ref, unref } from 'vue'; import { onMounted, reactive, ref, unref } from 'vue';
import { queryOrderDetail,refundOrder} from '../../api/ycnc'; import { queryOrderDetail, refundOrder, queryOrderState } from '../../api/ycnc';
import { getQueryString } from '../../utils/utils' import { getQueryString } from '../../utils/utils'
import usePay from './hooks/usePay'; import usePay from './hooks/usePay';
const id = ref(''); const id = ref('');
const orderNo = ref(''); const orderNo = ref('');
const orderDetail = reactive({}); const orderDetail = reactive({});
const pageType = ref(0)
let timer = undefined
// onshow h5 // onshow h5
onShow(() => { onShow(() => {
@ -62,11 +63,25 @@
console.log('url-->', url); console.log('url-->', url);
const order_id = getQueryString('order_id') const order_id = getQueryString('order_id')
const order_no = getQueryString('order_no') const order_no = getQueryString('order_no')
const isPayBack = getQueryString('isPayBack')
console.log(order_id, order_no); console.log(order_id, order_no);
console.log('isPayBack', isPayBack);
if (!order_id && !order_no) return if (!order_id && !order_no) return
id.value = order_id id.value = order_id
orderNo.value = order_no; orderNo.value = order_no;
if (isPayBack) {
queryEvent()
} else {
getDetail(); getDetail();
}
})
onHide(() => {
timer && clearInterval(timer)
})
onUnload(() => {
timer && clearInterval(timer)
}) })
const backIndex = () => { const backIndex = () => {
@ -75,6 +90,41 @@
}) })
} }
const timerEvent = () => {
timer && clearInterval(timer)
uni.showLoading({
title: "加载中",
mask: true,
});
timer = setInterval(()=>{
queryEvent()
}, 2500)
}
const queryEvent = () => {
uni.hideLoading()
const params = {
order_id: unref(id),
order_no: unref(orderNo)
}
queryOrderState({ params }).then(res => {
const { state, voucher_link } = res
if([3].includes(state)){
if(voucher_link){
timer && clearInterval(timer)
window.location.replace(voucher_link)
}else{
timerEvent()
}
}else if([1,2].includes(state)){
timerEvent()
}else{
timer && clearInterval(timer)
getDetail()
}
})
}
const viewPwd = (detailData) => { const viewPwd = (detailData) => {
const { voucher_link } = detailData const { voucher_link } = detailData
if (voucher_link) { if (voucher_link) {
@ -107,9 +157,9 @@
function pay(orderData) { function pay(orderData) {
console.log(orderData); console.log(orderData);
const {order_no,notify_url,price} = orderData; const { order_no, notify_url, price,brand,sign,plain_text } = orderData;
const { payFunc } = usePay(); const { payFunc } = usePay();
payFunc({order_no,notify_url,TranAmt:price}) payFunc({ order_no, notify_url, TranAmt: price,MerName:brand,sign,plain_text })
} }
onMounted(() => { onMounted(() => {
@ -121,6 +171,7 @@
order_id: unref(id), order_id: unref(id),
order_no: unref(orderNo) order_no: unref(orderNo)
} }
pageType.value = 1
queryOrderDetail({ params }).then(res => { queryOrderDetail({ params }).then(res => {
Object.assign(orderDetail, res) Object.assign(orderDetail, res)
}) })
@ -131,6 +182,7 @@
.page { .page {
background-color: #fafafa; background-color: #fafafa;
} }
.wrapper { .wrapper {
width: 702rpx; width: 702rpx;
height: 486rpx; height: 486rpx;
@ -139,34 +191,41 @@
margin-top: 24rpx; margin-top: 24rpx;
box-sizing: border-box; box-sizing: border-box;
padding: 32rpx 24rpx; padding: 32rpx 24rpx;
.pro-info { .pro-info {
border-bottom: 1rpx solid #F0E1E1; border-bottom: 1rpx solid #F0E1E1;
.title { .title {
font-weight: 500; font-weight: 500;
font-size: 28rpx; font-size: 28rpx;
color: #333333; color: #333333;
margin-bottom: 28rpx; margin-bottom: 28rpx;
} }
.content { .content {
margin-bottom: 24rpx; margin-bottom: 24rpx;
font-weight: 400; font-weight: 400;
.pro-img { .pro-img {
display: block; display: block;
width: 90rpx; width: 90rpx;
height: 90rpx; height: 90rpx;
margin-right: 34rpx; margin-right: 34rpx;
} }
.text-over { .text-over {
max-width: 80%; max-width: 80%;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
} }
.name { .name {
font-size: 24rpx; font-size: 24rpx;
color: #333333; color: #333333;
font-weight: 700; font-weight: 700;
} }
.amount { .amount {
color: #333333; color: #333333;
font-weight: 400; font-weight: 400;
@ -175,10 +234,12 @@
text:nth-child(1) { text:nth-child(1) {
font-size: 20rpx; font-size: 20rpx;
} }
text:nth-child(2) { text:nth-child(2) {
font-size: 22rpx; font-size: 22rpx;
} }
} }
.num { .num {
font-weight: 400; font-weight: 400;
font-size: 24rpx; font-size: 24rpx;
@ -186,8 +247,10 @@
} }
} }
} }
.order-info { .order-info {
border-bottom: 1rpx solid #F0E1E1; border-bottom: 1rpx solid #F0E1E1;
.info-item { .info-item {
font-weight: 400; font-weight: 400;
font-size: 22rpx; font-size: 22rpx;
@ -196,9 +259,11 @@
} }
} }
} }
.btns { .btns {
margin-top: 146rpx; margin-top: 146rpx;
display: flex; display: flex;
.btn { .btn {
width: 312rpx; width: 312rpx;
height: 76rpx; height: 76rpx;
@ -208,6 +273,7 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.pwd { .pwd {
font-weight: 500; font-weight: 500;
font-size: 32rpx; font-size: 32rpx;
@ -215,6 +281,7 @@
background: #EA0000; background: #EA0000;
margin-right: 10rpx; margin-right: 10rpx;
} }
.back { .back {
font-weight: 400; font-weight: 400;
font-size: 32rpx; font-size: 32rpx;

View File

@ -35,7 +35,7 @@ export default defineConfig(({ command, mode }) => {
}), }),
], ],
esbuild: { esbuild: {
drop: ["console", "debugger"], //打包去掉console,debugger // drop: ["console", "debugger"], //打包去掉console,debugger
}, },
} }
}) })