gaoluyang
3 天以前 ee42bf1badae06026efa79dc17d2a541297ab49b
src/pages/equipmentManagement/ledger/detail.vue
@@ -1,128 +1,150 @@
<template>
   <view class="ledger-detail">
   <view class="account-detail">
      <!-- 使用通用页面头部组件 -->
      <PageHeader :title="operationType === 'edit' ? '编辑设备台账' : '新增设备台账'" @back="goBack" />
      <PageHeader title="设备台账详情" @back="goBack" />
      
      <!-- 表单内容 -->
      <van-form @submit="sendForm" ref="formRef" label-width="110px" input-align="right" error-message-align="right" scroll-to-error scroll-to-error-position="center">
      <u-form @submit="sendForm" ref="formRef" :model="form" :rules="formRules" label-width="110">
         <!-- 基本信息 -->
         <van-cell-group title="基本信息" inset>
            <van-field
               v-model="form.deviceName"
               label="设备名称"
               placeholder="请输入设备名称"
               :rules="formRules.deviceName"
               required
               clearable
            />
            <van-field
               v-model="form.deviceModel"
               label="规格型号"
               placeholder="请输入规格型号"
               :readonly="form.deviceModel != null && operationType === 'edit'"
               :rules="formRules.deviceModel"
               required
               clearable
            />
            <van-field
               v-model="form.supplierName"
               label="供应商"
               required
               placeholder="请输入供应商"
               :rules="formRules.supplierName"
               clearable
            />
            <van-field
               v-model="form.unit"
               label="单位"
               required
               placeholder="请输入单位"
               :rules="formRules.unit"
               clearable
            />
            <van-field
               v-model="form.taxRate"
               required
               label="税率(%)"
               placeholder="请选择"
               readonly
               :rules="formRules.taxRate"
               @click="showTaxRatePicker"
               clearable
            />
            <van-field
               v-model="form.number"
               label="数量"
               required
               type="number"
               placeholder="请输入数量"
               :rules="formRules.number"
               @blur="mathNum"
               clearable
            />
            <van-field
               v-model="form.taxIncludingPriceUnit"
               label="含税单价"
               required
               type="number"
               placeholder="请输入含税单价"
               :rules="formRules.taxIncludingPriceUnit"
               @blur="mathNum"
               clearable
            />
            <van-field
               v-model="form.taxIncludingPriceTotal"
               label="含税总价"
               placeholder="自动生成"
               readonly
            />
            <van-field
               v-model="form.unTaxIncludingPriceTotal"
               label="不含税总价"
               placeholder="自动生成"
               readonly
            />
            <van-field
               v-model="form.createTime"
               label="录入日期"
               placeholder="请选择"
               readonly
               @click="showDatePicker"
               required
               clearable
            />
         </van-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" :loading="loading">保存</van-button>
         </view>
      </van-form>
         <u-cell-group title="基本信息">
            <u-form-item label="设备名称" prop="deviceName" required border-bottom>
               <u-input
                  v-model="form.deviceName"
                  placeholder="请输入设备名称"
                  clearable
               />
            </u-form-item>
            <u-form-item label="规格型号" prop="deviceModel" required border-bottom>
               <u-input
                  v-model="form.deviceModel"
                  :disabled="(form.deviceModel != null && operationType === 'edit')"
                  placeholder="请输入规格型号"
                  clearable
               />
            </u-form-item>
            <!-- <u-form-item label="设备品牌" prop="deviceBrand" required border-bottom>
               <u-input
                  v-model="form.deviceBrand"
                  placeholder="请输入设备品牌"
                  clearable
               />
            </u-form-item> -->
            <u-form-item label="供应商" prop="supplierName" required border-bottom>
               <u-input
                  v-model="form.supplierName"
                  placeholder="请输入供应商"
                  clearable
               />
            </u-form-item>
            <!-- <u-form-item label="存放位置" prop="storageLocation" required border-bottom>
               <u-input
                  v-model="form.storageLocation"
                  placeholder="请输入存放位置"
                  clearable
               />
            </u-form-item> -->
            <u-form-item label="单位" prop="unit" required border-bottom>
               <u-input
                  v-model="form.unit"
                  placeholder="请输入单位"
                  clearable
               />
            </u-form-item>
            <!-- <u-form-item label="启用折旧" prop="enableDepreciation" required border-bottom>
               <u-switch
                  v-model="form.enableDepreciation"
                  :active-value="true"
                  :inactive-value="false"
               />
            </u-form-item> -->
            <u-form-item label="数量" prop="number" required border-bottom>
               <u-input
                  v-model="form.number"
                  type="number"
                  placeholder="请输入数量"
                  clearable
                  @blur="mathNum"
               />
            </u-form-item>
            <u-form-item label="含税单价" prop="taxIncludingPriceUnit" required border-bottom>
               <u-input
                  v-model="form.taxIncludingPriceUnit"
                  type="number"
                  placeholder="请输入含税单价"
                  clearable
                  @blur="mathNum"
               />
            </u-form-item>
            <u-form-item label="含税总价" prop="taxIncludingPriceTotal" required border-bottom>
               <u-input
                  v-model="form.taxIncludingPriceTotal"
                  type="number"
                  placeholder="自动生成"
                  disabled
               />
            </u-form-item>
            <u-form-item label="税率(%)" prop="taxRate" required border-bottom>
               <u-input
                  v-model="form.taxRate"
                  placeholder="请选择税率"
                  readonly
                  @click="showTaxRatePicker = true"
               />
               <template #right>
                  <u-icon name="arrow-right" @click="showTaxRatePicker = true"></u-icon>
               </template>
               <up-action-sheet
                  :show="showTaxRatePicker"
                  :actions="taxRateActionList"
                  title="选择税率"
                  @select="onTaxRateSelect"
                  @close="showTaxRatePicker = false"
               />
            </u-form-item>
            <u-form-item label="不含税总价" prop="unTaxIncludingPriceTotal" required border-bottom>
               <u-input
                  v-model="form.unTaxIncludingPriceTotal"
                  type="number"
                  placeholder="自动生成"
                  disabled
               />
            </u-form-item>
            <u-form-item label="录入日期" prop="createTime" required border-bottom>
               <u-input
                  v-model="form.createTime"
                  placeholder="请选择录入日期"
                  readonly
                  @click="showDatePicker"
                  clearable
               />
               <template #right>
                  <u-icon name="arrow-right" @click="showDatePicker"></u-icon>
               </template>
            </u-form-item>
         </u-cell-group>
      <!-- 提交按钮 -->
      <view class="footer-btns">
         <u-button class="cancel-btn" @click="goBack">取消</u-button>
         <u-button class="save-btn" type="primary" @click="sendForm" :loading="loading">保存</u-button>
      </view>
   </u-form>
      <!-- 税率选择器 -->
      <van-popup v-model:show="showTaxRate" position="bottom">
         <van-picker
            :model-value="taxRatePickerValue"
            :columns="taxRateOptions"
            @confirm="onTaxRateConfirm"
            @cancel="showTaxRate = false"
         />
      </van-popup>
      <!-- 日期选择器 -->
      <van-popup v-model:show="showDate" position="bottom">
         <van-date-picker
            v-model="currentDate"
            title="选择日期"
   <!-- 日期选择器 -->
<up-datetime-picker
            :show="showDate"
            v-model="pickerDateValue"
            @confirm="onDateConfirm"
            @cancel="showDate = false"
            mode="date"
         />
      </van-popup>
   </view>
</view>
</template>
<script setup>
// 替换 Vant 的 toast
// import { showToast } from 'vant';
import { ref, computed, onMounted } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import PageHeader from '@/components/PageHeader.vue';
@@ -132,7 +154,12 @@
   calculateTaxIncludeTotalPrice,
   calculateTaxExclusiveTotalPrice,
} from "@/utils/summarizeTable";
import { showToast } from 'vant';
const showToast = (message) => {
   uni.showToast({
      title: message,
      icon: 'none'
   })
}
defineOptions({
   name: "设备台账表单",
@@ -142,28 +169,75 @@
const formRef = ref(null);
const operationType = ref('');
const loading = ref(false);
const showTaxRate = ref(false);
const taxRatePickerValue = ref([]);
const showDate = ref(false);
const currentDate = ref([new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()]);
const pickerDateValue = ref(Date.now());
const showTaxRatePicker = ref(false);
const taxRateActionList = ref([
  { name: '1', value: 1 },
  { name: '6', value: 6 },
  { name: '13', value: 13 }
]);
// 表单验证规则
const formRules = {
   deviceName: [{ required: true, trigger: "blur", message: "请输入" }],
   deviceModel: [{ required: true, trigger: "blur", message: "请输入" }],
   deviceBrand: [{ required: true, trigger: "blur", message: "请输入" }],
   supplierName: [{ required: true, trigger: "blur", message: "请输入" }],
   storageLocation: [{ required: true, trigger: "blur", message: "请输入" }],
   unit: [{ required: true, trigger: "blur", message: "请输入" }],
   number: [{ required: true, trigger: "blur", message: "请输入" }],
   taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "请输入" }],
   taxRate: [{ required: true, trigger: "change", message: "请输入" }],
   // 数字类型字段需要特殊处理,确保有数值时不会触发必填校验
   number: [{
      required: true,
      trigger: "blur",
      message: "请输入",
      validator: (rule, value, callback) => {
         // 对于数字类型,检查是否为有效数字(包括0)
         if (value !== undefined && value !== null && value !== '' && !isNaN(value)) {
            callback();
         } else {
            callback(new Error('请输入数量'));
         }
      }
   }],
   taxIncludingPriceUnit: [{
      required: true,
      trigger: "blur",
      message: "请输入",
      validator: (rule, value, callback) => {
         // 对于数字类型,检查是否为有效数字(包括0)
         if (value !== undefined && value !== null && value !== '' && !isNaN(value)) {
            callback();
         } else {
            callback(new Error('请输入含税单价'));
         }
      }
   }],
   taxRate: [{
      required: true,
      trigger: "change",
      message: "请选择",
      validator: (rule, value, callback) => {
         // 检查税率是否为有效数字
         if (value !== undefined && value !== null && value !== '' && !isNaN(value)) {
            callback();
         } else {
            callback(new Error('请选择税率'));
         }
      }
   }],
   createTime: [{ required: true, trigger: "change", message: "请选择" }],
};
// 使用 ref 声明表单数据
const form = ref({
   deviceName: undefined, // 设备名称
   deviceModel: undefined, // 规格型号
   deviceBrand: undefined, // 设备品牌
   supplierName: undefined, // 供应商
   storageLocation: undefined, // 存放位置
   unit: undefined, // 单位
   enableDepreciation: false, // 启用折旧
   number: undefined, // 数量
   taxIncludingPriceUnit: undefined, // 含税单价
   taxIncludingPriceTotal: undefined, // 含税总价
@@ -172,14 +246,7 @@
   createTime: dayjs().format("YYYY-MM-DD"), // 录入日期
});
// 税率选项
const taxRateOptions = computed(() => {
   return [
      { text: '1', value: 1 },
      { text: '6', value: 6 },
      { text: '13', value: 13 }
   ]
});
// 加载表单数据
const loadForm = async (id) => {
@@ -188,17 +255,27 @@
   }
   try {
      const { code, data } = await getLedgerById(id);
      console.log(data);
      if (code == 200) {
         form.value.deviceName = data.deviceName;
         form.value.deviceModel = data.deviceModel;
         form.value.deviceBrand = data.deviceBrand || '';
         form.value.supplierName = data.supplierName;
         form.value.storageLocation = data.storageLocation || '';
         form.value.unit = data.unit;
         form.value.enableDepreciation = !!data.enableDepreciation;
         form.value.number = data.number;
         form.value.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
         form.value.taxIncludingPriceTotal = data.taxIncludingPriceTotal;
         form.value.taxRate = data.taxRate;
         form.value.unTaxIncludingPriceTotal = data.unTaxIncludingPriceTotal;
         form.value.createTime = data.createTime;
         // 数据加载完成后,重置表单验证状态
         setTimeout(() => {
            clearValidate();
         }, 100);
      }
   } catch (e) {
      showToast('获取详情失败');
@@ -207,11 +284,12 @@
// 数学计算
const mathNum = () => {
   if (!form.value.taxIncludingPriceUnit) {
   // 只有在新增模式或者字段确实为空时才显示提示
   if (operationType.value !== 'edit' || (form.value.taxIncludingPriceUnit === undefined || form.value.taxIncludingPriceUnit === '')) {
      showToast("请输入单价");
      return;
   }
   if (!form.value.number) {
   if (operationType.value !== 'edit' || (form.value.number === undefined || form.value.number === '')) {
      showToast("请输入数量");
      return;
   }
@@ -232,44 +310,65 @@
   formRef.value?.clearValidate();
};
// 重置表单数据和校验状态
const resetForm = () => {
   form.value = {
      deviceName: undefined,
      deviceModel: undefined,
      supplierName: undefined,
      unit: undefined,
      number: undefined,
      taxIncludingPriceUnit: undefined,
      taxIncludingPriceTotal: undefined,
      taxRate: undefined,
      unTaxIncludingPriceTotal: undefined,
      createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
   };
};
const resetFormAndValidate = () => {
   resetForm();
   clearValidate();
};
// 提交表单
const sendForm = async () => {
   try {
      // 手动验证表单
      await formRef.value?.validate();
      // 检查必填字段
      let isValid = true;
      let errorMessage = '';
      // 检查文本类型必填字段
      if (!form.value.deviceName || form.value.deviceName.trim() === '') {
         isValid = false;
         errorMessage = '请输入设备名称';
      } else if (!form.value.deviceModel || form.value.deviceModel.trim() === '') {
         isValid = false;
         errorMessage = '请输入规格型号';
      } else if (!form.value.deviceBrand || form.value.deviceBrand.trim() === '') {
         isValid = false;
         errorMessage = '请输入设备品牌';
      } else if (!form.value.supplierName || form.value.supplierName.trim() === '') {
         isValid = false;
         errorMessage = '请输入供应商';
      } else if (!form.value.storageLocation || form.value.storageLocation.trim() === '') {
         isValid = false;
         errorMessage = '请输入存放位置';
      } else if (!form.value.unit || form.value.unit.trim() === '') {
         isValid = false;
         errorMessage = '请输入单位';
      }
      // 检查数字类型必填字段
      else if (form.value.number === undefined || form.value.number === null || form.value.number === '' || isNaN(form.value.number)) {
         isValid = false;
         errorMessage = '请输入数量';
      } else if (form.value.taxIncludingPriceUnit === undefined || form.value.taxIncludingPriceUnit === null || form.value.taxIncludingPriceUnit === '' || isNaN(form.value.taxIncludingPriceUnit)) {
         isValid = false;
         errorMessage = '请输入含税单价';
      } else if (form.value.taxRate === undefined || form.value.taxRate === null || form.value.taxRate === '' || isNaN(form.value.taxRate)) {
         isValid = false;
         errorMessage = '请选择税率';
      } else if (!form.value.createTime || form.value.createTime.trim() === '') {
         isValid = false;
         errorMessage = '请选择录入日期';
      }
      // 如果验证失败,显示错误提示
      if (!isValid) {
         showToast(errorMessage);
         return;
      }
      // 验证通过,显示提交中提示
      showToast('正在提交表单...');
      
      loading.value = true;
      const id = getPageId();
      
      // 准备提交数据,createTime 加上当前时分秒
      const submitData = { ...form.value };
      if (submitData.createTime && !submitData.createTime.includes(':')) {
         // 如果 createTime 只包含日期,添加当前时分秒
         submitData.createTime = submitData.createTime + ' ' + dayjs().format('HH:mm:ss');
      }
      
      const { code } = id
      const { code, res } = id
         ? await editLedger({ id: id, ...submitData })
         : await addLedger(submitData);
      
@@ -280,51 +379,58 @@
         }, 1500);
      } else {
         loading.value = false;
         console.log(res);
      }
   } catch (e) {
      loading.value = false;
      showToast('表单验证失败');
      showToast('提交失败');
   }
};
// 返回上一页
const goBack = () => {
   // 使用后清除storage中的ID,避免数据残留
         uni.removeStorageSync('ledgerId');
   uni.navigateBack();
};
// 获取页面参数
const getPageParams = () => {
   const pages = getCurrentPages();
   const currentPage = pages[pages.length - 1];
   const options = currentPage.options;
   if (options.id) {
      // 编辑模式,获取详情
      loadForm(options.id);
   } else {
      // 新增模式
   try {
      // 优先从storage中获取ID
      const ledgerId = uni.getStorageSync('ledgerId');
      if (ledgerId) {
         // 编辑模式,获取详情
         loadForm(ledgerId);
      } else {
         // 新增模式
         operationType.value = 'add';
      }
   } catch (e) {
      operationType.value = 'add';
   }
};
// 获取页面ID
const getPageId = () => {
   const pages = getCurrentPages();
   const currentPage = pages[pages.length - 1];
   const options = currentPage.options;
   return options.id;
   try {
      // 优先从storage中获取ID
      const ledgerId = uni.getStorageSync('ledgerId');
      if (ledgerId) {
         return ledgerId;
      }
   } catch (e) {
      console.error('获取页面ID出错:', e);
   }
   return null;
};
// 显示税率选择器
const showTaxRatePicker = () => {
   showTaxRate.value = true;
};
// 确认税率选择
const onTaxRateConfirm = ({ selectedValues, selectedOptions }) => {
   form.value.taxRate = selectedOptions[0].value;
   taxRatePickerValue.value = selectedValues;
   showTaxRate.value = false;
// 选择税率
const onTaxRateSelect = (e) => {
   form.value.taxRate = e.value;
   showTaxRatePicker.value = false;
   mathNum(); // 重新计算
};
@@ -334,10 +440,12 @@
};
// 确认日期选择
const onDateConfirm = ({ selectedValues }) => {
const onDateConfirm = (e) => {
   // 只保存年月日,不包含时分秒
   form.value.createTime = selectedValues.join('-');
   currentDate.value = selectedValues;
   const date = new Date(e.value);
   form.value.createTime = date.getFullYear() + '-' +
      String(date.getMonth() + 1).padStart(2, '0') + '-' +
      String(date.getDate()).padStart(2, '0');
   showDate.value = false;
};
@@ -353,6 +461,7 @@
</script>
<style scoped lang="scss">
@import '@/static/scss/form-common.scss';
.ledger-detail {
   min-height: 100vh;
   background: #f8f9fa;