test.vue 54 KB

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