test.vue 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573
  1. <template>
  2. <div class="hc-layout-box">
  3. <div
  4. id="wbs-left-tree" :style="`width:${isWbsTreeShow ? leftWidth : 0}px; ${isWbsTreeShow ? '' : 'display: none'}`"
  5. class="hc-layout-left-box bg-white" :class="[isWbsTreeShow ? 'show' : '']"
  6. >
  7. <div class="hc-project-box">
  8. <div class="hc-project-icon-box">
  9. <HcIcon name="stack" />
  10. </div>
  11. <div class="project-name-box ml-2">
  12. <div class="project-alias">{{ projectInfo?.projectName }}</div>
  13. </div>
  14. </div>
  15. <div class="hc-tree-box">
  16. <div class="hc-search-tree-val">
  17. <el-input v-model="searchTreeVal" clearable block placeholder="请输入名称关键词检索" @keyup="searchTreeKeyUp">
  18. <template #suffix>
  19. <HcIcon name="search-2" ui="text-xl iscusor" @click="searchTreeClick" />
  20. </template>
  21. </el-input>
  22. </div>
  23. <div v-if="isShowLeft" id="hc-tree-scrollbar" v-loading="treeLoading" class="hc-tree-scrollbar" element-loading-text="获取数据中...">
  24. <el-scrollbar v-show="isSearchTree" class="scroll-bar-right-16">
  25. <HcDataTree
  26. :datas="searchTreeData"
  27. is-counts
  28. is-type
  29. :auto-expand-keys="treeAutoExpandKeys"
  30. default-expand-all
  31. :menus="treeMenus"
  32. @node-tap="wbsElTreeClick"
  33. @menu-tap="ElTreeMenuClick"
  34. />
  35. </el-scrollbar>
  36. <el-scrollbar v-show="!isSearchTree" class="scroll-bar-right-16">
  37. <HcLazyTree
  38. ref="wbstree"
  39. :auto-expand-keys="treeAutoExpandKeys"
  40. is-counts
  41. is-type
  42. :menus="treeMenus"
  43. @load="treeLoadNode"
  44. @node-tap="wbsElTreeClick"
  45. @menu-tap="ElTreeMenuClick"
  46. />
  47. </el-scrollbar>
  48. </div>
  49. </div>
  50. <div class="hc-tree-foot-tip-box">
  51. <div class="dot-view green">已审批</div>
  52. <div class="dot-view black">未填报</div>
  53. <div class="dot-view orange">已填报-待审批</div>
  54. <div class="dot-view blue">已填报-未上报</div>
  55. <div class="dot-view red">已隐藏</div>
  56. </div>
  57. <!-- 左右拖动 -->
  58. <div class="horizontal-drag-line" @mousedown="onmousedown" />
  59. </div>
  60. <div class="hc-layout-content-box">
  61. <hc-body padding="0px">
  62. <!---展开收缩树 -->
  63. <div class="hc-expansion-contraction-tree" @click="setWbsTreeShow">
  64. <HcIcon v-show="isWbsTreeShow" name="arrow-left-s" />
  65. <HcIcon v-show="!isWbsTreeShow" name="arrow-right-s" />
  66. </div>
  67. <div style="height: 70px" class="mb-2 flex justify-around">
  68. <hc-card>
  69. <div style="line-height: 26px;">
  70. <div>
  71. <div class="text-16px font-800">上报且审批</div>
  72. <div>暂无任务...</div>
  73. </div>
  74. </div>
  75. </hc-card>
  76. <hc-card class="ml-2">
  77. <div style="line-height: 26px;">
  78. <div>
  79. <div class="text-16px font-800">re-sign</div>
  80. <div>暂无任务...</div>
  81. </div>
  82. </div>
  83. </hc-card>
  84. <hc-card class="ml-2">
  85. <div style="line-height: 26px;">
  86. <div>
  87. <div class="text-16px font-800">save-sign</div>
  88. <div>暂无任务...</div>
  89. </div>
  90. </div>
  91. </hc-card>
  92. <hc-card class="ml-2">
  93. <div v-if="false" style="line-height: 26px;">
  94. <div>
  95. <div class="text-16px font-800">电签检测</div>
  96. <div>暂无任务...</div>
  97. </div>
  98. </div>
  99. <div v-else style="line-height: 26px;">
  100. <div>
  101. <div class="text-16px font-800">电签检测 </div>
  102. <div>
  103. <el-progress
  104. :text-inside="true"
  105. :stroke-width="24"
  106. :percentage="100"
  107. status="success"
  108. size="small"
  109. />
  110. <span>300/300</span>
  111. </div>
  112. </div>
  113. </div>
  114. </hc-card>
  115. </div>
  116. <HcNewCard padding class="basic-info-box">
  117. <template #header>
  118. <!-- <el-button :disabled="tableCheckedKeys.length <= 0" :loading="reportLoading" hc-btn color="#FF976A" style="color: white;" @click="reportModalClick">
  119. <HcIcon name="send-plane-2" />
  120. <span>上报</span>
  121. </el-button>
  122. <el-button :disabled="tableCheckedKeys.length <= 0" :loading="reportLoading" hc-btn color="#FF976A" style="color: white;" @click="reportModalClick">
  123. <HcIcon name="send-plane-2" />
  124. <span>上报且审批</span>
  125. </el-button> -->
  126. <!-- <el-button :disabled="tableCheckedKeys.length <= 0" :loading="signLoading" hc-btn type="primary" @click="resignClick"> <HcIcon name="repeat" />re-sign</el-button> -->
  127. <!-- <el-button
  128. :disabled="tableCheckedKeys.length <= 0" :loading="saveAginLoading" hc-btn
  129. color="#e03997" @click="saveAginClick"
  130. >
  131. <HcIcon name="save" />
  132. <span>save-again</span>
  133. </el-button>
  134. -->
  135. <el-button
  136. :disabled="tableCheckedKeys.length <= 0" hc-btn
  137. color="#52B200"
  138. style="color: white;"
  139. @click="batchOnlineClick"
  140. >
  141. <HcIcon name="folder-download" />
  142. <span>电签检测</span>
  143. </el-button>
  144. <!-- <el-button
  145. style="color: white;"
  146. :disabled="tableCheckedKeys.length <= 0" hc-btn
  147. color="#3F9EFF" @click="batchOnline"
  148. >
  149. <HcIcon name="file-list" />
  150. <span>任务列表</span>
  151. </el-button> -->
  152. </template>
  153. <template #search>
  154. <div class="flex items-center">
  155. <div class="w-32">
  156. <el-select v-model="searchForm.majorDateType" clearable placeholder="资料类型">
  157. <el-option
  158. v-for="item in majorDataTypeOptions"
  159. :key="item.value"
  160. :label="item.label"
  161. :value="item.value"
  162. />
  163. </el-select>
  164. </div>
  165. <div class="ml-2 w-40">
  166. <el-select v-model="searchForm.fileUserIdAndName" clearable placeholder="填报人">
  167. <el-option
  168. v-for="item in reportingPersonData" :key="item.value" :label="item.label"
  169. :value="item.value"
  170. />
  171. </el-select>
  172. </div>
  173. <div class="ml-2 w-40">
  174. <el-select v-model="searchForm.sourceType" clearable placeholder="文件类型">
  175. <el-option
  176. v-for="item in fileTypeData" :key="item.value" :label="item.dictValue"
  177. :value="item.dictKey"
  178. />
  179. </el-select>
  180. </div>
  181. <div class="ml-2 w-40">
  182. <el-select v-model="searchForm.taskStatus" clearable placeholder="流程状态">
  183. <el-option
  184. v-for="item in processStatusData" :key="item.value"
  185. :label="item.dictValue" :value="item.dictKey"
  186. />
  187. </el-select>
  188. </div>
  189. <div class="ml-2 w-40">
  190. <el-select v-model="searchForm.chekStatus" clearable placeholder="检测状态">
  191. <el-option :value="0" label="未检测" />
  192. <el-option :value="1" label="一体机" />
  193. <el-option :value="2" label="检测无误" />
  194. <el-option :value="3" label="检测有误" />
  195. </el-select>
  196. </div>
  197. <div class="ml-2 w-64">
  198. <HcDatePicker :dates="betweenTime" clearable @change="betweenTimeUpdate" />
  199. </div>
  200. <div class="ml-2 w-60">
  201. <el-input
  202. v-model="searchForm.queryValue" clearable placeholder="请输入名称关键词检索"
  203. @keyup="keyUpEvent"
  204. />
  205. </div>
  206. <div class="ml-2">
  207. <el-button type="primary" @click="searchClick">
  208. <HcIcon name="search-2" />
  209. <span>搜索</span>
  210. </el-button>
  211. </div>
  212. </div>
  213. </template>
  214. <template #extra>
  215. <template v-if="contractInfo?.contractType === 2 || contractInfo?.contractType === 3">
  216. <HcNewSwitch :datas="contractTypeTab" :keys="contractTypeTabKey" size="default" @change="contractTypeTabChange" />
  217. </template>
  218. </template>
  219. <HcTable
  220. ref="tableListRef" :column="tableListColumn" :datas="tableListData" :loading="tableLoading"
  221. is-new :index-style="{ width: 60 }" is-check :check-style="{ width: 29 }"
  222. @selection-change="tableSelectionChange"
  223. >
  224. <template #taskStatusStr="{ row }">
  225. <el-tag
  226. :type="`${row.taskStatusStr === '已审批' ? 'success' : row.taskStatusStr === '待审批' ? 'warning' : row.taskStatusStr === '已废除' ? 'danger' : 'info'}`"
  227. class="mx-1" effect="dark"
  228. >
  229. {{ row.taskStatusStr }}
  230. </el-tag>
  231. </template>
  232. <template #name="{ row }">
  233. <span v-loading="row?.bussPreviewLoading" class="text-link" @click="tableRowName(row)">{{ row?.name }}</span>
  234. </template>
  235. <template #chekStatus="{ row }">
  236. <el-tag
  237. :type="`${row.chekStatus === 2 ? 'success' : row.chekStatus === 0 ? 'warning' : row.taskStatusStr === 3 ? 'danger' : 'info'}`"
  238. class="mx-1" effect="dark"
  239. >
  240. {{ row.chekStatus === 0 ? '未检出' : row.chekStatus === 1 ? '已提交' : row.chekStatus === 2 ? '检测无误' : '检测有误' }}
  241. </el-tag>
  242. </template>
  243. </HcTable>
  244. <template #action>
  245. <div class="lr-dialog-footer">
  246. <div class="right">
  247. <HcPages :pages="searchForm" @change="pageChange" />
  248. </div>
  249. </div>
  250. </template>
  251. </HcNewCard>
  252. </hc-body>
  253. </div>
  254. <!-- 批量上报审批 -->
  255. <HcReportModal
  256. :ids="reportIds"
  257. :node-id="primaryKeyId"
  258. :table-owner="contractTypeTabKey"
  259. :classify-type="classType"
  260. :contract-id="contractId"
  261. :flow-contract-id="nodeDataInfo?.contractId"
  262. :datas="reportDatas"
  263. :project-id="projectId"
  264. :show="showReportModal"
  265. :task-name="reportTaskName"
  266. :type-data="reportTypeData"
  267. :report-arr="reportArr"
  268. type="query"
  269. is-datas
  270. title="批量上报审批"
  271. url="informationWriteQuery/batchTask"
  272. @finish="showReportFinish"
  273. @hide="showReportModal = false"
  274. @tag-close="reportTaskTagClose"
  275. />
  276. <!-- 在线验签 -->
  277. <hc-new-drawer v-model="isOnlineVerifyDrawer" modal-class="hc-online-verify-drawer" to-id="app" @close="onlineVerifyDrawerClose">
  278. <hc-new-card>
  279. <template #header>
  280. <div class="online-verify-title">{{ onlineTitle }}</div>
  281. </template>
  282. <template #extra>
  283. <div class="online-verify-icon" @click="onlineVerifyDrawerClose">
  284. <HcIcon name="close-circle" />
  285. <span class="ml-1">关闭</span>
  286. </div>
  287. </template>
  288. <hc-body split padding="0px" :options="onlineVerifyOptions">
  289. <template #left>
  290. <hc-new-card>
  291. <HcPdf :src="onlineVerifyData.pdfUrl" />
  292. </hc-new-card>
  293. </template>
  294. <hc-new-card>
  295. <HcTable :column="cscTableColumn" :datas="cscTableData" is-new :index-style="{ width: 60 }" />
  296. </hc-new-card>
  297. </hc-body>
  298. </hc-new-card>
  299. </hc-new-drawer>
  300. <!-- 一键重签弹窗 -->
  301. <hc-new-dialog v-model="resignModal" title="一键重签" widths="38rem" :loading="signLoading" @close="cancelresign" @save="signClick">
  302. <div>
  303. 是否重新生成pdf:
  304. <el-radio-group v-model="resignModalRadio">
  305. <el-radio :value="0">否</el-radio>
  306. <el-radio :value="1">是</el-radio>
  307. </el-radio-group>
  308. </div>
  309. </hc-new-dialog>
  310. <!-- 一键重签弹窗1 -->
  311. <hc-new-dialog v-model="resignModal1" title="一键重签" widths="38rem" :loading="signLoading1" @close="cancelresign1" @save="signClick1">
  312. <div>
  313. <el-radio-group v-model="resignModalRadio1">
  314. <el-radio :value="0">全部电签</el-radio>
  315. <el-radio :value="1" :disabled="tableCheckedKeys.length > 1">部分电签</el-radio>
  316. </el-radio-group>
  317. </div>
  318. <div v-if="resignModalRadio1 === 1">
  319. <el-checkbox-group v-model="checkTaskUserIds">
  320. <el-checkbox v-for="item in tableCheckedKeys[0].waitingUserList" :key="item.id" :label="item.waitingUserName" :value="item.userId">
  321. <el-tag
  322. :type="`${item.status === 2 ? 'success' : item.status === 3 ? 'warning' : item.status === 999 ? 'danger' : 'info'}`"
  323. class="mx-1" effect="dark"
  324. >
  325. {{ item.waitingUserName }}
  326. </el-tag>
  327. </el-checkbox>
  328. </el-checkbox-group>
  329. </div>
  330. </hc-new-dialog>
  331. <!-- 重置文件题名弹窗 -->
  332. <hc-new-dialog v-model="resignTitleModal" title="重置题名" widths="38rem" :loading="resignTitleSaveLoad" @save="resignTitleSave">
  333. <div>
  334. 是否更改题名规则:
  335. <el-button type="primary" hc-btn size="small" @click="changeRuleClick">规则更改</el-button>
  336. </div>
  337. </hc-new-dialog>
  338. <!-- 规则修改弹窗 -->
  339. <hc-new-dialog v-model="ruleModal" title="更改重置题名题名规则" widths="88rem" :loading="ruleModalSaveLoad" @close="ruleModalClose" @save="ruleModalSave">
  340. <template #header>
  341. <div class="flex flex-col">
  342. <div class="mb-4 text-18px">
  343. <span>更改重置题名题名规则</span>
  344. </div>
  345. <div class="flex justify-between justify-items-center text-orange">
  346. <p>* 单条修改在表单下拉框选择规则,批量修改在右侧选规则点击【设置】统一更新所有规则</p>
  347. <p>* “修改后”仅为展示,【确认】后才会刷新文件题名</p>
  348. </div>
  349. </div>
  350. </template>
  351. <div class="flex items-center justify-between">
  352. <div>批量设置:</div>
  353. <el-select
  354. v-model="setValue"
  355. placeholder="请选择"
  356. multiple
  357. clearable
  358. class="custom-select flex-1"
  359. :popper-append-to-body="false"
  360. >
  361. <el-option
  362. v-for="item in nodeTypeData"
  363. :key="item.value"
  364. :label="item.label"
  365. :value="item.value"
  366. />
  367. </el-select>
  368. <el-button type="primary" hc-btn size="small" class="ml-2" :disabled="setValue.length === 0" @click="batchSetRule">设置</el-button>
  369. </div>
  370. <div style="position: relative; height: 440px" class="mt-2">
  371. <HcTable v-loading="ruleTableLoading" :column="ruleTableColumn" :datas="ruleTableData" :loading="ruleTableLoading">
  372. <template #rule="{ row }">
  373. <div class="flex items-center">
  374. <span class="text-red">*</span>
  375. <el-select
  376. v-model="row.rule"
  377. :class="{ 'error-border': !row.rule || row.rule.length === 0 }"
  378. placeholder="请选择"
  379. multiple
  380. clearable
  381. class="custom-select"
  382. :popper-append-to-body="false"
  383. @change="ruleChange(row)"
  384. >
  385. <el-option
  386. v-for="item in nodeTypeData"
  387. :key="item.value"
  388. :label="item.label"
  389. :value="item.value"
  390. />
  391. </el-select>
  392. </div>
  393. </template>
  394. </HcTable>
  395. </div>
  396. </hc-new-dialog>
  397. </div>
  398. </template>
  399. <script setup>
  400. import { nextTick, onMounted, ref, watch } from 'vue'
  401. import { useAppStore } from '~src/store'
  402. import { getStoreValue, setStoreValue } from '~src/utils/storage'
  403. import { arrToId, arrToKey, downloadBlob, getArrValue, getObjValue, isNullES, isString } from 'js-fast-way'
  404. import queryApi from '~api/data-fill/query'
  405. import { eVisaTaskCheckApi } from '~api/other'
  406. import { toPdfPage } from '~uti/btn-auth'
  407. import wbsApi from '~api/data-fill/wbs'
  408. import website from '~src/config'
  409. import { getDictionaryData } from '~uti/tools'
  410. import { getDictionary, userConfigSave } from '~api/other'
  411. import { useClick } from 'hc-vue3-ui'
  412. //变量
  413. const useAppState = useAppStore()
  414. const projectId = ref(useAppState.getProjectId)
  415. const contractId = ref(useAppState.getContractId)
  416. const projectInfo = ref(useAppState.getProjectInfo)
  417. const contractInfo = ref(useAppState.getContractInfo)
  418. const userInfo = ref(useAppState.getUserInfo)
  419. const isCollapse = ref(useAppState.getCollapse)
  420. const isLayout = ref(useAppState.isLayout)
  421. const isTemplateType = ref(useAppState.contractInfo?.templateType === 2)
  422. //变量
  423. const wbstree = ref(null)
  424. const wbstreeKey = ref(Math.random())
  425. //树搜索
  426. const isSearchTree = ref(false)
  427. const searchTreeHeight = ref()
  428. const searchTreeVal = ref('')
  429. //监听
  430. watch(() => [useAppState.getCollapse, searchTreeVal.value, useAppState.isLayout], ([Collapse, search, isLay]) => {
  431. isCollapse.value = Collapse
  432. isLayout.value = isLay || ''
  433. if (search.length == 0) {
  434. isSearchTree.value = false
  435. }
  436. })
  437. //是否禁用下载打印按钮
  438. const isCanDown = ref(false)
  439. //自动展开缓存
  440. const treeAutoExpandKeys = ref(getStoreValue('wbsTreeExpandKeys') || [])
  441. //渲染完成
  442. onMounted(() => {
  443. getFileUser()
  444. getReportNumber()
  445. getFirstTaskStatus()
  446. getDictBizClassify()
  447. getMajorDataTypeOptions()
  448. isCanDown.value = !website.localModel
  449. const treeWidth = useAppState.getTreeWidth
  450. leftWidth.value = isNullES(treeWidth) || treeWidth <= 0 ? 440 : treeWidth
  451. })
  452. //获取
  453. const majorDataTypeOptions = ref([])
  454. const getMajorDataTypeOptions = async () => {
  455. majorDataTypeOptions.value = (await getDictionaryData('major_data_type', false)).filter(item => item.value !== 0)
  456. }
  457. const searchTreeData = ref([])
  458. //回车
  459. const treeLoading = ref(true)
  460. const getSearchTreeData = async () => {
  461. treeLoading.value = true
  462. const { error, code, data } = await queryApi.getTreeNodeByQueryValueAndContractId({
  463. contractId: contractId.value,
  464. queryValue: searchTreeVal.value,
  465. tableOwner:contractTypeTabKey.value,
  466. })
  467. //判断状态
  468. if (!error && code === 200) {
  469. let treedata = getArrValue(data)
  470. searchTreeData.value = treedata
  471. treeLoading.value = false
  472. } else {
  473. treeLoading.value = false
  474. searchTreeData.value = []
  475. }
  476. }
  477. //回车
  478. const searchTreeKeyUp = (e) => {
  479. if (e.key === 'Enter') {
  480. searchTreeClick()
  481. }
  482. }
  483. const searchTreeClick = async () => {
  484. if (searchTreeVal.value) {
  485. searchTreeHeight.value = document.getElementById('hc-tree-scrollbar').offsetHeight
  486. isSearchTree.value = true
  487. //treeLoading.value = true
  488. getSearchTreeData().then()
  489. } else {
  490. isSearchTree.value = false
  491. }
  492. }
  493. //树相关的变量
  494. const primaryKeyId = ref('')
  495. const nodeItemInfo = ref({})
  496. const nodeDataInfo = ref({})
  497. //懒加载的数据
  498. const treeLoadNode = async ({ node, item, level }, resolve) => {
  499. let contractIdRelation = '', parentId = '', primaryKeyId = ''
  500. if (level !== 0) {
  501. const nodeData = getObjValue(item)
  502. contractIdRelation = nodeData?.contractIdRelation || ''
  503. parentId = contractIdRelation ? nodeData?.primaryKeyId : nodeData?.id
  504. primaryKeyId = nodeData?.id || ''
  505. }
  506. //获取数据
  507. const { data } = await queryApi.queryWbsTreeData({
  508. contractId: contractId.value || '',
  509. contractIdRelation,
  510. primaryKeyId,
  511. parentId,
  512. // classifyType: contractTypeTabKey.value,
  513. classifyType: classType.value,
  514. tableOwner:contractTypeTabKey.value,
  515. dataTime:new Date(),
  516. })
  517. resolve(getArrValue(data))
  518. treeLoading.value = false
  519. }
  520. //树被点击
  521. const wbsElTreeClick = ({ node, data, keys }) => {
  522. nodeItemInfo.value = node
  523. nodeDataInfo.value = data
  524. primaryKeyId.value = data['primaryKeyId'] || ''
  525. //缓存自动展开
  526. treeAutoExpandKeys.value = keys
  527. setStoreValue('wbsTreeExpandKeys', keys)
  528. //改变搜索表单数据
  529. searchForm.value.wbsId = data['primaryKeyId']
  530. //只有监理、指挥合同段才传contractIdRelation
  531. if (contractInfo.value?.contractType == 2 || contractInfo.value?.contractType == 3) {
  532. searchForm.value.contractIdRelation = data['contractIdRelation']
  533. } else {
  534. searchForm.value.contractIdRelation = ''
  535. }
  536. searchForm.value.current = 1
  537. getFileUser()
  538. getTableData()
  539. }
  540. //搜索条件
  541. const processStatusData = ref([]) //流程状态
  542. const reportingPersonData = ref([]) //填报人
  543. const fileTypeData = ref([]) //文件类型
  544. const reportBatchData = ref([]) //上报批次
  545. //获取所有填报人
  546. const getFileUser = async () => {
  547. const info = nodeDataInfo.value
  548. if (!info || !info?.contractIdRelation) {
  549. window.$message?.warning('请先点击左侧节点')
  550. return
  551. }
  552. const { error, code, data } = await queryApi.getFileUser({
  553. contractId: contractId.value,
  554. contractIdRelation: contractInfo.value?.contractType === 2 ? info?.contractIdRelation : contractId.value,
  555. })
  556. //判断状态
  557. if (!error && code === 200) {
  558. let res = getArrValue(data), userArr = []
  559. res.forEach(item => {
  560. userArr.push({ label: item['userName'], value: `${item['userId']}-${item['userName']}` })
  561. })
  562. reportingPersonData.value = userArr
  563. } else {
  564. reportingPersonData.value = []
  565. }
  566. }
  567. //获取上报批次
  568. const getReportNumber = async () => {
  569. const { error, code, data } = await queryApi.getReportNumber({
  570. contractId: contractId.value,
  571. projectId: projectId.value,
  572. })
  573. //判断状态
  574. if (!error && code === 200) {
  575. reportBatchData.value = getArrValue(data)
  576. } else {
  577. reportBatchData.value = []
  578. }
  579. }
  580. //获取流程状态
  581. const getFirstTaskStatus = async () => {
  582. const { error, code, data } = await queryApi.getFirstTaskStatus()
  583. //判断状态
  584. if (!error && code === 200) {
  585. processStatusData.value = getArrValue(data)
  586. } else {
  587. processStatusData.value = []
  588. }
  589. }
  590. //获取流程状态分类和文件类型分类
  591. const getDictBizClassify = async () => {
  592. const { error, code, data } = await queryApi.getDictBizClassify({
  593. contractId: contractId.value,
  594. code: 'fileType',
  595. })
  596. //判断状态
  597. if (!error && code === 200) {
  598. fileTypeData.value = getArrValue(data)
  599. } else {
  600. fileTypeData.value = []
  601. }
  602. }
  603. //搜索表单
  604. const searchForm = ref({
  605. taskStatus: null, fileUserIdAndName: null, sourceType: null, reportNumber: null, betweenTime: null,
  606. queryValue: null, contractIdRelation: null, wbsId: null, current: 1, size: 20, total: 0, majorDateType:'',
  607. waitingUserStatus:'',
  608. })
  609. //结构类型tab数据和相关处理
  610. // const contractTypeTabKey = ref('1')
  611. const contractTypeTabKey = ref(contractInfo.value?.contractType === 2 ? '2' : '1')
  612. //加载树需要的classType由合同段获取
  613. const classType = ref(contractInfo.value?.contractType === 2 ? '2' : '1')
  614. const contractTypeTab = ref([
  615. { key: '1', name: '施工数据' },
  616. { key: '2', name: '监理数据' },
  617. ])
  618. //是否显示左边树
  619. const isShowLeft = ref(true)
  620. const contractTypeTabChange = (item) => {
  621. contractTypeTabKey.value = item?.key
  622. //重新加载左边树
  623. isShowLeft.value = false
  624. setTimeout(()=>{
  625. isShowLeft.value = true
  626. }, 500)
  627. searchClick()
  628. }
  629. //日期时间被选择
  630. const betweenTime = ref(null)
  631. const betweenTimeUpdate = ({ arr, query }) => {
  632. betweenTime.value = arr
  633. searchForm.value.betweenTime = query
  634. }
  635. //回车搜索
  636. const keyUpEvent = (e) => {
  637. if (e.key === 'Enter') {
  638. searchForm.value.current = 1
  639. if (searchForm.value?.queryValue) {
  640. searchForm.value.queryValue = searchForm.value.queryValue.trim()
  641. }
  642. getTableData()
  643. }
  644. }
  645. //搜索
  646. const searchClick = () => {
  647. searchForm.value.current = 1
  648. if (searchForm.value?.queryValue) {
  649. searchForm.value.queryValue = searchForm.value.queryValue.trim()
  650. }
  651. wbstreeKey.value = Math.random()
  652. getTableData()
  653. // wbstree.value.resetNode().then((red)=>{
  654. // if(red){
  655. // getTableData()
  656. // }
  657. // })
  658. }
  659. //分页被点击
  660. const pageChange = ({ current, size }) => {
  661. searchForm.value.current = current
  662. searchForm.value.size = size
  663. getTableData()
  664. }
  665. //获取数据
  666. const tableListRef = ref(null)
  667. const tableLoading = ref(false)
  668. const tableListColumn = ref([
  669. { key: 'name', name: '文件题名' },
  670. { key: 'taskStatusStr', name: '资料状态', width: 100, align: 'center' },
  671. { key: 'taskStatusStr', name: '检测状态', width: 100, align: 'center' },
  672. { key: 'fileUserIdAndName', name: '填报人', width: 190, align: 'center' },
  673. { key: 'waitingUserList', name: '任务人', align: 'center' },
  674. ])
  675. const tableListData = ref([])
  676. const getTableData = async () => {
  677. if (searchForm.value.wbsId) {
  678. tableListRef.value?.clearSelection()
  679. tableCheckedKeys.value = []
  680. tableLoading.value = true
  681. // const classifyType = getContractTypeKey();
  682. const { error, code, data, msg } = await queryApi.getPageData({
  683. projectId: projectId.value,
  684. contractId: contractId.value,
  685. ...searchForm.value,
  686. classifyType: contractTypeTabKey.value,
  687. })
  688. //处理数据
  689. tableLoading.value = false
  690. if (!error && code === 200) {
  691. tableListData.value = getArrValue(data['records'])
  692. searchForm.value.total = data.total || 0
  693. } else {
  694. // window.$message?.error(msg)
  695. tableListData.value = []
  696. searchForm.value.total = 0
  697. }
  698. } else {
  699. window?.$message?.warning('请先选择一个树节点')
  700. }
  701. }
  702. //多选
  703. const tableCheckedKeys = ref([])
  704. const tableSelectionChange = (rows) => {
  705. tableCheckedKeys.value = rows.filter((item) => {
  706. return (item ?? '') !== ''
  707. })
  708. }
  709. //名称被点击
  710. const tableRowName = (row) => {
  711. bussPreview(row)
  712. }
  713. //多表预览
  714. const bussPreview = async (row) => {
  715. const info = nodeDataInfo.value
  716. row.bussPreviewLoading = true
  717. const { error, code, data } = await wbsApi.getBussPdfs({
  718. nodeId: row?.wbsId || '',
  719. classify: contractTypeTabKey.value,
  720. projectId: projectId.value,
  721. // contractId: contractId.value
  722. contractId: contractInfo.value?.contractType == 2 ? info?.contractIdRelation : contractId.value,
  723. })
  724. row.bussPreviewLoading = false
  725. if (!error && code === 200) {
  726. toPdfPage(data)
  727. //window.open(data, '_blank')
  728. } else {
  729. window.$message?.warning('获取PDF失败')
  730. }
  731. }
  732. //上报
  733. const reportIds = ref('')
  734. const reportTaskName = ref('')
  735. const reportDatas = ref([])
  736. const reportTypeData = ref([])
  737. const showReportModal = ref(false)
  738. const reportLoading = ref(false)
  739. const reportArr = ref([])
  740. const reportModalClick = async () => {
  741. const rows = tableCheckedKeys.value
  742. //判断是否满足条件
  743. const result = rows.every(({ status }) => {
  744. return status === 0 || status === 3
  745. })
  746. //处理数据
  747. let newArr = []
  748. for (let i = 0; i < rows.length; i++) {
  749. newArr.push(rows[i]['wbsId'])
  750. }
  751. reportTypeData.value = newArr
  752. let newArr1 = []
  753. for (let i = 0; i < rows.length; i++) {
  754. newArr1.push(rows[i]['id'])
  755. }
  756. reportArr.value = newArr1
  757. //判断状态
  758. if (result) {
  759. reportLoading.value = true
  760. const taskCheck = await eVisaTaskCheckApi({
  761. projectId: projectId.value,
  762. contractId: contractId.value,
  763. })
  764. if (taskCheck) {
  765. //初始ID
  766. const row = getObjValue(rows[0])
  767. reportIds.value = arrToId(rows)
  768. //设置任务数据
  769. let reportDataArr = []
  770. rows.forEach(item => {
  771. reportDataArr.push({
  772. id: item?.id,
  773. name: item?.name,
  774. })
  775. })
  776. reportDatas.value = reportDataArr
  777. //设置任务名称
  778. reportTaskName.value = rows.length > 1 ? `${row.name}等${rows.length}个文件` : row.name
  779. reportLoading.value = false
  780. showReportModal.value = true
  781. } else {
  782. reportLoading.value = false
  783. }
  784. } else {
  785. window.$message?.warning('已上报的文件不能进行再次上报,若要重新上报,要先撤回之前的上报,再重新上报')
  786. }
  787. }
  788. //上报的审批内容移除
  789. const reportTaskTagClose = (index) => {
  790. const row = tableCheckedKeys.value[index]
  791. tableListRef.value?.toggleRowSelection(row, false)
  792. }
  793. //上报完成
  794. const showReportFinish = () => {
  795. showReportModal.value = false
  796. getTableData()
  797. }
  798. //下载
  799. const downloadLoading = ref(false)
  800. const batchDownload = async () => {
  801. const rows = tableCheckedKeys.value
  802. const ids = arrToId(rows)
  803. //批量下载
  804. downloadLoading.value = true
  805. const { error, disposition, res } = await queryApi.batchDownloadFileToZip({ ids: ids })
  806. //处理数据
  807. downloadLoading.value = false
  808. if (!error) {
  809. if (disposition) {
  810. downloadBlob(res, disposition)
  811. } else {
  812. window.$message?.error('数据异常')
  813. }
  814. }
  815. }
  816. //打印
  817. const printLoading = ref(false)
  818. const batchPrint = async () => {
  819. const rows = tableCheckedKeys.value
  820. const ids = arrToId(rows)
  821. //批量下载
  822. printLoading.value = true
  823. const { error, code, data } = await queryApi.batchPrint({ ids: ids })
  824. //处理数据
  825. printLoading.value = false
  826. const res = isString(data) ? data ?? '' : ''
  827. if (!error && code === 200 && res) {
  828. toPdfPage(res)
  829. //window.open(res, '_blank')
  830. }
  831. }
  832. //废除
  833. const batchAbolishClick = () => {
  834. const rows = tableCheckedKeys.value
  835. //判断是否满足条件
  836. const result = rows.every(({ status }) => {
  837. return status !== 0 && status !== 3
  838. })
  839. //判断状态
  840. if (result) {
  841. //拼接ID
  842. const ids = arrToId(rows)
  843. window?.$messageBox?.alert('是否废除勾选的已上报文件?', '废除文件', {
  844. showCancelButton: true,
  845. confirmButtonText: '确定废除',
  846. cancelButtonText: '取消',
  847. callback: (action) => {
  848. if (action === 'confirm') {
  849. batchAbolishSave(ids)
  850. }
  851. },
  852. })
  853. } else {
  854. window.$message?.warning('未上报的文件不能废除')
  855. }
  856. }
  857. //废除勾选的已上报文件
  858. const batchAbolishSave = async (ids) => {
  859. const { error, code } = await queryApi.batchAbolish({ ids: ids, projectId:projectId.value, contractId:contractId.value })
  860. //处理数据
  861. if (!error && code === 200) {
  862. window.$message?.success('批量废除成功')
  863. tableCheckedKeys.value = []
  864. getTableData()
  865. }
  866. }
  867. //本地验签
  868. const localLoading = ref(false)
  869. const batchLocal = async () => {
  870. const rows = tableCheckedKeys.value
  871. //判断是否满足条件
  872. const result = rows.every(({ status }) => {
  873. return status === 2
  874. })
  875. //判断状态
  876. if (result) {
  877. const ids = arrToId(rows)
  878. //请求数据
  879. localLoading.value = true
  880. const { error, code, data, disposition, res } = await queryApi.localVerify({
  881. ids: ids,
  882. })
  883. //处理数据
  884. localLoading.value = false
  885. if (!error && code === 200) {
  886. if (disposition) {
  887. downloadBlob(res, disposition)
  888. } else {
  889. window.$message?.error('数据异常')
  890. }
  891. }
  892. } else {
  893. window.$message?.warning('存在未审批或未上报数据')
  894. }
  895. }
  896. //在线验签
  897. const onlineLoading = ref(false)
  898. const onlineVerifyData = ref({})
  899. const onlineTitle = ref('')
  900. const isOnlineVerifyDrawer = ref(false)
  901. const onlineVerifyOptions = {
  902. sizes: [50, 50],
  903. snapOffset: 0,
  904. minSize: ['10%', '80%'],
  905. }
  906. const batchOnline = async () => {
  907. const rows = tableCheckedKeys.value
  908. if (rows.length > 1) {
  909. window.$message?.warning('在线验签只能勾选一条数据进行验签')
  910. return
  911. }
  912. //判断是否满足条件
  913. const result = rows.every(({ status }) => {
  914. return status === 2
  915. })
  916. //判断状态
  917. if (!result) {
  918. window.$message?.warning('存在未审批或未上报数据')
  919. return
  920. }
  921. //发起请求
  922. onlineTitle.value = rows[0]?.name
  923. const ids = arrToId(rows)
  924. onlineLoading.value = true
  925. const { error, code, msg, data } = await queryApi.onlineVerify({
  926. ids: ids,
  927. })
  928. //处理数据
  929. onlineLoading.value = false
  930. if (!error && code === 200) {
  931. onlineVerifyData.value = getObjValue(data)
  932. cscTableData.value = getArrValue(data['certBeanVOList'])
  933. isOnlineVerifyDrawer.value = true
  934. } else {
  935. onlineVerifyData.value = {}
  936. window.$message?.error(msg ?? '操作失败')
  937. }
  938. }
  939. //签名信息
  940. const cscTableColumn = [
  941. { key:'dn', name: '签名者', width: 300 },
  942. { key:'time', name: '签名时间', width: 200 },
  943. { key:'result', name: '验签结果' },
  944. ]
  945. const cscTableData = ref([])
  946. //在线验签抽屉被关闭
  947. const onlineVerifyDrawerClose = () => {
  948. isOnlineVerifyDrawer.value = false
  949. onlineLoading.value = false
  950. }
  951. //树展开和收起
  952. const isWbsTreeShow = ref(true)
  953. const setWbsTreeShow = () => {
  954. isWbsTreeShow.value = !isWbsTreeShow.value
  955. }
  956. //左右拖动,改变树形结构宽度
  957. const leftWidth = ref(300)
  958. //更新配置
  959. watch(
  960. () => leftWidth.value,
  961. (diffVal) => {
  962. setUserConfig(diffVal)
  963. },
  964. )
  965. const setUserConfig = async (data) => {
  966. await useClick()
  967. useAppState.setTreeWidth(data)
  968. await userConfigSave({ treeWidth: data })
  969. }
  970. const onmousedown = () => {
  971. let leftNum = 0
  972. if (isLayout.value === 'no') {
  973. leftNum = 0
  974. } else {
  975. leftNum = isCollapse.value ? 142 : 272
  976. }
  977. document.onmousemove = (ve) => {
  978. let diffVal = ve.clientX - leftNum
  979. if (diffVal >= 310 && diffVal <= 900) {
  980. leftWidth.value = diffVal
  981. }
  982. }
  983. document.onmouseup = () => {
  984. document.onmousemove = null
  985. document.onmouseup = null
  986. }
  987. }
  988. const allElementsNotEmpty = (str)=> {
  989. // 使用split将字符串分割成字符数组
  990. // 使用every方法判断每个元素是否不为空字符串
  991. return str.split('').every(char => char !== '')
  992. }
  993. //一键重签
  994. const signLoading = ref(false)
  995. const resignModal = ref(false)
  996. const resignModalRadio = ref(0)
  997. const resignClick = async ()=>{
  998. const rows = tableCheckedKeys.value
  999. if (rows.length <= 0) {
  1000. window.$message?.warning('勾选错误!只能操作待审批和已审批数据')
  1001. return
  1002. }
  1003. resignModal.value = true
  1004. }
  1005. const signClick = async () => {
  1006. const rows = tableCheckedKeys.value
  1007. //获取任务id
  1008. const taskIds = arrToKey(rows, 'taskId')
  1009. const idsArr = taskIds.split(',')
  1010. let isCan = idsArr.some(ele=>!ele)
  1011. if (isCan) {
  1012. window.$message?.warning('参数异常,暂不支持该操作')
  1013. return
  1014. }
  1015. //发起请求
  1016. signLoading.value = true
  1017. const { error, code, msg } = await queryApi.reSigningEVisa({
  1018. contractId: contractId.value,
  1019. projectId: projectId.value,
  1020. taskIds: taskIds,
  1021. classifyType: contractTypeTabKey.value,
  1022. type:resignModalRadio.value,
  1023. })
  1024. //处理数据
  1025. signLoading.value = false
  1026. if (!error && code === 200) {
  1027. window.$message?.success(msg ?? '提交成功,请请耐心等待重签,可继续操作其它的功能。')
  1028. getTableData().then()
  1029. } else {
  1030. window.$message?.error(msg ?? '操作失败')
  1031. }
  1032. resignModal.value = false
  1033. }
  1034. const cancelresign = ()=>{
  1035. resignModalRadio.value = 0
  1036. resignModal.value = false
  1037. }
  1038. //重新验签
  1039. const saveAginClick = async ()=>{
  1040. const rows = tableCheckedKeys.value
  1041. const taskIds = rows.map(row => row.taskId)
  1042. if (taskIds.some(id => id)) {
  1043. window.$message?.warning('勾选错误!只能操作未上报的数据')
  1044. return
  1045. }
  1046. const objArr = rows.map(row => ({
  1047. id: row.id,
  1048. wbsId: row.wbsId,
  1049. projectId: projectId.value,
  1050. contractId: contractId.value,
  1051. }))
  1052. saveAginLoading.value = true
  1053. const { error, code, msg } = await queryApi.reSigningEVisaStatus0(objArr)
  1054. //处理数据
  1055. saveAginLoading.value = false
  1056. if (!error && code === 200) {
  1057. window.$message?.success(msg ?? '提交成功,请请耐心等待重签,可继续操作其它的功能。')
  1058. getTableData().then()
  1059. } else {
  1060. window.$message?.error(msg ?? '操作失败')
  1061. }
  1062. }
  1063. const saveAginLoading = ref(false)
  1064. //重置文件题名
  1065. const resignTitleModal = ref(false)
  1066. const resignTitleClick = async ()=>{
  1067. // resignTitleModal.value = true
  1068. if (isTemplateType.value) {
  1069. resignTitleModal.value = true
  1070. } else {
  1071. resignTitleSave()
  1072. }
  1073. }
  1074. const resignTitleSave = async ()=>{
  1075. const rows = tableCheckedKeys.value
  1076. let arr = []
  1077. rows.forEach(item=>{
  1078. arr.push({
  1079. id:item.id,
  1080. nodeName:'',
  1081. nameRule:'',
  1082. })
  1083. })
  1084. ruleModalSaveLoad.value = true
  1085. const { error, code, msg, data } = await queryApi.flushQueryName({
  1086. type:1,
  1087. list:arr,
  1088. })
  1089. //处理数据
  1090. ruleModalSaveLoad.value = false
  1091. if (!error && code === 200) {
  1092. window.$message?.success(msg)
  1093. resignTitleModal.value = false
  1094. getTableData().then()
  1095. } else {
  1096. window.$message?.error(msg || '操作失败')
  1097. }
  1098. }
  1099. const resignTitleSaveLoad = ref(false)
  1100. //规则更改
  1101. const changeRuleClick = async ()=>{
  1102. await getWbsNodeTypeApi()
  1103. ruleModal.value = true
  1104. ruleTableData.value = []
  1105. let arr = tableCheckedKeys.value.map(item=>{
  1106. return {
  1107. wbsId:item.wbsId,
  1108. projectId:projectId.value,
  1109. }
  1110. })
  1111. let arr1 = await getRuleListData(arr)
  1112. ruleTableData.value = arr1
  1113. for (let i = 0; i < ruleTableData.value.length; i++) {
  1114. const currentItem = ruleTableData.value[i]
  1115. const matchedItem = tableCheckedKeys.value.find(item => item.wbsId === currentItem.wbsId)
  1116. if (matchedItem) {
  1117. currentItem.name = matchedItem.name
  1118. currentItem.id = matchedItem.id
  1119. }
  1120. }
  1121. // ruleTableData.value = arr
  1122. }
  1123. const ruleModal = ref(false)
  1124. const ruleModalSaveLoad = ref(false)
  1125. const ruleModalClose = ()=>{
  1126. ruleModal.value = false
  1127. setValue.value = []
  1128. }
  1129. const ruleModalSave = async ()=>{
  1130. let isCanSave = ruleTableData.value.every(row => row.rule && row.rule.length > 0)
  1131. if (!isCanSave) {
  1132. window.$message.warning('请选择题名规规则')
  1133. return
  1134. }
  1135. let arr = []
  1136. ruleTableData.value.forEach(item=>{
  1137. arr.push({
  1138. id:item.id,
  1139. nodeName:item.newNodeName,
  1140. nameRule:item.rule.join('-'),
  1141. })
  1142. })
  1143. ruleModalSaveLoad.value = true
  1144. const { error, code, msg, data } = await queryApi.flushQueryName({
  1145. type:2,
  1146. list:arr,
  1147. })
  1148. //处理数据
  1149. ruleModalSaveLoad.value = false
  1150. if (!error && code === 200) {
  1151. window.$message?.success(msg)
  1152. getTableData().then()
  1153. ruleModalClose()
  1154. resignTitleModal.value = false
  1155. }
  1156. }
  1157. const setValue = ref('')
  1158. const ruleTableColumn = ref([
  1159. { key: 'name', name: '文件题名' },
  1160. { key: 'newNodeName', name: '修改后' },
  1161. { key: 'rule', name: '题名规则' },
  1162. ])
  1163. const ruleTableData = ref([])
  1164. const batchSetRule = async ()=>{
  1165. if (setValue.value.length === 0) {
  1166. window.$message.warning('请选择题名规则')
  1167. return
  1168. }
  1169. ruleTableData.value.forEach( (ele)=>{
  1170. ele.rule = setValue.value
  1171. let matchedItems = [] // 存储匹配的项
  1172. if (ele.rule.length > 0) {
  1173. // 1. 找出所有匹配的项
  1174. matchedItems = nodeTypeData.value.filter(dataItem =>
  1175. ele.rule.includes(dataItem.value),
  1176. )
  1177. // 2. 按原始 sort 排序
  1178. matchedItems.sort((a, b) => a.sort - b.sort)
  1179. // 3. 更新 ele.rule 为排序后的 value 数组
  1180. ele.rule = matchedItems.map(item => item.value)
  1181. }
  1182. })
  1183. let arr = []
  1184. ruleTableData.value.forEach((item)=>{
  1185. arr.push({
  1186. wbsId:item.wbsId,
  1187. nameRule:item.rule.join('-'),
  1188. })
  1189. })
  1190. let afterArr = await getRuleValue(arr)
  1191. for (let i = 0; i < ruleTableData.value.length; i++) {
  1192. const currentItem = ruleTableData.value[i]
  1193. const matchedItem = afterArr.find(item => item.wbsId === currentItem.wbsId)
  1194. if (matchedItem) {
  1195. currentItem.newNodeName = matchedItem.newNodeName
  1196. }
  1197. }
  1198. }
  1199. const ruleChange = async (ele) => {
  1200. let str = ''
  1201. let matchedItems = [] // 存储匹配的项
  1202. if (ele.rule.length > 0) {
  1203. // 1. 找出所有匹配的项
  1204. matchedItems = nodeTypeData.value.filter(dataItem =>
  1205. ele.rule.includes(dataItem.value),
  1206. )
  1207. // 2. 按原始 sort 排序
  1208. matchedItems.sort((a, b) => a.sort - b.sort)
  1209. // 3. 更新 ele.rule 为排序后的 value 数组
  1210. ele.rule = matchedItems.map(item => item.value)
  1211. // 4. 生成连接字符串
  1212. str = ele.rule.join('-')
  1213. }
  1214. // 5. 调用API
  1215. let arr = [{
  1216. wbsId: ele.wbsId,
  1217. nameRule: str,
  1218. }]
  1219. let afterArr = await getRuleValue(arr)
  1220. ele.newNodeName = afterArr[0].newNodeName
  1221. }
  1222. const getRuleLoad = ref(false)
  1223. const ruleTableLoading = ref(false)
  1224. const getRuleListData = async (arr) => {
  1225. ruleTableLoading.value = true
  1226. const { error, code, msg, data } = await queryApi.getNameRuleList(arr)
  1227. //处理数据
  1228. ruleTableLoading.value = false
  1229. if (!error && code === 200) {
  1230. return data || ''
  1231. } else {
  1232. return ''
  1233. }
  1234. }
  1235. const getRuleValue = async (arr) => {
  1236. // 检查 arr 中每一项的 nameRule 是否有值
  1237. const hasInvalidItem = arr.some(item => !item.nameRule || item.nameRule.length === 0)
  1238. if (hasInvalidItem) {
  1239. window.$message.warning('请选择题名规则')
  1240. return
  1241. }
  1242. getRuleLoad.value = true
  1243. const { error, code, msg, data } = await queryApi.previewNodeName(arr)
  1244. //处理数据
  1245. getRuleLoad.value = false
  1246. if (!error && code === 200) {
  1247. return data || ''
  1248. } else {
  1249. return ''
  1250. }
  1251. }
  1252. //获取节点类型
  1253. const nodeTypeData = ref([])
  1254. const getWbsNodeTypeApi = async () => {
  1255. const { data } = await getDictionary({
  1256. code: 'name_rule',
  1257. })
  1258. //处理数据
  1259. let newArr = []
  1260. const newData = getArrValue(data)
  1261. for (let i = 0; i < newData.length; i++) {
  1262. newArr.push({
  1263. label: newData[i]['dictValue'],
  1264. value:newData[i]['dictKey'],
  1265. })
  1266. }
  1267. nodeTypeData.value = newArr
  1268. }
  1269. //一键重签1
  1270. const resignModal1 = ref(false)
  1271. const resignModalRadio1 = ref(0)
  1272. const resignClick1 = ()=>{
  1273. const rows = tableCheckedKeys.value
  1274. if (rows.length <= 0) {
  1275. window.$message?.warning('勾选错误!只能操作待审批和已审批数据')
  1276. return
  1277. }
  1278. resignModal1.value = true
  1279. }
  1280. const signLoading1 = ref(false)
  1281. const cancelresign1 = ()=>{
  1282. resignModalRadio1.value = 0
  1283. resignModal1.value = false
  1284. checkTaskUserIds.value = []
  1285. }
  1286. const signClick1 = async () => {
  1287. const rows = tableCheckedKeys.value
  1288. //获取任务id
  1289. const ids = arrToId(rows)
  1290. if (resignModalRadio1.value === 1) {
  1291. if (checkTaskUserIds.value.length === 0) {
  1292. return window.$message?.warning('请选择用户')
  1293. }
  1294. } else {
  1295. checkTaskUserIds.value = []
  1296. }
  1297. //发起请求
  1298. signLoading1.value = true
  1299. const { error, code, msg } = await queryApi.reSigningEVisa1({
  1300. userIds: checkTaskUserIds.value.length === 1 ? checkTaskUserIds.value[0] : checkTaskUserIds.value.join(','),
  1301. ids: ids,
  1302. })
  1303. //处理数据
  1304. signLoading1.value = false
  1305. if (!error && code === 200) {
  1306. window.$message?.success(msg ?? '提交成功,请请耐心等待重签,可继续操作其它的功能。')
  1307. cancelresign1()
  1308. getTableData().then()
  1309. }
  1310. }
  1311. const checkTaskUserIds = ref([])
  1312. const batchOnlineClickLoad = ref(false)
  1313. const batchOnlineClick = async ()=>{
  1314. const rows = tableCheckedKeys.value
  1315. //获取任务id
  1316. const ids = arrToId(rows)
  1317. batchOnlineClickLoad.value = true
  1318. const { error, code, msg } = await queryApi.updateCheckPdfInfo(
  1319. {
  1320. classify:contractTypeTabKey.value,
  1321. type:2,
  1322. ids,
  1323. },
  1324. )
  1325. batchOnlineClickLoad.value = false
  1326. //处理数据
  1327. signLoading1.value = false
  1328. if (!error && code === 200) {
  1329. window.$message?.success(msg )
  1330. getTableData().then()
  1331. }
  1332. }
  1333. const treeMenus = ref([
  1334. {
  1335. icon: 'edit',
  1336. label: '电签检测',
  1337. key: 'add1',
  1338. },
  1339. ])
  1340. const ElTreeMenuClick = async ({ key, node, data, keys }) => {
  1341. nodeItemInfo.value = node
  1342. nodeDataInfo.value = data
  1343. setStoreValue('wbsTreeExpandKeys', keys)
  1344. if (key === 'add1') {
  1345. // console.log(22222)
  1346. const { error, code, msg } = await queryApi.updateCheckPdfInfo(
  1347. {
  1348. classify:contractTypeTabKey.value,
  1349. type:1,
  1350. primaryKeyId:nodeDataInfo.value.primaryKeyId,
  1351. },
  1352. )
  1353. batchOnlineClickLoad.value = false
  1354. //处理数据
  1355. signLoading1.value = false
  1356. if (!error && code === 200) {
  1357. window.$message?.success(msg )
  1358. getTableData().then()
  1359. }
  1360. }
  1361. }
  1362. </script>
  1363. <style lang="scss" scoped>
  1364. @import "../../styles/data-fill/query.scss";
  1365. .error-border {
  1366. border: 1px solid red;
  1367. }
  1368. .iscusor {
  1369. cursor: pointer;
  1370. }
  1371. .bg-primary-color {
  1372. background-color: var(--el-color-primary) ;
  1373. }
  1374. .basic-info-box {
  1375. height: calc(100% - 77px);
  1376. }
  1377. </style>
  1378. <style lang="scss">
  1379. .hc-online-verify-drawer .el-card.hc-new-card-box {
  1380. .hc-card-header-box {
  1381. .online-verify-title {
  1382. font-size: 20px;
  1383. }
  1384. .online-verify-icon {
  1385. display: flex;
  1386. align-items: center;
  1387. cursor: pointer;
  1388. color: #5a5959;
  1389. i {
  1390. font-size: 18px;
  1391. }
  1392. &:hover {
  1393. color: var(--el-color-primary);
  1394. }
  1395. }
  1396. }
  1397. }
  1398. .custom-select{
  1399. .el-select__wrapper {
  1400. height: 32px;
  1401. overflow-y: hidden;
  1402. }
  1403. .el-select__selection.is-near {
  1404. height: 32px;
  1405. overflow-y: hidden;
  1406. overflow-x: hidden;
  1407. flex-wrap: nowrap;
  1408. }
  1409. }
  1410. </style>