liujie
2026-08-06 07ccdb21597bfe0bf65e9ce814087c12bd0af959
update
3个文件已修改
160 ■■■■■ 已修改文件
mingdaojingjiang_uniapp/mingdaojingjiang_uniapp/pages/order-completed/index.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mingdaojingjiang_uniapp/mingdaojingjiang_uniapp/pages/order-pending-review/index.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mingdaojingjiang_uniapp/mingdaojingjiang_uniapp/pages/order-review-detail/index.vue 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mingdaojingjiang_uniapp/mingdaojingjiang_uniapp/pages/order-completed/index.vue
@@ -16,9 +16,9 @@
            <image class="guide-avatar__icon" :src="order.guideAvatar || '/static/ui-icons/user-blue.svg'" mode="aspectFill" />
          </view>
          <view class="guide-main">
            <text class="guide-name">?? ? {{ order.guideName }}</text>
            <text class="guide-name">导游 · {{ order.guideName }}</text>
            <view class="guide-stars">
              <text v-for="item in 5" :key="item" class="guide-star" :class="{ 'guide-star--inactive': item > guideStarCount }">?</text>
              <text v-for="item in 5" :key="item" class="guide-star" :class="{ 'guide-star--inactive': item > guideStarCount }">★</text>
            </view>
          </view>
          <view class="phone-action" @tap="handleCallGuide">
@@ -41,7 +41,7 @@
          <view class="price-row">
            <view class="unit-block">
              <text class="unit-price">¥{{ order.unitPrice }}/人</text>
              <text class="unit-price">¥{{ order.unitPrice }}{{ order.unit }}</text>
              <text class="quantity">x{{ order.quantity }}</text>
            </view>
            <text class="total-price">¥{{ order.total }}</text>
@@ -89,14 +89,14 @@
  id: orderDetail.value.id || orderId.value,
  scenic: orderDetail.value.scenicName || '-',
  service: formatServiceTitle(orderDetail.value.packageName, orderDetail.value.orderType),
  duration: orderDetail.value.durationMinutes ? `${orderDetail.value.durationMinutes}??` : '-',
  duration: orderDetail.value.durationMinutes ? `${orderDetail.value.durationMinutes}分钟` : '-',
  meetingPoint: orderDetail.value.meetingPointName || '-',
  unitPrice: formatAmount(orderDetail.value.unitPrice),
  unit: String(orderDetail.value.orderType || '').startsWith('GROUP_') ? '/?' : '/?',
  unit: String(orderDetail.value.orderType || '').startsWith('GROUP_') ? '/人' : '/团',
  quantity: Number(orderDetail.value.peopleCount || 1),
  total: formatAmount(orderDetail.value.amount),
  familyNo: orderDetail.value.familyNo || '',
  guideName: orderDetail.value.guideName || '???',
  guideName: orderDetail.value.guideName || '未分配',
  guideMobile: orderDetail.value.guideMobile || '',
  guideAvatar: resolveProfileAssetUrl(orderDetail.value.guideAvatar),
  guideRating: Number(orderDetail.value.guideRating || 0)
@@ -114,12 +114,12 @@
const guideStarCount = computed(() => Math.max(0, Math.min(5, Math.round(order.value.guideRating))))
const detailRows = computed(() => [
  { label: '????', value: formatDateTime(orderDetail.value.placedAt) },
  { label: '????', value: formatDateTime(orderDetail.value.acceptedAt) },
  { label: '????', value: `?${formatAmount(orderDetail.value.paymentAmount ?? orderDetail.value.amount)}` },
  { label: '?????', value: orderDetail.value.paymentOrderNo || '-' },
  { label: '??????', value: formatDateTime(orderDetail.value.serviceStartedAt) },
  { label: '??????', value: formatDateTime(orderDetail.value.completedAt) }
  { label: '下单时间', value: formatDateTime(orderDetail.value.placedAt) },
  { label: '接单时间', value: formatDateTime(orderDetail.value.acceptedAt) },
  { label: '支付金额', value: `¥${formatAmount(orderDetail.value.paymentAmount ?? orderDetail.value.amount)}` },
  { label: '支付流水号', value: orderDetail.value.paymentOrderNo || '-' },
  { label: '讲解开始时间', value: formatDateTime(orderDetail.value.serviceStartedAt) },
  { label: '讲解结束时间', value: formatDateTime(orderDetail.value.completedAt) }
])
onLoad((options = {}) => {
@@ -129,19 +129,19 @@
async function loadOrderDetail() {
  if (!orderId.value) {
    uni.showToast({ title: '??????', icon: 'none' })
    uni.showToast({ title: '订单参数缺失', icon: 'none' })
    return
  }
  try {
    orderDetail.value = await getTourOrder(orderId.value)
  } catch (error) {
    uni.showToast({ title: error.message || '??????', icon: 'none' })
    uni.showToast({ title: error.message || '订单加载失败', icon: 'none' })
  }
}
function handleCallGuide() {
  if (!order.value.guideMobile) {
    uni.showToast({ title: '????????', icon: 'none' })
    uni.showToast({ title: '暂无导游联系电话', icon: 'none' })
    return
  }
  uni.makePhoneCall({ phoneNumber: order.value.guideMobile })
@@ -170,10 +170,14 @@
}
function formatServiceTitle(packageName, orderType) {
  if (packageName) return String(packageName).replace(/\s*?\s*/g, '?')
  if (String(orderType || '').startsWith('GROUP_')) return '?????'
  if (String(orderType || '').startsWith('PRIVATE_')) return '?????'
  return '????'
  if (packageName) return String(packageName).replace(/\s*·\s*/g, '·')
  const serviceTitleMap = {
    GROUP_QUICK: '拼团·快讲',
    GROUP_PREMIUM: '拼团·精讲',
    PRIVATE_QUICK: '包团·快讲',
    PRIVATE_PREMIUM: '包团·精讲'
  }
  return serviceTitleMap[orderType] || '讲解服务'
}
</script>
mingdaojingjiang_uniapp/mingdaojingjiang_uniapp/pages/order-pending-review/index.vue
@@ -9,9 +9,9 @@
            <image class="guide-avatar__icon" :src="order.guideAvatar || '/static/ui-icons/user-blue.svg'" mode="aspectFill" />
          </view>
          <view class="guide-main">
            <text class="guide-name">?? ? {{ order.guideName }}</text>
            <text class="guide-name">导游 · {{ order.guideName }}</text>
            <view class="guide-stars">
              <text v-for="item in 5" :key="item" class="guide-star" :class="{ 'guide-star--inactive': item > guideStarCount }">?</text>
              <text v-for="item in 5" :key="item" class="guide-star" :class="{ 'guide-star--inactive': item > guideStarCount }">★</text>
            </view>
          </view>
          <view class="phone-action" @tap="handleCallGuide">
@@ -142,13 +142,13 @@
  id: orderDetail.value.id || orderId.value,
  scenic: orderDetail.value.scenicName || '-',
  service: formatServiceTitle(orderDetail.value.packageName, orderDetail.value.orderType),
  duration: orderDetail.value.durationMinutes ? `${orderDetail.value.durationMinutes}??` : '-',
  duration: orderDetail.value.durationMinutes ? `${orderDetail.value.durationMinutes}分钟` : '-',
  meetingPoint: orderDetail.value.meetingPointName || '-',
  unitPrice: formatAmount(orderDetail.value.unitPrice),
  unit: String(orderDetail.value.orderType || '').startsWith('GROUP_') ? '/?' : '/?',
  unit: String(orderDetail.value.orderType || '').startsWith('GROUP_') ? '/人' : '/团',
  quantity: Number(orderDetail.value.peopleCount || 1),
  total: formatAmount(orderDetail.value.amount),
  guideName: orderDetail.value.guideName || '???',
  guideName: orderDetail.value.guideName || '未分配',
  guideMobile: orderDetail.value.guideMobile || '',
  guideAvatar: resolveProfileAssetUrl(orderDetail.value.guideAvatar),
  guideRating: Number(orderDetail.value.guideRating || 0)
@@ -157,12 +157,12 @@
const guideStarCount = computed(() => Math.max(0, Math.min(5, Math.round(order.value.guideRating))))
const detailRows = computed(() => [
  { label: '????', value: formatDateTime(orderDetail.value.placedAt) },
  { label: '????', value: formatDateTime(orderDetail.value.acceptedAt) },
  { label: '????', value: `?${formatAmount(orderDetail.value.paymentAmount ?? orderDetail.value.amount)}` },
  { label: '?????', value: orderDetail.value.paymentOrderNo || '-' },
  { label: '??????', value: formatDateTime(orderDetail.value.serviceStartedAt) },
  { label: '??????', value: formatDateTime(orderDetail.value.completedAt) }
  { label: '下单时间', value: formatDateTime(orderDetail.value.placedAt) },
  { label: '接单时间', value: formatDateTime(orderDetail.value.acceptedAt) },
  { label: '支付金额', value: `¥${formatAmount(orderDetail.value.paymentAmount ?? orderDetail.value.amount)}` },
  { label: '支付流水号', value: orderDetail.value.paymentOrderNo || '-' },
  { label: '讲解开始时间', value: formatDateTime(orderDetail.value.serviceStartedAt) },
  { label: '讲解结束时间', value: formatDateTime(orderDetail.value.completedAt) }
])
onLoad((options = {}) => {
@@ -172,19 +172,19 @@
async function loadOrderDetail() {
  if (!orderId.value) {
    uni.showToast({ title: '??????', icon: 'none' })
    uni.showToast({ title: '订单参数缺失', icon: 'none' })
    return
  }
  try {
    orderDetail.value = await getTourOrder(orderId.value)
  } catch (error) {
    uni.showToast({ title: error.message || '??????', icon: 'none' })
    uni.showToast({ title: error.message || '订单加载失败', icon: 'none' })
  }
}
function handleCallGuide() {
  if (!order.value.guideMobile) {
    uni.showToast({ title: '????????', icon: 'none' })
    uni.showToast({ title: '暂无导游联系电话', icon: 'none' })
    return
  }
  uni.makePhoneCall({ phoneNumber: order.value.guideMobile })
@@ -211,7 +211,7 @@
async function submitReview() {
  if (!rating.value) {
    uni.showToast({ title: '??????', icon: 'none' })
    uni.showToast({ title: '请先选择评分', icon: 'none' })
    return
  }
  if (!order.value.id || submitting.value || submitSuccess.value) return
@@ -225,13 +225,13 @@
    })
    submitting.value = false
    submitSuccess.value = true
    uni.showToast({ title: '?????', icon: 'success' })
    uni.showToast({ title: '评价成功', icon: 'success' })
    setTimeout(() => {
      uni.redirectTo({ url: `/pages/order-review-detail/index?id=${order.value.id}` })
    }, 700)
  } catch (error) {
    submitting.value = false
    uni.showToast({ title: error.message || '??????', icon: 'none' })
    uni.showToast({ title: error.message || '评价提交失败', icon: 'none' })
  }
}
@@ -245,10 +245,14 @@
}
function formatServiceTitle(packageName, orderType) {
  if (packageName) return String(packageName).replace(/\s*?\s*/g, '?')
  if (String(orderType || '').startsWith('GROUP_')) return '?????'
  if (String(orderType || '').startsWith('PRIVATE_')) return '?????'
  return '????'
  if (packageName) return String(packageName).replace(/\s*·\s*/g, '·')
  const serviceTitleMap = {
    GROUP_QUICK: '拼团·快讲',
    GROUP_PREMIUM: '拼团·精讲',
    PRIVATE_QUICK: '包团·快讲',
    PRIVATE_PREMIUM: '包团·精讲'
  }
  return serviceTitleMap[orderType] || '讲解服务'
}
</script>
mingdaojingjiang_uniapp/mingdaojingjiang_uniapp/pages/order-review-detail/index.vue
@@ -9,9 +9,9 @@
            <image class="guide-avatar__icon" :src="order.guideAvatar || '/static/ui-icons/user-blue.svg'" mode="aspectFill" />
          </view>
          <view class="guide-main">
            <text class="guide-name">?? ? {{ order.guideName }}</text>
            <text class="guide-name">导游 · {{ order.guideName }}</text>
            <view class="guide-stars">
              <text v-for="item in 5" :key="item" class="guide-star" :class="{ 'guide-star--inactive': item > guideStarCount }">?</text>
              <text v-for="item in 5" :key="item" class="guide-star" :class="{ 'guide-star--inactive': item > guideStarCount }">★</text>
            </view>
          </view>
          <view class="phone-action" @tap="handleCallGuide">
@@ -34,7 +34,7 @@
          <view class="price-row">
            <view class="unit-block">
              <text class="unit-price">¥{{ order.unitPrice }}/人</text>
              <text class="unit-price">¥{{ order.unitPrice }}{{ order.unit }}</text>
              <text class="quantity">x{{ order.quantity }}</text>
            </view>
            <text class="total-price">¥{{ order.total }}</text>
@@ -60,16 +60,6 @@
            <text class="review-content__text">{{ review.content }}</text>
          </view>
          <view class="review-images">
            <view
              v-for="(image, index) in review.images"
              :key="image"
              class="review-image"
              @tap="previewImage(index)"
            >
              <image class="review-image__icon" src="/static/image.png" mode="aspectFit" />
            </view>
          </view>
        </view>
      </view>
    </scroll-view>
@@ -95,13 +85,13 @@
  id: orderDetail.value.id || orderId.value,
  scenic: orderDetail.value.scenicName || '-',
  service: formatServiceTitle(orderDetail.value.packageName, orderDetail.value.orderType),
  duration: orderDetail.value.durationMinutes ? `${orderDetail.value.durationMinutes}??` : '-',
  duration: orderDetail.value.durationMinutes ? `${orderDetail.value.durationMinutes}分钟` : '-',
  meetingPoint: orderDetail.value.meetingPointName || '-',
  unitPrice: formatAmount(orderDetail.value.unitPrice),
  unit: String(orderDetail.value.orderType || '').startsWith('GROUP_') ? '/?' : '/?',
  unit: String(orderDetail.value.orderType || '').startsWith('GROUP_') ? '/人' : '/团',
  quantity: Number(orderDetail.value.peopleCount || 1),
  total: formatAmount(orderDetail.value.amount),
  guideName: orderDetail.value.guideName || reviewDetail.value.guideName || '???',
  guideName: orderDetail.value.guideName || reviewDetail.value.guideName || '未分配',
  guideMobile: orderDetail.value.guideMobile || reviewDetail.value.guideMobile || '',
  guideAvatar: resolveProfileAssetUrl(orderDetail.value.guideAvatar),
  guideRating: Number(orderDetail.value.guideRating || 0)
@@ -111,8 +101,7 @@
const review = computed(() => ({
  rating: Number(reviewDetail.value.score || 0),
  content: reviewDetail.value.content || '??????',
  images: []
  content: reviewDetail.value.content || '暂无评价内容'
}))
onLoad((options = {}) => {
@@ -122,7 +111,7 @@
async function loadPageData() {
  if (!orderId.value) {
    uni.showToast({ title: '??????', icon: 'none' })
    uni.showToast({ title: '订单参数缺失', icon: 'none' })
    return
  }
  try {
@@ -133,23 +122,16 @@
    orderDetail.value = orderResult || {}
    reviewDetail.value = reviewResult || {}
  } catch (error) {
    uni.showToast({ title: error.message || '??????', icon: 'none' })
    uni.showToast({ title: error.message || '评价加载失败', icon: 'none' })
  }
}
function handleCallGuide() {
  if (!order.value.guideMobile) {
    uni.showToast({ title: '????????', icon: 'none' })
    uni.showToast({ title: '暂无导游联系电话', icon: 'none' })
    return
  }
  uni.makePhoneCall({ phoneNumber: order.value.guideMobile })
}
function previewImage(index) {
  uni.previewImage({
    current: review.value.images[index],
    urls: review.value.images
  })
}
function formatAmount(value) {
@@ -158,10 +140,14 @@
}
function formatServiceTitle(packageName, orderType) {
  if (packageName) return String(packageName).replace(/\s*?\s*/g, '?')
  if (String(orderType || '').startsWith('GROUP_')) return '?????'
  if (String(orderType || '').startsWith('PRIVATE_')) return '?????'
  return '????'
  if (packageName) return String(packageName).replace(/\s*·\s*/g, '·')
  const serviceTitleMap = {
    GROUP_QUICK: '拼团·快讲',
    GROUP_PREMIUM: '拼团·精讲',
    PRIVATE_QUICK: '包团·快讲',
    PRIVATE_PREMIUM: '包团·精讲'
  }
  return serviceTitleMap[orderType] || '讲解服务'
}
</script>
@@ -406,26 +392,4 @@
  line-height: 1.45;
}
.review-images {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18rpx;
  margin-top: 30rpx;
}
.review-image {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  border-radius: 4rpx;
  background: #e5e7eb;
}
.review-image__icon {
  width: 34rpx;
  height: 34rpx;
  opacity: 0.56;
}
</style>