query.vue 52 KB

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