方法提取

msb_prod
ch 2 years ago
parent 54e211723d
commit acc680a9cd

@ -79,6 +79,7 @@
"@vue/shared": "^3.0.0",
"core-js": "^3.6.5",
"flyio": "^0.6.2",
"js-util-all": "^1.0.6",
"regenerator-runtime": "^0.12.1",
"vue": "^2.6.11",
"vuex": "^3.2.0"

@ -0,0 +1,27 @@
/*
* @Author: ch
* @Date: 2022-07-09 16:28:10
* @LastEditors: ch
* @LastEditTime: 2022-07-09 17:25:13
* @Description: file content
*/
import {ToAsyncAwait, MsbRequest} from '@/common/utils';
// 第三方鉴权服务
const AUTH_URL = '/third';
const APPID = 'wxd2015f0c56defa02';
/**
* 获取授权页面地址
* @param {*} data
*/
export const ApiGetAuthUrl = (params) =>
ToAsyncAwait(MsbRequest.get(`${AUTH_URL}/wx/mp/getAuthorizationUrl/${params.appid}`, params));
/**
* 获取openId
* @param {*} data
*/
export const ApiGetOpenId = ({code, appid}) =>
ToAsyncAwait(MsbRequest.get(`${AUTH_URL}/wx/mp/getOpenId/${appid}`, { code }));

@ -0,0 +1,26 @@
/*
* @Author: ch
* @Date: 2022-07-09 16:27:57
* @LastEditors: ch
* @LastEditTime: 2022-07-09 18:29:05
* @Description: file content
*/
import {ToAsyncAwait, MsbRequest} from '@/common/utils';
// 第三方鉴权服务
const AUTH_URL = '/third';
/**
* 获取订单信息
* @param {*} data
*/
export const ApiGetOrderInfo = ({payOrderNo}) =>
ToAsyncAwait(MsbRequest.get(`/payCenter/payCenter/prepayOrder/${payOrderNo}`));
/**
* 获取openId
* @param {*} data
*/
export const ApiPostH5Pay = (data) =>
ToAsyncAwait(MsbRequest.put(`payCenter/payCenter/cashierPay`, data));

@ -0,0 +1,123 @@
/*
* @Author: ch
* @Date: 2022-03-17 16:36:59
* @LastEditors: ch
* @LastEditTime: 2022-04-22 20:30:03
* @Description: 针对uniapp request请求做了一次封装使用思维参考axios
*
*
* 方法
* method(option) 自定义请求同uni.request
* get(url, params, header) url 请求地址 params 请求参数
* header 请求头会针对当前请求头设置特定的请求头传了此参数request拦截器会失效
* post(url, data, header) 同上
* put(url, data, header) 同上
* delete(url, data, header) 同上
* use(hookName, callback) 注入hook拦截器 hookName 拦截器名request/response/error callback拦截器具体见拦截器说明
*
* 属性
* baseUrl 请求地址前缀
*
* 拦截器
* request 请求前拦截在这可统一设置请求头请求体等参数uni.request的第一个参数option都可以重置
* success 请求成功结果拦截
* error 请求错误拦截
*
* 示例
* const myReq = new MsbUniRequest();
* myReq.baseUrl = 'xxxx'
* myReq.use('request', (option)=>{
* // option 返回请求配置
* .....这里可以对option做一系列操作
* return option //最后返回一个正确的请求配置
* })
* myReq.use('success', (res)=>{
* //res 返回请求结果
* let newRes = ..... //这里可以对请求结果做统一处理
* return newRes
* })
*
* myReq.use('error', (error)=>{
* //error 返回错误结果
* let newError = ..... //这里可以对请求错误做统一处理
* return newError
* })
*/
class MsbUniRequest {
constructor (option){
this.baseUrl = '';
this.header = {
repeat : true
}
this.hook = {
request : null,
success : null,
error : null
}
}
method(option){
option.header = {...this.header,...option.header};
option.url = this.baseUrl + option.url;
if(this.hook.request){
option = this.hook.request(option);
};
if(!option){
throw new Error('没有请求配置或是request拦截未做return');
}
if(option.constructor === Promise){
return option
}
return new Promise((resolve, reject)=>{
uni.request({
...option,
success: res => {
const response = res || res[1];
// 200 - 399状态为正常
if(response.statusCode >= 200 && response.statusCode < 400){
if(!this.hook.success){
resolve(response);
}else{
let newRes = this.hook.success(response, option);
// 业务结果处理可能为一个Promise对象根据结果调用错误或正确状态
if(newRes && newRes.constructor === Promise){
newRes.then(res => {
resolve(res);
}, error =>{
reject(error);
})
}else{
resolve(newRes);
}
}
return false;
}
reject(this.hook.error ? this.hook.error(response, option) : response);
},
fail: error =>{
reject(this.hook.error ? this.hook.error(error, option) : error);
}
});
});
}
use(hookName, cb){
this.hook[hookName] = cb;
}
get(url, data, header){
return this.method({method : 'GET', url, data, header});
}
post(url, data, header){
return this.method({method : 'POST', url, data, header});
}
put(url, data, header){
return this.method({method : 'PUT', url, data, header});
}
delete(url, data, header){
return this.method({method : 'DELETE', url, data, header});
}
}
export default MsbUniRequest;

@ -1,50 +0,0 @@
/*
* @Author: ch
* @Date: 2022-04-29 14:26:10
* @LastEditors: ch
* @LastEditTime: 2022-06-30 16:03:35
* @Description: file content
*/
import { ApiPostAliH5Pay, ApiPostAliAppPay } from '@/common/api/pay';
import ENV from '@/common/config/env';
export const Alipay = async ({orderId})=>{
// #ifdef APP-PLUS
const {error, result} = await ApiPostAliAppPay({orderId});
if(error){
uni.$u.toast(error.message);
return false;
}
const par = result.payDataInfo;
uni.requestPayment({
provider: 'alipay',
orderInfo :par.payData,
success(res) {
uni.navigateTo({
url : `/payResult?orderId=${orderId}&payType=appWx`
});
},
fail(e) {
uni.navigateTo({
url : `/payResult?orderId=${orderId}&payType=appWx`
});
}
}).then(res => {
console.log('res',res);
})
// #endif
// #ifdef H5
const { error, result } = await ApiPostAliH5Pay({
orderId,
returnUrl : decodeURIComponent(`${ENV.staticUrl}/payResult?orderId=${orderId}&payType=alih5`)
});
if(error){
uni.$u.toast(error.message);
return false;
}
window.location.href = result.payDataInfo.payUrl;
// #endif
}

@ -0,0 +1,14 @@
/*
* @Author: ch
* @Date: 2022-03-22 16:52:28
* @LastEditors: ch
* @LastEditTime: 2022-07-09 16:46:43
* @LastEditTime: 2022-06-29 17:22:32
* @Description: 所有工具类统一在这输出
*/
import * as util from './utils';
import * as requset from './requset';
export * from './utils';
export * from './requset';
export default { ...util, ...requset}

@ -0,0 +1,34 @@
/*
* @Author: ch
* @Date: 2022-03-17 17:42:32
* @LastEditors: ch
* @LastEditTime: 2022-07-09 16:56:53
* @Description: 项目接口请求统一处理器返回一个需要token和不需要token的请求封装方法
*/
import MsbUniRequest from '@/common/plugins/msbUniRequest';
const MsbRequest = new MsbUniRequest();
MsbRequest.baseUrl = process.env.VUE_APP_BASE_URL;
MsbRequest.use('success', (response, option) =>{
if(response.statusCode === 200){
const result = response.data;
if(result.code === 'SUCCESS'){
return result.data;
}
return Promise.reject(result);
}
return response;
});
MsbRequest.use('error', (error, option) =>{
return {message:error.errMsg,code:error.statusCode}
});
export {
MsbRequest
}

@ -0,0 +1,34 @@
/*
* @Author: ch
* @Date: 2022-07-09 18:02:07
* @LastEditors: ch
* @LastEditTime: 2022-07-09 18:35:59
* @Description: 这个文件里面的方法都是直接挂载在uni对象和this上的
*/
import Vue from 'vue';
const _$toast = (msg, duration = 3000) => {
return new Promise((reverse, reject) => {
uni.showToast({
title: msg,
icon: 'none',
duration,
success() {
setTimeout(() => {
reverse(true)
}, duration)
},
fail() {
reject(false)
}
});
})
}
const utils = {
_$toast
}
for (let key in utils) {
uni[key] = utils[key];
Vue.prototype[key] = utils[key];
}

@ -0,0 +1,27 @@
/*
* @Author: ch
* @Date: 2022-03-17 19:15:10
* @LastEditors: ch
* @LastEditTime: 2022-07-09 16:55:11
* @Description: 一些无法归类的公共方法容器
*/
import {
toAsyncAwait as ToAsyncAwait,
isPhone as IsPhone,
formatDate as FormatDate,
creatUuid as CreateUUID,
formatSearchJson as FormatSearchJson,
formatJsonSearch as FormatJsonSearch
} from "js-util-all";
// 工具类的文件需要把文件提供的工具类统一放最下方做一个统一输出
export {
// async await 标识结果处理
ToAsyncAwait,
// 判断是否为手机号
IsPhone,
FormatSearchJson,
FormatJsonSearch,
}

@ -1,78 +0,0 @@
/*
* @Author: ch
* @Date: 2022-04-29 14:26:10
* @LastEditors: ch
* @LastEditTime: 2022-07-08 17:38:48
* @Description: file content
*/
import { ApiPostWxH5Pay, ApiPostWxJsApiPay, ApiPostWxAppPay } from '@/common/api/pay';
import ENV from '@/common/config/env';
export const Wxpay = async ({orderId,openId})=>{
// #ifdef APP-PLUS
const {error, result} = await ApiPostWxAppPay({orderId});
const par = result.payDataInfo;
uni.requestPayment({
provider: 'wxpay',
orderInfo :{
"appid": par.appId, // 微信开放平台 - 应用 - AppId
"noncestr": par.nonceStr, // 随机字符串
"package": par.packageValue, // 固定值
"partnerid": par.partnerId, // 微信支付商户号
"prepayid": par.prepayId, // 统一下单订单号
"timestamp": par.timeStamp ,// 时间戳(单位:秒)
"sign": par.sign // 签名,这里用的 MD5 签名
},
success(res) {
uni.navigateTo({
url : `/payResult?orderId=${orderId}&payType=appWx`
});
},
fail(e) {
uni.navigateTo({
url : `/payResult?orderId=${orderId}&payType=appWx`
});
}
}).then(res => {
console.log('res',res);
})
// #endif
// #ifdef H5
// 有openId则判断在微信浏览器内
if(openId) {
// 微信JSAPI
const {error, result} = await ApiPostWxJsApiPay({orderId,openId});
if(error){
uni.$u.toast(error.message);
return false;
}
const par = result.payDataInfo;
WeixinJSBridge.invoke('getBrandWCPayRequest', {
appId : par.appId,
timeStamp : par.timeStamp,
nonceStr : par.nonceStr,
package: par.packageValue,
signType : par.signType,
paySign : par.paySign
}, res => {
if(res.err_msg !== 'get_brand_wcpay_request:cancel'){
uni.navigateTo({
url : `/payResult?orderId=${orderId}&payType=wxjsapi`
});
}
})
}else{
// h5支付
const {error, result} = await ApiPostWxH5Pay({orderId});
if(error){
uni.$u.toast(error.message);
return false;
}
const redirect_url = decodeURIComponent(`${ENV.staticUrl}/payResult?orderId=${orderId}&payType=wxh5`);
window.location.href = `${result.payDataInfo.h5Url}&redirect_url=${redirect_url}`;
}
// #endif
}

@ -1,6 +1,59 @@
import Vue from 'vue'
import App from './App'
/*
* @Author: ch
* @Date: 2022-07-08 11:46:30
* @LastEditors: ch
* @LastEditTime: 2022-07-09 18:18:11
* @Description: file content
*/
import {FormatSearchJson} from '@/common/utils';
import {ApiGetOpenId, ApiGetAuthUrl} from '@/common/api/auth';
import { ApiGetOrderInfo } from '@/common/api/pay';
import Vue from 'vue';
import App from './App';
import '@/common/utils/uniUtilsIndex'
// 微信打开需要授权
const ua = navigator ? navigator.userAgent.toLowerCase() : '';
if (ua.includes('micromessenger')) {
const openId = localStorage.getItem('openId');
if(!openId){
let query = FormatSearchJson(window.location.search);
if(query.code){
ApiGetOpenId({
code : query.code
}).then(({error, result}) => {
if(error){
// uni.$u.toast(error.message);
return false;
}
store.commit('SET_OPEN_ID', result.openId);
})
} else {
ApiGetOpenId({ payOrderNo: query.payOrderNo }).then(res => {
ApiGetAuthUrl({
redirectUrl : window.location.href,
scope : 'snsapi_base'
}).then(({result, error}) => {
if(error){
// uni.$u.toast(error.message);
uni.showToast({
title: error.message,
icon: 'none',
duration : 2000
})
return false;
}
window.location.replace(result);
})
});
}
}
}
Vue.config.productionTip = false
App.mpType = 'app'

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-07-08 11:46:30
* @LastEditors: ch
* @LastEditTime: 2022-07-09 15:43:47
* @LastEditTime: 2022-07-09 18:34:53
* @Description: file content
-->
<template>
@ -27,6 +27,7 @@
</template>
<script>
import {ApiGetOrderInfo, ApiPostH5Pay} from '@/common/api/pay';
const ENV = process.env;
export default {
components:{},
@ -48,26 +49,19 @@ const ENV = process.env;
payOrderNo : this.$route.query.payOrderNo
}
},
onLoad() {
async onLoad() {
this.getOrderInfo();
},
methods: {
getOrderInfo (){
uni.request({
url: `${process.env.VUE_APP_BASE_URL}/payCenter/payCenter/prepayOrder/${this.payOrderNo}`,
success:(res)=> {
let data = res.data.data;
if(res.data.code === 'SUCCESS'){
this.orderInfo = data
}else{
alert(data.message);
uni.navigateBack();
}
},
fail(){
}
});
async getOrderInfo (){
const {error, result} = await ApiGetOrderInfo({
payOrderNo : this.payOrderNo
})
if(error){
uni._$toast(error.message);
return false;
}
this.orderInfo = result;
},
pay(){
@ -77,43 +71,30 @@ const ENV = process.env;
this.aliPay();
}
},
wxPay(){
async wxPay(){
// h5
uni.request({
url : `${ENV.VUE_APP_BASE_URL}/payCenter/payCenter/cashierPay`,
method : 'PUT',
data : {
const {error, result} = await ApiPostH5Pay({
payOrderNo : this.orderInfo.payOrderNo,
payCode : 'WX_H5',
appCode : this.orderInfo.prepayWxApp.prepayAppCode
},
success:(res)=>{
let data = res.data.data;
if(res.data.code === 'SUCCESS'){
window.location.replace(data.payDataInfo.h5Url);
}
}
});
});
if(error){
uni._$toast(error.message);
return false;
}
window.location.replace(data.payDataInfo.h5Url);
},
aliPay(){
//
uni.request({
url : `${ENV.VUE_APP_BASE_URL}/payCenter/payCenter/cashierPay`,
method : 'PUT',
data : {
async aliPay(){
const {error, result} = await ApiPostH5Pay({
payOrderNo : this.orderInfo.payOrderNo,
payCode : 'ALI_WAP',
appCode : this.orderInfo.prepayAliApp.prepayAppCode
},
success:(res)=>{
let data = res.data.data;
if(res.data.code === 'SUCCESS'){
window.location.replace(data.payDataInfo.payUrl);
}
}
});
});
if(error){
uni._$toast(error.message);
return false;
}
window.location.replace(data.payDataInfo.payUrl);
}
}
}

@ -2,21 +2,30 @@
* @Author: ch
* @Date: 2022-07-08 15:30:29
* @LastEditors: ch
* @LastEditTime: 2022-07-09 15:39:22
* @LastEditTime: 2022-07-09 17:16:22
* @Description: file content
-->
<template>
<view>
<template v-if="status === 'await'">
<view class="icon icon__await"></view>
<view class="icon icon__await">
<view class="icon--one"></view>
<view class="icon--two"></view>
</view>
<view class="title">支付结果查询中</view>
</template>
<template v-else-if="status === 'fail'">
<view class="icon icon__fail"></view>
<view class="icon icon__fail">
<view class="icon--one"></view>
<view class="icon--two"></view>
</view>
<view class="title">{{errorMsg}}</view>
</template>
<template v-else>
<view class="icon icon__success"></view>
<view class="icon icon__success">
<view class="icon--one"></view>
<view class="icon--two"></view>
</view>
<view class="title">支付成功</view>
</template>
<view class="btn" @click="back"></view>
@ -34,7 +43,7 @@ export default {
success : [3],
fail : [2,4,5,6]
},
errorMsg : ''
errorMsg : '支付失败'
}
},
mounted(){
@ -55,17 +64,17 @@ export default {
setTimeout(this.getOrderInfo,3000);
}else{
this.status = 'fail';
this.errorMsg = data.payStatusText
this.errorMsg = data.payStatusText;
}
}else{
this.status = 'fail';
this.errorMsg = '支付结果出错,请联系商家';
this.errorMsg = res.data.message;
}
}
})
},
back(){
uni.navigateBack();
uni.navigateBack(2);
}
}
}
@ -76,14 +85,51 @@ export default {
height: 120rpx;
border-radius: 50%;
margin: 166rpx auto 50rpx;
position: relative;
&--one,&--two{
width: 10rpx;
height: 50rpx;
border-radius: 5rpx;
background: rgba($color: #fff, $alpha: 1);
position: absolute;
left: 56rpx;
top: 35rpx;
transform: rotate(45deg);
}
&--one{
background: rgba($color: #fff, $alpha: .8);
transform: rotate(-45deg);
}
&__await{
background: #61ADFF;
.icon--two{
transform: rotate(0);
top: 30rpx;
left: 50rpx;
height: 40rpx;
}
.icon--one{
top: 60rpx;
left: 60rpx;
height: 30rpx;
}
}
&__fail{
background: #FF512B;
}
&__success{
background: #71CD87;
.icon--two{
top: 30rpx;
left: 65rpx;
height: 60rpx;
}
.icon--one{
top: 55rpx;
left: 37rpx;
height: 30rpx;
}
}
}
.title{

Loading…
Cancel
Save