Lufaneng 11 months ago
parent d7c95a7d71
commit 1000dd7022

@ -274,17 +274,197 @@
})
}
//
const payOrder = (order) => {
//
const wechatPay = async (orderInfo) => {
// #ifdef MP-WEIXIN
//
try {
const paymentResult = await uni.requestPayment({
provider: "wxpay",
timeStamp: orderInfo.timeStamp,
nonceStr: orderInfo.nonceStr,
package: orderInfo.package,
signType: orderInfo.signType,
paySign: orderInfo.paySign,
});
console.log("微信支付成功:", paymentResult);
return {
success: true,
data: paymentResult
};
} catch (error) {
console.error("微信支付失败:", error);
if (error.errMsg === "requestPayment:fail cancel") {
throw new Error("用户取消支付");
}
throw new Error("微信支付失败");
}
// #endif
// #ifdef H5
// H5
if (typeof WeixinJSBridge !== "undefined") {
return new Promise((resolve, reject) => {
WeixinJSBridge.invoke(
"getBrandWCPayRequest", {
appId: 'wxc504638e03981812',
timeStamp: orderInfo.timeStamp,
nonceStr: orderInfo.nonceStr,
package: orderInfo.package,
signType: orderInfo.signType,
paySign: orderInfo.paySign,
},
(res) => {
if (res.err_msg === "get_brand_wcpay_request:ok") {
resolve({
success: true,
data: res
});
} else if (res.err_msg === "get_brand_wcpay_request:cancel") {
reject(new Error("用户取消支付"));
} else {
reject(new Error("微信支付失败"));
}
}
);
});
} else {
//
const payUrl = orderInfo.mwebUrl; // H5
window.location.href = payUrl;
return {
success: true,
redirect: true
};
}
// #endif
};
// H5
const alipayPay = async (orderInfo) => {
// #ifdef H5
// H5
const payUrl = orderInfo.payUrl; // H5
window.location.href = payUrl;
return {
success: true,
redirect: true
};
// #endif
};
function showModalAsync(options) {
return new Promise((resolve, reject) => {
uni.showModal({
...options,
success: (res) => {
resolve(res); // await
},
fail: (err) => {
reject(err); //
}
});
});
}
//
const payOrder = async (order) => {
try {
uni.showLoading({
title: "正在处理支付...",
});
//
let paymentResult;
if (order.pay_channel === "wxpay") {
const res = await uni.login({
provider: 'weixin'
})
const orderResult = await RPC.post('/membership/order/pay_by_wechat_mini', {
code: res.code,
"order_no": order.order_no
})
uni.showLoading({
title: "正在跳转微信支付...",
});
console.log('orderResult', orderResult)
paymentResult = await wechatPay(orderResult);
} else if (order.pay_channel === "alipay") {
const orderResult = await RPC.post('/membership/order/pay_by_alipay', {
order_no: order.order_no
})
uni.showLoading({
title: "正在跳转支付宝...",
});
paymentResult = await alipayPay(orderResult);
} else if (order.pay_channel === 'wallet') {
const res = await showModalAsync({
title: '确认支付',
content: '确定继续支付这个订单吗?',
success: async (res) => {
content: '确认使用钱包余额支付?'
});
//
if (res.confirm) {
paymentResult = await RPC.post('/membership/order/pay_by_wallet', {
order_no: order.order_no
})
console.log('paymentResult', paymentResult)
} else if (res.cancel) {
console.log('用户点击了取消');
paymentResult = { success: false }
}
}
uni.hideLoading();
console.log('paymentResult', paymentResult)
//
if (paymentResult?.success) {
if (paymentResult.redirect) {
// H5
uni.showToast({
title: "正在跳转支付页面...",
icon: "loading",
duration: 2000,
});
} else {
//
setTimeout(() => {
uni.showToast({
title: "支付成功",
icon: "success",
});
//
const index = list.value.findIndex(item => item.id === order.id)
if (index !== -1) {
list.value[index].status = 'paid'
}
//
setTimeout(() => {
getList()
}, 500)
}, 1000)
}
}
} catch (error) {
uni.hideLoading();
console.error("支付失败:", error);
let errorMessage = "支付失败,请重试";
if (error.message === "用户取消支付") {
errorMessage = "支付已取消";
} else if (error.message) {
errorMessage = error.message;
} else if (error) {
errorMessage = error
}
uni.showToast({
title: errorMessage,
icon: "none",
});
}
})
}
const page = ref(1)

@ -3,12 +3,8 @@
<!-- 生成记录列表 -->
<view class="record-list">
<uv-swipe-action>
<uv-swipe-action-item
@click="delItem(record)"
:options="options"
v-for="record in list"
:key="record.id"
>
<uv-swipe-action-item @click="delItem(record)" :options="options" v-for="record in list"
:key="record.ID">
<view class="record-item">
<!-- 记录信息 -->
<view class="record-info">
@ -24,13 +20,10 @@
</view>
<!-- 状态标签 -->
<view
class="status-tag"
:class="{
<view class="status-tag" :class="{
completed: record.status == 4,
failed: record.status == 5,
}"
>
}">
<span v-if="record.status == 4"></span>
<span v-else-if="record.status == 5">生成失败</span>
<span v-else></span>
@ -38,27 +31,13 @@
<!-- 操作按钮 -->
<view class="record-actions">
<uv-button
v-if="record.status === 4"
type="primary"
size="small"
@click="downloadRecord(record)"
>
<uv-icon
name="download"
size="14"
color="white"
style="margin-right: 4px"
></uv-icon>
<uv-button v-if="record.status === 4" type="primary" size="small"
@click="downloadRecord(record)">
<uv-icon name="download" size="14" color="white" style="margin-right: 4px"></uv-icon>
下载
</uv-button>
<uv-button v-else type="info" size="small" disabled>
<uv-icon
name="download"
size="14"
color="#aaa"
style="margin-right: 4px"
></uv-icon>
<uv-icon name="download" size="14" color="#aaa" style="margin-right: 4px"></uv-icon>
下载
</uv-button>
</view>
@ -79,32 +58,37 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import RPC from "@/utils/request";
import dayjs from "dayjs";
import { onShow, onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
import {
ref,
onMounted
} from "vue";
import RPC from "@/utils/request";
import dayjs from "dayjs";
import {
onShow,
onPullDownRefresh,
onReachBottom
} from "@dcloudio/uni-app";
const options = ref([
{
const options = ref([{
text: "删除",
style: {
backgroundColor: "#f56c6c",
},
},
]);
const delItem = (item) => {
}, ]);
const delItem = (item) => {
console.log(item);
deleteRecord(item);
};
//
const loading = ref(false);
const loadingStatus = ref("loadmore");
const page = ref(1);
const list = ref([]);
const count = ref(0);
};
//
const loading = ref(false);
const loadingStatus = ref("loadmore");
const page = ref(1);
const list = ref([]);
const count = ref(0);
//
const downloadRecord = (record) => {
//
const downloadRecord = (record) => {
uni.showLoading({
title: "准备下载...",
});
@ -167,42 +151,38 @@ const downloadRecord = (record) => {
},
});
// #endif
};
};
//
const deleteRecord = (record) => {
//
const deleteRecord = (record) => {
uni.showModal({
title: "确认删除",
content: "确定要删除这条生成记录吗?删除后无法恢复。",
success: (res) => {
if (res.confirm) {
//
const index = records.value.findIndex((item) => item.id === record.id);
if (index !== -1) {
records.value.splice(index, 1);
}
RPC.post('/planned_delete', {
id: record.ID
}).then(() => {
list.value = list.value.filter((item) => item.ID !== record.ID);
uni.showToast({
title: "删除成功",
icon: "success",
});
// API
// try {
// await RPC.post('/api/generate-record/delete', { id: record.id })
// } catch (error) {
// console.error(':', error)
// }
})
//
}
},
});
};
};
//
const loadRecords = async () => {
//
const loadRecords = async () => {
uni.showLoading();
loadingStatus.value = "loading";
RPC.post("/planned_list", { page: page.value, page_size: 20 })
RPC.post("/planned_list", {
page: page.value,
page_size: 20
})
.then((res) => {
list.value = [...list.value, ...res.list];
count.value = res.total;
@ -217,14 +197,17 @@ const loadRecords = async () => {
}).finally(() => {
uni.hideLoading();
});
};
};
//
onPullDownRefresh(() => {
//
onPullDownRefresh(() => {
list.value = [];
page.value = 1;
loadingStatus.value = "loading";
RPC.post("/planned_list", { page: page.value, page_size: 20 })
RPC.post("/planned_list", {
page: page.value,
page_size: 20
})
.then((res) => {
list.value = [...list.value, ...res.list];
count.value = res.total;
@ -240,38 +223,38 @@ onPullDownRefresh(() => {
.finally(() => {
uni.stopPullDownRefresh();
});
});
});
onReachBottom(() => {
onReachBottom(() => {
loadmore();
});
});
const loadmore = () => {
const loadmore = () => {
if (list.value.length >= count.value || loadingStatus.value === "loading")
return;
console.log("上拉加载:");
loadingStatus.value = "loading";
page.value = ++page.value;
loadRecords();
};
};
onShow(() => {
onShow(() => {
//
list.value = [];
page.value = 1;
loadRecords();
});
});
</script>
<style lang="scss" scoped>
.container {
.container {
font-size: 14px;
min-height: 100vh;
background-color: #f8f8f8;
padding: 16px;
}
}
.record-list {
.record-list {
.record-item {
background: white;
border-radius: 12px;
@ -327,9 +310,9 @@ onShow(() => {
flex-shrink: 0;
}
}
}
}
.empty-state {
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
@ -341,10 +324,10 @@ onShow(() => {
font-size: 14px;
margin-top: 16px;
}
}
}
.load-more {
.load-more {
padding: 20px;
text-align: center;
}
}
</style>

@ -1,40 +0,0 @@
订单列表的
"id": it.ID, // 订单ID
"order_no": it.OrderNo, // 订单号M=会员订单R=充值订单)
"user_id": it.UserID, // 用户ID
"user_name": userNameMap[it.UserID], // 用户名
"plan_id": it.PlanID, // 套餐ID充值订单为0
"plan_name": planName, // 套餐名称(充值订单固定为“钱包充值”)
"order_type": it.OrderType, // 订单类型:会员购买/钱包充值(中文)
"amount_cents": it.AmountCents.ToInt64(), // 订单金额(分)
"amount": it.AmountCents.String(), // 订单金额(元,字符串,保留两位小数)
"pay_channel": it.PayChannel, // 支付渠道wallet|wxpay|alipay|other
"status": it.Status, // 订单状态created|paid|canceled|refunded
"pay_time": it.PayTime, // 支付时间Unix 时间戳,秒)
"transaction_id": it.TransactionID, // 第三方交易号/平台流水号
"remark": it.Remark, // 备注
"created_at": it.CreatedAt, // 创建时间Unix 时间戳,秒)
"updated_at": it.UpdatedAt, // 更新时间Unix 时间戳,秒)
消费列表
"id": it.ID, // 流水ID
"user_id": it.UserID, // 用户ID
"user_name": userName, // 用户名
"type": it.Type, // 交易类型recharge(充值)|purchase(消费)
"amount_cents": it.AmountCents.ToInt64(), // 金额(分)
"amount": it.AmountCents.String(), // 金额(元,字符串,保留两位小数)
"related_order_id": it.RelatedOrderID, // 关联的订单ID可为空
"order_no": it.OrderNo, // 关联订单号M* 会员订单 / R* 充值订单)
"pay_channel": it.PayChannel, // 支付渠道wallet|wxpay|alipay|other
"status": it.Status, // 交易状态success|failed|pending
"remark": it.Remark, // 备注
"balance_before_cents": it.BalanceBeforeCents.ToInt64(), // 变动前余额(分)
"balance_after_cents": it.BalanceAfterCents.ToInt64(), // 变动后余额(分)
"finished_at": it.FinishedAt, // 完成时间Unix 时间戳,秒)
"external_txn_id": it.ExternalTxnID, // 外部交易号(第三方平台返回)
"currency": it.Currency, // 币种(默认 CNY
"created_at": it.CreatedAt, // 创建时间Unix 时间戳,秒)
})

@ -41,8 +41,8 @@
<view class="section-title">选择支付方式</view>
<view class="payment-list">
<!-- 微信支付 -->
<view class="payment-item" :class="{ active: selectedPayment === 'wechat' }"
@click="selectPayment('wechat')">
<view class="payment-item" :class="{ active: selectedPayment === 'wxpay' }"
@click="selectPayment('wxpay')">
<view class="payment-info">
<uv-icon name="weixin-fill" color="#07c160" size="28"></uv-icon>
<view class="payment-details">
@ -50,7 +50,7 @@
<view class="payment-desc">安全快捷支持零钱和银行卡</view>
</view>
</view>
<uv-icon name="checkmark-circle-fill" :color="selectedPayment === 'wechat' ? '#4285f4' : '#ccc'"
<uv-icon name="checkmark-circle-fill" :color="selectedPayment === 'wxpay' ? '#4285f4' : '#ccc'"
size="20"></uv-icon>
</view>
@ -137,7 +137,7 @@
const currentBalance = ref(0);
const selectedAmount = ref(0);
const customAmount = ref('');
const selectedPayment = ref('wechat');
const selectedPayment = ref('wxpay');
const recharging = ref(false);
const showAlipay = ref(true);
@ -216,7 +216,7 @@
// #ifdef MP-WEIXIN
//
showAlipay.value = false;
selectedPayment.value = 'wechat';
selectedPayment.value = 'wxpay';
// #endif
// #ifdef H5
@ -225,7 +225,7 @@
//
const ua = navigator.userAgent.toLowerCase();
const isWechat = ua.indexOf('micromessenger') !== -1;
selectedPayment.value = isWechat ? 'wechat' : 'alipay';
selectedPayment.value = isWechat ? 'wxpay' : 'alipay';
// #endif
};
@ -386,7 +386,7 @@
//
let paymentResult;
if (selectedPayment.value === 'wechat') {
if (selectedPayment.value === 'wxpay') {
const res = await uni.login({
provider: 'weixin'
})

Loading…
Cancel
Save