query.vue 52 KB

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