1、华玺砂浆采购代码移植至军泰伟业
2、华玺砂浆发货和发货审核代码移植至军泰伟业
3、华玺砂浆报修和报修审核代码移植至军泰伟业
已添加3个文件
已修改11个文件
1170 ■■■■ 文件已修改
src/api/collaborativeApproval/shipmentReview.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/procurementManagement/procurementLedger.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/salesLedger.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/usePaginationApi.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/shipmentReview/fileList.vue 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/shipmentReview/index.vue 340 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/Form/RepairForm.vue 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/Modal/MaintainModal.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/Modal/RepairModal.vue 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/index.vue 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/spareParts/index.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementInvoiceLedger/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementLedger/index.vue 393 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 146 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/collaborativeApproval/shipmentReview.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
// å‘货审批
import request from "@/utils/request";
// èŽ·å–å‘è´§å®¡æ‰¹åˆ—è¡¨
export function getShipmentApprovalList(query) {
    return request({
        url: '/shipmentApproval/listPage',
        method: 'get',
        params: query,
    })
}
// å‘货申请批准
// /shipmentApproval/update
export function approveShipment(query) {
    return request({
        url: '/shipmentApproval/update',
        method: 'post',
        data: query,
    })
}
src/api/procurementManagement/procurementLedger.js
@@ -72,3 +72,30 @@
    method: "get",
  });
}
export function updateApprovalStatus(query) {
    return request({
        url: "/purchase/ledger/updateApprovalStatus",
        method: "post",
        data: query,
    });
}
// ä¿å­˜é‡‡è´­æ¨¡æ¿
// /purchase/ledger/addPurchaseTemplate
export function addPurchaseTemplate(data) {
    return request({
        url: "/purchase/ledger/addPurchaseTemplate",
        method: "post",
        data: data,
    });
}
// æŸ¥è¯¢é‡‡è´­æ¨¡æ¿
// /purchase/ledger/getPurchaseTemplateList
export function getPurchaseTemplateList(query) {
    return request({
        url: "/purchase/ledger/getPurchaseTemplateList",
        method: "get",
        params: query,
    });
}
src/api/salesManagement/salesLedger.js
@@ -109,3 +109,11 @@
    params: query,
  });
}
// é”€å”®å°è´¦é¡µé¢å‘货,查询库存是否充足
export function getProductInventory(query) {
    return request({
        url: "/sales/ledger/getProductInventory",
        method: "get",
        params: query,
    });
}
src/hooks/usePaginationApi.jsx
@@ -87,7 +87,7 @@
      current: pagination.currentPage,
      size: pagination.pageSize
    }).then(({ code, data, msg, ...rest }) => {
      if (code == 200) {
      if (code === 200) {
        // pagination.currentPage = meta.current_page;
        // pagination.pageSize = meta.per_page;
        pagination.total = data.total;
@@ -99,7 +99,11 @@
        loading.value = false;
        ElMessage({ message: msg, type: "error" });
      }
    });
    }).catch(() => {
        loading.value = false;
        ElMessage({ message: msg, type: "error" });
    }).finally(() => {});
  }
  function onSizeChange(val) {
src/views/collaborativeApproval/shipmentReview/fileList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
<template>
  <el-dialog v-model="dialogVisible" title="附件" width="40%" :before-close="handleClose">
    <el-table :data="tableData" border height="40vh">
      <el-table-column label="附件名称" prop="name" min-width="400" show-overflow-tooltip />
      <el-table-column fixed="right" label="操作" width="100" align="center">
        <template #default="scope">
          <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">下载</el-button>
          <el-button link type="primary" size="small" @click="lookFile(scope.row)">预览</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
  <filePreview ref="filePreviewRef" />
</template>
<script setup>
import { ref } from 'vue'
import filePreview from '@/components/filePreview/index.vue'
const dialogVisible = ref(false)
const tableData = ref([])
const { proxy } = getCurrentInstance();
const filePreviewRef = ref()
const handleClose = () => {
  dialogVisible.value = false
}
const open = (list) => {
  dialogVisible.value = true
  tableData.value = list
}
const downLoadFile = (row) => {
  proxy.$download.name(row.url);
}
const lookFile = (row) => {
  filePreviewRef.value.open(row.url)
}
defineExpose({
  open
})
</script>
<style></style>
src/views/collaborativeApproval/shipmentReview/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,340 @@
<template>
  <div class="app-container">
    <div class="search_form">
      <div>
        <span class="search_title">销售合同号:</span>
        <el-input
            v-model="searchForm.salesContractNo"
            style="width: 240px"
            placeholder="请输入销售合同号搜索"
            @change="handleQuery"
            clearable
            :prefix-icon="Search"
        />
        <span class="search_title ml10">审批状态:</span>
        <el-select v-model="searchForm.approveStatus" clearable @change="handleQuery" style="width: 240px">
          <el-option label="待审核" :value="2" />
          <el-option label="审核成功" :value="3" />
          <el-option label="审核失败" :value="4" />
        </el-select>
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
        >搜索</el-button
        >
      </div>
      <div>
<!--        <el-button type="primary" @click="openForm('add')">新增</el-button>-->
        <el-button @click="handleOut">导出</el-button>
<!--        <el-button type="danger" plain @click="handleDelete">删除</el-button>-->
      </div>
    </div>
    <div class="table_list">
      <PIMTable
          rowKey="id"
          :column="tableColumn"
          :tableData="tableData"
          :page="page"
          :isSelection="true"
          @selection-change="handleSelectionChange"
          :tableLoading="tableLoading"
          @pagination="pagination"
          :total="page.total"
      ></PIMTable>
    </div>
    <info-form-dia ref="infoFormDia" @close="handleQuery" :approveType="approveType"></info-form-dia>
    <approval-dia ref="approvalDia" @close="handleQuery"></approval-dia>
    <FileList ref="fileListRef" />
  </div>
</template>
<script setup>
import FileList from "./fileList.vue";
import { Search } from "@element-plus/icons-vue";
import {onMounted, ref} from "vue";
import {ElMessageBox} from "element-plus";
import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
import {getShipmentApprovalList, approveShipment} from "@/api/collaborativeApproval/shipmentReview.js";
// import {approveProcessDelete, approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess.js";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
// å®šä¹‰ç»„件接收的props
const props = defineProps({
  approveType: {
    type: [Number, String],
    default: 6
  }
});
const userList = ref([]);
const userStore = useUserStore();
const data = reactive({
  searchForm: {
    approveId: "",
    approveStatus: "",
  },
});
const { searchForm } = toRefs(data);
const tableColumn = ref([
  {
    label: "审批状态",
    prop: "approveStatus",
    dataType: "tag",
    width: 100,
    formatData: (params) => {
      if (params === 2) {
        return "待审核";
      } else if (params === 3) {
        return "审核完成";
      } else if (params === 4) {
        return "审核驳回";
      } else {
        return '未知状态';
      }
    },
    formatType: (params) => {
      if (params === 0) {
        return "warning";
      } else if (params === 2) {
        return "info";
      } else if (params === 3) {
        return "success";
      } else if (params === 4) {
        return "danger";
      } else {
        return 'danger';
      }
    },
  },
  {
    label: "销售合同号",
    prop: "salesContractNo",
    width: 170
  },
  {
    label: "客户名称",
    prop: "customerName",
    width: 200
  },
  {
    label: "产品大类",
    prop: "productCategory",
    width: 200
  },
  {
    label: "规格型号",
    prop: "specificationModel",
    width: 220
  },
  {
    label: "申请人",
    prop: "approveUserId",
    width: 120,
    align: "center",
    formatData:(params)=>{
      const user = userList.value.find(item => item.userId === params)
      return user ? user.nickName : '--'
    }
  },
  {
    label: "车牌号",
    prop: "shippingCarNumber",
    width: 120,
  },
  {
    label: "申请人",
    prop: "approveUserId",
    width: 120,
  },
  {
    label: "申请日期",
    prop: "executionDate",
    width: 200
  },
  {
    label: "当前审批人",
    prop: "salesman",
    width: 120
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: "right",
    width: 120,
    operation: [
      {
        name: "通过",
        type: "text",
        clickFun: (row) => {
          handleApproval("通过", row);
        },
        disabled: (row) => row.approveStatus !== 2
      },
      {
        name: "驳回",
        type: "text",
        clickFun: (row) => {
          handleApproval("驳回", row);
        },
        disabled: (row) => row.approveStatus !== 2
      },
      // {
      //   name: "编辑",
      //   type: "text",
      //   clickFun: (row) => {
      //     openForm("edit", row);
      //   },
      //   disabled: (row) => row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4
      // },
      // {
      //   name: "审核",
      //   type: "text",
      //   clickFun: (row) => {
      //     openApprovalDia("approval", row);
      //   },
      //   disabled: (row) => row.approveUserCurrentId == null || row.approveStatus == 2 || row.approveStatus == 3 || row.approveStatus == 4 || row.approveUserCurrentId !== userStore.id
      // },
      // {
      //   name: "详情",
      //   type: "text",
      //   clickFun: (row) => {
      //     openApprovalDia('view', row);
      //   },
      // },
      // {
      //   name: "附件",
      //   type: "text",
      //   clickFun: (row) => {
      //     downLoadFile(row);
      //   },
      // },
    ],
  },
]);
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const page = reactive({
  current: 1,
  size: 100,
  total: 0
});
const infoFormDia = ref()
const approvalDia = ref()
const { proxy } = getCurrentInstance()
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
  page.current = 1;
  getList();
};
const fileListRef = ref(null)
const downLoadFile = (row) => {
  fileListRef.value.open(row.commonFileList)
}
const pagination = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList();
};
const getList =async () => {
  let userLists = await userListNoPage();
  userList.value = userLists.data;
  tableLoading.value = true;
  getShipmentApprovalList({...page, ...searchForm.value,approveType:props.approveType}).then(res => {
    tableLoading.value = false;
    tableData.value = res.data.records
    page.total = res.data.total;
  }).catch(err => {
    tableLoading.value = false;
  })
};
// å¯¼å‡º
const handleOut = () => {
  const type = Number(props.approveType || 6)
  const urlMap = {
    0: "/shipmentApproval/export",
  }
  const url = urlMap[type] || urlMap[0]
  const nameMap = {
    0: "发货审核表",
  }
  const fileName = nameMap[type] || nameMap[0]
  proxy.download(url, {}, `${fileName}.xlsx`)
}
// è¡¨æ ¼é€‰æ‹©æ•°æ®
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
// æ‰“开新增、编辑弹框
const openForm = (type, row) => {
  nextTick(() => {
    infoFormDia.value?.openDialog(type, row)
  })
};
// æ‰“开新增检验弹框
const openApprovalDia = (type, row) => {
  nextTick(() => {
    approvalDia.value?.openDialog(type, row)
  })
};
// å®¡æ ¸é€šè¿‡/驳回
const handleApproval = (name = "审核",row) => {
  ElMessageBox.confirm(`选中的内容将被${name},是否确认${name}?`, "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async()=>{
    let res = await approveShipment({
      id: row.id,
      approveStatus: name === "通过" ? 3 : 4
    });
    if(res.code === 200){
      proxy.$modal.msgSuccess(`${name}成功`);
    }else{
      proxy.$modal.msgError(`${name}失败`);
    }
    await getList()
  }).catch(err=>{
    proxy.$modal.msgError(`未知错误,请联系管理员`);
  })
};
// åˆ é™¤
const handleDelete = () => {
  let ids = [];
  if (selectedRows.value.length > 0) {
    ids = selectedRows.value.map((item) => item.approveId);
  } else {
    proxy.$modal.msgWarning("请选择数据");
    return;
  }
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
      .then(() => {
        approveProcessDelete(ids).then((res) => {
          proxy.$modal.msgSuccess("删除成功");
          getList();
        });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
onMounted(() => {
  getList();
});
</script>
<style scoped></style>
src/views/equipmentManagement/repair/Form/RepairForm.vue
@@ -1,9 +1,9 @@
<template>
  <el-form :model="form" label-width="100px">
  <el-form :model="form" ref="formModelRefs" :rules="rules" label-width="100px">
    <el-row>
      <el-col :span="12">
        <el-form-item label="设备名称">
          <el-select v-model="form.deviceLedgerId" @change="setDeviceModel">
        <el-form-item label="设备名称" prop="deviceLedgerId">
          <el-select v-model="form.deviceLedgerId" @change="setDeviceModel" filterable>
            <el-option
              v-for="(item, index) in deviceOptions"
              :key="index"
@@ -14,7 +14,7 @@
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="规格型号">
        <el-form-item label="规格型号" prop="deviceModel">
          <el-input
            v-model="form.deviceModel"
            placeholder="请输入规格型号"
@@ -23,7 +23,7 @@
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="报修日期">
        <el-form-item label="报修日期" prop="repairTime">
          <el-date-picker
            v-model="form.repairTime"
            placeholder="请选择报修日期"
@@ -36,15 +36,15 @@
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="报修人">
          <el-input v-model="form.repairName" placeholder="请输入报修人" />
        <el-form-item label="报修人员" prop="repairName">
          <el-input v-model="form.repairName" placeholder="请输入报修人员" />
        </el-form-item>
      </el-col>
    </el-row>
    <el-row v-if="id">
      <el-col :span="12">
        <el-form-item label="报修状态">
          <el-select v-model="form.status">
          <el-select v-model="form.status" prop="status">
            <el-option label="待维修" :value="0"></el-option>
            <el-option label="完结" :value="1"></el-option>
            <el-option label="失败" :value="2"></el-option>
@@ -53,8 +53,27 @@
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="12">
        <el-form-item label="报修金额" prop="maintenancePrice">
          <el-input-number
              style="width: 100%"
              :min="0"
              v-model="form.maintenancePrice"
              placeholder="请输入保修金额"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="审批人员" prop="approverId">
          <el-select v-model="form.approverId" placeholder="请选择审批人员" clearable>
            <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
          </el-select>
        </el-form-item>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="24">
        <el-form-item label="故障现象">
        <el-form-item label="故障现象" prop="remark">
          <el-input
            v-model="form.remark"
            :rows="2"
@@ -68,9 +87,12 @@
</template>
<script setup>
import {onMounted} from "vue"
import dayjs from "dayjs";
import useFormData from "@/hooks/useFormData";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
const { id } = defineProps(["id"])
@@ -80,20 +102,44 @@
const userStore = useUserStore();
const deviceOptions = ref([]);
const formModelRefs = ref(null)
const userList = ref(null)
const loadDeviceName = async () => {
  const { data } = await getDeviceLedger();
  deviceOptions.value = data;
};
const rules = {
  deviceLedgerId: [{ required: true, message: "请选择设备名称", trigger: "change" }],
  repairTime: [{ required: true, message: "请选择报修日期", trigger: "change" }],
  repairName: [{ required: true, message: "请输入报修人", trigger: "blur" }],
  remark: [{ required: true, message: "请输入故障现象", trigger: "blur" }],
  maintenancePrice: [{ required: true, message: "请输入保修金额", trigger: "blur" }],
  approverId:[{required: true,message: "请选择审批人", trigger: "change"}]
};
// æ ¡éªŒè¡¨å•是否合规
const submitForm = async () => {
  if (!formModelRefs.value) return false;
  try {
    await formModelRefs.value.validate();
    return true; // è¡¨å•验证通过
  } catch (error) {
    return false; // è¡¨å•验证失败
  }
};
const { form, resetForm } = useFormData({
  deviceLedgerId: undefined, // è®¾å¤‡Id
  deviceName: undefined, // è®¾å¤‡åç§°
  deviceModel: undefined, // è§„格型号
  repairTime: undefined, // æŠ¥ä¿®æ—¥æœŸ
  repairTime: dayjs().format("YYYY-MM-DD"), // æŠ¥ä¿®æ—¥æœŸï¼Œé»˜è®¤å½“天
  repairName: userStore.nickName, // æŠ¥ä¿®äºº
  remark: undefined, // æ•…障现象
  status: 0, // æŠ¥ä¿®çŠ¶æ€
  maintenancePrice:0, // ä¿ä¿®é‡‘额
});
const setDeviceModel = (id) => {
@@ -113,17 +159,21 @@
  form.repairName = data.repairName;
  form.remark = data.remark;
  form.status = data.status;
  form.maintenancePrice = data.maintenancePrice
};
// onMounted(() => {
//   loadDeviceName();
// });
onMounted(async() => {
  // loadDeviceName();
  let userLists = await userListNoPage();
  userList.value = userLists.data;
});
defineExpose({
  loadDeviceName,
  resetForm,
  getForm,
  setForm,
  submitForm
});
</script>
src/views/equipmentManagement/repair/Modal/MaintainModal.vue
@@ -1,5 +1,5 @@
<template>
  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr">
  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr" draggable>
    <MaintainForm ref="maintainFormRef" />
    <template #footer>
            <el-button type="primary" @click="sendForm" :loading="loading">
src/views/equipmentManagement/repair/Modal/RepairModal.vue
@@ -1,5 +1,5 @@
<template>
  <el-dialog v-model="visible" :title="modalOptions.title" @close="close">
  <el-dialog v-model="visible" :title="modalOptions.title" @close="close" draggable>
    <RepairForm ref="repairFormRef" :id="id" />
    <template #footer>
            <el-button type="primary" @click="sendForm" :loading="loading">
@@ -38,17 +38,32 @@
} = useModal({ title: "设备报修" });
const sendForm = async () => {
  loading.value = true;
  const form = await repairFormRef.value.getForm();
  const { code } = id.value
    ? await editRepair({ id: unref(id), ...form })
    : await addRepair(form);
  if (code == 200) {
    ElMessage.success(`${id ? "编辑" : "新增"}报修成功`);
  try {
    // å¼€å§‹åŠ è½½
    loading.value = true;
    // æäº¤è¡¨å•并获取校验结果
    const submitStatus = await repairFormRef.value.submitForm();
    if (!submitStatus) {
      // å¦‚果表单验证失败,取消加载状态
      loading.value = false;
      return;
    }
    // èŽ·å–è¡¨å•æ•°æ®
    const form = await repairFormRef.value.getForm();
    // æ ¹æ®æ˜¯å¦æœ‰ID决定是编辑还是新增
    const { code } = id.value
        ? await editRepair({ id: unref(id), ...form })
        : await addRepair(form);
    if (code === 200) {
      ElMessage.success(`${id ? "编辑" : "新增"}报修成功`);
      emits("ok");
    }
  } catch (error) {
  } finally {
    // æ— è®ºæˆåŠŸè¿˜æ˜¯å¤±è´¥ï¼Œéƒ½å–æ¶ˆåŠ è½½çŠ¶æ€
    loading.value = false;
    closeModal();
    emits("ok");
  }
  loading.value = false;
};
const openAdd = async () => {
src/views/equipmentManagement/repair/index.vue
@@ -71,7 +71,7 @@
          <el-button
            type="primary"
            icon="Plus"
            :disabled="multipleList.length !== 1"
            :disabled="multipleList.length !== 1 || multipleList[0]?.status !== 1"
            @click="addMaintain"
          >
            æ–°å¢žç»´ä¿®
@@ -86,7 +86,7 @@
            type="danger"
            icon="Delete"
            :disabled="multipleList.length <= 0"
            @click="delRepairByIds(multipleList.map((item) => item.id))"
            @click="delRepairByIds(multipleList)"
          >
            æ‰¹é‡åˆ é™¤
          </el-button>
@@ -106,9 +106,12 @@
        @pagination="changePage"
      >
        <template #statusRef="{ row }">
          <el-tag v-if="row.status === 2" type="danger">失败</el-tag>
          <el-tag v-if="row.status === 1" type="success">完结</el-tag>
          <el-tag v-if="row.status === 0" type="warning">待维修</el-tag>
          <el-tag v-if="row.status === 5" type="danger">维修失败</el-tag>
          <el-tag v-if="row.status === 4" type="danger">维修成功</el-tag>
          <el-tag v-if="row.status === 3" type="danger">维修中</el-tag>
          <el-tag v-if="row.status === 2" type="danger">审核失败</el-tag>
          <el-tag v-if="row.status === 1" type="success">审核通过</el-tag>
          <el-tag v-if="row.status === 0" type="warning">审核中</el-tag>
        </template>
        <template #operation="{ row }">
          <el-button
@@ -116,6 +119,7 @@
            text
            icon="editPen"
            @click="editRepair(row.id)"
            :disabled="row.status !== 0"
          >
            ç¼–辑
          </el-button>
@@ -123,7 +127,8 @@
            type="danger"
            text
            icon="delete"
            @click="delRepairByIds(row.id)"
            @click="delRepairByIds(row)"
            :disabled="row.status !== 0"
          >
            åˆ é™¤
          </el-button>
@@ -282,15 +287,40 @@
// å•行删除
const delRepairByIds = async (ids) => {
  let isDel = false
  if(Array.isArray(ids)){
    ids.forEach((item)=>{
      if(item.status !== 0){
        isDel = true
      }
    })
  }else{
    if(ids.status !== 0){
      isDel = true
    }
  }
  if(isDel){
    ElMessage.warning("只能删除审核中的报修数据");
    return
  }
  ElMessageBox.confirm("确认删除报修数据, æ­¤æ“ä½œä¸å¯é€†?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    const { code } = await delRepair(ids);
    let idsList = ""
    if(Array.isArray(ids)){
      idsList = multipleList.value.map((item) => item.id);
      console.log(idsList)
    }else{
      idsList = ids.id
    }
    const { code } = await delRepair(idsList);
    if (code === 200) {
      ElMessage.success("删除成功");
      getTableData();
      await getTableData();
    }
  });
};
src/views/equipmentManagement/spareParts/index.vue
@@ -41,8 +41,7 @@
              ç¼–辑
            </el-button>
            <el-button
              type="text"
              size="small"
                            link
              @click="() => deleteCategory(row.id)"
              style="color: #f56c6c;"
              :disabled="loading"
@@ -70,17 +69,15 @@
        <el-form-item label="描述" prop="description">
          <el-input v-model="form.description"></el-input>
        </el-form-item>
        <el-form-item label="上级分类" prop="parentId">
          <el-select v-model="form.parentId" placeholder="请选择上级分类">
            <el-option label="无上级分类" :value="null"></el-option>
            <el-option
              v-for="(item, index) in categories"
              :key="index"
              :label="item.name"
              :value="item.id"
            ></el-option>
          </el-select>
        <el-form-item label="ä»·æ ¼" prop="price">
          <el-input-number
            v-model="form.price"
            placeholder="请输入价格"
            :min="0"
            :step="0.01"
            :precision="2"
            style="width: 100%"
          ></el-input-number>
        </el-form-item>
      </el-form>
      <template #footer>
src/views/procurementManagement/procurementInvoiceLedger/index.vue
@@ -222,7 +222,7 @@
    },
    {
      fixed: "right",
      width: 190,
      width: 150,
      label: "操作",
      dataType: "slot",
      slot: "operation",
src/views/procurementManagement/procurementLedger/index.vue
@@ -238,16 +238,25 @@
            </el-form-item>
          </el-col>
                    <el-col :span="12">
                        <el-form-item label="付款方式">
                            <el-input
                                v-model="form.paymentMethod"
                                placeholder="请输入"
                                clearable
                            />
                        </el-form-item>
            <el-form-item label="项目名称" prop="projectName">
              <el-input
                  v-model="form.projectName"
                  placeholder="请输入"
                  clearable
              />
            </el-form-item>
                    </el-col>
        </el-row>
                <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="付款方式">
              <el-input
                  v-model="form.paymentMethod"
                  placeholder="请输入"
                  clearable
              />
            </el-form-item>
          </el-col>
                    <el-col :span="12">
                        <el-form-item label="签订日期:" prop="executionDate">
                            <el-date-picker
@@ -264,14 +273,26 @@
                </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="录入人:" prop="recorderId">
            <el-form-item label="审批人:" prop="approverId">
              <el-select
                v-model="form.recorderId"
                placeholder="请选择"
                clearable
                filterable
                default-first-option
                :reserve-keyword="false"
                  v-model="form.approverId"
                  placeholder="请选择审批人"
                  clearable
              >
                <el-option
                    v-for="item in userList"
                    :key="item.userId"
                    :label="item.nickName"
                    :value="item.userId"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="录入人:" prop="recorderId" v-show="false">
              <el-select
                  v-model="form.recorderId"
                  placeholder="请选择"
                  clearable
                  disabled
              >
                <el-option
                  v-for="item in userList"
@@ -305,6 +326,37 @@
              >删除</el-button
            >
          </el-form-item>
          <div class="select-button-group" style="width: 220px; margin: 20px 0;" v-if="operationType === 'add'">
            <el-select
                filterable
                allow-create
                :reserve-keyword="true"
                :default-first-option="false"
                v-model="templateName"
                :input-value="filterInputValue"
                @filter-change="onTemplateFilterChange"
                @change="onTemplateChange"
                style="width: 180px; border-right: none; border-radius: 4px 0 0 4px;"
                placeholder="请选择"
                class="no-arrow-select"
            >
              <el-option
                  v-for="item in templateList"
                  :key="item.value"
                  :label="item.templateName"
                  :value="item.templateName"
              ></el-option>
            </el-select>
            <!-- æŒ‰é’®ï¼šä¸Ž Select é«˜åº¦åŒ¹é…ï¼ŒåŽ»æŽ‰å·¦ä¾§è¾¹æ¡†ï¼Œæ— ç¼è¡”æŽ¥ -->
            <el-button
                size="small"
                style="height: 32px; border-radius: 0 4px 4px 0; margin-left: -1px;"
                @click="handleButtonClick"
                :disabled="!templateName || templateName.trim() === '' || isTemplateNameDuplicate"
            >
              ä¿å­˜
            </el-button>
          </div>
        </el-row>
        <el-table
          :data="productData"
@@ -776,7 +828,7 @@
import pagination from "@/components/PIMTable/Pagination.vue";
import { ref, onMounted, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
import { Search } from "@element-plus/icons-vue";
import { ElMessageBox } from "element-plus";
import { ElMessageBox,ElMessage } from "element-plus";
import { userListNoPage } from "@/api/system/user.js";
import FileList from "./fileList.vue";
import {
@@ -795,6 +847,8 @@
  getPurchaseById,
  getOptions,
  createPurchaseNo,
  getPurchaseTemplateList,
  addPurchaseTemplate,
} from "@/api/procurementManagement/procurementLedger.js";
import useFormData from "@/hooks/useFormData.js";
import QRCode from "qrcode";
@@ -825,6 +879,103 @@
const qrCodeDialogVisible = ref(false);
const qrCodeUrl = ref("");
// è®¢å•审批状态显示文本
const approvalStatusText = {
  0: '审批中',
  1: '审批通过',
  2: '审批失败'
};
const templateName = ref('');
const filterInputValue = ref('');
const templateList = ref([]);
const isTemplateNameDuplicate = ref(false); // æ ‡è®°æ¨¡æ¿åç§°æ˜¯å¦é‡å¤
// æ£€æŸ¥æ¨¡æ¿åç§°æ˜¯å¦é‡å¤
const checkTemplateNameDuplicate = (name) => {
  if (!name || name.trim() === '') {
    isTemplateNameDuplicate.value = false;
    return false;
  }
  const isDuplicate = templateList.value.some(item => item.templateName === name.trim());
  isTemplateNameDuplicate.value = isDuplicate;
  return isDuplicate;
};
// é˜²æŠ–定时器
let duplicateCheckTimer = null;
const onTemplateFilterChange = (val) => {
  filterInputValue.value = val ?? '';
  // æ¸…除之前的定时器
  if (duplicateCheckTimer) {
    clearTimeout(duplicateCheckTimer);
  }
  // å®žæ—¶æ£€æŸ¥æ¨¡æ¿åç§°æ˜¯å¦é‡å¤ï¼ˆé˜²æŠ–处理,避免频繁提示)
  if (val && val.trim()) {
    duplicateCheckTimer = setTimeout(() => {
      const isDuplicate = checkTemplateNameDuplicate(val);
      if (isDuplicate) {
        ElMessage({
          message: '模板名称已存在,请更换模板名称',
          type: 'warning',
          duration: 2000
        });
      }
    }, 300); // 300ms é˜²æŠ–
  } else {
    isTemplateNameDuplicate.value = false;
  }
};
// allow-create æ—¶ï¼Œè¾“入不存在的内容会作为 string å€¼è¿”回;这里同步回输入框以确保文字不丢
const onTemplateChange = async (val) => {
  if (typeof val === 'string') {
    filterInputValue.value = val;
    // é€‰æ‹©æˆ–输入时检查重复
    checkTemplateNameDuplicate(val);
  }
  // è¿‡æ»¤æ•°æ®ï¼ŒæŸ¥æ‰¾åŒ¹é…çš„æ¨¡æ¿
  const matchedTemplate = templateList.value.find(item => item.templateName === val);
  if (matchedTemplate?.id) {
    // å¦‚果找到模板,加载模板数据
    form.value = {
      ...form.value,
      ...matchedTemplate,
    };
    productData.value = matchedTemplate.productData || [];
    // ç”Ÿæˆæ–°çš„采购合同号
    try {
      const res = await createPurchaseNo();
      if (res?.data) {
        form.value.purchaseContractNumber = res.data;
      }
    } catch (error) {
      console.error('生成采购合同号失败:', error);
    }
  } else {
    // å¦‚果没有找到模板,重置表单(保持当前表单状态)
    const currentFormData = { ...form.value };
    const currentProductData = [...productData.value];
    // å¦‚果对话框未打开,先打开
    if (!dialogFormVisible.value) {
      operationType.value = 'add';
      dialogFormVisible.value = true;
    }
    // ç­‰å¾…下一个 tick åŽæ¢å¤æ•°æ®
    await nextTick();
    form.value = {
      ...form.value,
      ...currentFormData,
    };
    productData.value = currentProductData;
  }
};
// ç”¨æˆ·ä¿¡æ¯è¡¨å•弹框数据
const operationType = ref("");
const dialogFormVisible = ref(false);
@@ -852,7 +1003,8 @@
    purchaseContractNumber: [
      { required: true, message: "请输入", trigger: "blur" },
    ],
    supplierId: [{ required: true, message: "请输入", trigger: "blur" }],
    approverId:[{ required: true, message: "请选择审批人", trigger: "change" }],
    projectName:[{ required:true, message:"请输入项目名称", trigger:"blur"}],
        entryDate: [{ required: true, message: "请选择", trigger: "change" }],
        executionDate: [{ required: true, message: "请选择", trigger: "change" }],
  },
@@ -933,6 +1085,83 @@
  page.current = 1;
  getList();
};
// ä¿å­˜æ¨¡æ¿
const handleButtonClick = async () => {
  // æ£€æŸ¥æ¨¡æ¿åç§°æ˜¯å¦ä¸ºç©º
  if (!templateName.value || templateName.value.trim() === '') {
    ElMessage({
      message: '请输入模板名称',
      type: 'warning',
    });
    return;
  }
  // æ£€æŸ¥æ¨¡æ¿åç§°æ˜¯å¦é‡å¤
  const isDuplicate = checkTemplateNameDuplicate(templateName.value);
  if (isDuplicate) {
    ElMessage({
      message: '模板名称已存在,请更换模板名称',
      type: 'warning',
    });
    return;
  }
  // æ£€æŸ¥ä¾›åº”商是否选择
  if (!form.value.supplierId) {
    ElMessage({
      message: '请先选择供应商',
      type: 'warning',
    });
    return;
  }
  // æ£€æŸ¥æ˜¯å¦æœ‰äº§å“æ•°æ®
  // if (!productData.value || productData.value.length === 0) {
  //   ElMessage({
  //     message: '请先添加产品信息',
  //     type: 'warning',
  //   });
  //   return;
  // }
  try {
    let params = {
      productData: proxy.HaveJson(productData.value),
      supplierId: form.value.supplierId,
      paymentMethod: form.value.paymentMethod,
      recorderId: form.value.recorderId,
      approverId: form.value.approverId,
      templateName: templateName.value.trim()
    };
    console.log(params);
    let res = await addPurchaseTemplate(params);
    if (res && res.code === 200) {
      ElMessage({
        message: '模板保存成功',
        type: 'success',
      });
      // ä¿å­˜æˆåŠŸåŽé‡æ–°èŽ·å–æ¨¡æ¿åˆ—è¡¨
      await getTemplateList();
      // æ¸…空模板名称输入
      templateName.value = '';
      filterInputValue.value = '';
      isTemplateNameDuplicate.value = false;
    } else {
      ElMessage({
        message: res?.msg || '模板保存失败',
        type: 'error',
      });
    }
  } catch (error) {
    console.error('保存模板失败:', error);
    ElMessage({
      message: '模板保存失败,请稍后重试',
      type: 'error',
    });
  }
};
// å­è¡¨åˆè®¡æ–¹æ³•
const summarizeChildrenTable = (param) => {
  return proxy.summarizeTable(
@@ -983,19 +1212,24 @@
};
const expandedRowKeys = ref([]);
// å±•开行
const expandChange = (row, expandedRows) => {
const expandChange = async (row, expandedRows) => {
  if (expandedRows.length > 0) {
    expandedRowKeys.value = [];
    try {
      productList({ salesLedgerId: row.id, type: 2 }).then((res) => {
        const index = tableData.value.findIndex((item) => item.id === row.id);
        if (index > -1) {
          tableData.value[index].children = res.data;
        }
      const res = await productList({ salesLedgerId: row.id, type: 2 });
      const index = tableData.value.findIndex((item) => item.id === row.id);
      if (index > -1) {
        tableData.value[index].children = res.data || [];
        expandedRowKeys.value.push(row.id);
      });
      }
    } catch (error) {
      console.log(error);
      console.error('加载产品列表失败:', error);
      proxy.$modal.msgError('加载产品列表失败');
      // å±•开失败时,移除展开状态
      const index = expandedRows.findIndex(item => item.id === row.id);
      if (index > -1) {
        expandedRows.splice(index, 1);
      }
    }
  } else {
    expandedRowKeys.value = [];
@@ -1014,40 +1248,63 @@
  ]);
};
// æ‰“开弹框
const openForm = (type, row) => {
const openForm = async (type, row) => {
  await getTemplateList()
  operationType.value = type;
  form.value = {};
  productData.value = [];
  fileList.value = [];
  if (operationType.value == "add") {
    createPurchaseNo().then((res) => {
      form.value.purchaseContractNumber = res.data;
    });
  }
  userListNoPage().then((res) => {
    userList.value = res.data;
  });
  getSalesNo().then((res) => {
    salesContractList.value = res;
  });
  getOptions().then((res) => {
    supplierList.value = res.data;
  });
  form.value.recorderId = userStore.id;
  form.value.entryDate = getCurrentDate();
  if (type === "edit") {
    currentId.value = row.id;
    getPurchaseById({ id: row.id, type: 2 }).then((res) => {
      form.value = { ...res };
      productData.value = form.value.productData;
      if (form.value.salesLedgerFiles) {
        fileList.value = form.value.salesLedgerFiles;
      } else {
        fileList.value = [];
  templateName.value = '';
  filterInputValue.value = '';
  isTemplateNameDuplicate.value = false;
  try {
    // å¹¶è¡ŒåŠ è½½åŸºç¡€æ•°æ®
    const [userRes, salesRes, supplierRes] = await Promise.all([
      userListNoPage(),
      getSalesNo(),
      getOptions()
    ]);
    userList.value = userRes.data || [];
    salesContractList.value = salesRes || [];
    // ä¾›åº”商过滤出isWhite=0 çš„æ•°æ®
    supplierList.value = (supplierRes.data || []).filter((item) => item.isWhite === 0);
    // è®¾ç½®é»˜è®¤å€¼
    form.value.recorderId = userStore.id;
    form.value.entryDate = getCurrentDate();
    if (type === "add") {
      // æ–°å¢žæ—¶ç”Ÿæˆé‡‡è´­åˆåŒå·
      try {
        const purchaseNoRes = await createPurchaseNo();
        if (purchaseNoRes?.data) {
          form.value.purchaseContractNumber = purchaseNoRes.data;
        }
      } catch (error) {
        console.error('生成采购合同号失败:', error);
        proxy.$modal.msgWarning('生成采购合同号失败');
      }
    });
    } else if (type === "edit" && row?.id) {
      // ç¼–辑时加载数据
      currentId.value = row.id;
      try {
        const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
        form.value = { ...purchaseRes };
        productData.value = purchaseRes.productData || [];
        fileList.value = purchaseRes.salesLedgerFiles || [];
      } catch (error) {
        console.error('加载采购台账数据失败:', error);
        proxy.$modal.msgError('加载数据失败');
        return;
      }
    }
    dialogFormVisible.value = true;
  } catch (error) {
    console.error('打开表单失败:', error);
    proxy.$modal.msgError('加载基础数据失败');
  }
  dialogFormVisible.value = true;
};
// ä¸Šä¼ å‰æ ¡æ£€
function handleBeforeUpload(file) {
@@ -1586,11 +1843,41 @@
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// æ·»åŠ è¡Œç±»åæ–¹æ³•
const tableRowClassName = ({ row }) => {
  return row.isInvalid ? 'invalid-row' : '';
};
// èŽ·å–æ¨¡æ¿ä¿¡æ¯
const getTemplateList =async ()=>{
  let res = await getPurchaseTemplateList()
  if(res && res.code===200 && Array.isArray(res.data)){
    templateList.value = res.data
  }
}
onMounted(() => {
  getList();
  getTemplateList();
});
</script>
<style scoped lang="scss"></style>
<style scoped lang="scss">
.invalid-row {
  opacity: 0.6;
  background-color: #f5f7fa;
}
.el-row{
  justify-content: space-between;
  align-items: center
}
.no-arrow-select {
  --el-select-suffix-icon-color: transparent; /* éšè—é»˜è®¤ä¸‹æ‹‰ç®­å¤´ */
}
.select-button-group {
  display: flex;
  align-items: center;
}
</style>
src/views/salesManagement/salesLedger/index.vue
@@ -42,18 +42,60 @@
              <el-table-column label="产品大类" prop="productCategory" />
              <el-table-column label="规格型号" prop="specificationModel" />
              <el-table-column label="单位" prop="unit" />
              <el-table-column label="生产状态" width="100px" align="center">
                <template #default="scope">
                  <el-tag v-if="scope.row.productionStatus === '已完成'" type="success">已完成</el-tag>
                  <el-tag v-if="scope.row.productionStatus === '生产中'" type="warning">生产中</el-tag>
                  <el-tag v-if="scope.row.productionStatus === '未开始'" type="danger">未开始</el-tag>
                  <el-tag v-if="!scope.row.productionStatus" type="info">暂无状态</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="产品状态" width="100px" align="center">
                <template #default="scope">
                  <el-tag v-if="scope.row.approveStatus === 0" type="info">未出库</el-tag>
                  <el-tag v-if="scope.row.approveStatus === 1" type="success">已出库</el-tag>
                  <el-tag v-if="scope.row.approveStatus === 2" type="warning">审核中</el-tag>
                  <el-tag v-if="scope.row.approveStatus === 3" type="success">审核成功</el-tag>
                  <el-tag v-if="scope.row.approveStatus === 4" type="danger">审核失败</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="发货车牌" minWidth="100px" align="center">
                <template #default="scope">
                  <div>
                    <el-tag type="success" v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</el-tag>
                    <el-tag v-else type="info">未发货</el-tag>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="发货日期" minWidth="100px" align="center">
                <template #default="scope">
                  <div>
                    <div v-if="scope.row.shippingDate">{{ scope.row.shippingDate }}</div>
                    <el-tag v-else type="info">未发货</el-tag>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="数量" prop="quantity" />
              <el-table-column label="税率(%)" prop="taxRate" />
              <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
              <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
              <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
            <!--操作-->
              <el-table-column Width="60px" label="操作" align="center">
                <template #default="scope">
                  <el-button :disabled="scope.row.approveStatus!==1" link type="primary" size="small" @click="openDeliveryForm(scope.row)">发货</el-button>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="销售合同号" prop="salesContractNo" width="180" show-overflow-tooltip />
        <el-table-column label="客户合同号" prop="customerContractNo" width="180" show-overflow-tooltip />
        <el-table-column label="客户名称" prop="customerName" width="300" show-overflow-tooltip />
        <el-table-column label="业务员" prop="salesman" width="100" show-overflow-tooltip />
        <el-table-column label="项目名称" prop="projectName" width="180" show-overflow-tooltip />
        <el-table-column label="付款方式" prop="paymentMethod" show-overflow-tooltip />
        <el-table-column label="合同金额(元)" prop="contractAmount" width="220" show-overflow-tooltip
          :formatter="formattedNumber" />
        <el-table-column label="录入人" prop="entryPersonName" width="100" show-overflow-tooltip />
@@ -68,12 +110,12 @@
        <el-table-column label="发货日期" prop="shippingDate" width="120" show-overflow-tooltip />
        <el-table-column label="录入日期" prop="entryDate" width="120" show-overflow-tooltip />
        <el-table-column label="签订日期" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" min-width="200" align="center">
        <el-table-column fixed="right" label="操作" min-width="100" align="center">
          <template #default="scope">
            <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">编辑</el-button>
<!--            <el-button link type="primary" size="small" @click="openForm('view', scope.row)">详情</el-button>-->
            <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">附件</el-button>
            <el-button v-if="!scope.row.shippingCarNumber" link type="primary" size="small" @click="openDeliveryForm(scope.row)">发货</el-button>
<!--            <el-button link type="primary" size="small" @click="openDeliveryForm(scope.row)">发货</el-button>-->
          </template>
        </el-table-column>
      </el-table>
@@ -136,7 +178,13 @@
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="付款方式">
              <el-input v-model="form.paymentMethod" placeholder="请输入" clearable :disabled="operationType === 'view'" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-form-item label="产品信息:" prop="entryDate">
            <el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">添加</el-button>
@@ -429,22 +477,23 @@
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="发货车牌号:" prop="shippingCarNumber">
              <el-select v-model="deliveryForm.shippingCarNumber" filterable allow-create placeholder="请选择发货车牌号">
                <el-option key="1" label="新A H5153" value="新A H5153"/>
                <el-option key="2" label="新A H4232" value="新A H4232"/>
                <el-option key="3" label="新A H4001" value="新A H4001"/>
                <el-option key="4" label="新A H6409" value="新A H6409"/>
                <el-option key="5" label="新A G7446" value="新A G7446"/>
                <el-option key="6" label="新H 80369" value="新H 80369"/>
              </el-select>
                            <!-- <el-input
                            <el-input
                                v-model="deliveryForm.shippingCarNumber"
                                placeholder="请输入发货车牌号"
                                clearable
                            /> -->
                            />
                        </el-form-item>
                    </el-col>
                </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="审批人:" prop="approverId">
              <el-select v-model="deliveryForm.approverId" 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-row>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
@@ -462,7 +511,7 @@
import pagination from "@/components/PIMTable/Pagination.vue";
import {onMounted, ref} from "vue";
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
import { ElMessageBox } from "element-plus";
import {ElMessage, ElMessageBox} from "element-plus";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
import FileList from "./fileList.vue";
@@ -475,7 +524,7 @@
  delLedger,
  addOrUpdateSalesLedgerProduct,
  delProduct,
  delLedgerFile,
  delLedgerFile, getProductInventory,
} from "@/api/salesManagement/salesLedger.js";
import { modelList, productTreeList } from "@/api/basicData/product.js";
import useFormData from "@/hooks/useFormData.js";
@@ -513,7 +562,9 @@
  form: {
    salesContractNo: "",
    salesman: "",
    customerContractNo: "",
    customerId: "",
    projectName: "",
    entryPerson: "",
    entryDate: "",
    maintenanceTime: "",
@@ -522,7 +573,11 @@
  },
  rules: {
    salesman: [{ required: true, message: "请选择", trigger: "change" }],
    customerContractNo: [
      { required: true, message: "请输入", trigger: "blur" },
    ],
    customerId: [{ required: true, message: "请选择", trigger: "change" }],
    projectName: [{ required: true, message: "请输入", trigger: "blur" }],
    entryPerson: [{ required: true, message: "请选择", trigger: "change" }],
    entryDate: [{ required: true, message: "请选择", trigger: "change" }],
    executionDate: [{ required: true, message: "请选择", trigger: "change" }],
@@ -596,6 +651,11 @@
    shippingCarNumber: [
      { required: true, message: "请输入发货车牌号", trigger: "blur" }
    ],
    approverId:[
      {
        required: true,message: "",
      }
    ]
  },
});
const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
@@ -627,14 +687,12 @@
  page.size = obj.limit;
  getList();
};
const getList = () => {
const getList =async () => {
  let userLists = await userListNoPage();
  userList.value = userLists.data;
  tableLoading.value = true;
  const { entryDate, ...rest } = searchForm;
  // å°†èŒƒå›´æ—¥æœŸå­—段传递给后端
  const params = { ...rest, ...page };
  // ç§»é™¤å½•入日期的默认值设置,只保留范围日期字段
  delete params.entryDate;
  ledgerListPage(params)
  ledgerListPage({ ...rest, ...page })
    .then((res) => {
      tableLoading.value = false;
      tableData.value = res.records;
@@ -714,23 +772,31 @@
  productSelectedRows.value = selectedRows;
};
const expandedRowKeys = ref([]);
// å±•开行
const expandChange = (row, expandedRows) => {
  if (expandedRows.length > 0) {
// å±•开行(始终只展开一行)
const expandChange = (row) => {
  const rowKey = row.id;
  const isExpanded = expandedRowKeys.value.includes(rowKey);
  if (isExpanded) {
    // å½“前行已展开 -> æ”¶èµ·
    expandedRowKeys.value = [];
    try {
      productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
        const index = tableData.value.findIndex((item) => item.id === row.id);
        if (index > -1) {
          tableData.value[index].children = res.data;
        }
        expandedRowKeys.value.push(row.id);
      });
    } catch (error) {
      console.log(error);
    }
  } else {
    expandedRowKeys.value = [];
    return;
  }
  // å±•开当前行前,先收起其它行
  expandedRowKeys.value = [];
  try {
    productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
      const index = tableData.value.findIndex((item) => item.id === row.id);
      if (index > -1) {
        tableData.value[index].children = res.data;
      }
      // åªä¿ç•™å½“前这一行处于展开状态
      expandedRowKeys.value = [rowKey];
    });
  } catch (error) {
    console.log(error);
  }
};
// ä¸»è¡¨åˆè®¡æ–¹æ³•
@@ -775,7 +841,7 @@
  //     form.value.entryPerson = userAll.user.userId // è®¾ç½®é»˜è®¤ä¸šåŠ¡å‘˜ä¸ºå½“å‰ç”¨æˆ·
  //   }
  // });
  // ç§»é™¤å½•入日期默认值设置,只处理范围日期字段
  form.value.entryDate = getCurrentDate(); // è®¾ç½®é»˜è®¤å½•入日期为当前日期
  dialogFormVisible.value = true;
};
function changs(val) {
@@ -1542,7 +1608,9 @@
  proxy.$refs["deliveryFormRef"].validate((valid) => {
    if (valid) {
      addShippingInfo({
        salesLedgerId: currentDeliveryRow.value.id,
        approverId:deliveryForm.value.approverId,
        salesLedgerId: currentDeliveryRow.value.salesLedgerId,
        salesLedgerProductId: currentDeliveryRow.value.id,
        shippingDate: deliveryForm.value.shippingDate,
        shippingCarNumber: deliveryForm.value.shippingCarNumber,
      })