MrShi
11 小时以前 ce06ca62a0dd65d4a8fb57126948449c804ad77e
small-program/shop/pages/Invoice-application/Invoice-application.vue
@@ -7,7 +7,8 @@
               v-model="keyword"
               class="search-input"
               type="text"
               :placeholder="currentTab === 'apply' ? '搜索订单编号' : '搜索'"
               placeholder="搜索订单编号"
               @confirm="handleSearch"
            />
         </view>
      </view>
@@ -15,27 +16,34 @@
      <scroll-view scroll-y class="page-scroll">
         <view v-if="currentTab === 'apply'" class="card-list">
            <view v-for="item in applyList" :key="item.id" class="invoice-card apply-card">
               <view class="order-no">订单编号:{{ item.orderNo }}</view>
               <view class="order-no">
                  <text>订单编号:{{ item.code }}</text>
                  <view class="mode-tag city-tag" v-if="item.type === 1">异地存取</view>
                  <view class="mode-tag local-tag" v-else>就地存取</view>
               </view>
               <view class="address-group">
                  <view class="address-row">
                     <view class="address-tag send-tag">寄</view>
                     <view class="address-tag send-tag" style="width: 60rpx; height: 60rpx;" v-if="item.type === 0">
                        <image style="width: 100%; height: 100%;" src="/static/icon/ic_store@2x.png" mode="aspectFit"></image>
                     </view>
                     <view class="address-tag send-tag" v-else>寄</view>
                     <view class="address-copy">
                        <view class="address-title-row">
                           <text class="address-title">{{ item.fromAddress }}</text>
                           <text class="address-title">{{ item.depositShopName }}</text>
                           <u-icon name="arrow-right" size="14" color="#40454d"></u-icon>
                        </view>
                        <text class="address-user">{{ item.fromUser }}</text>
                        <text class="address-user">{{ item.depositShopAddress }}</text>
                     </view>
                  </view>
                  <view class="address-dash"></view>
                  <view class="address-row">
                  <view class="address-dash" v-if="item.type === 1"></view>
                  <view class="address-row" v-if="item.type === 1">
                     <view class="address-tag receive-tag">收</view>
                     <view class="address-copy">
                        <view class="address-title-row">
                           <text class="address-title">{{ item.toAddress }}</text>
                           <text class="address-title">{{ item.takeShopId ? item.takeShopName : item.takeLocation }}</text>
                           <u-icon name="arrow-right" size="14" color="#40454d"></u-icon>
                        </view>
                        <text class="address-user">{{ item.toUser }}</text>
                        <text class="address-user">{{ item.takeShopId ? item.takeShopAddress : item.takeLocationRemark }}</text>
                     </view>
                  </view>
               </view>
@@ -48,7 +56,7 @@
               <view class="price-row">
                  <view class="price-copy">
                     <text class="price-label">实付款:</text>
                     <text class="price-value">¥{{ item.amount }}</text>
                     <text class="price-value">¥{{((item.estimatedAmount || 0)/100).toFixed(2) }}</text>
                  </view>
               <view class="action-btn primary-btn" @tap="goInvoiceRequest(item)">申请开票</view>
               </view>
@@ -58,21 +66,21 @@
         <view v-else class="card-list">
            <view v-for="item in historyList" :key="item.id" class="invoice-card history-card">
               <view class="history-head">
                  <text class="company-name">{{ item.company }}</text>
                  <text class="history-status" :class="item.status">{{ item.statusText }}</text>
                  <text class="company-name">{{ item.name }}</text>
                  <text class="history-status" :class="item.status === 1 ? 'done' : item.status === 99 ? 'failed' : 'processing'">{{ item.status == 1 ? '已开票' : item.status == 99 ? '开具失败' : '开票中' }}</text>
               </view>
               <view class="history-subline">
                  <text>{{ item.ticketType }}</text>
                  <text>{{ item.invoiceType === 0 ? '电子普通发票' : '电子专用发票' }}</text>
                  <text class="sub-sep">|</text>
                  <text>发票金额:</text>
                  <text class="history-amount">¥{{ item.amount }}</text>
                  <text class="history-amount">¥{{((item.invoiceAmount || 0)/100).toFixed(2) }}</text>
               </view>
               <view class="history-divider"></view>
               <view class="history-detail">
                  <view class="detail-item">开票编号:{{ item.applyNo }}</view>
                  <view class="detail-item">发票号码:{{ item.invoiceNo }}</view>
                  <view class="detail-item">申请时间:{{ item.applyTime }}</view>
                  <view v-if="item.failReason" class="detail-item fail-row">失败理由:<text class="fail-text">{{ item.failReason }}</text></view>
                  <view class="detail-item">开票编号:{{ item.orderNo }}</view>
                  <view class="detail-item">发票号码:{{ item.invoiceNo || '' }}</view>
                  <view class="detail-item">申请时间:{{ item.createTime }}</view>
                  <view v-if="item.remark" class="detail-item fail-row">失败理由:<text class="fail-text">{{ item.remark }}</text></view>
               </view>
               <view v-if="item.actions && item.actions.length" class="history-actions">
@@ -132,7 +140,8 @@
            currentTab: 'apply',
            keyword: '',
            showEmailPopup: false,
            email: '38742937@qq.com',
            email: '',
            currentInvoiceRecordId: '',
            currentYear: '近一年',
            tabs: [
               {
@@ -148,88 +157,111 @@
                  activeIcon: '/shop/static/icon/nav_lishi_sel@2x.png'
               }
            ],
            applyList: [
               {
                  id: 1,
                  orderNo: '202607131742520001',
                  fromAddress: '安徽省合肥市蜀山区莲花科技产业园F401',
                  fromUser: '张海涛 18733987653',
                  toAddress: '安徽省合肥市蜀山区尚泽大都会2栋302',
                  toUser: '张海涛 18733987653',
                  goodsText: '大件行李*1、中件行李*2、小件行李*3、背...',
                  amount: '125.00'
               },
               {
                  id: 2,
                  orderNo: '202607131742520001',
                  fromAddress: '安徽省合肥市蜀山区莲花科技产业园F401',
                  fromUser: '张海涛 18733987653',
                  toAddress: '安徽省合肥市蜀山区尚泽大都会2栋302',
                  toUser: '张海涛 18733987653',
                  goodsText: '大件行李*1、中件行李*2、小件行李*3、背...',
                  amount: '125.00'
               }
            ],
            historyList: [
               {
                  id: 1,
                  company: '安徽豆米科技有限公司',
                  status: 'processing',
                  statusText: '开票中',
                  ticketType: '电子专用发票',
                  amount: '100.00',
                  applyNo: '202607131742520001',
                  invoiceNo: '20260713174252000324',
                  applyTime: '2026-05-12 11:34:11',
                  failReason: '',
                  actions: []
               },
               {
                  id: 2,
                  company: '安徽豆米科技有限公司',
                  status: 'done',
                  statusText: '已开票',
                  ticketType: '电子专用发票',
                  amount: '100.00',
                  applyNo: '202607131742520001',
                  invoiceNo: '20260713174252000324',
                  applyTime: '2026-05-12 11:34:11',
                  failReason: '',
                  actions: [
                     { text: '查看电子发票', primary: false },
                     { text: '发送至邮箱', primary: true }
                  ]
               },
               {
                  id: 3,
                  company: '安徽豆米科技有限公司',
                  status: 'failed',
                  statusText: '开票失败',
                  ticketType: '电子专用发票',
                  amount: '100.00',
                  applyNo: '202607131742520001',
                  invoiceNo: '20260713174252000324',
                  applyTime: '2026-05-12 11:34:11',
                  failReason: '发票抬头错误',
                  actions: [
                     { text: '申请开票', primary: true }
                  ]
               }
            ]
            applyList: [],
            page: 1,
            capacity: 10,
            isRequest: true,
            historyPage: 1,
            historyCapacity: 10,
            historyIsRequest: true,
            historyList: [],
         };
      },
      watch: {
         currentTab() {
            if (this.currentTab === 'apply') {
               this.page = 1
               this.applyList = []
               this.isRequest = true
               this.getApplyList()
            } else if (this.currentTab === 'history') {
               this.historyPage = 1
               this.historyList = []
               this.historyIsRequest = true
               this.getHistoryList()
            }
         }
      },
      onLoad() {
         this.getApplyList()
      },
      onReachBottom() {
         if (this.currentTab === 'apply') {
            this.getApplyList()
         } else if (this.currentTab === 'history') {
            this.getHistoryList()
         }
      },
      methods: {
         async getApplyList() {
            if (!this.isRequest) return
            const res = await this.$u.api.myOrderPage({
               capacity: this.capacity,
               page: this.page,
               model: {
                  invoiceStatus: 1,
                  keyword: this.keyword
               }
            })
            if (res.code === 200) {
               const list = res.data.records || []
               list.forEach(item => {
                  if (item.detailList && item.detailList.length > 0) {
                     item.goodsText = item.detailList.map(d => d.luggageName + '*' + d.num).join('、')
                  }
               })
               this.applyList = [...this.applyList, ...list]
               this.page++
               if (res.data.total <= this.applyList.length) {
                  this.isRequest = false
               }
            }
         },
         async getHistoryList() {
            if (!this.historyIsRequest) return
            const res = await this.$u.api.invoicePage({
               page: this.historyPage,
               capacity: this.historyCapacity,
               model: {
                  orderNo: this.keyword
               }
            })
            if (res.code === 200) {
               const list = res.data.records || []
               list.forEach(item => {
                  if (item.status === 1) {
                     item.actions = [{ text: '发送至邮箱', primary: true }]
                  }
               })
               this.historyList = [...this.historyList, ...list]
               this.historyPage++
               if (res.data.total <= this.historyList.length) {
                  this.historyIsRequest = false
               }
            }
         },
         handleSearch() {
            this.historyPage = 1
            this.historyList = []
            this.historyIsRequest = true
            this.getHistoryList()
         },
         getTabIcon(tab) {
            return this.currentTab === tab.value ? tab.activeIcon : tab.icon;
         },
         goInvoiceRequest(item) {
            const id = item && item.id ? `?id=${item.id}` : '';
            const params = []
            if (item && item.id) params.push(`id=${item.id}`)
            if (item && item.code) params.push(`orderNo=${item.code}`)
            if (item && item.estimatedAmount) params.push(`invoiceAmount=${((item.estimatedAmount || 0) / 100).toFixed(2)}`)
            const query = params.length ? `?${params.join('&')}` : ''
            uni.navigateTo({
               url: `/shop/pages/Invoice-request/Invoice-request${id}`
               url: `/shop/pages/Invoice-request/Invoice-request${query}`
            });
         },
         handleAction(action) {
         handleAction(action, item) {
            if (action.text === '发送至邮箱') {
               this.currentInvoiceRecordId = item.id
               this.showEmailPopup = true;
               return;
            }
@@ -241,8 +273,20 @@
         closeEmailPopup() {
            this.showEmailPopup = false;
         },
         confirmSendEmail() {
            this.showEmailPopup = false;
         async confirmSendEmail() {
            if (!this.email) {
               uni.showToast({ title: '请输入邮箱', icon: 'none' });
               return;
            }
            const res = await this.$u.api.sendEmail({
               email: this.email,
               invoiceRecordId: this.currentInvoiceRecordId
            })
            if (res.code === 200) {
               uni.showToast({ title: '发送成功', icon: 'success' });
               this.showEmailPopup = false;
               this.email = '';
            }
         }
      }
   };
@@ -252,6 +296,32 @@
   .invoice-page {
      min-height: 100vh;
      background: linear-gradient(180deg, #f8f9fc 0%, #f4f6fb 100%);
   }
   .mode-tag {
      width: 112rpx;
      height: 38rpx;
      border-radius: 8rpx;
      display: flex;
      align-items: baseline;
      justify-content: center;
      font-weight: 400;
      font-size: 24rpx;
      color: #FFFFFF;
      margin-right: 14rpx;
      flex-shrink: 0;
   }
   .local-tag {
      background: #18abf8;
      // background: linear-gradient(90deg, #18abf8 0%, #39c5ff 100%);
   }
   .city-tag {
      // background: linear-gradient(90deg, #ff8b28 0%, #ffb14f 100%);
      margin-right: 0;
      background: #ff8b28;
      margin-bottom: 8rpx;
   }
   .search-bar {
@@ -316,9 +386,15 @@
   }
   .order-no {
      font-size: 28rpx;
      line-height: 40rpx;
      color: #9ca3af;
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: space-between;
      text {
         font-size: 28rpx;
         line-height: 40rpx;
         color: #9ca3af;
      }
   }
   .address-group {
@@ -346,6 +422,13 @@
   .send-tag {
      background: linear-gradient(180deg, #4bc7ff 0%, #1ea4ff 100%);
      display: flex;
      align-items: center;
      justify-content: center;
      image {
         width: 28rpx;
         height: 28rpx;
      }
   }
   .receive-tag {
@@ -472,21 +555,21 @@
   .history-status {
      flex-shrink: 0;
      font-size: 32rpx;
      font-weight: 600;
      font-weight: 400;
      font-size: 26rpx;
   }
   .history-status.processing {
      color: #ff4b4b;
      color: #FF0000;
   }
   .history-status.done,
   .history-amount {
      color: #1eb6ff;
      color: #10B2FA;
   }
   .history-status.failed {
      color: #a8adb8;
      color: #999999;
   }
   .history-subline {