邮储奶茶积分支付对接

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://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://milk.api.test.86698.cn'
# VITE_YCNC_MERCH_CODE = '100610100019029'
VITE_BASE_URL = 'http://milk.test.api.cdlsxd.cn'
# VITE_YCNC_MERCH_CODE = '100310100018908'
VITE_YCNC_MERCH_CODE = '100610100019042'
# 邮储奶茶活动(正式环境)
VITE_BASE_URL = 'https://milk.api.cdlsxd.cn'
VITE_YCNC_MERCH_CODE = '100510102294138'
# VITE_BASE_URL = 'https://milk.api.cdlsxd.cn'
# 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>
<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 v-for="(item,index) in products" :key="index" class="product-container">
<ProductItem :detail="item" :index="index"/>

View File

@ -26,7 +26,7 @@
<view class="btns flex flex-justify-end">
<view class="btn del" @click="goDel">删除订单</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>
</view>

View File

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

View File

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

View File

@ -82,9 +82,9 @@
product_id:unref(id)
}
goPay({params}).then(res => {
const {order_no,notify_url} = res;
const {order_no,notify_url,sign,plain_text} = res;
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 => {
console.log(err);
})

View File

@ -1,5 +1,5 @@
import dayjs from "dayjs";
import md5 from 'js-md5';
const handleParams = (obj) => Object.entries(obj).reduce((total,curr) => {
if(!total){
total += `${curr[0]}=${curr[1]}`
@ -12,20 +12,29 @@ const handleParams = (obj) => Object.entries(obj).reduce((total,curr) => {
export default function usePay(){
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 = {
MercUrl:notify_url,
TranAmt:Number(TranAmt).toFixed(2),
TranAmt:tranAmt,
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',
TxnDt:dayjs(Date.now()).format('YYYY-MM-DD'),
MercCode:import.meta.env.VITE_YCNC_MERCH_CODE
MercCode:MercCode,
IsIntegral:'1',
MerName:MerName,
}
const params = {
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);
}
return {payFunc}

View File

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

View File

@ -119,9 +119,9 @@
function pay(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();
payFunc({order_no,notify_url,TranAmt:price})
payFunc({order_no,notify_url,TranAmt:price,MerName:brand,sign,plain_text})
}
function viewDetail(orderData){

View File

@ -9,15 +9,12 @@
</route>
<template>
<view class="w-full h-full flex flex-col flex-items-center page">
<view class="wrapper">
<view class="w-full h-full flex flex-col flex-items-center page">
<view class="wrapper" v-if="pageType === 1">
<view class="pro-info">
<view class="title">订单详情</view>
<view class="content flex">
<image
class="pro-img"
:src="orderDetail.main_image"
/>
<image class="pro-img" :src="orderDetail.main_image" />
<view class="flex flex-1 flex-col">
<view class="flex flex-justify-between name" style="margin-bottom:12rpx">
<view class="text-over">{{ orderDetail.product_name }}</view>
@ -32,174 +29,242 @@
</view>
<view class="order-info">
<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" style="margin-bottom: 24rpx;">订单金额{{ orderDetail.price }}</view>
</view>
</view>
<view class="btns">
<view class="btn pwd" @click="viewPwd(orderDetail)" v-if="[3].includes(orderDetail.state) && !!orderDetail.voucher_link">查看卡密</view>
<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="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 back" @click="backIndex">返回首页</view>
</view>
</view>
</view>
</template>
<script setup>
import { onShow } from '@dcloudio/uni-app';
import { onMounted, reactive, ref, unref } from 'vue';
import { queryOrderDetail,refundOrder} from '../../api/ycnc';
import {getQueryString} from '../../utils/utils'
import usePay from './hooks/usePay';
const id = ref('');
const orderNo = ref('');
const orderDetail = reactive({});
import { onShow, onHide, onUnload } from '@dcloudio/uni-app';
import { onMounted, reactive, ref, unref } from 'vue';
import { queryOrderDetail, refundOrder, queryOrderState } from '../../api/ycnc';
import { getQueryString } from '../../utils/utils'
import usePay from './hooks/usePay';
const id = ref('');
const orderNo = ref('');
const orderDetail = reactive({});
const pageType = ref(0)
let timer = undefined
// onshow h5
onShow(()=>{
// onshow h5
onShow(() => {
const url = window.location.href
console.log('url-->',url);
console.log('url-->', url);
const order_id = getQueryString('order_id')
const order_no = getQueryString('order_no')
console.log(order_id,order_no);
if(!order_id && !order_no) return
const isPayBack = getQueryString('isPayBack')
console.log(order_id, order_no);
console.log('isPayBack', isPayBack);
if (!order_id && !order_no) return
id.value = order_id
orderNo.value = order_no;
if (isPayBack) {
queryEvent()
} else {
getDetail();
})
const backIndex = () => {
uni.navigateTo({
url:`/pages/ycnc/index`
})
}
})
const viewPwd = (detailData) => {
const {voucher_link} = detailData
onHide(() => {
timer && clearInterval(timer)
})
onUnload(() => {
timer && clearInterval(timer)
})
const backIndex = () => {
uni.navigateTo({
url: `/pages/ycnc/index`
})
}
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 { voucher_link } = detailData
if (voucher_link) {
console.log(`跳转外部链接-->${voucher_link}`);
window.location.href = voucher_link
}else{
} else {
console.error(`voucher_link无有效值`);
}
}
}
const goRefund = () => {
const {id} = orderDetail
if(!id){
const goRefund = () => {
const { id } = orderDetail
if (!id) {
uni.showToast({
icon:'none',
icon: 'none',
title: '无有效的订单id',
});
return
}
const params = {order_id:id}
refundOrder({params}).then(res => {
const params = { order_id: id }
refundOrder({ params }).then(res => {
uni.showToast({
icon:'success',
icon: 'success',
title: '退款成功',
});
}).catch(err => {
console.log(err);
})
}
}
function pay(orderData){
function pay(orderData) {
console.log(orderData);
const {order_no,notify_url,price} = orderData;
const {payFunc} = usePay();
payFunc({order_no,notify_url,TranAmt:price})
}
const { order_no, notify_url, price,brand,sign,plain_text } = orderData;
const { payFunc } = usePay();
payFunc({ order_no, notify_url, TranAmt: price,MerName:brand,sign,plain_text })
}
onMounted(() => {
onMounted(() => {
// getDetail()
})
})
const getDetail = () => {
const getDetail = () => {
const params = {
order_id:unref(id),
order_no:unref(orderNo)
order_id: unref(id),
order_no: unref(orderNo)
}
queryOrderDetail({params}).then(res => {
Object.assign(orderDetail,res)
pageType.value = 1
queryOrderDetail({ params }).then(res => {
Object.assign(orderDetail, res)
})
}
}
</script>
<style lang="scss" scoped>
.page{
.page {
background-color: #fafafa;
}
.wrapper{
.wrapper {
width: 702rpx;
height: 486rpx;
background: #FFFFFF;
border-radius: 24rpx;
margin-top:24rpx;
margin-top: 24rpx;
box-sizing: border-box;
padding:32rpx 24rpx;
.pro-info{
padding: 32rpx 24rpx;
.pro-info {
border-bottom: 1rpx solid #F0E1E1;
.title{
.title {
font-weight: 500;
font-size: 28rpx;
color: #333333;
margin-bottom: 28rpx;
}
.content{
margin-bottom:24rpx;
.content {
margin-bottom: 24rpx;
font-weight: 400;
.pro-img{
.pro-img {
display: block;
width:90rpx;
height:90rpx;
margin-right:34rpx;
width: 90rpx;
height: 90rpx;
margin-right: 34rpx;
}
.text-over{
max-width:80%;
.text-over {
max-width: 80%;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.name{
.name {
font-size: 24rpx;
color: #333333;
font-weight: 700;
}
.amount{
.amount {
color: #333333;
font-weight: 400;
font-size:24rpx;
font-size: 24rpx;
text:nth-child(1){
font-size:20rpx;
text:nth-child(1) {
font-size: 20rpx;
}
text:nth-child(2){
font-size:22rpx;
text:nth-child(2) {
font-size: 22rpx;
}
}
.num{
.num {
font-weight: 400;
font-size: 24rpx;
color: #9E9E9E;
}
}
}
.order-info{
.order-info {
border-bottom: 1rpx solid #F0E1E1;
.info-item{
.info-item {
font-weight: 400;
font-size: 22rpx;
color: #6C6C6C;
margin-top:24rpx;
margin-top: 24rpx;
}
}
}
.btns{
margin-top:146rpx;
.btns {
margin-top: 146rpx;
display: flex;
.btn{
.btn {
width: 312rpx;
height: 76rpx;
border-radius: 38rpx;
@ -208,14 +273,16 @@
align-items: center;
justify-content: center;
}
.pwd{
.pwd {
font-weight: 500;
font-size: 32rpx;
color: #FFFFFF;
background: #EA0000;
margin-right:10rpx;
margin-right: 10rpx;
}
.back{
.back {
font-weight: 400;
font-size: 32rpx;
color: #B9C8C7;

View File

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