fix(订单端): 详情支持取消未支付订单并同步列表,备注留言整行展示

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
吴昊天 2026-10-26 12:04:40 +08:00
parent e87a6b20be
commit b6367d82d9
5 changed files with 60 additions and 13 deletions

View File

@ -203,8 +203,8 @@
<div class="section">
<div class="title">买家留言</div>
<ul class="list">
<li class="item">
<div>{{ data.mark || '--' }}</div>
<li class="item item-full">
<div class="full-text">{{ data.mark || '--' }}</div>
</li>
</ul>
</div>
@ -227,8 +227,8 @@
<div class="section">
<div class="title">订单备注</div>
<ul class="list">
<li class="item">
<div>{{ data.remark || '--' }}</div>
<li class="item item-full">
<div class="full-text">{{ data.remark || '--' }}</div>
</li>
</ul>
</div>
@ -351,6 +351,20 @@ function isImageItem(item) {
&:nth-child(3n + 3) {
padding-left: 20px;
}
// 买家留言 / 订单备注:占满整行,避免按三列宽度提前换行
&.item-full {
flex: 0 0 100%;
padding-left: 0;
padding-right: 0;
word-break: break-word;
white-space: pre-wrap;
}
}
.full-text {
width: 100%;
line-height: 1.6;
}
.value {

View File

@ -46,14 +46,18 @@ export default {
}
uni.navigateTo({ url: routes.cashier + '?order_no=' + orderId + '&from_type=order' });
},
/** 取消订单 */
cancelOrder(order, params) {
/** 取消订单(详情页通过 context.onCancel 自行调接口并刷新;列表页走事件总线) */
cancelOrder(order, params, context) {
const orderNo = params.order_no || order.order_no || '';
uni.showModal({
title: i18n.t(`提示`),
content: i18n.t(`确定取消该订单吗?`),
success: (res) => {
if (res.confirm) {
if (context && typeof context.onCancel === 'function') {
context.onCancel({ order_no: orderNo });
return;
}
uni.$emit('order:cancel', { order_no: orderNo });
}
},

View File

@ -1,6 +1,6 @@
<!--
订单自定义表单
根据后端 custom_form 动态渲染必填信息字段
根据后端 custom_form 动态渲染表单信息字段
字段结构:{ label, field, type, options, required }
type 为管理端「自定义表单」类型:text 文本框 / number 数字 / email 邮件 /
data 日期 / time 时间 / id 身份证 / phone 手机号 / img 图片,
@ -8,7 +8,7 @@
-->
<template>
<view class="custom-form-section" v-if="visible && fields.length > 0">
<view class="section-title">{{ $t('必填信息') }}</view>
<view class="section-title">{{ $t('表单信息') }}</view>
<view class="form-list">
<view class="form-item" v-for="(field, index) in fields" :key="index" :class="{ 'is-bordered': index > 0 }">
<view class="form-label">

View File

@ -61,7 +61,7 @@ import { resolveSectionComponent, InfoListComponent } from '../components/order/
import SectionDispatcher from '../components/order/detail/SectionDispatcher.vue';
// #endif
import actionMap from '../api/action-map.js';
import { getCenterOrderDetail, takeOrder } from '@/api/order-center.js';
import { getCenterOrderDetail, takeOrder, cancelOrder } from '@/api/order-center.js';
import { express } from '@/api/order.js';
import routes from '../api/routes.js';
import { useColorTheme } from '@/composables/useColorTheme';
@ -82,6 +82,7 @@ const { colorStyle } = useColorTheme();
const pageConfig = ref({ sections: [], extensions: {} });
const loading = ref(true);
const confirmingReceive = ref(false);
const cancellingOrder = ref(false);
const logisticsLoading = ref(false);
// 送礼分享
const giftModalShow = ref(false);
@ -288,6 +289,8 @@ function onButtonAction(payload) {
var context;
if (payload.action === 'confirmReceive') {
context = { onConfirm: confirmReceive };
} else if (payload.action === 'cancelOrder') {
context = { onCancel: cancelUnpaidOrder };
} else if (payload.action === 'shareGift') {
context = { onShareGift: openGiftShare };
}
@ -313,12 +316,33 @@ async function confirmReceive(payload) {
await takeOrder(payload.order_no);
uni.showToast({ title: i18n.t('收货成功'), icon: 'success' });
await loadDetail();
// 通知列表页同步刷新(栈内列表仍挂载时立即更新)
uni.$emit('order:list-refresh');
} catch (e) {
uni.showToast({ title: e?.msg || i18n.t('收货失败'), icon: 'none' });
uni.showToast({ title: (typeof e === 'string' ? e : e?.msg) || i18n.t('收货失败'), icon: 'none' });
} finally {
confirmingReceive.value = false;
}
}
/**
* 详情页取消未支付订单
* @param {object} payload {order_no}
*/
async function cancelUnpaidOrder(payload) {
if (cancellingOrder.value) return;
cancellingOrder.value = true;
try {
await cancelOrder(payload.order_no);
uni.showToast({ title: i18n.t('取消成功'), icon: 'success' });
await loadDetail();
uni.$emit('order:list-refresh');
} catch (e) {
uni.showToast({ title: (typeof e === 'string' ? e : e?.msg) || i18n.t('取消失败'), icon: 'none' });
} finally {
cancellingOrder.value = false;
}
}
/**
* 行动入口卡片点击(ActionCard emit)
* @param {object} payload {action, link}

View File

@ -274,7 +274,7 @@ async function onCancelOrder({ order_no }) {
uni.showToast({ title: i18n.t('取消成功'), icon: 'success' });
refreshList();
} catch (e) {
uni.showToast({ title: e?.msg || i18n.t('取消失败'), icon: 'none' });
uni.showToast({ title: (typeof e === 'string' ? e : e?.msg) || i18n.t('取消失败'), icon: 'none' });
}
}
/**
@ -286,7 +286,7 @@ async function onConfirmOrder({ order_no }) {
uni.showToast({ title: i18n.t('收货成功'), icon: 'success' });
refreshList();
} catch (e) {
uni.showToast({ title: e?.msg || i18n.t('收货失败'), icon: 'none' });
uni.showToast({ title: (typeof e === 'string' ? e : e?.msg) || i18n.t('收货失败'), icon: 'none' });
}
}
/**
@ -298,15 +298,17 @@ async function onDeleteOrder({ order_no }) {
uni.showToast({ title: i18n.t('删除成功'), icon: 'success' });
refreshList();
} catch (e) {
uni.showToast({ title: e?.msg || i18n.t('删除失败'), icon: 'none' });
uni.showToast({ title: (typeof e === 'string' ? e : e?.msg) || i18n.t('删除失败'), icon: 'none' });
}
}
/**
* 刷新列表
* 必须先复位 loading,否则进行中的 loadOrders 会让本次刷新被 if (loading) return 吞掉
*/
function refreshList() {
page.value = 1;
finished.value = false;
loading.value = false;
orders.value = [];
getOrderData();
loadOrders();
@ -323,10 +325,13 @@ onMounted(() => {
uni.$on('order:cancel', onCancelOrder);
uni.$on('order:confirm', onConfirmOrder);
uni.$on('order:delete', onDeleteOrder);
// 详情页取消/收货成功后同步刷新栈内列表
uni.$on('order:list-refresh', refreshList);
});
onBeforeUnmount(() => {
uni.$off('order:cancel', onCancelOrder);
uni.$off('order:list-refresh', refreshList);
uni.$off('order:confirm', onConfirmOrder);
uni.$off('order:delete', onDeleteOrder);
});