329 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Vue
		
	
	
	
		
		
			
		
	
	
			329 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Vue
		
	
	
	
|  | <!-- | |||
|  |  * @Descripttion: 门票详情页面 | |||
|  |  * @version: 1.0.0 | |||
|  |  * @Author: Assistant | |||
|  |  * @Date: 2025-01-22 | |||
|  | --> | |||
|  | <template> | |||
|  |   <view class="ticket-detail-container"> | |||
|  |     <!-- 内容区域 --> | |||
|  |     <view class="content-area"> | |||
|  |       <view v-if="ticketDetail" class="ticket-detail-card"> | |||
|  |         <!-- 订单编号 --> | |||
|  |         <view class="order-section"> | |||
|  |           <text class="order-label">订单编号:</text> | |||
|  |           <text class="order-code">{{ ticketDetail.orderCode }}</text> | |||
|  |         </view> | |||
|  | 
 | |||
|  |         <!-- 活动信息 --> | |||
|  |         <view class="activity-section"> | |||
|  |           <view class="activity-title">{{ ticketDetail.actName }}</view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">门票价格:</text> | |||
|  |             <text class="detail-value price">¥{{ ticketDetail.price }}</text> | |||
|  |           </view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">支付时间:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.creationTime }}</text> | |||
|  |           </view> | |||
|  |         </view> | |||
|  | 
 | |||
|  |         <!-- 支付信息 --> | |||
|  |         <view class="pay-section"> | |||
|  |           <view class="section-title">支付信息</view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">支付编号:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.memberCode }}</text> | |||
|  |           </view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">支付昵称:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.memberName }}</text> | |||
|  |           </view> | |||
|  |         </view> | |||
|  | 
 | |||
|  |         <!-- 购票人信息 --> | |||
|  |         <view class="buyer-section"> | |||
|  |           <view class="section-title">购票人信息</view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">姓名:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.buyName }}</text> | |||
|  |           </view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">联系方式:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.phone }}</text> | |||
|  |           </view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">证件证号:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.idCard }}</text> | |||
|  |           </view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">性别:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.sexVal }}</text> | |||
|  |           </view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">服装尺寸:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.clothSize }}</text> | |||
|  |           </view> | |||
|  | 
 | |||
|  |           <view class="detail-item" v-if="ticketDetail.cohabitant"> | |||
|  |             <text class="detail-label">同住人:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.cohabitant }}</text> | |||
|  |           </view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">紧急联系方式:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.emergencyPhone }}</text> | |||
|  |           </view> | |||
|  |         </view> | |||
|  | 
 | |||
|  |         <!-- 展开更多信息 --> | |||
|  |         <view class="expand-section" @click="toggleExpand"> | |||
|  |           <text class="expand-text">{{ expanded ? '收起' : '查看更多' }}</text> | |||
|  |           <u-icon | |||
|  |             :name="expanded ? 'arrow-up' : 'arrow-down'" | |||
|  |             size="12" | |||
|  |             color="#999" | |||
|  |           ></u-icon> | |||
|  |         </view> | |||
|  | 
 | |||
|  |         <!-- 更多信息(展开时显示) --> | |||
|  |         <view v-if="expanded" class="more-info"> | |||
|  |           <view class="section-title">其他信息</view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">订单金额:</text> | |||
|  |             <text class="detail-value price" | |||
|  |               >¥{{ ticketDetail.orderAmount }}</text | |||
|  |             > | |||
|  |           </view> | |||
|  | 
 | |||
|  |           <view class="detail-item"> | |||
|  |             <text class="detail-label">购买数量:</text> | |||
|  |             <text class="detail-value">{{ ticketDetail.quantity }}</text> | |||
|  |           </view> | |||
|  |         </view> | |||
|  |       </view> | |||
|  | 
 | |||
|  |       <!-- 加载状态 --> | |||
|  |       <view v-if="loading" class="loading-state"> | |||
|  |         <u-loading-icon mode="spinner"></u-loading-icon> | |||
|  |         <text class="loading-text">加载中...</text> | |||
|  |       </view> | |||
|  | 
 | |||
|  |       <!-- 错误状态 --> | |||
|  |       <view v-if="error && !loading" class="error-state"> | |||
|  |         <text class="error-text">{{ error }}</text> | |||
|  |         <button class="retry-btn" @click="loadTicketDetail">重试</button> | |||
|  |       </view> | |||
|  | 
 | |||
|  |       <!-- 空状态 --> | |||
|  |       <view v-if="!ticketDetail && !loading && !error" class="empty-state"> | |||
|  |         <text class="empty-text">暂无数据</text> | |||
|  |       </view> | |||
|  |     </view> | |||
|  |   </view> | |||
|  | </template> | |||
|  | 
 | |||
|  | <script> | |||
|  | import { getTicketDetail } from '@/config/ticket.js' | |||
|  | 
 | |||
|  | export default { | |||
|  |   data() { | |||
|  |     return { | |||
|  |       ticketId: '', | |||
|  |       ticketDetail: null, | |||
|  |       loading: false, | |||
|  |       error: '', | |||
|  |       expanded: false, | |||
|  |     } | |||
|  |   }, | |||
|  |   onLoad(options) { | |||
|  |     if (options.ticketId) { | |||
|  |       this.ticketId = options.ticketId | |||
|  |       this.loadTicketDetail() | |||
|  |     } | |||
|  |   }, | |||
|  |   methods: { | |||
|  |     // 返回上一页
 | |||
|  |     goBack() { | |||
|  |       uni.navigateBack() | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 切换展开状态
 | |||
|  |     toggleExpand() { | |||
|  |       this.expanded = !this.expanded | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 加载门票详情
 | |||
|  |     async loadTicketDetail() { | |||
|  |       if (!this.ticketId) { | |||
|  |         this.error = '缺少门票ID' | |||
|  |         return | |||
|  |       } | |||
|  | 
 | |||
|  |       this.loading = true | |||
|  |       this.error = '' | |||
|  | 
 | |||
|  |       try { | |||
|  |         const res = await getTicketDetail({ ticketId: this.ticketId }) | |||
|  | 
 | |||
|  |         if (res.code === 200) { | |||
|  |           this.ticketDetail = res.data || res.rows?.[0] | |||
|  |         } else { | |||
|  |           this.error = res.msg || '加载失败' | |||
|  |         } | |||
|  |       } catch (error) { | |||
|  |         console.error('加载门票详情失败:', error) | |||
|  |         this.error = '网络错误,请重试' | |||
|  |       } finally { | |||
|  |         this.loading = false | |||
|  |       } | |||
|  |     }, | |||
|  |   }, | |||
|  | } | |||
|  | </script> | |||
|  | 
 | |||
|  | <style lang="scss" scoped> | |||
|  | .ticket-detail-container { | |||
|  |   min-height: 100vh; | |||
|  |   background: #f8f8f8; | |||
|  | } | |||
|  | 
 | |||
|  | .content-area { | |||
|  |   padding: 16px; | |||
|  | } | |||
|  | 
 | |||
|  | .ticket-detail-card { | |||
|  |   background: #fff; | |||
|  |   border-radius: 12px; | |||
|  |   overflow: hidden; | |||
|  |   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); | |||
|  | 
 | |||
|  |   .order-section { | |||
|  |     padding: 16px; | |||
|  |     border-bottom: 1px solid #f5f5f5; | |||
|  | 
 | |||
|  |     .order-label { | |||
|  |       font-size: 14px; | |||
|  |       color: #999; | |||
|  |     } | |||
|  | 
 | |||
|  |     .order-code { | |||
|  |       font-size: 14px; | |||
|  |       color: #666; | |||
|  |       margin-left: 4px; | |||
|  |     } | |||
|  |   } | |||
|  | 
 | |||
|  |   .activity-section { | |||
|  |     padding: 16px; | |||
|  |     border-bottom: 1px solid #f5f5f5; | |||
|  | 
 | |||
|  |     .activity-title { | |||
|  |       font-size: 18px; | |||
|  |       font-weight: 600; | |||
|  |       color: #333; | |||
|  |       margin-bottom: 16px; | |||
|  |       line-height: 1.4; | |||
|  |     } | |||
|  |   } | |||
|  | 
 | |||
|  |   .pay-section, | |||
|  |   .buyer-section, | |||
|  |   .more-info { | |||
|  |     padding: 16px; | |||
|  |     border-bottom: 1px solid #f5f5f5; | |||
|  | 
 | |||
|  |     .section-title { | |||
|  |       font-size: 16px; | |||
|  |       font-weight: 600; | |||
|  |       color: #333; | |||
|  |       margin-bottom: 12px; | |||
|  |     } | |||
|  |   } | |||
|  | 
 | |||
|  |   .detail-item { | |||
|  |     display: flex; | |||
|  |     margin-bottom: 12px; | |||
|  | 
 | |||
|  |     &:last-child { | |||
|  |       margin-bottom: 0; | |||
|  |     } | |||
|  | 
 | |||
|  |     .detail-label { | |||
|  |       font-size: 14px; | |||
|  |       color: #999; | |||
|  |       min-width: 100px; | |||
|  |       flex-shrink: 0; | |||
|  |     } | |||
|  | 
 | |||
|  |     .detail-value { | |||
|  |       font-size: 14px; | |||
|  |       color: #666; | |||
|  |       flex: 1; | |||
|  | 
 | |||
|  |       &.price { | |||
|  |         color: #005bac; | |||
|  |         font-weight: 600; | |||
|  |       } | |||
|  |     } | |||
|  |   } | |||
|  | 
 | |||
|  |   .expand-section { | |||
|  |     display: flex; | |||
|  |     align-items: center; | |||
|  |     justify-content: center; | |||
|  |     padding: 16px; | |||
|  |     border-bottom: 1px solid #f5f5f5; | |||
|  |     cursor: pointer; | |||
|  | 
 | |||
|  |     .expand-text { | |||
|  |       font-size: 14px; | |||
|  |       color: #999; | |||
|  |       margin-right: 4px; | |||
|  |     } | |||
|  |   } | |||
|  | 
 | |||
|  |   .more-info { | |||
|  |     border-bottom: none; | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | .loading-state, | |||
|  | .error-state, | |||
|  | .empty-state { | |||
|  |   display: flex; | |||
|  |   flex-direction: column; | |||
|  |   align-items: center; | |||
|  |   justify-content: center; | |||
|  |   padding: 60px 0; | |||
|  | 
 | |||
|  |   .loading-text, | |||
|  |   .error-text, | |||
|  |   .empty-text { | |||
|  |     font-size: 14px; | |||
|  |     color: #999; | |||
|  |     margin-top: 8px; | |||
|  |   } | |||
|  | 
 | |||
|  |   .retry-btn { | |||
|  |     margin-top: 16px; | |||
|  |     background: #005bac; | |||
|  |     color: #fff; | |||
|  |     border: none; | |||
|  |     border-radius: 20px; | |||
|  |     padding: 8px 24px; | |||
|  |     font-size: 14px; | |||
|  |   } | |||
|  | } | |||
|  | </style> |