collection.vue 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786
  1. <template>
  2. <hc-body :loading="treeLoading" :project-nmae="projectInfo.name" class="hc-file-collection-page" split>
  3. <template #tree>
  4. <HcTree
  5. ref="treeRef" :auto-expand-keys="treeAutoExpandKeys" :contract-id="contractId" :menus="ElTreeMenu"
  6. :project-id="projectId"
  7. @node-tap="projectTreeClick" @node-loading="treeNodeLoading" @menu-tap="ElTreeMenuClick"
  8. />
  9. </template>
  10. <hc-new-card>
  11. <template #header>
  12. <HcTooltip keys="file_collection_btn_upload_scanned_files">
  13. <el-button hc-btn type="primary" @click="uploadModalClick">上传扫描文件</el-button>
  14. </HcTooltip>
  15. <HcTooltip keys="file_collection_btn_sorting">
  16. <el-button hc-btn type="success" @click="sortingClick">分盒整理</el-button>
  17. </HcTooltip>
  18. <HcTooltip keys="file_collection_btn_download">
  19. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn>下载</el-button>
  20. </HcTooltip>
  21. <HcTooltip keys="file_collection_btn_certified">
  22. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn @click="certificationModalClick">认证</el-button>
  23. </HcTooltip>
  24. <HcTooltip keys="file_collection_btn_report">
  25. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn type="warning" @click="reportModalClick">上报</el-button>
  26. </HcTooltip>
  27. <HcTooltip keys="file_collection_btn_edit">
  28. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn @click="batchEditClick">编辑</el-button>
  29. </HcTooltip>
  30. <HcTooltip keys="file_collection_btn_repeal">
  31. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn @click="repealModalClick">废除</el-button>
  32. </HcTooltip>
  33. <HcTooltip keys="file_collection_btn_del">
  34. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn type="danger" @click="delModalClick">删除</el-button>
  35. </HcTooltip>
  36. <el-button :disabled="tableCheckedKeys.length <= 0" :loading="onlineLoading" color="#e03997" hc-btn @click="batchOnline">在线验签</el-button>
  37. </template>
  38. <template #extra>
  39. <HcTooltip keys="file_collection_btn_moves">
  40. <el-button color="#626aef" hc-btn @click="movesClick">跨目录移动</el-button>
  41. </HcTooltip>
  42. </template>
  43. <template #search>
  44. <div class="w-40">
  45. <el-select v-model="searchForm.isApprovalValue" clearable placeholder="审批状态">
  46. <el-option v-for="item in approvalStatus" :key="item.value" :label="item.label" :value="item.value" />
  47. </el-select>
  48. </div>
  49. <div class="ml-2 w-40">
  50. <el-select v-model="searchForm.isCertificationValue" clearable placeholder="认证状态">
  51. <el-option v-for="item in certifiedStatus" :key="item.value" :label="item.label" :value="item.value" />
  52. </el-select>
  53. </div>
  54. <div class="ml-2 w-64">
  55. <el-input v-model="searchForm.queryValue" clearable placeholder="请输入名称关键词检索" @keyup="keyUpEvent" />
  56. </div>
  57. <div class="ml-2">
  58. <el-button type="primary" @click="searchClick">搜索</el-button>
  59. </div>
  60. </template>
  61. <HcTable
  62. ref="tableRef" :check-style="{ width: 29 }" :column="tableColumn" :datas="tableData"
  63. :index-style="{ width: 80 }" :loading="tableLoading" is-check is-new
  64. @selection-change="tableSelection"
  65. >
  66. <template #table-column-header-num>
  67. <HcTooltip keys="file_collection_btn_sort">
  68. <span class="text-link text-lg" @click="tableSortClick">
  69. <HcIcon name="arrow-up-down" />
  70. </span>
  71. </HcTooltip>
  72. </template>
  73. <template #isApprovalValue="{ row }">
  74. <el-tag v-if="row?.isApprovalValue" :type="`${row.isApprovalValue === '已审批' ? 'success' : row.isApprovalValue === '待审批' ? 'warning' : row.isApprovalValue === '已废除' ? 'danger' : 'info'}`" class="mx-1" effect="dark">
  75. {{ row.isApprovalValue }}
  76. </el-tag>
  77. </template>
  78. <template #fileName="{ row }">
  79. <span class="text-link" @click="tableRowName(row)">{{ row?.fileName }}</span>
  80. </template>
  81. <template #sourceType="{ row }">
  82. <span>{{ row?.sourceType === 1 ? '原生' : '数字化' }}</span>
  83. </template>
  84. <template #fileTime="{ row }">
  85. <span>{{ getTableFileTime(row.fileTime) }}</span>
  86. </template>
  87. </HcTable>
  88. <template #action>
  89. <HcPages :pages="searchForm" @change="pageChange" />
  90. </template>
  91. </hc-new-card>
  92. <!-- 预组卷整理 -->
  93. <hc-new-dialog v-model="sortingModal" is-row-footer is-table title="预组卷整理" widths="850px" @close="sortingModalClose">
  94. <div class="hc-sorting-modal-collapse">
  95. <el-collapse v-model="sortingActiveKey">
  96. <template v-for="(item, index) in sortingItemData" :key="index">
  97. <el-collapse-item :id="`item-${index}`" :name="`item-${index}`" disabled>
  98. <template #title>
  99. <div class="hc-collapse-item-header">
  100. <div class="item-index">盒{{ index + 1 }}</div>
  101. <el-divider direction="vertical" />
  102. <div class="item-input">
  103. <el-input
  104. v-model="item.boxName" :class="item.isName ? 'is-error' : ''"
  105. placeholder="请输入案卷题名"
  106. @change="tableIsInput($event, item, 'isName')"
  107. @input="tableIsInput($event, item, 'isName')"
  108. />
  109. </div>
  110. <el-divider direction="vertical" />
  111. <div class="item-action">
  112. <el-button type="primary" @click="sortingSelectFile(item, index)">选择文件</el-button>
  113. <el-button type="danger" @click="sortingDelData(item, index)">删除</el-button>
  114. </div>
  115. </div>
  116. </template>
  117. <HcTable
  118. ref="sorTableRef" :check-style="{ width: 29 }" :column="sortingTableColumn" :datas="item.list"
  119. :index-style="{ width: 60 }" :loading="sortingTableLoading" is-check is-new
  120. @selection-change="rows => sortingTableSelection(rows, item.list, index)"
  121. @single-select="singleCheck"
  122. >
  123. <template #name="{ row }">
  124. <span class="text-link">{{ row?.fileName }}</span>
  125. </template>
  126. </HcTable>
  127. </el-collapse-item>
  128. </template>
  129. </el-collapse>
  130. </div>
  131. <template #leftRowFooter>
  132. <el-button hc-btn type="primary" @click="addSortingModalClick">
  133. <HcIcon name="add" />
  134. <span>添加分盒</span>
  135. </el-button>
  136. </template>
  137. <template #rightRowFooter>
  138. <el-button hc-btn @click="sortingModalClose">
  139. <HcIcon name="close" />
  140. <span>取消</span>
  141. </el-button>
  142. <el-button :loading="sortingModalLoading" hc-btn type="primary" @click="sortingModalSave">
  143. <HcIcon name="check" />
  144. <span>确认</span>
  145. </el-button>
  146. </template>
  147. </hc-new-dialog>
  148. <!-- 预组卷整理 无数据 -->
  149. <hc-new-dialog v-model="sortingNoneModal" is-row-footer is-table title="预组卷整理" widths="850px" @close="sortingNoneModalClose">
  150. <div class="flex-center">
  151. <i class="el-icon" data-v-029747aa="" style="font-size: 200px;color:#81b337;cursor: pointer;" @click="toSortingModal">
  152. <svg data-v-029747aa="" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
  153. <path d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm-38.4 409.6H326.4a38.4 38.4 0 1 0 0 76.8h147.2v147.2a38.4 38.4 0 0 0 76.8 0V550.4h147.2a38.4 38.4 0 0 0 0-76.8H550.4V326.4a38.4 38.4 0 1 0-76.8 0v147.2z" fill="currentColor" />
  154. </svg>
  155. </i>
  156. <span>添加分盒</span>
  157. </div>
  158. </hc-new-dialog>
  159. <!-- 跨目录移动 -->
  160. <hc-new-dialog v-model="movesModal" :loading="movesModalLoading" is-table title="跨目录移动" widths="990px" @close="movesModalClose" @save="movesModalSave">
  161. <div class="hc-moves-transfer-box">
  162. <div class="hc-moves-transfer-panel">
  163. <div class="panel-header">
  164. <div class="panel-header-label">
  165. <el-checkbox v-model="movesCheckAll" :indeterminate="isIndeterminate" class="space size-xl" @change="handleCheckAllChange">
  166. 选择需要迁移的文件
  167. </el-checkbox>
  168. </div>
  169. <div class="panel-header-extra">{{ checkedMoves.length }}/{{ fileDatasList.length }}</div>
  170. </div>
  171. <div class="panel-body">
  172. <el-scrollbar v-loading="fileDatasListLoading">
  173. <el-checkbox-group v-model="checkedMoves" @change="handleCheckedMovesChange">
  174. <!-- <div v-for="item in fileDatasList" :key="item.id" class="hc-file-checkbox">
  175. <el-checkbox class="size-xl space" :label="item">
  176. {{ item.fileName }}
  177. </el-checkbox>
  178. </div> -->
  179. <recycle-scroller
  180. :buffer="1000" :item-size="110" :items="fileDatasList"
  181. :prerender="200" class="virtual-list" key-field="id"
  182. style="height: 900px"
  183. >
  184. <template #default="{ item, index }">
  185. <div :key="index">
  186. <el-checkbox :value="item" class="space mt-5 size-xl">{{ item.fileName }}</el-checkbox>
  187. </div>
  188. </template>
  189. </recycle-scroller>
  190. </el-checkbox-group>
  191. </el-scrollbar>
  192. </div>
  193. </div>
  194. <div class="hc-moves-transfer-buttons">
  195. <HcIcon name="arrow-right-double" style="font-size: 22px;" type="primary" />
  196. </div>
  197. <div class="hc-moves-transfer-panel">
  198. <div class="panel-header">选择移动目录</div>
  199. <div v-loading="treePanelLoading" class="panel-body">
  200. <el-scrollbar>
  201. <HcTree
  202. :contract-id="contractId" :is-show-menu="false" :project-id="projectId"
  203. :show-radio-fun="showRadioFun" id-prefix="hc-tree-moves-" is-radio
  204. @radio-change="radioChange" @node-loading="panelTreeLoading"
  205. />
  206. </el-scrollbar>
  207. </div>
  208. </div>
  209. </div>
  210. </hc-new-dialog>
  211. <!-- 调整排序 -->
  212. <hc-new-dialog v-model="sortModal" is-row-footer is-table title="调整排序" widths="80vw" @close="sortModalClose">
  213. <el-alert :closable="false" title="可拖动排序,也可在后面点击图标,切换排序" type="error" />
  214. <div class="hc-table-h">
  215. <HcTable
  216. :column="sortTableColumn" :datas="sortTableData" :index-style="{ width: 80 }"
  217. :loading="sortTableLoading"
  218. is-new is-row-drop quick-sort ui="hc-table-row-drop"
  219. @row-drop="sortTableRowDrop" @row-sort="sortTableRowDrop"
  220. >
  221. <template #key2="{ row }">
  222. <span class="text-link">{{ row?.key2 }}</span>
  223. </template>
  224. <template #action="{ index }">
  225. <span class="text-link text-xl" @click="upSortClick(index)">
  226. <HcIcon fill name="arrow-up" />
  227. </span>
  228. <span class="text-link ml-2 text-xl" @click="downSortClick(index)">
  229. <HcIcon fill name="arrow-down" />
  230. </span>
  231. </template>
  232. </HcTable>
  233. </div>
  234. <template #leftRowFooter>
  235. <el-button hc-btn @click="sortModalClose">
  236. <HcIcon name="close" />
  237. <span>取消</span>
  238. </el-button>
  239. <el-button :loading="sortModalLoading" hc-btn type="primary" @click="sortModalSave">
  240. <HcIcon name="check" />
  241. <span>确认</span>
  242. </el-button>
  243. </template>
  244. <template #rightRowFooter>
  245. <HcPages :pages="sortSearchForm" :sizes="[10, 20, 50, 100, 200, 300, 400, 500, 600]" @change="sortPageChange" />
  246. </template>
  247. </hc-new-dialog>
  248. <!-- 新增编辑文件 -->
  249. <hc-new-dialog v-model="showUploadModal" is-table title="上传工程文件" widths="90vw" @close="uploadModalClose">
  250. <HcTable
  251. :column="tableUploadColumn" :datas="tableUploadData" :index-style="{ width: 80 }"
  252. :loading="uploadSaveLoading"
  253. is-new is-sort ui="hc-form-table" @row-sort="tableUploadRowSort"
  254. >
  255. <template #fileNumber="{ row }">
  256. <!-- <el-input v-model="row.fileNumber" :class="row['isFileNumber'] ? 'is-error' : ''" @input="tableIsInput($event, row, 'isFileNumber')"/> -->
  257. <el-input v-model="row.fileNumber" />
  258. </template>
  259. <template #fileName="{ row }">
  260. <el-input v-model="row.fileName" :class="row.isFileName ? 'is-error' : ''" @input="tableIsInput($event, row, 'isFileName')" />
  261. </template>
  262. <template #fileTime="{ row }">
  263. <el-date-picker v-model="row.fileTime" :clearable="false" format="YYYYMMDD" type="date" value-format="YYYYMMDD" />
  264. <!-- <el-input v-model="row.fileTime" :class="row['isFileTime'] ? 'is-error' : ''" @input="tableIsInput($event, row, 'isFileTime')"/> -->
  265. </template>
  266. <template v-if="isBuiltDrawing === 2" #sheetType="{ row }">
  267. <el-select v-model="row.sheetType">
  268. <el-option v-for="item in sheetType" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
  269. </el-select>
  270. </template>
  271. <template v-if="isBuiltDrawing === 2" #sheetSource="{ row }">
  272. <el-select v-model="row.sheetSource">
  273. <el-option v-for="item in sheetSourceType" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
  274. </el-select>
  275. </template>
  276. <template v-if="isBuiltDrawing === 2" #drawingNo="{ row }">
  277. <el-input v-model="row.drawingNo" />
  278. </template>
  279. <template v-if="isBuiltDrawing === 2" #citeChangeNumber="{ row }">
  280. <el-input v-model="row.citeChangeNumber" />
  281. </template>
  282. <template #isApproval="{ row }">
  283. <el-select v-model="row.isApproval">
  284. <el-option v-for="item in whetherData" :key="item.value" :label="item.label" :value="item.value" />
  285. </el-select>
  286. </template>
  287. <template #isNeedCertification="{ row }">
  288. <el-select v-model="row.isNeedCertification">
  289. <el-option v-for="item in whetherData" :key="item.value" :label="item.label" :value="item.value" />
  290. </el-select>
  291. </template>
  292. <template #dutyUser="{ row }">
  293. <el-input v-model="row.dutyUser" />
  294. </template>
  295. <template #isElement="{ row }">
  296. <el-select v-model="row.isElement">
  297. <el-option :value="1" label="是" />
  298. <el-option :value="0" label="否" />
  299. </el-select>
  300. </template>
  301. <template #action="{ row, index }">
  302. <el-button v-if="tableUploadType === 'edit'" :loading="row.newBtnLoading" plain size="small" type="primary" @click="substitutionClick(row)">替换</el-button>
  303. <el-button :loading="row.delBtnLoading" class="ml-2" plain size="small" type="danger" @click="delUploadData(row, index)">删除</el-button>
  304. </template>
  305. </HcTable>
  306. <template #footer>
  307. <div class="lr-dialog-footer">
  308. <div class="left flex items-center">
  309. <el-button v-if="tableUploadType === 'add'" hc-btn type="primary" @click="uploadFileClick">
  310. <HcIcon name="add-circle" />
  311. <span>新增上传</span>
  312. </el-button>
  313. </div>
  314. <div class="right">
  315. <el-button size="large" :loading="uploadSaveLoading" @click="batchUploadCancel">
  316. <HcIcon name="close" />
  317. <span>取消</span>
  318. </el-button>
  319. <el-button :loading="uploadSaveLoading" hc-btn type="primary" @click="batchUploadSave">
  320. <HcIcon name="save" />
  321. <span>提交保存</span>
  322. </el-button>
  323. </div>
  324. </div>
  325. </template>
  326. </hc-new-dialog>
  327. <!-- 批量认证 -->
  328. <hc-new-dialog v-model="showCertificationModal" is-table title="批量认证" widths="80vw">
  329. <div class="hc-card-body-flex">
  330. <div class="flex-table">
  331. <HcTable
  332. :column="CertColumns" :datas="CertData" :index-style="{ width: 80 }"
  333. is-new ui="hc-form-table"
  334. @row-click="CertRowClick"
  335. >
  336. <template #action="{ row, index }">
  337. <el-button plain size="small" type="primary" @click.stop="CertRowClick2(row)">预览</el-button>
  338. </template>
  339. </HcTable>
  340. </div>
  341. <div v-if="CertPdf" class="flex-iframe">
  342. <iframe :src="CertPdf" allow="display-capture" frameborder="1" height="100%" width="100%" />
  343. </div>
  344. <div v-else class="flex-iframe hc-no-table-form">
  345. <div class="table-form-no">
  346. <img :src="notableform" alt="">
  347. <div class="desc">暂无 PDF 数据</div>
  348. </div>
  349. </div>
  350. </div>
  351. <template #footer>
  352. <div class="dialog-footer">
  353. <el-button size="large" @click="showCertificationModal = false">
  354. <HcIcon name="close" />
  355. <span>取消</span>
  356. </el-button>
  357. <el-button :loading="CertLoading" hc-btn type="primary" @click="CertClick">
  358. <HcIcon name="save" />
  359. <span>确认认证</span>
  360. </el-button>
  361. </div>
  362. </template>
  363. </hc-new-dialog>
  364. <!-- 批量编辑 -->
  365. <HcReport :data="reportData" :show="isReport" @finish="reportFinish" @hide="isReport = false" />
  366. <!-- 在线验签 -->
  367. <hc-new-drawer v-model="isOnlineVerifyDrawer" modal-class="hc-online-verify-drawer" to-id="app" @close="onlineVerifyDrawerClose">
  368. <hc-new-card>
  369. <template #header>
  370. <div class="online-verify-title">这是标题名称</div>
  371. </template>
  372. <template #extra>
  373. <div class="online-verify-icon" @click="onlineVerifyDrawerClose">
  374. <HcIcon name="close-circle" />
  375. <span class="ml-1">关闭</span>
  376. </div>
  377. </template>
  378. <hc-body :options="onlineVerifyOptions" padding="0px" split>
  379. <template #left>
  380. <hc-new-card>
  381. <HcPdf :src="onlineVerifyData.pdfUrl" />
  382. </hc-new-card>
  383. </template>
  384. <hc-new-card>
  385. <HcTable :column="cscTableColumn" :datas="cscTableData" :index-style="{ width: 60 }" is-new />
  386. </hc-new-card>
  387. </hc-body>
  388. </hc-new-card>
  389. </hc-new-drawer>
  390. </hc-body>
  391. </template>
  392. <script setup>
  393. import { useAppStore } from '~src/store'
  394. import { getStoreValue, setStoreValue } from '~src/utils/storage'
  395. import { nextTick, onMounted, ref, watch } from 'vue'
  396. import HcTree from '~src/components/tree/hc-tree.vue'
  397. import HcReport from './components/HcReport.vue'
  398. import notableform from '~src/assets/view/notableform.svg'
  399. import { rowsToId } from '~uti/tools'
  400. import { HcDelMsg, HcUploadFileApi } from 'hc-vue3-ui'
  401. import archiveFileApi from '~api/archiveFile/archiveFile'
  402. import tasksFlowApi from '~api/tasks/flow'
  403. import { arrKeySort, arrToId, deepClone, getArrValue, getObjVal, isNullES } from 'js-fast-way'
  404. import tasksApi from '~api/tasks/data'
  405. import ossApi from '~api/oss'
  406. import { toPdfPage } from '~uti/btn-auth'
  407. //变量
  408. const useAppState = useAppStore()
  409. const projectId = ref(useAppState.getProjectId)
  410. const contractId = ref(useAppState.getContractId)
  411. const projectInfo = ref(useAppState.getProjectInfo)
  412. const isCollapse = ref(useAppState.getCollapse)
  413. //上传进度
  414. const uploadsLoading = ref(false)
  415. const treeRef = ref(null)
  416. //监听
  417. watch(() => [
  418. useAppState.getCollapse,
  419. ], ([Collapse]) => {
  420. isCollapse.value = Collapse
  421. })
  422. //渲染完成
  423. onMounted(() => {
  424. treeLoading.value = true
  425. setTableColumns()
  426. })
  427. //设置树菜单数据
  428. const ElTreeMenu = ref([
  429. { icon: 'add-circle', label: '新增', key: 'add' },
  430. { icon: 'draft', label: '编辑', key: 'edit' },
  431. { icon: 'delete-bin', label: '删除', key: 'del' },
  432. { icon: 'refresh', label: '目录同步', key: 'sync' },
  433. { icon: 'sort-asc', label: '排序', key: 'sort' },
  434. ])
  435. const dutyUser = ref('')
  436. //设置责任者
  437. const setdutyUser = async () => {
  438. const { error, code, data } = await archiveFileApi.getDutyUser({
  439. contractId: treecontractId.value,
  440. projectId: projectId.value,
  441. })
  442. if (!error && code === 200) {
  443. if (data?.contractType === 1) {
  444. dutyUser.value = data?.constructionUnitName || ''
  445. } else if (data?.contractType === 2) {
  446. dutyUser.value = data?.supervisionUnitName || ''
  447. } else if (data?.contractType === 3) {
  448. dutyUser.value = data?.contractorUnitName || ''
  449. }
  450. }
  451. }
  452. //打开文件选择框
  453. const uploadFileClick = () => {
  454. HcUploadFileApi({
  455. multiple: true,
  456. progress: () => {
  457. uploadsLoading.value = true
  458. },
  459. success: (file, res) => {
  460. uploadsChange(file.id, res.data)
  461. },
  462. error: (file) => {
  463. uploadsLoading.value = false
  464. window.$message.error(`${file.name} 上传失败`)
  465. },
  466. finish: () => {
  467. uploadsLoading.value = false
  468. window.$message.success('全部上传完成')
  469. },
  470. })
  471. }
  472. //替换文件
  473. const substitutionClick = (row) => {
  474. HcUploadFileApi({
  475. multiple: false,
  476. progress: () => {
  477. uploadsLoading.value = true
  478. },
  479. success: (_, { data }) => {
  480. //更新数据
  481. row.fileName = data?.originalName
  482. row.ossFileName = data?.name || ''
  483. row.fileUrl = data?.link || ''
  484. row.pdfFileUrl = data?.pdfUrl || ''
  485. row.filePage = data?.page || ''
  486. row.isUpdateUrl = 1
  487. uploadsLoading.value = false
  488. window.$message.success('上传成功')
  489. },
  490. error: (file) => {
  491. uploadsLoading.value = false
  492. window.$message.error(`${file.name} 上传失败`)
  493. },
  494. })
  495. }
  496. //树加载
  497. const treeLoading = ref(false)
  498. const treeNodeLoading = () => {
  499. treeLoading.value = false
  500. }
  501. const treePanelLoading = ref(false)
  502. const panelTreeLoading = () => {
  503. treePanelLoading.value = false
  504. }
  505. //审批状态
  506. const approvalStatus = ref([
  507. { label: '未上报', value: '0' },
  508. { label: '待审批', value: '1' },
  509. { label: '已审批', value: '2' },
  510. ])
  511. //认证状态
  512. const certifiedStatus = ref([
  513. { label: '已认证', value: '1' },
  514. { label: '未认证', value: '0' },
  515. ])
  516. //搜索表单
  517. const searchForm = ref({
  518. nodeIds: '',
  519. approval: null, certified: null, queryValue: null,
  520. current: 1, size: 20, total: 0,
  521. })
  522. //树相关的变量
  523. const isBuiltDrawing = ref(0)
  524. const isStorageNode = ref(0)
  525. const nodeIds = ref('')
  526. const treecontractId = ref('')
  527. //自动展开缓存
  528. const treeAutoExpandKeys = ref(getStoreValue('wbsTreeExpandKeys') || [])
  529. const projectTreeClick = ({ data, keys }) => {
  530. setStoreValue('wbsTreeExpandKeys', keys)
  531. treeAutoExpandKeys.value = keys || []
  532. nodeIds.value = data.id || ''
  533. isStorageNode.value = data['isStorageNode'] || 0
  534. treecontractId.value = data?.contractId || ''
  535. //设置搜索数据
  536. searchForm.value.current = 1
  537. searchForm.value.nodeIds = data.id || ''
  538. sortSearchForm.value.nodeIds = data.id || ''
  539. isBuiltDrawing.value = data.storageType
  540. getTableData()
  541. }
  542. //树菜单被点击
  543. const ElTreeMenuClick = async ({ data, keys }) => {
  544. setStoreValue('wbsTreeExpandKeys', keys)
  545. treeAutoExpandKeys.value = keys || []
  546. if (data?.extType === 2) {
  547. // 声像节点显示声像文件同步菜单
  548. // if (data?.storageType === 5 && data?.associationType === 3) {
  549. // ElTreeMenu.value = [
  550. // { icon: 'add-circle', label: '新增', key: 'add' },
  551. // { icon: 'draft', label: '编辑', key: 'edit' },
  552. // { icon: 'delete-bin', label: '删除', key: 'del' },
  553. // { icon: 'refresh', label: '目录同步', key: 'sync' },
  554. // { icon: 'refresh', label: '文件同步', key: 'fileSync' },
  555. // { icon: 'sort-asc', label: '排序', key: 'sort' },
  556. // { icon: 'refresh', label: '声像文件同步', key: 'syncVocie' },
  557. // ]
  558. // } else {
  559. // ElTreeMenu.value = [
  560. // { icon: 'add-circle', label: '新增', key: 'add' },
  561. // { icon: 'draft', label: '编辑', key: 'edit' },
  562. // { icon: 'delete-bin', label: '删除', key: 'del' },
  563. // { icon: 'refresh', label: '目录同步', key: 'sync' },
  564. // { icon: 'refresh', label: '文件同步', key: 'fileSync' },
  565. // { icon: 'sort-asc', label: '排序', key: 'sort' },
  566. // ]
  567. // }
  568. ElTreeMenu.value = [
  569. { icon: 'add-circle', label: '新增', key: 'add' },
  570. { icon: 'draft', label: '编辑', key: 'edit' },
  571. { icon: 'delete-bin', label: '删除', key: 'del' },
  572. { icon: 'refresh', label: '目录同步', key: 'sync' },
  573. { icon: 'refresh', label: '文件同步', key: 'fileSync' },
  574. { icon: 'sort-asc', label: '排序', key: 'sort' },
  575. ]
  576. } else {
  577. // 声像节点显示声像文件同步菜单
  578. // if (data?.storageType === 5 && data?.associationType === 3) {
  579. // ElTreeMenu.value = [
  580. // { icon: 'add-circle', label: '新增', key: 'add' },
  581. // { icon: 'draft', label: '编辑', key: 'edit' },
  582. // { icon: 'delete-bin', label: '删除', key: 'del' },
  583. // { icon: 'refresh', label: '目录同步', key: 'sync' },
  584. // { icon: 'sort-asc', label: '排序', key: 'sort' },
  585. // { icon: 'refresh', label: '声像文件同步', key: 'syncVocie' },
  586. // ]
  587. // } else {
  588. // ElTreeMenu.value = [
  589. // { icon: 'add-circle', label: '新增', key: 'add' },
  590. // { icon: 'draft', label: '编辑', key: 'edit' },
  591. // { icon: 'delete-bin', label: '删除', key: 'del' },
  592. // { icon: 'refresh', label: '目录同步', key: 'sync' },
  593. // { icon: 'sort-asc', label: '排序', key: 'sort' },
  594. // ]
  595. // }
  596. ElTreeMenu.value = [
  597. { icon: 'add-circle', label: '新增', key: 'add' },
  598. { icon: 'draft', label: '编辑', key: 'edit' },
  599. { icon: 'delete-bin', label: '删除', key: 'del' },
  600. { icon: 'refresh', label: '目录同步', key: 'sync' },
  601. { icon: 'sort-asc', label: '排序', key: 'sort' },
  602. ]
  603. }
  604. }
  605. //回车搜索
  606. const keyUpEvent = (e) => {
  607. if (e.key === 'Enter') {
  608. searchForm.value.current = 1
  609. getTableData()
  610. }
  611. }
  612. //搜索
  613. const searchClick = () => {
  614. searchForm.value.current = 1
  615. getTableData()
  616. }
  617. //分页被点击
  618. const pageChange = ({ current, size }) => {
  619. searchForm.value.current = current
  620. searchForm.value.size = size
  621. getTableData()
  622. }
  623. //表格数据
  624. const tableRef = ref(null)
  625. const tableColumn = ref([])
  626. //设置表头
  627. const setTableColumns = () => {
  628. if (isBuiltDrawing.value === 1) {
  629. tableColumn.value = [
  630. { key: 'sourceType', name: '文件来源', width: 100 },
  631. { key: 'fileNumber', name: '文件编号', width: 100, autoWidth: true },
  632. { key: 'fileName', name: '文件名称' },
  633. { key: 'filePage', name: '文件页数', width: 120 },
  634. { key: 'sheetType', name: '图幅', width: 110 },
  635. { key: 'sheetSourceValue', name: '图表来源', width: 110 },
  636. { key: 'drawingNo', name: '图号', width: 110 },
  637. { key: 'citeChangeNumber', name: '引用变更令编号', width: 110 },
  638. { key: 'isCertificationValue', name: '认证状态', width: 100 },
  639. { key: 'isApprovalValue', name: '状态', width: 100 },
  640. { key: 'fileTime', name: '文件时间', width: 120, autoWidth: true },
  641. { key: 'dutyUser', name: '责任者', width: 140 },
  642. ]
  643. sheetTypeStatus()
  644. sheetSourceStatus()
  645. } else {
  646. tableColumn.value = [
  647. { key: 'sourceType', name: '文件来源', width: 100 },
  648. { key: 'fileNumber', name: '文件编号', width: 100, autoWidth: true },
  649. { key: 'fileName', name: '文件名称' },
  650. { key: 'filePage', name: '文件页数', width: 100 },
  651. { key: 'isCertificationValue', name: '认证状态', width: 100 },
  652. { key: 'isApprovalValue', name: '状态', width: 100 },
  653. { key: 'fileTime', name: '文件时间', width: 120, autoWidth: true },
  654. { key: 'dutyUser', name: '责任者', width: 140 },
  655. ]
  656. }
  657. }
  658. const tableData = ref([])
  659. //获取数据
  660. const tableLoading = ref(false)
  661. const getTableData = async () => {
  662. tableLoading.value = true
  663. const { error, code, data } = await archiveFileApi.getarchiveFilePage({
  664. ...searchForm.value,
  665. projectId: projectId.value,
  666. contractId: contractId.value,
  667. })
  668. tableLoading.value = false
  669. if (!error && code === 200) {
  670. tableData.value = getArrValue(data['records'])
  671. searchForm.value.total = data['total'] || 0
  672. } else {
  673. tableData.value = []
  674. searchForm.value.total = 0
  675. }
  676. }
  677. //多选
  678. const tableCheckedKeys = ref([])
  679. const tableSelection = (rows) => {
  680. tableCheckedKeys.value = rows
  681. }
  682. //分盒整理
  683. const sortingModal = ref(false)
  684. const sortingClick = async () => {
  685. if (nodeIds.value && isStorageNode.value === 1) {
  686. const { error, code, data } = await archiveFileApi.getBoxNameAndBoxNumber({
  687. nodeId: nodeIds.value,
  688. })
  689. if (!error && code === 200) {
  690. if (data.length > 0) {
  691. sortingActiveKey.value = []
  692. sortingModal.value = true
  693. sortingItemData.value = getArrValue(data)
  694. sortingOldData.value = deepClone(sortingItemData.value)
  695. } else {
  696. console.log(1111111)
  697. sortingNoneModal.value = true
  698. }
  699. }
  700. } else {
  701. window?.$message?.warning('请先选择一个子节点')
  702. }
  703. }
  704. const sortingNoneModal = ref(false)//无数据显示的弹窗
  705. const toSortingModal = () => {
  706. sortingNoneModal.value = false
  707. sortingActiveKey.value = []
  708. sortingItemData.value = []
  709. sortingModal.value = true
  710. }
  711. const sortingNoneModalClose = () => {
  712. sortingNoneModal.value = false
  713. }
  714. const sortingItemData = ref([])
  715. const sortingOldData = ref([])//旧数据,用来对比是否修改名字
  716. //校验
  717. const tableIsInput = (val, row, key) => {
  718. //检测是否改过案卷名字
  719. if (key === 'isName') {
  720. row.isChange = true
  721. }
  722. row[key] = !val
  723. }
  724. const sortingActiveKey = ref([])
  725. const tableIndex = ref('')
  726. const sortingSelectFile = (row, index) => {
  727. tableIndex.value = index
  728. const key = `item-${index}`
  729. const indexNum = sortingActiveKey.value.indexOf(key)
  730. if (indexNum > -1) {
  731. sortingActiveKey.value.splice(indexNum, 1)
  732. } else {
  733. sortingActiveKey.value.push(key)
  734. if (!(row.list && row.list.length > 0)) {
  735. getSortingTableData(row, index)
  736. }
  737. }
  738. }
  739. //表格
  740. const sortingTableColumn = [
  741. { key: 'name', name: '文件名称' },
  742. ]
  743. //获取数据
  744. const sortingTableLoading = ref(false)
  745. const getSortingTableData = async (row, index) => {
  746. sortingTableLoading.value = true
  747. tableindex.value = index
  748. const { error, code, data } = await archiveFileApi.pageByBoxName({
  749. size: 99999,
  750. current: 1,
  751. projectId: projectId.value,
  752. contractId: contractId.value,
  753. nodeIds: nodeIds.value,
  754. boxName: row.boxName ? row.boxName : '',
  755. })
  756. sortingTableLoading.value = false
  757. if (!error && code === 200) {
  758. row.list = getArrValue(data['records'])
  759. setTableCheck(row, index).then()
  760. } else {
  761. row.list = []
  762. }
  763. }
  764. //表格ref
  765. const sorTableRef = ref([])
  766. const tableindex = ref('')
  767. //回显勾选
  768. const setTableCheck = async (row, index) => {
  769. if (row.ids) {
  770. const keys = row.ids.split(','), list = row.list
  771. for (let i = 0; i < list.length; i++) {
  772. const item = list[i]
  773. if (keys.indexOf(item.id) > -1) {
  774. item.checked = true
  775. await nextTick()
  776. // console.log(sorTableRef.value[index], 'sorTableRef.value[index]')
  777. sorTableRef.value[index].toggleRowSelection(item, true)
  778. }
  779. }
  780. }
  781. }
  782. //多选
  783. const checkList = ref([])
  784. const arrfliter = ref([])
  785. const singleCheck = async ({ row }) => {
  786. let isCheck = false
  787. let checkrow = JSON.parse(JSON.stringify(row))
  788. if (checkrow.checked === false || checkrow.checked === undefined) {
  789. if (checkList.value.length > 0) {
  790. let arr = checkList.value.filter(e => e.id === checkrow.id)
  791. if (arr.length > 0) {
  792. window.$message.warning('多个盒子不能选择同一份文件')
  793. await nextTick()
  794. sorTableRef.value[tableindex.value].toggleRowSelection(row, false)
  795. isCheck = true
  796. } else {
  797. isCheck = false
  798. row.tableindex = tableindex.value
  799. checkList.value.push(row)
  800. }
  801. } else {
  802. row.tableindex = tableindex.value
  803. checkList.value.push(row)
  804. }
  805. } else {
  806. let arr = checkList.value.filter(e => e.id === checkrow.id)
  807. if (isCheck === false && arr[0]?.checked === true || isCheck) {
  808. arrfliter.value = checkList.value.filter(e => e.id !== checkrow.id)
  809. } else {
  810. arrfliter.value = checkList.value
  811. }
  812. let newarr = []
  813. arrfliter.value.forEach((item) => {
  814. newarr.push(JSON.parse(JSON.stringify(item)))
  815. })
  816. checkList.value = newarr
  817. }
  818. }
  819. const sortingTableSelection = (rows, list, index) => {
  820. tableindex.value = index
  821. if (list) {
  822. list.forEach(element => {
  823. element.checked = false
  824. })
  825. }
  826. rows.forEach((element) => {
  827. element.checked = true
  828. })
  829. }
  830. //删除
  831. const sortingDelData = (row, index) => {
  832. sortingItemData.value.splice(index, 1)
  833. console.log(checkList.value, 'checkList.value')
  834. // checkList.value=[]
  835. //过滤掉当前选择的文件
  836. checkList.value = checkList.value.filter(e => e.tableindex !== index)
  837. if (row.boxNumber) {
  838. HcDelMsg(async (resolve) => {
  839. const { error, code } = await archiveFileApi.removeAllocation({
  840. boxName: row.boxName,
  841. boxNumber: row.boxNumber,
  842. })
  843. if (!error && code === 200) {
  844. window.$message?.success('删除成功!')
  845. sortingClick()
  846. }
  847. resolve() //关闭弹窗的回调
  848. })
  849. }
  850. }
  851. //添加分盒
  852. const addSortingModalClick = () => {
  853. console.log('添加分盒')
  854. sortingItemData.value.push({
  855. boxName: '',
  856. })
  857. }
  858. //确认保存
  859. const sortingModalLoading = ref(false)
  860. const sortingModalSave = async () => {
  861. sortingModalLoading.value = true
  862. //检测案卷名是否重复
  863. let nameRes = await checkNames()
  864. //console.log(nameRes)
  865. //return;
  866. for (let i = 0; i < nameRes.length; i++) {
  867. if (typeof nameRes[i].data == 'string') {
  868. window.$message?.error(nameRes[i].data + ',案卷名重复')
  869. sortingModalLoading.value = false
  870. return
  871. }
  872. }
  873. //组装数据
  874. let rows = []
  875. sortingItemData.value.forEach((item, index) => {
  876. let obj = {
  877. ids: '',
  878. boxName: item.boxName,
  879. boxNumber: index + 1,
  880. }
  881. let list = []
  882. if (item.list) {
  883. item.list.forEach((item2) => {
  884. if (item2.checked) {
  885. list.push(item2.id)
  886. }
  887. })
  888. obj.ids = list.join(',')
  889. } else {
  890. obj.ids = item.ids
  891. }
  892. rows.push(obj)
  893. })
  894. console.log(rows, 'rows')
  895. if (rows[0]?.ids) {
  896. const { error, code, data } = await archiveFileApi.allocation({
  897. list: rows,
  898. })
  899. if (!error && code === 200) {
  900. window.$message?.success('保存成功')
  901. sortingModal.value = false
  902. } else {
  903. window.$message?.error('保存失败')
  904. }
  905. } else {
  906. window.$message?.warning('空数据不能提交')
  907. }
  908. sortingModalLoading.value = false
  909. }
  910. const checkNames = () => {
  911. const arr = []
  912. sortingItemData.value.forEach((item) => {
  913. if (item.boxNumber) {
  914. if (item.isChange) {
  915. //是否修改过
  916. //对比旧的数据,是否相同
  917. for (let i = 0; i < sortingOldData.value.length; i++) {
  918. if (sortingOldData.value[i].boxNumber == item.boxNumber) {
  919. if (sortingOldData.value[i].boxName != item.boxName) {
  920. arr.push(
  921. archiveFileApi.getIsBoxName({
  922. boxName: item.boxName,
  923. }),
  924. )
  925. }
  926. return
  927. }
  928. }
  929. }
  930. } else {
  931. arr.push(
  932. archiveFileApi.getIsBoxName({
  933. boxName: item.boxName,
  934. }),
  935. )
  936. }
  937. })
  938. return Promise.all(arr)
  939. }
  940. //关闭
  941. const sortingModalClose = () => {
  942. sortingModal.value = false
  943. }
  944. //删除
  945. const delModalClick = () => {
  946. const rows = tableCheckedKeys.value
  947. //待审批,已审批都不能删除 豆海涛说,先取消限制
  948. /*const result = rows.some(({ isApprovalValue }) => {
  949. return isApprovalValue === '待审批' || isApprovalValue === '已审批'
  950. })
  951. if (result) {
  952. window.$message.warning('待审批或者已审批的文件都不能删除')
  953. return
  954. }
  955. if (rows.length <= 0) {
  956. window.$message?.error('请选择需要删除的数据')
  957. } else {
  958. HcDelMsg(async (resolve) => {
  959. const keys = arrToId(rows)
  960. const { error, code } = await archiveFileApi.removeFile({
  961. ids: keys,
  962. })
  963. if (!error && code === 200) {
  964. window.$message?.success('删除成功!')
  965. searchClick()
  966. }
  967. resolve() //关闭弹窗的回调
  968. })
  969. }*/
  970. HcDelMsg(async (resolve) => {
  971. const keys = arrToId(rows)
  972. const { error, code } = await archiveFileApi.removeFile({
  973. ids: keys,
  974. })
  975. if (!error && code === 200) {
  976. window.$message?.success('删除成功!')
  977. searchClick()
  978. }
  979. resolve() //关闭弹窗的回调
  980. })
  981. }
  982. //废除
  983. const repealModalClick = async () => {
  984. const rows = tableCheckedKeys.value
  985. if (rows.length <= 0) {
  986. window.$message?.error('请选择需要废除的数据')
  987. } else {
  988. window?.$messageBox?.alert('请谨慎考虑后,确认是否需要废除?', '废除提醒', {
  989. showCancelButton: true,
  990. confirmButtonText: '确认废除',
  991. cancelButtonText: '取消',
  992. type: 'warning',
  993. callback: async (action, instance, done) => {
  994. if (action === 'confirm') {
  995. instance.confirmButtonLoading = true
  996. const keys = arrToId(rows)
  997. const { error, code } = await tasksFlowApi.batchRepealTaskArchive({
  998. ids: keys,
  999. type: 1,
  1000. projectId: projectId.value,
  1001. contractId: contractId.value,
  1002. })
  1003. if (!error && code === 200) {
  1004. window.$message?.success('废除成功!')
  1005. searchClick()
  1006. }
  1007. instance.confirmButtonLoading = false
  1008. done()
  1009. } else {
  1010. done()
  1011. }
  1012. },
  1013. })
  1014. }
  1015. }
  1016. //跨目录移动
  1017. const movesModal = ref(false)
  1018. const movesClick = async () => {
  1019. movesModal.value = true
  1020. checkedMoves.value = []
  1021. movesCheckAll.value = false
  1022. treePanelLoading.value = true
  1023. fileDatasListLoading.value = true
  1024. const { error, code, data } = await archiveFileApi.getarchiveFilePage({
  1025. ...searchForm.value,
  1026. current: 1,
  1027. size: 50000,
  1028. projectId: projectId.value,
  1029. contractId: contractId.value,
  1030. })
  1031. fileDatasListLoading.value = false
  1032. if (!error && code === 200) {
  1033. fileDatasList.value = getArrValue(data['records'])
  1034. } else {
  1035. fileDatasList.value = []
  1036. }
  1037. }
  1038. //选择需要迁移的文件
  1039. const movesCheckAll = ref(false)
  1040. const isIndeterminate = ref(true)
  1041. const checkedMoves = ref([])
  1042. //左侧待迁移文件
  1043. const fileDatasList = ref([])
  1044. const fileDatasListLoading = ref(false)
  1045. //全选
  1046. const handleCheckAllChange = (val) => {
  1047. console.log(val, 'val')
  1048. const checked = fileDatasList.value
  1049. checkedMoves.value = val ? checked : []
  1050. isIndeterminate.value = false
  1051. }
  1052. //勾选
  1053. const handleCheckedMovesChange = (value) => {
  1054. const keys = fileDatasList.value
  1055. const checkedCount = value.length
  1056. movesCheckAll.value = checkedCount === keys.length
  1057. isIndeterminate.value = checkedCount > 0 && checkedCount < keys.length
  1058. }
  1059. //右侧radio
  1060. let radioNodeId = ''
  1061. const radioChange = (id) => {
  1062. //console.log(id)
  1063. radioNodeId = id
  1064. }
  1065. //只显示储存节点的单选
  1066. const showRadioFun = (data) => {
  1067. if (data.isStorageNode == 1) {
  1068. return true
  1069. } else {
  1070. return false
  1071. }
  1072. }
  1073. //保存
  1074. const movesModalLoading = ref(false)
  1075. const movesModalSave = async () => {
  1076. const keys = rowsToId(checkedMoves.value)
  1077. let ids = keys
  1078. if (checkedMoves.value.length < 1) {
  1079. window.$message?.warning('请勾选需要迁移的文件')
  1080. return
  1081. }
  1082. if (radioNodeId == '') {
  1083. window.$message?.warning('请选择要移动到的节点')
  1084. return
  1085. }
  1086. movesModalLoading.value = true
  1087. const { error, code, data } = await archiveFileApi.migrateFile({
  1088. ids: ids,
  1089. nodeId: radioNodeId,
  1090. })
  1091. movesModalLoading.value = false
  1092. if (!error && code === 200) {
  1093. window.$message?.success('保存成功')
  1094. movesModal.value = false
  1095. getTableData()
  1096. } else {
  1097. window.$message?.error('保存失败')
  1098. }
  1099. }
  1100. //关闭
  1101. const movesModalClose = () => {
  1102. movesModal.value = false
  1103. }
  1104. //表格排序
  1105. const sortModal = ref(false)
  1106. //显示
  1107. const tableSortClick = () => {
  1108. sortModal.value = true
  1109. getSortTableData()
  1110. }
  1111. //搜索表单
  1112. const sortSearchForm = ref({
  1113. nodeIds: '',
  1114. current: 1, size: 20, total: 0,
  1115. })
  1116. //分页被点击
  1117. const sortPageChange = ({ current, size }) => {
  1118. sortSearchForm.value.current = current
  1119. sortSearchForm.value.size = size
  1120. getSortTableData()
  1121. }
  1122. //表格数据
  1123. const sortTableColumn = ref([
  1124. { key: 'fileNumber', name: '文件编号', width: 160 },
  1125. { key: 'fileName', name: '文件名称' },
  1126. { key: 'action', name: '排序', width: 90 },
  1127. ])
  1128. const sortTableData = ref([])
  1129. const sortTableLoading = ref(false)
  1130. const getSortTableData = async () => {
  1131. sortTableLoading.value = true
  1132. const { error, code, data } = await archiveFileApi.getarchiveFilePage({
  1133. ...sortSearchForm.value,
  1134. projectId: projectId.value,
  1135. contractId: contractId.value,
  1136. })
  1137. sortTableLoading.value = false
  1138. if (!error && code === 200) {
  1139. sortTableData.value = getArrValue(data['records'])
  1140. sortSearchForm.value.total = data['total'] || 0
  1141. } else {
  1142. sortTableData.value = []
  1143. sortSearchForm.value.total = 0
  1144. }
  1145. }
  1146. //拖动完成
  1147. const sortTableRowDrop = (rows) => {
  1148. sortTableData.value = [] // 先清空,否则排序会异常
  1149. nextTick(() => {
  1150. sortTableData.value = rows
  1151. })
  1152. }
  1153. //向下
  1154. const downSortClick = (index) => {
  1155. const indexs = index + 1
  1156. const data = sortTableData.value
  1157. if (indexs !== data.length) {
  1158. const tmp = data.splice(indexs, 1)
  1159. sortTableData.value.splice(index, 0, tmp[0])
  1160. } else {
  1161. window?.$message?.warning('已经处于置底,无法下移')
  1162. }
  1163. }
  1164. //向上
  1165. const upSortClick = (index) => {
  1166. const data = sortTableData.value || []
  1167. if (index !== 0) {
  1168. const tmp = data.splice(index - 1, 1)
  1169. sortTableData.value.splice(index, 0, tmp[0])
  1170. } else {
  1171. window?.$message?.warning('已经处于置顶,无法上移')
  1172. }
  1173. }
  1174. //保存
  1175. const sortModalLoading = ref(false)
  1176. const sortModalSave = async () => {
  1177. await batchEditSaveApi(sortTableData.value)
  1178. sortModal.value = false
  1179. }
  1180. //关闭
  1181. const sortModalClose = () => {
  1182. sortModal.value = false
  1183. }
  1184. //获取认证状态
  1185. const certificationType = ref([])
  1186. const certificationStatus = async () => {
  1187. const { error, code, data } = await tasksApi.queryTaskTypeStatus({
  1188. typeOrStatus: 'certification_status',
  1189. })
  1190. //处理数据
  1191. if (!error && code === 200) {
  1192. certificationType.value = getArrValue(data)
  1193. } else {
  1194. certificationType.value = []
  1195. }
  1196. }
  1197. //获取图幅类型
  1198. const sheetType = ref([])
  1199. const sheetTypeStatus = async () => {
  1200. console.log(1111111)
  1201. const { error, code, data } = await tasksApi.queryTaskTypeStatus({
  1202. typeOrStatus: 'sheet_type',
  1203. })
  1204. //处理数据
  1205. if (!error && code === 200) {
  1206. sheetType.value = getArrValue(data)
  1207. } else {
  1208. sheetType.value = []
  1209. }
  1210. }
  1211. //获取图表来源
  1212. const sheetSourceType = ref([])
  1213. const sheetSourceStatus = async () => {
  1214. const { error, code, data } = await tasksApi.queryTaskTypeStatus({
  1215. typeOrStatus: 'sheet_source',
  1216. })
  1217. //处理数据
  1218. if (!error && code === 200) {
  1219. sheetSourceType.value = getArrValue(data)
  1220. } else {
  1221. sheetSourceType.value = []
  1222. }
  1223. }
  1224. //新增文件
  1225. const tableUploadType = ref('add')
  1226. const showUploadModal = ref(false)
  1227. const uploadModalClick = () => {
  1228. if (nodeIds.value && isStorageNode.value === 1) {
  1229. tableUploadType.value = 'add'
  1230. setTableUploadColumn()
  1231. uploadSaveLoading.value = false
  1232. tableUploadData.value = []
  1233. showUploadModal.value = true
  1234. setdutyUser()
  1235. } else {
  1236. window?.$message?.warning('请先选择一个子节点')
  1237. }
  1238. }
  1239. const uploadModalClose = () => {
  1240. batchUploadCancel()
  1241. }
  1242. //设置文件表头
  1243. const tableUploadColumn = ref([
  1244. { key: 'fileNumber', name: '文件编号' },
  1245. { key: 'fileName', name: '文件名称' },
  1246. { key: 'fileTime', name: '文件时间' },
  1247. { key: 'isApproval', name: '是否需要审批' },
  1248. { key: 'isNeedCertification', name: '是否需要认证' },
  1249. { key: 'dutyUser', name: '责任者' },
  1250. { key: 'isElement', name: '是否四要素' },
  1251. { key: 'action', name: '操作', width: 180 },
  1252. ])
  1253. const setTableUploadColumn = () => {
  1254. if (isBuiltDrawing.value === 2) {
  1255. tableUploadColumn.value = [
  1256. { key: 'fileNumber', name: '文件编号' },
  1257. { key: 'fileName', name: '文件名称' },
  1258. { key: 'fileTime', name: '文件时间' },
  1259. { key: 'sheetType', name: '图幅' },
  1260. { key: 'sheetSource', name: '图表来源' },
  1261. { key: 'drawingNo', name: '图号' },
  1262. { key: 'citeChangeNumber', name: '引用变更令编号' },
  1263. { key: 'isApproval', name: '是否需要审批' },
  1264. { key: 'isNeedCertification', name: '是否需要认证' },
  1265. { key: 'dutyUser', name: '责任者' },
  1266. { key: 'isElement', name: '是否四要素' },
  1267. { key: 'action', name: '操作', width: 180 },
  1268. ]
  1269. sheetTypeStatus()
  1270. sheetSourceStatus()
  1271. } else {
  1272. tableUploadColumn.value = [
  1273. { key: 'fileNumber', name: '文件编号' },
  1274. { key: 'fileName', name: '文件名称' },
  1275. { key: 'fileTime', name: '文件时间' },
  1276. { key: 'isApproval', name: '是否需要审批' },
  1277. { key: 'isNeedCertification', name: '是否需要认证' },
  1278. { key: 'dutyUser', name: '责任者' },
  1279. { key: 'isElement', name: '是否四要素' },
  1280. { key: 'action', name: '操作', width: 180 },
  1281. ]
  1282. }
  1283. }
  1284. const tableUploadData = ref([])
  1285. //上传的文件结果
  1286. const uploadsChange = (fileId, item) => {
  1287. if (getObjVal(item)) {
  1288. let newArr = tableUploadData.value
  1289. const sheet = sheetType.value, source = sheetSourceType.value
  1290. let name = item['originalName'] || ''
  1291. let fileName = name.substring(0, name.lastIndexOf('.'))
  1292. newArr.push({
  1293. fileUploadId: fileId,
  1294. projectId: projectId.value,
  1295. contractId: contractId.value,
  1296. nodeId: nodeIds.value,
  1297. fileNumber: '',
  1298. fileName: fileName,
  1299. ossFileName: item?.name || '',
  1300. fileTime: null,
  1301. fileUrl: item?.link || '',
  1302. sheetType: sheet.length > 0 ? sheet[0]['dictKey'] || '' : '',
  1303. sheetSource: source.length > 0 ? source[0]['dictKey'] || '' : '',
  1304. drawingNo: '',
  1305. citeChangeNumber: '',
  1306. isApproval: 0,
  1307. isNeedCertification: 1,
  1308. dutyUser: dutyUser.value,
  1309. pdfFileUrl: item?.pdfUrl || '',
  1310. filePage: item?.page || '',
  1311. isElement: 0,
  1312. isUpdateUrl: 0,
  1313. fileSize: item?.fileSize,
  1314. })
  1315. //tableUploadData.value = newArr
  1316. tableUploadData.value = arrKeySort(newArr, 'fileUploadId')
  1317. } else {
  1318. console.log(item)
  1319. }
  1320. }
  1321. //表单下拉数据
  1322. const whetherData = ref([
  1323. { label: '不需要', value: 0 },
  1324. { label: '需要', value: 1 },
  1325. ])
  1326. //表格数据排序
  1327. const tableUploadRowSort = (arr) => {
  1328. tableUploadData.value = arr
  1329. }
  1330. //删除
  1331. const delUploadData = async (row, index) => {
  1332. if (row['ossFileName']) {
  1333. row['delBtnLoading'] = true
  1334. await ossApi.removeFile({ fileName: row['ossFileName'] })
  1335. row['delBtnLoading'] = false
  1336. tableUploadData.value.splice(index, 1)
  1337. } else {
  1338. tableUploadData.value.splice(index, 1)
  1339. }
  1340. }
  1341. //批量上传保存
  1342. const uploadSaveLoading = ref(false)
  1343. const batchUploadSave = async () => {
  1344. const rows = tableUploadData.value
  1345. if (rows.length > 0) {
  1346. //验证表单数据
  1347. uploadSaveLoading.value = true
  1348. let isTableRows = false
  1349. for (let i = 0; i < rows.length; i++) {
  1350. // if (!rows[i]['fileNumber']) {
  1351. // rows[i]['isFileNumber'] = true
  1352. // isTableRows = true
  1353. // } else if (!rows[i]['fileName']) {
  1354. // rows[i]['isFileName'] = true
  1355. // isTableRows = true
  1356. // }
  1357. // if (!rows[i]['fileTime']) {
  1358. // rows[i]['isFileTime'] = true
  1359. // isTableRows = true
  1360. // }
  1361. // else
  1362. if (!rows[i]['fileName']) {
  1363. rows[i]['isFileName'] = true
  1364. isTableRows = true
  1365. }
  1366. }
  1367. //判断数据
  1368. if (isTableRows) {
  1369. uploadSaveLoading.value = false
  1370. window.$message?.warning('请先完善表单信息')
  1371. } else {
  1372. if (tableUploadType.value === 'add') {
  1373. await batchUploadSaveApi(rows)
  1374. } else {
  1375. await batchEditSaveApi(rows)
  1376. }
  1377. }
  1378. } else {
  1379. window.$message?.warning('请先上传文件')
  1380. }
  1381. }
  1382. //确认上传保存
  1383. const batchUploadSaveApi = async (rows) => {
  1384. uploadSaveLoading.value = true
  1385. const { error, code } = await archiveFileApi.batchUploadSave({
  1386. list: rows,
  1387. }, false)
  1388. //判断状态
  1389. uploadSaveLoading.value = false
  1390. if (!error && code === 200) {
  1391. window.$message?.success('保存成功')
  1392. batchUploadCancel()
  1393. getTableData()
  1394. } else {
  1395. window.$message?.error('保存失败')
  1396. }
  1397. }
  1398. //取消上传
  1399. const batchUploadCancel = () => {
  1400. tableUploadData.value = []
  1401. uploadSaveLoading.value = false
  1402. uploadsLoading.value = false
  1403. showUploadModal.value = false
  1404. }
  1405. //上传新文件
  1406. // const newUploadsChange = ({fileList}, row) => {
  1407. // if (fileList.length > 0) {
  1408. // tableUploadType.value = 'edit'
  1409. // const item = fileList[0]
  1410. // const name = item['originalName'] || ''
  1411. // const fileName = name.substring(0, name.lastIndexOf("."))
  1412. // //更新数据
  1413. // row.fileName = fileName;
  1414. // row.ossFileName = item?.name || ''
  1415. // row.fileUrl = item?.link || ''
  1416. // row.pdfFileUrl = item?.pdfUrl || ''
  1417. // row.filePage = item?.page || ''
  1418. // row.isUpdateUrl=1
  1419. // }
  1420. // }
  1421. // const newUploadsProgress = (val, row) => {
  1422. // row.newBtnLoading = val
  1423. // }
  1424. //批量编辑
  1425. const batchEditClick = () => {
  1426. const rows = deepClone(tableCheckedKeys.value)
  1427. //判断是否满足条件 豆海涛说,先取消限制
  1428. /*const result = rows.every(({ status }) => {
  1429. return status !== 1 && status !== 2
  1430. })
  1431. //判断状态
  1432. if (result) {
  1433. tableUploadType.value = 'edit'
  1434. setTableUploadColumn()
  1435. uploadSaveLoading.value = false
  1436. tableUploadData.value = rows
  1437. showUploadModal.value = true
  1438. } else {
  1439. window.$message?.warning('已上报或已审批的文件不能编辑')
  1440. }*/
  1441. tableUploadType.value = 'edit'
  1442. setTableUploadColumn()
  1443. uploadSaveLoading.value = false
  1444. tableUploadData.value = rows
  1445. showUploadModal.value = true
  1446. }
  1447. //确认编辑上传保存
  1448. const batchEditSaveApi = async (rows) => {
  1449. uploadSaveLoading.value = true
  1450. const { error, code } = await archiveFileApi.batchUpdateSort({
  1451. list: rows,
  1452. }, false)
  1453. //判断状态
  1454. uploadSaveLoading.value = false
  1455. if (!error && code === 200) {
  1456. window.$message?.success('保存成功')
  1457. batchUploadCancel()
  1458. getTableData()
  1459. } else {
  1460. window.$message?.error('保存失败')
  1461. }
  1462. }
  1463. //批量认证
  1464. const CertData = ref([])
  1465. const CertIds = ref([])
  1466. const CertPdf = ref('')
  1467. const CertColumns = [
  1468. { key: 'fileName', name: '文件名称' },
  1469. { key: 'action', name: '操作', width: 100 },
  1470. ]
  1471. //批量认证弹窗
  1472. const showCertificationModal = ref(false)
  1473. const certificationModalClick = () => {
  1474. const rows = tableCheckedKeys.value
  1475. CertData.value = rows
  1476. CertIds.value = rowsToId(rows)
  1477. CertPdf.value = rows[0]?.pdfFileUrl || ''
  1478. const result = rows.every(({ isCertification }) => {
  1479. return isCertification === 0
  1480. })
  1481. const result1 = rows.every(({ status }) => {
  1482. return status === 0 || status === 3
  1483. })//已上报不能认证
  1484. if (!result1) {
  1485. window.$message.warning('已上报的文件不能进行认证')
  1486. } else {
  1487. if (result) {
  1488. CertData.value = rows
  1489. CertIds.value = rowsToId(rows)
  1490. CertPdf.value = rows[0]?.pdfFileUrl || ''
  1491. showCertificationModal.value = true
  1492. } else {
  1493. window.$message?.warning('已认证的文件不能再认证')
  1494. }
  1495. }
  1496. }
  1497. //认证行被点击
  1498. const CertRowClick = ({ row }) => {
  1499. const pdfFileUrl = row?.pdfFileUrl || ''
  1500. if (CertPdf.value !== pdfFileUrl) {
  1501. CertPdf.value = pdfFileUrl
  1502. }
  1503. }
  1504. //认证预览被点击
  1505. const CertRowClick2 = ({ pdfFileUrl }) => {
  1506. const pdfUrl = pdfFileUrl || ''
  1507. if (CertPdf.value !== pdfUrl) {
  1508. CertPdf.value = pdfUrl
  1509. }
  1510. }
  1511. //确认认证
  1512. const CertLoading = ref(false)
  1513. const CertClick = async () => {
  1514. CertLoading.value = true
  1515. const { error, code, msg } = await tasksFlowApi.batchCertification({
  1516. ids: CertIds.value,
  1517. }, false)
  1518. //判断状态
  1519. CertLoading.value = false
  1520. if (!error && code === 200) {
  1521. window.$message?.success('认证成功')
  1522. showCertificationModal.value = false
  1523. searchClick()
  1524. } else {
  1525. window.$message?.error(msg)
  1526. }
  1527. }
  1528. //名称被点击
  1529. const tableRowName = (row) => {
  1530. console.log(row, 'row')
  1531. if (row?.isCertificationValue === '已认证' || row?.isApprovalValue === '已审批') {
  1532. if (row['eVisaFile']) {
  1533. toPdfPage(row['eVisaFile'])
  1534. //window.open(row['eVisaFile'], '_blank')
  1535. } else if (row['pdfFileUrl']) {
  1536. toPdfPage(row['pdfFileUrl'])
  1537. //window.open(row['pdfFileUrl'], '_blank')
  1538. } else {
  1539. window.$message?.warning('文件不存在')
  1540. }
  1541. } else {
  1542. if (row['pdfFileUrl']) {
  1543. toPdfPage(row['pdfFileUrl'])
  1544. //window.open(row['pdfFileUrl'], '_blank')
  1545. } else {
  1546. window.$message?.warning('文件不存在')
  1547. }
  1548. }
  1549. }
  1550. //上报
  1551. const isReport = ref(false)
  1552. const reportData = ref([])
  1553. const reportModalClick = () => {
  1554. reportData.value = []
  1555. const rows = tableCheckedKeys.value
  1556. //判断是否满足条件
  1557. const result = rows.every(({ status }) => {
  1558. return status === 0 || status === 3
  1559. })
  1560. const result1 = rows.every(({ isCertification }) => {
  1561. return isCertification === 1
  1562. })
  1563. if (result1) {
  1564. window.$message?.warning('已认证的文件不能进行上报')
  1565. return false
  1566. } else {
  1567. if (!result) {
  1568. window.$message?.warning('已上报的文件不能进行再次上报')
  1569. return false
  1570. }
  1571. }
  1572. rows.sort((a, b) => a.sort - b.sort)
  1573. //展示上报弹窗
  1574. reportData.value = rows
  1575. console.log(reportData.value, ' reportData.valu')
  1576. isReport.value = true
  1577. }
  1578. //上报完成
  1579. const reportFinish = () => {
  1580. searchClick()
  1581. }
  1582. //在线验签
  1583. const onlineLoading = ref(false)
  1584. const onlineVerifyData = ref({})
  1585. const isOnlineVerifyDrawer = ref(false)
  1586. const onlineVerifyOptions = {
  1587. sizes: [50, 50],
  1588. snapOffset: 0,
  1589. minSize: ['10%', '80%'],
  1590. }
  1591. const batchOnline = async () => {
  1592. const rows = tableCheckedKeys.value
  1593. if (rows.length > 1) {
  1594. window.$message?.warning('在线验签只能勾选一条数据进行验签')
  1595. return
  1596. }
  1597. //判断是否满足条件
  1598. const result = rows.every(({ status }) => {
  1599. return status === 2
  1600. })
  1601. //判断状态
  1602. if (!result) {
  1603. window.$message?.warning('存在未审批或未上报数据')
  1604. return
  1605. }
  1606. //发起请求
  1607. //const ids = arrToId(rows)
  1608. onlineLoading.value = true
  1609. /*const { error, code, msg, data } = await queryApi.onlineVerify({
  1610. ids: ids,
  1611. })
  1612. //处理数据
  1613. onlineLoading.value = false
  1614. if (!error && code === 200) {
  1615. onlineVerifyData.value = getObjValue(data)
  1616. //cscTableData.value = getArrValue(data['certBeanVOList'])
  1617. isOnlineVerifyDrawer.value = true
  1618. } else {
  1619. onlineVerifyData.value = {}
  1620. window.$message?.error(msg ?? '操作失败')
  1621. }*/
  1622. onlineVerifyData.value = {}
  1623. isOnlineVerifyDrawer.value = true
  1624. }
  1625. //签名信息
  1626. const cscTableColumn = [
  1627. { key: 'user', name: '签名者', width: 300 },
  1628. { key: 'time', name: '签名时间', width: 200 },
  1629. { key: 'val', name: '摘要' },
  1630. ]
  1631. const cscTableData = ref([])
  1632. //在线验签抽屉被关闭
  1633. const onlineVerifyDrawerClose = () => {
  1634. isOnlineVerifyDrawer.value = false
  1635. onlineLoading.value = false
  1636. }
  1637. //处理时间
  1638. const getTableFileTime = (time) => {
  1639. if (isNullES(time)) return ''
  1640. return time.replace(/-/g, '')
  1641. }
  1642. </script>
  1643. <style lang="scss">
  1644. @import '~style/file/collection.scss';
  1645. //在线验签
  1646. .hc-online-verify-drawer .el-card.hc-new-card-box {
  1647. .hc-card-header-box {
  1648. .online-verify-title {
  1649. font-size: 20px;
  1650. }
  1651. .online-verify-icon {
  1652. display: flex;
  1653. align-items: center;
  1654. cursor: pointer;
  1655. color: #5a5959;
  1656. i {
  1657. font-size: 18px;
  1658. }
  1659. &:hover {
  1660. color: var(--el-color-primary);
  1661. }
  1662. }
  1663. }
  1664. }
  1665. html.dark .hc-online-verify-drawer .el-card.hc-new-card-box {
  1666. background-color: var(--hc-bg-color);
  1667. .hc-card-header-box {
  1668. .online-verify-icon {
  1669. color: var(--el-color-primary);
  1670. }
  1671. }
  1672. }
  1673. </style>