This commit is contained in:
2026-03-30 15:09:54 +08:00
parent a98fb14ae7
commit 345b543cfd
8 changed files with 741 additions and 1183 deletions

View File

@ -157,14 +157,12 @@ export const createOrder = ({
}; };
// 创建抖音订单 // 创建抖音订单
export const createCartOrder = ({ export const createCartOrder = ({ id }) => {
product_pic= "",
}) => {
return request({ return request({
url: CREATE_CART_ORDER, url: CREATE_CART_ORDER,
method: "post", method: "post",
data: { data: {
orderId id
}, },
}); });
}; };

View File

@ -58,7 +58,7 @@ export const CANCEL_PET_ORDER = '/order/pet/cancel'
// 取消商城接口 // 取消商城接口
export const CANCEL_MALL_ORDER = '/product/order/cancel' export const CANCEL_MALL_ORDER = '/douyin/goods/order/cancel'
// 卡包列表接口 // 卡包列表接口
export const USER_HolderList = '/membership/instances' export const USER_HolderList = '/membership/instances'

View File

@ -1,187 +0,0 @@
<template>
<view class="refund-button-wrapper" :class="{ 'compact-mode': compact }" :style="wrapperStyle">
<view class="pay-button-container">
<pay-button-sdk
:mode="mode"
:order-status="orderStatus"
:order-id="orderId"
:refund-total-amount="refundTotalAmount"
@getgoodsinfo="handleGetGoodsInfo"
@placeorder="handlePlaceOrder"
@pay="handlePay"
@refund="handleRefund"
@error="handleError"
>
<text class="refund-text">退款</text>
</pay-button-sdk>
</view>
</view>
</template>
<script>
export default {
name: "RefundButton",
props: {
// 模式1-仅退款2-退货退款
mode: {
type: [String, Number],
default: '1'
},
// 订单状态1-待发货2-待收货3-已完成
orderStatus: {
type: [String, Number],
default: '1'
},
// 订单ID
orderId: {
type: String,
required: true
},
// 退款总金额(单位:分)
refundTotalAmount: {
type: Number,
default: 0
},
// 是否使用紧凑模式(适合订单列表页)
compact: {
type: Boolean,
default: false
}
},
computed: {
wrapperStyle() {
if (!this.compact) {
return {
flex: '1',
width: '100%',
display: 'flex',
height: '48px'
}
}
return {}
}
},
methods: {
// 抖音官方组件生命周期回调 - 获取商品信息
handleGetGoodsInfo(e) {
console.log('抖音组件获取商品信息回调:', e.detail)
// 退款模式下不需要额外处理,直接返回成功即可
e.detail.success({
// 可根据实际业务补充商品信息
amount: this.refundTotalAmount
})
},
// 抖音官方组件生命周期回调 - 下单
handlePlaceOrder(e) {
console.log('抖音组件下单回调:', e.detail)
// 退款模式下不需要额外处理,直接返回成功即可
e.detail.success({
orderId: this.orderId
})
},
// 抖音官方组件生命周期回调 - 支付
handlePay(e) {
console.log('抖音组件支付回调:', e.detail)
// 退款模式下不需要额外处理,直接返回成功即可
e.detail.success()
},
// 退款成功回调
handleRefund(e) {
console.log('抖音退款组件退款成功回调:', e.detail)
this.$emit('refund', {
detail: {
status: 'success',
data: e.detail
}
})
},
// 错误回调
handleError(e) {
console.error('抖音退款组件错误回调:', e.detail)
this.$emit('error', {
detail: {
status: 'error',
message: e.detail.errMsg || '退款失败'
}
})
}
}
};
</script>
<style lang="scss" scoped>
.refund-button-wrapper {
height: 73rpx !important;
border-radius: 100px;
border: 2rpx solid #FF19A0;
color: #FF19A0;
background: transparent;
display: flex !important;
align-items: center;
justify-content: center;
font-size: 14px;
overflow: hidden;
flex: 1 !important;
width: 100% !important;
min-width: 0 !important;
box-sizing: border-box;
}
.pay-button-container {
width: 100% !important;
height: 100% !important;
display: flex !important;
align-items: center;
justify-content: center;
flex: 1 !important;
min-width: 0 !important;
}
.refund-button-sdk {
width: 100% !important;
height: 100% !important;
display: flex !important;
align-items: center;
justify-content: center;
box-sizing: border-box;
flex: 1 !important;
}
// 强制设置 pay-button-sdk 内部元素样式
::v-deep .pay-button-sdk {
width: 100% !important;
height: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
flex: 1 !important;
}
.refund-text {
color: #FF19A0;
font-family: PingFang SC;
font-size: 14px;
}
.refund-button-wrapper.compact-mode {
width: 70px;
height: 34px;
border-radius: 64rpx;
border: 1px solid #FF19A0;
margin-left: 20rpx;
font-size: 24rpx;
flex: none;
display: flex !important;
align-items: center;
justify-content: center;
padding: 0;
}
.compact-mode .refund-text {
font-size: 24rpx;
}
</style>

View File

@ -1,5 +1,13 @@
{ {
"easycom": {}, "easycom": {},
"ttPlugins": {
"dependencies": {
"tta5a3d31e3aecfb9b11": {
"version": "0.0.51",
"isDynamic": false
}
}
},
"pages": [ "pages": [
{ {
"path": "pages/client/index/index", "path": "pages/client/index/index",
@ -299,8 +307,7 @@
"style": { "style": {
"navigationBarTitleText": "订单详情", "navigationBarTitleText": "订单详情",
"usingComponents": { "usingComponents": {
"refund-button": "plugin://myTradePlugin/pay-button", "pay-button-sdk": "tta5a3d31e3aecfb9b11://pay-button"
"pay-button-sdk": "plugin://myTradePlugin/pay-button"
} }
} }
}, },
@ -315,7 +322,7 @@
"style": { "style": {
"navigationBarTitleText": "商城订单", "navigationBarTitleText": "商城订单",
"usingComponents": { "usingComponents": {
"pay-button-sdk": "plugin://myTradePlugin/pay-button" "pay-button-sdk": "tta5a3d31e3aecfb9b11://pay-button"
} }
} }
}, },

View File

@ -65,33 +65,13 @@
</view> </view>
</template> </template>
<!-- 待发货 --> <!-- 待预约 -->
<template v-if="[SHOP_ORDER_UNSLIVER].includes(data.status)"> <template v-if="[SHOP_ORDER_UNSLIVER].includes(data.status)">
<view class="order-btns-right"> <view class="order-btns-right">
<!-- <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('concactService', data)"> <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('refund', data)">
联系客服 申请退款
</view> --> </view>
<!-- <view <view class="flex-center fs-24 app-fc-white status-btn confirm"
class="flex-center fs-24 app-fc-main status-btn"
@click.stop="$emit('afterSale', data)"
>
申请售后
</view> -->
<!-- <view class="flex-center fs-24 app-fc-main status-btn" @click.stop="$emit('refund', data)">
退款
</view> -->
<refund-button
mode="2"
order-status="1"
:order-id="data.order_no"
:refund-total-amount="(data.actual_price || 0) * 100"
:compact="true"
@refund="handleRefund"
@error="handleError"
style="width:140rpx;height:68rpx;"
/>
<view class="flex-center fs-24 app-fc-white status-btn confirm"
@click.stop="jumpToReservation"> @click.stop="jumpToReservation">
立即预约 立即预约
</view> </view>
@ -155,7 +135,6 @@
<script> <script>
import PopUpModal from "@/components/PopUpModal.vue"; import PopUpModal from "@/components/PopUpModal.vue";
import GoodInfo from "./GoodInfo.vue"; import GoodInfo from "./GoodInfo.vue";
import RefundButton from "@/components/RefundButton.vue";
import { import {
SHOP_ORDER_STATUS, SHOP_ORDER_STATUS,
SHOP_ORDER_UNPAY, SHOP_ORDER_UNPAY,
@ -202,13 +181,45 @@
}, },
components: { components: {
GoodInfo, GoodInfo,
PopUpModal, PopUpModal
RefundButton
}, },
options: { options: {
styleIsolation: "shared", styleIsolation: "shared",
}, },
computed: { computed: {
// 抖音退款组件需要的订单ID
orderId() {
return this.data.order_id || this.data.order_no || "";
},
// 抖音退款组件需要的订单状态1=待核销/待发货2=已核销/已发货)
orderStatusForSDK() {
// 根据你的业务状态映射到抖音SDK需要的状态
// SHOP_ORDER_UNSLIVER = 待发货 -> 映射为 1
if (this.data.status === SHOP_ORDER_UNSLIVER) {
return 1;
}
// SHOP_ORDER_UNRECEIVE = 待收货 -> 映射为 2
if (this.data.status === SHOP_ORDER_UNRECEIVE) {
return 2;
}
return 1;
},
// 订单总金额(单位:分)
orderTotalAmount() {
const price = this.data.actual_price || 0;
// 转换为分
return Math.round(parseFloat(price) * 100);
},
// UniApp 需要传入的退款参数对象
refundParams() {
return {
reasonCode: [410],
note: '用户申请退款',
applySource: 101,
afterSaleType: 3,
needRefundPackFee: true
}
},
orderStatus() { orderStatus() {
return SHOP_ORDER_STATUS[this.data.status] || ""; return SHOP_ORDER_STATUS[this.data.status] || "";
}, },
@ -258,18 +269,32 @@
this.stopCountDown(); this.stopCountDown();
}, },
methods: { methods: {
handleRefund(e) { // 退款回调(组件触发)
console.log('退款结果:', e.detail) handleRefund(event) {
if (e.detail.status === 'success') { const { status, result, outOrderNo } = event.detail
uni.showToast({ title: '退款申请已提交', icon: 'success' }) console.log('退款回调:', { status, result, outOrderNo })
if (status === 'success') {
uni.showToast({
title: '退款申请已提交',
icon: 'success'
})
this.$emit('refund', this.data) this.$emit('refund', this.data)
} else { } else {
uni.showToast({ title: '退款失败', icon: 'none' }) uni.showToast({
title: result?.errMsg || '退款失败,请稍后重试',
icon: 'none'
})
} }
}, },
handleError(e) { // 错误处理
console.error('组件错误:', e.detail) handleError(event) {
console.error('退款组件报错:', event.detail)
uni.showToast({
title: '组件加载失败,请稍后重试',
icon: 'none'
})
}, },
startCountDown() { startCountDown() {

File diff suppressed because it is too large Load Diff

View File

@ -263,13 +263,20 @@
<!-- 待发货 --> <!-- 待发货 -->
<template v-if="[SHOP_ORDER_UNSLIVER].includes(orderData.status)"> <template v-if="[SHOP_ORDER_UNSLIVER].includes(orderData.status)">
<!-- 使用原来的 RefundButton 组件 --> <!-- 抖音退款组件 -->
<view class="refund-btn-wrapper"> <view class="refund-btn-wrapper">
<refund-button <pay-button-sdk
mode="2" mode=1
order-status="1" :order-id="orderData.order_no || orderData.order_id"
:order-id="orderData.order_no" :order-status="1"
:refund-total-amount="Math.round((orderData.actual_price || 0) * 100)" :refund-total-amount="Math.round((orderData.actual_price || 0) * 100)"
:apply-refund-params="{
reasonCode: [410],
note: '用户申请退款',
applySource: 101,
afterSaleType: 3,
needRefundPackFee: true
}"
@refund="handleRefundSuccess" @refund="handleRefundSuccess"
@error="handleRefundError" @error="handleRefundError"
/> />
@ -344,7 +351,6 @@
import SliverInfo from "./components/SliverInfo.vue"; import SliverInfo from "./components/SliverInfo.vue";
import CallModal from "@/components/petOrder/call-modal.vue"; import CallModal from "@/components/petOrder/call-modal.vue";
import DraggableContact from "@/components/DraggableContact.vue"; import DraggableContact from "@/components/DraggableContact.vue";
import RefundButton from "@/components/RefundButton.vue";
import { import {
walletTransaction, walletTransaction,
cancelPetOrderRefund, cancelPetOrderRefund,
@ -391,8 +397,7 @@ import {
SuccessModal, SuccessModal,
SliverInfo, SliverInfo,
CallModal, CallModal,
DraggableContact, DraggableContact
RefundButton
}, },
data() { data() {
return { return {

View File

@ -9,7 +9,7 @@
<view v-for="(data, index) in list" :key="data.order_id" :class="{ left: index % 2 === 0 }" <view v-for="(data, index) in list" :key="data.order_id" :class="{ left: index % 2 === 0 }"
class="flex-column-start news-item"> class="flex-column-start news-item">
<order-item :data="data" @disableScroll="disableScrollAction" @cancelOrder="cancelOrderAction" <order-item :data="data" @disableScroll="disableScrollAction" @cancelOrder="cancelOrderAction"
@refund="refundAction" @concactService="jumpToWeChat" @confirmSliver="confirmSliver" @remindSilver="remindSliver" @pay="pay" @refund="handleRefundFromItem" @concactService="jumpToWeChat" @confirmSliver="confirmSliver" @remindSilver="remindSliver" @pay="pay"
@afterSale="afterSale" @checkSliver="checkSliver" @remark="remark" @remarkDetails="remarkDetails" @afterSale="afterSale" @checkSliver="checkSliver" @remark="remark" @remarkDetails="remarkDetails"
@jumpToDetails="jumpToDetails" /> @jumpToDetails="jumpToDetails" />
</view> </view>
@ -250,7 +250,7 @@ export default {
mask: true, mask: true,
}); });
const data = { const data = {
order_id: this.orderInfo.order_id, id: this.orderInfo.order_id,
// business_type:1 // business_type:1
} }
@ -308,37 +308,58 @@ export default {
title: "支付中", title: "支付中",
mask: true, mask: true,
}); });
payOrder({
type: 4, const plugin = tt.requirePlugin('tta5a3d31e3aecfb9b11');
total_fee: Number(data.actual_price), plugin.continueToPay({
order_id: data.order_id, orderId: "orderId", // 内部订单号
order_no: data.order_no outOrderNo: "outOrderNo", // 外部订单号 2个订单号必填一个
}).then((res) => { success: (res) => {
tt.pay({ const { orderId, outOrderNo } = res;
orderInfo: { console.log("success res", res);
order_id:res.data.orderInfo.order_id, console.log("orderId", orderId, "outOrderNo", outOrderNo);
order_token:res.data.orderInfo.order_token, },
}, fail: (res) => {
service:5, uni.hideLoading();
success: (res) => { const { orderId, outOrderNo, errNo, errMsg, errLogId } = res;
uni.hideLoading(); if (errLogId) {
uni.showToast({ console.log("查询订单信息失败", errNo, errMsg, errLogId);
title: "支付成功", }
icon: "none", if (orderId || outOrderNo) {
}); console.log("支付失败", errNo, errMsg, orderId, outOrderNo);
this.additionalBom = false, }
this.elasticLayer = false, },
this.reloadData(); });
}, // payOrder({
fail: (err) => { // type: 4,
uni.hideLoading(); // total_fee: Number(data.actual_price),
uni.showToast({ // order_id: data.order_id,
title: err?.msg || "支付失败", // order_no: data.order_no
icon: "none", // }).then((res) => {
}); // tt.pay({
}, // orderInfo: {
}); // order_id:res.data.orderInfo.order_id,
}); // order_token:res.data.orderInfo.order_token,
// },
// service:5,
// success: (res) => {
// uni.hideLoading();
// uni.showToast({
// title: "支付成功",
// icon: "none",
// });
// this.additionalBom = false,
// this.elasticLayer = false,
// this.reloadData();
// },
// fail: (err) => {
// uni.hideLoading();
// uni.showToast({
// title: err?.msg || "支付失败",
// icon: "none",
// });
// },
// });
// });
// this.additionalBom = true; // this.additionalBom = true;
// this.elasticLayer = true; // this.elasticLayer = true;
@ -499,6 +520,16 @@ export default {
this.cancelModalContent = "确定要退款吗?"; this.cancelModalContent = "确定要退款吗?";
this.orderInfo = data; this.orderInfo = data;
}, },
// 处理从 OrderItem 传来的退款事件
handleRefundFromItem(data) {
// 跳转到订单详情页处理退款,因为插件组件只能在页面中使用
uni.navigateTo({
url: `/pages/client/order/details?id=${data?.order_id}`,
events: {
refreshData: () => this.reloadData(),
},
});
},
// 联系客服按钮点击 - 使用自定义弹窗(与首页在线客服功能一致) // 联系客服按钮点击 - 使用自定义弹窗(与首页在线客服功能一致)
handleContactBtnClick() { handleContactBtnClick() {
console.log('[list.vue] handleContactBtnClick called') console.log('[list.vue] handleContactBtnClick called')