gongchunyi
2 天以前 6fe8cfb3cc0d40d92c1107879771678bf94ef570
src/views/collaborativeApproval/approvalProcess/index.vue
@@ -1,213 +1,589 @@
<template>
  <div class="app-container">
    <!-- 标签页切换不同的审批类型 -->
    <el-tabs v-model="activeTab"
             @tab-change="handleTabChange"
             class="approval-tabs">
      <el-tab-pane label="公出管理"
                   name="1"></el-tab-pane>
      <el-tab-pane label="请假管理"
                   name="2"></el-tab-pane>
      <el-tab-pane label="出差管理"
                   name="3"></el-tab-pane>
      <el-tab-pane label="报销管理"
                   name="4"></el-tab-pane>
      <el-tab-pane label="采购审批"
                   name="5"></el-tab-pane>
      <el-tab-pane label="报价审批"
                   name="6"></el-tab-pane>
      <el-tab-pane label="发货审批"
                   name="7"></el-tab-pane>
    </el-tabs>
    <div class="search_form">
      <div>
        <span class="search_title">供应商:</span>
        <el-input
            v-model="searchForm.supplier"
            style="width: 240px"
            placeholder="请输入供应商搜索"
            @change="handleQuery"
            clearable
            :prefix-icon="Search"
        />
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
        >搜索</el-button
        >
        <span class="search_title">流程编号:</span>
        <el-input v-model="searchForm.approveId"
                  style="width: 240px"
                  placeholder="请输入流程编号搜索"
                  @change="handleQuery"
                  clearable
                  :prefix-icon="Search" />
        <span class="search_title ml10">审批状态:</span>
        <el-select v-model="searchForm.approveStatus"
                   clearable
                   @change="handleQuery"
                   style="width: 240px">
          <el-option label="待审核"
                     :value="0" />
          <el-option label="审核中"
                     :value="1" />
          <el-option label="审核完成"
                     :value="2" />
          <el-option label="审核未通过"
                     :value="3" />
          <el-option label="已重新提交"
                     :value="4" />
        </el-select>
        <el-button type="primary"
                   @click="handleQuery"
                   style="margin-left: 10px">搜索</el-button>
      </div>
      <div>
        <el-button type="primary" @click="openForm('add')">新增</el-button>
<!--        <el-button @click="handleOut">导出</el-button>-->
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
        <el-button @click="handleOut">审批人维护</el-button>
        <el-button type="primary"
                   @click="openForm('add')"
                   v-if="currentApproveType !== 5 && currentApproveType !== 6 && currentApproveType !== 7">新增</el-button>
        <el-button @click="handleExport">导出</el-button>
        <el-button type="danger"
                   plain
                   @click="handleDelete"
                   v-if="currentApproveType !== 5 && currentApproveType !== 6 && currentApproveType !== 7">删除</el-button>
      </div>
    </div>
    <div class="table_list">
      <PIMTable
          rowKey="id"
          :column="tableColumn"
          :tableData="tableData"
          :page="page"
          :isSelection="true"
          @selection-change="handleSelectionChange"
          :tableLoading="tableLoading"
          @pagination="pagination"
          :total="page.total"
      ></PIMTable>
      <PIMTable rowKey="id"
                :column="tableColumnCopy"
                :tableData="tableData"
                :page="page"
                :isSelection="true"
                @selection-change="handleSelectionChange"
                :tableLoading="tableLoading"
                @pagination="pagination"
                :total="page.total"></PIMTable>
    </div>
    <info-form-dia ref="infoFormDia" @close="handleQuery"></info-form-dia>
    <approval-dia ref="approvalDia" @close="handleQuery"></approval-dia>
    <info-form-dia ref="infoFormDia"
                   @close="handleQuery"
                   :approveType="currentApproveType"></info-form-dia>
    <approval-dia ref="approvalDia"
                  @close="handleQuery"
                  :approveType="currentApproveType"></approval-dia>
    <FileList ref="fileListRef" />
    <!-- 审批人维护对话框 -->
    <el-dialog v-model="approverDialogVisible"
               title="审批人维护"
               width="800px">
      <div class="approver-dialog">
        <div class="selected-info"
             v-if="selectedApprovers.length > 0">
          <div class="info-title">已选择的审批人:</div>
          <div class="selected-list">
            <el-tag v-for="approver in selectedApprovers"
                    :key="approver.id"
                    class="approver-tag">
              {{ approver.userName }}
              <el-icon class="el-tag__close el-icon--close"
                       @click="removeApprover(approver)">
                <CircleClose />
              </el-icon>
            </el-tag>
          </div>
        </div>
        <el-table ref="approverTable"
                  :data="approverList"
                  style="width: 100%"
                  @selection-change="handleApproverSelectionChange"
                  v-loading="approverLoading">
          <el-table-column type="selection"
                           width="55"></el-table-column>
          <el-table-column prop="userId"
                           label="ID"></el-table-column>
          <el-table-column prop="userName"
                           label="姓名"></el-table-column>
          <el-table-column prop="createTime"
                           label="创建时间"></el-table-column>
        </el-table>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="approverDialogVisible = false">取消</el-button>
          <el-button type="primary"
                     @click="submitApprovers"
                     :disabled="selectedApprovers.length === 0">
            提交
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import {onMounted, ref} from "vue";
import {ElMessageBox} from "element-plus";
import {qualityInspectDel, qualityInspectListPage} from "@/api/qualityManagement/rawMaterialInspection.js";
import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
  import FileList from "./fileList.vue";
  import { Search } from "@element-plus/icons-vue";
  import {
    onMounted,
    ref,
    computed,
    reactive,
    toRefs,
    nextTick,
    getCurrentInstance,
  } from "vue";
  import { ElMessageBox } from "element-plus";
  import { useRoute } from "vue-router";
  import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
  import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
  import {
    approveProcessDelete,
    approveProcessListPage,
    approveUserList,
    addApproveUser,
    deleteApproveUser,
  } from "@/api/collaborativeApproval/approvalProcess.js";
  import { userListNoPageByTenantId } from "@/api/system/user.js";
  import useUserStore from "@/store/modules/user";
const data = reactive({
  searchForm: {
    supplier: "",
  },
});
const { searchForm } = toRefs(data);
const tableColumn = ref([
  {
    label: "审批状态",
    prop: "checkResult",
    dataType: "tag",
    formatData: (params) => {
      if (params == 0) {
        return "待审核";
      } else if (params == 1) {
        return "已完成";
      } else if (params == 2) {
        return "不通过";
      } else {
        return '审核中';
      }
  const userStore = useUserStore();
  const route = useRoute();
  // 当前选中的标签页,默认为公出管理
  const activeTab = ref("1");
  // 当前审批类型,根据选中的标签页计算
  const currentApproveType = computed(() => {
    return Number(activeTab.value);
  });
  // 标签页切换处理
  const handleTabChange = tabName => {
    // 切换标签页时重置搜索条件和分页,并重新加载数据
    searchForm.value.approveId = "";
    searchForm.value.approveStatus = "";
    page.current = 1;
    getList();
  };
  const data = reactive({
    searchForm: {
      approveId: "",
      approveStatus: "",
    },
    formatType: (params) => {
      if (params == '不合格') {
        return "danger";
      } else if (params == '合格') {
        return "success";
      } else {
        return null;
  });
  const { searchForm } = toRefs(data);
  // 动态表格列配置,根据审批类型生成列
  const tableColumnCopy = computed(() => {
    const isLeaveType = currentApproveType.value === 2; // 请假管理
    const isReimburseType = currentApproveType.value === 4; // 报销管理
    const isQuotationType = currentApproveType.value === 6; // 报价审批
    const isPurchaseType = currentApproveType.value === 5; // 采购审批
    // 基础列配置
    const baseColumns = [
      {
        label: "审批状态",
        prop: "approveStatus",
        dataType: "tag",
        width: 100,
        formatData: params => {
          if (params == 0) {
            return "待审核";
          } else if (params == 1) {
            return "审核中";
          } else if (params == 2) {
            return "审核完成";
          } else if (params == 4) {
            return "已重新提交";
          } else {
            return "不通过";
          }
        },
        formatType: params => {
          if (params == 0) {
            return "warning";
          } else if (params == 1) {
            return "primary";
          } else if (params == 2) {
            return "success";
          } else if (params == 4) {
            return "info";
          } else {
            return "danger";
          }
        },
      },
      {
        label: "流程编号",
        prop: "approveId",
        width: 170,
      },
      {
        label: "申请部门",
        prop: "approveDeptName",
        width: 220,
      },
      {
        label: isQuotationType
          ? "报价单号"
          : isPurchaseType
          ? "采购合同号"
          : "审批事由",
        prop: "approveReason",
      },
      {
        label: "申请人",
        prop: "approveUserName",
        width: 120,
      },
    ];
    // 金额列(仅报销管理显示)
    if (isReimburseType) {
      baseColumns.push({
        label: "金额(元)",
        prop: "price",
        width: 120,
      });
    }
    // 日期列(根据类型动态配置)
    baseColumns.push(
      {
        label: isLeaveType ? "开始日期" : "申请日期",
        prop: isLeaveType ? "startDate" : "approveTime",
        width: 200,
      },
      {
        label: "结束日期",
        prop: isLeaveType ? "endDate" : "approveOverTime",
        width: 120,
      }
    },
  },
  {
    label: "流程编号",
    prop: "supplier",
    width: 230
  },
  {
    label: "申请部门",
    prop: "checkName",
  },
  {
    label: "审批事由",
    prop: "productName",
  },
  {
    label: "申请人",
    prop: "model",
  },
  {
    label: "申请日期",
    prop: "unit",
  },
  {
    label: "结束日期",
    prop: "quantity",
    width: 120
  },
  {
    label: "当前审批人",
    prop: "checkCompany",
    width: 120
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: "right",
    width: 150,
    operation: [
    );
    // 当前审批人列
    baseColumns.push({
      label: "当前审批人",
      prop: "approveUserCurrentName",
      width: 120,
    });
    // 操作列
    const actionOperations = [
      {
        name: "编辑",
        type: "text",
        clickFun: (row) => {
        clickFun: row => {
          openForm("edit", row);
        },
        disabled: row =>
          currentApproveType.value === 5 ||
          currentApproveType.value === 6 ||
          currentApproveType.value === 7 ||
          row.approveStatus == 2 ||
          row.approveStatus == 1 ||
          row.approveStatus == 4,
      },
      {
        name: "审核",
        type: "text",
        clickFun: (row) => {
        clickFun: row => {
          openApprovalDia("approval", row);
        },
        disabled: row =>
          row.approveUserCurrentId == null ||
          row.approveStatus == 2 ||
          row.approveStatus == 3 ||
          row.approveStatus == 4 ||
          row.approveUserCurrentId !== userStore.id,
      },
      {
        name: "详情",
        type: "text",
        clickFun: (row) => {
          openApprovalDia('view', row);
        clickFun: row => {
          openApprovalDia("view", row);
        },
      },
    ],
  },
]);
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const page = reactive({
  current: 1,
  size: 100,
  total: 0
});
const infoFormDia = ref()
const approvalDia = ref()
const { proxy } = getCurrentInstance()
    ];
// 查询列表
/** 搜索按钮操作 */
const handleQuery = () => {
  page.current = 1;
  getList();
};
const pagination = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList();
};
const getList = () => {
  tableLoading.value = true;
  qualityInspectListPage({...page, ...searchForm.value, inspectType: 0}).then(res => {
    tableLoading.value = false;
    tableData.value = res.data.records
    page.total = res.data.total;
  }).catch(err => {
    tableLoading.value = false;
  })
};
// 表格选择数据
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
    // 报价审批(类型 6)不展示“附件”操作
    if (!isQuotationType) {
      actionOperations.push({
        name: "附件",
        type: "text",
        clickFun: row => {
          downLoadFile(row);
        },
      });
    }
// 打开新增、编辑弹框
const openForm = (type, row) => {
  nextTick(() => {
    infoFormDia.value?.openDialog(type, row)
  })
};
// 打开新增检验弹框
const openApprovalDia = (type, row) => {
  nextTick(() => {
    approvalDia.value?.openDialog(type, row)
  })
};
    baseColumns.push({
      dataType: "action",
      label: "操作",
      align: "center",
      fixed: "right",
      width: 230,
      operation: actionOperations,
    });
// 删除
const handleDelete = () => {
  let ids = [];
  if (selectedRows.value.length > 0) {
    ids = selectedRows.value.map((item) => item.id);
  } else {
    proxy.$modal.msgWarning("请选择数据");
    return;
  }
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    return baseColumns;
  });
  const tableData = ref([]);
  const selectedRows = ref([]);
  const tableLoading = ref(false);
  const page = reactive({
    current: 1,
    size: 100,
    total: 0,
  });
  const infoFormDia = ref();
  const approvalDia = ref();
  const { proxy } = getCurrentInstance();
  // 审批人维护对话框
  const approverDialogVisible = ref(false);
  const selectedApprovers = ref([]);
  const existingApprovers = ref([]); // 已有的审批人列表
  const approverLoading = ref(false); // 加载状态
  // 审批人列表数据
  const approverList = ref([]);
  const approverTable = ref(null);
  // 查询列表
  /** 搜索按钮操作 */
  const handleQuery = () => {
    page.current = 1;
    getList();
  };
  const fileListRef = ref(null);
  const downLoadFile = row => {
    fileListRef.value.open(row.commonFileList);
  };
  const pagination = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
  };
  const getList = () => {
    tableLoading.value = true;
    approveProcessListPage({
      ...page,
      ...searchForm.value,
      approveType: currentApproveType.value,
    })
      .then(res => {
        tableLoading.value = false;
        tableData.value = res.data.records;
        page.total = res.data.total;
      })
      .catch(err => {
        tableLoading.value = false;
      });
  };
  // 导出
  const handleExport = () => {
    const type = currentApproveType.value;
    const urlMap = {
      0: "/approveProcess/exportZero",
      1: "/approveProcess/exportOne",
      2: "/approveProcess/exportTwo",
      3: "/approveProcess/exportThree",
      4: "/approveProcess/exportFour",
      5: "/approveProcess/exportFive",
      6: "/approveProcess/exportSix",
      7: "/approveProcess/exportSeven",
    };
    const url = urlMap[type] || urlMap[0];
    const nameMap = {
      0: "协同审批管理表",
      1: "公出管理审批表",
      2: "请假管理审批表",
      3: "出差管理审批表",
      4: "报销管理审批表",
      5: "采购申请审批表",
      6: "报价审批表",
      7: "发货审批表",
    };
    const fileName = nameMap[type] || nameMap[0];
    proxy.download(url, {}, `${fileName}.xlsx`);
  };
  // 审批人维护
  const handleOut = () => {
    approverLoading.value = true;
    // 从 API 获取所有用户列表
    userListNoPageByTenantId()
      .then(res => {
        // 转换 API 返回的数据结构为表格需要的格式
        approverList.value = res.data.map(user => ({
          userId: user.userId,
          userName: user.nickName,
          createTime: user.createTime || "",
        }));
        // 获取当前审批类型已有的审批人列表
        const currentType = currentApproveType.value;
        approveUserList({ approveType: currentType })
          .then(approversRes => {
            existingApprovers.value = approversRes.data || [];
            // approverList.value = approversRes.data;
            selectedApprovers.value = existingApprovers.value;
            // approverList.value = ;
            // 标记已有的审批人
            // approverList.value = allUsers.map(user => ({
            //   ...user,
            //   id:
            //     existingApprovers.value.find(
            //       approver => approver.userId === user.userId
            //     )?.id || 0,
            //   isExisting: existingApprovers.value.some(
            //     approver => approver.userId === user.userId
            //   ),
            // }));
            console.log(approverList.value, "==approverList.value==");
            approverDialogVisible.value = true;
            approverLoading.value = false;
            // 更新表格勾选状态
            nextTick(() => {
              if (approverTable.value) {
                // 先清空所有勾选
                approverList.value.forEach(row => {
                  approverTable.value.toggleRowSelection(row, false);
                });
                // 再勾选已有的审批人
                existingApprovers.value.forEach(existingApprover => {
                  const row = approverList.value.find(
                    user => user.userId === existingApprover.userId
                  );
                  if (row) {
                    approverTable.value.toggleRowSelection(row, true);
                  }
                });
              }
            });
          })
          .catch(err => {
            console.error("获取已有审批人列表失败:", err);
            proxy.$modal.msgError("获取已有审批人列表失败");
            approverLoading.value = false;
          });
      })
      .catch(err => {
        console.error("获取用户列表失败:", err);
        proxy.$modal.msgError("获取用户列表失败");
        approverLoading.value = false;
      });
  };
  // 处理审批人选择
  const handleApproverSelectionChange = selection => {
    selectedApprovers.value = selection;
  };
  // 移除审批人
  const removeApprover = approver => {
    selectedApprovers.value = selectedApprovers.value.filter(
      item => item.id !== approver.id
    );
    approverTable.value.toggleRowSelection(approver, false);
  };
  // 提交审批人
  const submitApprovers = () => {
    if (selectedApprovers.value.length === 0) {
      proxy.$modal.msgWarning("请选择审批人");
      return;
    }
    const currentType = currentApproveType.value;
    const selectedIds = selectedApprovers.value.map(approver => approver.userId);
    const existingIds = existingApprovers.value.map(approver => approver.userId);
    // 需要删除的审批人(原有的但未被选择的)
    const toDelete = existingApprovers.value
      .filter(approver => !selectedIds.includes(approver.userId))
      .map(approver => approver.id);
    // 需要添加的审批人(新选择的但不在现有列表中的)
    const toAdd = selectedApprovers.value
      .filter(approver => !existingIds.includes(approver.userId))
      .map(approver => ({
        approveType: currentType,
        id: 0,
        userId: approver.userId,
        userName: approver.userName,
      }));
    console.log(toDelete, "==删除==");
    console.log(toAdd, "==添加==");
    // 先删除不需要的审批人
    const deletePromise =
      toDelete.length > 0 ? deleteApproveUser(toDelete) : Promise.resolve();
    deletePromise
      .then(() => {
        qualityInspectDel(ids).then((res) => {
        // 然后添加新的审批人
        if (toAdd.length === 0) {
          return Promise.resolve();
        }
        // 逐个添加审批人
        return Promise.all(toAdd.map(user => addApproveUser(user)));
      })
      .then(() => {
        proxy.$modal.msgSuccess("审批人维护成功");
        approverDialogVisible.value = false;
        selectedApprovers.value = [];
      })
      .catch(err => {
        console.error("审批人维护失败:", err);
        proxy.$modal.msgError("审批人维护失败");
      });
  };
  // 表格选择数据
  const handleSelectionChange = selection => {
    selectedRows.value = selection;
  };
  // 打开新增、编辑弹框
  const openForm = (type, row) => {
    nextTick(() => {
      infoFormDia.value?.openDialog(type, row);
    });
  };
  // 打开新增检验弹框
  const openApprovalDia = (type, row) => {
    nextTick(() => {
      approvalDia.value?.openDialog(type, row);
    });
  };
  // 删除
  const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
      ids = selectedRows.value.map(item => item.approveId);
    } else {
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        approveProcessDelete(ids).then(res => {
          proxy.$modal.msgSuccess("删除成功");
          getList();
        });
@@ -215,24 +591,65 @@
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
// 导出
const handleOut = () => {
  ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
      .then(() => {
        proxy.download("/quality/qualityInspect/export", {inspectType: 0}, "原材料检验.xlsx");
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
};
onMounted(() => {
  getList();
});
  };
  onMounted(() => {
    // 根据URL参数设置标签页和查询条件
    const approveType = route.query.approveType;
    const approveId = route.query.approveId;
    if (approveType) {
      // 设置标签页(approveType 对应 activeTab 的 name)
      activeTab.value = String(approveType);
    }
    if (approveId) {
      // 设置流程编号查询条件
      searchForm.value.approveId = String(approveId);
    }
    // 查询列表
    getList();
  });
</script>
<style scoped></style>
<style scoped>
  .approval-tabs {
    margin-bottom: 10px;
  }
  /* 审批人维护对话框样式 */
  .approver-dialog {
    display: flex;
    flex-direction: column;
    gap: 20px;
  }
  .selected-info {
    /* margin-top: 20px; */
    padding: 15px;
    background: #f5f7fa;
    border-radius: 4px;
  }
  .info-title {
    font-weight: 600;
    margin-bottom: 10px;
    color: #303133;
  }
  .selected-list {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }
  .approver-tag {
    margin-right: 10px;
  }
  .dialog-footer {
    width: 100%;
    display: flex;
    justify-content: flex-end;
  }
</style>