fei
2025-11-19 9505153e1941acd6498591ef10abe81ba4c05fbc
src/views/archiveManager/archiveMaterial/index.vue
@@ -14,7 +14,29 @@
    <el-row>
    <el-col :span="16">
          <el-form-item label="责任者" prop="creator">
            <el-input v-model="form.creator" placeholder="请输入责任者" />
            <div class="title-search-wrapper">
              <el-input
                v-model="form.creator"
                placeholder="请输入责任者"
                @input="handleCreatorInput"
                @focus="showCreatorSuggestions = true"
                @blur="handleCreatorBlur"
              />
              <!-- 下拉建议框 -->
              <div
                v-if="showCreatorSuggestions && creatorSuggestions.length > 0"
                class="title-suggestions"
              >
                <div
                  v-for="(item, index) in creatorSuggestions"
                  :key="index"
                  class="suggestion-item"
                  @mousedown="selectCreatorSuggestion(item)"
                >
                  {{ item }}
                </div>
              </div>
            </div>
          </el-form-item>
          </el-col>
  </el-row>
@@ -22,7 +44,29 @@
  <el-col :span="16">
          <el-form-item label="文件题名" prop="title">
            <el-input v-model="form.title" placeholder="请输入文件题名" />
            <div class="title-search-wrapper">
              <el-input
                v-model="form.title"
                placeholder="请输入文件题名"
                @input="handleTitleInput"
                @focus="showTitleSuggestions = true"
                @blur="handleTitleBlur"
              />
              <!-- 下拉建议框 -->
              <div
                v-if="showTitleSuggestions && titleSuggestions.length > 0"
                class="title-suggestions"
              >
                <div
                  v-for="(item, index) in titleSuggestions"
                  :key="index"
                  class="suggestion-item"
                  @mousedown="selectTitleSuggestion(item)"
                >
                  {{ item }}
                </div>
              </div>
            </div>
          </el-form-item>
    </el-col>
    </el-row>
@@ -197,7 +241,7 @@
      <el-row :gutter="12" class="mb8">
      <el-row :gutter="12" class="mb8 fixed-row">
        <el-col :span="1.5">
          <el-button
            type="primary"
@@ -226,6 +270,7 @@
            icon="el-icon-download"
            size="mini"
            @click="handleExport"
            v-hasPermi="['system:materials:list']"
          >导出</el-button>
        </el-col>
@@ -586,7 +631,7 @@
          placeholder="请选择日期">
        </el-date-picker> -->
      </el-form-item>
      <el-form-item label="页号" prop="pageNumber">
    <!--  <el-form-item label="页号" prop="pageNumber">
        <el-col :span="8">
          <el-input
            v-model.number="queryParams.pageNumber"
@@ -606,7 +651,7 @@
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      </el-form-item> -->
     <el-form-item label="文字材料" prop="fileStyle">
          <el-select
            v-model="queryParams.fileStyle"
@@ -740,7 +785,7 @@
  </template>
  <script>
  import { listMaterials, enload, getMaterials, delMaterials, addMaterials, updateMaterials } from "@/api/system/materials"
  import { islegal, listMaterials, enload, getMaterials, delMaterials, addMaterials, updateMaterials } from "@/api/system/materials"
import { getToken } from '@/utils/auth'
import store from '@/store'
import { updateStatusById } from "@/api/system/records"
@@ -750,6 +795,11 @@
    name: "Materials",
    data() {
      return {
        // 记录元素初始位置和状态
  originalOffsetLeft: 0,
        originalWidth: 0,
            placeholderEl: null,
       importDialogVisible: false,
      fileList: [],
      uploadUrl:  process.env.VUE_APP_BASE_API +'/system/materials/upload/'+this.recordId, // 替换为实际的上传接口
@@ -819,6 +869,13 @@
        materialsList: [],
        // 弹出层标题
        title: "",
        // 文件题名搜索相关
        titleSuggestions: [], // 匹配的文件题名建议列表
        showTitleSuggestions: false, // 是否显示建议框
        titleSearchTimer: null, // 防抖定时器
        creatorSuggestions: [], // 匹配的责任人建议列表
        showCreatorSuggestions: false, // 是否显示责任人建议框
        creatorSearchTimer: null, // 责任人查询防抖定时器
        // 是否显示弹出层
        open: false,
        titles: "",
@@ -883,12 +940,25 @@
        }
      }
    },
   mounted() {
     // 添加滚动事件监听
     window.addEventListener('scroll', this.handleScroll);
    // 改为监听keydown事件
    document.addEventListener('keydown', this.handleKeyDown)
  },
  beforeDestroy() {
    // 移除滚动事件监听
    document.removeEventListener('keydown', this.handleKeyDown)
    // 移除滚动事件监听
    window.removeEventListener('scroll', this.handleScroll);
    // 清理占位符
    if (this.placeholderEl && this.placeholderEl.parentNode) {
      this.placeholderEl.parentNode.removeChild(this.placeholderEl);
    }
  },
    created() {
      //const roleId = this.$route.params && this.$route.params.roleId
@@ -961,12 +1031,25 @@
      }
      if(fileCount!==this.total)
      {
        this.$modal.msgWarning('请选择与记录数一致的文件或者修改对应的页码使其对应')
        this.$modal.msgWarning('请选择与记录数一致的文件')
        return
      }
      //判断页号与上传上传的文件的页号是不是一一对应的
      // 执行上传
      this.$refs.upload.submit()
     islegal(this.recordId).then(response => {
       console.log(response.data)
       var res = response.data
       if(res)
       {
         // 执行上传
           this.$refs.upload.submit()
           this.getList()
       }
       else
       {
         this.$modal.msgError("页号不连续,请修改为连续正确的页号!")
       }
     })
    },
    clearFileList() {
      this.fileList = [];
@@ -1040,6 +1123,114 @@
        }
        this.resetForm("forms")
      },
      // 处理文件题名输入事件
      handleTitleInput() {
        // 清除之前的定时器(防抖)
        if (this.titleSearchTimer) {
          clearTimeout(this.titleSearchTimer);
        }
        // 当输入框为空时,清空建议列表
        if (!this.form.title.trim()) {
          this.titleSuggestions = [];
          return;
        }
        // 设置新的定时器,延迟执行查询
        this.titleSearchTimer = setTimeout(() => {
          this.searchTitleSuggestions();
        }, 300);
      },
      // 搜索文件题名建议
      searchTitleSuggestions() {
        // 使用现有的listMaterials API,传入title作为查询参数
        listMaterials(
       {
          title: this.form.title,
          pageSize: 10 // 限制返回数量
        }).then(response => {
          console.log(response.data.data)
        //  alert(23)
          // 提取并去重title字段
          const titles = response.data.data.map(item => item.title);
          // 去重处理
          this.titleSuggestions = [...new Set(titles)];
          // 显示建议框
          this.showTitleSuggestions = true;
        }).catch(() => {
          // 错误处理
          this.titleSuggestions = [];
        });
      },
      // 处理失焦事件
      handleTitleBlur() {
        // 延迟隐藏,以便可以点击选择建议项
        setTimeout(() => {
          this.showTitleSuggestions = false;
        }, 200);
      },
      // 选择建议项
      selectTitleSuggestion(title) {
        this.form.title = title;
        this.showTitleSuggestions = false;
      },
      // 处理责任人输入事件
      handleCreatorInput() {
        // 清除之前的定时器(防抖)
        if (this.creatorSearchTimer) {
          clearTimeout(this.creatorSearchTimer);
        }
        // 当输入框为空时,清空建议列表
        if (!this.form.creator.trim()) {
          this.creatorSuggestions = [];
          return;
        }
        // 设置新的定时器,延迟执行查询
        this.creatorSearchTimer = setTimeout(() => {
          this.searchCreatorSuggestions();
        }, 300);
      },
      // 搜索责任人建议
      searchCreatorSuggestions() {
        // 使用现有的listMaterials API,传入creator作为查询参数
        listMaterials(
        {
          creator: this.form.creator,
          pageSize: 10 // 限制返回数量
        }).then(response => {
          // 提取并去重creator字段
          const creators = response.data.data.map(item => item.creator).filter(Boolean);
          // 去重处理
          this.creatorSuggestions = [...new Set(creators)];
          // 显示建议框
          this.showCreatorSuggestions = true;
        }).catch(() => {
          // 错误处理
          this.creatorSuggestions = [];
        });
      },
      // 处理责任人输入框失焦事件
      handleCreatorBlur() {
        // 延迟隐藏,以便可以点击选择建议项
        setTimeout(() => {
          this.showCreatorSuggestions = false;
        }, 200);
      },
      // 选择责任人建议项
      selectCreatorSuggestion(creator) {
        this.form.creator = creator;
        this.showCreatorSuggestions = false;
      },
      // 表单重置
      reset() {
        this.form = {
@@ -1218,11 +1409,25 @@
          this.$modal.msgSuccess("删除成功")
        }).catch(() => {})
      },
      /** 导出按钮操作 */
      /** 导出按钮操作 - 支持导出选中行或全部数据 */
      handleExport() {
        this.download('system/materials/export', {
          ...this.queryParams
        }, `materials_${new Date().getTime()}.xlsx`)
        // 判断是否有选中的行
        if (this.ids && this.ids.length > 0) {
          // 显示导出选中行的提示
          this.$message.info(`正在导出${this.ids.length}条选中的数据...`);
          // 导出选中的行数据
          this.download('system/materials/export', {
            ids: this.ids.join(','),
         //   exportType: 'selected'
          }, `materials_selected_${new Date().getTime()}.xlsx`)
        } else {
          // 显示导出全部数据的提示
          this.$message.info('正在导出符合当前查询条件的所有数据...');
          // 没有选中行时,导出当前查询条件的数据
          this.download('system/materials/export', {
            ...this.queryParams
          }, `materials_${new Date().getTime()}.xlsx`)
        }
      },
       /** 导入模板下载操作*/
@@ -1293,13 +1498,112 @@
      }).catch(() => {})
    },
    }
    // 滚动事件处理
    handleScroll() {
      const fixedRow = document.querySelector('.fixed-row');
      if (!fixedRow) return;
      // 获取元素当前位置信息
      const rect = fixedRow.getBoundingClientRect();
      const parentRect = fixedRow.parentNode.getBoundingClientRect();
      // 检查元素是否应该进入悬浮状态
      if (rect.top <= 0) {
        // 只在不在floating状态时添加,避免重复操作
        if (!fixedRow.classList.contains('floating')) {
          // 记录元素原始的左偏移量(相对于父容器)
          this.originalOffsetLeft = rect.left - parentRect.left;
          // 记录元素的原始宽度
          this.originalWidth = rect.width;
          // 添加floating类,使元素固定在顶部
          fixedRow.classList.add('floating');
          // 设置固定位置时的样式,保持与原始布局一致
          fixedRow.style.left = this.originalOffsetLeft + 'px';
          fixedRow.style.width = this.originalWidth + 'px';
          // 添加临时占位符,防止页面布局跳动
          if (!this.placeholderEl) {
            this.placeholderEl = document.createElement('div');
            this.placeholderEl.style.height = rect.height + 'px';
            this.placeholderEl.style.marginBottom = '10px';
            this.placeholderEl.style.boxSizing = 'border-box';
            fixedRow.parentNode.insertBefore(this.placeholderEl, fixedRow.nextSibling);
          }
        }
      } else {
        // 当元素回到视口顶部以上时,移除悬浮状态,恢复到文档流中
        if (fixedRow.classList.contains('floating')) {
          // 移除floating类
          fixedRow.classList.remove('floating');
          // 重置样式,让浏览器使用原始样式
          fixedRow.style.left = '';
          fixedRow.style.width = '';
          // 移除占位符,让元素回到原始位置
          if (this.placeholderEl && this.placeholderEl.parentNode) {
            this.placeholderEl.parentNode.removeChild(this.placeholderEl);
            this.placeholderEl = null;
          }
        }
      }
    },
}
  }
  </script>
</script>
<style scoped>
.title-search-wrapper {
        position: relative;
        width: 100%;
      }
      .title-suggestions {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        z-index: 1000;
        background-color: #fff;
        border: 1px solid #dcdfe6;
        border-radius: 4px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        max-height: 200px;
        overflow-y: auto;
        margin-top: 4px;
      }
      .suggestion-item {
        padding: 10px 15px;
        cursor: pointer;
        transition: background-color 0.2s;
      }
      .suggestion-item:hover {
        background-color: #f5f7fa;
      }
.title-border {
  border-bottom: 1px solid #dcdfe6;
  padding-bottom: 10px;
  margin-bottom: 20px;
}
.fixed-row {
  position: static;
  z-index: 1000;
  background-color: #fff;
  padding: 10px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  margin-bottom: 10px;
  box-sizing: border-box;
}
.fixed-row.floating {
  position: fixed;
  top: 0;
  z-index: 2000;
  padding: 10px;
  margin-bottom: 0;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  background-color: #fff;
}
</style>