gaoluyang
13 小时以前 31c32afd520773cba392003c8e2743827fb9ccac
Merge remote-tracking branch 'origin/dev_new' into dev_new
已修改2个文件
2220 ■■■■ 文件已修改
src/pages/sales/salesAccount/detail.vue 1883 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/salesAccount/view.vue 337 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/salesAccount/detail.vue
@@ -1,230 +1,213 @@
<template>
  <view class="account-detail">
    <!-- 使用通用页面头部组件 -->
        <PageHeader title="台账详情" @back="goBack" />
         <!-- 表单区域 -->
        <up-form @submit="onSubmit" label-width="110" ref="formRef" :rules="rules" :model="form">
            <up-form-item label="销售合同号" prop="salesContractNo" >
                <up-input v-model="form.salesContractNo" placeholder="自动生成" disabled />
            </up-form-item>
            <up-form-item
                label="业务员"
                prop="salesman"
                required
                @click="showPicker = true"
            >
                <up-input
                    v-model="form.salesman"
                    readonly
                    @click="showPicker = true"
                    placeholder="点击选择业务员"
                />
                <template #right>
                    <up-icon
                        name="arrow-right"
                        @click="showPicker = true"
                    ></up-icon>
                </template>
            </up-form-item>
            <up-form-item label="客户合同号" prop="customerContractNo" required >
                <up-input
                    v-model="form.customerContractNo"
                    placeholder="请输入客户合同号"
                />
            </up-form-item>
            <up-form-item
                label="客户名称"
                prop="customerName"
                required
            >
                <up-input
                    v-model="form.customerName"
                    readonly
                    placeholder="点击选择客户"
                    @click="showCustomerPicker = true"
                />
                <template #right>
                    <up-icon
                        name="arrow-right"
                        @click="showCustomerPicker = true"
                    ></up-icon>
                </template>
            </up-form-item>
            <up-form-item label="项目名称" prop="projectName" required >
                <up-input v-model="form.projectName" placeholder="请输入项目名称" />
            </up-form-item>
            <up-form-item
                label="签订日期"
                prop="executionDate"
                required
            >
                <up-input
                    v-model="form.executionDate"
                    readonly
                    placeholder="点击选择时间"
                    @click="showDatePicker = true"
                />
                <template #right>
                    <up-icon
                        name="arrow-right"
                        @click="showDatePicker = true"
                    ></up-icon>
                </template>
            </up-form-item>
            <up-form-item label="付款方式" prop="paymentMethod" >
                <up-input v-model="form.paymentMethod" placeholder="请输入付款方式" />
            </up-form-item>
            <up-form-item label="录入人" prop="entryPersonName" >
                <up-input v-model="form.entryPersonName" placeholder="请输入" disabled />
            </up-form-item>
            <up-form-item label="录入日期" prop="entryDate" >
                <up-input v-model="form.entryDate" placeholder="请输入" disabled />
            </up-form-item>
            <!-- 业务员选择 -->
            <up-action-sheet
                :show="showPicker"
                :actions="userActionList"
                title="选择业务员"
                @select="onSalesmanSelect"
                @close="showPicker = false"
            />
            <!-- 日期选择 -->
            <up-popup :show="showDatePicker" mode="bottom" @close="showDatePicker = false">
                <up-datetime-picker
                    :show="true"
                    v-model="pickerDateValue"
                    @confirm="onDateConfirm"
                    @cancel="showDatePicker = false"
                    mode="date"
                />
            </up-popup>
            <!-- 客户选择 -->
            <up-action-sheet
                :show="showCustomerPicker"
                :actions="customerActionList"
                title="选择客户"
                @select="onCustomerSelect"
                @close="showCustomerPicker = false"
            />
            <!-- 产品大类选择器 -->
            <up-popup :show="showCategoryPicker" mode="bottom">
                <!-- 头部按钮区域 -->
                <view class="popup-header">
                    <view @click="showCategoryPicker = false" class="cancelButton">取消</view>
                    <view @click="confirmCategorySelection" class="confirmButton">确定</view>
                </view>
                <u-tree
                    :data="productOptions"
                    :props="defaultProps"
                    show-checkbox
                    default-expand-all
                    check-strictly
                    @check-change="onCategoryConfirm"
                />
            </up-popup>
            <!-- 规格型号选择器 -->
            <up-action-sheet
                :show="showSpecificationPicker"
                :actions="specificationActionList"
                title="选择规格型号"
                @select="onSpecificationSelect"
                @close="showSpecificationPicker = false"
            />
            <!-- 税率选择器 -->
            <up-action-sheet
                :show="showTaxRatePicker"
                :actions="taxRateActionList"
                title="选择税率"
                @select="onTaxRateSelect"
                @close="showTaxRatePicker = false"
            />
            <!-- 发票类型选择器 -->
            <up-action-sheet
                :show="showInvoiceTypePicker"
                :actions="invoiceTypeActionList"
                title="选择发票类型"
                @select="onInvoiceTypeSelect"
                @close="showInvoiceTypePicker = false"
            />
            <!-- 产品信息 -->
            <view class="product-section">
                <view class="section-header">
                    <view>
                        <text class="section-title">产品信息</text>
                    </view>
                    <view>
                        <up-button type="primary" size="small" @click="addProduct" class="add-btn" v-if="operationType !== 'view'">
                            新增
                        </up-button>
                    </view>
                </view>
                <view class="product-card" v-for="(product, idx) in productData" :key="idx">
                    <!-- 产品类 -->
                    <view class="product-header">
                        <view class="product-title">
                            <view class="document-icon">
                                <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
                            </view>
                            <text class="product-productCategory">产品 {{ idx + 1 }}</text>
                        </view>
                        <!-- 操作按钮 -->
                        <view class="product-actions" v-if="operationType !== 'view'">
                            <up-button type="error" size="mini" @click="removeProduct(idx)" class="del-btn">
                                删除
                            </up-button>
                        </view>
                    </view>
                    <!-- 产品信息表单 -->
                    <view class="product-form">
                        <!-- 产品大类 -->
                        <up-form-item
                            label="产品大类"
                            prop="productCategory"
                            required
                        >
                            <up-input
                                v-model="product.productCategory"
                                readonly
                                placeholder="请选择"
                                @click="openCategoryPicker(idx)"
                            />
                            <template #right>
                                <up-icon
                                    name="arrow-right"
                                    @click="showCategoryPicker = true"
                                ></up-icon>
                            </template>
                        </up-form-item>
                        <!-- 规格型号 -->
                        <up-form-item
                            label="规格型号"
                            prop="specificationModel"
                            required
                        >
                            <up-input
                                v-model="product.specificationModel"
                                readonly
                                placeholder="请选择"
                                @click="openSpecificationPicker(idx)"
                            />
                            <template #right>
                                <up-icon
                                    name="arrow-right"
                                    @click="showSpecificationPicker = true"
                                ></up-icon>
                            </template>
                        </up-form-item>
                        <!-- 绑定机器 -->
                        <up-form-item
    <PageHeader title="台账详情"
                @back="goBack" />
    <!-- 表单区域 -->
    <up-form @submit="onSubmit"
             label-width="110"
             ref="formRef"
             :rules="rules"
             :model="form">
      <up-form-item label="销售合同号"
                    prop="salesContractNo">
        <up-input v-model="form.salesContractNo"
                  placeholder="自动生成"
                  disabled />
      </up-form-item>
      <up-form-item label="业务员"
                    prop="salesman"
                    required
                    @click="showPicker = true">
        <up-input v-model="form.salesman"
                  readonly
                  @click="showPicker = true"
                  placeholder="点击选择业务员" />
        <template #right>
          <up-icon name="arrow-right"
                   @click="showPicker = true"></up-icon>
        </template>
      </up-form-item>
      <up-form-item label="客户合同号"
                    prop="customerContractNo"
                    required>
        <up-input v-model="form.customerContractNo"
                  placeholder="请输入客户合同号" />
      </up-form-item>
      <up-form-item label="客户名称"
                    prop="customerName"
                    required>
        <up-input v-model="form.customerName"
                  readonly
                  placeholder="点击选择客户"
                  @click="showCustomerPicker = true" />
        <template #right>
          <up-icon name="arrow-right"
                   @click="showCustomerPicker = true"></up-icon>
        </template>
      </up-form-item>
      <up-form-item label="项目名称"
                    prop="projectName"
                    required>
        <up-input v-model="form.projectName"
                  placeholder="请输入项目名称" />
      </up-form-item>
      <up-form-item label="签订日期"
                    prop="executionDate"
                    required>
        <up-input v-model="form.executionDate"
                  readonly
                  placeholder="点击选择时间"
                  @click="showDatePicker = true" />
        <template #right>
          <up-icon name="arrow-right"
                   @click="showDatePicker = true"></up-icon>
        </template>
      </up-form-item>
      <up-form-item label="付款方式"
                    prop="paymentMethod">
        <up-input v-model="form.paymentMethod"
                  placeholder="请输入付款方式" />
      </up-form-item>
      <up-form-item label="录入人"
                    prop="entryPersonName">
        <up-input v-model="form.entryPersonName"
                  placeholder="请输入"
                  disabled />
      </up-form-item>
      <up-form-item label="录入日期"
                    prop="entryDate">
        <up-input v-model="form.entryDate"
                  placeholder="请输入"
                  disabled />
      </up-form-item>
      <!-- 业务员选择 -->
      <up-action-sheet :show="showPicker"
                       :actions="userActionList"
                       title="选择业务员"
                       @select="onSalesmanSelect"
                       @close="showPicker = false" />
      <!-- 日期选择 -->
      <up-popup :show="showDatePicker"
                mode="bottom"
                @close="showDatePicker = false">
        <up-datetime-picker :show="true"
                            v-model="pickerDateValue"
                            @confirm="onDateConfirm"
                            @cancel="showDatePicker = false"
                            mode="date" />
      </up-popup>
      <!-- 客户选择 -->
      <up-action-sheet :show="showCustomerPicker"
                       :actions="customerActionList"
                       title="选择客户"
                       @select="onCustomerSelect"
                       @close="showCustomerPicker = false" />
      <!-- 产品大类选择器 -->
      <up-popup :show="showCategoryPicker"
                mode="bottom">
        <!-- 头部按钮区域 -->
        <view class="popup-header">
          <view @click="showCategoryPicker = false"
                class="cancelButton">取消</view>
          <view @click="confirmCategorySelection"
                class="confirmButton">确定</view>
        </view>
        <u-tree :data="productOptions"
                :props="defaultProps"
                show-checkbox
                default-expand-all
                check-strictly
                @check-change="onCategoryConfirm" />
      </up-popup>
      <!-- 规格型号选择器 -->
      <up-action-sheet :show="showSpecificationPicker"
                       :actions="specificationActionList"
                       title="选择规格型号"
                       @select="onSpecificationSelect"
                       @close="showSpecificationPicker = false" />
      <!-- 税率选择器 -->
      <up-action-sheet :show="showTaxRatePicker"
                       :actions="taxRateActionList"
                       title="选择税率"
                       @select="onTaxRateSelect"
                       @close="showTaxRatePicker = false" />
      <!-- 发票类型选择器 -->
      <up-action-sheet :show="showInvoiceTypePicker"
                       :actions="invoiceTypeActionList"
                       title="选择发票类型"
                       @select="onInvoiceTypeSelect"
                       @close="showInvoiceTypePicker = false" />
      <!-- 产品信息 -->
      <view class="product-section">
        <view class="section-header">
          <view>
            <text class="section-title">产品信息</text>
          </view>
          <view>
            <up-button type="primary"
                       size="small"
                       @click="addProduct"
                       class="add-btn"
                       v-if="operationType !== 'view'">
              新增
            </up-button>
          </view>
        </view>
        <view class="product-card"
              v-for="(product, idx) in productData"
              :key="idx">
          <!-- 产品类 -->
          <view class="product-header">
            <view class="product-title">
              <view class="document-icon">
                <up-icon name="file-text"
                         size="16"
                         color="#ffffff"></up-icon>
              </view>
              <text class="product-productCategory">产品 {{ idx + 1 }}</text>
            </view>
            <!-- 操作按钮 -->
            <view class="product-actions"
                  v-if="operationType !== 'view'">
              <up-button type="error"
                         size="mini"
                         @click="removeProduct(idx)"
                         class="del-btn">
                删除
              </up-button>
            </view>
          </view>
          <!-- 产品信息表单 -->
          <view class="product-form">
            <!-- 产品大类 -->
            <up-form-item label="产品大类"
                          prop="productCategory"
                          required>
              <up-input v-model="product.productCategory"
                        readonly
                        placeholder="请选择"
                        @click="openCategoryPicker(idx)" />
              <template #right>
                <up-icon name="arrow-right"
                         @click="showCategoryPicker = true"></up-icon>
              </template>
            </up-form-item>
            <!-- 规格型号 -->
            <up-form-item label="规格型号"
                          prop="specificationModel"
                          required>
              <up-input v-model="product.specificationModel"
                        readonly
                        placeholder="请选择"
                        @click="openSpecificationPicker(idx)" />
              <template #right>
                <up-icon name="arrow-right"
                         @click="showSpecificationPicker = true"></up-icon>
              </template>
            </up-form-item>
            <!-- 绑定机器 -->
            <!-- <up-form-item
                            label="绑定机器"
                            prop="speculativeTradingName"
                            required
@@ -234,760 +217,730 @@
                                v-model="product.speculativeTradingName"
                                placeholder="请输入"
                            />
                        </up-form-item>
                        <!-- 单位 -->
                        <up-form-item
                            label="单位"
                            prop="unit"
                            required
                        >
                            <up-input
                                v-model="product.unit"
                                placeholder="请输入"
                            />
                        </up-form-item>
                        <!-- 税率 -->
                        <up-form-item
                            label="税率(%)"
                            prop="taxRate"
                            required
                        >
                            <up-input
                                v-model="product.taxRate"
                                readonly
                                placeholder="请选择"
                                @click="openTaxRatePicker(idx)"
                            />
                            <template #right>
                                <up-icon
                                    name="arrow-right"
                                    @click="showTaxRatePicker = true"
                                ></up-icon>
                            </template>
                        </up-form-item>
                        <!-- 含税单价 -->
                        <up-form-item
                            label="含税单价(元)"
                            prop="taxInclusiveUnitPrice"
                            required
                        >
                            <up-input
                                v-model="product.taxInclusiveUnitPrice"
                                type="number"
                                placeholder="请输入"
                                @blur="formatTaxPrice(idx)"
                            />
                        </up-form-item>
                        <!-- 数量 -->
                        <up-form-item
                            label="数量"
                            prop="quantity"
                            required
                        >
                            <up-input
                                v-model="product.quantity"
                                type="number"
                                placeholder="请输入"
                                @blur="formatAmount(idx)"
                            />
                        </up-form-item>
                        <!-- 含税总价 -->
                        <up-form-item
                            label="含税总价(元)"
                            prop="taxInclusiveTotalPrice"
                            required
                        >
                            <up-input
                                v-model="product.taxInclusiveTotalPrice"
                                type="number"
                                placeholder="请输入"
                                @blur="formatTaxTotal(idx)"
                            />
                        </up-form-item>
                        <!-- 不含税总价 -->
                        <up-form-item
                            label="不含税总价(元)"
                            prop="taxExclusiveTotalPrice"
                            required
                        >
                            <up-input
                                v-model="product.taxExclusiveTotalPrice"
                                type="number"
                                placeholder="请输入"
                                @blur="formatNoTaxTotal(idx)"
                            />
                        </up-form-item>
                        <!-- 发票类型 -->
                        <up-form-item
                            label="发票类型"
                            prop="invoiceType"
                            required
                        >
                            <up-input
                                v-model="product.invoiceType"
                                readonly
                                placeholder="请选择"
                                @click="openInvoiceTypePicker(idx)"
                            />
                            <template #right>
                                <up-icon
                                    name="arrow-right"
                                    @click="showInvoiceTypePicker = true"
                                ></up-icon>
                            </template>
                        </up-form-item>
                    </view>
                </view>
            </view>
        </up-form>
        <!-- 使用公共底部按钮组件 -->
        <FooterButtons
            :show="operationType !== 'view'"
            cancelText="取消"
            confirmText="保存"
            @cancel="goBack"
            @confirm="onSubmit"
        />
                        </up-form-item> -->
            <!-- 单位 -->
            <up-form-item label="单位"
                          prop="unit"
                          required>
              <up-input v-model="product.unit"
                        placeholder="请输入" />
            </up-form-item>
            <!-- 税率 -->
            <up-form-item label="税率(%)"
                          prop="taxRate"
                          required>
              <up-input v-model="product.taxRate"
                        readonly
                        placeholder="请选择"
                        @click="openTaxRatePicker(idx)" />
              <template #right>
                <up-icon name="arrow-right"
                         @click="showTaxRatePicker = true"></up-icon>
              </template>
            </up-form-item>
            <!-- 含税单价 -->
            <up-form-item label="含税单价(元)"
                          prop="taxInclusiveUnitPrice"
                          required>
              <up-input v-model="product.taxInclusiveUnitPrice"
                        type="number"
                        placeholder="请输入"
                        @blur="formatTaxPrice(idx)" />
            </up-form-item>
            <!-- 数量 -->
            <up-form-item label="数量"
                          prop="quantity"
                          required>
              <up-input v-model="product.quantity"
                        type="number"
                        placeholder="请输入"
                        @blur="formatAmount(idx)" />
            </up-form-item>
            <!-- 含税总价 -->
            <up-form-item label="含税总价(元)"
                          prop="taxInclusiveTotalPrice"
                          required>
              <up-input v-model="product.taxInclusiveTotalPrice"
                        type="number"
                        placeholder="请输入"
                        @blur="formatTaxTotal(idx)" />
            </up-form-item>
            <!-- 不含税总价 -->
            <up-form-item label="不含税总价(元)"
                          prop="taxExclusiveTotalPrice"
                          required>
              <up-input v-model="product.taxExclusiveTotalPrice"
                        type="number"
                        placeholder="请输入"
                        @blur="formatNoTaxTotal(idx)" />
            </up-form-item>
            <!-- 发票类型 -->
            <up-form-item label="发票类型"
                          prop="invoiceType"
                          required>
              <up-input v-model="product.invoiceType"
                        readonly
                        placeholder="请选择"
                        @click="openInvoiceTypePicker(idx)" />
              <template #right>
                <up-icon name="arrow-right"
                         @click="showInvoiceTypePicker = true"></up-icon>
              </template>
            </up-form-item>
          </view>
        </view>
      </view>
    </up-form>
    <!-- 使用公共底部按钮组件 -->
    <FooterButtons :show="operationType !== 'view'"
                   cancelText="取消"
                   confirmText="保存"
                   @cancel="goBack"
                   @confirm="onSubmit" />
  </view>
</template>
<script setup>
import {onMounted, ref, computed} from 'vue';
import {userListNoPage} from "@/api/system/user";
import { formatDateToYMD } from '@/utils/ruoyi'
import {
    addOrUpdateSalesLedger,
    customerList,
    getSalesLedgerWithProducts,
    modelList,
    productTreeList
} from "@/api/salesManagement/salesLedger";
import useUserStore from "@/store/modules/user";
import {calculateTaxExclusiveTotalPrice} from "@/utils/summarizeTable";
import PageHeader from '@/components/PageHeader.vue';
import FooterButtons from '@/components/FooterButtons.vue';
  import { onMounted, ref, computed } from "vue";
  import { userListNoPage } from "@/api/system/user";
  import { formatDateToYMD } from "@/utils/ruoyi";
  import {
    addOrUpdateSalesLedger,
    customerList,
    getSalesLedgerWithProducts,
    modelList,
    productTreeList,
  } from "@/api/salesManagement/salesLedger";
  import useUserStore from "@/store/modules/user";
  import { calculateTaxExclusiveTotalPrice } from "@/utils/summarizeTable";
  import PageHeader from "@/components/PageHeader.vue";
  import FooterButtons from "@/components/FooterButtons.vue";
// 获取页面参数
const operationType = ref('');
const editData = ref(null);
const formRef = ref(null);
  // 获取页面参数
  const operationType = ref("");
  const editData = ref(null);
  const formRef = ref(null);
const userStore = useUserStore()
const form = ref({
    id: '',
  salesContractNo: '',
    customerContractNo: '',
    customerId: '',
    customerName: '',
    projectName: '',
    executionDate: '',
  paymentMethod: '',
    entryPerson: '',
    entryPersonName: '',
    entryDate: '',
});
const showPicker = ref(false);
const showDatePicker = ref(false);
const pickerDateValue = ref(Date.now());
const showCustomerPicker = ref(false);
const userList = ref([]);
const customerOption = ref([]);
const userActionList = computed(() => {
    return userList.value.map(user => ({
        name: user.text,
        value: user.value
    }))
})
const formatter = (type, value) => {
    if (type === 'year') {
        return `${value}`;
    }
    if (type === 'month') {
        return `${value}`;
    }
    if (type === 'day') {
        return `${value}`;
    }
    return value;
};
const customerActionList = computed(() => {
    return customerOption.value.map(customer => ({
        name: customer.text,
        value: customer.value
    }))
})
// 日期选择列表已移除,改用 up-datetime-picker
// 产品大类选择列表
const categoryActionList = computed(() => {
    const flattenCategories = (categories, result = []) => {
        categories.forEach(category => {
            result.push({
                name: category.label,
                value: category.id
            })
            if (category.children && category.children.length > 0) {
                flattenCategories(category.children, result)
            }
        })
        return result
    }
    return flattenCategories(productOptions.value)
})
// 规格型号选择列表
const specificationActionList = computed(() => {
    return modelOptions.value.map(model => ({
        name: model.text,
        value: model.value,
        unit: model.unit,
        speculativeTradingName: model.speculativeTradingName
    }))
})
// 税率选择列表
const taxRateActionList = computed(() => {
    return taxRateOptions.value.map(rate => ({
        name: rate.text,
        value: rate.value
    }))
})
// 发票类型选择列表
const invoiceTypeActionList = computed(() => {
    return invoiceTypeOptions.value.map(type => ({
        name: type.text,
        value: type.value
    }))
})
const productData = ref([]);
// 选择器相关变量
const showCategoryPicker = ref(false);
const showSpecificationPicker = ref(false);
const showTaxRatePicker = ref(false);
const showInvoiceTypePicker = ref(false);
// 选择器显示状态变量已在上面定义
// 临时变量已不再需要
const currentProductIndex = ref(0);
// 选项数据
const productOptions = ref([]);
const selectedCategoryNode = ref(null);
const defaultProps = ref({
    children: 'children',
    label: 'label',
    nodeKey: 'id'
});
const modelOptions = ref([]);
// 防止循环计算的标志
// const isCalculating = ref(false);
const taxRateOptions = ref([
  { text: '1', value: '1' },
  { text: '6', value: '6' },
  { text: '13', value: '13' },
]);
const invoiceTypeOptions = ref([
  { text: '增普票', value: '增普票' },
  { text: '增专票', value: '增专票' },
]);
// 表单校验规则
const rules = {
    salesman: [
        { required: true, message: '请选择业务员', trigger: 'change' }
    ],
    customerContractNo: [
        { required: true, message: '请输入客户合同号', trigger: 'blur' }
    ],
    customerName: [
        { required: true, message: '请选择客户名称', trigger: 'change' }
    ],
    projectName: [
        { required: true, message: '请输入项目名称', trigger: 'blur' }
    ],
    executionDate: [
        { required: true, message: '请选择签订日期', trigger: 'change' }
    ]
};
const addProduct = () => {
    if (productData.value === null) {
        productData.value = []
    }
    productData.value.push({
    productCategory: '',
    specificationModel: '',
        productModelId: '',
    unit: '',
    speculativeTradingName: '',
    taxRate: '',
    taxInclusiveUnitPrice: '',
    quantity: '',
    taxInclusiveTotalPrice: '',
    taxExclusiveTotalPrice: '',
    invoiceType: ''
  const userStore = useUserStore();
  const form = ref({
    id: "",
    salesContractNo: "",
    customerContractNo: "",
    customerId: "",
    customerName: "",
    projectName: "",
    executionDate: "",
    paymentMethod: "",
    entryPerson: "",
    entryPersonName: "",
    entryDate: "",
  });
};
// 业务员选择事件
const onSalesmanSelect = (item) => {
    form.value.salesman = item.name
}
// 日期确认事件
const onDateConfirm = (e) => {
    form.value.executionDate = formatDateToYMD(e.value)
    // 保持pickerDateValue为时间戳格式,而不是格式化的字符串
    pickerDateValue.value = e.value
    showDatePicker.value = false;
}
// 客户选择事件
const onCustomerSelect = (item) => {
    form.value.customerName = item.name
    form.value.customerId = item.value
}
// 原有的确认方法已被新的action-sheet选择方法替代
const removeProduct = (idx) => {
    productData.value.splice(idx, 1);
};
// 显示选择器
const openCategoryPicker = (idx) => {
  currentProductIndex.value = idx;
  showCategoryPicker.value = true;
};
const openSpecificationPicker = (idx) => {
  currentProductIndex.value = idx;
  showSpecificationPicker.value = true;
};
const openTaxRatePicker = (idx) => {
  currentProductIndex.value = idx;
  showTaxRatePicker.value = true;
};
const openInvoiceTypePicker = (idx) => {
  currentProductIndex.value = idx;
  showInvoiceTypePicker.value = true;
};
// 选择器确认事件
const onCategoryConfirm = (node) => {
    // 获取选中的节点信息
    console.log('selected node---', node);
    // 存储选中的节点,用于确认时获取数据
    selectedCategoryNode.value = node;
};
// 确认产品大类选择
const confirmCategorySelection = () => {
    if (selectedCategoryNode.value) {
        // 设置选中的产品大类
        productData.value[currentProductIndex.value].productCategory = selectedCategoryNode.value.label;
        const id = selectedCategoryNode.value.id
        // 重置选中的节点
        selectedCategoryNode.value = null;
        productData.value[currentProductIndex.value].specificationModel = ''
        productData.value[currentProductIndex.value].productModelId = ''
        getModels(id)
    }
    showCategoryPicker.value = false;
};
// 获取规格型号
const getModels = (value) => {
    modelList({ id: value }).then((res) => {
        modelOptions.value = res.map(user => ({
            text: user.model,
            value: user.id,
            unit: user.unit,
            speculativeTradingName: user.speculativeTradingName,
        }));
    });
};
// 规格型号选择事件
const onSpecificationSelect = (item) => {
console.log('selected item---', item);
    productData.value[currentProductIndex.value].specificationModel = item.name
    productData.value[currentProductIndex.value].productModelId = item.value
    productData.value[currentProductIndex.value].unit = item.unit
    productData.value[currentProductIndex.value].speculativeTradingName = item.speculativeTradingName
}
// 税率选择事件
const onTaxRateSelect = (item) => {
    productData.value[currentProductIndex.value].taxRate = item.value
    // 重新计算不含税总价
    const inclusiveTotalPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveTotalPrice)
    const taxRate = parseFloat(item.value)
    if (inclusiveTotalPrice && taxRate) {
        productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
            calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate)
    }
};
// 发票类型选择事件
const onInvoiceTypeSelect = (item) => {
    productData.value[currentProductIndex.value].invoiceType = item.name
};
// 格式化函数 - 固定两位小数
const formatTaxPrice = (idx) => {
  if (productData.value[idx].taxInclusiveUnitPrice) {
    const value = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
    if (!isNaN(value)) {
        productData.value[idx].taxInclusiveUnitPrice = value.toFixed(2);
  const showPicker = ref(false);
  const showDatePicker = ref(false);
  const pickerDateValue = ref(Date.now());
  const showCustomerPicker = ref(false);
  const userList = ref([]);
  const customerOption = ref([]);
  const userActionList = computed(() => {
    return userList.value.map(user => ({
      name: user.text,
      value: user.value,
    }));
  });
  const formatter = (type, value) => {
    if (type === "year") {
      return `${value}`;
    }
  }
    if (!productData.value[idx].taxRate) {
        uni.showToast({
            title: '请先选择税率',
            icon: 'none'
        });
        return;
    }
    const quantity = parseFloat(productData.value[idx].quantity);
    const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
    if (!quantity || quantity <= 0 || !unitPrice) {
        return;
    }
    // 计算含税总价
    productData.value[idx].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
    // 如果有税率,计算不含税总价
    if (productData.value[idx].taxRate) {
        productData.value[idx].taxExclusiveTotalPrice =
            calculateTaxExclusiveTotalPrice(
                productData.value[idx].taxInclusiveTotalPrice,
                productData.value[idx].taxRate
            );
    }
};
// 数量输入框失焦
const formatAmount = (idx) => {
  if (productData.value[idx].quantity) {
    const value = parseFloat(productData.value[idx].quantity);
    if (!isNaN(value)) {
        productData.value[idx].quantity = value.toFixed(2);
    if (type === "month") {
      return `${value}`;
    }
  }
    if (!productData.value[idx].taxRate) {
        uni.showToast({
            title: '请先选择税率',
            icon: 'none'
        });
        return;
    }
    const quantity = parseFloat(productData.value[idx].quantity);
    const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
    if (!quantity || quantity <= 0 || !unitPrice) {
        return;
    }
    // 计算含税总价
    productData.value[idx].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
    // 如果有税率,计算不含税总价
    if (productData.value[idx].taxRate) {
        productData.value[idx].taxExclusiveTotalPrice =
            calculateTaxExclusiveTotalPrice(
                productData.value[idx].taxInclusiveTotalPrice,
                productData.value[idx].taxRate
            );
    }
};
// 含税总价失焦,根据含税总价计算含税单价和数量
const formatTaxTotal = (idx) => {
  if (productData.value[idx].taxInclusiveTotalPrice) {
    const value = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
    if (!isNaN(value)) {
        productData.value[idx].taxInclusiveTotalPrice = value.toFixed(2);
    if (type === "day") {
      return `${value}`;
    }
  }
    const totalPrice = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
    const quantity = parseFloat(productData.value[idx].quantity);
    if (!totalPrice || !quantity || quantity <= 0) {
        return;
    }
    // 计算含税单价 = 含税总价 / 数量
    productData.value[idx].taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
    // 如果有税率,计算不含税总价
    if (productData.value[idx].taxRate) {
        productData.value[idx].taxExclusiveTotalPrice =
            calculateTaxExclusiveTotalPrice(
                totalPrice,
                productData.value[idx].taxRate
            );
    }
};
// 不含税总价失焦, 根据不含税总价计算含税单价和数量
const formatNoTaxTotal = (idx) => {
  if (productData.value[idx].taxExclusiveTotalPrice) {
    const value = parseFloat(productData.value[idx].taxExclusiveTotalPrice);
    if (!isNaN(value)) {
        productData.value[idx].taxExclusiveTotalPrice = value.toFixed(2);
    }
  }
    if (!productData.value[idx].taxRate) {
        uni.showToast({
            title: '请先选择税率',
            icon: 'none'
        });
        return;
    }
    const exclusiveTotalPrice = parseFloat(productData.value[idx].taxExclusiveTotalPrice);
    const quantity = parseFloat(productData.value[idx].quantity);
    const taxRate = parseFloat(productData.value[idx].taxRate);
    if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
        return;
    }
    // 先计算含税总价 = 不含税总价 / (1 - 税率/100)
    const taxRateDecimal = taxRate / 100;
    const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
    productData.value[idx].taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
    // 计算含税单价 = 含税总价 / 数量
    productData.value[idx].taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
};
const goBack = () => {
    // 清理本地存储的数据
    uni.removeStorageSync('operationType');
    uni.removeStorageSync('editData');
    uni.navigateBack();
};
const onSubmit = async () => {
    // 首先校验基本表单
    const formValid = await formRef.value.validate().catch(() => false);
    if (!formValid) {
        return;
    }
    // 校验产品信息
    if (!productData.value || productData.value.length === 0) {
        uni.showToast({
            title: '请添加产品信息',
            icon: 'none'
        });
        return;
    }
    // 检查每个产品是否填写完整
    for (let i = 0; i < productData.value.length; i++) {
        const product = productData.value[i];
        // 优化数字字段验证,处理可能的字符串格式数值
        const taxInclusiveUnitPrice = parseFloat(product.taxInclusiveUnitPrice);
        const quantity = parseFloat(product.quantity);
        const taxInclusiveTotalPrice = parseFloat(product.taxInclusiveTotalPrice);
        const taxExclusiveTotalPrice = parseFloat(product.taxExclusiveTotalPrice);
        if (!product.productCategory) {
            uni.showToast({
                title: `产品${i + 1}:请选择产品大类`,
                icon: 'none'
            });
            return;
        }
        if (!product.specificationModel) {
            uni.showToast({
                title: `产品${i + 1}:请选择规格型号`,
                icon: 'none'
            });
            return;
        }
        if (!product.unit) {
            uni.showToast({
                title: `产品${i + 1}:请输入单位`,
                icon: 'none'
            });
            return;
        }
        if (!product.taxRate) {
            uni.showToast({
                title: `产品${i + 1}:请选择税率`,
                icon: 'none'
            });
            return;
        }
        if (isNaN(taxInclusiveUnitPrice) || taxInclusiveUnitPrice <= 0) {
            uni.showToast({
                title: `产品${i + 1}:请输入有效的含税单价`,
                icon: 'none'
            });
            return;
        }
        if (isNaN(quantity) || quantity <= 0) {
            uni.showToast({
                title: `产品${i + 1}:请输入有效的数量`,
                icon: 'none'
            });
            return;
        }
        if (isNaN(taxInclusiveTotalPrice) || taxInclusiveTotalPrice <= 0) {
            uni.showToast({
                title: `产品${i + 1}:请输入有效的含税总价`,
                icon: 'none'
            });
            return;
        }
        if (isNaN(taxExclusiveTotalPrice) || taxExclusiveTotalPrice <= 0) {
            uni.showToast({
                title: `产品${i + 1}:请输入有效的不含税总价`,
                icon: 'none'
            });
            return;
        }
        if (!product.invoiceType) {
            uni.showToast({
                title: `产品${i + 1}:请选择发票类型`,
                icon: 'none'
            });
            return;
        }
    }
    // 表单校验通过,提交数据
    form.value.productData = JSON.parse(JSON.stringify(productData.value));
    form.value.type = 1;
    addOrUpdateSalesLedger(form.value).then((res) => {
        uni.showToast({
            title: '提交成功',
            icon: 'success',
        });
        goBack();
    });
};
const setUserInfo = () => {
    form.value.entryPerson = userStore.id;
    form.value.entryPersonName = userStore.nickName;
    // 设置当天日期
    const today = new Date()
    const year = today.getFullYear()
    const month = String(today.getMonth() + 1).padStart(2, '0')
    const day = String(today.getDate()).padStart(2, '0')
    form.value.entryDate = `${year}-${month}-${day}`
    // 设置日期选择器默认值为今天
    pickerDateValue.value = `${year}-${month}-${day}`
}
// 填充表单数据(编辑模式)
const fillFormData = () => {
  if (!editData.value) return;
    getSalesLedgerWithProducts({ id: editData.value.id, type: 1 }).then((res) => {
        productData.value = res.productData;
    });
    console.log(editData.value)
  // 填充基本信息
  form.value.salesContractNo = editData.value.salesContractNo || '';
  form.value.customerContractNo = editData.value.customerContractNo || '';
  form.value.customerName = editData.value.customerName || '';
  form.value.projectName = editData.value.projectName || '';
  form.value.executionDate = editData.value.executionDate || '';
  form.value.paymentMethod = editData.value.paymentMethod || '';
  form.value.salesman = editData.value.salesman || '';
  form.value.entryPerson = editData.value.entryPerson || '';
  form.value.entryPersonName = editData.value.entryPersonName || '';
  form.value.entryDate = editData.value.entryDate || '';
  form.value.id = editData.value.id || '';
  form.value.customerId = editData.value.customerId || '';
  // 设置日期选择器的值
  if (editData.value.executionDate) {
        pickerDateValue.value = editData.value.executionDate
    }
};
const getUserList = () => {
    userListNoPage().then((res) => {
        // 移除多余的数组包装
        userList.value = res.data.map(user => ({
            text: user.nickName,
            value: user.nickName
        }));
    })
};
const getCustomerList = () => {
    customerList().then((res) => {
        // 移除多余的数组包装
        customerOption.value = res.map(item => ({
            text: item.customerName,
            value: item.id
        }));
    })
};
const convertIdToValue = (data) => {
    // 如果传入的不是数组,则返回空数组
    if (!Array.isArray(data)) {
        return [];
    }
    // 递归映射函数
    return data.map(item => {
        // 创建新对象,映射字段
        const mappedItem = {
            label: item.label, // 关键:将 label 映射为 text
            id: item.id,       // 保留 id
        };
        // 如果存在 children 数组,则递归处理
        if (item.children && Array.isArray(item.children) && item.children.length > 0) {
            mappedItem.children = convertIdToValue(item.children);
        }
        return mappedItem;
    });
};
// 获取产品大类tree数据
const getProductOptions = () => {
    productTreeList().then((res) => {
        productOptions.value = convertIdToValue(res);
    });
};
    return value;
  };
  const customerActionList = computed(() => {
    return customerOption.value.map(customer => ({
      name: customer.text,
      value: customer.value,
    }));
  });
  // 日期选择列表已移除,改用 up-datetime-picker
onMounted(() => {
    // 获取页面参数
    operationType.value = uni.getStorageSync('operationType') || '';
    // 获取人员列表
    getUserList()
    // 获取客户列表
    getCustomerList()
    // 获取产品大类tree数据
    getProductOptions()
    // 赋值默认信息
    if (operationType.value === 'add') {
        setUserInfo()
    }
    // 获取编辑数据并填充表单
    const editDataStr = uni.getStorageSync('editData');
    if (editDataStr) {
        try {
            editData.value = JSON.parse(editDataStr);
            // 如果是编辑模式,等待数据加载完成后填充表单数据
            if (operationType.value !== 'add' && editData.value) {
                // 使用 nextTick 确保数据加载完成后再填充
                setTimeout(() => {
                    fillFormData();
                }, 100);
            }
        } catch (error) {
            console.error('解析编辑数据失败:', error);
        }
    }
});
  // 产品大类选择列表
  const categoryActionList = computed(() => {
    const flattenCategories = (categories, result = []) => {
      categories.forEach(category => {
        result.push({
          name: category.label,
          value: category.id,
        });
        if (category.children && category.children.length > 0) {
          flattenCategories(category.children, result);
        }
      });
      return result;
    };
    return flattenCategories(productOptions.value);
  });
  // 规格型号选择列表
  const specificationActionList = computed(() => {
    return modelOptions.value.map(model => ({
      name: model.text,
      value: model.value,
      unit: model.unit,
      speculativeTradingName: model.speculativeTradingName,
    }));
  });
  // 税率选择列表
  const taxRateActionList = computed(() => {
    return taxRateOptions.value.map(rate => ({
      name: rate.text,
      value: rate.value,
    }));
  });
  // 发票类型选择列表
  const invoiceTypeActionList = computed(() => {
    return invoiceTypeOptions.value.map(type => ({
      name: type.text,
      value: type.value,
    }));
  });
  const productData = ref([]);
  // 选择器相关变量
  const showCategoryPicker = ref(false);
  const showSpecificationPicker = ref(false);
  const showTaxRatePicker = ref(false);
  const showInvoiceTypePicker = ref(false);
  // 选择器显示状态变量已在上面定义
  // 临时变量已不再需要
  const currentProductIndex = ref(0);
  // 选项数据
  const productOptions = ref([]);
  const selectedCategoryNode = ref(null);
  const defaultProps = ref({
    children: "children",
    label: "label",
    nodeKey: "id",
  });
  const modelOptions = ref([]);
  // 防止循环计算的标志
  // const isCalculating = ref(false);
  const taxRateOptions = ref([
    { text: "1", value: "1" },
    { text: "6", value: "6" },
    { text: "13", value: "13" },
  ]);
  const invoiceTypeOptions = ref([
    { text: "增普票", value: "增普票" },
    { text: "增专票", value: "增专票" },
  ]);
  // 表单校验规则
  const rules = {
    salesman: [{ required: true, message: "请选择业务员", trigger: "change" }],
    customerContractNo: [
      { required: true, message: "请输入客户合同号", trigger: "blur" },
    ],
    customerName: [
      { required: true, message: "请选择客户名称", trigger: "change" },
    ],
    projectName: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
    executionDate: [
      { required: true, message: "请选择签订日期", trigger: "change" },
    ],
  };
  const addProduct = () => {
    if (productData.value === null) {
      productData.value = [];
    }
    productData.value.push({
      productCategory: "",
      specificationModel: "",
      productModelId: "",
      unit: "",
      speculativeTradingName: "",
      taxRate: "",
      taxInclusiveUnitPrice: "",
      quantity: "",
      taxInclusiveTotalPrice: "",
      taxExclusiveTotalPrice: "",
      invoiceType: "",
    });
  };
  // 业务员选择事件
  const onSalesmanSelect = item => {
    form.value.salesman = item.name;
  };
  // 日期确认事件
  const onDateConfirm = e => {
    form.value.executionDate = formatDateToYMD(e.value);
    // 保持pickerDateValue为时间戳格式,而不是格式化的字符串
    pickerDateValue.value = e.value;
    showDatePicker.value = false;
  };
  // 客户选择事件
  const onCustomerSelect = item => {
    form.value.customerName = item.name;
    form.value.customerId = item.value;
  };
  // 原有的确认方法已被新的action-sheet选择方法替代
  const removeProduct = idx => {
    productData.value.splice(idx, 1);
  };
  // 显示选择器
  const openCategoryPicker = idx => {
    currentProductIndex.value = idx;
    showCategoryPicker.value = true;
  };
  const openSpecificationPicker = idx => {
    currentProductIndex.value = idx;
    showSpecificationPicker.value = true;
  };
  const openTaxRatePicker = idx => {
    currentProductIndex.value = idx;
    showTaxRatePicker.value = true;
  };
  const openInvoiceTypePicker = idx => {
    currentProductIndex.value = idx;
    showInvoiceTypePicker.value = true;
  };
  // 选择器确认事件
  const onCategoryConfirm = node => {
    // 获取选中的节点信息
    console.log("selected node---", node);
    // 存储选中的节点,用于确认时获取数据
    selectedCategoryNode.value = node;
  };
  // 确认产品大类选择
  const confirmCategorySelection = () => {
    if (selectedCategoryNode.value) {
      // 设置选中的产品大类
      productData.value[currentProductIndex.value].productCategory =
        selectedCategoryNode.value.label;
      const id = selectedCategoryNode.value.id;
      // 重置选中的节点
      selectedCategoryNode.value = null;
      productData.value[currentProductIndex.value].specificationModel = "";
      productData.value[currentProductIndex.value].productModelId = "";
      getModels(id);
    }
    showCategoryPicker.value = false;
  };
  // 获取规格型号
  const getModels = value => {
    modelList({ id: value }).then(res => {
      modelOptions.value = res.map(user => ({
        text: user.model,
        value: user.id,
        unit: user.unit,
        speculativeTradingName: user.speculativeTradingName,
      }));
    });
  };
  // 规格型号选择事件
  const onSpecificationSelect = item => {
    console.log("selected item---", item);
    productData.value[currentProductIndex.value].specificationModel = item.name;
    productData.value[currentProductIndex.value].productModelId = item.value;
    productData.value[currentProductIndex.value].unit = item.unit;
    productData.value[currentProductIndex.value].speculativeTradingName =
      item.speculativeTradingName;
  };
  // 税率选择事件
  const onTaxRateSelect = item => {
    productData.value[currentProductIndex.value].taxRate = item.value;
    // 重新计算不含税总价
    const inclusiveTotalPrice = parseFloat(
      productData.value[currentProductIndex.value].taxInclusiveTotalPrice
    );
    const taxRate = parseFloat(item.value);
    if (inclusiveTotalPrice && taxRate) {
      productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
        calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate);
    }
  };
  // 发票类型选择事件
  const onInvoiceTypeSelect = item => {
    productData.value[currentProductIndex.value].invoiceType = item.name;
  };
  // 格式化函数 - 固定两位小数
  const formatTaxPrice = idx => {
    if (productData.value[idx].taxInclusiveUnitPrice) {
      const value = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
      if (!isNaN(value)) {
        productData.value[idx].taxInclusiveUnitPrice = value.toFixed(2);
      }
    }
    if (!productData.value[idx].taxRate) {
      uni.showToast({
        title: "请先选择税率",
        icon: "none",
      });
      return;
    }
    const quantity = parseFloat(productData.value[idx].quantity);
    const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
    if (!quantity || quantity <= 0 || !unitPrice) {
      return;
    }
    // 计算含税总价
    productData.value[idx].taxInclusiveTotalPrice = (
      unitPrice * quantity
    ).toFixed(2);
    // 如果有税率,计算不含税总价
    if (productData.value[idx].taxRate) {
      productData.value[idx].taxExclusiveTotalPrice =
        calculateTaxExclusiveTotalPrice(
          productData.value[idx].taxInclusiveTotalPrice,
          productData.value[idx].taxRate
        );
    }
  };
  // 数量输入框失焦
  const formatAmount = idx => {
    if (productData.value[idx].quantity) {
      const value = parseFloat(productData.value[idx].quantity);
      if (!isNaN(value)) {
        productData.value[idx].quantity = value.toFixed(2);
      }
    }
    if (!productData.value[idx].taxRate) {
      uni.showToast({
        title: "请先选择税率",
        icon: "none",
      });
      return;
    }
    const quantity = parseFloat(productData.value[idx].quantity);
    const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
    if (!quantity || quantity <= 0 || !unitPrice) {
      return;
    }
    // 计算含税总价
    productData.value[idx].taxInclusiveTotalPrice = (
      unitPrice * quantity
    ).toFixed(2);
    // 如果有税率,计算不含税总价
    if (productData.value[idx].taxRate) {
      productData.value[idx].taxExclusiveTotalPrice =
        calculateTaxExclusiveTotalPrice(
          productData.value[idx].taxInclusiveTotalPrice,
          productData.value[idx].taxRate
        );
    }
  };
  // 含税总价失焦,根据含税总价计算含税单价和数量
  const formatTaxTotal = idx => {
    if (productData.value[idx].taxInclusiveTotalPrice) {
      const value = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
      if (!isNaN(value)) {
        productData.value[idx].taxInclusiveTotalPrice = value.toFixed(2);
      }
    }
    const totalPrice = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
    const quantity = parseFloat(productData.value[idx].quantity);
    if (!totalPrice || !quantity || quantity <= 0) {
      return;
    }
    // 计算含税单价 = 含税总价 / 数量
    productData.value[idx].taxInclusiveUnitPrice = (
      totalPrice / quantity
    ).toFixed(2);
    // 如果有税率,计算不含税总价
    if (productData.value[idx].taxRate) {
      productData.value[idx].taxExclusiveTotalPrice =
        calculateTaxExclusiveTotalPrice(
          totalPrice,
          productData.value[idx].taxRate
        );
    }
  };
  // 不含税总价失焦, 根据不含税总价计算含税单价和数量
  const formatNoTaxTotal = idx => {
    if (productData.value[idx].taxExclusiveTotalPrice) {
      const value = parseFloat(productData.value[idx].taxExclusiveTotalPrice);
      if (!isNaN(value)) {
        productData.value[idx].taxExclusiveTotalPrice = value.toFixed(2);
      }
    }
    if (!productData.value[idx].taxRate) {
      uni.showToast({
        title: "请先选择税率",
        icon: "none",
      });
      return;
    }
    const exclusiveTotalPrice = parseFloat(
      productData.value[idx].taxExclusiveTotalPrice
    );
    const quantity = parseFloat(productData.value[idx].quantity);
    const taxRate = parseFloat(productData.value[idx].taxRate);
    if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
      return;
    }
    // 先计算含税总价 = 不含税总价 / (1 - 税率/100)
    const taxRateDecimal = taxRate / 100;
    const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
    productData.value[idx].taxInclusiveTotalPrice =
      inclusiveTotalPrice.toFixed(2);
    // 计算含税单价 = 含税总价 / 数量
    productData.value[idx].taxInclusiveUnitPrice = (
      inclusiveTotalPrice / quantity
    ).toFixed(2);
  };
  const goBack = () => {
    // 清理本地存储的数据
    uni.removeStorageSync("operationType");
    uni.removeStorageSync("editData");
    uni.navigateBack();
  };
  const onSubmit = async () => {
    // 首先校验基本表单
    const formValid = await formRef.value.validate().catch(() => false);
    if (!formValid) {
      return;
    }
    // 校验产品信息
    if (!productData.value || productData.value.length === 0) {
      uni.showToast({
        title: "请添加产品信息",
        icon: "none",
      });
      return;
    }
    // 检查每个产品是否填写完整
    for (let i = 0; i < productData.value.length; i++) {
      const product = productData.value[i];
      // 优化数字字段验证,处理可能的字符串格式数值
      const taxInclusiveUnitPrice = parseFloat(product.taxInclusiveUnitPrice);
      const quantity = parseFloat(product.quantity);
      const taxInclusiveTotalPrice = parseFloat(product.taxInclusiveTotalPrice);
      const taxExclusiveTotalPrice = parseFloat(product.taxExclusiveTotalPrice);
      if (!product.productCategory) {
        uni.showToast({
          title: `产品${i + 1}:请选择产品大类`,
          icon: "none",
        });
        return;
      }
      if (!product.specificationModel) {
        uni.showToast({
          title: `产品${i + 1}:请选择规格型号`,
          icon: "none",
        });
        return;
      }
      if (!product.unit) {
        uni.showToast({
          title: `产品${i + 1}:请输入单位`,
          icon: "none",
        });
        return;
      }
      if (!product.taxRate) {
        uni.showToast({
          title: `产品${i + 1}:请选择税率`,
          icon: "none",
        });
        return;
      }
      if (isNaN(taxInclusiveUnitPrice) || taxInclusiveUnitPrice <= 0) {
        uni.showToast({
          title: `产品${i + 1}:请输入有效的含税单价`,
          icon: "none",
        });
        return;
      }
      if (isNaN(quantity) || quantity <= 0) {
        uni.showToast({
          title: `产品${i + 1}:请输入有效的数量`,
          icon: "none",
        });
        return;
      }
      if (isNaN(taxInclusiveTotalPrice) || taxInclusiveTotalPrice <= 0) {
        uni.showToast({
          title: `产品${i + 1}:请输入有效的含税总价`,
          icon: "none",
        });
        return;
      }
      if (isNaN(taxExclusiveTotalPrice) || taxExclusiveTotalPrice <= 0) {
        uni.showToast({
          title: `产品${i + 1}:请输入有效的不含税总价`,
          icon: "none",
        });
        return;
      }
      if (!product.invoiceType) {
        uni.showToast({
          title: `产品${i + 1}:请选择发票类型`,
          icon: "none",
        });
        return;
      }
    }
    // 表单校验通过,提交数据
    form.value.productData = JSON.parse(JSON.stringify(productData.value));
    form.value.type = 1;
    addOrUpdateSalesLedger(form.value).then(res => {
      uni.showToast({
        title: "提交成功",
        icon: "success",
      });
      goBack();
    });
  };
  const setUserInfo = () => {
    form.value.entryPerson = userStore.id;
    form.value.entryPersonName = userStore.nickName;
    // 设置当天日期
    const today = new Date();
    const year = today.getFullYear();
    const month = String(today.getMonth() + 1).padStart(2, "0");
    const day = String(today.getDate()).padStart(2, "0");
    form.value.entryDate = `${year}-${month}-${day}`;
    // 设置日期选择器默认值为今天
    pickerDateValue.value = `${year}-${month}-${day}`;
  };
  // 填充表单数据(编辑模式)
  const fillFormData = () => {
    if (!editData.value) return;
    getSalesLedgerWithProducts({ id: editData.value.id, type: 1 }).then(res => {
      productData.value = res.productData;
    });
    console.log(editData.value);
    // 填充基本信息
    form.value.salesContractNo = editData.value.salesContractNo || "";
    form.value.customerContractNo = editData.value.customerContractNo || "";
    form.value.customerName = editData.value.customerName || "";
    form.value.projectName = editData.value.projectName || "";
    form.value.executionDate = editData.value.executionDate || "";
    form.value.paymentMethod = editData.value.paymentMethod || "";
    form.value.salesman = editData.value.salesman || "";
    form.value.entryPerson = editData.value.entryPerson || "";
    form.value.entryPersonName = editData.value.entryPersonName || "";
    form.value.entryDate = editData.value.entryDate || "";
    form.value.id = editData.value.id || "";
    form.value.customerId = editData.value.customerId || "";
    // 设置日期选择器的值
    if (editData.value.executionDate) {
      pickerDateValue.value = editData.value.executionDate;
    }
  };
  const getUserList = () => {
    userListNoPage().then(res => {
      // 移除多余的数组包装
      userList.value = res.data.map(user => ({
        text: user.nickName,
        value: user.nickName,
      }));
    });
  };
  const getCustomerList = () => {
    customerList().then(res => {
      // 移除多余的数组包装
      customerOption.value = res.map(item => ({
        text: item.customerName,
        value: item.id,
      }));
    });
  };
  const convertIdToValue = data => {
    // 如果传入的不是数组,则返回空数组
    if (!Array.isArray(data)) {
      return [];
    }
    // 递归映射函数
    return data.map(item => {
      // 创建新对象,映射字段
      const mappedItem = {
        label: item.label, // 关键:将 label 映射为 text
        id: item.id, // 保留 id
      };
      // 如果存在 children 数组,则递归处理
      if (
        item.children &&
        Array.isArray(item.children) &&
        item.children.length > 0
      ) {
        mappedItem.children = convertIdToValue(item.children);
      }
      return mappedItem;
    });
  };
  // 获取产品大类tree数据
  const getProductOptions = () => {
    productTreeList().then(res => {
      productOptions.value = convertIdToValue(res);
    });
  };
  onMounted(() => {
    // 获取页面参数
    operationType.value = uni.getStorageSync("operationType") || "";
    // 获取人员列表
    getUserList();
    // 获取客户列表
    getCustomerList();
    // 获取产品大类tree数据
    getProductOptions();
    // 赋值默认信息
    if (operationType.value === "add") {
      setUserInfo();
    }
    // 获取编辑数据并填充表单
    const editDataStr = uni.getStorageSync("editData");
    if (editDataStr) {
      try {
        editData.value = JSON.parse(editDataStr);
        // 如果是编辑模式,等待数据加载完成后填充表单数据
        if (operationType.value !== "add" && editData.value) {
          // 使用 nextTick 确保数据加载完成后再填充
          setTimeout(() => {
            fillFormData();
          }, 100);
        }
      } catch (error) {
        console.error("解析编辑数据失败:", error);
      }
    }
  });
</script>
<style lang="scss">
@import '@/static/scss/form-common.scss';
  @import "@/static/scss/form-common.scss";
</style>
src/pages/sales/salesAccount/view.vue
@@ -1,8 +1,8 @@
<template>
  <view class="account-view">
    <!-- 使用通用页面头部组件 -->
        <PageHeader title="台账详情" @back="goBack" />
    <PageHeader title="台账详情"
                @back="goBack" />
    <!-- 基本信息展示 -->
    <view class="info-section">
      <view class="section-title">基本信息</view>
@@ -45,19 +45,22 @@
        </view>
      </view>
    </view>
    <!-- 产品信息展示 -->
    <view class="product-section" v-if="productData && productData.length > 0">
    <view class="product-section"
          v-if="productData && productData.length > 0">
      <view class="section-title">产品信息</view>
      <view class="product-card" v-for="(product, idx) in productData" :key="idx">
      <view class="product-card"
            v-for="(product, idx) in productData"
            :key="idx">
        <view class="product-header">
          <view class="product-title">
            <!-- 替换 van-icon 为 u-icon -->
            <u-icon name="file-text" color="#2979ff" size="15" />
            <u-icon name="file-text"
                    color="#2979ff"
                    size="15" />
            <text class="product-productCategory">产品 {{ idx + 1 }}</text>
          </view>
        </view>
        <view class="product-info">
          <view class="info-grid">
            <view class="info-item">
@@ -68,10 +71,10 @@
              <text class="info-label">规格型号</text>
              <text class="info-value">{{ product.specificationModel }}</text>
            </view>
            <view class="info-item">
            <!-- <view class="info-item">
              <text class="info-label">绑定机器</text>
              <text class="info-value">{{ product.speculativeTradingName }}</text>
            </view>
            </view> -->
            <view class="info-item">
              <text class="info-label">单位</text>
              <text class="info-value">{{ product.unit }}</text>
@@ -104,192 +107,192 @@
        </view>
      </view>
    </view>
    <view v-else class="no-product">
    <view v-else
          class="no-product">
      <text>暂无产品信息</text>
    </view>
  </view>
</template>
<script setup>
import {onMounted, ref} from 'vue';
import {getSalesLedgerWithProducts} from "@/api/salesManagement/salesLedger";
import PageHeader from '@/components/PageHeader.vue';
  import { onMounted, ref } from "vue";
  import { getSalesLedgerWithProducts } from "@/api/salesManagement/salesLedger";
  import PageHeader from "@/components/PageHeader.vue";
// 获取页面参数
const editData = ref(null);
  // 获取页面参数
  const editData = ref(null);
const form = ref({
  id: '',
  salesContractNo: '',
  customerContractNo: '',
  customerId: '',
  customerName: '',
  projectName: '',
  executionDate: '',
  paymentMethod: '',
  entryPerson: '',
  entryPersonName: '',
  entryDate: '',
  salesman: ''
});
// 产品数据
const productData = ref([]);
// 返回上一页
const goBack = () => {
  // 清理本地存储的数据
  uni.removeStorageSync('editData');
  uni.navigateBack();
};
// 填充表单数据
const fillFormData = () => {
  if (!editData.value) return;
  // 获取完整的产品信息
    getSalesLedgerWithProducts({ id: editData.value.id, type: 1 }).then((res) => {
    productData.value = res.productData || [];
        form.value = {...res}
  const form = ref({
    id: "",
    salesContractNo: "",
    customerContractNo: "",
    customerId: "",
    customerName: "",
    projectName: "",
    executionDate: "",
    paymentMethod: "",
    entryPerson: "",
    entryPersonName: "",
    entryDate: "",
    salesman: "",
  });
};
onMounted(() => {
  // 获取编辑数据并填充表单
  const editDataStr = uni.getStorageSync('editData');
  if (editDataStr) {
    try {
      editData.value = JSON.parse(editDataStr);
      // 使用 nextTick 确保数据加载完成后再填充
      setTimeout(() => {
        fillFormData();
      }, 100);
    } catch (error) {
      console.error('解析编辑数据失败:', error);
  // 产品数据
  const productData = ref([]);
  // 返回上一页
  const goBack = () => {
    // 清理本地存储的数据
    uni.removeStorageSync("editData");
    uni.navigateBack();
  };
  // 填充表单数据
  const fillFormData = () => {
    if (!editData.value) return;
    // 获取完整的产品信息
    getSalesLedgerWithProducts({ id: editData.value.id, type: 1 }).then(res => {
      productData.value = res.productData || [];
      form.value = { ...res };
    });
  };
  onMounted(() => {
    // 获取编辑数据并填充表单
    const editDataStr = uni.getStorageSync("editData");
    if (editDataStr) {
      try {
        editData.value = JSON.parse(editDataStr);
        // 使用 nextTick 确保数据加载完成后再填充
        setTimeout(() => {
          fillFormData();
        }, 100);
      } catch (error) {
        console.error("解析编辑数据失败:", error);
      }
    }
  }
});
  });
</script>
<style scoped lang="scss">
.account-view {
  min-height: 100vh;
  background: #f8f9fa;
  padding-bottom: 2rem;
}
  .account-view {
    min-height: 100vh;
    background: #f8f9fa;
    padding-bottom: 2rem;
  }
.header {
  display: flex;
  align-items: center;
  background: #fff;
  padding: 1rem 1.25rem;
  border-bottom: 0.0625rem solid #f0f0f0;
  position: sticky;
  top: 0;
  z-index: 100;
}
  .header {
    display: flex;
    align-items: center;
    background: #fff;
    padding: 1rem 1.25rem;
    border-bottom: 0.0625rem solid #f0f0f0;
    position: sticky;
    top: 0;
    z-index: 100;
  }
.title {
  flex: 1;
  text-align: center;
  font-size: 1.125rem;
  font-weight: 600;
  color: #333;
}
  .title {
    flex: 1;
    text-align: center;
    font-size: 1.125rem;
    font-weight: 600;
    color: #333;
  }
.info-section {
  background: #fff;
  margin: 1rem;
  padding: 1rem;
  border-radius: 0.5rem;
  box-shadow: 0 0.125rem 0.5rem rgba(0,0,0,0.04);
}
  .info-section {
    background: #fff;
    margin: 1rem;
    padding: 1rem;
    border-radius: 0.5rem;
    box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.04);
  }
.product-section {
  background: #fff;
  margin: 1rem;
  padding: 1rem;
  border-radius: 0.5rem;
  box-shadow: 0 0.125rem 0.5rem rgba(0,0,0,0.04);
}
  .product-section {
    background: #fff;
    margin: 1rem;
    padding: 1rem;
    border-radius: 0.5rem;
    box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.04);
  }
.section-title {
  font-size: 1rem;
  font-weight: 600;
  color: #333;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 0.0625rem solid #e8e8e8;
}
  .section-title {
    font-size: 1rem;
    font-weight: 600;
    color: #333;
    margin-bottom: 1rem;
    padding-bottom: 0.5rem;
    border-bottom: 0.0625rem solid #e8e8e8;
  }
.info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}
  .info-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
  }
.info-item {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
  .info-item {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
  }
.info-label {
  font-size: 0.75rem;
  color: #666;
  font-weight: 400;
}
  .info-label {
    font-size: 0.75rem;
    color: #666;
    font-weight: 400;
  }
.info-value {
  font-size: 0.875rem;
  color: #333;
  font-weight: 500;
}
  .info-value {
    font-size: 0.875rem;
    color: #333;
    font-weight: 500;
  }
.info-value.highlight {
  color: #2979ff;
  font-weight: 600;
}
  .info-value.highlight {
    color: #2979ff;
    font-weight: 600;
  }
.product-card {
  background: #f8f9fa;
  border-radius: 0.5rem;
  padding: 1rem;
  margin-bottom: 1rem;
  border: 0.0625rem solid #e8e8e8;
}
  .product-card {
    background: #f8f9fa;
    border-radius: 0.5rem;
    padding: 1rem;
    margin-bottom: 1rem;
    border: 0.0625rem solid #e8e8e8;
  }
.product-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 0.0625rem solid #e8e8e8;
}
  .product-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1rem;
    padding-bottom: 0.5rem;
    border-bottom: 0.0625rem solid #e8e8e8;
  }
.product-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
  .product-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
.product-productCategory {
  font-size: 0.875rem;
  font-weight: 500;
  color: #333;
}
  .product-productCategory {
    font-size: 0.875rem;
    font-weight: 500;
    color: #333;
  }
.product-info .info-grid {
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
}
  .product-info .info-grid {
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
  }
.no-product {
  text-align: center;
  padding: 2rem;
  color: #999;
  font-size: 0.875rem;
}
  .no-product {
    text-align: center;
    padding: 2rem;
    color: #999;
    font-size: 0.875rem;
  }
</style>