zhangwencui
10 天以前 3b0d62ccee6666c8e87470b333a19311e49547d1
三项优化内容
已修改8个文件
7706 ■■■■■ 文件已修改
src/views/basicData/customerFile/index.vue 71 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/supplierManage/components/HomeTab.vue 948 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/supplierManage/index.vue 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementLedger/index.vue 670 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionCosting/index.vue 692 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/index.vue 140 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/index.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 5107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/customerFile/index.vue
@@ -15,10 +15,10 @@
                   style="width: 240px"
                   clearable
                   @change="handleQuery">
          <el-option label="零售客户"
                     value="零售客户" />
          <el-option label="进销商客户"
                     value="进销商客户" />
          <el-option label="对公"
                     value="1" />
          <el-option label="对私"
                     value="2" />
        </el-select>
        <el-button type="primary"
                   @click="handleQuery"
@@ -125,10 +125,10 @@
              <el-select v-model="form.customerType"
                         placeholder="请选择"
                         clearable>
                <el-option label="零售客户"
                           value="零售客户" />
                <el-option label="进销商客户"
                           value="进销商客户" />
                <el-option label="对公"
                           :value="1" />
                <el-option label="对私"
                           :value="2" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -276,7 +276,8 @@
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitReminderForm">确认</el-button>
          <el-button type="primary"
                     @click="submitReminderForm">确认</el-button>
          <el-button @click="closeReminderDialog">取消</el-button>
        </div>
      </template>
@@ -359,7 +360,8 @@
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitNegotiationForm">确认</el-button>
          <el-button type="primary"
                     @click="submitNegotiationForm">确认</el-button>
          <el-button @click="closeNegotiationDialog">取消</el-button>
        </div>
      </template>
@@ -383,7 +385,7 @@
            <el-col :span="12">
              <div class="info-item">
                <span class="info-label">客户分类:</span>
                <span class="info-value">{{ detailForm.customerType }}</span>
                <span class="info-value">{{ detailForm.customerType==1?"对公":"对私" }}</span>
              </div>
            </el-col>
          </el-row>
@@ -713,6 +715,9 @@
      label: "客户分类",
      prop: "customerType",
      width: 120,
      formatData: params => {
        return params == 1 ? "对公" : "对私";
      },
    },
    {
      label: "客户名称",
@@ -786,13 +791,13 @@
            openForm("edit", row);
          },
        },
                {
                    name: "添加洽谈进度",
                    type: "text",
                    clickFun: row => {
                        openNegotiationDialog(row);
                    },
                },
        {
          name: "添加洽谈进度",
          type: "text",
          clickFun: row => {
            openNegotiationDialog(row);
          },
        },
        {
          name: "回访提醒",
          type: "text",
@@ -800,13 +805,13 @@
            openReminderDialog(row);
          },
        },
                {
                    name: "详情",
                    type: "text",
                    clickFun: row => {
                        openDetailDialog(row);
                    },
                },
        {
          name: "详情",
          type: "text",
          clickFun: row => {
            openDetailDialog(row);
          },
        },
      ],
    },
  ]);
@@ -854,20 +859,20 @@
    },
    rules: {
      customerName: [{ required: true, message: "请输入", trigger: "blur" }],
      taxpayerIdentificationNumber: [
        { required: true, message: "请输入", trigger: "blur" },
      ],
      companyAddress: [{ required: true, message: "请输入", trigger: "blur" }],
      companyPhone: [{ required: true, message: "请输入", trigger: "blur" }],
      // taxpayerIdentificationNumber: [
      //   { required: true, message: "请输入", trigger: "blur" },
      // ],
      // companyAddress: [{ required: true, message: "请输入", trigger: "blur" }],
      // companyPhone: [{ required: true, message: "请输入", trigger: "blur" }],
      // contactPerson: [{ required: true, message: "请输入", trigger: "blur" }],
      // contactPhone: [{ required: true, message: "请输入", trigger: "blur" }],
      maintainer: [{ required: false, message: "请选择", trigger: "change" }],
      maintenanceTime: [
        { required: false, message: "请选择", trigger: "change" },
      ],
      basicBankAccount: [{ required: true, message: "请输入", trigger: "blur" }],
      bankAccount: [{ required: true, message: "请输入", trigger: "blur" }],
      bankCode: [{ required: true, message: "请输入", trigger: "blur" }],
      // basicBankAccount: [{ required: true, message: "请输入", trigger: "blur" }],
      // bankAccount: [{ required: true, message: "请输入", trigger: "blur" }],
      // bankCode: [{ required: true, message: "请输入", trigger: "blur" }],
      customerType: [{ required: true, message: "请选择", trigger: "change" }],
    },
  });
src/views/basicData/supplierManage/components/HomeTab.vue
@@ -3,185 +3,172 @@
    <div class="search_form">
      <div>
        <span class="search_title">供应商档案:</span>
        <el-input
            v-model="searchForm.supplierName"
            style="width: 240px"
            placeholder="输入供应商名称搜索"
            @change="handleQuery"
            clearable
            :prefix-icon="Search"
        />
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
        >搜索</el-button
        >
        <el-input v-model="searchForm.supplierName"
                  style="width: 240px"
                  placeholder="输入供应商名称搜索"
                  @change="handleQuery"
                  clearable
                  :prefix-icon="Search" />
        <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 type="primary"
                   @click="openForm('add')">新增供应商</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="info" plain icon="Upload" @click="handleImport"
        >导入</el-button
        >
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
        <el-button type="info"
                   plain
                   icon="Upload"
                   @click="handleImport">导入</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"
      ></PIMTable>
      <PIMTable rowKey="id"
                :column="tableColumn"
                :tableData="tableData"
                :page="page"
                :isSelection="true"
                @selection-change="handleSelectionChange"
                :tableLoading="tableLoading"
                @pagination="pagination"></PIMTable>
    </div>
    <el-dialog
        v-model="dialogFormVisible"
        :title="operationType === 'add' ? '新增供应商信息' : '编辑供应商信息'"
        width="70%"
        @close="closeDia"
    >
      <el-form
          :model="form"
          label-width="140px"
          label-position="top"
          :rules="rules"
          ref="formRef"
      >
    <el-dialog v-model="dialogFormVisible"
               :title="operationType === 'add' ? '新增供应商信息' : '编辑供应商信息'"
               width="70%"
               @close="closeDia">
      <el-form :model="form"
               label-width="140px"
               label-position="top"
               :rules="rules"
               ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="供应商名称:" prop="supplierName">
              <el-input
                  v-model="form.supplierName"
                  placeholder="请输入"
                  clearable
              />
            <el-form-item label="供应商名称:"
                          prop="supplierName">
              <el-input v-model="form.supplierName"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
                label="纳税人识别号:"
                prop="taxpayerIdentificationNum"
            >
              <el-input
                  v-model="form.taxpayerIdentificationNum"
                  placeholder="请输入"
                  clearable
              />
            <el-form-item label="纳税人识别号:"
                          prop="taxpayerIdentificationNum">
              <el-input v-model="form.taxpayerIdentificationNum"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="公司地址:" prop="companyAddress">
              <el-input
                  v-model="form.companyAddress"
                  placeholder="请输入"
                  clearable
              />
            <el-form-item label="公司地址:"
                          prop="companyAddress">
              <el-input v-model="form.companyAddress"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="公司电话:" prop="companyPhone">
              <el-input
                  v-model="form.companyPhone"
                  placeholder="请输入"
                  clearable
              />
            <el-form-item label="公司电话:"
                          prop="companyPhone">
              <el-input v-model="form.companyPhone"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="开户行:" prop="bankAccountName">
              <el-input
                  v-model="form.bankAccountName"
                  placeholder="请输入"
                  clearable
              />
            <el-form-item label="开户行:"
                          prop="bankAccountName">
              <el-input v-model="form.bankAccountName"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="账号:" prop="bankAccountNum">
              <el-input
                  v-model="form.bankAccountNum"
                  placeholder="请输入"
                  clearable
              />
            <el-form-item label="账号:"
                          prop="bankAccountNum">
              <el-input v-model="form.bankAccountNum"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="联系人:" prop="contactUserName">
              <el-input
                  v-model="form.contactUserName"
                  placeholder="请输入"
                  clearable
              />
            <el-form-item label="联系人:"
                          prop="contactUserName">
              <el-input v-model="form.contactUserName"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="联系电话:" prop="contactUserPhone">
              <el-input
                  v-model="form.contactUserPhone"
                  placeholder="请输入"
                  clearable
              />
            <el-form-item label="联系电话:"
                          prop="contactUserPhone">
              <el-input v-model="form.contactUserPhone"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="维护人:" prop="maintainUserId">
              <el-select
                  v-model="form.maintainUserId"
                  placeholder="请选择"
                  clearable
                  disabled
              >
                <el-option
                    v-for="item in userList"
                    :key="item.nickName"
                    :label="item.nickName"
                    :value="item.userId"
                />
            <el-form-item label="维护人:"
                          prop="maintainUserId">
              <el-select v-model="form.maintainUserId"
                         placeholder="请选择"
                         clearable
                         disabled>
                <el-option v-for="item in userList"
                           :key="item.nickName"
                           :label="item.nickName"
                           :value="item.userId" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="维护时间:" prop="maintainTime">
              <el-date-picker
                  style="width: 100%"
                  v-model="form.maintainTime"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  type="date"
                  placeholder="请选择"
                  clearable
              />
            <el-form-item label="维护时间:"
                          prop="maintainTime">
              <el-date-picker style="width: 100%"
                              v-model="form.maintainTime"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              type="date"
                              placeholder="请选择"
                              clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="供应商类型:" prop="supplierType">
              <el-select v-model="form.supplierType" placeholder="请选择" clearable>
                <el-option label="甲" value="甲" />
                <el-option label="乙" value="乙" />
                <el-option label="丙" value="丙" />
                <el-option label="丁" value="丁" />
            <el-form-item label="供应商类型:"
                          prop="supplierType">
              <el-select v-model="form.supplierType"
                         placeholder="请选择"
                         clearable>
                <el-option label="对公"
                           :value="1" />
                <el-option label="对私"
                           :value="2" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否白名单:" prop="isWhite">
              <el-select v-model="form.isWhite" placeholder="请选择" clearable>
                <el-option label="是" :value="0" />
                <el-option label="否" :value="1" />
            <el-form-item label="是否白名单:"
                          prop="isWhite">
              <el-select v-model="form.isWhite"
                         placeholder="请选择"
                         clearable>
                <el-option label="是"
                           :value="0" />
                <el-option label="否"
                           :value="1" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -189,50 +176,44 @@
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button type="primary"
                     @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- ä¾›åº”商导入对话框 -->
    <el-dialog
        :title="upload.title"
        v-model="upload.open"
        width="400px"
        append-to-body
    >
      <el-upload
          ref="uploadRef"
          :limit="1"
          accept=".xlsx, .xls"
          :headers="upload.headers"
          :action="upload.url + '?updateSupport=' + upload.updateSupport"
          :disabled="upload.isUploading"
          :on-progress="handleFileUploadProgress"
          :on-success="handleFileSuccess"
          :on-error="handleFileError"
          :auto-upload="false"
          drag
      >
    <el-dialog :title="upload.title"
               v-model="upload.open"
               width="400px"
               append-to-body>
      <el-upload ref="uploadRef"
                 :limit="1"
                 accept=".xlsx, .xls"
                 :headers="upload.headers"
                 :action="upload.url + '?updateSupport=' + upload.updateSupport"
                 :disabled="upload.isUploading"
                 :on-progress="handleFileUploadProgress"
                 :on-success="handleFileSuccess"
                 :on-error="handleFileError"
                 :auto-upload="false"
                 drag>
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <template #tip>
          <div class="el-upload__tip text-center">
            <span>仅允许导入xls、xlsx格式文件。</span>
            <el-link
                type="primary"
                :underline="false"
                style="font-size: 12px; vertical-align: baseline"
                @click="importTemplate"
            >下载模板</el-link
            >
            <el-link type="primary"
                     :underline="false"
                     style="font-size: 12px; vertical-align: baseline"
                     @click="importTemplate">下载模板</el-link>
          </div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitFileForm">ç¡® å®š</el-button>
          <el-button type="primary"
                     @click="submitFileForm">ç¡® å®š</el-button>
          <el-button @click="upload.open = false">取 æ¶ˆ</el-button>
        </div>
      </template>
@@ -242,349 +223,364 @@
</template>
<script setup>
import { onMounted, ref } from "vue";
import { Search } from "@element-plus/icons-vue";
import { delSupplier } from "@/api/basicData/supplierManageFile.js";
import { ElMessageBox } from "element-plus";
import { userListNoPage } from "@/api/system/user.js";
import {
  addSupplier,
  getSupplier,
  listSupplier,
  updateSupplier,
} from "@/api/basicData/supplierManageFile.js";
import useUserStore from "@/store/modules/user";
import { getToken } from "@/utils/auth.js";
import FilesDia from "../filesDia.vue";
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
  import { onMounted, ref } from "vue";
  import { Search } from "@element-plus/icons-vue";
  import { delSupplier } from "@/api/basicData/supplierManageFile.js";
  import { ElMessageBox } from "element-plus";
  import { userListNoPage } from "@/api/system/user.js";
  import {
    addSupplier,
    getSupplier,
    listSupplier,
    updateSupplier,
  } from "@/api/basicData/supplierManageFile.js";
  import useUserStore from "@/store/modules/user";
  import { getToken } from "@/utils/auth.js";
  import FilesDia from "../filesDia.vue";
  const { proxy } = getCurrentInstance();
  const userStore = useUserStore();
const tableColumn = ref([
  {
    label: "供应商名称",
    prop: "supplierName",
    width: 250,
  },
  {
    label: "供应商类型",
    prop: "supplierType",
    width: 120,
  },
  {
    label: "纳税人识别号",
    prop: "taxpayerIdentificationNum",
    width: 230,
  },
  {
    label: "公司地址",
    prop: "companyAddress",
    width: 220,
  },
  {
    label: "联系方式",
    prop: "companyPhone",
    width:150
  },
  {
    label: "开户行",
    prop: "bankAccountName",
    width: 220,
  },
  {
    label: "账号",
    prop: "bankAccountNum",
    width: 220,
  },
  {
    label: "联系人",
    prop: "contactUserName",
  },
  {
    label: "联系电话",
    prop: "contactUserPhone",
    width: 150,
  },
  {
    label: "维护人",
    prop: "maintainUserName",
  },
  {
    label: "维护时间",
    prop: "maintainTime",
    width:100
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: 'right',
    width: 150,
    operation: [
      {
        name: "编辑",
        type: "text",
        clickFun: (row) => {
          openForm("edit", row);
        },
  const tableColumn = ref([
    {
      label: "供应商名称",
      prop: "supplierName",
      width: 250,
    },
    {
      label: "供应商类型",
      prop: "supplierType",
      width: 120,
      formatData: params => {
        return params == 1 ? "对公" : "对私";
      },
      {
        //资质附件
        name: "资质文件",
        type: "text",
        clickFun: (row) => {
          openFilesFormDia(row)
    },
    {
      label: "纳税人识别号",
      prop: "taxpayerIdentificationNum",
      width: 230,
    },
    {
      label: "公司地址",
      prop: "companyAddress",
      width: 220,
    },
    {
      label: "联系方式",
      prop: "companyPhone",
      width: 150,
    },
    {
      label: "开户行",
      prop: "bankAccountName",
      width: 220,
    },
    {
      label: "账号",
      prop: "bankAccountNum",
      width: 220,
    },
    {
      label: "联系人",
      prop: "contactUserName",
    },
    {
      label: "联系电话",
      prop: "contactUserPhone",
      width: 150,
    },
    {
      label: "维护人",
      prop: "maintainUserName",
    },
    {
      label: "维护时间",
      prop: "maintainTime",
      width: 100,
    },
    {
      dataType: "action",
      label: "操作",
      align: "center",
      fixed: "right",
      width: 150,
      operation: [
        {
          name: "编辑",
          type: "text",
          clickFun: row => {
            openForm("edit", row);
          },
        },
        {
          //资质附件
          name: "资质文件",
          type: "text",
          clickFun: row => {
            openFilesFormDia(row);
          },
        },
      ],
    },
  ]);
  const tableData = ref([]);
  const selectedRows = ref([]);
  const userList = ref([]);
  const tableLoading = ref(false);
  const page = reactive({
    current: 1,
    size: 100,
    total: 0,
  });
  const filesDia = ref();
  // ç”¨æˆ·ä¿¡æ¯è¡¨å•弹框数据
  const operationType = ref("");
  const dialogFormVisible = ref(false);
  const data = reactive({
    searchForm: {
      supplierName: "",
    },
    form: {
      supplierName: "",
      taxpayerIdentificationNum: "",
      companyAddress: "",
      companyPhone: "",
      bankAccountName: "",
      bankAccountNum: "",
      contactUserName: "",
      contactUserPhone: "",
      maintainUserId: "",
      maintainTime: "",
      supplierType: "",
      isWhite: "",
    },
    rules: {
      supplierName: [{ required: true, message: "请输入", trigger: "blur" }],
      // taxpayerIdentificationNum: [
      //   { required: true, message: "请输入", trigger: "blur" },
      // ],
      // companyAddress: [{ required: true, message: "请输入", trigger: "blur" }],
      // companyPhone: [{ required: true, message: "请输入", trigger: "blur" }],
      // bankAccountName: [{ required: true, message: "请输入", trigger: "blur" }],
      // bankAccountNum: [{ required: true, message: "请输入", trigger: "blur" }],
      contactUserName: [{ required: false, message: "请输入", trigger: "blur" }],
      contactUserPhone: [{ required: false, message: "请输入", trigger: "blur" }],
      maintainUserId: [{ required: false, message: "请选择", trigger: "change" }],
      maintainTime: [{ required: false, message: "请选择", trigger: "change" }],
      supplierType: [
        { required: true, message: "请选择供应商类型", trigger: "change" },
      ],
    },
  });
  const { searchForm, form, rules } = toRefs(data);
  // æŸ¥è¯¢åˆ—表
  /** æœç´¢æŒ‰é’®æ“ä½œ */
  const handleQuery = () => {
    page.current = 1;
    getList();
  };
  const pagination = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
  };
  /** æäº¤ä¸Šä¼ æ–‡ä»¶ */
  function submitFileForm() {
    upload.isUploading = true;
    proxy.$refs["uploadRef"].submit();
  }
  const getList = () => {
    tableLoading.value = true;
    listSupplier({ ...searchForm.value, ...page, isWhite: 0 }).then(res => {
      tableLoading.value = false;
      tableData.value = res.data.records;
      page.total = res.data.total;
    });
  };
  const upload = reactive({
    // æ˜¯å¦æ˜¾ç¤ºå¼¹å‡ºå±‚(供应商导入)
    open: false,
    // å¼¹å‡ºå±‚标题(供应商导入)
    title: "",
    // æ˜¯å¦ç¦ç”¨ä¸Šä¼ 
    isUploading: false,
    // æ˜¯å¦æ›´æ–°å·²ç»å­˜åœ¨çš„用户数据
    updateSupport: 1,
    // è®¾ç½®ä¸Šä¼ çš„请求头部
    headers: { Authorization: "Bearer " + getToken() },
    // ä¸Šä¼ çš„地址
    url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import",
  });
  /** å¯¼å…¥æŒ‰é’®æ“ä½œ */
  function handleImport() {
    upload.title = "供应商导入";
    upload.open = true;
  }
  /** ä¸‹è½½æ¨¡æ¿ */
  function importTemplate() {
    proxy.download(
      "/system/supplier/downloadTemplate",
      {},
      "供应商导入模板.xlsx"
    );
  }
  /**文件上传中处理 */
  const handleFileUploadProgress = (event, file, fileList) => {
    upload.isUploading = true;
  };
  /** æ–‡ä»¶ä¸Šä¼ æˆåŠŸå¤„ç† */
  const handleFileSuccess = (response, file, fileList) => {
    upload.isUploading = false;
    if (response.code === 200) {
      proxy.$modal.msgSuccess("文件上传成功");
      upload.open = false;
      proxy.$refs["uploadRef"].clearFiles();
      getList();
    } else if (response.code === 500) {
      proxy.$modal.msgError(response.msg);
    } else {
      proxy.$modal.msgWarning(response.msg);
    }
  };
  /** æ–‡ä»¶ä¸Šä¼ å¤±è´¥å¤„理 */
  const handleFileError = (error, file, fileList) => {
    upload.isUploading = false;
    proxy.$modal.msgError("文件上传失败");
  };
  // è¡¨æ ¼é€‰æ‹©æ•°æ®
  const handleSelectionChange = selection => {
    selectedRows.value = selection;
  };
  // æ‰“开弹框
  const openForm = (type, row) => {
    operationType.value = type;
    form.value = {};
    form.value.maintainUserId = userStore.id;
    form.value.maintainTime = getCurrentDate();
    userListNoPage().then(res => {
      userList.value = res.data;
    });
    if (type === "edit") {
      getSupplier(row.id).then(res => {
        form.value = { ...res.data };
      });
    }
    dialogFormVisible.value = true;
  };
  // æäº¤è¡¨å•
  const submitForm = () => {
    proxy.$refs["formRef"].validate(valid => {
      if (valid) {
        if (operationType.value === "edit") {
          submitEdit();
        } else {
          submitAdd();
        }
      }
    ],
  },
]);
const tableData = ref([]);
const selectedRows = ref([]);
const userList = ref([]);
const tableLoading = ref(false);
const page = reactive({
  current: 1,
  size: 100,
  total: 0,
});
const filesDia = ref()
// ç”¨æˆ·ä¿¡æ¯è¡¨å•弹框数据
const operationType = ref("");
const dialogFormVisible = ref(false);
const data = reactive({
  searchForm: {
    supplierName: "",
  },
  form: {
    supplierName: "",
    taxpayerIdentificationNum: "",
    companyAddress: "",
    companyPhone: "",
    bankAccountName: "",
    bankAccountNum: "",
    contactUserName: "",
    contactUserPhone: "",
    maintainUserId: "",
    maintainTime: "",
    supplierType: "",
    isWhite: "",
  },
  rules: {
    supplierName: [{ required: true, message: "请输入", trigger: "blur" }],
    taxpayerIdentificationNum: [
      { required: true, message: "请输入", trigger: "blur" },
    ],
    companyAddress: [{ required: true, message: "请输入", trigger: "blur" }],
    companyPhone: [{ required: true, message: "请输入", trigger: "blur" }],
    bankAccountName: [{ required: true, message: "请输入", trigger: "blur" }],
    bankAccountNum: [{ required: true, message: "请输入", trigger: "blur" }],
    contactUserName: [{ required: false, message: "请输入", trigger: "blur" }],
    contactUserPhone: [{ required: false, message: "请输入", trigger: "blur" }],
    maintainUserId: [{ required: false, message: "请选择", trigger: "change" }],
    maintainTime: [{ required: false, message: "请选择", trigger: "change" }],
    supplierType: [{ required: true, message: "请选择供应商类型", trigger: "change" }],
  },
});
const { searchForm, form, rules } = toRefs(data);
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
  page.current = 1;
  getList();
};
const pagination = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList();
};
/** æäº¤ä¸Šä¼ æ–‡ä»¶ */
function submitFileForm() {
  upload.isUploading = true;
  proxy.$refs["uploadRef"].submit();
}
const getList = () => {
  tableLoading.value = true;
  listSupplier({ ...searchForm.value, ...page, isWhite: 0 }).then((res) => {
    tableLoading.value = false;
    tableData.value = res.data.records;
    page.total = res.data.total;
  });
};
const upload = reactive({
  // æ˜¯å¦æ˜¾ç¤ºå¼¹å‡ºå±‚(供应商导入)
  open: false,
  // å¼¹å‡ºå±‚标题(供应商导入)
  title: "",
  // æ˜¯å¦ç¦ç”¨ä¸Šä¼ 
  isUploading: false,
  // æ˜¯å¦æ›´æ–°å·²ç»å­˜åœ¨çš„用户数据
  updateSupport: 1,
  // è®¾ç½®ä¸Šä¼ çš„请求头部
  headers: { Authorization: "Bearer " + getToken() },
  // ä¸Šä¼ çš„地址
  url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import",
});
/** å¯¼å…¥æŒ‰é’®æ“ä½œ */
function handleImport() {
  upload.title = "供应商导入";
  upload.open = true;
}
/** ä¸‹è½½æ¨¡æ¿ */
function importTemplate() {
  proxy.download("/system/supplier/downloadTemplate", {}, "供应商导入模板.xlsx");
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
  upload.isUploading = true;
};
/** æ–‡ä»¶ä¸Šä¼ æˆåŠŸå¤„ç† */
const handleFileSuccess = (response, file, fileList) => {
  upload.isUploading = false;
  if(response.code === 200){
    proxy.$modal.msgSuccess("文件上传成功");
    upload.open = false;
    proxy.$refs["uploadRef"].clearFiles();
    getList();
  }else if(response.code === 500){
    proxy.$modal.msgError(response.msg);
  }else{
    proxy.$modal.msgWarning(response.msg);
  }
};
/** æ–‡ä»¶ä¸Šä¼ å¤±è´¥å¤„理 */
const handleFileError = (error, file, fileList) => {
  upload.isUploading = false;
  proxy.$modal.msgError("文件上传失败");
};
// è¡¨æ ¼é€‰æ‹©æ•°æ®
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
// æ‰“开弹框
const openForm = (type, row) => {
  operationType.value = type;
  form.value = {};
  form.value.maintainUserId = userStore.id;
  form.value.maintainTime = getCurrentDate();
  userListNoPage().then((res) => {
    userList.value = res.data;
  });
  if (type === "edit") {
    getSupplier(row.id).then((res) => {
      form.value = { ...res.data };
    });
  }
  dialogFormVisible.value = true;
};
// æäº¤è¡¨å•
const submitForm = () => {
  proxy.$refs["formRef"].validate((valid) => {
    if (valid) {
      if (operationType.value === "edit") {
        submitEdit();
      } else {
        submitAdd();
      }
    }
  });
};
// æäº¤æ–°å¢ž
const submitAdd = () => {
  addSupplier(form.value).then((res) => {
    proxy.$modal.msgSuccess("提交成功");
    closeDia();
    getList();
  });
};
// æäº¤ä¿®æ”¹
const submitEdit = () => {
  updateSupplier(form.value).then((res) => {
    proxy.$modal.msgSuccess("提交成功");
    closeDia();
    getList();
  });
};
// å…³é—­å¼¹æ¡†
const closeDia = () => {
  proxy.resetForm("formRef");
  dialogFormVisible.value = false;
};
// å¯¼å‡º
const handleOut = () => {
  ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
  };
  // æäº¤æ–°å¢ž
  const submitAdd = () => {
    addSupplier(form.value).then(res => {
      proxy.$modal.msgSuccess("提交成功");
      closeDia();
      getList();
    });
  };
  // æäº¤ä¿®æ”¹
  const submitEdit = () => {
    updateSupplier(form.value).then(res => {
      proxy.$modal.msgSuccess("提交成功");
      closeDia();
      getList();
    });
  };
  // å…³é—­å¼¹æ¡†
  const closeDia = () => {
    proxy.resetForm("formRef");
    dialogFormVisible.value = false;
  };
  // å¯¼å‡º
  const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        proxy.download("/system/supplier/export", { isWhite: 0 }, "供应商档案.xlsx");
        proxy.download(
          "/system/supplier/export",
          { isWhite: 0 },
          "供应商档案.xlsx"
        );
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
// åˆ é™¤
const handleDelete = () => {
  let ids = [];
  if (selectedRows.value.length > 0) {
    // æ£€æŸ¥æ˜¯å¦æœ‰ä»–人维护的数据
    const unauthorizedData = selectedRows.value.filter(item => item.maintainUserName !== userStore.nickName);
    if (unauthorizedData.length > 0) {
      proxy.$modal.msgWarning("不可删除他人维护的数据");
  };
  // åˆ é™¤
  const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
      // æ£€æŸ¥æ˜¯å¦æœ‰ä»–人维护的数据
      const unauthorizedData = selectedRows.value.filter(
        item => item.maintainUserName !== userStore.nickName
      );
      if (unauthorizedData.length > 0) {
        proxy.$modal.msgWarning("不可删除他人维护的数据");
        return;
      }
      ids = selectedRows.value.map(item => item.id);
    } else {
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    ids = selectedRows.value.map((item) => item.id);
  } else {
    proxy.$modal.msgWarning("请选择数据");
    return;
  }
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除提示", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        tableLoading.value = true;
        delSupplier(ids)
            .then((res) => {
              proxy.$modal.msgSuccess("删除成功");
              getList();
            })
            .finally(() => {
              tableLoading.value = false;
            });
          .then(res => {
            proxy.$modal.msgSuccess("删除成功");
            getList();
          })
          .finally(() => {
            tableLoading.value = false;
          });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
  };
// èŽ·å–å½“å‰æ—¥æœŸå¹¶æ ¼å¼åŒ–ä¸º YYYY-MM-DD
function getCurrentDate() {
  const today = new Date();
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, "0"); // æœˆä»½ä»Ž0开始
  const day = String(today.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
}
// æ‰“开附件弹框
const openFilesFormDia = (row) => {
  nextTick(() => {
    filesDia.value?.openDialog(row)
  })
};
  // èŽ·å–å½“å‰æ—¥æœŸå¹¶æ ¼å¼åŒ–ä¸º YYYY-MM-DD
  function getCurrentDate() {
    const today = new Date();
    const year = today.getFullYear();
    const month = String(today.getMonth() + 1).padStart(2, "0"); // æœˆä»½ä»Ž0开始
    const day = String(today.getDate()).padStart(2, "0");
    return `${year}-${month}-${day}`;
  }
  // æ‰“开附件弹框
  const openFilesFormDia = row => {
    nextTick(() => {
      filesDia.value?.openDialog(row);
    });
  };
onMounted(() => {
  getList();
});
  onMounted(() => {
    getList();
  });
defineExpose({
  getList,
});
  defineExpose({
    getList,
  });
</script>
src/views/basicData/supplierManage/index.vue
@@ -1,11 +1,14 @@
<!-- åœ¨ä½ çš„主页面中 -->
<template>
  <div class="app-container">
    <el-tabs v-model="activeTab" @tab-change="handleTabChange">
      <el-tab-pane label="正常供应商" name="home">
    <el-tabs v-model="activeTab"
             @tab-change="handleTabChange">
      <el-tab-pane label="正常供应商"
                   name="home">
        <HomeTab ref="homeTab" />
      </el-tab-pane>
      <el-tab-pane label="黑名单" name="blacklist">
      <el-tab-pane label="黑名单"
                   name="blacklist">
        <BlacklistTab ref="blacklistTab" />
      </el-tab-pane>
    </el-tabs>
@@ -13,31 +16,35 @@
</template>
<script>
import HomeTab from './components/HomeTab.vue'
import BlacklistTab from './components/BlacklistTab.vue'
  import HomeTab from "./components/HomeTab.vue";
  import BlacklistTab from "./components/BlacklistTab.vue";
export default {
  name: 'MainPage',
  components: {
    HomeTab,
    BlacklistTab
  },
  data() {
    return {
      activeTab: 'home'
    }
  },
  methods: {
    handleTabChange(tabName) {
      this.activeTab = tabName
      this.$nextTick(() => {
        if (tabName === 'home') {
          this.$refs.homeTab && this.$refs.homeTab.getList && this.$refs.homeTab.getList()
        } else if (tabName === 'blacklist') {
          this.$refs.blacklistTab && this.$refs.blacklistTab.getList && this.$refs.blacklistTab.getList()
        }
      })
  export default {
    name: "MainPage",
    components: {
      HomeTab,
      BlacklistTab,
    },
  }
}
    data() {
      return {
        activeTab: "home",
      };
    },
    methods: {
      handleTabChange(tabName) {
        this.activeTab = tabName;
        this.$nextTick(() => {
          if (tabName === "home") {
            this.$refs.homeTab &&
              this.$refs.homeTab.getList &&
              this.$refs.homeTab.getList();
          } else if (tabName === "blacklist") {
            this.$refs.blacklistTab &&
              this.$refs.blacklistTab.getList &&
              this.$refs.blacklistTab.getList();
          }
        });
      },
    },
  };
</script>
src/views/procurementManagement/procurementLedger/index.vue
@@ -33,6 +33,18 @@
                      prefix-icon="Search"
                      @change="handleQuery" />
          </el-form-item>
          <el-form-item label="供应商类型:">
            <el-select v-model="searchForm.supplierType"
                       placeholder="请选择"
                       style="width: 220px"
                       clearable
                       @change="handleQuery">
              <el-option label="对公"
                         value="1" />
              <el-option label="对私"
                         value="2" />
            </el-select>
          </el-form-item>
          <el-form-item label="录入日期:">
            <el-date-picker v-model="searchForm.entryDate"
                            value-format="YYYY-MM-DD"
@@ -53,7 +65,9 @@
      <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
        <el-button type="primary"
                   @click="openForm('add')">新增台账</el-button>
        <el-button type="primary" plain @click="handleImport">导入</el-button>
        <el-button type="primary"
                   plain
                   @click="handleImport">导入</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger"
                   plain
@@ -94,18 +108,29 @@
                               prop="availableQuality" />
              <el-table-column label="退货数量"
                               prop="returnQuality" />
              <el-table-column label="税率(%)"
                               prop="taxRate" />
                               prop="taxRate"
                               v-if="props.row.supplierType === 1" />
              <el-table-column label="含税单价(元)"
                               prop="taxInclusiveUnitPrice"
                               :formatter="formattedNumber" />
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 1" />
              <el-table-column label="含税总价(元)"
                               prop="taxInclusiveTotalPrice"
                               :formatter="formattedNumber" />
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 1" />
              <el-table-column label="不含税总价(元)"
                               prop="taxExclusiveTotalPrice"
                               :formatter="formattedNumber" />
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 1" />
              <el-table-column label="单价(对私)"
                               prop="unitPrice"
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 2" />
              <el-table-column label="总价(对私)"
                               prop="totalPrice"
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 2" />
            </el-table>
          </template>
        </el-table-column>
@@ -119,12 +144,20 @@
                         show-overflow-tooltip />
        <el-table-column label="销售合同号"
                         prop="salesContractNo"
                          width="160"
                         width="160"
                         show-overflow-tooltip />
        <el-table-column label="供应商名称"
                         prop="supplierName"
                          width="160"
                         width="160"
                         show-overflow-tooltip />
        <el-table-column label="供应商类型"
                         prop="supplierType"
                         width="100"
                         show-overflow-tooltip>
          <template #default="scope">
            {{ scope.row.supplierType === 1 ? '对公' : '对私' }}
          </template>
        </el-table-column>
        <el-table-column label="项目名称"
                         prop="projectName"
                         width="320"
@@ -134,9 +167,8 @@
                         width="100"
                         show-overflow-tooltip>
          <template #default="scope">
            <el-tag
              :type="getApprovalStatusType(scope.row.approvalStatus)"
              size="small">
            <el-tag :type="getApprovalStatusType(scope.row.approvalStatus)"
                    size="small">
              {{ approvalStatusText[scope.row.approvalStatus] || '未知状态' }}
            </el-tag>
          </template>
@@ -189,12 +221,12 @@
                  @pagination="paginationChange" />
    </div>
    <FormDialog v-model="dialogFormVisible"
               :title="operationType === 'add' ? '新增采购台账页面' : '编辑采购台账页面'"
               :width="'70%'"
               :operation-type="operationType"
               @close="closeDia"
               @confirm="submitForm"
               @cancel="closeDia">
                :title="operationType === 'add' ? '新增采购台账页面' : '编辑采购台账页面'"
                :width="'70%'"
                :operation-type="operationType"
                @close="closeDia"
                @confirm="submitForm"
                @cancel="closeDia">
      <el-form :model="form"
               label-width="140px"
               label-position="top"
@@ -232,11 +264,12 @@
              <el-select v-model="form.supplierId"
                         placeholder="请选择"
                         filterable
                         clearable>
                         clearable
                         @change="handleSupplierChange">
                <el-option v-for="item in supplierList"
                           :key="item.id"
                           :label="item.supplierName"
                                                     :value="item.id" >{{item.supplierName + '---' + item.supplierType}}</el-option>
                           :value="item.id">{{item.supplierName + '---' + (item.supplierType === 1 ? item.taxpayerIdentificationNum || '无' : '对私')}}</el-option>
              </el-select>
            </el-form-item>
          </el-col>
@@ -304,38 +337,33 @@
              <template #label>
                <div style="display: flex; align-items: center; justify-content: space-between; width: 100%;">
                  <span>审批人选择:</span>
                  <el-button type="primary" size="small" @click="addApproverNode" icon="Plus">新增节点</el-button>
                  <el-button type="primary"
                             size="small"
                             @click="addApproverNode"
                             icon="Plus">新增节点</el-button>
                </div>
              </template>
              <div class="approver-nodes-container">
                <div
                  v-for="(node, index) in approverNodes"
                  :key="node.id"
                  class="approver-node-item"
                >
                <div v-for="(node, index) in approverNodes"
                     :key="node.id"
                     class="approver-node-item">
                  <div class="approver-node-header">
                    <span class="approver-node-label">审批节点 {{ index + 1 }}</span>
                    <el-button
                      v-if="approverNodes.length > 1"
                      type="danger"
                      size="small"
                      text
                      @click="removeApproverNode(index)"
                      icon="Delete"
                    >删除</el-button>
                    <el-button v-if="approverNodes.length > 1"
                               type="danger"
                               size="small"
                               text
                               @click="removeApproverNode(index)"
                               icon="Delete">删除</el-button>
                  </div>
                  <el-select
                    v-model="node.userId"
                    placeholder="请选择审批人"
                    filterable
                    style="width: 100%;"
                  >
                    <el-option
                      v-for="user in userList"
                      :key="user.userId"
                      :label="user.nickName"
                      :value="user.userId"
                    />
                  <el-select v-model="node.userId"
                             placeholder="请选择审批人"
                             filterable
                             style="width: 100%;">
                    <el-option v-for="user in userList"
                               :key="user.userId"
                               :label="user.nickName"
                               :value="user.userId" />
                  </el-select>
                </div>
              </div>
@@ -346,6 +374,7 @@
          <el-form-item label="产品信息:"
                        prop="entryDate">
            <el-button type="primary"
                       v-if="currentSupplierType"
                       @click="openProductForm('add')">添加</el-button>
            <el-button plain
                       type="danger"
@@ -373,11 +402,10 @@
                         :value="item.templateName">
                <div style="display: flex; justify-content: space-between; align-items: center;">
                  <span>{{ item.templateName }}</span>
                  <el-icon
                    v-if="item.id"
                    class="delete-icon"
                    @click.stop="handleDeleteTemplate(item)"
                    style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
                  <el-icon v-if="item.id"
                           class="delete-icon"
                           @click.stop="handleDeleteTemplate(item)"
                           style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
                    <Delete />
                  </el-icon>
                </div>
@@ -420,19 +448,33 @@
                           show-overflow-tooltip />
          <el-table-column label="税率(%)"
                           prop="taxRate"
                           width="80" />
                           width="80"
                           v-if="currentSupplierType === 1" />
          <el-table-column label="含税单价(元)"
                           prop="taxInclusiveUnitPrice"
                           :formatter="formattedNumber"
                           width="150" />
                           width="150"
                           v-if="currentSupplierType === 1" />
          <el-table-column label="含税总价(元)"
                           prop="taxInclusiveTotalPrice"
                           :formatter="formattedNumber"
                           width="150" />
                           width="150"
                           v-if="currentSupplierType === 1" />
          <el-table-column label="不含税总价(元)"
                           prop="taxExclusiveTotalPrice"
                           :formatter="formattedNumber"
                           width="150" />
                           width="150"
                           v-if="currentSupplierType === 1" />
          <el-table-column label="单价(对私)"
                           prop="unitPrice"
                           :formatter="formattedNumber"
                           width="150"
                           v-if="currentSupplierType === 2" />
          <el-table-column label="总价(对私)"
                           prop="totalPrice"
                           :formatter="formattedNumber"
                           width="150"
                           v-if="currentSupplierType === 2" />
          <el-table-column label="是否质检"
                           prop="isChecked"
                           width="150">
@@ -493,28 +535,24 @@
      </el-form>
    </FormDialog>
    <!-- å¯¼å…¥å¼¹çª— -->
    <FormDialog
      v-model="importUpload.open"
      :title="importUpload.title"
      :width="'600px'"
      @close="importUpload.open = false"
      @confirm="submitImportFile"
      @cancel="importUpload.open = false"
    >
      <el-upload
        ref="importUploadRef"
        :limit="1"
        accept=".xlsx,.xls"
        :action="importUpload.url"
        :headers="importUpload.headers"
        :before-upload="importUpload.beforeUpload"
        :on-success="importUpload.onSuccess"
        :on-error="importUpload.onError"
        :on-progress="importUpload.onProgress"
        :on-change="importUpload.onChange"
        :auto-upload="false"
        drag
      >
    <FormDialog v-model="importUpload.open"
                :title="importUpload.title"
                :width="'600px'"
                @close="importUpload.open = false"
                @confirm="submitImportFile"
                @cancel="importUpload.open = false">
      <el-upload ref="importUploadRef"
                 :limit="1"
                 accept=".xlsx,.xls"
                 :action="importUpload.url"
                 :headers="importUpload.headers"
                 :before-upload="importUpload.beforeUpload"
                 :on-success="importUpload.onSuccess"
                 :on-error="importUpload.onError"
                 :on-progress="importUpload.onProgress"
                 :on-change="importUpload.onChange"
                 :auto-upload="false"
                 drag>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          å°†æ–‡ä»¶æ‹–到此处,或<em>点击上传</em>
@@ -522,22 +560,24 @@
        <template #tip>
          <div class="el-upload__tip">
            ä»…支持 xls/xlsx,大小不超过 10MB。
            <el-button link type="primary" @click="downloadTemplate">下载导入模板</el-button>
            <el-button link
                       type="primary"
                       @click="downloadTemplate">下载导入模板</el-button>
          </div>
        </template>
      </el-upload>
    </FormDialog>
    <FormDialog v-model="productFormVisible"
               :title="productOperationType === 'add' ? '新增产品' : '编辑产品'"
               :width="'40%'"
               :operation-type="productOperationType"
               @close="closeProductDia"
               @confirm="submitProduct"
               @cancel="closeProductDia">
                :title="productOperationType === 'add' ? '新增产品' : '编辑产品'"
                :width="'40%'"
                :operation-type="productOperationType"
                @close="closeProductDia"
                @confirm="submitProduct"
                @cancel="closeProductDia">
      <el-form :model="productForm"
               label-width="140px"
               label-position="top"
               :rules="productRules"
               :rules="getProductRules()"
               ref="productFormRef">
        <el-row :gutter="30">
          <el-col :span="24">
@@ -581,7 +621,8 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="税率(%):"
                          prop="taxRate">
                          prop="taxRate"
                          v-if="currentSupplierType === 1">
              <el-select v-model="productForm.taxRate"
                         placeholder="请选择"
                         clearable
@@ -598,18 +639,6 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="含税单价(元):"
                          prop="taxInclusiveUnitPrice">
              <el-input-number v-model="productForm.taxInclusiveUnitPrice"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%"
                               @change="mathNum" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="数量:"
                          prop="quantity">
              <el-input-number :step="0.1"
@@ -619,14 +648,39 @@
                               style="width: 100%"
                               v-model="productForm.quantity"
                               placeholder="请输入"
                               @change="currentSupplierType === 1 ? mathNum() : mathNumPrivate()" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="含税单价(元):"
                          prop="taxInclusiveUnitPrice"
                          v-if="currentSupplierType === 1">
              <el-input-number v-model="productForm.taxInclusiveUnitPrice"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%"
                               @change="mathNum" />
            </el-form-item>
            <el-form-item label="单价(对私):"
                          prop="unitPrice"
                          v-else>
              <el-input-number v-model="productForm.unitPrice"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%"
                               @change="mathNumPrivate" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="含税总价(元):"
                          prop="taxInclusiveTotalPrice">
                          prop="taxInclusiveTotalPrice"
                          v-if="currentSupplierType === 1">
              <el-input-number v-model="productForm.taxInclusiveTotalPrice"
                               :precision="2"
                               :step="0.1"
@@ -635,10 +689,34 @@
                               style="width: 100%"
                               @change="reverseMathNum('taxInclusiveTotalPrice')" />
            </el-form-item>
            <el-form-item label="总价(对私):"
                          prop="totalPrice"
                          v-else>
              <el-input-number v-model="productForm.totalPrice"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%"
                               @change="reverseMathNumPrivate('totalPrice')" />
            </el-form-item>
          </el-col>
          <el-col v-if="currentSupplierType === 2"
                  :span="12">
            <el-form-item label="库存预警数量:"
                          prop="warnNum">
              <el-input-number v-model="productForm.warnNum"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="不含税总价(元):"
                          prop="taxExclusiveTotalPrice">
                          prop="taxExclusiveTotalPrice"
                          v-if="currentSupplierType === 1">
              <el-input-number v-model="productForm.taxExclusiveTotalPrice"
                               :precision="2"
                               :step="0.1"
@@ -652,7 +730,8 @@
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="发票类型:"
                          prop="invoiceType">
                          prop="invoiceType"
                          v-if="currentSupplierType === 1">
              <el-select v-model="productForm.invoiceType"
                         placeholder="请选择"
                         clearable>
@@ -663,7 +742,8 @@
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
          <el-col v-if="currentSupplierType === 1"
                  :span="12">
            <el-form-item label="库存预警数量:"
                          prop="warnNum">
              <el-input-number v-model="productForm.warnNum"
@@ -690,11 +770,9 @@
        </el-row>
      </el-form>
    </FormDialog>
    <FileListDialog
      ref="fileListRef"
      v-model="fileListDialogVisible"
      title="附件列表"
    />
    <FileListDialog ref="fileListRef"
                    v-model="fileListDialogVisible"
                    title="附件列表" />
  </div>
</template>
@@ -712,8 +790,8 @@
  import { Search, Delete } from "@element-plus/icons-vue";
  import { ElMessageBox, ElMessage } from "element-plus";
  import { userListNoPage } from "@/api/system/user.js";
  import FormDialog from '@/components/Dialog/FormDialog.vue';
  import FileListDialog from '@/components/Dialog/FileListDialog.vue';
  import FormDialog from "@/components/Dialog/FormDialog.vue";
  import FileListDialog from "@/components/Dialog/FileListDialog.vue";
  import {
    getSalesLedgerWithProducts,
    addOrUpdateSalesLedgerProduct,
@@ -748,6 +826,7 @@
  const salesContractList = ref([]);
  const supplierList = ref([]);
  const tableLoading = ref(false);
  const currentSupplierType = ref(null); // è·Ÿè¸ªå½“前选择的供应商类型
  const page = reactive({
    current: 1,
    size: 100,
@@ -766,11 +845,31 @@
  const addApproverNode = () => {
    approverNodes.value.push({ id: nextApproverId++, userId: null });
  };
  const removeApproverNode = (index) => {
  const removeApproverNode = index => {
    approverNodes.value.splice(index, 1);
  };
  // è®¢å•审批状态显示文本
  // å¤„理供应商选择变化
  const handleSupplierChange = async supplierId => {
    const selectedSupplier = supplierList.value.find(
      item => item.id === supplierId
    );
    if (selectedSupplier) {
      // åªæœ‰å½“当前供应商类型不为 null ä¸”发生变化时,才清空产品表
      // è¿™æ ·åœ¨ç¼–辑时加载数据后调用该函数不会清空产品数据
      if (
        currentSupplierType.value !== null &&
        currentSupplierType.value !== selectedSupplier.supplierType
      ) {
        productData.value = [];
      }
      currentSupplierType.value = selectedSupplier.supplierType;
    } else {
      currentSupplierType.value = null;
      productData.value = [];
    }
    await getTemplateList();
  };
  const approvalStatusText = {
    1: "待审核",
    2: "审批中",
@@ -779,12 +878,12 @@
  };
  // èŽ·å–å®¡æ‰¹çŠ¶æ€æ ‡ç­¾ç±»åž‹
  const getApprovalStatusType = (status) => {
  const getApprovalStatusType = status => {
    const typeMap = {
      1: "info",      // å¾…审核 - ç°è‰²
      2: "warning",   // å®¡æ‰¹ä¸­ - æ©™è‰²
      3: "success",   // å®¡æ‰¹é€šè¿‡ - ç»¿è‰²
      4: "danger",    // å®¡æ‰¹å¤±è´¥ - çº¢è‰²
      1: "info", // å¾…审核 - ç°è‰²
      2: "warning", // å®¡æ‰¹ä¸­ - æ©™è‰²
      3: "success", // å®¡æ‰¹é€šè¿‡ - ç»¿è‰²
      4: "danger", // å®¡æ‰¹å¤±è´¥ - çº¢è‰²
    };
    return typeMap[status] || "";
  };
@@ -866,7 +965,8 @@
        form.value.paymentMethod = matchedTemplate.paymentMethod;
      }
      // æ¨¡æ¿æ•°æ®ä¸­çš„产品字段是 productList,需要转换为 productData
      productData.value = matchedTemplate.productList || matchedTemplate.productData || [];
      productData.value =
        matchedTemplate.productList || matchedTemplate.productData || [];
    } else {
      // æœªåŒ¹é…åˆ°å·²æœ‰æ¨¡æ¿ï¼Œè§†ä¸ºæ–°æ¨¡æ¿
      currentTemplateId.value = null;
@@ -902,6 +1002,7 @@
      entryDate: null, // å½•入日期
      entryDateStart: undefined,
      entryDateEnd: undefined,
      supplierType: "", // ä¾›åº”商类型
    },
    form: {
      purchaseContractNumber: "",
@@ -985,6 +1086,43 @@
    },
  });
  const { productForm, productRules } = toRefs(productFormData);
  const getProductRules = () => {
    const baseRules = {
      productId: [{ required: true, message: "请选择", trigger: "change" }],
      productModelId: [{ required: true, message: "请选择", trigger: "change" }],
      unit: [{ required: true, message: "请输入", trigger: "blur" }],
      quantity: [{ required: true, message: "请输入", trigger: "blur" }],
      warnNum: [{ required: true, message: "请选择", trigger: "change" }],
      isChecked: [{ required: true, message: "请选择", trigger: "change" }],
    };
    if (currentSupplierType.value === 1) {
      // å¯¹å…¬ä¾›åº”商需要验证的字段
      return {
        ...baseRules,
        taxInclusiveUnitPrice: [
          { required: true, message: "请输入", trigger: "blur" },
        ],
        taxRate: [{ required: true, message: "请选择", trigger: "change" }],
        taxInclusiveTotalPrice: [
          { required: true, message: "请输入", trigger: "blur" },
        ],
        taxExclusiveTotalPrice: [
          { required: true, message: "请输入", trigger: "blur" },
        ],
        invoiceType: [{ required: true, message: "请选择", trigger: "change" }],
      };
    } else if (currentSupplierType.value === 2) {
      // å¯¹ç§ä¾›åº”商需要验证的字段
      return {
        ...baseRules,
        unitPrice: [{ required: true, message: "请输入", trigger: "blur" }],
        totalPrice: [{ required: true, message: "请输入", trigger: "blur" }],
      };
    } else {
      return baseRules;
    }
  };
  const upload = reactive({
    // ä¸Šä¼ çš„地址
    url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
@@ -1000,7 +1138,7 @@
    url: import.meta.env.VITE_APP_BASE_API + "/purchase/ledger/import",
    headers: { Authorization: "Bearer " + getToken() },
    isUploading: false,
    beforeUpload: (file) => {
    beforeUpload: file => {
      const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
      const isLt10M = file.size / 1024 / 1024 < 10;
      if (!isExcel) {
@@ -1049,7 +1187,11 @@
  // ä¸‹è½½å¯¼å…¥æ¨¡æ¿ï¼ˆå¦‚后端路径不同,可在此处调整)
  const downloadTemplate = () => {
    proxy.download("/purchase/ledger/exportTemplate", {}, "采购台账导入模板.xlsx");
    proxy.download(
      "/purchase/ledger/exportTemplate",
      {},
      "采购台账导入模板.xlsx"
    );
  };
  const submitImportFile = () => {
@@ -1114,8 +1256,8 @@
    // æ£€æŸ¥æ˜¯å¦æœ‰äº§å“æ•°æ®
    if (!productData.value || productData.value.length === 0) {
      ElMessage({
        message: '请先添加产品信息',
        type: 'warning',
        message: "请先添加产品信息",
        type: "warning",
      });
      return;
    }
@@ -1126,7 +1268,7 @@
        .filter(node => node.userId)
        .map(node => node.userId)
        .join(",");
      let params = {
        productData: proxy.HaveJson(productData.value),
        supplierId: form.value.supplierId,
@@ -1136,7 +1278,12 @@
        approveUserIds: approveUserIds,
        templateName: templateName.value.trim(),
      };
      console.log("template params ===>", params, "currentTemplateId:", currentTemplateId.value);
      console.log(
        "template params ===>",
        params,
        "currentTemplateId:",
        currentTemplateId.value
      );
      // å¦‚æžœ currentTemplateId æœ‰å€¼ï¼Œè¯´æ˜Žå½“前是“编辑已有模板” â†’ è°ƒç”¨æ›´æ–°æŽ¥å£
      // å¦åˆ™ä¸ºâ€œæ–°å»ºæ¨¡æ¿â€ â†’ è°ƒç”¨æ–°å¢žæŽ¥å£
@@ -1147,7 +1294,10 @@
          ...params,
        });
      } else {
        res = await addPurchaseTemplate(params);
        res = await addPurchaseTemplate({
          ...params,
          templateType: currentSupplierType.value,
        });
      }
      if (res && res.code === 200) {
@@ -1179,22 +1329,34 @@
  };
  // å­è¡¨åˆè®¡æ–¹æ³•
  const summarizeChildrenTable = param => {
    return proxy.summarizeTable(
      param,
      [
    // æ£€æŸ¥æ˜¯å¦æœ‰æ•°æ®ï¼Œä»¥åŠæ•°æ®çš„供应商类型
    const hasData = param && param.data && param.data.length > 0;
    const supplierType = hasData ? param.data[0].supplierType : null;
    // æ ¹æ®ä¾›åº”商类型确定要合计的字段
    const fields = [
      "ticketsNum",
      "ticketsAmount",
      "futureTickets",
      "futureTicketsAmount",
    ];
    if (supplierType === 1) {
      // å¯¹å…¬ä¾›åº”商
      fields.unshift(
        "taxInclusiveUnitPrice",
        "taxInclusiveTotalPrice",
        "taxExclusiveTotalPrice",
        "ticketsNum",
        "ticketsAmount",
        "futureTickets",
        "futureTicketsAmount",
      ],
      {
        ticketsNum: { noDecimal: true }, // ä¸ä¿ç•™å°æ•°
        futureTickets: { noDecimal: true }, // ä¸ä¿ç•™å°æ•°
      }
    );
        "taxExclusiveTotalPrice"
      );
    } else if (supplierType === 2) {
      // å¯¹ç§ä¾›åº”商
      fields.unshift("unitPrice", "totalPrice");
    }
    return proxy.summarizeTable(param, fields, {
      ticketsNum: { noDecimal: true }, // ä¸ä¿ç•™å°æ•°
      futureTickets: { noDecimal: true }, // ä¸ä¿ç•™å°æ•°
    });
  };
  const paginationChange = obj => {
    page.current = obj.page;
@@ -1238,7 +1400,12 @@
        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 || [];
          // ä¸ºå­è¡¨æ ¼æ•°æ®æ·»åŠ ä¾›åº”å•†ç±»åž‹ä¿¡æ¯
          const children = (res.data || []).map(item => ({
            ...item,
            supplierType: row.supplierType, // ä»Žçˆ¶è¡ŒèŽ·å–ä¾›åº”å•†ç±»åž‹
          }));
          tableData.value[index].children = children;
          expandedRowKeys.value.push(row.id);
        }
      } catch (error) {
@@ -1260,11 +1427,17 @@
  };
  // å­è¡¨åˆè®¡æ–¹æ³•
  const summarizeProTable = param => {
    return proxy.summarizeTable(param, [
      "taxInclusiveUnitPrice",
      "taxInclusiveTotalPrice",
      "taxExclusiveTotalPrice",
    ]);
    const fields = [];
    if (currentSupplierType.value === 1) {
      fields.push(
        "taxInclusiveUnitPrice",
        "taxInclusiveTotalPrice",
        "taxExclusiveTotalPrice"
      );
    } else if (currentSupplierType.value === 2) {
      fields.push("unitPrice", "totalPrice");
    }
    return proxy.summarizeTable(param, fields);
  };
  // æ‰“开弹框
  const openForm = async (type, row) => {
@@ -1275,8 +1448,8 @@
        return;
      }
    }
    await getTemplateList();
    currentSupplierType.value = null;
    operationType.value = type;
    form.value = {};
    productData.value = [];
@@ -1307,6 +1480,7 @@
      form.value.entryDate = getCurrentDate();
      if (type === "add") {
        await getTemplateList();
        // æ–°å¢žæ—¶ç”Ÿæˆé‡‡è´­åˆåŒå·
        try {
          const purchaseNoRes = await createPurchaseNo();
@@ -1330,9 +1504,13 @@
            const approverIds = purchaseRes.approveUserIds.split(",");
            approverNodes.value = approverIds.map((id, index) => ({
              id: index + 1,
              userId: Number(id)
              userId: Number(id),
            }));
            nextApproverId = approverIds.length + 1;
          }
          // è®¾ç½®å½“前供应商类型
          if (form.value.supplierId) {
            handleSupplierChange(form.value.supplierId);
          }
        } catch (error) {
          console.error("加载采购台账数据失败:", error);
@@ -1408,8 +1586,10 @@
          proxy.$modal.msgError("请为所有审批节点选择审批人!");
          return;
        }
        const approveUserIds = approverNodes.value.map(node => node.userId).join(",");
        const approveUserIds = approverNodes.value
          .map(node => node.userId)
          .join(",");
        if (productData.value.length > 0) {
          // æ–°å¢žæ—¶ï¼Œéœ€è¦ä»Žæ¯ä¸ªäº§å“å¯¹è±¡ä¸­åˆ é™¤ id å­—段
          let processedProductData = productData.value;
@@ -1438,7 +1618,10 @@
        }
        // æ–°å¢žæ—¶ä¸ä¼ é€’id
        const submitData = { ...form.value };
        const submitData = {
          ...form.value,
          purchaseType: currentSupplierType.value,
        };
        if (operationType.value === "add") {
          delete submitData.id;
        }
@@ -1463,20 +1646,39 @@
  const openProductForm = async (type, row, index) => {
    productOperationType.value = type;
    productOperationIndex.value = index;
    productForm.value = {};
    productForm.value = {
      productId: "",
      productCategory: "",
      productModelId: "",
      specificationModel: "",
      unit: "",
      quantity: "",
      // å¯¹å…¬å­—段
      taxInclusiveUnitPrice: "",
      taxRate: "",
      taxInclusiveTotalPrice: "",
      taxExclusiveTotalPrice: "",
      invoiceType: "",
      // å¯¹ç§å­—段
      unitPrice: "",
      totalPrice: "",
      // å…¬å…±å­—段
      warnNum: "",
      isChecked: true,
    };
    proxy.resetForm("productFormRef");
    productFormVisible.value = true;
    // å…ˆèŽ·å–äº§å“é€‰é¡¹ï¼Œç¡®ä¿æ•°æ®åŠ è½½å®Œæˆ
    await getProductOptions();
    // ç­‰å¾… DOM æ›´æ–°
    await nextTick();
    if (type === "edit") {
      // å¤åˆ¶è¡Œæ•°æ®
      productForm.value = { ...row };
      // å¦‚果是从模板加载的数据,可能没有 productId å’Œ productModelId
      // éœ€è¦æ ¹æ® productCategory å’Œ specificationModel æ¥æŸ¥æ‰¾å¯¹åº”çš„ ID
      if (!productForm.value.productId && productForm.value.productCategory) {
@@ -1487,25 +1689,34 @@
              return nodes[i].value;
            }
            if (nodes[i].children && nodes[i].children.length > 0) {
              const found = findProductIdByCategory(nodes[i].children, categoryName);
              const found = findProductIdByCategory(
                nodes[i].children,
                categoryName
              );
              if (found) return found;
            }
          }
          return null;
        };
        const productId = findProductIdByCategory(productOptions.value, productForm.value.productCategory);
        const productId = findProductIdByCategory(
          productOptions.value,
          productForm.value.productCategory
        );
        if (productId) {
          productForm.value.productId = productId;
          // èŽ·å–åž‹å·åˆ—è¡¨å¹¶ç­‰å¾…å®Œæˆ
          const modelRes = await modelList({ id: productId });
          modelOptions.value = modelRes;
          // ç­‰å¾… DOM æ›´æ–°
          await nextTick();
          // æ ¹æ® specificationModel æŸ¥æ‰¾ productModelId
          if (productForm.value.specificationModel && modelOptions.value.length > 0) {
          if (
            productForm.value.specificationModel &&
            modelOptions.value.length > 0
          ) {
            const modelItem = modelOptions.value.find(
              item => item.model === productForm.value.specificationModel
            );
@@ -1519,15 +1730,15 @@
      } else if (productForm.value.productId) {
        // å¦‚果有 productId,正常加载型号列表
        await getModels(productForm.value.productId);
        // ç­‰å¾… DOM æ›´æ–°
        await nextTick();
        if (productForm.value.productModelId) {
          getProductModel(productForm.value.productModelId);
        }
      }
      // æœ€åŽå†ç­‰å¾…一次 DOM æ›´æ–°ï¼Œç¡®ä¿æ‰€æœ‰æ•°æ®éƒ½å·²è®¾ç½®
      await nextTick();
    }
@@ -1611,15 +1822,21 @@
    });
  };
  const submitProductEdit = () => {
    productForm.value.salesLedgerId = currentId.value;
    productForm.value.type = 2;
    addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
      proxy.$modal.msgSuccess("提交成功");
      closeProductDia();
      getPurchaseById({ id: currentId.value, type: 2 }).then(res => {
        productData.value = res.productData;
      });
    });
    // ç›´æŽ¥ä¿®æ”¹æœ¬åœ°æ•°æ®ï¼Œä¸å†è°ƒç”¨æŽ¥å£
    if (productOperationType.value === "add") {
      // æ–°å¢žäº§å“
      productData.value.push({ ...productForm.value });
    } else if (productOperationType.value === "edit") {
      // ç¼–辑产品
      if (
        productOperationIndex.value !== "" &&
        productOperationIndex.value !== null
      ) {
        productData.value[productOperationIndex.value] = { ...productForm.value };
      }
    }
    proxy.$modal.msgSuccess("操作成功");
    closeProductDia();
  };
  // åˆ é™¤äº§å“
  const deleteProduct = () => {
@@ -1627,40 +1844,27 @@
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    if (operationType.value === "add") {
      productSelectedRows.value.forEach(selectedRow => {
        const index = productData.value.findIndex(
          product => product.id === selectedRow.id
        );
        if (index !== -1) {
          productData.value.splice(index, 1);
        }
      });
    } else {
      let ids = [];
      if (productSelectedRows.value.length > 0) {
        ids = productSelectedRows.value.map(item => item.id);
      }
      ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delProduct(ids).then(res => {
            proxy.$modal.msgSuccess("删除成功");
            closeProductDia();
            getPurchaseById({ id: currentId.value, type: 2 }).then(
              res => {
                productData.value = res.productData;
              }
            );
          });
        })
        .catch(() => {
          proxy.$modal.msg("已取消");
    // ç›´æŽ¥ä»Žæœ¬åœ°æ•°æ®ä¸­åˆ é™¤ï¼Œä¸å†è°ƒç”¨æŽ¥å£
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        productSelectedRows.value.forEach(selectedRow => {
          const index = productData.value.findIndex(
            product => product.id === selectedRow.id
          );
          if (index !== -1) {
            productData.value.splice(index, 1);
          }
        });
    }
        proxy.$modal.msgSuccess("删除成功");
        closeProductDia();
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
  };
  // å…³é—­äº§å“å¼¹æ¡†
  const closeProductDia = () => {
@@ -1826,6 +2030,27 @@
      }
    }
  };
  // å¯¹ç§ä¾›åº”商的价格计算
  const mathNumPrivate = () => {
    const { unitPrice, quantity } = productForm.value;
    if (unitPrice && quantity) {
      productForm.value.totalPrice = (unitPrice * quantity).toFixed(2);
    }
  };
  // å¯¹ç§ä¾›åº”商的反向价格计算
  const reverseMathNumPrivate = type => {
    const { unitPrice, quantity, totalPrice } = productForm.value;
    if (type === "totalPrice") {
      if (quantity) {
        productForm.value.unitPrice = (totalPrice / quantity).toFixed(2);
      } else if (unitPrice) {
        productForm.value.quantity = (totalPrice / unitPrice).toFixed(2);
      }
    }
  };
  // é”€å”®åˆåŒé€‰æ‹©æ”¹å˜æ–¹æ³•
  const salesLedgerChange = async row => {
    console.log("row", row);
@@ -1855,19 +2080,26 @@
  // èŽ·å–æ¨¡æ¿ä¿¡æ¯
  const getTemplateList = async () => {
    let res = await getPurchaseTemplateList();
    if (res && res.code === 200 && Array.isArray(res.data)) {
      templateList.value = res.data;
    console.log("currentSupplierType.value", currentSupplierType.value);
    if (currentSupplierType.value) {
      let res = await getPurchaseTemplateList({
        templateType: currentSupplierType.value,
      });
      if (res && res.code === 200 && Array.isArray(res.data)) {
        templateList.value = res.data;
      }
    } else {
      templateList.value = [];
    }
  };
  // åˆ é™¤æ¨¡æ¿
  const handleDeleteTemplate = async (item) => {
  const handleDeleteTemplate = async item => {
    if (!item.id) {
      proxy.$modal.msgWarning("无法删除该模板");
      return;
    }
    try {
      await ElMessageBox.confirm(
        `确定要删除模板"${item.templateName}"吗?`,
@@ -1878,7 +2110,7 @@
          type: "warning",
        }
      );
      const res = await delPurchaseTemplate([item.id]);
      if (res && res.code === 200) {
        ElMessage({
@@ -1931,7 +2163,7 @@
    display: flex;
    align-items: center;
  }
  // å®¡æ‰¹äººèŠ‚ç‚¹å®¹å™¨æ ·å¼
  .approver-nodes-container {
    display: flex;
@@ -1942,7 +2174,7 @@
    border-radius: 4px;
    border: 1px solid #e4e7ed;
  }
  .approver-node-item {
    flex: 0 0 calc(33.333% - 12px);
    min-width: 200px;
@@ -1951,38 +2183,38 @@
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    transition: all 0.3s;
    &:hover {
      border-color: #409eff;
      box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
    }
  }
  .approver-node-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
  }
  .approver-node-label {
    font-size: 13px;
    font-weight: 500;
    color: #606266;
  }
  @media (max-width: 1200px) {
    .approver-node-item {
      flex: 0 0 calc(50% - 8px);
    }
  }
  @media (max-width: 768px) {
    .approver-node-item {
      flex: 0 0 100%;
    }
  }
  // åˆ é™¤å›¾æ ‡æ ·å¼
  .delete-icon {
    transition: all 0.3s;
src/views/productionManagement/productionCosting/index.vue
@@ -1,371 +1,387 @@
<template>
    <div class="app-container">
        <el-row :gutter="16" class="content-row">
            <!-- å·¦ä¾§å°è´¦ + é¡¶éƒ¨ç­›é€‰ -->
            <el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8" class="left-col">
                <div class="left-panel">
                <div class="left-header">
          <el-form :model="searchForm" inline>
            <el-form-item prop="dateType">
              <el-radio-group v-model="searchForm.dateType" size="small" @change="handleDateTypeChange">
                <el-radio-button label="day">日</el-radio-button>
                <el-radio-button label="month">月</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="日期:" prop="dateRange">
              <el-date-picker
                  v-model="searchForm.dateRange"
                  :type="searchForm.dateType === 'day' ? 'date' : 'daterange'"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  format="YYYY-MM-DD"
                  value-format="YYYY-MM-DD"
                  style="width: 200px"
                  @change="handleDateRangeChange"
              />
  <div class="app-container">
    <el-row :gutter="16"
            class="content-row">
      <!-- å·¦ä¾§å°è´¦ + é¡¶éƒ¨ç­›é€‰ -->
      <el-col :xs="24"
              :sm="24"
              :md="24"
              :lg="8"
              :xl="8"
              class="left-col">
        <div class="left-panel">
          <div class="left-header">
            <el-form :model="searchForm"
                     inline>
              <el-form-item prop="dateType">
                <el-radio-group v-model="searchForm.dateType"
                                size="small"
                                @change="handleDateTypeChange">
                  <el-radio-button label="day">日</el-radio-button>
                  <el-radio-button label="month">月</el-radio-button>
                </el-radio-group>
              </el-form-item>
              <el-form-item label="日期:"
                            prop="dateRange">
                <el-date-picker v-model="searchForm.dateRange"
                                :type="searchForm.dateType === 'day' ? 'date' : 'daterange'"
                                range-separator="至"
                                start-placeholder="开始日期"
                                end-placeholder="结束日期"
                                format="YYYY-MM-DD"
                                value-format="YYYY-MM-DD"
                                style="width: 200px"
                                @change="handleDateRangeChange" />
              </el-form-item>
            </el-form>
          </div>
          <PIMTable rowKey="id"
                    :column="leftTableColumn"
                    :tableData="leftTableData"
                    :tableLoading="tableLoading"
                    :page="page"
                    @row-click="handleLeftRowClick"
                    @pagination="pagination"></PIMTable>
        </div>
      </el-col>
      <!-- å³ä¾§æ˜Žç»† -->
      <el-col :xs="24"
              :sm="24"
              :md="24"
              :lg="16"
              :xl="16"
              class="right-col">
        <div class="right-panel">
          <el-form inline>
            <el-form-item>
              <el-button type="primary"
                         @click="handleOut">导出</el-button>
            </el-form-item>
          </el-form>
                </div>
                <PIMTable
                    rowKey="id"
                    :column="leftTableColumn"
                    :tableData="leftTableData"
                    :tableLoading="tableLoading"
          :page="page"
          @row-click="handleLeftRowClick"
          @pagination="pagination"
        ></PIMTable>
                </div>
            </el-col>
            <!-- å³ä¾§æ˜Žç»† -->
            <el-col :xs="24" :sm="24" :md="24" :lg="16" :xl="16" class="right-col">
                <div class="right-panel">
                    <el-form inline>
                        <el-form-item>
                            <el-button type="primary" @click="handleOut">导出</el-button>
                        </el-form-item>
                    </el-form>
                    <PIMTable
                        rowKey="id"
                        :column="tableColumn"
                        :tableData="tableData"
                        :page="page1"
                        :tableLoading="tableLoading1"
                        style="margin-right: 20px;"
                        @pagination="pagination1"
                    ></PIMTable>
                </div>
            </el-col>
        </el-row>
    </div>
          <PIMTable rowKey="id"
                    :column="tableColumn"
                    :tableData="tableData"
                    :page="page1"
                    :tableLoading="tableLoading1"
                    style="margin-right: 20px;"
                    @pagination="pagination1"></PIMTable>
        </div>
      </el-col>
    </el-row>
  </div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import { ElMessageBox } from "element-plus";
import dayjs from "dayjs";
import {salesLedgerProductionAccountingListProductionDetails, salesLedgerProductionAccountingList} from "@/api/productionManagement/productionCosting.js";
const { proxy } = getCurrentInstance();
  import { onMounted, ref } from "vue";
  import { ElMessageBox } from "element-plus";
  import dayjs from "dayjs";
  import {
    salesLedgerProductionAccountingListProductionDetails,
    salesLedgerProductionAccountingList,
  } from "@/api/productionManagement/productionCosting.js";
  const { proxy } = getCurrentInstance();
const tableColumn = ref([
    {
        label: "生产日期",
        prop: "schedulingDate",
    minWidth: 100,
    },
    {
        label: "生产人",
        prop: "schedulingUserName",
    minWidth: 100,
    },
    {
        label: "合同号",
        prop: "salesContractNo",
    minWidth: 100,
    },
    {
        label: "客户名称",
        prop: "customerName",
    minWidth: 100,
    },
    {
        label: "产品大类",
        prop: "productName",
    minWidth: 100,
    },
    {
        label: "规格型号",
        prop: "productModelName",
    minWidth: 100,
    },
    {
        label: "单位",
        prop: "unit",
    minWidth: 100,
    },
    {
        label: "工序",
        prop: "process",
    minWidth: 100,
    },
    {
        label: "生产数量",
        prop: "quantity",
    minWidth: 100,
    },
    {
        label: "工时定额",
        prop: "workHours",
    minWidth: 100,
    },
    {
        label: "工资",
        prop: "wages",
    minWidth: 100,
    },
]);
// å·¦ä¾§æ±‡æ€»å°è´¦åˆ—(生产人、产量、工资、合格率)
const leftTableColumn = ref([
    {
        label: "生产人",
        prop: "schedulingUserName",
    minWidth: 100,
    },
    {
        label: "产量",
        prop: "outputNum",
    minWidth: 100,
  },
    {
        label: "工资",
        prop: "wages",
    minWidth: 100,
    },
    {
        label: "合格率",
        prop: "outputRate",
    minWidth: 100,
    formatData: (val) => {
      if (val == null || val === '') return '-'
      return parseFloat(val).toFixed(2)
  const tableColumn = ref([
    {
      label: "生产日期",
      prop: "schedulingDate",
      minWidth: 100,
    },
    },
]);
    {
      label: "生产人",
      prop: "schedulingUserName",
      minWidth: 100,
    },
    // {
    //     label: "合同号",
    //     prop: "salesContractNo",
    //   minWidth: 100,
    // },
    // {
    //     label: "客户名称",
    //     prop: "customerName",
    //   minWidth: 100,
    // },
    {
      label: "产品大类",
      prop: "productName",
      minWidth: 100,
    },
    {
      label: "规格型号",
      prop: "productModelName",
      minWidth: 100,
    },
    {
      label: "单位",
      prop: "unit",
      minWidth: 100,
    },
    {
      label: "工序",
      prop: "process",
      minWidth: 100,
    },
    {
      label: "生产数量",
      prop: "quantity",
      minWidth: 100,
    },
    {
      label: "工时定额",
      prop: "workHours",
      minWidth: 100,
    },
    {
      label: "工资",
      prop: "wages",
      minWidth: 100,
    },
  ]);
const tableData = ref([]);
const tableLoading = ref(false);
const tableLoading1 = ref(false);
const leftTableData = ref([]);
// æ—¥ / æœˆ åˆ‡æ¢ï¼ˆé»˜è®¤æŒ‰æ—¥ï¼‰
const page = reactive({
    current: 1,
    size: 100,
    total: 0,
});
  // å·¦ä¾§æ±‡æ€»å°è´¦åˆ—(生产人、产量、工资、合格率)
  const leftTableColumn = ref([
    {
      label: "生产人",
      prop: "schedulingUserName",
      minWidth: 100,
    },
    {
      label: "产量",
      prop: "outputNum",
      minWidth: 100,
    },
    {
      label: "工资",
      prop: "wages",
      minWidth: 100,
    },
    {
      label: "合格率",
      prop: "outputRate",
      minWidth: 100,
      formatData: val => {
        if (val == null || val === "") return "-";
        return parseFloat(val).toFixed(2);
      },
    },
  ]);
const page1 = reactive({
  current: 1,
  size: 100,
  total: 0,
});
  const tableData = ref([]);
  const tableLoading = ref(false);
  const tableLoading1 = ref(false);
  const leftTableData = ref([]);
  // æ—¥ / æœˆ åˆ‡æ¢ï¼ˆé»˜è®¤æŒ‰æ—¥ï¼‰
  const page = reactive({
    current: 1,
    size: 100,
    total: 0,
  });
const data = reactive({
    searchForm: {
        schedulingUserName: "",
        salesContractNo: "",
    dateType: "day",
    dateRange: dayjs().format("YYYY-MM-DD"),
        entryDate: dayjs().format("YYYY-MM-DD"),
        entryDateStart: undefined,
        entryDateEnd: undefined,
    },
});
const { searchForm } = toRefs(data);
  const page1 = reactive({
    current: 1,
    size: 100,
    total: 0,
  });
const pagination = (obj) => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
};
  const data = reactive({
    searchForm: {
      schedulingUserName: "",
      salesContractNo: "",
      dateType: "day",
      dateRange: dayjs().format("YYYY-MM-DD"),
      entryDate: dayjs().format("YYYY-MM-DD"),
      entryDateStart: undefined,
      entryDateEnd: undefined,
    },
  });
  const { searchForm } = toRefs(data);
const pagination1 = (obj) => {
  page1.current = obj.page;
  page1.size = obj.limit;
    getList1();
};
  const pagination = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
  };
const handleDateRangeChange = (value) => {
    if (value) {
    if (searchForm.value.dateType === "day") {
      searchForm.value.entryDate = value;
  const pagination1 = obj => {
    page1.current = obj.page;
    page1.size = obj.limit;
    getList1();
  };
  const handleDateRangeChange = value => {
    if (value) {
      if (searchForm.value.dateType === "day") {
        searchForm.value.entryDate = value;
      } else {
        searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
        searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
      }
    } else {
      searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
      searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
      searchForm.value.entryDate = undefined;
      searchForm.value.entryDateStart = undefined;
      searchForm.value.entryDateEnd = undefined;
    }
    reloadData();
  };
  const getList = () => {
    tableLoading.value = true;
    const params = { ...searchForm.value, ...page };
    salesLedgerProductionAccountingList(params)
      .then(res => {
        const records = res.data.records || [];
        leftTableData.value = records;
        page.total = res.data.total || 0;
      })
      .finally(() => {
        tableLoading.value = false;
      });
  };
  const getList1 = () => {
    tableLoading1.value = true;
    const params = { ...page1, ...searchForm.value };
    salesLedgerProductionAccountingListProductionDetails(params)
      .then(res => {
        tableData.value = res.data.records || [];
        page1.total = res.data.total || 0;
      })
      .finally(() => {
        tableLoading1.value = false;
      });
  };
  // æž„建左侧汇总台账(按生产人汇总产量、工资等)
  const buildLeftTableData = records => {
    const map = {};
    records.forEach(item => {
      const key = item.schedulingUserName || "未知";
      if (!map[key]) {
        map[key] = {
          id: key,
          schedulingUserName: key,
          finishedNum: 0,
          wages: 0,
          qualifiedRate: item.qualifiedRate ?? null,
        };
      }
      map[key].finishedNum += Number(item.finishedNum || 0);
      map[key].wages += Number(item.wages || 0);
      if (item.qualifiedRate != null) {
        map[key].qualifiedRate = item.qualifiedRate;
      }
    });
    leftTableData.value = Object.values(map);
  };
  // å·¦ä¾§æ—¥/月切换
  const handleDateTypeChange = value => {
    // è¿™é‡Œåªä½œä¸ºç­›é€‰æ¡ä»¶çš„一部分,直接重新查询列表
    if (value === "day") {
      searchForm.value.entryDate = dayjs().format("YYYY-MM-DD");
      searchForm.value.dateRange = searchForm.value.entryDate;
    } else {
      searchForm.value.entryDateStart = dayjs()
        .startOf("month")
        .format("YYYY-MM-DD");
      searchForm.value.entryDateEnd = dayjs().endOf("month").format("YYYY-MM-DD");
      searchForm.value.dateRange = [
        searchForm.value.entryDateStart,
        searchForm.value.entryDateEnd,
      ];
    }
    } else {
        searchForm.value.entryDate = undefined;
        searchForm.value.entryDateStart = undefined;
        searchForm.value.entryDateEnd = undefined;
    }
  reloadData()
};
    reloadData();
  };
const getList = () => {
    tableLoading.value = true;
    const params = { ...searchForm.value, ...page };
  const reloadData = () => {
    page.current = 1;
    page1.current = 1;
    getList();
    tableData.value = [];
  };
  salesLedgerProductionAccountingList(params).then((res) => {
        const records = res.data.records || [];
    leftTableData.value = records;
        page.total = res.data.total || 0;
    }).finally(() => {
    tableLoading.value = false;
  })
  // ç‚¹å‡»å·¦ä¾§è¡Œï¼Œåˆ·å³ä¾§æ˜Žç»†ï¼ˆæŒ‰ç”Ÿäº§äººè¿‡æ»¤ï¼‰
  const handleLeftRowClick = row => {
    searchForm.value.schedulingUserName = row.schedulingUserName || "";
    handleQuery();
  };
  // æŸ¥è¯¢åˆ—表
  /** æœç´¢æŒ‰é’®æ“ä½œ */
  const handleQuery = () => {
    page1.current = 1;
    getList1();
  };
  // å¯¼å‡º
  const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        proxy.download(
          "/salesLedger/productionAccounting/export",
          {},
          "生产核算.xlsx"
        );
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
  };
};
const getList1 = () => {
  tableLoading1.value = true;
  const params = { ...page1, ...searchForm.value };
  salesLedgerProductionAccountingListProductionDetails(params).then((res) => {
    tableData.value = res.data.records || [];;
    page1.total = res.data.total || 0;
  }).finally(() => {
    tableLoading1.value = false;
  })
};
// æž„建左侧汇总台账(按生产人汇总产量、工资等)
const buildLeftTableData = (records) => {
    const map = {};
    records.forEach((item) => {
        const key = item.schedulingUserName || "未知";
        if (!map[key]) {
            map[key] = {
                id: key,
                schedulingUserName: key,
                finishedNum: 0,
                wages: 0,
                qualifiedRate: item.qualifiedRate ?? null,
            };
        }
        map[key].finishedNum += Number(item.finishedNum || 0);
        map[key].wages += Number(item.wages || 0);
        if (item.qualifiedRate != null) {
            map[key].qualifiedRate = item.qualifiedRate;
        }
    });
    leftTableData.value = Object.values(map);
};
// å·¦ä¾§æ—¥/月切换
const handleDateTypeChange = (value) => {
    // è¿™é‡Œåªä½œä¸ºç­›é€‰æ¡ä»¶çš„一部分,直接重新查询列表
  if (value === "day") {
    searchForm.value.entryDate = dayjs().format("YYYY-MM-DD");
    searchForm.value.dateRange = searchForm.value.entryDate
  } else {
    searchForm.value.entryDateStart = dayjs().startOf("month").format("YYYY-MM-DD");
    searchForm.value.entryDateEnd = dayjs().endOf("month").format("YYYY-MM-DD");
    searchForm.value.dateRange = [searchForm.value.entryDateStart, searchForm.value.entryDateEnd]
  }
  reloadData()
};
const reloadData = () => {
  page.current = 1;
  page1.current = 1;
  getList();
  tableData.value = []
}
// ç‚¹å‡»å·¦ä¾§è¡Œï¼Œåˆ·å³ä¾§æ˜Žç»†ï¼ˆæŒ‰ç”Ÿäº§äººè¿‡æ»¤ï¼‰
const handleLeftRowClick = (row) => {
    searchForm.value.schedulingUserName = row.schedulingUserName || "";
    handleQuery();
};
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
  page1.current = 1;
  getList1();
};
// å¯¼å‡º
const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            proxy.download("/salesLedger/productionAccounting/export", {}, "生产核算.xlsx");
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
        });
};
onMounted(() => {
    getList();
});
  onMounted(() => {
    getList();
  });
</script>
<style scoped lang="scss">
.content-row {
  width: 100%;
}
  .content-row {
    width: 100%;
  }
.content-row .left-col,
.content-row .right-col {
  margin-bottom: 16px;
}
  .content-row .left-col,
  .content-row .right-col {
    margin-bottom: 16px;
  }
.left-panel,
.right-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}
  .left-panel,
  .right-panel {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
  }
.left-header {
  display: flex;
  align-items: center;
  gap: 12px;
}
  .left-header {
    display: flex;
    align-items: center;
    gap: 12px;
  }
.left-title {
  font-size: 16px;
  color: #ffffff;
}
  .left-title {
    font-size: 16px;
    color: #ffffff;
  }
.header-filters {
  display: flex;
  align-items: center;
  flex: 1;
  justify-content: flex-end;
  gap: 8px;
}
  .header-filters {
    display: flex;
    align-items: center;
    flex: 1;
    justify-content: flex-end;
    gap: 8px;
  }
.search_title {
  color: #ffffff;
}
  .search_title {
    color: #ffffff;
  }
.ml10 {
  margin-left: 10px;
}
  .ml10 {
    margin-left: 10px;
  }
</style>
src/views/productionManagement/productionOrder/index.vue
@@ -11,14 +11,14 @@
                    style="width: 160px;"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="合同号:">
        <!-- <el-form-item label="合同号:">
          <el-input v-model="searchForm.salesContractNo"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    style="width: 160px;"
                    @change="handleQuery" />
        </el-form-item>
        </el-form-item> -->
        <el-form-item label="产品名称:">
          <el-input v-model="searchForm.productCategory"
                    placeholder="请输入"
@@ -41,8 +41,10 @@
        </el-form-item>
      </el-form>
      <div>
        <el-button type="primary" @click="isShowNewModal = true">新增</el-button>
        <el-button type="danger" @click="handleDelete">删除</el-button>
        <el-button type="primary"
                   @click="isShowNewModal = true">新增</el-button>
        <el-button type="danger"
                   @click="handleDelete">删除</el-button>
        <el-button @click="handleOut">导出</el-button>
      </div>
    </div>
@@ -57,11 +59,9 @@
                @selection-change="handleSelectionChange"
                @pagination="pagination">
        <template #completionStatus="{ row }">
          <el-progress
            :percentage="toProgressPercentage(row?.completionStatus)"
            :color="progressColor(toProgressPercentage(row?.completionStatus))"
            :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''"
          />
          <el-progress :percentage="toProgressPercentage(row?.completionStatus)"
                       :color="progressColor(toProgressPercentage(row?.completionStatus))"
                       :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
        </template>
      </PIMTable>
    </div>
@@ -90,10 +90,9 @@
        </span>
      </template>
    </el-dialog>
    <new-product-order v-if="isShowNewModal"
                         v-model:visible="isShowNewModal"
                         @completed="handleQuery" />
                       v-model:visible="isShowNewModal"
                       @completed="handleQuery" />
  </div>
</template>
@@ -106,12 +105,15 @@
    productOrderListPage,
    listProcessRoute,
    bindingRoute,
    listProcessBom, delProductOrder,
    listProcessBom,
    delProductOrder,
  } from "@/api/productionManagement/productionOrder.js";
  import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
  import {fileDel} from "@/api/financialManagement/revenueManagement.js";
  import { fileDel } from "@/api/financialManagement/revenueManagement.js";
  import PIMTable from "@/components/PIMTable/PIMTable.vue";
  const NewProductOrder = defineAsyncComponent(() => import("@/views/productionManagement/productionOrder/New.vue"));
  const NewProductOrder = defineAsyncComponent(() =>
    import("@/views/productionManagement/productionOrder/New.vue")
  );
  const { proxy } = getCurrentInstance();
@@ -122,32 +124,32 @@
    {
      label: "生产订单号",
      prop: "npsNo",
      width: '120px',
      width: "120px",
    },
    {
      label: "销售合同号",
      prop: "salesContractNo",
      width: '150px',
    },
    {
      label: "客户名称",
      prop: "customerName",
      width: '200px',
    },
    // {
    //   label: "销售合同号",
    //   prop: "salesContractNo",
    //   width: "150px",
    // },
    // {
    //   label: "客户名称",
    //   prop: "customerName",
    //   width: "200px",
    // },
    {
      label: "产品名称",
      prop: "productCategory",
      width: '120px',
      width: "120px",
    },
    {
      label: "规格",
      prop: "specificationModel",
      width: '120px',
      width: "120px",
    },
    {
      label: "工艺路线编号",
      prop: "processRouteCode",
      width: '200px',
      width: "200px",
    },
    {
      label: "需求数量",
@@ -176,12 +178,12 @@
      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
      width: 120,
    },
    {
      label: "交付日期",
      prop: "deliveryDate",
      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
      width: 120,
    },
    // {
    //   label: "交付日期",
    //   prop: "deliveryDate",
    //   formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
    //   width: 120,
    // },
    {
      dataType: "action",
      label: "操作",
@@ -253,18 +255,18 @@
  // æ·»åŠ è¡¨è¡Œç±»åæ–¹æ³•
  const tableRowClassName = ({ row }) => {
    if (!row.deliveryDate) return '';
    if (row.isFh) return '';
    if (!row.deliveryDate) return "";
    if (row.isFh) return "";
    const diff = row.deliveryDaysDiff;
    if (diff === 15) {
      return 'yellow';
      return "yellow";
    } else if (diff === 10) {
      return 'pink';
      return "pink";
    } else if (diff === 2) {
      return 'purple';
      return "purple";
    } else if (diff < 2) {
      return 'red';
      return "red";
    }
  };
@@ -402,14 +404,14 @@
  };
  // è¡¨æ ¼é€‰æ‹©æ•°æ®
  const handleSelectionChange = (selection) => {
  const handleSelectionChange = selection => {
    selectedRows.value = selection;
  };
  const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
      ids = selectedRows.value.map((item) => item.id);
      ids = selectedRows.value.map(item => item.id);
    } else {
      proxy.$modal.msgWarning("请选择数据");
      return;
@@ -418,14 +420,16 @@
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    }).then(() => {
      delProductOrder(ids).then((res) => {
        proxy.$modal.msgSuccess("删除成功");
        getList();
    })
      .then(() => {
        delProductOrder(ids).then(res => {
          proxy.$modal.msgSuccess("删除成功");
          getList();
        });
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
    }).catch(() => {
      proxy.$modal.msg("已取消");
    });
  };
  // å¯¼å‡º
@@ -436,7 +440,11 @@
      type: "warning",
    })
      .then(() => {
        proxy.download("/productOrder/export", {...searchForm.value}, "生产订单.xlsx");
        proxy.download(
          "/productOrder/export",
          { ...searchForm.value },
          "生产订单.xlsx"
        );
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
@@ -451,23 +459,23 @@
</script>
<style scoped lang="scss">
.search_form{
  align-items: start;
}
  .search_form {
    align-items: start;
  }
::v-deep .yellow {
  background-color: #FAF0DE;
}
  ::v-deep .yellow {
    background-color: #faf0de;
  }
::v-deep .pink {
  background-color: #FAE1DE;
}
  ::v-deep .pink {
    background-color: #fae1de;
  }
::v-deep .red {
  background-color: #f80202;
}
  ::v-deep .red {
    background-color: #f80202;
  }
::v-deep .purple{
  background-color: #F4DEFA;
}
  ::v-deep .purple {
    background-color: #f4defa;
  }
</style>
src/views/productionManagement/productionReporting/index.vue
@@ -99,8 +99,7 @@
                                style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="操作"
                             >
            <el-table-column label="操作">
              <template #default="scope">
                <el-button link
                           type="primary"
@@ -172,11 +171,11 @@
      prop: "workOrderNo",
      width: 120,
    },
    {
      label: "销售合同号",
      prop: "salesContractNo",
      width: 120,
    },
    // {
    //   label: "销售合同号",
    //   prop: "salesContractNo",
    //   width: 120,
    // },
    {
      label: "产品名称",
      prop: "productName",
@@ -202,7 +201,7 @@
      prop: "unit",
      width: 120,
    },
    {
      label: "创建时间",
      prop: "createTime",
src/views/salesManagement/salesLedger/index.vue
ÎļþÌ«´ó