feat: 小程序跳转H5+支付

This commit is contained in:
zc 2025-11-08 20:34:15 +08:00
parent d4fecd7e9b
commit 581c7d8532
13 changed files with 216 additions and 156 deletions

View File

@ -7,7 +7,10 @@ const envVersion = accountInfo.miniProgram.envVersion || "trial";
const GDEnvs = {
develop: {
web: "https://h5.goudezhao.com",
// web: "http://192.168.1.105:3000",
web: "http://localhost:3000",
// web: "http://10.10.0.27:3000",
// web: "https://h5.goudezhao.com",
host: "https://api.1024api.com",
mdHost: "https://tcomlog.yijiesudai.com",
},

View File

@ -15,6 +15,7 @@
"pages": [
"pages/home/index",
"pages/login/index",
"pages/pay/index",
"pages/category/index",
"pages/shopping-cart/index",
"pages/mine/index",

View File

@ -195,7 +195,7 @@ Page({
categories: res.data.map((item: any) => ({
id: item.id,
name: item.name,
icon: item.categoryImageUrl,
icon: item.imageUrl,
categoryId: "",
children: item.childrens.map((child: any) => ({
id: child.id,

View File

@ -82,8 +82,8 @@ $theme-color: #06CD31;
align-items: center;
margin-bottom: 20rpx;
.category-icon {
width: 100rpx;
height: 100rpx;
width: 120rpx;
height: 120rpx;
background-color: #bbb;
border-radius: 40rpx;
margin-bottom: 8rpx;

View File

@ -122,12 +122,13 @@ Page({
},
});
},
// testzc 去商品详情
// 去商品详情
onGoCommodity(e: any) {
wx.navigateTo({
url: `/pages/H5/index?url=${encodeURIComponent(
`https://h5.goudezhao.com/commodity-detail?id=${e.currentTarget.dataset.id}`
)}`,
onGoH5Page({
is_need_login: false,
type: "",
url: `/commodity-detail?id=${e.currentTarget.dataset.id}`,
// url: `/commodity-detail?id=56`,
});
},
// 添加到购物车
@ -162,7 +163,7 @@ Page({
categories: res.data.map((item: any) => ({
id: item.id,
name: item.name,
icon: item.categoryImageUrl,
icon: item.imageUrl,
categoryId: "",
})),
});

View File

@ -35,7 +35,7 @@
<text class="view-more">更多</text>
</view>
<scroll-view class="sale-products" scroll-x>
<view class="sale-item" wx:for="{{flashSaleProducts}}" wx:key="id">
<view class="sale-item" wx:for="{{flashSaleProducts}}" wx:key="id" bindtap="onGoCommodity" data-id="{{item.id}}">
<image class="sale-image" src="{{item.image}}" />
<view class="sale-price-wrap">
<text class="sale-price">¥{{item.price}}</text>

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1 @@
/* pages/protocol/index.wxss */

View File

@ -0,0 +1,26 @@
// pages/protocol/index.ts
import { requestPayment } from "../../utils/common";
Page({
/**
*
*/
data: {
url: "",
},
/**
* --
*/
onLoad(options) {
var payParams = JSON.parse(decodeURIComponent(options.payParams as string));
requestPayment(payParams)
.then((res: any) => {
console.warn("----- my data is 2222: ", 2222, res);
})
.catch((err: any) => {
console.warn("----- my data is 3333: ", 3333, err);
});
console.warn("----- my data is 1111: ", 1111, payParams);
},
});

View File

@ -0,0 +1 @@
<web-view id="webview" src="{{url}}" />

View File

@ -16,3 +16,29 @@ export const getGlobalData = (key: string) => {
}
return null;
};
/**
*
* @param paymentParams
* @returns Promise
*/
export const requestPayment = (paymentParams: {
timeStamp: string;
nonceStr: string;
package: string;
signType?: "MD5" | "HMAC-SHA256";
paySign: string;
}): Promise<WechatMiniprogram.GeneralCallbackResult> => {
return new Promise((resolve, reject) => {
wx.requestPayment({
...paymentParams,
signType: paymentParams.signType || "MD5",
success: (res) => {
resolve(res);
},
fail: (err) => {
reject(err);
},
});
});
};

View File

@ -4,7 +4,6 @@ export const wxInfo = wx.getSystemInfoSync();
export const mpInfo = wx.getAccountInfoSync();
export const miniProgramVersion = mpInfo.miniProgram.version || "1.0.0";
const webUrl = require("../api/base").allBaseUrl.GDEnvs.web;
// 获取微信小程序token
export const getWxToken = async () => {
return new Promise((resolve) => {
@ -12,48 +11,10 @@ export const getWxToken = async () => {
wx.getStorage({
key: "user_info",
async success(res) {
console.warn("----- my data is res1111: ", res);
if (res.data.token) {
wx.hideLoading();
const envParams = { linktoken: "miniProgram" };
// 获取经纬度
const locationDataObj = wx.getStorageSync("locationData");
if (locationDataObj) Object.assign(envParams, { ...locationDataObj });
// 获取小程序启动时的参数
const launchOptions = wx.getStorageSync("launch_options");
if (launchOptions)
Object.assign(envParams, { wxXcxLaunchOptions: launchOptions });
// 获取系统信息
Object.assign(envParams, {
phoneType: wxInfo.model,
devType: wxInfo.platform === "ios" ? 0 : 1,
devOS: wxInfo.platform,
devOSVersion: wxInfo.system,
devVersion: wxInfo.version,
appVersion: miniProgramVersion.replace(/\./g, ""),
});
const extendParams = {
lzCode: "CJTG_XCX_LZ",
uniqueCode: res.data.uniqueCode,
userName: res.data.userName,
userId: res.data.userId,
token: res.data.token,
};
wx.getStorage({
key: "unique_code",
success(res) {
if (res) {
Object.assign(extendParams, { uniqueCode: res });
}
},
});
const obj = { envParams, extendParams };
const returnDataValue = encodeURIComponent(
Base64.encode(JSON.stringify(obj))
);
resolve(returnDataValue);
resolve(handleGetReturnData(res.data));
}
},
fail() {
@ -83,14 +44,36 @@ export const onGoH5Page = (params: any) => {
if (type === "third") {
wx.navigateTo({ url: `/pages/H5/index?url=${encodeURIComponent(url)}` });
} else {
const targetUrl = `${url}${
const userInfo = wx.getStorageSync("user_info") || {};
const returnData = handleGetReturnData(userInfo);
const targetUrl = `${webUrl}${url}${
/\?/.test(url) ? "&" : "?"
}jumpData=${encodeURIComponent(
Base64.encode(JSON.stringify({ is_need_login: false }))
)}`;
}returnData=${returnData}`;
wx.navigateTo({
url: `/pages/H5/index?url=${encodeURIComponent(targetUrl)}`,
});
}
}
};
const handleGetReturnData = (userInfo: any) => {
const envParams = {};
const locationDataObj = wx.getStorageSync("locationData") || {}; // 获取经纬度
const launchOptions = wx.getStorageSync("launch_options") || {}; // 获取小程序启动时的参数
Object.assign(
envParams,
{
wxXcxLaunchOptions: launchOptions,
phoneType: wxInfo.model,
devType: wxInfo.platform === "ios" ? 0 : 1,
devOS: wxInfo.platform,
devOSVersion: wxInfo.system,
devVersion: wxInfo.version,
appVersion: miniProgramVersion.replace(/\./g, ""),
},
locationDataObj
);
const obj = { envParams, extendParams: userInfo };
console.warn("----- my data is obj111: ", obj);
return encodeURIComponent(Base64.encode(JSON.stringify(obj)));
};

View File

@ -2,153 +2,149 @@
* @description: HTTP请求方法枚举
*/
export enum HttpMethod {
GET = 'GET',
POST = 'POST',
OPTIONS = 'OPTIONS',
PUT = 'PUT',
DELETE = 'DELETE'
GET = "GET",
POST = "POST",
OPTIONS = "OPTIONS",
PUT = "PUT",
DELETE = "DELETE",
}
/**
* @description: HTTP请求配置
*/
*/
interface RequestConfig {
/** API路径 */
url?: string
url?: string;
/** Method类型 */
method?: HttpMethod
method?: HttpMethod;
/** 接口返回数据 */
data?: any
data?: any;
/** 无TOKEN触发异常捕获时是否执行异常逻辑 */
needToken?: boolean
needToken?: boolean;
/** Header头部 */
header?: object
header?: object;
/** 返回的数据格式 */
dataType?: string
dataType?: string;
/** 请求报错时是否弹出message提示默认弹出*/
noShowMsg?: boolean
noShowMsg?: boolean;
}
class HttpRequest {
private static instance: HttpRequest
private constructor() { }
private static instance: HttpRequest;
private constructor() {}
public static getInstance(): HttpRequest {
if (!this.instance) {
this.instance = new HttpRequest()
this.instance = new HttpRequest();
}
return this.instance
return this.instance;
}
// 处理请求异常状态码
private handerErrorStatus(statusCode: number, requestConfig: RequestConfig) {
let msg = '服务找不到'
let msg = "服务找不到";
if (statusCode === 502 || statusCode === 503) {
msg = '服务器开小差了~'
msg = "服务器开小差了~";
}
!requestConfig.noShowMsg && wx.showToast({
title: `${msg},错误码:${statusCode}`,
icon: 'none'
})
return msg
!requestConfig.noShowMsg &&
wx.showToast({
title: `${msg},错误码:${statusCode}`,
icon: "none",
});
return msg;
}
// 处理请求异常
private handerError(err: { errMsg: string }, requestConfig: RequestConfig) {
let msg = `请求异常`
let msg = `请求异常`;
if (/timeout/.test(err.errMsg)) {
msg = '请求超时'
msg = "请求超时";
}
!requestConfig.noShowMsg && wx.showToast({
title: msg,
icon: 'none'
});
return msg
!requestConfig.noShowMsg &&
wx.showToast({
title: msg,
icon: "none",
});
return msg;
}
// 服务器接口请求
public request<T>(requestConfig: RequestConfig): Promise<T> {
const _this = this
const wxSystemInfo = wx.getSystemInfoSync()
const _this = this;
const wxSystemInfo = wx.getSystemInfoSync();
const user_info = wx.getStorageSync("user_info") || {};
const reqData = Object.assign(requestConfig.data, {
channelCode: 'CJTG_XCX_LZ',
devType: wxSystemInfo.platform === 'ios' ? 0 : 1
})
const user_info = wx.getStorageSync('user_info')
if (user_info) {
Object.assign(reqData, { token: user_info.token, userName: user_info.userName })
}
buyerId: user_info.buyerId,
flag: user_info.flag,
});
return new Promise((resolve, reject) => {
wx.request({
method: requestConfig.method,
url: `${requestConfig.url}`,
data: reqData,
header: requestConfig?.header,
dataType: 'json',
success (res) {
const code = res.statusCode || -404
const data = res.data
const isWhiteApi = requestConfig.url?.indexOf('/front/problem')
header: { ...(requestConfig?.header || {}), token: user_info.token },
dataType: "json",
success(res) {
const code = res.statusCode || -404;
const data = res.data;
/** 接口请求成功*/
if (code == 200) {
if (isWhiteApi === -1) {
if ([1003, 1004, 1005, 1006].includes((data as any).code)) {
wx.showModal({
content: (data as any).msg,
success (res) {
if (res.confirm) {
wx.removeStorageSync('user_info')
wx.navigateTo({ url: '/pages/login/index' })
} else if (res.cancel) {
try {
wx.removeStorageSync('user_info')
} catch (e) {
console.log('登录失效catch', e)
}
wx.reLaunch({ url: '/pages/index/index' })
wx.hideLoading()
if (["1003", "1004", "1005", "1006"].includes((data as any).code)) {
wx.showModal({
content: (data as any).msg,
success(res) {
if (res.confirm) {
wx.removeStorageSync("user_info");
wx.navigateTo({ url: "/pages/login/index" });
} else if (res.cancel) {
try {
wx.removeStorageSync("user_info");
} catch (e) {
console.log("登录失效catch", e);
}
wx.reLaunch({ url: "/pages/index/index" });
wx.hideLoading();
}
})
} else {
resolve(data as any)
}
},
});
} else {
resolve(data as any)
resolve(data as any);
}
} else if (code === 401) {
// 未授权
!requestConfig.noShowMsg && wx.showModal({
title: '登录失效',
content: '登录失效,请重新登录',
}).then(resModa => {
if (resModa.confirm) {
wx.removeStorageSync('user_info')
wx.navigateTo({ url: '/pages/login/index' })
} else if (resModa.cancel) {
try {
wx.removeStorageSync('user_info')
wx.reLaunch({ url: '/pages/index/index' })
} catch (e) {
console.log('登录失效catch', e)
}
}
})
reject({ code, msg: '未登录', data: data })
!requestConfig.noShowMsg &&
wx
.showModal({
title: "登录失效",
content: "登录失效,请重新登录",
})
.then((resModa) => {
if (resModa.confirm) {
wx.removeStorageSync("user_info");
wx.navigateTo({ url: "/pages/login/index" });
} else if (resModa.cancel) {
try {
wx.removeStorageSync("user_info");
wx.reLaunch({ url: "/pages/index/index" });
} catch (e) {
console.log("登录失效catch", e);
}
}
});
reject({ code, msg: "未登录", data: data });
} else {
//非200及401状态码-数据处理
const errMsg = _this.handerErrorStatus(code, requestConfig)
reject({ code, msg: errMsg, data })
const errMsg = _this.handerErrorStatus(code, requestConfig);
reject({ code, msg: errMsg, data });
}
},
fail: err => {
console.log('失败了', err);
fail: (err) => {
console.log("失败了", err);
let msg = _this.handerError(err, requestConfig)
reject({ msg })
}
})
})
let msg = _this.handerError(err, requestConfig);
reject({ msg });
},
});
});
}
/**
@ -159,7 +155,12 @@ class HttpRequest {
* @return {*}
*/
public get<T>(url: string, data?: Object, OtherConfig?: RequestConfig) {
return this.request<T>({ method: HttpMethod.GET, url, data, ...OtherConfig })
return this.request<T>({
method: HttpMethod.GET,
url,
data,
...OtherConfig,
});
}
/**
@ -171,7 +172,12 @@ class HttpRequest {
* @return {*}
*/
public post<T>(url: string, data: Object, OtherConfig?: RequestConfig) {
return this.request<T>({ method: HttpMethod.POST, url, data, ...OtherConfig })
return this.request<T>({
method: HttpMethod.POST,
url,
data,
...OtherConfig,
});
}
/**
@ -182,7 +188,12 @@ class HttpRequest {
* @return {*}
*/
public delete<T>(url: string, data: Object, OtherConfig?: RequestConfig) {
return this.request<T>({ method: HttpMethod.DELETE, url, data, ...OtherConfig })
return this.request<T>({
method: HttpMethod.DELETE,
url,
data,
...OtherConfig,
});
}
/**
@ -193,9 +204,13 @@ class HttpRequest {
* @return {*}
*/
public put<T>(url: string, data?: Object, OtherConfig?: RequestConfig) {
return this.request<T>({ method: HttpMethod.PUT, url, data, ...OtherConfig })
return this.request<T>({
method: HttpMethod.PUT,
url,
data,
...OtherConfig,
});
}
}
export const httpRequest = HttpRequest.getInstance()
export const httpRequest = HttpRequest.getInstance();