spring
8 天以前 ba01c8bd58bea9acbb98c2097765b939a81b21cd
src/views/fileManagement/return/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,595 @@
<template>
  <div class="app-container return-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-input
            v-model="searchForm.returner"
            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="openReturnDia('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="returnList"
        :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="returnDia"
      :title="returnOperationType === 'add' ? '新增归还' : '编辑归还'"
      width="800px"
      @close="closeReturnDia"
      @keydown.enter.prevent
    >
      <el-form
        :model="returnForm"
        label-width="140px"
        :rules="returnRules"
        ref="returnFormRef"
      >
                 <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="文档:" prop="borrowId">
               <el-select v-model="returnForm.borrowId" placeholder="请选择文档" style="width: 100%" @change="handleDocumentChange">
                 <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-col :span="12">
             <el-form-item label="借阅人:" prop="borrower">
               <el-input v-model="returnForm.borrower" placeholder="借阅人将根据文档选择自动带出" disabled />
             </el-form-item>
           </el-col>
         </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="归还人:" prop="returner">
              <el-input v-model="returnForm.returner" placeholder="请输入归还人" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="归还日期:" prop="returnDate">
              <el-date-picker
                v-model="returnForm.returnDate"
                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="dueReturnDate">
               <el-date-picker
                 v-model="returnForm.dueReturnDate"
                 type="date"
                 placeholder="应归还日期将根据文档选择自动带出"
                 style="width: 100%"
                 format="YYYY-MM-DD"
                 value-format="YYYY-MM-DD"
                 disabled
               />
             </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="returnForm.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="submitReturnForm">确认</el-button>
          <el-button @click="closeReturnDia">取消</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 { getReturnListPage, returnDocument, deleteReturn, getDocumentList, updateBorrow, reventUpdate } from '@/api/fileManagement/return';
const { proxy } = getCurrentInstance();
// å“åº”式数据
const returnDia = ref(false);
const returnOperationType = ref("");
const tableLoading = ref(false);
const returnList = ref([]);
const selectedRows = ref([]);
const documentList = ref([]); // æ–‡æ¡£åˆ—表
// åˆ†é¡µç›¸å…³
const pagination = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0,
});
// æŸ¥è¯¢è¡¨å•
const searchForm = reactive({
  borrowStatus: "",
  borrower: "",
  returner: "",
  dateRange: []
});
// å½’还表单
const returnForm = reactive({
  id: "",
  borrowId: "",
  borrower: "",
  returner: "",
  borrowStatus: "",
  returnDate: "",
  dueReturnDate: "",
  remark: ""
});
// è¡¨å•验证规则
const returnRules = reactive({
  borrowId: [{ required: true, message: "请选择文档", trigger: "change" }],
  returner: [{ required: true, message: "请输入归还人", trigger: "blur" }],
  returnDate: [{ required: true, message: "请选择归还日期", trigger: "change" }]
});
// è¡¨æ ¼åˆ—配置
const tableColumns = ref([
  {
    label: '文档名称',
    prop: 'docName',
    width: '200',
  },
  { label: '借阅人', prop: 'borrower' },
  { label: '归还人', prop: 'returner' },
  {
    label: '借阅状态',
    prop: 'borrowStatus',
    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: 'returnDate' },
  { label: '应归还日期', prop: 'dueReturnDate' },
  { label: '备注', prop: 'remark', width: '150' },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: 'right',
    width: '150',
    operation: [
      {
        name: "编辑",
        type: "text",
        clickFun: (row) => {
          openReturnDia('edit', row)
        },
      },
      {
        name: "删除",
        type: "text",
        clickFun: (row) => {
          handleDelete(row)
        },
      },
    ],
  }
]);
// åˆå§‹åŒ–数据
const initData = async () => {
  await Promise.all([
    loadDocumentList(),
    loadReturnList()
  ]);
};
// åŠ è½½æ–‡æ¡£åˆ—è¡¨
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 loadReturnList = async () => {
  try {
    tableLoading.value = true;
    // æž„建查询参数
    const query = {
      page: pagination.currentPage,
      size: pagination.pageSize,
      borrowStatus: searchForm.borrowStatus || undefined,
      borrower: searchForm.borrower || undefined,
      returner: searchForm.returner || 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 getReturnListPage(query);
    if (res.code === 200) {
      returnList.value = res.data.records || [];
      pagination.total = res.data.total || 0;
    } else {
      ElMessage.error(res.msg || "获取归还列表失败");
      returnList.value = [];
      pagination.total = 0;
    }
    // é‡ç½®é€‰æ‹©çŠ¶æ€
    selectedRows.value = [];
  } catch (error) {
    ElMessage.error("获取归还列表失败,请重试");
    returnList.value = [];
    pagination.total = 0;
  } finally {
    tableLoading.value = false;
  }
};
// æŸ¥è¯¢
const handleSearch = () => {
  pagination.currentPage = 1;
  loadReturnList();
};
// é‡ç½®æŸ¥è¯¢
const handleReset = () => {
  searchForm.borrowStatus = "";
  searchForm.borrower = "";
  searchForm.returner = "";
  searchForm.dateRange = [];
  pagination.currentPage = 1;
  loadReturnList();
  ElMessage.success("查询条件已重置");
};
// æ‰“开归还弹框
const openReturnDia = (type, data) => {
  returnOperationType.value = type;
  returnDia.value = true;
  if (type === "edit") {
    // ç¼–辑模式,加载现有数据
    Object.assign(returnForm, data);
    // ç¼–辑模式下,文档选择后自动填充借阅人和应归还日期
    if (returnForm.borrowId) {
      handleDocumentChange(returnForm.borrowId);
    }
  } else {
    // æ–°å¢žæ¨¡å¼ï¼Œæ¸…空表单
    Object.keys(returnForm).forEach(key => {
      returnForm[key] = "";
    });
    // è®¾ç½®é»˜è®¤çŠ¶æ€
    returnForm.borrowStatus = "归还";
    // è®¾ç½®å½“前日期为归还日期
    returnForm.returnDate = new Date().toISOString().split('T')[0];
  }
};
// å…³é—­å½’还弹框
const closeReturnDia = () => {
  proxy.$refs.returnFormRef.resetFields();
  returnDia.value = false;
};
// æäº¤å½’还表单
const submitReturnForm = () => {
  proxy.$refs.returnFormRef.validate(async (valid) => {
    if (valid) {
      try {
                 if (returnOperationType.value === "edit") {
           // ç¼–辑模式,调用归还更新接口
           const res = await reventUpdate({
             id: returnForm.id,
             documentationId: returnForm.documentationId,
             borrower: returnForm.borrower,
             returner: returnForm.returner,
             borrowStatus: returnForm.borrowStatus,
             returnDate: returnForm.returnDate,
             dueReturnDate: returnForm.dueReturnDate,
             remark: returnForm.remark
           });
          if (res.code === 200) {
            ElMessage.success("编辑成功");
            await loadReturnList();
            closeReturnDia();
          } else {
            ElMessage.error(res.msg || "编辑失败");
          }
        } else {
          // æ–°å¢žæ¨¡å¼ï¼Œè°ƒç”¨å½’还接口
          const res = await returnDocument({
            borrowId: returnForm.borrowId,
            borrower: returnForm.borrower,
            returner: returnForm.returner,
            borrowStatus: returnForm.borrowStatus,
            returnDate: returnForm.returnDate,
            dueReturnDate: returnForm.dueReturnDate,
            remark: returnForm.remark
          });
          if (res.code === 200) {
            ElMessage.success("新增成功");
            await loadReturnList();
            closeReturnDia();
          } else {
            ElMessage.error(res.msg || "新增失败");
          }
        }
      } catch (error) {
        ElMessage.error("操作失败,请重试");
      }
    }
  });
};
// åˆ é™¤å½’还记录
const handleDelete = (row) => {
  ElMessageBox.confirm(
    `确定要删除这条归还记录吗?`,
    "删除提示",
    {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    }
  ).then(async () => {
    try {
      const res = await deleteReturn([row.id]);
      if (res.code === 200) {
        ElMessage.success("删除成功");
        await loadReturnList();
      } 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 deleteReturn(selectedIds);
      if (res.code === 200) {
        ElMessage.success("批量删除成功");
        await loadReturnList();
      } 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;
  loadReturnList();
};
// å¤„理文档选择变化
const handleDocumentChange = (documentId) => {
  if (documentId) {
    // æ ¹æ®é€‰æ‹©çš„æ–‡æ¡£ID,从文档列表中查找对应的文档信息
    const selectedDoc = documentList.value.find(doc => doc.id === documentId);
    if (selectedDoc) {
      // è‡ªåŠ¨å¡«å……å€Ÿé˜…äººå’Œåº”å½’è¿˜æ—¥æœŸ
      returnForm.borrower = selectedDoc.borrower || selectedDoc.borrowerName || '';
      returnForm.dueReturnDate = selectedDoc.dueReturnDate || selectedDoc.expectedReturnDate || '';
    }
  } else {
    // æ¸…空相关字段
    returnForm.borrower = '';
    returnForm.dueReturnDate = '';
  }
};
// ç”Ÿå‘½å‘¨æœŸ
onMounted(() => {
  initData();
});
</script>
<style scoped>
.return-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>