src/views/salesManagement/salesLedger/index.vue
@@ -40,11 +40,32 @@
            @change="changeDaterange"
          />
        </el-form-item>
        <el-form-item label="审批状态:">
          <el-select
            v-model="searchForm.approvalStatus"
            placeholder="请选择"
            clearable
            style="width: 160px"
            @change="handleQuery"
          >
            <el-option
              v-for="item in approvalStatusOptions"
              :key="item"
              :label="item"
              :value="item"
            />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery"> 搜索 </el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 卖油 / 代储拆成两个页签,各自固定带 ledgerType 调同一个列表接口 -->
    <el-tabs v-model="activeTab" @tab-change="handleTabChange" class="ledger-tabs">
      <el-tab-pane label="销售台账(卖油)" name="卖油" />
      <el-tab-pane label="代储台账" name="代储" />
    </el-tabs>
    <div class="table_list">
      <div class="actions">
        <div></div>
@@ -72,7 +93,7 @@
        style="width: 100%"
        :summary-method="summarizeMainTable"
        @expand-change="expandChange"
        height="calc(100vh - 18.5em)"
        height="calc(100vh - 21.5em)"
      >
        <el-table-column
          align="center"
@@ -221,9 +242,22 @@
          label="合同金额(元)"
          prop="contractAmount"
          width="220"
          show-overflow-tooltip
          :formatter="formattedNumber"
        />
        >
          <template #default="{ row, column }">
            <el-tooltip
              v-if="row.exceedsTrustFund"
              :content="`合同金额已超出该客户信托基金(信托基金:${row.trustFund})`"
              placement="top"
            >
              <el-text type="danger">
                {{ formattedNumber(row, column, row.contractAmount) }}
              </el-text>
            </el-tooltip>
            <span v-else>
              {{ formattedNumber(row, column, row.contractAmount) }}
            </span>
          </template>
        </el-table-column>
        <el-table-column
          label="实际合同金额(元)"
          prop="netContractAmount"
@@ -255,6 +289,33 @@
          width="120"
          show-overflow-tooltip
        />
        <el-table-column
          label="销售类型"
          prop="ledgerType"
          width="100"
          show-overflow-tooltip
        />
        <el-table-column
          v-if="activeTab === '代储'"
          label="油库"
          prop="oilDepotName"
          width="180"
          show-overflow-tooltip
        />
        <el-table-column
          v-if="activeTab === '代储'"
          label="储罐号"
          prop="tankNo"
          width="140"
          show-overflow-tooltip
        />
        <el-table-column label="审批状态" width="110" align="center">
          <template #default="{ row }">
            <el-tag :type="getApprovalStatusType(row.approvalStatus)" size="small">
              {{ row.approvalStatus || "-" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column
          label="备注"
          prop="remarks"
@@ -314,8 +375,24 @@
        :rules="rules"
        ref="formRef"
      >
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="销售类型:" prop="ledgerType">
              <el-radio-group
                v-model="form.ledgerType"
                :disabled="operationType === 'view'"
              >
                <el-radio value="卖油">卖油</el-radio>
                <el-radio value="代储">卖存储位置(代储)</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 报价单导入入口:放在表单顶部,选择后反显客户/业务员等 -->
        <el-row v-if="operationType === 'add'" style="margin-bottom: 10px">
        <el-row
          v-if="operationType === 'add' && form.ledgerType !== '代储'"
          style="margin-bottom: 10px"
        >
          <el-col :span="24" style="text-align: right">
            <el-button type="primary" plain @click="openQuotationDialog">
              从销售报价导入
@@ -379,6 +456,7 @@
                clearable
                :disabled="operationType === 'view'"
                filterable
                @change="loadCustomerTrustFund"
              >
                <el-option
                  v-for="item in customerOption"
@@ -483,7 +561,72 @@
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
        <!-- 代储:卖存储位置,只选油库+储罐并手工填合同金额 -->
        <el-row v-if="form.ledgerType === '代储'" :gutter="30">
          <el-col :span="12">
            <el-form-item label="油库:" prop="oilDepotId">
              <el-select
                v-model="form.oilDepotId"
                placeholder="请选择"
                clearable
                filterable
                :disabled="operationType === 'view'"
                style="width: 100%"
              >
                <el-option
                  v-for="item in oilDepotOptions"
                  :key="item.id"
                  :label="item.depotName"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="储罐号:" prop="tankId">
              <el-select
                v-model="form.tankId"
                placeholder="请选择"
                clearable
                filterable
                :disabled="operationType === 'view'"
                style="width: 100%"
              >
                <el-option
                  v-for="item in tankOptions"
                  :key="item.id"
                  :label="item.tankNo"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row v-if="form.ledgerType === '代储'" :gutter="30">
          <el-col :span="12">
            <el-form-item label="合同金额(元):" prop="contractAmount">
              <el-input-number
                v-model="form.contractAmount"
                :min="0"
                :precision="2"
                :controls="false"
                placeholder="请输入"
                :disabled="operationType === 'view'"
                style="width: 100%"
              />
              <!-- 选中客户后本地比对信托基金,实时预览是否超限 -->
              <el-alert
                v-if="isContractOverTrustFund"
                type="warning"
                show-icon
                :closable="false"
                class="trust-fund-alert"
                :title="`合同金额已超出该客户信托基金(信托基金:${selectedCustomerTrustFund})`"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row v-if="form.ledgerType !== '代储'">
          <el-form-item label="产品信息:" prop="entryDate">
            <el-button
              v-if="operationType !== 'view'"
@@ -501,6 +644,7 @@
          </el-form-item>
        </el-row>
        <el-table
          v-if="form.ledgerType !== '代储'"
          :data="productData"
          border
          @selection-change="productSelected"
@@ -1172,7 +1316,7 @@
<script setup>
import { getToken } from "@/utils/auth";
import pagination from "@/components/PIMTable/Pagination.vue";
import { onMounted, ref, getCurrentInstance } from "vue";
import { computed, onMounted, ref, getCurrentInstance } from "vue";
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
import { ElMessageBox, ElMessage } from "element-plus";
import useUserStore from "@/store/modules/user";
@@ -1198,7 +1342,9 @@
import FileUpload from "@/components/AttachmentUpload/file/index.vue";
import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
import { getCurrentDate } from "@/utils/index.js";
import { listCustomer } from "@/api/basicData/customer.js";
import { getCustomer, listCustomer } from "@/api/basicData/customer.js";
import { allOilDepot } from "@/api/basicData/oilDepot.js";
import { allTankInfo } from "@/api/basicData/tankInfo.js";
const FileList = defineAsyncComponent(() =>
  import("@/components/Dialog/FileList.vue")
@@ -1209,6 +1355,14 @@
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
const { tax_rate } = proxy.useDict("tax_rate");
// 卖油 / 代储两个页签,固定带 ledgerType 调同一个列表接口
const activeTab = ref("卖油");
const approvalStatusOptions = ["待审批", "审核中", "通过", "拒绝"];
// 代储表单:油库、储罐下拉(两者互相独立,储罐不挂在油库下)
const oilDepotOptions = ref([]);
const tankOptions = ref([]);
// 代储表单:选中客户的信托基金,用于合同金额超限实时预览
const selectedCustomerTrustFund = ref(null);
const tableData = ref([]);
const productData = ref([]);
const selectedRows = ref([]);
@@ -1236,6 +1390,7 @@
    entryDate: null, // 录入日期
    entryDateStart: undefined,
    entryDateEnd: undefined,
    approvalStatus: "", // 审批状态
  },
  form: {
    salesContractNo: "",
@@ -1250,8 +1405,13 @@
    executionDate: "",
    hasProductionRecord: false,
    createTime: "",
    ledgerType: "卖油", // 销售类型:卖油 / 代储
    oilDepotId: "", // 代储:油库
    tankId: "", // 代储:储罐
    contractAmount: null, // 代储:合同金额由前端手工填
  },
  rules: {
    ledgerType: [{ required: true, message: "请选择", trigger: "change" }],
    salesman: [{ required: true, message: "请选择", trigger: "change" }],
    customerId: [{ required: true, message: "请选择", trigger: "change" }],
    entryPerson: [{ required: true, message: "请选择", trigger: "change" }],
@@ -1262,6 +1422,14 @@
});
const { form, rules } = toRefs(data);
const { form: searchForm } = useFormData(data.searchForm);
// 代储合同金额超信托基金(客户未维护信托基金时不提示)
const isContractOverTrustFund = computed(() => {
  const fund = selectedCustomerTrustFund.value;
  if (fund === null || fund === undefined || fund === "") return false;
  const amount = Number(form.value.contractAmount);
  if (!(amount > 0)) return false;
  return amount > Number(fund);
});
// 产品表单弹框数据
const productFormVisible = ref(false);
const productOperationType = ref("");
@@ -1514,14 +1682,14 @@
const getList = () => {
  tableLoading.value = true;
  const { entryDate, ...rest } = searchForm;
  // 将范围日期字段传递给后端
  const params = { ...rest, ...page };
  // 将范围日期字段传递给后端;ledgerType 由当前页签决定
  const params = { ...rest, ...page, ledgerType: activeTab.value };
  // 移除录入日期的默认值设置,只保留范围日期字段
  delete params.entryDate;
  return ledgerListPage(params)
    .then((res) => {
      tableLoading.value = false;
      tableData.value = res.records;
      tableData.value = res.records || [];
      tableData.value.map((item) => {
        item.children = [];
      });
@@ -1692,19 +1860,40 @@
// 添加表行类名方法
const tableRowClassName = ({ row }) => {
  if (!row.deliveryDate) return "";
  if (row.isFh) return "";
  const diff = row.deliveryDaysDiff;
  if (diff === 15) {
    return "yellow";
  } else if (diff === 10) {
    return "pink";
  } else if (diff === 2) {
    return "purple";
  } else if (diff < 2) {
    return "red";
  let className = "";
  if (row.deliveryDate && !row.isFh) {
    const diff = row.deliveryDaysDiff;
    if (diff === 15) {
      className = "yellow";
    } else if (diff === 10) {
      className = "pink";
    } else if (diff === 2) {
      className = "purple";
    } else if (diff < 2) {
      className = "red";
    }
  }
  // 本笔合同金额超客户信托基金:左侧红边,不覆盖上面的交期底色
  if (row.exceedsTrustFund) {
    className = className ? `${className} trust-fund-exceed` : "trust-fund-exceed";
  }
  return className;
};
// 台账审批状态(后端维护,与发货状态 statusTextMap 无关)
const getApprovalStatusType = status => {
  const map = {
    待审批: "warning",
    审核中: "primary",
    通过: "success",
    拒绝: "danger",
  };
  return map[status] || "info";
};
// 页签切换:换 ledgerType 重新查列表
const handleTabChange = () => {
  page.current = 1;
  expandedRowKeys.value = [];
  getList();
};
// 主表合计方法
const summarizeMainTable = (param) => {
@@ -1750,14 +1939,24 @@
  form.value = {};
  productData.value = [];
  selectedQuotation.value = null;
  selectedCustomerTrustFund.value = null;
  let userLists = await userListNoPage();
  userList.value = userLists.data;
  listCustomer({ current: -1, size: -1, type: 0 }).then((res) => {
    customerOption.value = res.data.records;
  });
  // 油库/储罐下拉(代储用),两者互相独立
  allOilDepot().then((res) => {
    oilDepotOptions.value = res.data || [];
  });
  allTankInfo().then((res) => {
    tankOptions.value = res.data || [];
  });
  form.value.entryPerson = userStore.id;
  if (type === "add") {
    // 新增时设置录入日期为当天
    // 新增时默认跟随当前页签的销售类型
    form.value.ledgerType = activeTab.value;
    // 录入日期默认为当天
    form.value.entryDate = getCurrentDate();
    // 签订日期默认为当天
    form.value.executionDate = getCurrentDate();
@@ -1770,10 +1969,15 @@
    getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
      form.value = { ...res };
      form.value.entryPerson = Number(res.entryPerson);
      productData.value = form.value.productData;
      // 历史单据/后端未返回时兜底为卖油,否则必填校验会卡住编辑
      form.value.ledgerType = form.value.ledgerType || "卖油";
      // 代储没有产品明细
      productData.value = form.value.productData || [];
      fileList.value = form.value.storageBlobVOs;
      // 编辑时设置自动生成为false,允许手动修改
      form.value.autoGenerateContractNo = false;
      // 回显信托基金,供代储合同金额实时比对
      loadCustomerTrustFund();
    });
  }
  // let userAll = await userStore.getInfo()
@@ -1784,6 +1988,18 @@
  // });
  form.value.entryDate = getCurrentDate(); // 设置默认录入日期为当前日期
  dialogFormVisible.value = true;
};
// 取该客户的信托基金,供代储合同金额实时比对(客户未维护即为空,不提示)
const loadCustomerTrustFund = () => {
  const id = form.value.customerId;
  if (!id) {
    selectedCustomerTrustFund.value = null;
    return;
  }
  getCustomer(id).then((res) => {
    selectedCustomerTrustFund.value = res?.data?.trustFund ?? null;
  });
};
// 打开报价单选择弹窗(仅审批通过)
@@ -1901,15 +2117,36 @@
const submitForm = () => {
  proxy.$refs["formRef"].validate((valid) => {
    if (valid) {
      console.log("productData.value--", productData.value);
      if (productData.value !== null && productData.value.length > 0) {
        form.value.productData = proxy.HaveJson(productData.value);
      form.value.type = 1;
      form.value.ledgerType = form.value.ledgerType || "卖油";
      if (form.value.ledgerType === "代储") {
        // 代储:卖存储位置,没有产品明细,合同金额手工填
        if (!form.value.oilDepotId) {
          proxy.$modal.msgWarning("代储必须选择油库");
          return;
        }
        if (!form.value.tankId) {
          proxy.$modal.msgWarning("代储必须选择储罐");
          return;
        }
        if (!(Number(form.value.contractAmount) > 0)) {
          proxy.$modal.msgWarning("代储必须填写合同金额");
          return;
        }
        delete form.value.productData;
      } else {
        proxy.$modal.msgWarning("请添加产品信息");
        return;
        // 卖油:合同金额由产品明细汇总,代储字段清空
        if (productData.value !== null && productData.value.length > 0) {
          form.value.productData = proxy.HaveJson(productData.value);
        } else {
          proxy.$modal.msgWarning("请添加产品信息");
          return;
        }
        form.value.oilDepotId = "";
        form.value.tankId = "";
        form.value.contractAmount = null;
      }
      form.value.storageBlobDTOs = fileList;
      form.value.type = 1;
      if (form.value.autoGenerateContractNo) {
        form.value.salesContractNo = "";
      }
@@ -3024,6 +3261,28 @@
  background-color: #f4defa;
}
/* 本笔合同金额超客户信托基金:只加左侧红边,避免覆盖上面的交期底色 */
:deep(.trust-fund-exceed) td:first-child {
  box-shadow: inset 3px 0 0 var(--el-color-danger);
}
.trust-fund-alert {
  margin-top: 6px;
  width: 100%;
}
.ledger-tabs {
  margin-bottom: 8px;
}
.ledger-tabs :deep(.el-tabs__header) {
  margin-bottom: 0;
}
.ledger-tabs :deep(.el-tabs__content) {
  display: none;
}
.table_list {
  margin-top: unset;
}