Files
lilishop-uniapp/pages/order/cardKey/cardKeyDetail.vue
田香琪 370c63afcd feat: 更新电子卡券卡密详情页及相关逻辑
- 修改卡密详情页以支持多种卡密展示,优化卡密信息的结构和样式
- 增加卡密履约状态管理,支持卡密发放状态的显示
- 更新 utils/goodsType.js,增加卡密履约状态的处理逻辑
- 优化数据加载逻辑,确保卡密信息的准确性和完整性
2026-08-03 16:14:05 +08:00

252 lines
6.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
@Author Mike
@Date 2026-08-03
-->
<template>
<view class="card-key-page">
<view v-if="loading" class="card-key-page__loading">加载中...</view>
<view v-else-if="errorMessage" class="card-key-page__empty">{{ errorMessage }}</view>
<view v-else-if="!cardKeyRows.length" class="card-key-page__empty">
{{ emptyMessage }}
</view>
<view v-else>
<view
v-for="(line, lineIndex) in cardKeyFulfillLines"
:key="line.key || lineIndex"
class="card-key-fulfill-block"
>
<view v-if="cardKeyFulfillLines.length > 1" class="card-key-fulfill-title">
{{ line.goodsName || (line.isGift ? '满赠电子卡券' : '电子卡券') }}
</view>
<view
class="card-key-item"
v-for="(row, index) in line.cardKeys"
:key="`${line.key}-${row.cardNo || index}-${index}`"
>
<view class="card-key-item__title">卡密 {{ index + 1 }}</view>
<view class="card-key-item__row">
<text class="card-key-item__label">卡号</text>
<text class="card-key-item__value card-key-item__value--plain" selectable>{{
row.cardNo || '-'
}}</text>
</view>
<view class="card-key-item__row">
<text class="card-key-item__label">卡密</text>
<text class="card-key-item__value card-key-item__value--plain" selectable>{{
row.cardSecret || '-'
}}</text>
</view>
<view class="card-key-item__actions">
<view class="card-key-item__copy" @click="copyCardKey(row)">复制</view>
</view>
</view>
</view>
<view class="card-key-page__footer">
<view class="card-key-page__copy-all" @click="copyAllCardKeys">复制全部</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
/**
* 电子卡券卡密二级页(原型 P-09
* 数据来源GET /buyer/order/order/{orderSn} → orderItems[].cardKeys明文 cardSecret
*/
import { ref, computed } from 'vue'
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
import { getOrderDetail } from '@/api/order.js'
import { setClipboard } from '@/utils/filters.js'
import {
isECouponOrder,
collectCardKeyFulfillLines,
flattenOrderCardKeys,
resolveCardKeyFulfillMessage,
CARD_KEY_FULFILL_STATUS,
} from '@/utils/goodsType.js'
const orderSn = ref('')
const loading = ref(true)
const errorMessage = ref('')
const orderItems = ref<any[]>([])
const giftECouponOrders = ref<any[]>([])
const orderStatus = ref('')
const cardKeyFulfillLines = computed(() =>
collectCardKeyFulfillLines(orderItems.value, giftECouponOrders.value).filter(
(line) => line.status === CARD_KEY_FULFILL_STATUS.DELIVERED && line.cardKeys.length
)
)
const cardKeyRows = computed(() =>
flattenOrderCardKeys(orderItems.value, false, giftECouponOrders.value)
)
const emptyMessage = computed(() => {
if (orderStatus.value === 'CANCELLED') {
return '订单已关闭,暂无卡密信息'
}
const pending = collectCardKeyFulfillLines(
orderItems.value,
giftECouponOrders.value
).find((line) => line.status !== CARD_KEY_FULFILL_STATUS.DELIVERED)
if (pending) {
return resolveCardKeyFulfillMessage(pending)
}
if (orderStatus.value === 'COMPLETED') {
return '卡密尚未发放,请稍后刷新'
}
return '暂无卡密信息'
})
onLoad((options) => {
orderSn.value = options?.sn || ''
loadData()
})
onPullDownRefresh(() => {
loadData(true)
})
function loadData(fromPullDown = false) {
if (!orderSn.value) {
loading.value = false
errorMessage.value = '订单编号无效'
if (fromPullDown) uni.stopPullDownRefresh()
return
}
if (!fromPullDown) {
loading.value = true
errorMessage.value = ''
}
getOrderDetail(orderSn.value)
.then((res) => {
if (!res.data.success) {
errorMessage.value = res.data.message || '加载失败'
return
}
const result = res.data.result
const isEcoupon = isECouponOrder(result?.order?.orderType)
const hasGiftEcoupon =
Array.isArray(result?.giftECouponOrders) && result.giftECouponOrders.length > 0
if (!isEcoupon && !hasGiftEcoupon) {
errorMessage.value = '该订单没有电子卡券卡密'
return
}
orderItems.value = result.orderItems || []
giftECouponOrders.value = result.giftECouponOrders || []
orderStatus.value = result.order?.orderStatus || ''
})
.catch(() => {
errorMessage.value = '加载失败,请稍后重试'
})
.finally(() => {
loading.value = false
if (fromPullDown) uni.stopPullDownRefresh()
})
}
function copyCardKey(row: any) {
const text = `卡号:${row.cardNo || ''}\n卡密${row.cardSecret || ''}`
setClipboard(text)
}
function copyAllCardKeys() {
const text = cardKeyRows.value
.map(
(row, index) =>
`${index + 1}. 卡号:${row.cardNo || ''} 卡密:${row.cardSecret || ''}`
)
.join('\n')
if (!text) {
uni.showToast({ title: '暂无可复制卡密', icon: 'none' })
return
}
setClipboard(text)
}
</script>
<style lang="scss" scoped>
.card-key-page {
min-height: 100vh;
padding: 24rpx;
background: #f7f7f7;
}
.card-key-page__loading,
.card-key-page__empty {
padding: 120rpx 40rpx;
text-align: center;
color: #999;
font-size: 28rpx;
}
.card-key-fulfill-title {
font-size: 26rpx;
color: #666;
margin-bottom: 12rpx;
}
.card-key-item {
background: #fff;
border-radius: 20rpx;
padding: 28rpx;
margin-bottom: 24rpx;
}
.card-key-item__title {
font-size: 28rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
}
.card-key-item__row {
display: flex;
align-items: flex-start;
margin-bottom: 16rpx;
font-size: 26rpx;
line-height: 1.6;
}
.card-key-item__label {
color: #666;
flex-shrink: 0;
}
.card-key-item__value {
color: #333;
word-break: break-all;
}
.card-key-item__value--plain {
font-family: monospace;
flex: 1;
}
.card-key-item__actions {
display: flex;
justify-content: flex-end;
margin-top: 8rpx;
}
.card-key-item__copy {
color: $main-color;
font-size: 26rpx;
}
.card-key-page__footer {
padding: 20rpx 0 40rpx;
}
.card-key-page__copy-all {
height: 88rpx;
line-height: 88rpx;
text-align: center;
background: $main-color;
color: #fff;
border-radius: 44rpx;
font-size: 28rpx;
}
</style>