spring
9 天以前 ba01c8bd58bea9acbb98c2097765b939a81b21cd
src/views/fileManagement/borrow/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,582 @@
<template>
  <div class="app-container borrow-view">
    <!-- æŸ¥è¯¢åŒºåŸŸ -->
    <div class="search-container">
      <el-form :model="searchForm" :inline="true" class="search-form">
                 <el-form-item label="借阅状态:">
           <el-select v-model="searchForm.borrowStatus" placeholder="请选择借阅状态" clearable style="width: 150px">
             <el-option label="借阅" value="借阅" />
             <el-option label="归还" value="归还" />
           </el-select>
         </el-form-item>
        <el-form-item label="借阅人:">
          <el-input
            v-model="searchForm.borrower"
            placeholder="请输入借阅人"
            clearable
            style="width: 200px"
          />
        </el-form-item>
        <el-form-item label="借阅日期范围:">
          <el-date-picker
            v-model="searchForm.dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            style="width: 300px"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">
            <el-icon><Search /></el-icon>
            æŸ¥è¯¢
          </el-button>
          <el-button @click="handleReset">
            <el-icon><Refresh /></el-icon>
            é‡ç½®
          </el-button>
        </el-form-item>
        <el-form-item style="margin-left: auto;">
          <el-button type="primary" @click="openBorrowDia('add')">
            <el-icon><Plus /></el-icon>
            æ–°å¢žå€Ÿé˜…
          </el-button>
          <el-button
            type="danger"
            @click="handleBatchDelete"
            :disabled="selectedRows.length === 0"
          >
            <el-icon><Delete /></el-icon>
            æ‰¹é‡åˆ é™¤ ({{ selectedRows.length }})
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- è¡¨æ ¼åŒºåŸŸ -->
    <div class="table-container">
      <PIMTable
        :table-data="borrowList"
        :column="tableColumns"
        :is-selection="true"
        :border="true"
        :table-loading="tableLoading"
        :page="{
          current: pagination.currentPage,
          size: pagination.pageSize,
          total: pagination.total,
          layout: 'total, sizes, prev, pager, next, jumper'
        }"
        @selection-change="handleSelectionChange"
        @pagination="handlePagination"
      />
    </div>
    <!-- å€Ÿé˜…新增/编辑对话框 -->
    <el-dialog
      v-model="borrowDia"
      :title="borrowOperationType === 'add' ? '新增借阅' : '编辑借阅'"
      width="800px"
      @close="closeBorrowDia"
      @keydown.enter.prevent
    >
      <el-form
        :model="borrowForm"
        label-width="140px"
        :rules="borrowRules"
        ref="borrowFormRef"
      >
        <el-row :gutter="20">
        </el-row>
                 <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="借阅人:" prop="borrower">
               <el-input v-model="borrowForm.borrower" placeholder="请输入借阅人" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="借阅书籍:" prop="documentationId">
               <el-select v-model="borrowForm.documentationId" placeholder="请选择借阅书籍" style="width: 100%">
                 <el-option
                   v-for="item in documentList"
                   :key="item.id"
                   :label="item.docName || item.name"
                   :value="item.id"
                 />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="借阅日期:" prop="borrowDate">
              <el-date-picker
                v-model="borrowForm.borrowDate"
                type="date"
                placeholder="选择借阅日期"
                style="width: 100%"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="应归还日期:" prop="dueReturnDate">
              <el-date-picker
                v-model="borrowForm.dueReturnDate"
                type="date"
                placeholder="选择应归还日期"
                style="width: 100%"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
              />
            </el-form-item>
          </el-col>
        </el-row>
                 <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="借阅目的:" prop="borrowPurpose">
               <el-input v-model="borrowForm.borrowPurpose" placeholder="请输入借阅目的" />
             </el-form-item>
           </el-col>
         </el-row>
        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item label="备注:" prop="remark">
              <el-input
                v-model="borrowForm.remark"
                type="textarea"
                :rows="3"
                placeholder="请输入备注信息"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitBorrowForm">确认</el-button>
          <el-button @click="closeBorrowDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { Search, Refresh, Plus, Delete } from '@element-plus/icons-vue';
import PIMTable from '@/components/PIMTable/PIMTable.vue';
import { getBorrowList, addBorrow, updateBorrow, deleteBorrow, getDocumentList } from '@/api/fileManagement/borrow';
const { proxy } = getCurrentInstance();
// å“åº”式数据
const borrowDia = ref(false);
const borrowOperationType = ref("");
const tableLoading = ref(false);
const borrowList = ref([]);
const selectedRows = ref([]);
const documentList = ref([]); // æ–‡æ¡£åˆ—表,用于借阅书籍选择
// åˆ†é¡µç›¸å…³
const pagination = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0,
});
// æŸ¥è¯¢è¡¨å•
const searchForm = reactive({
  documentationId: "",
  borrowStatus: "",
  borrower: "",
  returnerId: "",
  dateRange: []
});
// å€Ÿé˜…表单
const borrowForm = reactive({
  id: "",
  documentationId: "",
  borrower: "",
  returnerId: "",
  borrowPurpose: "",
  borrowDate: "",
  dueReturnDate: "",
  returnDate: "",
  borrowStatus: "",
  remark: ""
});
// è¡¨å•验证规则
const borrowRules = reactive({
  documentationId: [{ required: true, message: "请选择借阅书籍", trigger: "change" }],
  borrower: [{ required: true, message: "请输入借阅人", trigger: "blur" }],
  borrowPurpose: [{ required: true, message: "请输入借阅目的", trigger: "blur" }],
  borrowDate: [{ required: true, message: "请选择借阅日期", trigger: "change" }],
  dueReturnDate: [{ required: true, message: "请选择应归还日期", trigger: "change" }],
  borrowStatus: [{ required: true, message: "请选择借阅状态", trigger: "change" }]
});
// è¡¨æ ¼åˆ—配置
const tableColumns = ref([
  {
    label: '文档名称',
    prop: 'docName',
    width: '200',
  },
  { label: '借阅人', prop: 'borrower' },
  { label: '借阅目的', prop: 'borrowPurpose' },
  { label: '借阅日期', prop: 'borrowDate' },
  { label: '应归还日期', prop: 'dueReturnDate' },
  {
    label: '借阅状态',
    prop: 'borrowStatus',
    width: '100',
    dataType: 'tag',
    formatData: (params) => {
      if (params === null || params === undefined || params === '') return '-';
      return params;
    },
         formatType: (params) => {
       if (params === '归还') return 'success';
       if (params === '借阅') return 'warning';
       return 'info';
     }
  },
  { label: '备注', prop: 'remark', width: '150' },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: 'right',
    width: '150',
    operation: [
      {
        name: "编辑",
        type: "text",
        clickFun: (row) => {
          openBorrowDia('edit', row)
        },
      },
      {
        name: "删除",
        type: "text",
        clickFun: (row) => {
          handleDelete(row)
        },
      },
    ],
  }
]);
// åˆå§‹åŒ–数据
const initData = async () => {
  await Promise.all([
    loadDocumentList(),
    loadBorrowList()
  ]);
};
// åŠ è½½æ–‡æ¡£åˆ—è¡¨
const loadDocumentList = async () => {
  try {
    const res = await getDocumentList();
    if (res.code === 200) {
      documentList.value = res.data || [];
    } else {
      ElMessage.error(res.msg || "获取文档列表失败");
      documentList.value = [];
    }
  } catch (error) {
    ElMessage.error("获取文档列表失败,请重试");
    documentList.value = [];
  }
};
// åŠ è½½å€Ÿé˜…åˆ—è¡¨
const loadBorrowList = async () => {
  try {
    tableLoading.value = true;
    // æž„建查询参数
    const query = {
      page: pagination.currentPage,
      size: pagination.pageSize,
      documentationId: searchForm.documentationId || undefined,
      borrowStatus: searchForm.borrowStatus || undefined,
      borrower: searchForm.borrower || undefined,
      returnerId: searchForm.returnerId || undefined,
      entryDateStart: searchForm.dateRange && searchForm.dateRange.length > 0 ? searchForm.dateRange[0] : undefined,
      entryDateEnd: searchForm.dateRange && searchForm.dateRange.length > 1 ? searchForm.dateRange[1] : undefined
    };
    // ç§»é™¤undefined的参数
    Object.keys(query).forEach(key => {
      if (query[key] === undefined) {
        delete query[key];
      }
    });
    const res = await getBorrowList(query);
    if (res.code === 200) {
      borrowList.value = res.data.records || [];
      pagination.total = res.data.total || 0;
    } else {
      ElMessage.error(res.msg || "获取借阅列表失败");
      borrowList.value = [];
      pagination.total = 0;
    }
    // é‡ç½®é€‰æ‹©çŠ¶æ€
    selectedRows.value = [];
  } catch (error) {
    ElMessage.error("获取借阅列表失败,请重试");
    borrowList.value = [];
    pagination.total = 0;
  } finally {
    tableLoading.value = false;
  }
};
// æŸ¥è¯¢
const handleSearch = () => {
  pagination.currentPage = 1;
  loadBorrowList();
};
// é‡ç½®æŸ¥è¯¢
const handleReset = () => {
  searchForm.documentationId = "";
  searchForm.borrowStatus = "";
  searchForm.borrower = "";
  searchForm.returnerId = "";
  searchForm.dateRange = [];
  pagination.currentPage = 1;
  loadBorrowList();
  ElMessage.success("查询条件已重置");
};
// æ‰“开借阅弹框
const openBorrowDia = async (type, data) => {
  // å…ˆåˆ·æ–°æ–‡æ¡£åˆ—表
  await loadDocumentList();
  borrowOperationType.value = type;
  borrowDia.value = true;
  if (type === "edit") {
    // ç¼–辑模式,加载现有数据
    Object.assign(borrowForm, data);
  } else {
    // æ–°å¢žæ¨¡å¼ï¼Œæ¸…空表单
    Object.keys(borrowForm).forEach(key => {
      borrowForm[key] = "";
    });
         // è®¾ç½®é»˜è®¤çŠ¶æ€
     borrowForm.borrowStatus = "借阅";
    // è®¾ç½®å½“前日期为借阅日期
    borrowForm.borrowDate = new Date().toISOString().split('T')[0];
  }
};
// å…³é—­å€Ÿé˜…弹框
const closeBorrowDia = () => {
  proxy.$refs.borrowFormRef.resetFields();
  borrowDia.value = false;
};
// æäº¤å€Ÿé˜…表单
const submitBorrowForm = () => {
  proxy.$refs.borrowFormRef.validate(async (valid) => {
    if (valid) {
      try {
        if (borrowOperationType.value === "edit") {
          // ç¼–辑模式,更新现有数据
          const res = await updateBorrow({
            borrower:borrowForm.borrower,
            id: borrowForm.id,
            borrowPurpose: borrowForm.borrowPurpose,
            borrowDate: borrowForm.borrowDate,
            dueReturnDate: borrowForm.dueReturnDate,
            returnDate: borrowForm.returnDate,
            remark: borrowForm.remark
          });
          if (res.code === 200) {
            ElMessage.success("编辑成功");
            await loadBorrowList();
            closeBorrowDia();
          } else {
            ElMessage.error(res.msg || "编辑失败");
          }
        } else {
          // æ–°å¢žæ¨¡å¼ï¼Œæ·»åŠ æ–°æ•°æ®
          const res = await addBorrow({
            documentationId: borrowForm.documentationId,
            borrower: borrowForm.borrower,
            returnerId: borrowForm.returnerId,
            borrowPurpose: borrowForm.borrowPurpose,
            borrowDate: borrowForm.borrowDate,
            dueReturnDate: borrowForm.dueReturnDate,
            returnDate: borrowForm.returnDate,
            borrowStatus: borrowForm.borrowStatus,
            remark: borrowForm.remark
          });
          if (res.code === 200) {
            ElMessage.success("新增成功");
            await loadBorrowList();
            closeBorrowDia();
          } else {
            ElMessage.error(res.msg || "新增失败");
          }
        }
      } catch (error) {
        ElMessage.error("操作失败,请重试");
      }
    }
  });
};
// åˆ é™¤å€Ÿé˜…记录
const handleDelete = (row) => {
  ElMessageBox.confirm(
    `确定要删除这条借阅记录吗?`,
    "删除提示",
    {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    }
  ).then(async () => {
    try {
      const res = await deleteBorrow([row.id]);
      if (res.code === 200) {
        ElMessage.success("删除成功");
        await loadBorrowList();
      } else {
        ElMessage.error(res.msg || "删除失败");
      }
    } catch (error) {
      ElMessage.error("删除失败,请重试");
    }
  }).catch(() => {
    ElMessage.info("已取消删除");
  });
};
// æ‰¹é‡åˆ é™¤
const handleBatchDelete = () => {
  if (selectedRows.value.length === 0) {
    ElMessage.warning("请选择要删除的记录");
    return;
  }
  ElMessageBox.confirm(
    `确定要删除选中的 ${selectedRows.value.length} æ¡å€Ÿé˜…记录吗?`,
    "批量删除提示",
    {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    }
  ).then(async () => {
    try {
      const selectedIds = selectedRows.value.map(row => row.id);
      const res = await deleteBorrow(selectedIds);
      if (res.code === 200) {
        ElMessage.success("批量删除成功");
        await loadBorrowList();
      } else {
        ElMessage.error(res.msg || "批量删除失败");
      }
    } catch (error) {
      ElMessage.error("批量删除失败,请重试");
    }
  }).catch(() => {
    ElMessage.info("已取消删除");
  });
};
// é€‰æ‹©å˜åŒ–事件
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
// å¤„理分页变化
const handlePagination = (current, size) => {
  pagination.currentPage = current;
  pagination.pageSize = size;
  loadBorrowList();
};
// ç”Ÿå‘½å‘¨æœŸ
onMounted(() => {
  initData();
});
</script>
<style scoped>
.borrow-view {
  padding: 20px;
}
.search-container {
  background: #ffffff;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.search-form {
  margin: 0;
}
.table-container {
  background: #ffffff;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.empty-data {
  text-align: center;
  color: #909399;
  padding: 40px;
  font-size: 14px;
}
.dialog-footer {
  text-align: right;
}
:deep(.el-form-item__label) {
  font-weight: 500;
  color: #303133;
}
:deep(.el-input__wrapper) {
  box-shadow: 0 0 0 1px #dcdfe6 inset;
}
:deep(.el-input__wrapper:hover) {
  box-shadow: 0 0 0 1px #c0c4cc inset;
}
:deep(.el-input__wrapper.is-focus) {
  box-shadow: 0 0 0 1px #409eff inset;
}
</style>