hsy
5 小时以前 2d3530a7c11557a40807ad7c0b9e302ce6ce3a9f
src/views/salesManagement/salesLedger/index.vue
@@ -117,6 +117,11 @@
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column label="审批中数量" width="120" align="center">
                <template #default="scope">
                  <span>{{ scope.row.pendingApprovalQuantity || 0 }}</span>
                </template>
              </el-table-column>
              <el-table-column
                label="快递公司"
                prop="expressCompany"
@@ -148,6 +153,7 @@
                </template>
              </el-table-column>
              <el-table-column label="数量" prop="quantity" />
              <el-table-column label="退货数量" prop="returnQuantity" />
              <el-table-column label="待发货数量" prop="noQuantity" />
              <el-table-column label="税率(%)" prop="taxRate" />
              <el-table-column
@@ -182,6 +188,7 @@
          </template>
        </el-table-column>
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column
          label="销售合同号"
          prop="salesContractNo"
@@ -210,10 +217,24 @@
          label="付款方式"
          prop="paymentMethod"
          show-overflow-tooltip
        />
        >
          <template #default="scope">
            <dict-tag
              :options="checkout_payment"
              :value="scope.row.paymentMethod"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="合同金额(元)"
          prop="contractAmount"
          width="220"
          show-overflow-tooltip
          :formatter="formattedNumber"
        />
        <el-table-column
          label="实际合同金额(元)"
          prop="netContractAmount"
          width="220"
          show-overflow-tooltip
          :formatter="formattedNumber"
@@ -309,6 +330,76 @@
            </el-button>
          </el-col>
        </el-row>
        <el-divider content-position="left">关联项目</el-divider>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="客户名称:" prop="customerId">
              <el-select
                v-model="form.customerId"
                placeholder="请选择"
                clearable
                :disabled="operationType === 'view'"
                filterable
              >
                <el-option
                  v-for="item in customerOption"
                  :key="item.id"
                  :label="item.customerName"
                  :value="item.id"
                >
                  {{
                    item.customerName + "——" + item.taxpayerIdentificationNumber
                  }}
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="项目名称:" prop="projectId">
              <el-select
                v-model="form.projectId"
                placeholder="请选择项目"
                clearable
                filterable
                :disabled="operationType === 'view'"
                @focus="previousProjectId = form.projectId"
                @change="handleProjectChange"
              >
                <el-option
                  v-for="item in projectOptions"
                  :key="item.id"
                  :label="item.no + ' - ' + item.title"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="关联合同:" prop="associatedContractIds">
              <el-select
                v-model="form.associatedContractIds"
                multiple
                placeholder="请选择关联合同"
                clearable
                filterable
                :disabled="operationType === 'view'"
                style="width: 100%"
              >
                <el-option
                  v-for="item in contractOptions"
                  :key="item.id"
                  :label="item.contractNo"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-divider content-position="left">台账信息</el-divider>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="销售合同号:" prop="salesContractNo">
@@ -359,44 +450,11 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="客户名称:" prop="customerId">
              <el-select
                v-model="form.customerId"
                placeholder="请选择"
                clearable
                :disabled="operationType === 'view'"
                filterable
              >
                <el-option
                  v-for="item in customerOption"
                  :key="item.id"
                  :label="item.customerName"
                  :value="item.id"
                >
                  {{
                    item.customerName + "——" + item.taxpayerIdentificationNumber
                  }}
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="项目名称:" prop="projectName">
              <el-input
                v-model="form.projectName"
                placeholder="请输入"
                clearable
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="签订日期:" prop="executionDate">
              <el-date-picker
                style="width: 100%"
                v-model="form.executionDate"
                @change="(val) => { if(val) form.year = parseInt(val.substring(0, 4)) }"
                value-format="YYYY-MM-DD"
                format="YYYY-MM-DD"
                type="date"
@@ -408,12 +466,19 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="付款方式">
              <el-input
              <el-select
                v-model="form.paymentMethod"
                placeholder="请输入"
                placeholder="请选择付款方式"
                clearable
                :disabled="operationType === 'view'"
              />
              >
                <el-option
                  v-for="item in checkout_payment"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
@@ -470,13 +535,160 @@
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="签单单位:" prop="signingUnitId">
              <el-tree-select
                v-model="form.signingUnitId"
                :data="deptOptions"
                :props="{ value: 'id', label: 'label', children: 'children' }"
                value-key="id"
                placeholder="请选择签单单位"
                check-strictly
                clearable
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="办事处:" prop="officeId">
              <el-tree-select
                v-model="form.officeId"
                :data="deptOptions"
                :props="{ value: 'id', label: 'label', children: 'children' }"
                value-key="id"
                placeholder="请选择办事处"
                check-strictly
                clearable
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="组负责人:" prop="groupLeaderId">
              <el-select
                v-model="form.groupLeaderId"
                filterable
                placeholder="请选择组负责人"
                clearable
                :disabled="operationType === 'view'"
              >
                <el-option
                  v-for="item in userList"
                  :key="item.userId"
                  :label="item.nickName"
                  :value="item.userId"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="年份:">
              <el-input
                v-model="form.year"
                placeholder="自动取签订日期"
                disabled
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="是否开发票:">
              <el-switch
                v-model="form.isInvoice"
                :active-value="1"
                :inactive-value="0"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否中标:">
              <el-switch
                v-model="form.isBid"
                :active-value="1"
                :inactive-value="0"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12" v-if="form.isBid === 1">
            <el-form-item label="中标价:">
              <el-input-number
                v-model="form.bidPrice"
                :precision="2"
                :step="1000"
                :min="0"
                style="width: 100%"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.isBid !== 1">
            <el-form-item label="未中标原因:">
              <el-input
                v-model="form.unbidReason"
                placeholder="请输入未中标原因"
                clearable
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="合同原件约定回传日期:">
              <el-date-picker
                style="width: 100%"
                v-model="form.contractOriginalReturnDate"
                value-format="YYYY-MM-DD"
                format="YYYY-MM-DD"
                type="date"
                placeholder="请选择日期"
                clearable
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="备注:" prop="remarks">
              <el-input
                v-model="form.remarks"
                placeholder="请输入"
                clearable
                type="textarea"
                :rows="2"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row v-if="operationType !== 'view'" :gutter="30">
          <el-col :span="24">
            <el-form-item label="附件材料:" prop="salesLedgerFiles">
              <FileUpload
                v-model:file-list="fileList"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-divider content-position="left">产品信息</el-divider>
        <el-row>
          <el-form-item label="产品信息:" prop="entryDate">
          <el-form-item label="" prop="entryDate">
            <el-button
              v-if="operationType !== 'view'"
              type="primary"
              @click="openProductForm('add')"
              >添加
              >添加明细
            </el-button>
            <el-button
              v-if="operationType !== 'view'"
@@ -553,30 +765,6 @@
            </template>
          </el-table-column>
        </el-table>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="备注:" prop="remarks">
              <el-input
                v-model="form.remarks"
                placeholder="请输入"
                clearable
                type="textarea"
                :rows="2"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row v-if="operationType !== 'view'" :gutter="30">
          <el-col :span="24">
            <el-form-item label="附件材料:" prop="salesLedgerFiles">
              <FileUpload
                v-model:file-list="fileList"
                :disabled="operationType === 'view'"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </FormDialog>
    <!-- 从报价单导入(仅审批通过) -->
@@ -1092,6 +1280,56 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="发货单据:" prop="shippingDocument">
              <el-input
                v-model="deliveryForm.shippingDocument"
                placeholder="请输入发货单据"
                clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="8">
            <el-form-item label="是否对账:" prop="isReconciled">
              <el-switch v-model="deliveryForm.isReconciled" :active-value="1" :inactive-value="0" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="是否结算:" prop="isSettled">
              <el-switch v-model="deliveryForm.isSettled" :active-value="1" :inactive-value="0" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="是否已开票:" prop="isInvoiced">
              <el-switch v-model="deliveryForm.isInvoiced" :active-value="1" :inactive-value="0" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12" v-if="deliveryForm.isReconciled === 1">
            <el-form-item label="对账单归档情况:" prop="statementArchivingStatus">
              <el-input
                type="textarea"
                v-model="deliveryForm.statementArchivingStatus"
                placeholder="请输入对账单归档情况"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="deliveryForm.isSettled === 1">
            <el-form-item label="结算单归档情况:" prop="settlementArchivingStatus">
              <el-input
                type="textarea"
                v-model="deliveryForm.settlementArchivingStatus"
                placeholder="请输入结算单归档情况"
                clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="库存:" prop="batchNo">
              <el-table
                :data="deliveryForm.batchNoList"
@@ -1163,9 +1401,11 @@
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
import { ElMessageBox, ElMessage } from "element-plus";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
import { userListNoPage, deptTreeSelect } from "@/api/system/user.js";
import { listProject, getProject } from "@/api/projectManagement/project.js";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
import { contractListNoPage } from "@/api/salesManagement/contractManagement.js";
import {
  ledgerListPage,
  productList,
@@ -1195,12 +1435,15 @@
const route = useRoute();
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
const { tax_rate } = proxy.useDict("tax_rate");
const { tax_rate, checkout_payment } = proxy.useDict("tax_rate", "checkout_payment");
const tableData = ref([]);
const productData = ref([]);
const selectedRows = ref([]);
const productSelectedRows = ref([]);
const userList = ref([]);
const deptOptions = ref([]);
const projectOptions = ref([]);
const contractOptions = ref([]);
const customerOption = ref([]);
const productOptions = ref([]);
const modelOptions = ref([]);
@@ -1235,6 +1478,18 @@
    maintenanceTime: "",
    productData: [],
    executionDate: "",
    projectId: undefined,
    associatedContractIds: [],
    year: "",
    signingUnitId: undefined,
    officeId: undefined,
    groupLeaderId: undefined,
    isInvoice: 0,
    bidPrice: undefined,
    isBid: 0,
    unbidReason: "",
    contractOriginalReturnDate: "",
    hasProductionRecord: false,
    createTime: "",
  },
@@ -1310,6 +1565,51 @@
  total: 0,
});
const selectedQuotation = ref(null);
const previousProjectId = ref(null);
const handleProjectChange = (val) => {
  if (productData.value && productData.value.length > 0) {
    ElMessageBox.confirm("当前已录入产品明细,切换项目将被覆盖,是否继续?", "提示", {
      type: "warning",
    })
      .then(() => {
        previousProjectId.value = val;
        fetchAndPopulateProject(val);
      })
      .catch(() => {
        form.value.projectId = previousProjectId.value;
      });
  } else {
    previousProjectId.value = val;
    fetchAndPopulateProject(val);
  }
};
const fetchAndPopulateProject = (val) => {
  let proj = projectOptions.value.find((p) => p.id === val);
  form.value.projectName = proj ? proj.title : "";
  if (!val) {
    productData.value = [];
    return;
  }
  getProject(val).then((res) => {
    const projectInfo = res.data;
    if (projectInfo.info && projectInfo.info.clientId) {
      form.value.customerId = projectInfo.info.clientId;
    }
    if (projectInfo.salesLedgerProductList) {
      productData.value = projectInfo.salesLedgerProductList.map((item) => ({
        ...item,
        id: undefined,
        salesLedgerId: undefined
      }));
    } else {
      productData.value = [];
    }
  });
};
// 发货相关
const deliveryFormVisible = ref(false);
@@ -1410,6 +1710,12 @@
    expressCompany: "",
    expressNumber: "",
    type: "货车", // 货车, 快递
    shippingDocument: "",
    isReconciled: 0,
    statementArchivingStatus: "",
    isSettled: 0,
    settlementArchivingStatus: "",
    isInvoiced: 0,
  },
  deliveryRules: {
    shippingCarNumber: [
@@ -1737,6 +2043,9 @@
  form.value = {};
  productData.value = [];
  selectedQuotation.value = null;
  deptTreeSelect().then(res => deptOptions.value = res.data);
  listProject({}).then(res => projectOptions.value = res.rows || res.data.records || res.data);
  contractListNoPage({}).then(res => contractOptions.value = res.data);
  let userLists = await userListNoPage();
  userList.value = userLists.data;
  listCustomer({ current: -1, size: -1, type: 0 }).then((res) => {
@@ -1749,7 +2058,7 @@
    // 签订日期默认为当天
    form.value.executionDate = getCurrentDate();
    // 创建时间默认为当天
    form.value.createTime = getCurrentDate();
    form.value.createTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
    // 默认自动生成销售合同号
    form.value.autoGenerateContractNo = true;
  } else {
@@ -2007,6 +2316,12 @@
    return;
  }
  // 检查是否只剩一条数据,销售台账至少保留一条产品
  if (productData.value.length <= 1) {
    proxy.$modal.msgWarning("销售台账至少需要保留一条产品数据");
    return;
  }
  if (operationType.value === "add") {
    productData.value = productData.value.filter(
      (item) => !productSelectedRows.value.includes(item)
@@ -2155,7 +2470,7 @@
};
// 打印功能
const handlePrint = async () => {
  const handlePrint = async () => {
  if (selectedRows.value.length === 0) {
    proxy.$modal.msgWarning("请选择要打印的数据");
    return;
@@ -2512,11 +2827,7 @@
// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return getCurrentDate();
  const date = new Date(dateString);
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  return `${year}/${month}/${day}`;
  return dayjs(dateString).format("YYYY/MM/DD HH:mm:ss");
};
// 格式化日期时间
const formatDateTime = (date) => {
@@ -2803,7 +3114,7 @@
/**
 * 判断是否可以发货
 * 只有在产品状态是充足,发货状态是待发货和审核拒绝的时候才可以发货
 * 只有在产品状态是充足,发货状态是待发货、审批中、审核拒绝、部分发货的时候才可以发货
 * @param row 行数据
 */
const canShip = (row) => {
@@ -2815,15 +3126,16 @@
  // 获取发货状态
  const shippingStatus = row.shippingStatus;
  // 如果已发货(有发货日期或车牌号),不能再次发货
  // 如果已发货,不能再次发货
  if (shippingStatus === "已发货") {
    return false;
  }
  // 发货状态必须是"待发货"或"审核拒绝"
  // 发货状态必须是"待发货"、"审批中"、"审核拒绝"或"部分发货"
  const statusStr = shippingStatus ? String(shippingStatus).trim() : "";
  return (
    statusStr === "待发货" ||
    statusStr === "审批中" ||
    statusStr === "审核拒绝" ||
    statusStr === "部分发货"
  );
@@ -2844,9 +3156,15 @@
  // 检查是否可以发货
  if (!canShip(row)) {
    proxy.$modal.msgWarning(
      "只有在产品状态是充足,发货状态是待发货或审核拒绝的时候才可以发货"
      "只有在产品状态是充足,发货状态是待发货、审批中、审核拒绝或部分发货的时候才可以发货"
    );
    return;
  }
  // 审批中时提示用户已有待审批的发货记录
  const statusStr = row.shippingStatus ? String(row.shippingStatus).trim() : "";
  if (statusStr === "审批中") {
    proxy.$modal.msgWarning("该产品存在待审批的发货记录,请注意避免重复提交");
  }
  currentDeliveryRow.value = row;
@@ -2971,13 +3289,22 @@
  let res = await userStore.getInfo();
  currentFactoryName.value = res.user.currentFactoryName;
};
onMounted(() => {
onMounted(async () => {
  searchForm.salesContractNo = route.query.salesContractNo;
  getList();
  userListNoPage().then((res) => {
    userList.value = res.data;
  });
  getCurrentFactoryName();
  if (route.query.action === "add") {
    await openForm("add");
    if (route.query.projectId) {
      const pId = Number(route.query.projectId);
      form.value.projectId = pId;
      fetchAndPopulateProject(pId);
    }
  }
});
</script>