瀏覽代碼

首件上报页面优化预览

duy 2 年之前
父節點
當前提交
ddd222e8f7
共有 3 個文件被更改,包括 2872 次插入0 次删除
  1. 6 0
      src/router/modules/base.js
  2. 1966 0
      src/views/other/components/ListItem.vue
  3. 900 0
      src/views/other/first-item copy.vue

+ 6 - 0
src/router/modules/base.js

@@ -172,6 +172,12 @@ export default [
                 meta: {title: '首件工程'},
                 component: () => import('~src/views/other/first-item.vue')
             }
+            // {
+            //     path: '/other/first-item',
+            //     name: 'other-first-item',
+            //     meta: {title: '首件工程'},
+            //     component: () => import('~src/views/other/first-item copy.vue')
+            // }
         ],
     },
     {

+ 1966 - 0
src/views/other/components/ListItem.vue

@@ -0,0 +1,1966 @@
+<template>
+    <div class="data-fill-list-box">
+        <el-collapse v-model="ActiveKey"  @change="CollapseChange">
+            <template v-for="(item,index) in listDatas" :key="item?.id">
+                <el-collapse-item :name="`item-${index}-${item?.id}`" :disabled="item['isBussShow'] === 2" :id="`item-${index}-${item?.id}`">
+                    <template #title>
+                        <div class="hc-collapse-item-header">
+                            <div class="text-lg truncate item-title">{{item.name}}</div>
+                            <div class="hc-extra-text-box">
+                                <HcTooltip keys="wbs_del_table" v-if="item['isCopeTab'] === 2">
+                                    <el-button type="danger" plain :disabled="item['isBussShow'] === 2" @click.stop="delClick(item,index)">删除本表</el-button>
+                                </HcTooltip>
+                                <HcTooltip keys="wbs_copy_table">
+                                    <el-button type="primary" :loading="copyClickLoading" plain :disabled="item['isBussShow'] === 2" @click.stop="copyClick(item,index)">复制本表</el-button>
+                                </HcTooltip>
+                                <HcTooltip keys="wbs_hide_table">
+                                    <el-button type="primary" plain @click.stop="hideClick(item,index)">
+                                        <template v-if="item['isBussShow'] === 1">隐藏本表</template>
+                                        <template v-else>显示本表</template>
+                                    </el-button>
+                                </HcTooltip>
+                                <HcTooltip keys="wbs_preview_table" v-if="isStatus != 3">
+                                    <el-button type="info" plain disabled v-if="item['isBussShow'] === 2 || item['isTabPdf'] === 1|| item['pdfUrl'] === ''">预览</el-button>
+                                    <el-button type="primary" plain @click.stop="previewClick(item,index)" v-else>预览</el-button>
+                                </HcTooltip>
+                                <HcTooltip keys="wbs_upload_table">
+                                    <el-button :type="item['tabFileType'] === 2?'success':'primary'" plain :disabled="item['isBussShow'] === 2" @click.stop="uploadClick(item,index)">
+                                        <template v-if="item['tabFileType'] === 2">已上传</template>
+                                        <template v-else>上传</template>
+                                    </el-button>
+                                </HcTooltip>
+                            </div>
+                        </div>
+                    </template>
+                    <div class="data-fill-list-item-content">
+                        <div class="data-fill-table-form-box">
+                            <div class="hc-excel-table-form-view" :id="`table-form-${item?.id}`" />
+                            <div class="hc-no-table-form" v-if="item?.isTableForm === false">
+                                <div class="table-form-no">
+                                    <img :src="notableform" alt=""/>
+                                    <div class="desc">暂无表单数据</div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="data-fill-table-tip-box">
+                            <div class="text-orange tip-title">
+                                <HcIcon name="error" fill ui="text-2xl"/>
+                                <span class="ml-1">提示</span>
+                            </div>
+                            <div class="text-gray-400 tip-item">1、灰色框代表可通过系统识别计算,公式自动引用,可通过公式计算少量数据,(表头数据及简单),也可只填写白色框数据</div>
+                            <div class="text-gray-400 tip-item">2、系统支持键盘中,shift + tab键向上一个填报框切换,tab向下一个填报框切换。暂不支持上下按键切换输入框</div>
+                            <div class="table-tip-foot">
+                                <div class="tip-left-btn">
+                                    <HcTooltip keys="wbs_import_table">
+                                        <div class="text-gray-400 dow-text">
+                                            <HcIcon name="publish" ui="text-lg"/>
+                                            <span class="ml-1">导入列表数据</span>
+                                        </div>
+                                    </HcTooltip>
+                                    <HcTooltip keys="wbs_download_table">
+                                        <div class="text-main dow-text">
+                                            <HcIcon name="file_download" ui="text-lg"/>
+                                            <span class="ml-1">下载导入模板</span>
+                                        </div>
+                                    </HcTooltip>
+                                </div>
+                                <div class="tip-right-btn">
+                                    <HcTooltip keys="wbs_save_table">
+                                        <el-button type="primary" hc-btn :disabled="item?.isTableForm === false" :loading="tableFormSaveLoading" @click="tableFormSaveClick(item,index)">
+                                            <HcIcon name="save"/>
+                                            <span>保存</span>
+                                        </el-button>
+                                    </HcTooltip>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </el-collapse-item>
+            </template>
+        </el-collapse>
+    </div>
+
+    <!--右键菜单-->
+    <HcContextMenu ref="contextMenuRef" :datas="tableFormMenu" @item-click="handleMenuSelect"/>
+
+    <!--上传文件-->
+    <HcDialog :show="uploadModal" title="上传文件" widths="38rem" :footer="false" @close="uploadModal = false">
+        <HcUpload :fileList="fileListData" :datas="uploadData" @change='uploadChange'/>
+    </HcDialog>
+
+    <!--插入设计值/频率-->
+    <HcDialog :show="IDVFModal" title="插入设计值/频率" widths="600px" saveText="确认插入" @close="closeIDVFModal" @save="IDVFModalSaveClick">
+        <el-alert title="填写完设计值和频率,系统自动计算实测值" type="warning" :closable="false"/>
+        <el-form ref="formIDVFRef" :model="formIDVFModel" label-width="auto" size="large">
+            <div class="form-item-div text-center mb-3">
+                <el-radio-group size="large" v-model="formIDVFModel.type">
+                    <el-radio :label="1">公路工程</el-radio>
+                    <el-radio :label="2" class="ml-4">水利水电</el-radio>
+                </el-radio-group>
+            </div>
+            <el-form-item label="设计值">
+                <!-- onkeyup="value = value.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g,'$1')" -->
+                <el-input v-model="formIDVFModel.design" placeholder="如果设计值存在两个,则使用 '/' 连接,例如12/23"/>
+            </el-form-item>
+            <el-form-item label="频率" v-if="formIDVFModel.type === 1">
+                <!--  onkeyup="value = value.replace(/^(0+)|[^\d]+/g,'')" -->
+                <el-input v-model="formIDVFModel.size" placeholder="如果设计值使用 '/' 连接,则频率也是用 '/' 连接,例如5/10"/>
+            </el-form-item>
+            <el-form-item label="容量" v-if="formIDVFModel.type === 2">
+                <!--   onkeyup="value = value.replace(/^(0+)|[^\d]+/g,'')" -->
+                <el-input v-model="formIDVFModel.capacity" placeholder="如果容量存在两个,则使用 '*',或者 '/' 连接例如2*4,5/7"/>
+            </el-form-item>
+            <el-form-item label="合格点数">
+                <el-input v-model="formIDVFModel.pass" placeholder="如果设计值使用 '/' 连接,则合格点数也是用 '/' 连接,例如2/5"/>
+            </el-form-item>
+            <el-form-item label="偏差范围">
+                <el-input v-model="formIDVFModel.dev" placeholder="如果设计值使用 '/' 连接,则偏差范围也是用 '/' 连接,例如±2/±3" />
+            </el-form-item>
+        </el-form>
+    </HcDialog>
+
+    <!--插入特殊字符-->
+    <HcDialog :show="specialModal" title="插入特殊字符" widths="600px" saveText="确认插入" @close="specialModal = false" @save="specialNodeClick">
+        <el-form ref="specialFormRef" :model="specialFormModel" :rules="specialFormRules" label-width="0px" size="large" class="mb-6">
+            <el-form-item prop="val" class="special-form-item">
+                <el-input v-model="specialFormModel.val" ref="specialRef" id="specialId" placeholder="请选择特殊字符代码" clearable @blur="specialInputBlur"/>
+            </el-form-item>
+        </el-form>
+        <el-row :gutter="20" style="margin: -10px;">
+            <el-col :span="3" style="padding: 10px;" v-for="item in specialCharacters">
+                <div class="special-box" @click="specialClick">
+                    <span class="font-EUDC" :title="`字符代码(C):${item !== 'K̅'?item.slice(2,7):'K̅'}`" v-html="item"/>
+                </div>
+            </el-col>
+        </el-row>
+    </HcDialog>
+
+    <!--关联试验数据-->
+    <HcDialog :show="CTDModal" title="关联试验数据"  widths="84%"   :footer="false"  @close="CTDModal = false">
+       <div class="adding-form-dialog-box">
+            <div class="dialog-tree-box">
+                 <el-scrollbar>
+                      <ElTree class="hc-tree-node tree-line"
+                        ref="ElTreeRef"
+                        :props="ElTreeProps"
+                        :load="ElTreeLoadNode"
+                        lazy
+                        highlight-current
+                        accordion
+                        node-key="primaryKeyId"
+                        :default-expanded-keys="defaultExpandedCids"
+                        :autoExpandKeys="CTDTreeAutoExpandKeys"
+                        @node-click="CTDElTreeClick"
+                        :indent="0"
+                       
+                      >
+                      </ElTree>
+                 </el-scrollbar>
+            </div>
+            <div class="dialog-table-box">
+                <div class="dialog-search">
+                     <div class="w-64 ml-2">
+                            <HcDatePicker :dates="CTDbetweenTime" clearable @change="CTDbetweenTimeUpdate"/>
+                    </div>
+                     <div class="ml-2">
+                            <el-button type="primary" @click="CTDsearchClick">
+                                <HcIcon name="search-2"/>
+                                <span>搜索</span>
+                            </el-button>
+                    </div>
+                </div>
+                <div class="dialog-table">
+                        <HcTable  :loading="CTDdialogTableLoading" :column="CTDdialogTableColumn" :datas="CTDdialogTableData1" >
+                             <template #recordNo="{row}">
+                                <span class="text-link" @click="CTDtableRowName(row)" >{{row?.recordNo}}</span>
+                            </template>
+                        </HcTable>
+                </div>
+                <div class="dialog-pages">
+                        <HcPages :pages="CTDsearchFormPage" @change="CTDsearchFormPageChange"/>
+                </div>
+            </div>
+       </div>
+                
+
+    </HcDialog>
+    <!-- 选择要插入的数据 -->
+      <HcDialog :show="insertDataShow" title="选择需要插入的数据"  widths="84%"  saveText="保存" @close="cancelinsertData" @save="submitinsertData">
+          <div>
+               <div class="flex-1" style="padding-left:20px">
+                    <HcNewSwitch :datas="tabTypeTab" :keys="tabTypeKey" @change="tabTypeChange" size="default" :round="false"/>
+                      <el-select v-model="testReportId" :placeholder="placeholderType" clearable class="ml-2 w-80" @change="testReportIdchange" :loading="insertDataSelectoading">
+                                <el-option v-for="item in testReportData" :key="item.id" :label="item['fullName']" :value="item['id']"/>
+                      </el-select>
+                </div>
+                <div class="dialog-table-box">
+                     <!-- <div class="dialog-table">
+                        <HcTable :column="insertDataTableColumn" :datas="insertDataTable" :loading="insertDataTableLoading">
+                            <template #tempLow="{row}">{{row['tempLow']}} ~ {{row['tempHigh']}}</template>
+                            <template #action="{row}">
+                                     <el-checkbox size="large"  @change="insertDataTableCheck(row)"/>
+                               
+                            </template>
+                        </HcTable>
+                     </div> -->
+                     <!-- <div class="dialog-pages">
+                        <HcPages :pages="insertDataPage" @change="insertDataPageChange"/>
+                    </div> -->
+                 <div class="copy-node-many-table">
+                    <el-scrollbar v-loading="insertDataTableLoading" >
+                        <el-table :data="insertDataTable" border stripe    @selection-change="insertDataTableCheck">
+                            <el-table-column type="selection" width="55" />
+                            <el-table-column prop="key_12__3_1" label="数据名称"/>
+                            <!-- <el-table-column prop="action" label="操作" width="120" align="center">
+                                <template #default="{row}">
+                                      <el-checkbox  size="large"  @change="insertDataTableCheck(row)"/>
+                                </template> -->
+                            <!-- </el-table-column> -->
+                        </el-table>
+                    </el-scrollbar>
+                </div>
+                </div>
+          </div>
+      </HcDialog>
+    <!-- 复制本表 -->
+     <HcDialog :show="CopyModal" title="复制本表" widths="1200px" saveText="确认复制" @close="CopyModal = false" @save="CopyModal = false">
+        <el-alert title="复跨节点复制: 把当前表格已形成的数据复制到其他工程部位的相同表格里面" type="warning" :closable="false"/>
+        <el-alert title="本节点复制:在当前节点内复制本表及数据" type="warning" :closable="false"/>
+        <div class="radio-group-box">
+            <el-radio-group v-model="CopyModalType">
+                            <el-radio label="1">跨节点复制</el-radio>
+                            <el-radio label="2" class="ml-4">本节点复制</el-radio>
+            </el-radio-group>
+        </div>
+        <div class="copy-node-many-box" v-if="CopyModalType=== '1'">
+                <div class="copy-node-many-tree">
+                    <el-scrollbar>
+                      <WbsTree 
+                      :projectId="projectId" 
+                      :contractId="contractId" 
+                      @nodeTap="wbsElTreeClick" 
+                      @nodeLoading="ElTreeNodeLoading"
+                     
+                      />
+                    </el-scrollbar>
+                </div>
+                <div class="copy-node-many-table">
+                    <el-scrollbar v-loading="ListItemLoading" >
+                        <el-table :data="copyModalTable" border stripe>
+                            <el-table-column prop="fullName" label="表格名称"/>
+                            <el-table-column prop="action" label="操作" width="120" align="center">
+                                <template #default="{row}">
+                                      <el-checkbox v-model="row.isCheck"  size="large"  @change="copyModalTableCheck(row)"/>
+                                </template>
+                            </el-table-column>
+                        </el-table>
+                    </el-scrollbar>
+                </div>
+            </div>
+    </HcDialog>
+        <!--关联试验文件-->
+    <HcDialog :show="fileModal" title="关联试验文件"  widths="84%"  saveText="保存" @close="fileModal = false" @save="savefileModal">
+        <div class="radio-box">
+                <el-radio-group v-model="fileModalradio" @change="radioChange">
+                    <el-radio :label="1">试验检测</el-radio>
+                    <el-radio :label="2">第三方检测</el-radio>
+                    <el-radio :label="3">外委检测</el-radio>
+                </el-radio-group>
+        </div>
+       <div class="adding-form-dialog-box">
+            <div class="dialog-tree-box">
+                 <el-scrollbar>
+                    <!-- 试验检测树 -->
+                        <ElTree class="hc-tree-node tree-line"
+                        :props="ElTreeProps"
+                        :load="ElTreeLoadNode"
+                        lazy
+                        highlight-current
+                        accordion
+                        node-key="primaryKeyId"
+                        @node-click="fileModalElTreeClick"
+                        :indent="0"
+                        v-if="fileModalradio==1"
+                      >
+                      </ElTree>
+                      <!-- 第三方树 -->
+                        <ElTree 
+                        v-else
+                        class="hc-tree-node" ref="ElTreeRef2" :props="thirdElTreeProps" :data="thirdtreeDatas" highlight-current accordion node-key="id"
+                         @node-click="thirdtreeDatasElTreeClick" :indent="0">
+                        </ElTree>
+                 </el-scrollbar>
+            </div>
+            <div class="dialog-table-box">
+                <div class="dialog-search">
+                     <div class="w-64 ml-2">
+                            <HcDatePicker :dates="filebetweenTime" clearable @change="filebetweenTimeUpdate"/>
+                    </div>
+                     <div class="ml-2">
+                            <el-button type="primary" @click="filesearchClick">
+                                <HcIcon name="search-2"/>
+                                <span>搜索</span>
+                            </el-button>
+                    </div>
+                </div>
+                <div class="dialog-table">
+                        <HcTable ref="dialogTableRef1" :loading="filedialogTableLoading" :column="filedialogTableColumn" :datas="filedialogTableData" isCheck @selection-change="filedialogTableSelection1"  v-if="fileModalradio==1">
+                             <template #recordNo="{row}">
+                                <span :class="[row?.isSelectedStatus==1?'text-green':'']">{{row?.recordNo}}</span>
+                            </template>
+                        </HcTable>
+                        <HcTable ref="dialogTableRef2" :loading="filedialogTableLoading" :column="filedialogTableColumn1" :datas="filedialogTableData" isCheck @selection-change="filedialogTableSelection" v-if="fileModalradio==2">
+                             <template #reportNo="{row}">
+                                <span :class="[row?.isSelectedStatus===1?'text-green':'']">{{row?.reportNo}}</span>
+                            </template>
+                        </HcTable>
+                        <HcTable ref="dialogTableRef" :loading="filedialogTableLoading" :column="filedialogTableColumn1" :datas="filedialogTableData" isCheck @selection-change="filedialogTableSelection" v-if="fileModalradio==3">
+                             <template #reportNo="{row}">
+                                <span :class="[row?.isSelectedStatus===1?'text-green':'']">{{row?.reportNo}}</span>
+                            </template>
+                        </HcTable>
+                  
+                </div>
+                <div class="dialog-pages">
+                        <HcPages :pages="filesearchFormPage" @change="filesearchFormPageChange"/>
+                </div>
+            </div>
+       </div>
+                
+
+    </HcDialog>
+</template>
+
+<script setup>
+import {ref,watch,nextTick} from "vue";
+import {getStoreData, setStoreData} from '~src/utils/storage'
+import notableform from '~src/assets/view/notableform.svg';
+import HTableForm from "~src/plugins/HTableForm"
+import WbsTree from "../components/WbsTree.vue"
+import wbsApi from "~api/data-fill/wbs"
+import firstApi from '~api/other/first-item';
+import dataApi from "~api/tentative/detect/test";
+import thirdApi from "~api/tentative/detect/third";
+import {getTreeAll} from "~api/tentative/detect"
+import HcUpload from "./HcUpload.vue"
+import {utilsText, isType, formValidate, deepClone, getObjValue} from "vue-utils-plus"
+import {useAppStore} from "~src/store";
+import samplingApi from "~api/tentative/material/sampling"
+
+//初始
+const props = defineProps({
+    datas: {
+        type: Array,
+        default: () => ([])
+    },
+    classify: {
+        type: [String,Number],
+        default: ''
+    },
+    status: {
+        type: [String,Number],
+        default: ''
+    },
+    primaryKeyId: {
+        type: [String,Number],
+        default: ''
+    },
+    contractId: {
+        type: [String,Number],
+        default: ''
+    },
+    projectInfo: {
+        type: Object,
+        default: () => ({})
+    },
+    authBtnTabKey: {
+        type: [String,Number],
+        default: ''
+    },
+    drawType:{
+        type:Boolean,
+        default:false
+    },
+    wbsTempId: {
+        type: [String,Number],
+        default: ''
+    }, 
+    tenantId: {
+        type: [String,Number],
+        default: ''
+    },
+    wbsType: {
+        type: [String,Number],
+        default: ''
+    },
+    treeItem :{
+         type: Object,
+        default: () => ({})
+    },
+    tableFileData:{
+        type: Array,
+        default: () => ([])
+    },
+    finishFile:{
+         type: Object,
+        default: () => ({})
+    }
+})
+const {isString, getObjNullValue, getArrValue} = isType()
+const {setPosInsert, setPosRange} = utilsText()
+const listDatas = ref(props.datas)
+const classify = ref(props.classify)
+const isStatus = ref(props.status)
+const isPrimaryKeyId = ref(props.primaryKeyId)
+const contractId = ref(props.contractId)
+const projectInfo = ref(props.projectInfo)
+const useAppState = useAppStore()
+const authBtnTabKey = ref(props.authBtnTabKey)
+const drawType = ref(props.drawType)
+const wbsTempId = ref(props.wbsTempId);
+const tenantId = ref(props.tenantId);
+const wbsType = ref(props.wbsType);
+const treeItem = ref(props.treeItem);
+const tableFileData = ref(props.tableFileData);
+const finishFile = ref(props.finishFile);
+
+//全局变量
+const projectId = ref(useAppState.getProjectId);
+
+//监听
+watch(() => [
+    props.datas,
+    props.classify,
+    props.primaryKeyId,
+    props.contractId,
+    props.projectInfo,
+    props.treeItem,
+    props.tableFileData,
+    props.finishFile
+], ([datas, classifyVal, primaryKeyId, cid, pInfo,TreeItem,TableFileData,FinishFile]) => {
+    listDatas.value = datas
+    classify.value = classifyVal
+    isPrimaryKeyId.value = primaryKeyId
+    contractId.value = cid
+    projectInfo.value = pInfo
+    treeItem.value=TreeItem
+    tableFileData.value=TableFileData
+    finishFile.value=FinishFile
+    setFormDataNum(datas)
+})
+
+//监听
+// watch(() => [
+//     props.status
+// ], ([val]) => {
+//     //1 未填报,2待上报,3已上报
+//     isStatus.value = val
+// })
+//监听
+watch(() => [
+    props.autoExpandKeys,
+    props.projectId,
+    props.contractId,
+    props.wbsTempId,
+    props.tenantId,
+    props.wbsType,
+     props.status
+], ([expandKeys, UserProjectId, UserContractId, UserWbsTempId, UserTenantId, UserIdPrefix, wbs_type,val]) => {
+   
+    projectId.value = UserProjectId
+    contractId.value = UserContractId
+    wbsTempId.value = UserWbsTempId
+    tenantId.value = UserTenantId
+    
+    wbsType.value = wbs_type
+     isStatus.value = val
+})
+
+//渲染完成
+nextTick(() => {
+    setFormDataNum(props.datas)
+})
+
+//获取表单初始数据
+const getFormDataInit = (item, pkeyId) => {
+    return {
+        projectId: item?.projectId,
+        contractId: item?.contractId,
+        classify: classify.value,
+        pkeyId: pkeyId ? pkeyId + '' : '',
+        nodeId: isPrimaryKeyId.value
+    }
+}
+
+//设置表单对象的数量
+const formData = ref([])
+const setFormDataNum = (datas) => {
+    ActiveKey.value = []
+    let newArr = [];
+    for (let i = 0; i < datas.length; i++) {
+        newArr.push({
+            ...getFormDataInit(datas[i], datas[i].pkeyId),
+            isCollapseLoad: false,
+        })
+    }
+    formData.value = newArr
+    setTableFormMenu(projectInfo.value)
+}
+
+//展开事件
+const ActiveKey = ref([])
+const formKeyIds = ref('')
+const CollapseChange = async (name) => {
+    console.log(name,'name')
+    ActiveKey.value = name
+    console.log(name,'name');
+    let names=[]
+    if(name.length>0){
+         names = name[0] ? name[name.length-1].split('-') : name[0]
+    }
+   
+    console.log(names,'names');
+    if (names.length > 0) {
+        getOffsetTop(name);
+        const index = names[1]
+        const item = listDatas.value[index]
+        formKeyIds.value = item.id ? item.id + '' : ''
+        if (!item.isTableFormRender) {
+            //获取已填写的数据
+            await getBussDataInfo(item,item.id, index)
+            //渲染表单
+            await getExcelHtml(item,index)
+        }
+    } else {
+        getOffsetTop()
+        formKeyIds.value = ''
+    }
+}
+
+//获取模板标签数据
+const formRegExpJson = ref({})
+const getExcelHtml = async (item,index) => {
+    const pkeyIds = item.id ? item.id + '' : ''
+    if (pkeyIds) {
+        const {error, code, data} = await firstApi.getFirstExcelHtml({contractId: contractId.value}, false)
+        // const resData = isString(data) ? data || '' : ''
+        //处理数据
+        const resData = isString(data?.data) ? data?.data || '' : ''
+       
+        if (!error && code === 200 && resData) {
+            item.isTableForm = true
+            //渲染表单
+            HTableForm.createForm({
+                template: resData,
+                tableForm: formData.value[index],
+                appId: `#table-form-${pkeyIds}`,
+                onRight: (event, KeyName) => {
+                    onRightClick(event, KeyName, index)
+                },
+                //表单正则效验
+                onBlur: (event, key, reg, val, msg, leng) => {
+                    setTableFormBlurReg(pkeyIds, event, key, reg, val, msg, item, index, leng)
+                }
+            })
+            item.isTableFormRender = true
+            item.isRenderTableForm = true
+        } else {
+            item.isTableForm = false
+            item.isRenderTableForm = true
+            window?.$message?.warning('暂无表单')
+        }
+    } else {
+        item.isTableForm = false
+        item.isRenderTableForm = false
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+
+//正则效验
+const setTableFormBlurReg = (pkeyId, event, key, reg, val, msg, item, index, leng) => {
+    const dom = document.getElementById(key)?.parentElement ?? ''
+    if (dom) {
+        if (val && reg) {
+            let regx = new RegExp(reg);
+            let state = regx.test(val);
+            if (state) {
+                delete formRegExpJson.value[pkeyId]
+                dom.style = ''
+            } else {
+                formRegExpJson.value[pkeyId] = {key, reg, val, msg, state, nodeName: item.nodeName, itemId: `item-${index}-${item?.pkeyId}`}
+                dom.style = '--el-input-border-color: #fe0000; box-shadow: 0 0 0 2px #fe0000 inset;'
+                window?.$message?.warning(msg)
+            }
+        } else {
+            delete formRegExpJson.value[pkeyId]
+            dom.style = ''
+        }
+        /*let efficacyRegState = true, efficacyLengState = true;
+        //正则效验
+        if (val && reg) {
+            let regx = new RegExp(reg);
+            let state = regx.test(val);
+            console.log('reg:', reg)
+            console.log('val:', val)
+            console.log('state:', state)
+            if (!state) {
+                efficacyRegState = true
+            } else {
+                efficacyRegState = false
+                window?.$message?.warning(msg)
+            }
+        } else {
+            efficacyRegState = true
+        }
+        //校验字符长度
+        if (val && leng) {
+            const num = val.toString().length;
+            if (num > leng) {
+                efficacyLengState = false
+                window?.$message?.warning('长度不能超过' + leng)
+            } else {
+                efficacyLengState = true
+            }
+        } else {
+            efficacyLengState = true
+        }
+        //处理效验结果
+        if (efficacyRegState && efficacyLengState) {
+            delete formRegExpJson.value[pkeyId]
+            dom.style = ''
+        } else {
+            formRegExpJson.value[pkeyId] = {key, reg, val, msg, leng, state: efficacyRegState, lengState: efficacyLengState, nodeName: item.nodeName, itemId: `item-${index}-${item?.pkeyId}`}
+            dom.style = '--el-input-border-color: #fe0000; box-shadow: 0 0 0 2px #fe0000 inset;'
+        }*/
+    }
+}
+
+//获取已填写的数据
+const getBussDataInfo = async (item, pkeyId, index) => {
+    const pkeyIds = pkeyId ? pkeyId + '' : ''
+    if (pkeyIds) {
+        const {error, code, data} = await firstApi.getFirstBussDataInfo({
+             contractId: contractId.value || '',
+            firstId: pkeyId + ''
+        }, false)
+        const resData = getObjNullValue(data)
+        if (!error && code === 200 && resData) {
+            HTableForm.setPickerKey(resData)
+            const InitObj = getFormDataInit(item, pkeyId) //有数据,关联数据
+            formData.value[index] = {...resData, ...InitObj, isCollapseLoad: true}
+        } else {
+            formData.value[index] = {...getFormDataInit(item, pkeyId), isCollapseLoad: true}
+        }
+    } else {
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+
+//单个保存
+const tableFormSaveLoading = ref(false)
+const tableFormSaveClick = async (item,index) => {
+    if (isStatus.value !== '3') {
+        console.log(item)
+        const res = await saveExcelBussData(item,index)
+        console.log(res,'res')
+        if (res) {
+            await getBussPdfInfo(item,true,res)
+            renewData()
+        }
+    } else {
+        window?.$message?.warning('已上报的资料,不允许保存。')
+    }
+}
+//处理数据
+const rowsToArr = (rows) => {
+    let newArr = [];
+    for (let i = 0; i < rows.length; i++) {
+        newArr.push({
+            id: rows[i]?.id,
+            name: rows[i]?.name
+        })
+    }
+    return newArr
+}
+
+//保存表单数据
+const saveExcelBussData = async (item, index, showTip = true) => {
+  
+    const isRegExp = !!getObjNullValue(formRegExpJson.value)
+    if (!isRegExp) {
+        tableFormSaveLoading.value = true
+        const InitObj = getFormDataInit(item, item.id)
+         
+         
+        // const {error, code} = await firstApi.saveBussData({
+        //     ...formData.value[index],
+        //     ...InitObj
+        // })
+        const info = treeItem.value;
+         const { primaryKeyId } = treeItem.value
+         console.log(primaryKeyId,'primaryKeyId')
+          const linkIds = rowsToArr(tableFileData.value);
+          console.log(formData.value[index],'formData')
+         const { error, code, data } = await firstApi.saveBussData({
+           ...formData.value[index],
+            projectId: projectId.value,
+            contractId: contractId.value,
+            firstNodeId: primaryKeyId,
+            pkeyId:info.id ,
+            classify: '1',
+            isFirst: 1,
+            linkProcessList: linkIds,
+            ...finishFile.value
+        }, false)
+        //处理数据
+        tableFormSaveLoading.value = false
+        if (!error && code === 200) {
+            if(showTip) window?.$message?.success('保存成功')
+            return data
+        } else {
+            return false
+        }
+    } else {
+        window?.$message?.warning('请先修改完红色输入框的数据')
+        return false
+    }
+}
+
+//预览PDF
+const getBussPdfInfo = async (item, showTip = true,resid) => {
+    console.log(resid,'resid');
+    const pkeyIds = item.id ? item.id + '' : ''
+    if (pkeyIds) {
+        const {error, code, data} = await  firstApi.getFirstBussPdfInfo({
+           firstId:resid?resid:pkeyIds
+        },false)
+        if (!error && code === 200) {
+            if (data) {
+                window.open(data, '_blank')
+            } else if(showTip) {
+                window?.$message?.warning('PDF错误')
+            }
+        } else {
+            if(showTip) {
+                window?.$message?.warning(data.msg || '获取PDF失败')
+            }
+        }
+    } else {
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+
+//删除本表
+const delClick = async (item) => {
+    const pkeyIds = item.pkeyId ? item.pkeyId + '' : ''
+    if (pkeyIds) {
+        if (isStatus.value !== '3') {
+            const {error, code} = await wbsApi.removeBussTabInfo({
+                pkeyid: pkeyIds,
+                classify: classify.value,
+            })
+            if (!error && code === 200) {
+                window?.$message?.success('操作成功')
+                renewData()
+            }
+        } else {
+            window?.$message?.warning('已上报的资料,不允许删除')
+        }
+    } else {
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+//复制本表弹窗
+const CopyModal = ref(false);
+const CopyModalType=ref('1');
+const treeLoading = ref(false);
+const copyModalTable=ref([])
+const insertDataShow = ref(false);
+//类型tab数据和相关处理
+const tabTypeKey = ref('2')
+const tabTypeTab = ref([
+    {key:'1',  name: '试验记录表'},
+    {key:'2', name: '试验报告单'},
+]);
+let placeholderType=ref('试验报告单')
+const tabTypeChange = ({key}) => {
+    tabTypeKey.value = key
+    if( tabTypeKey.value==='1'){
+        placeholderType='试验记录表'
+    }else{
+         placeholderType='试验报告单'
+    }
+    testReportId.value=''
+    getSearchNodeTables()
+    
+}
+const insertDataTableLoading=ref(false)
+const insertDataTableColumn = ref(
+      [{key:'key_12__3_1', name: '数据名称'}],
+)
+const insertDataTable=ref([])
+const multipleSelection = ref([])
+const insertDataTableCheck = (val) => {
+  multipleSelection.value = val
+}
+//分页
+const insertDataPage = ref({current: 1, size: 20, total: 0})
+const insertDataPageChange = ({current, size}) => {
+    insertDataPage.value.current = current
+    insertDataPage.value.size = size
+    // getDialogTableData()
+}
+
+const testReportId=ref('');
+const testReportData=ref([])
+let checPkd=ref([])
+const testReportIdchange = (key) => {
+testReportData.value.forEach((item)=>{
+        if(item.id=key){
+            checPkd.value.push(item)
+        }
+    })
+
+ getBussddataInfotrialData()
+}
+//树相关变量
+// const primaryKeyId = ref('')
+const nodeItemInfo = ref({})
+const nodeDataInfo = ref({})
+//树加载完成
+const ElTreeNodeLoading = () => {
+    treeLoading.value = false
+}
+
+//获取数据列表
+const ListItemLoading = ref(false);
+const checked1=ref(true)
+const searchNodeAllTable = async () => {
+    copyModalTable.value = []
+    const info = nodeDataInfo.value;
+    ListItemLoading.value = true
+    const {error, code, data} = await wbsApi.searchNodeAllTable({
+        projectId: projectId.value,
+        contractId: contractId.value,
+        primaryKeyId: info['primaryKeyId'],
+        type: authBtnTabKey.value
+    })
+    //处理数据
+    ListItemLoading.value = false
+    if (!error && code === 200) {
+        copyModalTable.value = getArrValue(data);
+        copyModalTable.value.forEach((item)=>{
+            item.isCheck=false
+        })
+    } else {
+        copyModalTable.value = []
+    }
+}
+const getTableDataAll = () => {
+    searchNodeAllTable()
+}
+
+//树被点击
+const wbsElTreeClick = ({node, data, keys}) => {
+    nodeItemInfo.value = node
+    nodeDataInfo.value = data
+    getTableDataAll();
+}
+const copyClickLoading=ref(false)
+//复制本表
+const copyClick = async (item,index) => {
+    // CopyModal.value=true;
+    // const copyModalTable=ref([])
+
+    if (item.id) {
+        if (isStatus.value !== '3') {
+            copyClickLoading.value=true
+            if (!item.isRenderTableForm) {
+                await copeBussTab(item.id + '')
+            } else if (!item.isTableForm) {
+                window?.$message?.warning('暂无表单数据')
+            } else if (item.isRenderTableForm) {
+                const res = await saveExcelBussData(item,index,false)
+                if (res) {
+                    await copeBussTab(item.id + '')
+                } else {
+                    window?.$message?.warning('复制本表操作失败')
+                }
+            } else {
+                window?.$message?.warning(`数据异常了, isRenderTableForm: ${item.isRenderTableForm}, isTableForm: ${item.isTableForm}, pkeyIds:${item.pkeyId}`)
+            }
+        } else {
+            window?.$message?.warning('已上报的资料,不允许复制')
+        }
+    } else {
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+
+//勾选复制本表
+const copyModalTableCheck = async (item) => {
+   console.log('复制本表',item);
+}
+const copeBussTab = async (pkeyIds) => {
+    const {error, code} = await wbsApi.copeBussTab({
+        pkeyId: pkeyIds
+    })
+    if (!error && code === 200) {
+        window?.$message?.success('操作成功')
+        renewData()
+    }
+}
+
+
+//隐藏本表
+const hideClick = async (item) => {
+    const pkeyIds = item.id ? item.id + '' : ''
+    if (pkeyIds) {
+        if (isStatus.value !== '3') {
+            const isBussShow = item['isBussShow'] === 2 ? 1 : 2 //状态(1显示 2隐藏)
+            const {error, code} = await wbsApi.showBussTab({
+                pkeyId: pkeyIds,
+                status: isBussShow
+            })
+            if (!error && code === 200) {
+                window?.$message?.success('操作成功')
+                renewData()
+            }
+        } else {
+            window?.$message?.warning('已上报的资料,不允许隐藏')
+        }
+    } else {
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+
+//预览
+const previewClick = async (item,index) => {
+    await getBussPdfInfo(item)
+}
+
+//上传变量
+const uploadModal = ref(false)
+const fileListData = ref([]);
+const uploadData = ref({})
+
+//上传被点击
+const uploadClick = (item,index) => {
+    const pkeyIds = item.id ? item.id + '' : ''
+    const keyName = `item-${index}-${pkeyIds}`
+    if (pkeyIds) {
+        if (isStatus.value !== '3' && item.isTableForm) {
+            uploadModal.value = true
+            uploadData.value = getFormDataInit(item,pkeyIds)
+            //获取文件列表
+            getBussFileList(pkeyIds)
+        } else if (!item.isRenderTableForm) {
+            CollapseChange(keyName)
+            window?.$message?.warning('请再次点击上传')
+        } else if (!item.isTableForm) {
+            window?.$message?.warning('暂无表单数据')
+        } else {
+            window?.$message?.warning('已上报的资料,不允许上传')
+        }
+    } else {
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+
+//获取文件列表
+const getBussFileList = async (pkeyId) => {
+    const {error, code, data} = await wbsApi.getBussFileList({
+        pkeyid: pkeyId
+    })
+    if (!error && code === 200) {
+        fileListData.value = getArrValue(data)
+    } else {
+        fileListData.value = []
+    }
+}
+
+//上传文件
+const uploadChange = async ({type}) => {
+    if(type === 'success') {
+        uploadModal.value = false
+        renewData()
+    } else if (type === 'del') {
+        renewData()
+    }
+}
+
+//相关变量
+const tableFormItemNode = ref({})
+
+//菜单数据
+const tableFormMenu = ref([])
+
+//设置菜单权限数据
+const setTableFormMenu = (info) => {
+    const infos = getObjValue(info)
+    const isOpen = infos['isOpenRandomNumber'] ?? 0
+    let newArr = []
+    if (isOpen === 1) {
+        newArr.push({label: '插入设计值/频率', key: "IDVF"})
+    }
+    //newArr.push({label: '插入设计值/频率', key: "IDVF"})
+    newArr.push({label: '插入特殊字符', key: "special"})
+    newArr.push({label: '关联试验数据', key: "CTD"}),
+    newArr.push({label: '关联试验文件', key: "file"})
+    tableFormMenu.value = newArr
+}
+
+
+//鼠标右键事件
+const contextMenuRef = ref(null)
+const onRightClick = (event, KeyName, index) => {
+    //取光标位置
+    const specialDom = document.getElementById(KeyName + "")
+    const startPos = specialDom?.selectionStart || 0
+    const endPos = specialDom?.selectionEnd || 0
+    //存储临时信息
+    tableFormItemNode.value = {KeyName, index, startPos, endPos, pkeyId: formKeyIds.value}
+    contextMenuRef.value?.showMenu(event) //展开菜单
+}
+
+//鼠标右键菜单被点击
+const handleMenuSelect = ({key}) => {
+    if (key === 'IDVF') {
+        IDVFModal.value = true
+    } else if (key === 'special') {
+        specialModalShow()
+    } else if (key === 'CTD') {
+        CTDModal.value = true
+        CTDbetweenTime.value=[]
+        CTDdialogTableData1.value=[]
+    }else if(key === 'file'){
+        fileModal.value=true;
+        fileModalradio.value=1
+        filedialogTableData.value=[]
+       
+    }
+}
+
+//插入设计值
+const IDVFModal = ref(false)
+const formIDVFRef = ref(null)
+const formIDVFModel = ref({type: 1, design: '', size: '', dev: '', key: '', capacity: '', pass: '', pkId: ''})
+
+
+//插入特殊字符
+const specialModal = ref(false)
+const specialCharacters = ref([
+    '&#57344;', "&#57345;", "&#57346;", "&#57347;", '&#8804;', '&#8805;', '&#8451;',
+    '&#9312;', '&#9313;', '&#9314;', '&#9315;', '&#9316;', '&#9317;', '&#9318;', '&#9319;', '&#9320;', '&#9321;', '&#9322;', '&#9323;',
+    '&#9324;', '&#9325;', '&#9326;', '&#9327;', '&#9328;', '&#9329;', '&#9330;', '&#9331;',
+    "&#8544;", "&#8545;", "&#8546;", "&#8547;", "&#8548;", "&#8549;", "&#8550;", "&#8551;", "&#8552;", "&#8553;", "&#8554;", "&#8555;","K̅"
+])
+
+//输入框验证
+const specialFormRef = ref(null)
+const specialFormModel = ref({val: ''})
+const specialFormRules = {
+    val: {
+        required: true,
+        trigger: "blur",
+        message: "请选择特殊字符代码"
+    }
+}
+//显示插入特殊字符
+const specialRef = ref(null)
+const specialModalShow = () => {
+    specialFormModel.value.val = ''
+    specialModal.value = true
+    nextTick(() => {
+        specialRef.value?.focus();
+    })
+}
+//失去焦点
+const specialPos = ref({start: 0, end: 0})
+const specialInputBlur = (e) => {
+    specialPos.value = {
+        start: e?.target?.selectionStart || 0,
+        end: e?.target?.selectionEnd || 0
+    }
+}
+//点击符号
+const specialClick = (event) => {
+    const text = event?.target?.innerText ?? ''
+    const start = specialPos.value.start
+    const end = specialPos.value.end
+    const form = specialFormModel.value.val
+    specialFormModel.value.val = setPosInsert(start, end, form, text)
+    specialRef.value?.focus();
+    let posVal = start + text.length;
+    nextTick(() => {
+        setPosRange('specialId', posVal)
+    })
+}
+
+//确认插入
+const specialNodeClick = async () => {
+    const res = await formValidate(specialFormRef.value)
+    if (res) {
+        const item = tableFormItemNode.value
+        const form = formData.value[item.index]
+        const val = specialFormModel.value.val ?? ''
+        formData.value[item.index][item.KeyName] = setPosInsert(item.startPos, item.endPos, form[item.KeyName], val)
+        specialModal.value = false
+        specialRef.value?.focus();
+        let posVal = item.startPos + val.length;
+        nextTick(() => {
+            setPosRange(item.KeyName, posVal)
+        })
+    }
+}
+
+//关联试验数据
+const CTDModal = ref(false)
+//树形结构异步加载数据
+const defaultExpandedCids = ref([])
+//自动展开缓存
+const CTDTreeAutoExpandKeys = ref(getStoreData('CTDElTreeExpandKeys') || [])
+const dialogTableRef =ref(null)
+const dialogTableRef1 =ref(null)
+const dialogTableRef2 =ref(null)
+
+const ElTreeProps = ref({
+    label: 'title',
+    children: 'children',
+    isLeaf: 'hasChildren'
+})
+const ElTreeLoadNode = async (node, resolve) => {
+    let parentId = '0';
+    if (node.level !== 0) {
+        parentId = node?.data?.id
+    }
+    //获取数据
+    const {error, code, data} = await samplingApi.queryLazyTree({
+        wbsId: wbsTempId.value,
+        tenantId: tenantId.value,
+        projectId: projectId.value,
+        parentId,
+        wbsType: wbsType.value
+    })
+    //处理数据
+    if (!error && code === 200) {
+        let clickKey = '', defaultExpandedArr = [];
+        const keys = CTDTreeAutoExpandKeys.value || []
+        const resData = getArrValue(data)
+        for (let i = 0; i < resData.length; i++) {
+            resData[i].hasChildren = !resData[i].hasChildren
+        }
+        if (keys.length > 0) {
+            let lastKey = keys[keys.length-1];
+            for (const item of resData) {
+                //自动展开
+                if (isItem(keys,item?.primaryKeyId)) {
+                    defaultExpandedArr.push(item?.primaryKeyId)
+                }
+                //最后一个,选中点击
+                if (item?.primaryKeyId === lastKey) {
+                    clickKey = item?.primaryKeyId
+                }
+            }
+        } else if (node.level === 0) {
+            defaultExpandedArr.push(resData[0]?.primaryKeyId)
+        }
+        //自动展开
+        defaultExpandedCids.value = defaultExpandedArr
+        if (node.level === 0) {
+            emit('nodeLoading')
+            if(resData.length<=0){
+                 window?.$message?.warning('该项目未使用试验系统,无法获取数据')
+            }
+        }
+        resolve(resData)
+
+        //最后一个,执行点击
+        if (clickKey) {
+            await nextTick(() => {
+                // document.getElementById(`${idPrefix.value}${clickKey}`)?.click()
+            })
+        }
+    } else {
+        if (node.level === 0) {
+            emit('nodeLoading')
+        }
+        resolve([])
+    }
+}
+//节点被点击
+const CTDnodeItemInfo = ref({})
+const CTDnodeDataInfo = ref({})
+const CTDdialogTableData1=ref([])
+const filedialogTableData=ref([])
+//多选
+const filetableCheckedKeys = ref([]);
+const filedialogTableSelection1 = (rows) => {
+    filetableCheckedKeys.value = rows.filter((item) => {
+        return (item??'') !== '';
+    })
+  
+}
+const filedialogTableSelection = (rows) => {
+    filetableCheckedKeys.value = rows.filter((item) => {
+        return (item??'') !== '';
+    })
+  
+}
+//确认关联试验文件
+const savefileModal = ()=>{
+    const idarr=[]
+    filetableCheckedKeys.value.forEach((item)=>{
+             idarr.push(item.id)
+    })
+    const idval=idarr.join(',')
+    if(idval.length>0){
+        savesubmitRelationFile(idval)
+        fileModal.value=false
+    }else{
+         window?.$message?.warning('请选择你要关联的文件')
+    }
+    
+    
+}
+const CTDdialogTableColumn = ref([
+    {key:'recordNo', name: '报告编号'},
+    {key:'reportDate', name: '报告日期'},
+    {key:'projectPositionName', name: '工程用途及部位'},
+    {key:'detectionResultName', name: '检测结果'},
+])
+const filedialogTableColumn = ref([
+    // reportNo
+    {key:'recordNo', name: '报告编号'},
+    {key:'reportDate', name: '报告日期'},
+    {key:'projectPositionName', name: '工程用途及部位'},
+    {key:'detectionResultName', name: '检测结果'},
+])
+const filedialogTableColumn1 = ref([
+    // reportNo
+    {key:'reportNo', name: '报告编号'},
+    {key:'reportDate', name: '报告日期'},
+    {key:'projectPositionName', name: '工程用途及部位'},
+    {key:'detectionResultName', name: '检测结果'},
+])
+const CTDElTreeClick = (data,node,keys) => {
+    CTDnodeItemInfo.value = node
+    CTDnodeDataInfo.value = data
+    getNodeData()
+    //缓存展开的节点
+     CTDTreeAutoExpandKeys.value = keys.value || []
+    setStoreData('CTDElTreeExpandKeys', keys.value)
+
+}
+//获取试验树节点下的记录信息
+const getNodeData = async ()=>{
+    //获取数据
+    CTDdialogTableLoading.value = true
+    const {error, code, data} = await samplingApi.gettrialPage({
+        contractId: contractId.value,
+        nodeId: CTDnodeDataInfo.value.primaryKeyId,
+        current: CTDsearchFormPage.value.current,
+        size: CTDsearchFormPage.value.size,
+        startTime:CTDsearchFormPage.value.startTime,
+        endTime:CTDsearchFormPage.value.lastTime,
+    })
+    //处理数据
+    if (!error && code === 200) {
+        CTDdialogTableData1.value = getArrValue(data['records'])
+        CTDsearchFormPage.value.total = data.total || 0
+        CTDdialogTableLoading.value = false
+    } else {
+        CTDdialogTableData1.value = []
+        CTDsearchFormPage.value.total = 0
+        CTDdialogTableLoading.value = false
+    }
+}
+//试验文件节点下的数据
+const getfileNodeData = async ()=>{
+    //获取数据
+    filedialogTableLoading.value = true
+    const {error, code, data} = await samplingApi.gettrialPage({
+        contractId: contractId.value,
+        nodeId: filenodeDataInfo.value.primaryKeyId,
+        current: filesearchFormPage.value.current,
+        size: filesearchFormPage.value.size,
+        startTime:filesearchFormPage.value.startTime,
+        endTime:filesearchFormPage.value.lastTime,
+        qualityTestPKeyId:isPrimaryKeyId.value
+    })
+    //处理数据
+    if (!error && code === 200) {
+        filedialogTableData.value = getArrValue(data['records'])
+        filesearchFormPage.value.total = data.total || 0
+        filedialogTableLoading.value = false
+        let defaultarr=[]
+        filedialogTableData.value.forEach((item)=>{
+            if(item.isSelectedStatus===1){
+                defaultarr.push(item)
+                
+            }
+         tabtoggleSelection(defaultarr)
+        })
+       
+    } else {
+        filedialogTableData.value = []
+        filesearchFormPage.value.total = 0
+        filesearchFormPage.value = false
+    }
+}
+
+const tabtoggleSelection=(rows)=> {
+  if (rows) {
+    rows.forEach(row => {
+      nextTick(()=>{
+           dialogTableRef1.value?.toggleRowSelection(row,true);
+      })
+    });
+  } else {
+      dialogTableRef1.value?.clearSelection();
+     
+  }
+}
+const outtabtoggleSelection=(rows)=> {
+  if (rows) {
+    rows.forEach(row => {
+      nextTick(()=>{
+           dialogTableRef2.value?.toggleRowSelection(row,true);
+      })
+     
+    });
+  } else {
+    dialogTableRef2.value?.clearSelection();
+  }
+}
+const thirdtabtoggleSelection=(rows)=> {
+    console.log(rows,'rows');
+  if (rows) {
+    rows.forEach(row => {
+      nextTick(()=>{
+          if(fileModalradio.value==2){
+              dialogTableRef2.value?.toggleRowSelection(row,true);
+          }else{
+                dialogTableRef.value?.toggleRowSelection(row,true);
+          }
+          
+      })
+     
+    });
+  } else {
+       if(fileModalradio.value==2){
+           dialogTableRef2.value?.clearSelection();
+       }else{
+             dialogTableRef.value?.clearSelection();
+       }
+   
+
+  }
+}
+//获取试验表中的data数据接口:
+const getBussddataInfotrialData = async ()=>{
+    insertDataTableLoading.value=true;
+    const {error, code, data} = await dataApi.getBussddataInfotrial({
+        id:testReportId.value,
+        pkeyId:checPkd.value[0]['pKeyId'],
+    })
+
+    insertDataTableLoading.value = false
+    if (!error && code === 200) {
+        insertDataTable.value = getArrValue(data)
+    } else {
+        insertDataTable.value = []
+         
+    }
+
+}
+
+//保存试验节点数据
+
+//取消关联数据
+const cancelinsertData = async () => {
+    insertDataShow.value=false
+    
+}
+//确定关联试验数据数据
+const submitinsertData = async () => {
+    if (multipleSelection.value.length>0) {
+        const item = tableFormItemNode.value
+        const form = formData.value[item.index]
+          const val =[]
+         multipleSelection.value.forEach((item)=>{
+             val.push(item['key_12__3_1'])
+         })
+         const newval=val.join('、')
+        formData.value[item.index][item.KeyName] = setPosInsert(item.startPos, item.endPos, form[item.KeyName], newval)
+        insertDataShow.value = false
+        CTDModal.value=false
+        let posVal = item.startPos + newval.length;
+        nextTick(() => {
+            setPosRange(item.KeyName, posVal)
+        })
+    }else{
+         window?.$message?.warning('请选择你要关联的数据')
+    }
+}
+
+    //节点被点击
+const ElTreeClick = async (data,node) => {
+    console.log(data,mode);
+    let autoKeysArr = []
+    await getNodeExpandKeys(node, autoKeysArr)
+    const autoKeys = autoKeysArr.reverse()
+    emit('nodeTap', {node, data, keys: autoKeys})
+}
+//处理自动展开的节点KEY
+const getNodeExpandKeys = async (node, newKeys) => {
+    const parent = node?.parent ?? []
+    const primaryKeyId = node?.data?.primaryKeyId ?? ''
+    if (primaryKeyId) {
+        newKeys.push(primaryKeyId)
+        await getNodeExpandKeys(parent, newKeys)
+    }
+}
+const CTDbetweenTime = ref([])
+const filebetweenTime = ref([])
+//搜索表单
+const CTDsearchFormPage = ref({
+   startTime: null,lastTime: null,  wbsId: null, current: 1, size: 20, total: 0
+})
+const filesearchFormPage = ref({
+   startTime: null,lastTime: null,  wbsId: null, current: 1, size: 20, total: 0
+})
+const CTDsearchFormPageChange = ({current, size}) => {
+    CTDsearchFormPage.value.current = current
+    CTDsearchFormPage.value.size = size
+    // getDialogTableData()
+}
+const filesearchFormPageChange = ({current, size}) => {
+    filesearchFormPage.value.current = current
+    filesearchFormPage.value.size = size
+    // getDialogTableData()
+}
+const CTDbetweenTimeUpdate = ({arr, query}) => {
+    CTDbetweenTime.value = arr
+    CTDsearchFormPage.value.startTime = arr[0]
+     CTDsearchFormPage.value.lastTime = arr[1]
+}
+const filebetweenTimeUpdate = ({arr, query}) => {
+    filebetweenTime.value = arr
+    filesearchFormPage.value.startTime = arr[0]
+     filesearchFormPage.value.lastTime = arr[1]
+}
+//搜索
+const CTDsearchClick = () => {
+    CTDsearchFormPage.value.current = 1;
+    getNodeData()
+}
+const filesearchClick = () => {
+    filesearchFormPage.value.current = 1;
+    getfileNodeData()
+}
+const CTDdialogTableLoading = ref (false)
+const filedialogTableLoading = ref (false)
+const insertDataSelectoading=ref(false)
+const CTDdialogTableKeys = ref ([])
+
+let currowid=ref('')
+//名称被点击
+const CTDtableRowName = (row) => {
+     currowid=row.id
+    insertDataShow.value=true
+    getSearchNodeTables()
+ }
+const getSearchNodeTables = async () => {
+    insertDataSelectoading.value = true
+    const { error, code, data } = await dataApi.searchNodeTables({
+        id: currowid,
+        projectId: projectId.value,
+        contractId: contractId.value,
+        primaryKeyId: CTDnodeDataInfo.value.primaryKeyId,
+        type: authBtnTabKey.value,
+        tableType: tabTypeKey.value
+    })
+    //处理数据
+    insertDataSelectoading.value = false
+    if (!error && code === 200) {
+        testReportData.value = getArrValue(data)
+    } else {
+        testReportData.value = []
+         
+    }
+}
+
+//关联试验文件
+const fileModal = ref(false)
+const fileModalradio = ref(1)
+const radioChange = (val)=>{
+    if(val!==1){
+        getthirdTreeDatas(val)
+    }
+}
+//获取试验文件树树数据
+const fileModaltreeDatas = ref([])
+//节点被点击
+//节点被点击
+const filenodeItemInfo = ref({})
+const filenodeDataInfo = ref({})
+const  fileTableData1=ref([])
+const  fileTableColumn = ref([
+    {key:'recordNo', name: '报告编号'},
+    {key:'reportDate', name: '报告日期'},
+    {key:'projectPositionName', name: '工程用途及部位'},
+    {key:'detectionResultName', name: '检测结果'},
+])
+
+const fileModalElTreeClick = async (data,node) => {
+   filenodeItemInfo.value = node
+    filenodeDataInfo.value = data
+    getfileNodeData()
+}
+
+//获取第三方树试验文件
+
+//获取树数据
+const thirdtreeDatas = ref([])
+const thirdElTreeProps = ref({
+    label: 'nodeName',
+    children: 'children',
+    isLeaf: 'hasChildren'
+})
+const getthirdTreeDatas = async (type) => {
+    const { error, code, data } = await getTreeAll({
+        projectId: projectId.value,
+        contractId: contractId.value
+    })
+    if (!error && code === 200) {
+        if(type==2){
+            thirdtreeDatas.value = getArrValue(data['rightTree'])
+        }else{
+             thirdtreeDatas.value = getArrValue(data['leftTree'])
+        }
+       
+        
+    } else {
+        thirdtreeDatas.value = []
+    }
+}
+const thirdfilenodeItemInfo = ref({})
+const thirdfilenodeDataInfo = ref({})
+//获取第三方树节点下的数据
+const getthirdTreetavleDatas = async () => {
+    filedialogTableLoading.value=true
+    const { error, code, data } = await thirdApi.queryPage({
+        projectId: projectId.value,
+        contractId: contractId.value,
+        nodeId: thirdfilenodeDataInfo.value.id,
+        current: filesearchFormPage.value.current,
+        size: filesearchFormPage.value.size,
+        startTime:filesearchFormPage.value.startTime,
+        endTime:filesearchFormPage.value.lastTime,
+        qualityTestPKeyId:isPrimaryKeyId.value
+
+
+    })
+     //处理数据
+    if (!error && code === 200) {
+        filedialogTableData.value = getArrValue(data['records'])
+        filesearchFormPage.value.total = data.total || 0
+        filedialogTableLoading.value = false
+        if( filedialogTableData.value.length>0){
+               let defaultarr=[]
+                filedialogTableData.value.forEach((item)=>{
+                if(item.isSelectedStatus===1){
+                    defaultarr.push(item)
+    
+                }
+           if(fileModalradio===2){
+               outtabtoggleSelection(defaultarr)
+           }else{
+               thirdtabtoggleSelection(defaultarr)
+           }
+            
+            })
+        }
+    } else {
+        filedialogTableData.value = []
+        filesearchFormPage.value.total = 0
+        filesearchFormPage.value = false
+    }
+    filedialogTableLoading.value=false
+}
+const thirdtreeDatasElTreeClick =(data,node)=>{
+    thirdfilenodeItemInfo.value = node
+    thirdfilenodeDataInfo.value = data
+    getthirdTreetavleDatas()
+}
+//关联试验文件
+ const savesubmitRelationFile =async (ids)=>{
+     console.log( isPrimaryKeyId.value,' isPrimaryKeyId.value');
+    const { error, code, data } = await samplingApi.submitRelationFile({
+        projectId: projectId.value,
+        contractId: contractId.value,
+        nodeId: isPrimaryKeyId.value,
+        type:fileModalradio.value,
+        ids
+    })
+    if (!error && code === 200) {
+                window?.$message?.success('操作成功')
+    }
+ }
+//设计值频率计算
+const IDVFModalSaveClick = async () => {
+    const {pkeyId, KeyName, index} = tableFormItemNode.value
+    if (pkeyId) {
+        const { design, size } = formIDVFModel.value
+        const { error, code, data } = await wbsApi.queryFormulaRange({
+            ...formIDVFModel.value,
+            // dev: (!design && !size) ? '±5': '',
+            key: KeyName,
+            pkId: pkeyId,
+
+        })
+        //处理数据
+        const res = getObjNullValue(data)
+        if (!error && code === 200 && res) {
+            Object.keys(data).forEach(key => {
+                formData.value[index][key] = data[key]
+            })
+            IDVFModal.value = false
+        }
+    } else {
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+const closeIDVFModal=()=>{
+     IDVFModal.value = false
+     formIDVFModel.value={type: 1, design: '', size: '', dev: '', key: '', capacity: '', pass: '', pkId: ''}
+}
+//事件
+const emit = defineEmits(['renew','offsetTop'])
+
+//被点击
+const getOffsetTop = (key = '') => {
+    if (key) {
+        const dom = document.getElementById(key[key.length-1])
+        if(!drawType.value){
+             if(dom.offsetTop>=583&&ActiveKey.value.length>1){
+                 emit('offsetTop', dom.offsetTop-583)
+            }else{
+                emit('offsetTop', dom.offsetTop)
+            }
+        }else {
+            if(dom.offsetTop>=424&&ActiveKey.value.length>1){
+                  emit('offsetTop', dom.offsetTop-424)
+            }else{
+                emit('offsetTop', dom.offsetTop)
+            }
+        }
+       
+    } else {
+        emit('offsetTop', 0)
+    }
+     ActiveKey.value =  ActiveKey.value[ActiveKey.value.length-1]
+}
+
+//通知数据更新
+const renewData = () => {
+    emit('renew')
+    ActiveKey.value = []
+}
+
+//获取表单数据
+const getFormData = () => {
+    const formArr = formData.value;
+    return formArr.filter((item) => {
+        return (item.pkeyId??'') !== '' && item.isCollapseLoad;
+    })
+}
+
+//获取表单效验数据
+const getFormRegExpJson = () => {
+    return deepClone(formRegExpJson.value);
+}
+
+//获取当前展开项
+const getActiveKey = () => {
+    return ActiveKey.value;
+}
+
+//设置当前展开项
+const setActiveKey = (key) => {
+    return ActiveKey.value = key;
+}
+
+//名称被点击
+const tableRowName = (row) => {
+    console.log(row,'row');
+    //如果 evisaPdfUrl 不为空,使用evisaPdfUrl,反之使用pdfUrl
+    // if (row['evisaPdfUrl']) {
+    //     window.open(row['evisaPdfUrl'],'_blank')
+    // } else if (row['pdfUrl']) {
+    //     window.open(row['pdfUrl'],'_blank')
+    // } else {
+    //     window.$message?.warning('文件不存在')
+    // }
+}
+// 暴露出去
+defineExpose({
+    getFormData,
+    getFormRegExpJson,
+    getActiveKey,
+    setActiveKey
+})
+</script>
+
+<style lang="scss" scoped>
+table{
+    width: 100%;
+}
+.data-fill-list-box {
+    position: relative;
+    //margin-bottom: 25%;
+    .hc-collapse-item-header {
+        flex: 1;
+        position: relative;
+        margin-left: 46px;
+        display: flex;
+        align-items: center;
+        .item-title {
+            flex: 1;
+            position: relative;
+            user-select: none;
+            color: #50545E;
+            font-size: 16px;
+            font-weight: 400;
+            cursor: pointer;
+        }
+        .hc-extra-text-box {
+            position: relative;
+            padding-right: 24px;
+        }
+    }
+    .data-fill-list-item-content {
+        position: relative;
+        display: flex;
+        height: calc(100vh - 386px);
+        .data-fill-table-form-box {
+            position: relative;
+            padding: 24px 20px;
+            height: 100%;
+            overflow: auto;
+            flex: 1;
+            border: 8px solid #50545E;
+           
+            .hc-no-table-form {
+                position: relative;
+                height: 100%;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+               
+                .table-form-no {
+                    position: relative;
+                    img {
+                        width: 350px;
+                    }
+                    .desc {
+                        text-align: center;
+                        font-size: 20px;
+                        color: #aaa;
+                    }
+                }
+            }
+        }
+        .data-fill-table-tip-box {
+            width: 240px;
+            position: relative;
+            border-left: 1px solid #E9E9E9;
+            padding: 20px 15px 80px;
+            .tip-title {
+                font-size: 16px;
+                margin-bottom: 10px;
+                display: flex;
+                align-items: center;
+            }
+            .tip-item {
+                margin-bottom: 20px;
+            }
+            .table-tip-foot {
+                position: absolute;
+                bottom: 15px;
+                right: 0;
+                left: 0;
+                display: flex;
+                align-items: center;
+                padding: 0 15px;
+                .tip-left-btn {
+                    flex: 1;
+                    .dow-text {
+                        cursor: pointer;
+                        display: flex;
+                        align-items: center;
+                    }
+                }
+            }
+        }
+    }
+}
+.special-box {
+    position: relative;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    border: 1px solid #eee;
+    border-radius: 3px;
+    height: 52px;
+    width: 52px;
+    cursor: pointer;
+    user-select: none;
+    transition: color .3s, background-color .3s;
+    &:hover {
+        color: var(--el-color-primary);
+        background-color: var(--el-color-primary-light-8);
+    }
+    .font-EUDC {
+        font-size: 22px;
+    }
+}
+.radio-group-box{
+    text-align: center;
+}
+</style>
+
+<style lang="scss">
+.data-fill-list-box {
+    .el-collapse {
+        --el-collapse-header-height: 60px;
+        border: 0;
+        .el-collapse-item {
+            margin: 0 0 16px;
+            background-color: #f1f5f8;
+            border: 1px solid #E9E9E9;
+            border-radius: 4px;
+        }
+        .el-collapse-item__header {
+            background-color: transparent;
+            font-weight: 400;
+            border-bottom: 0;
+            cursor: default;
+            font-size: 14px;
+            .el-collapse-item__arrow {
+                position: absolute;
+                color: #50545E;
+                cursor: pointer;
+                left: 20px;
+                margin: 0;
+            }
+        }
+        .el-collapse-item.is-active .el-collapse-item__header.is-active {
+            background-color: #E7EEF4;
+        }
+        .el-collapse-item__wrap {
+            background-color: transparent;
+            border-bottom: 0;
+            .el-collapse-item__content {
+                position: relative;
+                padding-bottom: 0;
+                font-size: 14px;
+                color: #50545E;
+                line-height: initial;
+            }
+        }
+    }
+}
+
+//插入特殊字符弹窗的输入框
+.data-fill-list-box .data-fill-table-form-box td,
+.data-fill-list-box .data-fill-table-form-box td .el-input .el-input__wrapper .el-input__inner,
+.el-form-item.special-form-item .el-form-item__content .el-input .el-input__wrapper .el-input__inner {
+    font-family: "EUDC", 宋体, v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+}
+//复制本表弹窗
+.copy-node-many-box {
+    position: relative;
+    height: 53vh;
+    display: flex;
+    margin-top: 24px;
+    margin-bottom: -30px;
+    border-top: 1px solid #efeff5;
+    .copy-node-many-tree {
+        position: relative;
+        flex: 1;
+        height: 100%;
+        padding: 20px 20px 20px 0;
+        border-right: 1px solid #efeff5;
+    }
+    .copy-node-many-table {
+        position: relative;
+        flex: 1;
+        height: 100%;
+        padding: 20px 0 20px 20px;
+    }
+}
+
+//关联试验数据
+.adding-form-dialog-box {
+    position: relative;
+    height: 100%;
+    display: flex;
+    .dialog-tree-box {
+        position: relative;
+        border-right: 1px solid #EEEEEE;
+        width: 500px;
+        height: 100%
+    }
+    .dialog-table-box {
+        position: relative;
+        flex: 1;
+        height: 100%;
+        padding: 18px;
+        .dialog-search {
+            position: relative;
+            display: flex;
+        }
+        .dialog-table {
+            position: relative;
+            height: calc(100% - 68px);
+            padding: 18px 0;
+        }
+        .dialog-pages {
+            position: relative;
+        }
+    }
+}
+.copy-node-many-table {
+    position: relative;
+    flex: 1;
+    height: 100%;
+    padding: 20px 0 20px 20px;
+}
+.dialog-table-box {
+        position: relative;
+        flex: 1;
+        height: 100%;
+        padding: 18px;
+        .dialog-search {
+            position: relative;
+            display: flex;
+        }
+        .dialog-table {
+            position: relative;
+            height: calc(100% - 68px);
+            padding: 18px 0;
+        }
+        .dialog-pages {
+            position: relative;
+        }
+    }
+.text-blue{
+    color: blue;
+}
+.text-green{
+    color:green
+}
+
+</style>

+ 900 - 0
src/views/other/first-item copy.vue

@@ -0,0 +1,900 @@
+<template>
+    <div class="hc-layout-box" id="first-item-node-layout-target">
+        <div class="hc-layout-left-box" :style="'width:' + leftWidth + 'px;'" v-show="!isFirstReportDrawer">
+            <div class="hc-project-box">
+                <div class="hc-project-icon-box">
+                    <HcIcon name="stack"/>
+                </div>
+                <div class="ml-2 project-name-box">
+                    <span class="text-xl text-cut project-alias">{{projectInfo['projectAlias']}}</span>
+                    <div class="text-xs text-cut project-name">{{projectInfo['name']}}</div>
+                </div>
+            </div>
+            <div class="hc-tree-box">
+                <el-scrollbar>
+                    <WbsTree :autoExpandKeys="TreeAutoExpandKeys" :projectId="projectId" :contractId="contractId" @nodeTap="nodeWbsElTreeClick"/>
+                </el-scrollbar>
+            </div>
+            <!--左右拖动-->
+            <div class="horizontal-drag-line" @mousedown="onmousedown"/>
+        </div>
+        <div class="hc-layout-content-box first-item" v-show="!isFirstReportDrawer">
+            <HcCard :scrollbar="false" actionSize="lg">
+                <template #header>
+                    <HcTooltip keys="other-first-item-report" v-if="tabTypeKey === 'mark'">
+                        <el-button type="primary" hc-btn :disabled="tableSelectionKeys.length <= 0" @click="firstReportClick">
+                            <HcIcon name="send-plane-2"/>
+                            <span>上报首件111111</span>
+                        </el-button>
+                    </HcTooltip>
+                    <HcTooltip keys="other-first-item-report-approval" v-if="tabTypeKey === 'query'">
+                        <el-button type="primary" hc-btn :disabled="tableSelectionKeys.length <= 0" @click="reportModalClick(1)">
+                            <HcIcon name="send-plane-2"/>
+                            <span>上报审批</span>
+                        </el-button>
+                    </HcTooltip>
+                    <HcTooltip keys="other-first-item-repeal" v-if="tabTypeKey === 'query'">
+                        <el-button hc-btn :disabled="tableSelectionKeys.length <= 0" @click="batchAbolishClick">
+                            <HcIcon name="delete-bin-3"/>
+                            <span>批量废除</span>
+                        </el-button>
+                    </HcTooltip>
+                    <HcTooltip keys="other-first-item-down-print">
+                        <el-button hc-btn :disabled="tableSelectionKeys.length <= 0" :loading="printLoading" @click="batchPrint">
+                            <HcIcon name="printer"/>
+                            <span>预览/打印</span>
+                        </el-button>
+                    </HcTooltip>
+                </template>
+                <template #extra>
+                    <HcNewSwitch :datas="tabTypeTab" :keys="tabTypeKey" @change="tabTypeChange"/>
+                </template>
+                <template #search>
+                    <div class="w-32">
+                        <el-select v-model="searchForm.status" placeholder="流程状态" clearable>
+                            <el-option v-for="item in processStatus" :label="item['dictValue']" :value="item['dictKey']"/>
+                        </el-select>
+                    </div>
+                    <div class="w-32 ml-3">
+                        <el-select v-model="searchForm.reportNumber" placeholder="上报批次" clearable>
+                            <el-option v-for="item in reportBatch" :label="item" :value="item"/>
+                        </el-select>
+                    </div>
+                    <div class="w-64 ml-3">
+                        <HcDatePicker :dates="betweenTime" clearable @change="betweenTimeUpdate"/>
+                    </div>
+                    <div class="w-64 ml-3">
+                        <el-input v-model="searchForm.queryValue" placeholder="请输入名称关键词检索" clearable @keyup="keyUpEvent"/>
+                    </div>
+                    <div class="ml-2">
+                        <el-button type="primary" @click="searchClick">
+                            <HcIcon name="search-2"/>
+                            <span>搜索</span>
+                        </el-button>
+                    </div>
+                </template>
+                <HcTable ref="tableListRef" :column="tableListColumn" :datas="tableListData" :loading="tableLoading" isCheck @selection-change="tableSelectionChange">
+                    <template #name="{row}">
+                        <span class="text-link" @click="tableRowName(row)">{{row?.name}}</span>
+                    </template>
+                    <template #waitingUserList="{row}">
+                        <template v-for="item in row['waitingUserList']">
+                            <el-tag :type="`${item.status === 2 ? 'success' : item.status === 3 ? 'warning' : item.status === 999 ? 'danger' : 'info'}`"
+                                    class="mx-1" effect="dark" v-if="item['waitingUserName']">{{item['waitingUserName']}}</el-tag>
+                        </template>
+                    </template>
+                    <template #taskStatusStr="{row}">
+                        <el-tag :type="`${row.status === 2 ? 'success' : row.status === 0 ? 'warning' : row.status === 1 ? 'danger' : 'info'}`"
+                                class="mx-1" effect="dark" v-if="row['taskStatusStr']">{{row['taskStatusStr']}}</el-tag>
+                    </template>
+                </HcTable>
+                <template #action>
+                    <div class="lr-dialog-footer">
+                        <div class="left">
+                            <span class="text-success">任务人中:</span>
+                            <el-tag type="success" class="mx-1" effect="dark">已签字</el-tag>
+                            <el-tag type="warning" class="mx-1" effect="dark">已废除</el-tag>
+                            <el-tag type="danger" class="mx-1" effect="dark">签字异常</el-tag>
+                        </div>
+                        <div class="right">
+                            <HcPages :pages="searchForm" @change="pageChange"/>
+                        </div>
+                    </div>
+                </template>
+            </HcCard>
+        </div>
+
+        <!--上报首件-->
+        <HcDrawer :show="isFirstReportDrawer" :isCard="false" uis="hc-first-item-node-layout" to-id="first-item-node-layout-target" @close="FirstReportDrawerClose">
+            <div class="node-content">
+                <div class="node-form">
+                    <el-scrollbar v-if="contractId && isTableForm" ref="ListItemScrollRef" >
+                        <!-- <div class="hc-excel-table-form-view" :id="`table-form-${contractId}`"></div> -->
+                         <ListItem ref="ListItemsRef"
+                            :datas="ListItemDatas" 
+                            :status="NodeStatus" 
+                            :classify="authBtnTabKey"
+                            @offsetTop="ListItemOffsetTop" 
+                            :projectInfo="projectInfo" 
+                            :treeItem="treeItem"
+                            :contractId="contractId" 
+                            @renew="renewtable"
+                            :drawType="isDrawType"
+                            :tableFileData="tableFileData"
+                            :finishFile="finishFile"
+                            />
+                    </el-scrollbar>
+                    <HcStatus :desc="statusDesc" v-else/>
+                </div>
+                <div class="node-file">
+                    <div class="title">上传总结报告1111</div>
+                    <div class="node-upload-box" v-if="contractId && isTableForm">
+                        <HcUpload :fileList="fileListData" :pkeyId="pkeyIds" @finish='uploadChange'/>
+                    </div>
+                    <div class="node-upload-box" v-else>
+                        <el-alert title="表单异常,暂时无法使用上传" type="warning" show-icon :closable="false"/>
+                    </div>
+                    <el-divider border-style="dashed" />
+                    <div class="title">文件附件</div>
+                    <div class="hc-table-node-file-box">
+                        <HcTable :column="tableFileColumn" :datas="tableFileData" :isIndex="false">
+                            <template #action="{row,index}">
+                                <el-button type="danger" plain size="small" @click="tableDelButton(index)">删除</el-button>
+                            </template>
+                        </HcTable>
+                    </div>
+                </div>
+            </div>
+            <div class="node-action">
+                <el-button type="primary" hc-btn :disabled="!contractId || !isTableForm||NodeStatus === '3'" :loading="tableFormSaveLoading" @click="saveBussData">
+                    <HcIcon name="save"/>
+                    <span>保存</span>
+                </el-button>
+                <el-button hc-btn :disabled="!contractId || !isTableForm || !tableFormId||NodeStatus === '1'" @click="bussPdfInfo">
+                    <HcIcon name="eye"/>
+                    <span>预览</span>
+                </el-button>
+                <el-button hc-btn :disabled="!contractId || !isTableForm || !tableFormId||NodeStatus === '3' || NodeStatus === '1'" :loading="reportLoading" @click="reportModalClick(2)">
+                    <HcIcon name="send-plane-2"/>
+                    <span>上报</span>
+                </el-button>
+                <el-button hc-btn @click="FirstReportDrawerClose">
+                    <HcIcon name="close"/>
+                    <span>返回</span>
+                </el-button>
+            </div>
+        </HcDrawer>
+
+        <!--上报审批-->
+        <HcReportModal
+            title="上报审批"
+            url="informationWriteQuery/batchTask"
+            :show="showReportModal"
+            :projectId="projectId"
+            :contractId="contractId"
+            type="first"
+            :typeData="reportTypeData"
+            :taskName="reportTaskName"
+            :ids="reportIds"
+            :isDatas="isReportModalDatas"
+            :datas="reportDatas"
+            @hide="showReportModal = false"
+            @finish="showReportFinish"
+            @tagClose="reportTaskTagClose"
+        />
+    </div>
+</template>
+
+<script setup>
+import {useAppStore} from "~src/store";
+import {nextTick, onMounted, ref, watch} from 'vue'
+import {useRouter, useRoute} from 'vue-router'
+import WbsTree from "./components/WbsTree.vue"
+import HcUpload from "./components/HcUpload.vue"
+import HTableForm from "~src/plugins/HTableForm"
+import {getReportNumber,eVisaTaskCheckApi} from "~api/other";
+import firstApi from '~api/other/first-item';
+import tasksApi from '~api/tasks/data';
+import {getStoreData, setStoreData} from '~src/utils/storage'
+import {getArrValue, isString, getObjValue, getObjNullValue,deepClone} from "vue-utils-plus"
+import queryApi from "~api/data-fill/query";
+import wbsApi from "~api/data-fill/wbs";
+import ListItem from "./components/ListItem.vue"
+//变量
+const router = useRouter()
+const useRoutes = useRoute()
+const useAppState = useAppStore()
+const projectId = ref(useAppState.getProjectId);
+const contractId = ref(useAppState.getContractId);
+const projectInfo = ref(useAppState.getProjectInfo);
+const contractInfo = ref(useAppState.getContractInfo);
+const isCollapse = ref(useAppState.getCollapse)
+
+//路由参数
+const routerQuery = useRoutes?.query;
+const typeName = routerQuery?.type || 'mark'
+
+//监听
+watch(() => [
+    useAppState.getCollapse
+], ([Collapse]) => {
+    isCollapse.value = Collapse
+})
+
+
+//自动展开缓存
+const TreeAutoExpandKeys = ref(getStoreData('firstItemTreeKeys') || [])
+
+//类型tab数据和相关处理
+const tabTypeKey = ref(typeName)
+const tabTypeTab = ref([
+    {key:'mark',  name: '已标记为首件'},
+    {key:'query', name: '首件查询'}
+]);
+
+const tabTypeChange = (item) => {
+    tableFormId.value = ''
+    tabTypeKey.value = item?.key
+    if (searchForm.value.wbsId) {
+        searchForm.value.current = 1;
+        getTableData()
+    }
+    //路由跳转
+    router.push({
+        path: useRoutes.path,
+        query: {type: item?.key}
+    })
+}
+
+//渲染完成
+onMounted(() => {
+    firstTaskStatus()
+})
+const renewtable=()=>{
+     getTableData()
+     queryNodeStatus()
+}
+//项目树被点击
+const treeItem = ref({})
+const nodeWbsElTreeClick = ({data, keys}) => {
+    treeItem.value = data
+    searchForm.value.contractIdRelation = data['contractIdRelation']
+    searchForm.value.wbsId = data['primaryKeyId']
+    //缓存自动展开
+    TreeAutoExpandKeys.value = keys
+    setStoreData('firstItemTreeKeys', keys)
+    //获取相关数据
+    getReportNumberByContractId(data['contractIdRelation'])
+    searchClick()
+}
+
+//获取流程状态
+const processStatus = ref([])
+const firstTaskStatus = async () => {
+    const { data } = await tasksApi.queryTaskTypeStatus({
+        typeOrStatus: 'first_task_status'
+    })
+    //处理数据
+    processStatus.value = getArrValue(data)
+}
+//查询状态
+const NodeStatus = ref('1')
+ const { contractType } = contractInfo.value;
+const authBtnTabKey = ref(contractType===2?'2':'1')
+const queryNodeStatus = async () => {
+    const info = treeItem.value;
+    console.log(info,'info')
+    const {error, code, data} = await wbsApi.queryNodeStatus({
+        // primaryKeyId: info['contractIdRelation'] ? info['id'] : info['primaryKeyId'],
+        // classify: 1
+       primaryKeyId: authBtnTabKey.value==1 ? info['id'] : info['primaryKeyId'],
+        classify: authBtnTabKey.value
+        
+    })
+    //1 未填报,2待上报,3已上报
+    if (!error && code === 200) {
+        NodeStatus.value = data ?? '1'
+    } else {
+        NodeStatus.value = '1'
+    }
+}
+//获取上报批次
+const reportBatch = ref([])
+const getReportNumberByContractId = async (cid) => {
+    const { data } = await getReportNumber({
+        contractId: contractId.value,
+        contractIdRelation: cid ?? '',
+        firstTitle: tabTypeKey.value === 'query' ? 1: null
+    })
+    //处理数据
+    reportBatch.value = getArrValue(data)
+}
+
+//搜索表单
+const searchForm = ref({
+    wbsId: '', status: null, reportNumber: null, queryValue: '', betweenTime: '',
+    contractIdRelation: '', current: 1, size: 20, total: 0
+})
+
+//日期时间被选择
+const betweenTime = ref(null)
+const betweenTimeUpdate = ({query,arr}) => {
+    betweenTime.value = arr
+    searchForm.value.betweenTime = query
+}
+
+//回车搜索
+const keyUpEvent = (e) => {
+    if (e.key === "Enter") {
+        searchClick()
+    }
+}
+
+//搜索
+const searchClick = () => {
+    if (searchForm.value.wbsId) {
+        searchForm.value.current = 1;
+        getTableData()
+    } else {
+        window?.$message?.warning('请先在左边选择一个树节点')
+    }
+}
+
+//分页被点击
+const pageChange = ({current, size}) => {
+    searchForm.value.current = current
+    searchForm.value.size = size
+    getTableData()
+}
+
+//表格表头
+const tableListColumn = ref([
+    {key:'name', name: '文件名称'},
+    {key:'waitingUserList', name: '任务人'},
+    {key:'startTime', name: '开始时间', width: 180},
+    {key:'taskStatusStr', name: '流程状态', width: 140},
+    {key:'reportNumber', name: '上报批次', width: 120},
+])
+
+//获取表格数据
+const tableLoading = ref(false)
+const tableListData = ref([])
+//获取数据列表
+
+const ListItemsRef = ref(null)
+//是否是抽屉
+const isDrawType = ref(false)
+//设置滚动条位置
+const ListItemScrollRef = ref(null)
+const ListItemOffsetTop = (offsetTop) => {
+    if (offsetTop > 0) {
+        setTimeout(() => {
+            ListItemScrollRef.value?.setScrollTop(offsetTop)
+        }, 350)
+    } else {
+        ListItemScrollRef.value?.setScrollTop(offsetTop)
+    }
+}
+const getTableData = async () => {
+    const searchInfo = searchForm.value
+    const tabKey = tabTypeKey.value
+    if (!!searchInfo.wbsId) {
+        //初始处理
+        tableLoading.value = true
+        tableListRef.value?.clearSelection()
+        tableSelectionKeys.value = []
+        tableListData.value = []
+        //获取相关数据
+        let addFormData = {
+            projectId: projectId.value,
+            contractId: contractId.value,
+            isFirst: 1,
+        }
+        const treeInfo = treeItem.value
+        //已标记的首件
+        if (tabKey === 'mark' && addFormData['firstTitle']) {
+            delete addFormData.firstTitle
+        }
+        //查询数据
+        if (tabKey === 'query') {
+            addFormData['firstTitle'] = 1
+        }
+        addFormData['wbsId'] = treeInfo['contractIdRelation'] ? treeInfo['id'] : treeInfo['primaryKeyId']
+        //处理数据
+        const { error, code, data } = await firstApi.getQueryPageData({
+            ...addFormData,
+            ...searchInfo,
+        })
+        tableLoading.value = false
+        if (!error && code === 200) {
+            tableListData.value = getArrValue(data['records'])
+
+            searchForm.value.total = data.total || 0
+        } else {
+            tableListData.value = []
+            searchForm.value.total = 0
+        }
+    } else {
+        window?.$message?.warning('请先选择一个树节点')
+    }
+}
+
+//多选
+const tableListRef = ref(null)
+const tableSelectionKeys = ref([]);
+const tableSelectionChange = (rows) => {
+    tableSelectionKeys.value = rows.filter((item) => {
+        return (item??'') !== '';
+    })
+}
+
+//文件名称被点击
+const tableRowName = (row) => {
+    //如果 evisaPdfUrl 不为空,使用evisaPdfUrl,反之使用pdfUrl
+    if (tabTypeKey.value === 'query') {
+        //首件查询时,直接调用接口
+        getBussPdfInfo(row.id + '')
+    } else if (row['evisaPdfUrl']) {
+        window.open(row['evisaPdfUrl'],'_blank')
+    } else if (row['pdfUrl']) {
+        window.open(row['pdfUrl'],'_blank')
+    } else {
+        window.$message?.warning('文件不存在')
+    }
+}
+const ListItemDatas = ref([]);
+//上报首件
+const isFirstReportDrawer = ref(false)
+const isCanreport=ref(false)
+const firstReportClick = () => {
+    const rows = deepClone(tableSelectionKeys.value)
+    console.log(rows,'rows')
+    nextTick(()=>{
+      ListItemDatas.value=rows
+
+    })
+      console.log( ListItemDatas.value,' ListItemDatas.value')
+    //判断是否满足条件
+    const result = rows.every(({status})=> {
+        return status === 2
+        // return status === 0 || status === 3
+    })
+    isCanreport.value=result
+    //判断状态
+    // if (result) {
+    //     isFirstReportDrawer.value = true
+    //     queryNodeStatus()
+    //     tableFileData.value = rows
+    //     getFirstExcelHtml()
+    // } else {
+    //     tableFileData.value = []
+    //     window.$message?.warning('已上报的文件不能进行再次上报,若要重新上报,要先撤回之前的上报,再重新上报')
+    // }
+        isFirstReportDrawer.value = true
+        // getTableData()
+        queryNodeStatus()
+        tableFileData.value = rows
+        getFirstExcelHtml()
+}
+const FirstReportDrawerClose = () => {
+    isFirstReportDrawer.value = false
+}
+
+//获取表单
+const statusDesc = ref('')
+const isTableForm = ref(false)
+const pkeyIds = ref('')
+const getFirstExcelHtml = async () => {
+    const cid = contractId.value;
+    const { error, code, data } = await firstApi.getFirstExcelHtml({
+        contractId: contractId.value || ''
+    }, false)
+    //处理数据
+    const temp = isString(data?.data) ? data?.data || '' : ''
+    if (!error && code === 200 && temp) {
+        let pkeyId = data?.id || ''
+        pkeyIds.value = pkeyId
+        await getFirstBussDataInfo(pkeyId)
+        setHTableForm(temp, cid)
+    } else {
+        isTableForm.value = false
+        statusDesc.value = '暂无表单'
+        window?.$message?.warning('暂无表单')
+    }
+}
+
+//渲染表单
+const tableFormApp = ref(null)
+const setHTableForm = (resData, cid) => {
+    //先卸载
+    if (tableFormApp.value) {
+        tableFormApp.value?.unmount()
+    }
+    if (resData) {
+        isTableForm.value = true
+        nextTick(() => {
+            tableFormApp.value = HTableForm.createForm({
+                template: resData,
+                tableForm: tableFormData.value,
+                appId: `#table-form-${cid}`
+            })
+        })
+    } else {
+        isTableForm.value = false
+        statusDesc.value = '暂无表单'
+        window?.$message?.warning('暂无表单')
+    }
+}
+
+//获取回显数据
+const tableFormData = ref({})
+const getFirstBussDataInfo = async (pkeyId) => {
+    if (pkeyId) {
+        const { data } = await firstApi.getFirstBussDataInfo({
+            contractId: contractId.value || '',
+            firstId: pkeyId + ''
+        }, false)
+        const info = getObjValue(data)
+        if (getObjNullValue(info)) {
+            HTableForm.setPickerKey(info)
+            tableFormData.value = info
+        } else {
+            tableFormData.value = {}
+        }
+    } else {
+        tableFormData.value = {}
+    }
+}
+
+//上传变量
+const fileListData = ref([]);
+const finishFile = ref({
+    sourceUrl: '', pdfUrl: '', firstFileName: ''
+})
+//上传文件
+const uploadChange = async ({type, res}) => {
+    if (type === 'success') {
+        const {code, data, msg} = res
+        if (code === 200) {
+            finishFile.value = {
+                sourceUrl: data?.sourceUrl,
+                pdfUrl: data?.pdfUrl,
+                firstFileName: data?.fileName,
+            }
+            window.$message?.success(msg);
+        } else {
+            window.$message?.error(msg || '上传失败');
+        }
+    }
+}
+
+//文件附件列表
+const tableFileColumn = ref([
+    {key:'name', name: '文件名称'},
+    {key:'action', name: '操作', width: 80, align: 'center'}
+]);
+const tableFileData = ref([]);
+const tableDelButton = (index) => {
+    const arr = tableFileData.value
+    if (arr.length > 1) {
+        window?.$messageBox?.alert('确定删除该文件吗?', '删除提醒', {
+            type: 'warning',
+            showCancelButton: true,
+            confirmButtonText: '确定删除',
+            cancelButtonText: '取消',
+            callback: (action) => {
+                if (action === 'confirm') {
+                    tableFileData.value.splice(index, 1)
+                }
+            }
+        })
+    } else {
+        window?.$message?.warning('至少保留一个文件')
+    }
+}
+
+//填报数据保存
+const pdfId=ref('')
+const saveBussData = async () => {
+    console.log('保存');
+    const { id } = treeItem.value
+    const res = await saveExcelBussData(id + '')
+    //刷新页面
+    //  window?.location?.reload()  //刷新页面
+    if (res) {
+        pdfId.value=res
+         queryNodeStatus()
+        await getBussPdfInfo(res)
+         
+          
+       
+    }
+}
+
+//保存请求
+const tableFormSaveLoading = ref(false)
+const tableFormId = ref('')
+const saveExcelBussData = async (pkeyId) => {
+    tableFormId.value = ''
+    const { primaryKeyId } = treeItem.value
+    tableFormSaveLoading.value = true
+    const linkIds = rowsToArr(tableFileData.value);
+    const { error, code, data } = await firstApi.saveBussData({
+        ...tableFormData.value,
+        projectId: projectId.value,
+        contractId: contractId.value,
+        firstNodeId: primaryKeyId,
+        pkeyId: pkeyId,
+        classify: '1',
+        isFirst: 1,
+        linkProcessList: linkIds,
+        ...finishFile.value
+    }, false)
+    //判断状态
+    tableFormSaveLoading.value = false
+    if (!error && code === 200 && isString(data)) {
+        window.$message?.success('保存成功')
+        tableFormId.value = data
+        return data
+    } else {
+        window.$message?.error('保存失败')
+        tableFormId.value = ''
+        return ''
+    }
+}
+
+//pdf预览
+const bussPdfInfo = () => {
+    const { id } = treeItem.value
+    // getBussPdfInfo(id + '')
+     getBussPdfInfo(pdfId.value)
+      
+}
+
+//预览PDF请求
+const getBussPdfInfo = async (pkeyId) => {
+    const { error, code, data } = await firstApi.getFirstBussPdfInfo({
+        firstId: pkeyId
+    })
+    //判断状态
+    const res = isString(data)? data ?? '': ''
+    if (!error && code === 200 && res) {
+        window.open(res,'_blank')
+    }
+}
+
+//上报审批
+const reportIds = ref('')
+const showReportModal = ref(false)
+const reportTaskName = ref('')
+const reportAddition = ref({})
+const reportLoading = ref(false)
+const reportTypeData = ref('')
+const reportDatas = ref([])
+const isReportModalDatas = ref(false)
+const iscanReport=ref(false)
+//上报方法封装
+const toreportModalClick = async (type) => {
+    if(type){
+            const { primaryKeyId, contractIdRelation } = treeItem.value
+            let rows = [];
+            //处理获取流程的条件
+            if (tabTypeKey.value === 'mark') {
+                reportTypeData.value = tableFormId.value
+                isReportModalDatas.value = false
+                rows = tableFileData.value
+            } else {
+                isReportModalDatas.value = true
+                rows = tableSelectionKeys.value
+            }
+            if (rows.length > 0) {
+                reportLoading.value = true
+                const taskCheck = await eVisaTaskCheckApi({
+                    projectId: projectId.value,
+                    contractId: contractId.value
+                })
+                if (taskCheck) {
+                    if (tabTypeKey.value === 'mark') {
+                        reportIds.value = tableFormId.value
+                        const { data } = await firstApi.queryFirstDocumentTitle({
+                            projectId: projectId.value,
+                            contractId: contractId.value,
+                            queryId: tableFormId.value
+                        })
+                        reportTaskName.value = isString(data) ? data ?? '' : ''
+                    } else {
+                        reportIds.value = rowsToId(rows)
+                        //设置任务数据
+                        let reportDataArr = []
+                        rows.forEach(item => {
+                            reportDataArr.push({
+                                id: item?.id,
+                                name: item?.name
+                            })
+                        })
+                        reportDatas.value = reportDataArr
+                        //其他数据
+                        reportTypeData.value = rows[0]['id']
+                        reportTaskName.value = rows.length > 1?`${rows[0].name}等${rows.length}个文件`:rows[0].name
+                    }
+                    reportLoading.value = false
+                    //附加数据
+                    reportAddition.value = {
+                        classify: 1,
+                        isFirst: 1,
+                        primaryKeyId: primaryKeyId,
+                        contractIdRelation: contractIdRelation ?? contractId.value,
+                    }
+                    showReportModal.value = true
+                } else {
+                    reportLoading.value = false
+                }
+            } else {
+                window.$message?.warning('暂无相关数据')
+            }
+        }else{
+             window.$message?.warning('当前工序资料还未审批,待审批完成才能进行首件模板上报')
+            
+        }
+}
+const reportModalClick = async (type) => {
+    if(type===2){
+         console.log('上报')
+        iscanReport.value=isCanreport.value;
+        toreportModalClick(iscanReport.value)
+
+    }
+    
+    else{
+         const rows = deepClone(tableSelectionKeys.value)
+         let result=false
+            console.log('上报审批',rows)
+        //判断自身是否满足条件
+         const result1 = rows.every(({taskStatusStr})=> {
+            return taskStatusStr === '未上报'||taskStatusStr === '已废除'
+        })
+        if(result1){
+             //判断工序节点是否满足条件
+             result = rows.every(({isApprove})=> {
+                return isApprove === true
+            })
+             iscanReport.value=result
+              toreportModalClick(iscanReport.value)
+        }else{
+              window.$message?.warning('已上报的数据不能重复上报')
+               iscanReport.value=false
+        }
+       
+        
+         
+    }
+   
+}
+
+//上报的审批内容移除
+const reportTaskTagClose = (index) => {
+    const row = tableSelectionKeys.value[index];
+    tableListRef.value?.toggleRowSelection(row,false)
+}
+const getTableDataAll = () => {
+    getTableData()
+    firstTaskStatus()
+}
+//上报完成
+const showReportFinish = () => {
+    showReportModal.value = false
+    getTableDataAll()
+}
+
+//打印
+const printLoading = ref(false)
+const batchPrint = async () => {
+    const rows = tableSelectionKeys.value;
+    const ids = rowsToId(rows)
+    //批量下载
+    printLoading.value = true
+    const { error, code, data } = await firstApi.batchPrint({
+        ids: ids
+    })
+    //处理数据
+    printLoading.value = false
+    //判断状态
+    const res = isString(data)? data ?? '': ''
+    if (!error && code === 200 && res) {
+        window.open(res,'_blank')
+    }
+}
+
+//废除
+const batchAbolishClick = () => {
+    const rows = tableSelectionKeys.value;
+    //判断是否满足条件
+    const result = rows.every(({status})=> {
+        return status !== 0 && status !== 3
+    })
+    //判断状态
+    if (result) {
+        //拼接ID
+        const ids = rowsToId(rows)
+        window?.$messageBox?.alert('是否废除勾选的已上报文件?', '废除文件', {
+            showCancelButton: true,
+            confirmButtonText: '确定废除',
+            cancelButtonText: '取消',
+            callback: (action) => {
+                if (action === 'confirm') {
+                    batchAbolishSave(ids)
+                }
+            }
+        })
+    } else {
+        window.$message?.warning('未上报的文件不能废除')
+    }
+}
+//废除勾选的已上报文件
+const batchAbolishSave = async (ids) => {
+    const { error, code } = await queryApi.batchAbolish({ids: ids})
+    //处理数据
+    if (!error && code === 200) {
+        window.$message?.success('批量废除成功')
+        tableSelectionKeys.value = []
+        getTableData()
+    }
+}
+
+//拼接ID
+const rowsToId = (rows) => {
+    return rows.map((obj) => {
+        return obj.id;
+    }).join(",")
+}
+
+//处理数据
+const rowsToArr = (rows) => {
+    let newArr = [];
+    for (let i = 0; i < rows.length; i++) {
+        newArr.push({
+            id: rows[i]?.id,
+            name: rows[i]?.name
+        })
+    }
+    return newArr
+}
+
+//左右拖动,改变树形结构宽度
+const leftWidth = ref(382)
+const onmousedown = () => {
+    const leftNum = isCollapse.value ? 142 : 272
+    document.onmousemove = (ve) => {
+        const diffVal = ve.clientX - leftNum;
+        if(diffVal >= 310 && diffVal <= 900) {
+            leftWidth.value = diffVal;
+        }
+    }
+    document.onmouseup = () => {
+        document.onmousemove = null;
+        document.onmouseup = null;
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "../../styles/other/first-item.scss";
+</style>
+
+<style lang="scss">
+.hc-first-item-node-layout.el-overlay {
+    position: absolute;
+    background-color: transparent;
+    margin: -24px;
+    height: revert;
+    .hc-drawer-box.el-drawer {
+        --el-drawer-bg-color: transparent;
+        .el-drawer__body {
+            padding: 24px;
+            display: flex;
+            flex-direction: column;
+            overflow: hidden;
+        }
+    }
+}
+</style>