gaoluyang
3 天以前 ee42bf1badae06026efa79dc17d2a541297ab49b
src/pages/sales/invoiceLedger/detail.vue
@@ -1,57 +1,92 @@
<template>
   <view class="account-detail">
   <view class="account-view">
      <!-- 使用通用页面头部组件 -->
      <PageHeader title="编辑开票台账" @back="goBack" />
      <van-form @submit="submitForm" ref="formRef" label-width="110px" input-align="right" error-message-align="right" scroll-to-error scroll-to-error-position="center">
         <van-cell-group title="基本信息" inset>
            <van-field v-model="form.salesContractNo" label="销售合同号" readonly />
            <van-field v-model="form.customerName" label="客户名称" readonly />
            <van-field v-model="form.invoiceNo" label="发票号" placeholder="请输入" required :rules="[{ required: true, message: '请输入发票号' }]" />
            <van-field v-model="form.invoiceTotal" label="发票金额(元)" type="number" placeholder="请输入" required :rules="[{ required: true, message: '请输入发票金额' }]" />
            <view class="tip-text" v-if="form.taxInclusiveTotalPrice">合同总额:{{ formatAmount(form.taxInclusiveTotalPrice) }} 元</view>
            <van-field v-model="form.invoicePerson" label="开票人" readonly />
            <van-field v-model="form.invoiceDate" label="开票日期" readonly placeholder="请选择" @click="showInvoiceDatePicker = true" required :rules="[{ required: true, message: '请选择开票日期' }]" />
         </van-cell-group>
         <van-cell-group title="附件材料(仅支持 pdf)" inset>
            <van-uploader
               accept=".pdf"
               multiple
               :after-read="afterReadUpload"
               :before-read="beforeReadPdf"
            >
               <van-button class="upload-btn" icon="plus" type="primary" block>上传文件</van-button>
            </van-uploader>
            <view class="uploaded-list" v-if="fileList.length">
               <view class="uploaded-item" v-for="(f, idx) in fileList" :key="idx">
                  <text class="file-name">{{ f.name || getFileNameFromUrl(f.url) }}</text>
                  <van-button size="mini" type="danger" plain @click="removeUploaded(idx)">移除</van-button>
               </view>
            </view>
         </van-cell-group>
      <PageHeader title="发票详情" @back="goBack" />
      <!-- 表单内容 -->
      <u-form @submit="submitForm" ref="formRef" label-width="110" input-align="right" error-message-align="right">
         <u-cell-group title="基本信息">
            <u-form-item label="销售合同号" border-bottom>
               <u-input v-model="form.salesContractNo" readonly />
            </u-form-item>
            <u-form-item label="客户名称" border-bottom>
               <u-input v-model="form.customerName" readonly />
            </u-form-item>
            <u-form-item label="发票号" prop="invoiceNo" required border-bottom>
               <u-input v-model="form.invoiceNo" placeholder="请输入" />
            </u-form-item>
            <u-form-item label="发票金额(元)" prop="invoiceTotal" required border-bottom>
               <u-input v-model="form.invoiceTotal" type="number" placeholder="请输入" />
            </u-form-item>
            <u-form-item label="开票人" border-bottom>
               <u-input v-model="form.invoicePerson" readonly />
            </u-form-item>
            <u-form-item label="开票日期" prop="invoiceDate" required border-bottom>
               <u-input v-model="form.invoiceDate" readonly placeholder="请选择" @click="showInvoiceDatePicker = true" />
            </u-form-item>
         </u-cell-group>
<!--         <u-cell-group title="附件材料(仅支持 pdf)">-->
<!--            <u-upload-->
<!--               accept=".pdf"-->
<!--               multiple-->
<!--               :afterRead="afterReadUpload"-->
<!--               :beforeRead="beforeReadPdf"-->
<!--            >-->
<!--               <u-button class="upload-btn" type="primary">-->
<!--                  上传文件-->
<!--               </u-button>-->
<!--            </u-upload>-->
<!--            <view class="uploaded-list" v-if="fileList.length">-->
<!--               <view class="uploaded-item" v-for="(f, idx) in fileList" :key="idx">-->
<!--                  <text class="file-name">{{ f.name || getFileNameFromUrl(f.url) }}</text>-->
<!--                  <u-button size="mini" type="error" plain @click="removeUploaded(idx)">移除</u-button>-->
<!--               </view>-->
<!--            </view>-->
<!--         </u-cell-group>-->
         <!-- 提交按钮 -->
         <view class="footer-btns">
            <van-button class="cancel-btn" @click="goBack">取消</van-button>
            <van-button class="save-btn" native-type="submit" form-type="submit">保存</van-button>
            <u-button class="cancel-btn" @click="goBack">取消</u-button>
            <u-button class="save-btn" type="primary" @click="submitForm">保存</u-button>
         </view>
      </van-form>
      </u-form>
      <van-popup v-model:show="showInvoiceDatePicker" position="bottom">
         <van-date-picker
            v-model="currentInvoiceDate"
      <!-- 开票日期选择器 -->
      <u-popup v-model="showInvoiceDatePicker" mode="bottom">
         <u-datetime-picker
            v-model="invoiceDateValue"
            title="选择开票日期"
            @confirm="onInvoiceDateConfirm"
            @cancel="showInvoiceDatePicker = false"
         />
      </van-popup>
      </u-popup>
   </view>
</template>
<script setup>
// 替换 toast 方法
const showToast = (message) => {
  uni.showToast({
    title: message,
    icon: 'none'
  })
}
const showLoadingToast = (message) => {
  uni.showLoading({
    title: message || '加载中...'
  })
}
const closeToast = () => {
  uni.hideLoading()
}
import { ref, onMounted } from 'vue'
import { showToast, showLoadingToast, closeToast } from 'vant'
import dayjs from 'dayjs'
import { formatDateToYMD } from '@/utils/ruoyi'
import useUserStore from '@/store/modules/user'
import { getToken } from '@/utils/auth'
import { invoiceLedgerProductInfo, invoiceLedgerSaveOrUpdate } from '@/api/salesManagement/invoiceLedger.js'
@@ -92,10 +127,11 @@
   return num.toFixed(2)
}
const onInvoiceDateConfirm = ({ selectedValues }) => {
   form.value.invoiceDate = selectedValues.join('-')
   currentInvoiceDate.value = selectedValues
   showInvoiceDatePicker.value = false
// 日期确认事件
const onInvoiceDateConfirm = (e) => {
   form.value.invoiceDate = formatDateToYMD(e.value)
   currentInvoiceDate.value = formatDateToYMD(e.value)
   showInvoiceDatePicker.value = false;
}
// 上传前校验(兼容 Vant Uploader 的 file/fileList 结构)
@@ -120,7 +156,7 @@
const uploadSingleFile = async (fileObj) => {
   return new Promise((resolve, reject) => {
      showLoadingToast({ message: '正在上传...' })
      showLoadingToast('正在上传...')
      const baseUrl = config.baseUrl + '/invoiceLedger/uploadFile'
      const filePath = fileObj?.url || fileObj?.tempFilePath || fileObj?.file?.path
@@ -205,7 +241,7 @@
const loadDetail = async (id) => {
   try {
      showLoadingToast({ message: '加载中...' })
      showLoadingToast('加载中...')
      const res = await invoiceLedgerProductInfo({ id })
      const data = res?.data || res
      form.value = { ...data }
@@ -228,7 +264,7 @@
      if (!form.value.invoiceNo) { showToast('请输入发票号'); return }
      if (!form.value.invoiceTotal) { showToast('请输入发票金额'); return }
      if (!form.value.invoiceDate) { showToast('请选择开票日期'); return }
      showLoadingToast({ message: '提交中...' })
      showLoadingToast('提交中...')
      form.value.fileList = fileList.value
      await invoiceLedgerSaveOrUpdate(form.value)
      closeToast()
@@ -255,17 +291,88 @@
</script>
<style scoped lang="scss">
.account-detail {
@import '@/static/scss/form-common.scss';
.account-view {
   min-height: 100vh;
   background: #f8f9fa;
   padding-bottom: 5rem;
}
.info-section {
   background: #fff;
   margin-bottom: 16px;
}
.info-grid {
   display: flex;
   flex-wrap: wrap;
   padding: 16px;
}
.info-item {
   display: flex;
   width: 100%;
   margin-bottom: 12px;
   &:last-child {
      margin-bottom: 0;
   }
   .info-label {
      font-size: 14px;
      color: #999;
      min-width: 100px;
   }
   .info-value {
      font-size: 14px;
      color: #333;
      flex: 1;
   }
   .info-value.highlight {
      color: #2979ff;
      font-weight: 500;
   }
   .info-value.medium {
      font-size: 16px;
   }
}
.uploaded-list { padding: 8px 16px 0 16px; }
.uploaded-item { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f5f5f5; }
.file-name { font-size: 12px; color: #333; margin-right: 8px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-text { padding: 4px 16px 0 16px; font-size: 12px; color: #888; }
.footer-btns { position: fixed; left: 0; right: 0; bottom: 0; background: #fff; display: flex; justify-content: space-around; align-items: center; padding: 0.75rem 0; box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05); z-index: 1000; }
.cancel-btn { font-weight: 400; font-size: 1rem; color: #FFFFFF; width: 6.375rem; background: #C7C9CC; box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2); border-radius: 2.5rem 2.5rem 2.5rem 2.5rem; }
.save-btn { font-weight: 400; font-size: 1rem; color: #FFFFFF; width: 14rem; background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%); box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2); border-radius: 2.5rem 2.5rem 2.5rem 2.5rem; }
.footer-btns {
   position: fixed;
   left: 0;
   right: 0;
   bottom: 0;
   background: #fff;
   display: flex;
   justify-content: space-around;
   align-items: center;
   padding: 0.75rem 0;
   box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
   z-index: 1000;
}
.cancel-btn {
   font-weight: 400;
   font-size: 1rem;
   color: #FFFFFF;
   width: 6.375rem;
   background: #C7C9CC;
   box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
   border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
}
.save-btn {
   font-weight: 400;
   font-size: 1rem;
   color: #FFFFFF;
   width: 14rem;
   background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%);
   box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
   border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
}
</style>