fei
昨天 ba6ea01d3fe185f760f6c847a5dceaf14c01ef05
修改了代码
5个文件已修改
302 ■■■■ 已修改文件
src/api/system/records.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/archiveManager/archiveMaterial/index.vue 176 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/archiveManager/index.vue 113 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/records.js
@@ -87,3 +87,12 @@
    data: ids
  })
}
export function getIdFileCounts(ids)
{
  return request({
    url: '/system/records/getAllFilesCounts',
    method: 'post',
    data: ids
  })
}
src/router/index.js
@@ -123,7 +123,7 @@
      },
      //案卷详细信息管理
      {
        path: 'archiveMaterialManager/:recordId/:pageCount/:sho',
        path: 'archiveMaterialManager/:recordId/:pageCount/:sho/:recordStrId/:inquiryNumber',
        component: () => import('@/views/archiveManager/archiveMaterial/index'),
        name: 'ArchiveMaterialManager',
        meta: { title: '详细信息', activeMenu: '/archiveManager/infoManager' }
src/utils/request.js
@@ -17,7 +17,7 @@
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 30000
  timeout: 100000
})
// request拦截器
src/views/archiveManager/archiveMaterial/index.vue
@@ -2,7 +2,7 @@
    <div class="app-container">
      <div v-if="sho">
         <h2 class="title-border">添加案卷详细记录   {当前录入了{{total}}条}</h2>
         <h2 class="title-border">添加案卷详细记录   {当前录入了{{total}}条}  {当前档号为: {{recordStrId}} } {当前文号为: {{inquiryNumber}} }  </h2>
 <el-form ref="form" :model="form" :rules="rules" label-width="100px">
   <el-row>
@@ -26,7 +26,11 @@
                placeholder="请输入责任者"
                @input="handleCreatorInput"
                @focus="showCreatorSuggestions = true"
                @blur="handleCreatorBlur"
                        @keydown.up.prevent="handleKeyUp"
                        @keydown.down.prevent="handleKeyDown"
                        @keydown.enter.prevent="handleKeyEnter"
                        ref="creatorInput"
              />
              <!-- 下拉建议框 -->
              <div
@@ -37,7 +41,7 @@
                  v-for="(item, index) in creatorSuggestions"
                  :key="index"
                  class="suggestion-item"
                  @mousedown="selectCreatorSuggestion(item)"
                  @mousedown.prevent="selectCreatorSuggestion(item)"
                >
                  {{ item }}
                </div>
@@ -308,43 +312,7 @@
          >删除</el-button>
        </el-col>
          <el-col :span="1.5">
          <el-button
          v-if="sho"
            type="success"
            plain
            icon="el-icon-edit"
            size="mini"
            @click="handleImport"
            v-hasPermi="['system:materials:edit']"
          >全部附件导入</el-button>
            <!-- 在按钮下方添加导入对话框 -->
  <el-dialog title="批量导入附件" :visible.sync="importDialogVisible" width="50%">
    <el-upload
      class="upload-demo"
      ref="upload"
      :action="uploadUrl"
      :headers="headers"
      :data="uploadParams"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :file-list="fileList"
        :on-change="handleFileChange"
      :auto-upload="false"
      multiple
      accept=".jpg,.png"
    >
      <el-button slot="trigger" size="small" type="primary">选择文件</el-button>
      <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button>
      <el-button style="margin-left: 10px;" size="small" type="danger" @click="clearFileList">清空列表</el-button>
      <div slot="tip" class="el-upload__tip">可上传JPG等格式文件,单个文件不超过50MB</div>
    </el-upload>
  </el-dialog>
        </el-col>
        <el-col :span="1.5">
        <el-button
          type="warning"
@@ -373,6 +341,44 @@
        </el-upload>
      </el-col>
      <el-col :span="1.5">
              <el-button
              v-if="sho"
                type="success"
                plain
                icon="el-icon-edit"
                size="mini"
                @click="handleImport"
                v-hasPermi="['system:materials:edit']"
              >全部附件导入</el-button>
              已经上传了 {{this.fileCut}} 张附件,还要上传 {{this.totalPageCount-this.fileCut}} 张附件
                <!-- 在按钮下方添加导入对话框 -->
      <el-dialog title="批量导入附件" :visible.sync="importDialogVisible" width="50%">
        <el-upload
          class="upload-demo"
          ref="upload"
          :action="uploadUrl"
          :headers="headers"
          :data="uploadParams"
          :on-success="handleSuccess"
          :on-error="handleError"
          :on-preview="handlePreview"
          :on-remove="handleRemove"
          :file-list="fileList"
            :on-change="handleFileChange"
          :auto-upload="false"
          multiple
          accept=".jpg,.png"
        >
          <el-button slot="trigger" size="small" type="primary">选择文件</el-button>
          <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button>
          <el-button style="margin-left: 10px;" size="small" type="danger" @click="clearFileList">清空列表</el-button>
          <div slot="tip" class="el-upload__tip">可上传JPG等格式文件,单个文件不超过50MB</div>
        </el-upload>
      </el-dialog>
            </el-col>
        <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
      </el-row>
@@ -404,17 +410,17 @@
              </template>
            </el-table-column>
                <el-table-column label="文件材料序号" align="center" prop="fileNumber" />
        <el-table-column label="文件编号" align="center" prop="documentNumber" />
        <el-table-column label="文件编号" align="center" prop="documentNumber" width="180"/>
        <el-table-column label="责任者" align="center" prop="creator" />
        <el-table-column label="文件题名" align="center" prop="title" />
        <el-table-column label="责任者" align="center" prop="creator" width="180"/>
        <el-table-column label="文件题名" align="center" prop="title" width="220"/>
        <el-table-column label="日期" align="center" prop="date" width="180">
          <template slot-scope="scope">
            <span>{{ parseTime(scope.row.date, '{y}-{m}-{d}') }}</span>
          </template>
        </el-table-column>
        <el-table-column label="页号" sortable align="center" prop="pageNumber"  />
        <el-table-column label="备注" align="center" prop="remarks" />
        <el-table-column label="备注" align="center" prop="remarks" width="180"/>
            <!--          <el-table-column label="页次" sortable align="center" prop="pageOrder"  />
--->
        <el-table-column label="所处阶段" sortable align="center" width="180" prop="stage" />
@@ -820,6 +826,8 @@
    name: "Materials",
    data() {
      return {
        //附件数量
        fileCut: 0,
        //是否显示相关内容
        sho: true,
        totalPageCount: 0,
@@ -885,6 +893,8 @@
          { value: '06-业务数据', label: '06-业务数据' },
        ],
        recordId: null,
        inquiryNumber: '',
        recordStrId: '',
        // 遮罩层
        loading: true,
        // 选中数组
@@ -1029,7 +1039,8 @@
    created() {
      //const roleId = this.$route.params && this.$route.params.roleId
      const recordId = this.$route.params && this.$route.params.recordId
      this.recordStrId = this.$route.params && this.$route.params.recordStrId
      this.inquiryNumber = this.$route.params && this.$route.params.inquiryNumber
      this.totalPageCount = this.$route.params && this.$route.params.pageCount
      this.sho = this.$route.params && this.$route.params.sho
@@ -1052,9 +1063,44 @@
        this.queryParams.recordId = recordId
        this.getList()
        getFileCount(recordId).then(response=>{
          this.fileCut = response.length
         // alert(this.fileCut)
        })
      }
    },
    methods: {
      // 输入事件(示例:可根据输入内容过滤建议列表)
          handleCreatorInput(val) {
            // 重置选中索引
            this.selectedIndex = -1;
            // 这里替换成你的实际建议列表获取逻辑
            // this.creatorSuggestions = ['张三', '李四', '王五', '赵六'].filter(item =>
            //   item.includes(val)
            // );
          },
          // 上方向键逻辑
          handleKeyUp() {
            if (!this.showCreatorSuggestions || this.creatorSuggestions.length === 0) return;
            // 向上切换,到顶则回到最后一项
            this.selectedIndex = this.selectedIndex <= 0
              ? this.creatorSuggestions.length - 1
              : this.selectedIndex - 1;
          },
          // 下方向键逻辑
          handleKeyDown() {
            if (!this.showCreatorSuggestions || this.creatorSuggestions.length === 0) return;
            // 向下切换,到底则回到第一项
            this.selectedIndex = this.selectedIndex >= this.creatorSuggestions.length - 1
              ? 0
              : this.selectedIndex + 1;
          },
          // 回车选中当前高亮项
          handleKeyEnter() {
            if (this.selectedIndex >= 0 && this.selectedIndex < this.creatorSuggestions.length) {
              this.selectCreatorSuggestion(this.creatorSuggestions[this.selectedIndex]);
            }
          },
        // 上传失败回调
    handleError(err, file, fileList) {
      // 失败计数+1
@@ -1090,6 +1136,10 @@
        // 关闭上传对话框
        this.importDialogVisible = false;
        // 刷新列表数据
        getFileCount(recordId).then(response=>{
          this.fileCut = response.length
         // alert(this.fileCut)
        })
        this.getList();
      }
    },
@@ -1122,6 +1172,7 @@
        this.$modal.msgWarning('请先选择文件再上传')
        return
      }
     // alert(this.recordId)
@@ -1138,11 +1189,38 @@
       // }
     //  else
       {
         // 定义允许的最大值
         const maxValue = this.totalPageCount;
         // 过滤fileList数组,保留数字部分不超过maxValue的元素
         this.fileList = this.fileList.filter(item => {
          // 步骤1:检测是否包含中文([\u4e00-\u9fa5]是中文的Unicode范围)
             const hasChinese = /[\u4e00-\u9fa5]/.test(item.name);
             // 有中文直接返回false,删除该元素
             if (hasChinese) return false;
           // 步骤1:提取name中的纯数字部分
           // 正则表达式解释:\d+ 匹配一个或多个数字
           const numStr = item.name.match(/\d+/);
           // 处理没有数字的情况(返回false,会被过滤掉)
           if (!numStr) return false;
           // 步骤2:将数字字符串转为数字
           const num = parseInt(numStr[0], 10);
           // 步骤3:判断是否小于等于最大值
           return num <= maxValue;
         });
         // 初始化上传状态计数
         this.uploadSuccessCount = 0;
         this.uploadFailCount = 0;
         this.totalUploadFiles = fileCount;
         // 执行上传
         console.log(this.fileList)
           this.$refs.upload.submit()
      //     this.getList()
       }
@@ -1332,6 +1410,16 @@
      selectCreatorSuggestion(creator) {
        this.form.creator = creator;
        this.showCreatorSuggestions = false;
        // 手动触发 input 事件,确保表单验证等逻辑正常
            this.$nextTick(() => {
              const inputElement = this.$el.querySelector('textarea');
              if (inputElement) {
                inputElement.focus();
                // 将光标定位到文本末尾
                const length = inputElement.value.length;
                inputElement.setSelectionRange(length, length);
              }
            });
      },
      // 处理材料类型变化
src/views/archiveManager/index.vue
@@ -1,5 +1,6 @@
<template>
  <div class="app-container">
    <el-dialog title="搜索" :visible.sync="openSearch" width="1200px" top="5vh" append-to-body>
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="档案号" prop="recordId">
        <el-input
@@ -251,8 +252,18 @@
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
</el-dialog>
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleSearch"
        >搜索</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="primary"
@@ -296,7 +307,7 @@
        >导出</el-button>
      </el-col>
          <el-col :span="1.5">
          <el-col  v-if="userId!=1" :span="1.5">
        <el-button
          type="warning"
          plain
@@ -955,7 +966,7 @@
import axios from 'axios'
import { getToken } from '@/utils/auth'
import { enload, batchSubmitRecords,updateStatusById,listRecords,getMaxId, getRecords, delRecords, addRecords, updateRecords } from "@/api/system/records"
import { enload, getIdFileCounts,batchSubmitRecords,updateStatusById,listRecords,getMaxId, getRecords, delRecords, addRecords, updateRecords } from "@/api/system/records"
import { listAllCategory } from "@/api/system/category"
import { listAllProjectName } from "@/api/system/projectName"
import { listPlaceName, listAllPlaceName } from "@/api/system/placeName"
@@ -970,6 +981,7 @@
  name: "Records",
  data() {
    return {
      openSearch: false,
      totalUser: 0,
      visibleUser:false,
      userList:[],
@@ -1162,6 +1174,10 @@
    }
  },
  methods: {
    handleSearch()
    {
      this.openSearch = true;
    },
    /** 选择授权用户操作 */
    handleSelectUser() {
    //  const archiveRecordsId = this.queryParams.archiveRecordsId
@@ -1481,15 +1497,22 @@
    CheckInfo(row)
    {
   if(row.pageCount==null)
      {
        this.$modal.msgWarning("请先补充页码信息!")
        return;
      }
      var mid = row.id
      const roleId = 2
   //   alert(mid)
      var recordId = mid
      var pageCount = row.pageCount
      var recordStrId = row.recordId
      var inquiryNumber = row.inquiryNumber
      var sho = false
    //  this.$router.push("/archiveManager/infoManagerAu/user/" + roleId+"/"+recordId)
      this.$router.push("/archiveManager/infoManagerAu/archiveMaterialManager/" + recordId+"/"+pageCount+"/"+sho)
      this.$router.push("/archiveManager/infoManagerAu/archiveMaterialManager/" + recordId+"/"+pageCount+"/"+sho+"/"+recordStrId+"/"+inquiryNumber)
    },
    /*导出备考表*/
@@ -1510,7 +1533,12 @@
     JuanInfo(row)
     {
       var id = row.id
       console.log(row.pageCount)
      if(row.pageCount==null)
      {
        this.$modal.msgWarning("请先补充页码信息!")
        return;
      }
                 id = Number(id)
           var recordId = row.recordId
@@ -1536,6 +1564,8 @@
        //判断必须修改的字段是否补充完整了
       var valid = false;
      var pageCount = row.pageCount
      var recordStrId = row.recordId
      var inquiryNumber = row.inquiryNumber
      if(row.projectName!=null&&row.pageCount!=null&&row.caseTitle!=null&&row.constructionUnit)
       valid = true;
        if (valid) {
@@ -1547,7 +1577,7 @@
      var sho = true
    //  this.$router.push("/archiveManager/infoManagerAu/user/" + roleId+"/"+recordId)
      this.$router.push("/archiveManager/infoManagerAu/archiveMaterialManager/" + recordId+"/"+pageCount+"/"+sho)
      this.$router.push("/archiveManager/infoManagerAu/archiveMaterialManager/" + recordId+"/"+pageCount+"/"+sho+"/"+recordStrId+"/"+inquiryNumber)
      }else
      {
        this.$modal.msgWarning("请补充页号等相关信息,再编辑卷内目录!")
@@ -1633,24 +1663,75 @@
      this.getUserList()
    },
    /** 批量提交 */
    handleBatchSubmit() {
    async handleBatchSubmit() {
     // alert(this.ids)
      if (this.ids.length === 0) {
        this.$modal.msgWarning('请选择要提交的档案记录')
        return
      }
      const myValidIds = this.recordsList
  .filter(item => item.ownData === true)
  .map(item => item.id);
          // 检查选中的ID是否全部属于自己
    const invalidIds = this.ids.filter(id => !myValidIds.includes(id));
      const validRecords = this.recordsList
  // .filter(item => item.ownData === true)
    // 1. 转换recordsList为pageCount映射(核心步骤)
    const recordPageCountMap = this.recordsList.reduce((map, item) => {
      map[String(item.id)] = item.pageCount || item.totalpageCount || 0;
      return map;
    }, {});
    if (invalidIds.length > 0) {
      this.$message.error(`包含无权操作的ID: ${invalidIds.join(',')}`);
      return false;
  console.log("-------")
  let recordFileCountMap = {};
  try {
    // 调用接口:入参为有权操作的ID列表,返回 { recordId: 附件数, ... }
    const response = await getIdFileCounts(this.ids)
    // 假设接口返回格式:{ code: 0, data: { "1001": 5, "1002": 8 } }
    if (response.code === 200) {
      recordFileCountMap = response.data;
     // alert(434343)
    } else {
      this.$modal.msgError('获取附件数量失败:' + response.msg);
      return;
    }
  } catch (error) {
    this.$modal.msgError('接口调用失败:' + error.message);
    return;
  }
 // 3. 核心:筛选出「附件数等于自身totalpageCount」的有效ID
 const submitAbleIds = []; // 存储所有符合条件的ID
 const invalidAttachIds = []; // 存储附件数不匹配的ID(用于提示)
 for (const id of this.ids) {
   // 替换为项目实际字段名
   const attachmentCount = recordFileCountMap[id] || 0;
   const recordTotalPage = recordPageCountMap[id] || 0;
   if (attachmentCount === recordTotalPage) {
     submitAbleIds.push(id); // 符合条件,加入提交列表
   } else {
     invalidAttachIds.push({
       id: id,
       required: recordTotalPage
     });
   }
 }
 // 4. 提示附件数不匹配的记录
 if (invalidAttachIds.length > 0) {
   const tipMsg = invalidAttachIds.map(item =>
     `(ID:${item.id}) ,要求${item.required}个`
   ).join(';');
   this.$modal.msgWarning(`以下记录附件数量不匹配,将跳过提交:${tipMsg}`);
 }
 // 5. 检查是否有可提交的ID
 if (submitAbleIds.length === 0) {
   this.$modal.msgWarning('暂无符合所有条件的记录可提交');
   return;
 }
    //如果id全部有效才继续提交
      batchSubmitRecords( this.ids ).then(response => {
      batchSubmitRecords( submitAbleIds ).then(response => {
        if (response.code === 0) {
          this.$modal.msgSuccess('批量提交成功')
          this.getList()