1026 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Vue
		
	
	
	
			
		
		
	
	
			1026 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Vue
		
	
	
	
<!--
 | 
						||
 * @Descripttion: 门票活动页面
 | 
						||
 * @version: 1.0.0
 | 
						||
 * @Author: Assistant
 | 
						||
 * @Date: 2025-01-22
 | 
						||
-->
 | 
						||
<template>
 | 
						||
  <view class="ticket-container">
 | 
						||
    <!-- Tab切换 -->
 | 
						||
    <view class="tab-container">
 | 
						||
      <view class="tab-wrapper">
 | 
						||
        <view
 | 
						||
          class="tab-item"
 | 
						||
          :class="{ active: currentTab === 0 }"
 | 
						||
          @click="switchTab(0)"
 | 
						||
        >
 | 
						||
          <text class="tab-text">门票活动</text>
 | 
						||
          <view class="tab-line" v-if="currentTab === 0"></view>
 | 
						||
        </view>
 | 
						||
        <view
 | 
						||
          class="tab-item"
 | 
						||
          :class="{ active: currentTab === 1 }"
 | 
						||
          @click="switchTab(1)"
 | 
						||
        >
 | 
						||
          <text class="tab-text">我的门票</text>
 | 
						||
          <view class="tab-line" v-if="currentTab === 1"></view>
 | 
						||
        </view>
 | 
						||
      </view>
 | 
						||
    </view>
 | 
						||
 | 
						||
    <!-- 内容区域 -->
 | 
						||
    <view class="content-area">
 | 
						||
      <!-- 门票活动列表 -->
 | 
						||
      <view v-if="currentTab === 0" class="activity-list">
 | 
						||
        <view
 | 
						||
          class="activity-card"
 | 
						||
          v-for="item in activityList"
 | 
						||
          :key="item.pkId"
 | 
						||
        >
 | 
						||
          <view class="card-content">
 | 
						||
            <view class="activity-image">
 | 
						||
              <image :src="item.actCover" mode="aspectFill"></image>
 | 
						||
            </view>
 | 
						||
            <view class="activity-info">
 | 
						||
              <view class="activity-title">{{ item.actName }}</view>
 | 
						||
              <view class="activity-detail">
 | 
						||
                <text class="detail-label">活动日期:</text>
 | 
						||
                <text class="detail-value"
 | 
						||
                  >{{ item.actStartDate }}~{{ item.actEndDate }}</text
 | 
						||
                >
 | 
						||
              </view>
 | 
						||
              <view class="activity-detail">
 | 
						||
                <text class="detail-label">购买日期:</text>
 | 
						||
                <text class="detail-value"
 | 
						||
                  >{{ item.disStartDate }}~{{ item.disEndDate }}</text
 | 
						||
                >
 | 
						||
              </view>
 | 
						||
              <view class="activity-detail">
 | 
						||
                <text class="detail-label">总票数:</text>
 | 
						||
                <text class="detail-value">{{ item.quantity }}</text>
 | 
						||
              </view>
 | 
						||
              <view class="bottom-section">
 | 
						||
                <view class="price-info">
 | 
						||
                  <text class="price-symbol">¥</text>
 | 
						||
                  <text class="price-value">{{ item.payMoney }}</text>
 | 
						||
                </view>
 | 
						||
                <button class="buy-btn" @click="goBuyTicket(item)">购买</button>
 | 
						||
              </view>
 | 
						||
            </view>
 | 
						||
          </view>
 | 
						||
        </view>
 | 
						||
 | 
						||
        <!-- 空状态 -->
 | 
						||
        <view v-if="!activityList.length && !loading" class="empty-state">
 | 
						||
          <text class="empty-text">没有更多数据了</text>
 | 
						||
        </view>
 | 
						||
 | 
						||
        <!-- 加载状态 -->
 | 
						||
        <view v-if="loading" class="loading-state">
 | 
						||
          <u-loading-icon mode="spinner"></u-loading-icon>
 | 
						||
          <text class="loading-text">加载中...</text>
 | 
						||
        </view>
 | 
						||
      </view>
 | 
						||
 | 
						||
      <!-- 我的门票列表 -->
 | 
						||
      <view v-if="currentTab === 1" class="ticket-list">
 | 
						||
        <view class="ticket-card" v-for="item in ticketList" :key="item.pkId">
 | 
						||
          <view class="ticket-header">
 | 
						||
            <text class="order-code">订单编号:{{ item.orderCode }}</text>
 | 
						||
          </view>
 | 
						||
          <view class="ticket-content">
 | 
						||
            <view class="ticket-info">
 | 
						||
              <view class="ticket-title">{{ item.actName }}</view>
 | 
						||
              <!-- 基础信息:始终显示 -->
 | 
						||
              <view class="ticket-detail">
 | 
						||
                <text class="detail-label">门票价格:</text>
 | 
						||
                <text class="detail-value price">¥{{ item.price }}</text>
 | 
						||
              </view>
 | 
						||
              <view class="ticket-detail">
 | 
						||
                <text class="detail-label">支付时间:</text>
 | 
						||
                <text class="detail-value">{{ item.creationTime }}</text>
 | 
						||
              </view>
 | 
						||
              <view class="ticket-detail">
 | 
						||
                <text class="detail-label">支付编号:</text>
 | 
						||
                <text class="detail-value">{{ item.memberCode }}</text>
 | 
						||
              </view>
 | 
						||
              <view class="ticket-detail">
 | 
						||
                <text class="detail-label">支付昵称:</text>
 | 
						||
                <text class="detail-value">{{ item.memberName }}</text>
 | 
						||
              </view>
 | 
						||
              <view class="ticket-detail">
 | 
						||
                <text class="detail-label">姓名:</text>
 | 
						||
                <text class="detail-value">{{ item.buyName }}</text>
 | 
						||
              </view>
 | 
						||
              <view class="ticket-detail">
 | 
						||
                <text class="detail-label">联系方式:</text>
 | 
						||
                <text class="detail-value">{{ item.phone }}</text>
 | 
						||
              </view>
 | 
						||
 | 
						||
              <!-- 展开显示的更多信息 -->
 | 
						||
              <view v-if="item.expanded" class="expanded-details">
 | 
						||
                <view class="ticket-detail" v-if="item.idCard">
 | 
						||
                  <text class="detail-label">证件证号:</text>
 | 
						||
                  <text class="detail-value">{{ item.idCard }}</text>
 | 
						||
                </view>
 | 
						||
                <view class="ticket-detail" v-if="item.sexVal">
 | 
						||
                  <text class="detail-label">性别:</text>
 | 
						||
                  <text class="detail-value">{{ item.sexVal }}</text>
 | 
						||
                </view>
 | 
						||
                <view class="ticket-detail" v-if="item.clothSize">
 | 
						||
                  <text class="detail-label">服装尺寸:</text>
 | 
						||
                  <text class="detail-value">{{ item.clothSize }}</text>
 | 
						||
                </view>
 | 
						||
                <view class="ticket-detail" v-if="item.cohabitant">
 | 
						||
                  <text class="detail-label">同住人:</text>
 | 
						||
                  <text class="detail-value">{{ item.cohabitant }}</text>
 | 
						||
                </view>
 | 
						||
                <view class="ticket-detail" v-if="item.emergencyPhone">
 | 
						||
                  <text class="detail-label">紧急联系方式:</text>
 | 
						||
                  <text class="detail-value">{{ item.emergencyPhone }}</text>
 | 
						||
                </view>
 | 
						||
              </view>
 | 
						||
 | 
						||
              <!-- 操作按钮:仅在24小时内显示 -->
 | 
						||
              <view
 | 
						||
                v-if="isWithin24Hours(item.creationTime)"
 | 
						||
                class="action-buttons"
 | 
						||
              >
 | 
						||
                <button class="cancel-btn" @click="showCancelConfirm(item)">
 | 
						||
                  撤销门票
 | 
						||
                </button>
 | 
						||
                <button class="edit-btn" @click="showEditModal(item)">
 | 
						||
                  修改信息
 | 
						||
                </button>
 | 
						||
              </view>
 | 
						||
 | 
						||
              <view class="expand-action" @click="toggleExpand(item)">
 | 
						||
                <text class="expand-text">{{
 | 
						||
                  item.expanded ? '收起' : '查看更多'
 | 
						||
                }}</text>
 | 
						||
                <u-icon
 | 
						||
                  :name="item.expanded ? 'arrow-up' : 'arrow-down'"
 | 
						||
                  size="12"
 | 
						||
                  color="#999"
 | 
						||
                ></u-icon>
 | 
						||
              </view>
 | 
						||
            </view>
 | 
						||
          </view>
 | 
						||
        </view>
 | 
						||
 | 
						||
        <!-- 空状态 -->
 | 
						||
        <view v-if="!ticketList.length && !ticketLoading" class="empty-state">
 | 
						||
          <text class="empty-text">没有更多数据了</text>
 | 
						||
        </view>
 | 
						||
 | 
						||
        <!-- 加载状态 -->
 | 
						||
        <view v-if="ticketLoading" class="loading-state">
 | 
						||
          <u-loading-icon mode="spinner"></u-loading-icon>
 | 
						||
          <text class="loading-text">加载中...</text>
 | 
						||
        </view>
 | 
						||
      </view>
 | 
						||
    </view>
 | 
						||
 | 
						||
    <!-- 撤销确认弹窗 -->
 | 
						||
    <u-modal
 | 
						||
      :show="showCancelModal"
 | 
						||
      title="确认撤销"
 | 
						||
      :content="cancelModalContent"
 | 
						||
      :show-cancel-button="true"
 | 
						||
      confirm-text="确认撤销"
 | 
						||
      cancel-text="取消"
 | 
						||
      @confirm="confirmCancel"
 | 
						||
      @cancel="showCancelModal = false"
 | 
						||
    ></u-modal>
 | 
						||
 | 
						||
    <!-- 修改信息弹窗 -->
 | 
						||
    <u-popup :show="editModalVisible" mode="center" border-radius="12">
 | 
						||
      <view class="edit-modal">
 | 
						||
        <view class="modal-header">
 | 
						||
          <text class="modal-title">修改门票信息</text>
 | 
						||
          <u-icon name="close" size="20" @click="closeEditModal"></u-icon>
 | 
						||
        </view>
 | 
						||
        <scroll-view scroll-y class="modal-content">
 | 
						||
          <view class="form-item">
 | 
						||
            <text class="form-label optional">活动名称</text>
 | 
						||
            <input
 | 
						||
              class="form-input disabled"
 | 
						||
              :value="editForm.actName"
 | 
						||
              disabled
 | 
						||
            />
 | 
						||
          </view>
 | 
						||
          <view class="form-item">
 | 
						||
            <text class="form-label optional">订单编号</text>
 | 
						||
            <input
 | 
						||
              class="form-input disabled"
 | 
						||
              :value="editForm.orderCode"
 | 
						||
              disabled
 | 
						||
            />
 | 
						||
          </view>
 | 
						||
          <view class="form-item">
 | 
						||
            <text class="form-label">姓名</text>
 | 
						||
            <input
 | 
						||
              class="form-input"
 | 
						||
              v-model="editForm.buyName"
 | 
						||
              placeholder="请输入姓名"
 | 
						||
            />
 | 
						||
          </view>
 | 
						||
          <view class="form-item">
 | 
						||
            <text class="form-label">手机号</text>
 | 
						||
            <input
 | 
						||
              class="form-input"
 | 
						||
              v-model="editForm.phone"
 | 
						||
              placeholder="请输入手机号"
 | 
						||
            />
 | 
						||
          </view>
 | 
						||
          <view class="form-item">
 | 
						||
            <text class="form-label">身份证号</text>
 | 
						||
            <input
 | 
						||
              class="form-input"
 | 
						||
              v-model="editForm.idCard"
 | 
						||
              placeholder="请输入身份证号"
 | 
						||
            />
 | 
						||
          </view>
 | 
						||
          <view class="form-item">
 | 
						||
            <text class="form-label">性别</text>
 | 
						||
            <u-radio-group v-model="editForm.sex" direction="row">
 | 
						||
              <u-radio :name="1" label="男"></u-radio>
 | 
						||
              <u-radio :name="2" label="女"></u-radio>
 | 
						||
            </u-radio-group>
 | 
						||
          </view>
 | 
						||
          <view class="form-item">
 | 
						||
            <text class="form-label">尺码</text>
 | 
						||
            <input
 | 
						||
              class="form-input"
 | 
						||
              v-model="editForm.clothSize"
 | 
						||
              placeholder="请输入尺码"
 | 
						||
            />
 | 
						||
          </view>
 | 
						||
          <view class="form-item">
 | 
						||
            <text class="form-label optional">同住人</text>
 | 
						||
            <input
 | 
						||
              class="form-input"
 | 
						||
              v-model="editForm.cohabitant"
 | 
						||
              placeholder="请输入同住人"
 | 
						||
            />
 | 
						||
          </view>
 | 
						||
          <view class="form-item">
 | 
						||
            <text class="form-label optional">紧急联系人</text>
 | 
						||
            <input
 | 
						||
              class="form-input"
 | 
						||
              v-model="editForm.emergencyPhone"
 | 
						||
              placeholder="请输入紧急联系人电话"
 | 
						||
            />
 | 
						||
          </view>
 | 
						||
        </scroll-view>
 | 
						||
        <view class="modal-footer">
 | 
						||
          <button class="confirm-btn" @click="updateTicketInfo">确定</button>
 | 
						||
        </view>
 | 
						||
      </view>
 | 
						||
    </u-popup>
 | 
						||
  </view>
 | 
						||
</template>
 | 
						||
 | 
						||
<script>
 | 
						||
import {
 | 
						||
  getTicketActivityList,
 | 
						||
  getMyTicketList,
 | 
						||
  cancelTicket,
 | 
						||
  updateTicket,
 | 
						||
} from '@/config/ticket.js'
 | 
						||
 | 
						||
export default {
 | 
						||
  data() {
 | 
						||
    return {
 | 
						||
      currentTab: 0,
 | 
						||
      activityList: [],
 | 
						||
      ticketList: [],
 | 
						||
      loading: false,
 | 
						||
      ticketLoading: false,
 | 
						||
      activityPage: {
 | 
						||
        pageNum: 1,
 | 
						||
        pageSize: 10,
 | 
						||
      },
 | 
						||
      ticketPage: {
 | 
						||
        pageNum: 1,
 | 
						||
        pageSize: 10,
 | 
						||
      },
 | 
						||
      // 弹窗相关
 | 
						||
      showCancelModal: false,
 | 
						||
      editModalVisible: false,
 | 
						||
      selectedTicket: null,
 | 
						||
      editForm: {
 | 
						||
        pkId: '',
 | 
						||
        actName: '',
 | 
						||
        memberCode: '',
 | 
						||
        memberName: '',
 | 
						||
        orderCode: '',
 | 
						||
        orderAmount: '',
 | 
						||
        price: '',
 | 
						||
        quantity: '',
 | 
						||
        buyName: '',
 | 
						||
        phone: '',
 | 
						||
        idCard: '',
 | 
						||
        sex: '',
 | 
						||
        sexVal: '',
 | 
						||
        clothSize: '',
 | 
						||
        cohabitant: '',
 | 
						||
        emergencyPhone: '',
 | 
						||
        creationTime: '',
 | 
						||
      },
 | 
						||
    }
 | 
						||
  },
 | 
						||
  computed: {
 | 
						||
    // 撤销弹窗内容
 | 
						||
    cancelModalContent() {
 | 
						||
      return this.selectedTicket
 | 
						||
        ? `确定要撤销订单 ${this.selectedTicket.orderCode} 吗?撤销后不可恢复。`
 | 
						||
        : '确定要撤销此订单吗?撤销后不可恢复。'
 | 
						||
    },
 | 
						||
  },
 | 
						||
  onLoad() {
 | 
						||
    this.loadActivityList()
 | 
						||
  },
 | 
						||
  onPullDownRefresh() {
 | 
						||
    this.refreshCurrentTab()
 | 
						||
  },
 | 
						||
  // onReachBottom() {
 | 
						||
  //   this.loadMoreData()
 | 
						||
  // },
 | 
						||
  methods: {
 | 
						||
    // 返回上一页
 | 
						||
    goBack() {
 | 
						||
      uni.navigateBack()
 | 
						||
    },
 | 
						||
 | 
						||
    // 切换Tab
 | 
						||
    switchTab(index) {
 | 
						||
      this.currentTab = index
 | 
						||
      if (index === 0) {
 | 
						||
        this.loadActivityList()
 | 
						||
      } else {
 | 
						||
        this.loadTicketList()
 | 
						||
      }
 | 
						||
    },
 | 
						||
 | 
						||
    // 刷新当前Tab数据
 | 
						||
    refreshCurrentTab() {
 | 
						||
      if (this.currentTab === 0) {
 | 
						||
        this.activityPage.pageNum = 1
 | 
						||
        this.activityList = []
 | 
						||
        this.loadActivityList()
 | 
						||
      } else {
 | 
						||
        this.ticketPage.pageNum = 1
 | 
						||
        this.ticketList = []
 | 
						||
        this.loadTicketList()
 | 
						||
      }
 | 
						||
    },
 | 
						||
 | 
						||
    // 加载更多数据
 | 
						||
    loadMoreData() {
 | 
						||
      if (this.currentTab === 0) {
 | 
						||
        this.activityPage.pageNum++
 | 
						||
        this.loadActivityList()
 | 
						||
      } else {
 | 
						||
        this.ticketPage.pageNum++
 | 
						||
        this.loadTicketList()
 | 
						||
      }
 | 
						||
    },
 | 
						||
 | 
						||
    // 加载活动列表
 | 
						||
    async loadActivityList() {
 | 
						||
      this.loading = true
 | 
						||
      try {
 | 
						||
        const res = await getTicketActivityList(this.activityPage)
 | 
						||
        if (res.code === 200) {
 | 
						||
          if (this.activityPage.pageNum === 1) {
 | 
						||
            this.activityList = res.rows || []
 | 
						||
          } else {
 | 
						||
            this.activityList.push(...(res.rows || []))
 | 
						||
          }
 | 
						||
        }
 | 
						||
      } catch (error) {
 | 
						||
        console.error('加载活动列表失败:', error)
 | 
						||
        uni.$u.toast('加载失败,请重试')
 | 
						||
      } finally {
 | 
						||
        this.loading = false
 | 
						||
        uni.stopPullDownRefresh()
 | 
						||
      }
 | 
						||
    },
 | 
						||
 | 
						||
    // 加载门票列表
 | 
						||
    async loadTicketList() {
 | 
						||
      this.ticketLoading = true
 | 
						||
      try {
 | 
						||
        const res = await getMyTicketList(this.ticketPage)
 | 
						||
        if (res.code === 200) {
 | 
						||
          if (this.ticketPage.pageNum === 1) {
 | 
						||
            this.ticketList = res.rows || []
 | 
						||
          } else {
 | 
						||
            this.ticketList.push(...(res.rows || []))
 | 
						||
          }
 | 
						||
        }
 | 
						||
      } catch (error) {
 | 
						||
        console.error('加载门票列表失败:', error)
 | 
						||
        uni.$u.toast('加载失败,请重试')
 | 
						||
      } finally {
 | 
						||
        this.ticketLoading = false
 | 
						||
        uni.stopPullDownRefresh()
 | 
						||
      }
 | 
						||
    },
 | 
						||
 | 
						||
    // 去购买门票
 | 
						||
    goBuyTicket(activity) {
 | 
						||
      uni.navigateTo({
 | 
						||
        url: `/pages/ticket/buy?activityId=${activity.pkId}&activityName=${encodeURIComponent(activity.actName)}&price=${activity.payMoney}`,
 | 
						||
      })
 | 
						||
    },
 | 
						||
 | 
						||
    // 查看门票详情
 | 
						||
    goTicketDetail(ticket) {
 | 
						||
      uni.navigateTo({
 | 
						||
        url: `/pages/ticket/detail?ticketId=${ticket.pkId}`,
 | 
						||
      })
 | 
						||
    },
 | 
						||
 | 
						||
    // 切换展开/收起状态
 | 
						||
    toggleExpand(item) {
 | 
						||
      // 使用 $set 确保响应式更新
 | 
						||
      this.$set(item, 'expanded', !item.expanded)
 | 
						||
    },
 | 
						||
 | 
						||
    // 判断是否为当天购买
 | 
						||
    isWithin24Hours(creationTime) {
 | 
						||
      if (!creationTime) return false
 | 
						||
      const createDate = new Date(creationTime)
 | 
						||
      const now = new Date()
 | 
						||
 | 
						||
      // 获取创建日期的年月日
 | 
						||
      const createYear = createDate.getFullYear()
 | 
						||
      const createMonth = createDate.getMonth()
 | 
						||
      const createDay = createDate.getDate()
 | 
						||
 | 
						||
      // 获取当前日期的年月日
 | 
						||
      const nowYear = now.getFullYear()
 | 
						||
      const nowMonth = now.getMonth()
 | 
						||
      const nowDay = now.getDate()
 | 
						||
 | 
						||
      // 判断是否为同一天
 | 
						||
      return (
 | 
						||
        createYear === nowYear &&
 | 
						||
        createMonth === nowMonth &&
 | 
						||
        createDay === nowDay
 | 
						||
      )
 | 
						||
    },
 | 
						||
 | 
						||
    // 显示撤销确认弹窗
 | 
						||
    showCancelConfirm(ticket) {
 | 
						||
      this.selectedTicket = ticket
 | 
						||
      this.showCancelModal = true
 | 
						||
    },
 | 
						||
 | 
						||
    // 确认撤销门票
 | 
						||
    async confirmCancel() {
 | 
						||
      if (!this.selectedTicket) return
 | 
						||
 | 
						||
      try {
 | 
						||
        uni.showLoading({ title: '撤销中...' })
 | 
						||
        const res = await cancelTicket({
 | 
						||
          orderCode: this.selectedTicket.orderCode,
 | 
						||
        })
 | 
						||
 | 
						||
        if (res.code === 200) {
 | 
						||
          uni.$u.toast('撤销成功')
 | 
						||
          this.showCancelModal = false
 | 
						||
          this.selectedTicket = null
 | 
						||
          // 刷新列表
 | 
						||
          this.refreshCurrentTab()
 | 
						||
        } else {
 | 
						||
          uni.$u.toast(res.msg || '撤销失败')
 | 
						||
        }
 | 
						||
      } catch (error) {
 | 
						||
        console.error('撤销门票失败:', error)
 | 
						||
        uni.$u.toast('撤销失败,请重试')
 | 
						||
      } finally {
 | 
						||
        uni.hideLoading()
 | 
						||
      }
 | 
						||
    },
 | 
						||
 | 
						||
    // 显示修改信息弹窗
 | 
						||
    showEditModal(ticket) {
 | 
						||
      this.selectedTicket = ticket
 | 
						||
      // 填充表单数据
 | 
						||
      this.editForm = {
 | 
						||
        pkId: ticket.pkId,
 | 
						||
        actName: ticket.actName,
 | 
						||
        memberCode: ticket.memberCode,
 | 
						||
        memberName: ticket.memberName,
 | 
						||
        orderCode: ticket.orderCode,
 | 
						||
        orderAmount: ticket.orderAmount,
 | 
						||
        price: ticket.price,
 | 
						||
        quantity: ticket.quantity,
 | 
						||
        buyName: ticket.buyName || '',
 | 
						||
        phone: ticket.phone || '',
 | 
						||
        idCard: ticket.idCard || '',
 | 
						||
        sex: ticket.sex || '',
 | 
						||
        sexVal: ticket.sexVal || '',
 | 
						||
        clothSize: ticket.clothSize || '',
 | 
						||
        cohabitant: ticket.cohabitant || '',
 | 
						||
        emergencyPhone: ticket.emergencyPhone || '',
 | 
						||
        creationTime: ticket.creationTime,
 | 
						||
      }
 | 
						||
      this.editModalVisible = true
 | 
						||
    },
 | 
						||
 | 
						||
    // 关闭修改弹窗
 | 
						||
    closeEditModal() {
 | 
						||
      this.editModalVisible = false
 | 
						||
      this.selectedTicket = null
 | 
						||
      this.editForm = {
 | 
						||
        pkId: '',
 | 
						||
        actName: '',
 | 
						||
        memberCode: '',
 | 
						||
        memberName: '',
 | 
						||
        orderCode: '',
 | 
						||
        orderAmount: '',
 | 
						||
        price: '',
 | 
						||
        quantity: '',
 | 
						||
        buyName: '',
 | 
						||
        phone: '',
 | 
						||
        idCard: '',
 | 
						||
        sex: '',
 | 
						||
        sexVal: '',
 | 
						||
        clothSize: '',
 | 
						||
        cohabitant: '',
 | 
						||
        emergencyPhone: '',
 | 
						||
        creationTime: '',
 | 
						||
      }
 | 
						||
    },
 | 
						||
 | 
						||
    // 更新门票信息
 | 
						||
    async updateTicketInfo() {
 | 
						||
      // 表单验证
 | 
						||
      if (!this.editForm.buyName) {
 | 
						||
        uni.$u.toast('请输入姓名')
 | 
						||
        return
 | 
						||
      }
 | 
						||
      if (!this.editForm.phone) {
 | 
						||
        uni.$u.toast('请输入手机号')
 | 
						||
        return
 | 
						||
      }
 | 
						||
      if (!this.editForm.idCard) {
 | 
						||
        uni.$u.toast('请输入身份证号')
 | 
						||
        return
 | 
						||
      }
 | 
						||
      if (!this.editForm.sex && this.editForm.sex !== 0) {
 | 
						||
        uni.$u.toast('请选择性别')
 | 
						||
        return
 | 
						||
      }
 | 
						||
      if (!this.editForm.clothSize) {
 | 
						||
        uni.$u.toast('请输入尺码')
 | 
						||
        return
 | 
						||
      }
 | 
						||
      if (this.editForm.emergencyPhone === this.editForm.phone) {
 | 
						||
        uni.$u.toast('紧急联系方式不能与联系方式相同')
 | 
						||
        return
 | 
						||
      }
 | 
						||
 | 
						||
      // 设置性别值
 | 
						||
      this.editForm.sexVal = this.editForm.sex === 1 ? '男' : '女'
 | 
						||
 | 
						||
      try {
 | 
						||
        uni.showLoading({ title: '更新中...' })
 | 
						||
        const res = await updateTicket(this.editForm)
 | 
						||
 | 
						||
        if (res.code === 200) {
 | 
						||
          uni.$u.toast('修改成功')
 | 
						||
          this.closeEditModal()
 | 
						||
          // 刷新列表
 | 
						||
          this.refreshCurrentTab()
 | 
						||
        } else {
 | 
						||
          uni.$u.toast(res.msg || '修改失败')
 | 
						||
        }
 | 
						||
      } catch (error) {
 | 
						||
        console.error('更新门票信息失败:', error)
 | 
						||
        uni.$u.toast('修改失败,请重试')
 | 
						||
      } finally {
 | 
						||
        uni.hideLoading()
 | 
						||
      }
 | 
						||
    },
 | 
						||
  },
 | 
						||
}
 | 
						||
</script>
 | 
						||
 | 
						||
<style lang="scss" scoped>
 | 
						||
::v-deep(.uni-scroll-view) {
 | 
						||
  box-sizing: border-box;
 | 
						||
}
 | 
						||
.ticket-container {
 | 
						||
  min-height: 100vh;
 | 
						||
  background: #f8f8f8;
 | 
						||
}
 | 
						||
 | 
						||
.custom-navbar {
 | 
						||
  position: fixed;
 | 
						||
  top: 0;
 | 
						||
  left: 0;
 | 
						||
  right: 0;
 | 
						||
  z-index: 999;
 | 
						||
  background: #fff;
 | 
						||
  padding-top: var(--status-bar-height);
 | 
						||
  border-bottom: 2rpx solid #eee;
 | 
						||
 | 
						||
  .navbar-content {
 | 
						||
    display: flex;
 | 
						||
    align-items: center;
 | 
						||
    height: 88rpx;
 | 
						||
    padding: 0 32rpx;
 | 
						||
 | 
						||
    .back-btn {
 | 
						||
      width: 80rpx;
 | 
						||
      height: 80rpx;
 | 
						||
      display: flex;
 | 
						||
      align-items: center;
 | 
						||
      justify-content: center;
 | 
						||
    }
 | 
						||
 | 
						||
    .navbar-title {
 | 
						||
      flex: 1;
 | 
						||
      text-align: center;
 | 
						||
      font-size: 36rpx;
 | 
						||
      font-weight: 600;
 | 
						||
      color: #333;
 | 
						||
    }
 | 
						||
 | 
						||
    .placeholder {
 | 
						||
      width: 80rpx;
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
.tab-container {
 | 
						||
  position: fixed;
 | 
						||
  top: calc(var(--status-bar-height) + 88rpx);
 | 
						||
  left: 0;
 | 
						||
  right: 0;
 | 
						||
  z-index: 998;
 | 
						||
  background: #fff;
 | 
						||
  border-bottom: 2rpx solid #eee;
 | 
						||
 | 
						||
  .tab-wrapper {
 | 
						||
    display: flex;
 | 
						||
    align-items: center;
 | 
						||
 | 
						||
    .tab-item {
 | 
						||
      flex: 1;
 | 
						||
      position: relative;
 | 
						||
      display: flex;
 | 
						||
      flex-direction: column;
 | 
						||
      align-items: center;
 | 
						||
      padding: 32rpx 0;
 | 
						||
      cursor: pointer;
 | 
						||
 | 
						||
      .tab-text {
 | 
						||
        font-size: 32rpx;
 | 
						||
        color: #666;
 | 
						||
        transition: color 0.3s;
 | 
						||
      }
 | 
						||
 | 
						||
      .tab-line {
 | 
						||
        position: absolute;
 | 
						||
        bottom: 0;
 | 
						||
        width: 60rpx;
 | 
						||
        height: 6rpx;
 | 
						||
        background: #005bac;
 | 
						||
        border-radius: 3rpx;
 | 
						||
      }
 | 
						||
 | 
						||
      &.active .tab-text {
 | 
						||
        color: #005bac;
 | 
						||
        font-weight: 600;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
.content-area {
 | 
						||
  margin-top: calc(100rpx);
 | 
						||
  padding: 24rpx;
 | 
						||
  min-height: calc(100vh - 100rpx);
 | 
						||
}
 | 
						||
 | 
						||
.activity-card {
 | 
						||
  background: #fff;
 | 
						||
  border-radius: 16rpx;
 | 
						||
  margin-bottom: 24rpx;
 | 
						||
  overflow: hidden;
 | 
						||
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
 | 
						||
  border: 1rpx solid #f0f0f0;
 | 
						||
 | 
						||
  .card-content {
 | 
						||
    display: flex;
 | 
						||
    padding: 24rpx;
 | 
						||
    gap: 20rpx;
 | 
						||
 | 
						||
    .activity-image {
 | 
						||
      flex-shrink: 0;
 | 
						||
      width: 208rpx;
 | 
						||
      height: 208rpx;
 | 
						||
      border-radius: 40rpx;
 | 
						||
      overflow: hidden;
 | 
						||
      image {
 | 
						||
        width: 100%;
 | 
						||
        height: 100%;
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    .activity-info {
 | 
						||
      flex: 1;
 | 
						||
      display: flex;
 | 
						||
      flex-direction: column;
 | 
						||
 | 
						||
      .activity-title {
 | 
						||
        font-size: 28rpx;
 | 
						||
        font-weight: 600;
 | 
						||
        color: #333;
 | 
						||
        line-height: 1.4;
 | 
						||
        margin-bottom: 16rpx;
 | 
						||
      }
 | 
						||
 | 
						||
      .activity-detail {
 | 
						||
        display: flex;
 | 
						||
        margin-bottom: 8rpx;
 | 
						||
 | 
						||
        .detail-label {
 | 
						||
          font-size: 20rpx;
 | 
						||
          color: #999;
 | 
						||
          min-width: 140rpx;
 | 
						||
        }
 | 
						||
 | 
						||
        .detail-value {
 | 
						||
          font-size: 20rpx;
 | 
						||
          color: #666;
 | 
						||
          flex: 1;
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      .bottom-section {
 | 
						||
        display: flex;
 | 
						||
        justify-content: space-between;
 | 
						||
        align-items: center;
 | 
						||
        .price-info {
 | 
						||
          display: flex;
 | 
						||
          align-items: baseline;
 | 
						||
          color: #ff4444;
 | 
						||
 | 
						||
          .price-symbol {
 | 
						||
            font-size: 24rpx;
 | 
						||
            margin-right: 2rpx;
 | 
						||
          }
 | 
						||
 | 
						||
          .price-value {
 | 
						||
            font-size: 32rpx;
 | 
						||
            font-weight: 700;
 | 
						||
          }
 | 
						||
        }
 | 
						||
 | 
						||
        .buy-btn {
 | 
						||
          background: #005bac;
 | 
						||
          color: #fff;
 | 
						||
          border: none;
 | 
						||
          border-radius: 40rpx;
 | 
						||
          padding: 0rpx 32rpx;
 | 
						||
          font-size: 20rpx;
 | 
						||
          font-weight: 600;
 | 
						||
          margin: 0;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
.ticket-card {
 | 
						||
  background: #fff;
 | 
						||
  border-radius: 16rpx;
 | 
						||
  margin-bottom: 24rpx;
 | 
						||
  padding: 24rpx;
 | 
						||
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
 | 
						||
 | 
						||
  .ticket-header {
 | 
						||
    margin-bottom: 16rpx;
 | 
						||
 | 
						||
    .order-code {
 | 
						||
      font-size: 24rpx;
 | 
						||
      color: #999;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  .ticket-content {
 | 
						||
    .ticket-info {
 | 
						||
      .ticket-title {
 | 
						||
        font-size: 28rpx;
 | 
						||
        font-weight: 600;
 | 
						||
        color: #333;
 | 
						||
        margin-bottom: 16rpx;
 | 
						||
        line-height: 1.3;
 | 
						||
      }
 | 
						||
 | 
						||
      .ticket-detail {
 | 
						||
        display: flex;
 | 
						||
        margin-bottom: 12rpx;
 | 
						||
 | 
						||
        .detail-label {
 | 
						||
          font-size: 24rpx;
 | 
						||
          color: #999;
 | 
						||
          min-width: 140rpx;
 | 
						||
        }
 | 
						||
 | 
						||
        .detail-value {
 | 
						||
          font-size: 24rpx;
 | 
						||
          color: #666;
 | 
						||
 | 
						||
          &.price {
 | 
						||
            color: #ff4444;
 | 
						||
            font-weight: 600;
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      .expanded-details {
 | 
						||
        animation: fadeIn 0.3s ease-in-out;
 | 
						||
 | 
						||
        .ticket-detail {
 | 
						||
          margin-bottom: 12rpx;
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      .action-buttons {
 | 
						||
        display: flex;
 | 
						||
        gap: 16rpx;
 | 
						||
        margin-top: 16rpx;
 | 
						||
        padding: 16rpx 0;
 | 
						||
 | 
						||
        .cancel-btn,
 | 
						||
        .edit-btn {
 | 
						||
          flex: 1;
 | 
						||
          height: 60rpx;
 | 
						||
          border: none;
 | 
						||
          border-radius: 30rpx;
 | 
						||
          font-size: 24rpx;
 | 
						||
          font-weight: 600;
 | 
						||
          margin: 0;
 | 
						||
        }
 | 
						||
 | 
						||
        .cancel-btn {
 | 
						||
          background: #fff;
 | 
						||
          color: #ff4444;
 | 
						||
          border: 2rpx solid #ff4444;
 | 
						||
        }
 | 
						||
 | 
						||
        .edit-btn {
 | 
						||
          background: #005bac;
 | 
						||
          color: #fff;
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      .expand-action {
 | 
						||
        display: flex;
 | 
						||
        align-items: center;
 | 
						||
        justify-content: center;
 | 
						||
        margin-top: 16rpx;
 | 
						||
        padding: 16rpx 0;
 | 
						||
        border-top: 1rpx solid #eee;
 | 
						||
        cursor: pointer;
 | 
						||
        transition: background-color 0.2s;
 | 
						||
 | 
						||
        &:active {
 | 
						||
          background-color: #f8f8f8;
 | 
						||
        }
 | 
						||
 | 
						||
        .expand-text {
 | 
						||
          font-size: 24rpx;
 | 
						||
          color: #999;
 | 
						||
          margin-right: 8rpx;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
.empty-state,
 | 
						||
.loading-state {
 | 
						||
  display: flex;
 | 
						||
  flex-direction: column;
 | 
						||
  align-items: center;
 | 
						||
  justify-content: center;
 | 
						||
  padding: 120rpx 0;
 | 
						||
 | 
						||
  .empty-text,
 | 
						||
  .loading-text {
 | 
						||
    font-size: 28rpx;
 | 
						||
    color: #999;
 | 
						||
    margin-top: 16rpx;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
@keyframes fadeIn {
 | 
						||
  from {
 | 
						||
    opacity: 0;
 | 
						||
    transform: translateY(-10rpx);
 | 
						||
  }
 | 
						||
  to {
 | 
						||
    opacity: 1;
 | 
						||
    transform: translateY(0);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 修改信息弹窗样式
 | 
						||
.edit-modal {
 | 
						||
  width: 640rpx;
 | 
						||
  max-height: 90vh;
 | 
						||
  background: #fff;
 | 
						||
  border-radius: 24rpx;
 | 
						||
  overflow: hidden;
 | 
						||
 | 
						||
  .modal-header {
 | 
						||
    display: flex;
 | 
						||
    align-items: center;
 | 
						||
    justify-content: space-between;
 | 
						||
    padding: 32rpx;
 | 
						||
    border-bottom: 2rpx solid #eee;
 | 
						||
 | 
						||
    .modal-title {
 | 
						||
      font-size: 32rpx;
 | 
						||
      font-weight: 600;
 | 
						||
      color: #333;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  .modal-content {
 | 
						||
    max-height: 70vh;
 | 
						||
    padding: 32rpx;
 | 
						||
    box-sizing: border-box;
 | 
						||
    padding-bottom: 20px;
 | 
						||
    overflow-y: hidden;
 | 
						||
    .form-item {
 | 
						||
      margin-bottom: 32rpx;
 | 
						||
 | 
						||
      .form-label {
 | 
						||
        display: block;
 | 
						||
        font-size: 28rpx;
 | 
						||
        color: #333;
 | 
						||
        margin-bottom: 16rpx;
 | 
						||
 | 
						||
        &::after {
 | 
						||
          content: '*';
 | 
						||
          color: #ff4444;
 | 
						||
          margin-left: 4rpx;
 | 
						||
        }
 | 
						||
 | 
						||
        &.optional::after {
 | 
						||
          display: none;
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      .form-input {
 | 
						||
        width: 100%;
 | 
						||
        height: 80rpx;
 | 
						||
        padding: 0 24rpx;
 | 
						||
        border: 2rpx solid #ddd;
 | 
						||
        border-radius: 12rpx;
 | 
						||
        font-size: 28rpx;
 | 
						||
        color: #333;
 | 
						||
        background: #fff;
 | 
						||
        box-sizing: border-box;
 | 
						||
 | 
						||
        &.disabled {
 | 
						||
          background: #f5f5f5;
 | 
						||
          color: #999;
 | 
						||
        }
 | 
						||
 | 
						||
        &:focus {
 | 
						||
          border-color: #005bac;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  .modal-footer {
 | 
						||
    padding: 32rpx;
 | 
						||
    border-top: 2rpx solid #eee;
 | 
						||
 | 
						||
    .confirm-btn {
 | 
						||
      width: 100%;
 | 
						||
      height: 80rpx;
 | 
						||
      background: #005bac;
 | 
						||
      color: #fff;
 | 
						||
      border: none;
 | 
						||
      border-radius: 40rpx;
 | 
						||
      font-size: 32rpx;
 | 
						||
      font-weight: 600;
 | 
						||
      margin: 0;
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
</style>
 |