wbs.vue 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033
  1. <template>
  2. <div class="h-full">
  3. <HcCard v-if="wbsTypeTabKey === 'map'" id-ref="wbs-node-tree-card-target">
  4. <template #header>
  5. <HcTooltip keys="wbs_views_division_btn">
  6. <el-button class="mr-10" hc-btn type="primary" @click="divisionClick">
  7. <HcIcon :line="false" name="node-tree"/>
  8. <span>划分变更</span>
  9. </el-button>
  10. </HcTooltip>
  11. <HcNewSwitch v-if="isDrawer" :datas="authBtnTabdata" :keys="authBtnTabKey" :round="false"
  12. size="default" @change="authBtnTabClick"/>
  13. </template>
  14. <template #extra>
  15. <HcNewSwitch :datas="wbsTypeTab" :keys="wbsTypeTabKey" @change="wbsTypeTabChange"/>
  16. </template>
  17. <NodeTree
  18. ref="NodeTreeRef"
  19. :accordion='NodeTreeAccordion'
  20. :autoExpandKeys="TreeAutoExpandKeys"
  21. :contractId="contractId"
  22. :isMark="TreeMark"
  23. :menus="ElTreeMenu"
  24. :projectId="projectId"
  25. @menuClick="NodeTreeMenuClick"
  26. @nodeClick="NodeTreeClick"
  27. @nodeDblClick="NodeTreeDblClick"/>
  28. <template #action>
  29. <div class="hc-tree-mp-tip-box">
  30. <div class="dot-view green">已审批</div>
  31. <div class="dot-view black">未填报</div>
  32. <div class="dot-view orange">已填报-待审批</div>
  33. <div class="dot-view blue">已填报-未上报</div>
  34. </div>
  35. </template>
  36. <HcDrawer :show="isDrawer" actionUi="text-center" to-id="wbs-node-tree-card-target" @close="drawerClose">
  37. <!--清表列表-->
  38. <el-scrollbar v-if="ListItemDatas.length > 0" ref="ListItemScrollRef">
  39. <CollapseForm ref="ListItemsRef"
  40. :classify="authBtnTabKey"
  41. :contractId="contractId"
  42. :datas="ListItemDatas"
  43. :drawType="isDrawType"
  44. :primaryKeyId="primaryKeyId"
  45. :status="NodeStatus"
  46. :tenantId="userInfo?.tenant_id"
  47. :wbsTempId="projectInfo?.referenceWbsTemplateIdTrial"
  48. :wbsType="2"
  49. @offsetTop="ListItemOffsetTop"
  50. @renew="getTableDataAll"/>
  51. </el-scrollbar>
  52. <HcStatus v-else text="暂无表单"/>
  53. <!--底部按钮区域-->
  54. <template #action>
  55. <HcTooltip v-if="NodeStatus !== '3'" keys="wbs_save">
  56. <el-button :disabled="NodeStatus === '3' || ListItemDatas.length <= 0"
  57. :loading="tableFormSaveLoading"
  58. hc-btn
  59. type="primary"
  60. @click="tableFormSaveClick">
  61. <HcIcon name="save"/>
  62. <span>保存</span>
  63. </el-button>
  64. </HcTooltip>
  65. <HcTooltip v-if="NodeStatus !== '3'" keys="wbs_report">
  66. <el-button :disabled="NodeStatus === '3' || NodeStatus === '1'"
  67. :loading="reportLoading"
  68. hc-btn
  69. @click="reportModalClick">
  70. <HcIcon name="send-plane-2"/>
  71. <span>上报</span>
  72. </el-button>
  73. </HcTooltip>
  74. <HcTooltip keys="wbs_preview">
  75. <el-button :disabled="NodeStatus === '1'"
  76. :loading="bussPdfsLoading"
  77. hc-btn
  78. @click="bussPdfsClick">
  79. <HcIcon name="eye"/>
  80. <span>预览</span>
  81. </el-button>
  82. </HcTooltip>
  83. <HcTooltip v-if="NodeStatus === '3'" keys="wbs_abolish">
  84. <el-button hc-btn>
  85. <HcIcon name="arrow-go-back"/>
  86. <span>撤回上报流程</span>
  87. </el-button>
  88. </HcTooltip>
  89. <HcTooltip keys="wbs_views_drawings">
  90. <el-button :disabled="!nodeDataInfo?.fileUrl" hc-btn @click="viewsDrawings">
  91. <HcIcon name="image"/>
  92. <span>图纸</span>
  93. </el-button>
  94. </HcTooltip>
  95. <el-button hc-btn>
  96. <HcIcon name="file"/>
  97. <span>附件</span>
  98. </el-button>
  99. <el-button hc-btn @click="drawerClose">
  100. <HcIcon name="close"/>
  101. <span>关闭填报页面</span>
  102. </el-button>
  103. </template>
  104. </HcDrawer>
  105. </HcCard>
  106. <div v-if="wbsTypeTabKey === 'tree'" class="hc-layout-box">
  107. <div id="wbs-left-tree" :class="[isWbsTreeShow?'show':'', isMouseTree ? 'on-transition':'']"
  108. :style="'width:' + (isWbsTreeShow ? leftWidth : 0) + 'px;'"
  109. class="hc-layout-left-box">
  110. <div class="hc-project-box">
  111. <div class="hc-project-icon-box">
  112. <HcIcon name="stack"/>
  113. </div>
  114. <div class="ml-2 project-name-box">
  115. <span class="text-xl text-cut project-alias">{{ projectInfo['projectAlias'] }}</span>
  116. <div class="text-xs text-cut project-name">{{ projectInfo['name'] }}</div>
  117. </div>
  118. </div>
  119. <div class="hc-tree-box">
  120. <div class="hc-search-tree-val">
  121. <el-input v-model="searchTreeVal" block clearable placeholder="请输入名称关键词检索"
  122. size="large" @keyup="searchTreeKeyUp">
  123. <template #suffix>
  124. <HcIcon name="search-2" ui="text-xl iscusor" @click="searchTreeClick"/>
  125. </template>
  126. </el-input>
  127. </div>
  128. <div v-loading="treeLoading" id="hc-tree-scrollbar" class="hc-tree-scrollbar" element-loading-text="获取数据中...">
  129. <HcTreeDataV2
  130. :isShow="isSearchTree"
  131. :datas="searchTreeData"
  132. :height="searchTreeHeight"
  133. :isMark="TreeMark"
  134. :menus="ElTreeMenu"
  135. :searchTreeVal="searchTreeVal"
  136. :submitCounts="true"
  137. :ElTreeLoadNode="searchElTreeLoadNode"
  138. isColor
  139. @changeSearch="changeisSearch"
  140. @changetreelaod="changetreelaod"
  141. @menuTap="ElTreeMenuClick"
  142. @nodeTap="wbsElTreeClick"/>
  143. <el-scrollbar class="scroll-bar-right-16" v-show="!isSearchTree">
  144. <WbsTree
  145. ref="wbstree"
  146. :autoExpandKeys="TreeAutoExpandKeys"
  147. :classifyType="authBtnTabKey"
  148. :contractId="contractId"
  149. :isMark="TreeMark"
  150. :menus="ElTreeMenu"
  151. :projectId="projectId"
  152. :submitCounts="true"
  153. :treeKey="wbstreeKey"
  154. isColor
  155. @menuTap="ElTreeMenuClick"
  156. @nodeLoading="ElTreeNodeLoading"
  157. @nodeTap="wbsElTreeClick"/>
  158. </el-scrollbar>
  159. </div>
  160. </div>
  161. <div class="hc-tree-foot-tip-box">
  162. <div class="dot-view green">已审批</div>
  163. <div class="dot-view black">未填报</div>
  164. <div class="dot-view orange">已填报-待审批</div>
  165. <div class="dot-view blue">已填报-未上报</div>
  166. </div>
  167. <!--左右拖动-->
  168. <div class="horizontal-drag-line" @mousedown="onmousedown"/>
  169. </div>
  170. <div id="wbs-content-box" class="hc-layout-content-box">
  171. <!---展开收缩树-->
  172. <div class="hc-expansion-contraction-tree" @click="setWbsTreeShow">
  173. <HcIcon v-show="isWbsTreeShow" name="arrow-left-s"/>
  174. <HcIcon v-show="!isWbsTreeShow" name="arrow-right-s"/>
  175. </div>
  176. <HcCard actionUi="text-center">
  177. <template #header>
  178. <HcNewSwitch :datas="authBtnTabdata" :keys="authBtnTabKey" :round="false"
  179. size="default" @change="authBtnTabClick"/>
  180. </template>
  181. <!--切换导图或树形模式-->
  182. <template #extra>
  183. <HcNewSwitch :datas="wbsTypeTab" :keys="wbsTypeTabKey" @change="wbsTypeTabChange"/>
  184. </template>
  185. <!--清表列表-->
  186. <el-scrollbar v-if="ListItemDatas.length > 0" ref="ListItemScrollRef" v-loading="ListItemLoading">
  187. <CollapseForm ref="ListItemRef"
  188. :TreeAutoExpandKeys="TreeAutoExpandKeys"
  189. :classify="authBtnTabKey"
  190. :contractId="contractId"
  191. :datas="ListItemDatas"
  192. :drawType="!isDrawType"
  193. :primaryKeyId="primaryKeyId"
  194. :status="NodeStatus"
  195. :tenantId="userInfo?.tenant_id"
  196. :wbsTempId="projectInfo?.referenceWbsTemplateIdTrial"
  197. :wbsType="2"
  198. :treenodeDataInfo="nodeDataInfo"
  199. @offsetTop="ListItemOffsetTop"
  200. @renew="getTableDataAll"/>
  201. </el-scrollbar>
  202. <HcStatus v-else text="暂无表单"/>
  203. <!--底部按钮区域-->
  204. <template #action>
  205. <div class="hc-table-form-action-tip">
  206. <el-alert :closable="false"
  207. class="hc-alert"
  208. show-icon
  209. style=""
  210. title="完善资料填写后记得一定要保存哦"
  211. type="warning"/>
  212. </div>
  213. <HcTooltip v-if="NodeStatus !== '3'" keys="wbs_save">
  214. <el-button :disabled="NodeStatus === '3' || ListItemDatas.length <= 0"
  215. :loading="tableFormSaveLoading"
  216. hc-btn
  217. style="width:150px;font-weight: bold;font-size:large"
  218. type="primary"
  219. @click="tableFormSaveClick">
  220. <HcIcon name="save"/>
  221. <span>保存</span>
  222. </el-button>
  223. </HcTooltip>
  224. <HcTooltip v-if="NodeStatus !== '3'" keys="wbs_report">
  225. <el-button :disabled="NodeStatus === '3' || NodeStatus === '1'" :loading="reportLoading"
  226. hc-btn @click="reportModalClick">
  227. <HcIcon name="send-plane-2"/>
  228. <span>上报</span>
  229. </el-button>
  230. </HcTooltip>
  231. <HcTooltip keys="wbs_preview">
  232. <el-button :disabled="NodeStatus === '1'" :loading="bussPdfsLoading" hc-btn
  233. @click="bussPdfsClick">
  234. <HcIcon name="eye"/>
  235. <span>预览</span>
  236. </el-button>
  237. </HcTooltip>
  238. <HcTooltip v-if="NodeStatus === '3'" keys="wbs_abolish">
  239. <el-button hc-btn @click="abolishOneClick">
  240. <HcIcon name="arrow-go-back"/>
  241. <span>撤回上报流程</span>
  242. </el-button>
  243. </HcTooltip>
  244. <HcTooltip keys="wbs_views_drawings">
  245. <el-button :disabled="!nodeDataInfo?.fileUrl" hc-btn @click="viewsDrawings">
  246. <HcIcon name="image"/>
  247. <span>图纸</span>
  248. </el-button>
  249. </HcTooltip>
  250. <el-button hc-btn @click="attachmentModalShow">
  251. <HcIcon name="file"/>
  252. <span>附件</span>
  253. </el-button>
  254. </template>
  255. </HcCard>
  256. </div>
  257. </div>
  258. <!--上传图纸-->
  259. <div class="upload-drawing">
  260. <el-upload :accept="accept" :action="action" :before-upload="beforeUpload" :headers="getTokenHeader()"
  261. :on-error="uploadError" :on-success="uploadFinish">
  262. <div id="upload-drawing">上传图纸</div>
  263. </el-upload>
  264. </div>
  265. <!--查看图纸-->
  266. <HcDragModal :isShow="drawingsShow" closeIcon lefts="145" title="查看图纸" tops="100" ui="hc-image-preview-box"
  267. widths="380px" @close="drawingsClose">
  268. <div class="hc-image-preview-view">
  269. <el-image-viewer :url-list="[nodeDataInfo.fileUrl]"/>
  270. </div>
  271. </HcDragModal>
  272. <!--编辑节点-->
  273. <HcDialog :loading="editNodeLoading" :show="editNodeModal" title="编辑节点" widths="600px"
  274. @close="editNodeModal = false" @save="editNodeClick">
  275. <el-form ref="formEditNodeRef" :model="formEditNodeModel" :rules="formEditNodeRules" label-width="auto"
  276. size="large">
  277. <el-form-item label="节点名称" prop="title">
  278. <el-input v-model="formEditNodeModel.title" placeholder="请输入节点名称"/>
  279. </el-form-item>
  280. <el-form-item label="上级节点">
  281. <el-input v-model="formEditNodeModel.parent.title" disabled/>
  282. </el-form-item>
  283. <el-form-item label="节点类型">
  284. <el-select v-model="formEditNodeModel.type" block disabled>
  285. <el-option v-for="item in nodeTypeData" :label="item.label" :value="item.value"/>
  286. </el-select>
  287. </el-form-item>
  288. <el-form-item label="划分编号">
  289. <el-input v-model="formEditNodeModel.partitionCode" placeholder="请输入划分编号"/>
  290. </el-form-item>
  291. <el-form-item class="hc-position-input-icon" label="模板位置">
  292. <el-input v-model="formEditNodeModel.position" :autosize="{ minRows: 3, maxRows: 6 }"
  293. type="textarea"/>
  294. <el-tooltip content="一键复制模板位置">
  295. <HcIcon name="file-copy-2" @click="copyPositionText(formEditNodeModel.position)"/>
  296. </el-tooltip>
  297. </el-form-item>
  298. </el-form>
  299. </HcDialog>
  300. <!--复制节点-->
  301. <HcDialog :loading="copyNodeLoading" :show="copyNodeModal" :widths="copyNodeTabKey === '1'?'600px':'1200px'"
  302. loading-text="复制节点中,请耐心等待..."
  303. title="复制节点" @close="copyNodeModal = false">
  304. <div class="header-new-switch">
  305. <el-form ref="formCopyNodeModelRef" :model="formCopyNodeModel" label-position="left"
  306. :rules="formCopyNodeModelRules" label-width="auto" size="large">
  307. <el-form-item label="是否复制数据" prop="isCopyData" style="margin-bottom: 0;" >
  308. <!-- <el-input v-model="formCopyNodeModel.classify" placeholder="请输入节点名称"/> -->
  309. <el-radio-group v-model="isCopyData">
  310. <el-radio :label="1">是</el-radio>
  311. <el-radio :label="0">否</el-radio>
  312. </el-radio-group>
  313. </el-form-item>
  314. <el-form-item label="所属方" prop="classify" style="margin-bottom: 0;" v-if="isCopyData===1">
  315. <!-- <el-input v-model="formCopyNodeModel.classify" placeholder="请输入节点名称"/> -->
  316. <el-checkbox-group v-model="classifyList">
  317. <el-checkbox label="施工"/>
  318. <el-checkbox label="监理"/>
  319. </el-checkbox-group>
  320. </el-form-item>
  321. </el-form>
  322. <!--HcNewSwitch :datas="authBtnTabdata" :keys="classifyType" :round="false" size="default"
  323. @change="classifyTypeTabClick"/-->
  324. </div>
  325. <div v-if="copyNodeTabKey === '1'" class="copy-node-form-box">
  326. <el-form ref="formCopyNodeModelRef" :model="formCopyNodeModel"
  327. :rules="formCopyNodeModelRules" label-width="auto" size="large">
  328. <el-form-item v-if="copyNodeTabKey === '1'" label="节点名称" prop="title" style="margin-bottom: 0;">
  329. <el-input v-model="formCopyNodeModel.title" placeholder="请输入节点名称"/>
  330. </el-form-item>
  331. <el-form-item v-if="copyNodeTabKey === '1'" label="划分编号" prop="partitionCode"
  332. style="margin-top: 10px;">
  333. <el-input v-model="formCopyNodeModel.partitionCode" placeholder="请输入划分编号"/>
  334. </el-form-item>
  335. </el-form>
  336. </div>
  337. <div v-if="copyNodeTabKey === '3'" class="copy-node-form-box">
  338. <el-form ref="formCopyNodeModelRef" :model="formCopyNodeModel"
  339. :rules="formCopyNodeModelRules" label-width="auto" size="large">
  340. <el-form-item label="所属方" prop="classify" style="margin-bottom: 0;">
  341. <!-- <el-input v-model="formCopyNodeModel.classify" placeholder="请输入节点名称"/> -->
  342. <el-checkbox-group v-model="classifyList">
  343. <el-checkbox label="施工"/>
  344. <el-checkbox label="监理"/>
  345. </el-checkbox-group>
  346. </el-form-item>
  347. </el-form>
  348. </div>
  349. <div v-if="copyNodeTabKey !== '1'" class="copy-node-many-box">
  350. <div class="copy-node-many-tree">
  351. <el-scrollbar>
  352. <WbsTree :autoExpandKeys="TreeAutoExpandKeys" :contractId="contractId" :isAutoClick="false"
  353. :isAutoKeys="false" :projectId="projectId" :classifyType="authBtnTabKey"
  354. idPrefix="tree-node-copy-" @nodeTap="copyNodeElTreeClick"/>
  355. </el-scrollbar>
  356. </div>
  357. <div class="copy-node-many-table">
  358. <el-scrollbar>
  359. <el-table :data="copyNodeTable" border stripe>
  360. <el-table-column label="复制到的位置" prop="title"/>
  361. <el-table-column v-if="copyNodeTabKey === '2'" label="节点名称" prop="nodeName">
  362. <template #default="{row}">
  363. <el-form ref="copyNodeTableRef" :model="row" :rules="copyNodeTableRules"
  364. label-width="0" size="large">
  365. <el-form-item prop="nodeName" style="margin-bottom: 0;">
  366. <el-input v-model="row.nodeName" placeholder="请输入节点名称"/>
  367. </el-form-item>
  368. </el-form>
  369. </template>
  370. </el-table-column>
  371. <el-table-column v-if="copyNodeTabKey === '2'" label="划分编号" prop="partitionCode">
  372. <template #default="{row}">
  373. <el-form ref="copyNodeTableRef" :model="row" :rules="copyNodeTableRules"
  374. label-width="0" size="large">
  375. <el-form-item prop="partitionCode" style="margin-bottom: 0;">
  376. <el-input v-model="row.partitionCode" placeholder="请输入划分编号"/>
  377. </el-form-item>
  378. </el-form>
  379. </template>
  380. </el-table-column>
  381. <el-table-column align="center" label="操作" prop="action" width="120">
  382. <template #default="{_,$index}">
  383. <el-button plain type="danger" @click="copyNodeTableDel($index)">删除</el-button>
  384. </template>
  385. </el-table-column>
  386. </el-table>
  387. </el-scrollbar>
  388. </div>
  389. </div>
  390. <template #footer>
  391. <div class="lr-dialog-footer">
  392. <div class="left">
  393. <template v-for="item in copyNodeTab">
  394. <el-button v-if="item?.key === copyNodeTabKey" plain size="large" type="primary"
  395. @click="copyNodeTabChange(item?.key)">{{ item.name }}
  396. </el-button>
  397. <el-button v-else bg size="large" text @click="copyNodeTabChange(item?.key)">
  398. {{ item.name }}
  399. </el-button>
  400. </template>
  401. </div>
  402. <div class="right">
  403. <el-button :disabled="copyNodeLoading" size="large" @click="copyNodeModal = false">取消
  404. </el-button>
  405. <el-button :loading="copyNodeLoading" hc-btn type="primary" @click="copyNodeClick">提交
  406. </el-button>
  407. </div>
  408. </div>
  409. </template>
  410. </HcDialog>
  411. <!--新增子节点-->
  412. <HcDialog :loading="addNodeLoading" :show="addNodeModal" loading-text="新增节点中,请耐心等待..."
  413. title="新增子节点"
  414. widths="720px" @close="addNodeModal = false">
  415. <el-alert :closable="false" title="双击节点,可编辑节点名称,编辑完成后,请按回车或输入框消失后,再点提交"
  416. type="warning"/>
  417. <HcTreeNode v-if="addTreeNodeType === '1'" :nodeId="addTreeNodeId" :oldId="addTreeNodeOldId" :contractId="contractId" :wbsId="projectInfo.referenceWbsTemplateId"
  418. :projectId="projectId" @check-change="addTreeNodeCheckChange"/>
  419. <HcTreeNode v-if="addTreeNodeType === '2'" :nodeId="addTreeNodeId" :oldId="addTreeNodeOldId" :contractId="contractId" :wbsId="projectInfo.referenceWbsTemplateId"
  420. :projectId="projectId"
  421. strictly @check-change="addTreeNodeCheckChange"/>
  422. <template #footer>
  423. <div class="lr-dialog-footer">
  424. <div class="left flex items-center">
  425. <div class="mr-4">选中方式:</div>
  426. <el-radio-group v-model="addTreeNodeType">
  427. <el-radio label="1">当前及子节点</el-radio>
  428. <el-radio class="ml-4" label="2">仅当前节点</el-radio>
  429. </el-radio-group>
  430. </div>
  431. <div class="right">
  432. <el-button size="large" @click="addNodeModal = false">取消</el-button>
  433. <el-button :loading="addNodeLoading" hc-btn type="primary" @click="addNodeClick">提交
  434. </el-button>
  435. </div>
  436. </div>
  437. </template>
  438. </HcDialog>
  439. <!--调整排序-->
  440. <HcDialog :loading="sortNodeLoading" :show="sortNodeModal" title="调整排序" widths="700px"
  441. @close="sortNodeModal = false" @save="sortNodeClick">
  442. <el-alert :closable="false" title="可拖动排序,也可在后面点击图标,切换排序" type="warning"/>
  443. <div class="sort-node-body-box list-group header">
  444. <div class="list-group-item">
  445. <div class="index-box">序号</div>
  446. <div class="title-box">节点名称</div>
  447. <div class="icon-box">排序</div>
  448. </div>
  449. </div>
  450. <Draggable :list="sortNodeData" class="sort-node-body-box list-group" ghost-class="ghost" item-key="id"
  451. @end="sortNodeDrag = false" @start="sortNodeDrag = true">
  452. <template #item="{element, index}">
  453. <div class="list-group-item">
  454. <div class="index-box">{{ index + 1 }}</div>
  455. <div class="title-box">{{ element.title }}</div>
  456. <div class="icon-box">
  457. <span class="icon" @click="downSortClick(index)">
  458. <HcIcon name="arrow-down" ui="text-lg"/>
  459. </span>
  460. <span class="icon" @click="upSortClick(index)">
  461. <HcIcon name="arrow-up" ui="text-lg"/>
  462. </span>
  463. </div>
  464. </div>
  465. </template>
  466. </Draggable>
  467. </HcDialog>
  468. <!--批量上报审批-->
  469. <HcReportModal :addition="reportAddition"
  470. :contractId="contractInfo?.contractType==2?nodeDataInfo?.contractIdRelation:contractId"
  471. :ids="reportIds"
  472. :projectId="projectId"
  473. :show="showReportModal"
  474. :taskName="reportTaskName"
  475. :typeData="reportTypeData"
  476. title="批量上报审批" type="wbs" url="informationWriteQuery/taskOne"
  477. @finish="showReportFinish" @hide="showReportModal = false"/>
  478. <!--查看附件-->
  479. <HcDialog :footer="false" :show="attachmentModal" isTable title="附件列表" widths="780px"
  480. @close="attachmentModal = false">
  481. <div class="hc-attachment-card">
  482. <div class="hc-attachment-header">表单名称</div>
  483. <div class="hc-attachment-content">
  484. <div class="hc-attachment-item">
  485. <div class="hc-attachment-file-name">
  486. <HcIcon name="attachment"/>
  487. <div class="name">文件名称</div>
  488. </div>
  489. <div class="hc-attachment-btn-box">
  490. <el-button plain size="small" type="primary">
  491. <HcIcon name="eye"/>
  492. <span>预览</span>
  493. </el-button>
  494. <el-button plain size="small" style="margin-left: 16px" type="danger">
  495. <HcIcon name="close"/>
  496. <span>删除</span>
  497. </el-button>
  498. </div>
  499. </div>
  500. <div class="hc-attachment-item">
  501. <div class="hc-attachment-file-name">
  502. <HcIcon name="attachment"/>
  503. <div class="name">文件名称</div>
  504. </div>
  505. <div class="hc-attachment-btn-box">
  506. <el-button plain size="small" type="primary">
  507. <HcIcon name="eye"/>
  508. <span>预览</span>
  509. </el-button>
  510. <el-button plain size="small" style="margin-left: 16px" type="danger">
  511. <HcIcon name="close"/>
  512. <span>删除</span>
  513. </el-button>
  514. </div>
  515. </div>
  516. <div class="hc-attachment-item">
  517. <div class="hc-attachment-file-name">
  518. <HcIcon name="attachment"/>
  519. <div class="name">文件名称</div>
  520. </div>
  521. <div class="hc-attachment-btn-box">
  522. <el-button plain size="small" type="primary">
  523. <HcIcon name="eye"/>
  524. <span>预览</span>
  525. </el-button>
  526. <el-button plain size="small" style="margin-left: 16px" type="danger">
  527. <HcIcon name="close"/>
  528. <span>删除</span>
  529. </el-button>
  530. </div>
  531. </div>
  532. </div>
  533. </div>
  534. <div class="hc-attachment-card">
  535. <div class="hc-attachment-header">表单名称</div>
  536. <div class="hc-attachment-content">
  537. <div class="hc-attachment-item">
  538. <div class="hc-attachment-file-name">
  539. <HcIcon name="attachment"/>
  540. <div class="name">文件名称</div>
  541. </div>
  542. <div class="hc-attachment-btn-box">
  543. <el-button plain size="small" type="primary">
  544. <HcIcon name="eye"/>
  545. <span>预览</span>
  546. </el-button>
  547. <el-button plain size="small" style="margin-left: 16px" type="danger">
  548. <HcIcon name="close"/>
  549. <span>删除</span>
  550. </el-button>
  551. </div>
  552. </div>
  553. <div class="hc-attachment-item">
  554. <div class="hc-attachment-file-name">
  555. <HcIcon name="attachment"/>
  556. <div class="name">文件名称</div>
  557. </div>
  558. <div class="hc-attachment-btn-box">
  559. <el-button plain size="small" type="primary">
  560. <HcIcon name="eye"/>
  561. <span>预览</span>
  562. </el-button>
  563. <el-button plain size="small" style="margin-left: 16px" type="danger">
  564. <HcIcon name="close"/>
  565. <span>删除</span>
  566. </el-button>
  567. </div>
  568. </div>
  569. <div class="hc-attachment-item">
  570. <div class="hc-attachment-file-name">
  571. <HcIcon name="attachment"/>
  572. <div class="name">文件名称</div>
  573. </div>
  574. <div class="hc-attachment-btn-box">
  575. <el-button plain size="small" type="primary">
  576. <HcIcon name="eye"/>
  577. <span>预览</span>
  578. </el-button>
  579. <el-button plain size="small" style="margin-left: 16px" type="danger">
  580. <HcIcon name="close"/>
  581. <span>删除</span>
  582. </el-button>
  583. </div>
  584. </div>
  585. </div>
  586. </div>
  587. <div class="hc-attachment-card">
  588. <div class="hc-attachment-header">表单名称</div>
  589. <div class="hc-attachment-content">
  590. <div class="hc-attachment-item">
  591. <div class="hc-attachment-file-name">
  592. <HcIcon name="attachment"/>
  593. <div class="name">文件名称</div>
  594. </div>
  595. <div class="hc-attachment-btn-box">
  596. <el-button plain size="small" type="primary">
  597. <HcIcon name="eye"/>
  598. <span>预览</span>
  599. </el-button>
  600. <el-button plain size="small" style="margin-left: 16px" type="danger">
  601. <HcIcon name="close"/>
  602. <span>删除</span>
  603. </el-button>
  604. </div>
  605. </div>
  606. <div class="hc-attachment-item">
  607. <div class="hc-attachment-file-name">
  608. <HcIcon name="attachment"/>
  609. <div class="name">文件名称</div>
  610. </div>
  611. <div class="hc-attachment-btn-box">
  612. <el-button plain size="small" type="primary">
  613. <HcIcon name="eye"/>
  614. <span>预览</span>
  615. </el-button>
  616. <el-button plain size="small" style="margin-left: 16px" type="danger">
  617. <HcIcon name="close"/>
  618. <span>删除</span>
  619. </el-button>
  620. </div>
  621. </div>
  622. <div class="hc-attachment-item">
  623. <div class="hc-attachment-file-name">
  624. <HcIcon name="attachment"/>
  625. <div class="name">文件名称</div>
  626. </div>
  627. <div class="hc-attachment-btn-box">
  628. <el-button plain size="small" type="primary">
  629. <HcIcon name="eye"/>
  630. <span>预览</span>
  631. </el-button>
  632. <el-button plain size="small" style="margin-left: 16px" type="danger">
  633. <HcIcon name="close"/>
  634. <span>删除</span>
  635. </el-button>
  636. </div>
  637. </div>
  638. </div>
  639. </div>
  640. </HcDialog>
  641. </div>
  642. </template>
  643. <script setup>
  644. import {ref, watch, onMounted} from "vue";
  645. import {useRouter, useRoute} from 'vue-router'
  646. import {useAppStore} from "~src/store";
  647. import {HcIsButton} from "~src/plugins/IsButtons";
  648. import CollapseForm from "./collapse-form/index.vue"
  649. import NodeTree from "./components/nodeTree/index.vue"
  650. import HcTreeNode from "./components/HcTreeNode.vue"
  651. import HcTreeData from "./components/HcTreeData.vue"
  652. import HcTreeDataV2 from "./components/HcTreeDataV2.vue"
  653. import WbsTree from "./components/WbsTree.vue"
  654. import {getTokenHeader} from '~src/api/request/header';
  655. import {getStoreValue, setStoreValue} from '~src/utils/storage'
  656. import {deepClone, formValidate, setCopyText, getObjValue, getArrValue, getObjVal, isString} from "js-fast-way"
  657. import {getDictionary, eVisaTaskCheckApi} from "~api/other"
  658. import wbsApi from "~api/data-fill/wbs"
  659. import queryApi from '~api/data-fill/query';
  660. import Draggable from "vuedraggable";
  661. //初始变量
  662. const router = useRouter()
  663. const useRoutes = useRoute()
  664. const useAppState = useAppStore()
  665. //全局变量
  666. const projectId = ref(useAppState.getProjectId);
  667. const contractId = ref(useAppState.getContractId);
  668. const projectInfo = ref(useAppState.getProjectInfo);
  669. const contractInfo = ref(useAppState.getContractInfo);
  670. const isCollapse = ref(useAppState.getCollapse)
  671. const userInfo = ref(useAppState.getUserInfo);
  672. //路由参数
  673. const routerQuery = useRoutes?.query;
  674. // const typeName = routerQuery?.type || 'map'
  675. const typeName = routerQuery?.type || 'tree'
  676. //是否是抽屉
  677. const isDrawType = ref(true)
  678. //自动展开缓存
  679. const TreeAutoExpandKeys = ref(getStoreValue('wbsTreeExpandKeys') || [])
  680. //树搜索
  681. const isSearchTree = ref(false)
  682. const wbstreeKey = ref(Math.random())
  683. const searchElTreeLoadNode = ref(true)
  684. const searchTreeHeight = ref()
  685. const getSearchTreeData = async () => {
  686. searchElTreeLoadNode.value = true
  687. if (contractInfo.value?.contractType == 2 || contractInfo.value?.contractType == 3) {
  688. const {error, code, data} = await queryApi.getTreeallJl({
  689. contractId: contractId.value,
  690. })
  691. //判断状态
  692. if (!error && code === 200) {
  693. // searchTreeData.value = getArrValue(data)
  694. let searchobj = getObjValue(data)
  695. let searcharr = []
  696. for (let key in searchobj) {
  697. searcharr.push(searchobj[key][0])
  698. }
  699. searchTreeData.value = searcharr
  700. searchElTreeLoadNode.value = false
  701. treeLoading.value = false
  702. } else {
  703. treeLoading.value = false
  704. searchElTreeLoadNode.value = false
  705. searchTreeData.value = []
  706. }
  707. console.log(searchTreeData.value)
  708. } else {
  709. searchElTreeLoadNode.value = true
  710. const {error, code, data} = await queryApi.getTreeall({
  711. contractId: contractId.value,
  712. projectId: projectId.value,
  713. wbsId: projectInfo?.value.referenceWbsTemplateId
  714. })
  715. //判断状态
  716. if (!error && code === 200) {
  717. searchTreeData.value = getArrValue(data)
  718. searchElTreeLoadNode.value = false
  719. treeLoading.value = false
  720. } else {
  721. treeLoading.value = false
  722. searchElTreeLoadNode.value = false
  723. searchTreeData.value = []
  724. }
  725. console.log(searchTreeData.value)
  726. }
  727. }
  728. //监听
  729. watch(() => [
  730. useAppState.getCollapse,
  731. ], ([Collapse]) => {
  732. isCollapse.value = Collapse
  733. })
  734. watch(projectId, (val) => {
  735. if (val) {
  736. getSearchTreeData()
  737. }
  738. },
  739. {
  740. immediate: true
  741. }
  742. )
  743. //渲染完成
  744. onMounted(() => {
  745. treeLoading.value = typeName === 'tree';
  746. setContractType(contractInfo.value?.contractType)
  747. getDictionaryApi()
  748. })
  749. //身份按钮切换数据
  750. const authBtnTabKey = ref('1')
  751. //变量
  752. const wbstree = ref(null)
  753. const authBtnTabClick = (val) => {
  754. if (!primaryKeyId.value) {
  755. window?.$message?.warning('请先在左侧项目树选择一个节点')
  756. } else if (val['key'] !== authBtnTabKey.value) {
  757. authBtnTabKey.value = val['key']
  758. // wbstreeKey.value=new Date().toString()
  759. getTableDataAll()
  760. }
  761. }
  762. //contractType, 1施工,2监理
  763. const setContractType = (contractType) => {
  764. if (contractType <= 0) {
  765. authBtnTabKey.value = '1'
  766. } else if (contractType === 3) {
  767. authBtnTabKey.value = '1'
  768. } else {
  769. authBtnTabKey.value = contractType + ''
  770. }
  771. setElTreeMenu(contractType)
  772. }
  773. const getTableDataAll = () => {
  774. searchNodeAllTable()
  775. queryNodeStatus()
  776. // wbstree.value.resetNode().then((res)=>{
  777. // if(res){
  778. // searchNodeAllTable()
  779. // queryNodeStatus()
  780. // }
  781. // })
  782. }
  783. //结构类型tab数据和相关处理
  784. const wbsTypeTabKey = ref(typeName)
  785. const wbsTypeTab = ref([
  786. {key: 'map', name: '导图结构填报'},
  787. {key: 'tree', name: '树形结构填报'}
  788. ]);
  789. const authBtnTabdata = ref([
  790. {key: '1', name: '施工质检'},
  791. {key: '2', name: '监理质检'}
  792. ]);
  793. const wbsTypeTabChange = (item) => {
  794. wbsTypeTabKey.value = item?.key;
  795. ListItemDatas.value = []
  796. isDrawer.value = false;
  797. treeLoading.value = typeName === 'tree';
  798. //路由跳转
  799. router.push({
  800. path: useRoutes.path,
  801. query: {
  802. type: item?.key
  803. }
  804. })
  805. getSearchTreeData()
  806. }
  807. //上传文件的
  808. const action = ref("/api/blade-resource/oss/endpoint/put-file")
  809. const accept = ref("image/png,image/jpg,image/jpeg")
  810. const NodeTreeAccordion = ref(true)
  811. //设置树菜单数据
  812. const ElTreeMenu = ref([])
  813. const TreeMark = ref(false)
  814. const setElTreeMenu = (contractType) => {
  815. let newArr = [];
  816. if (contractType === 1) {
  817. if (HcIsButton('wbs_tree_add')) {
  818. newArr.push({icon: 'add-circle', label: '新增节点', key: "add"})
  819. }
  820. if (HcIsButton('wbs_tree_edit')) {
  821. newArr.push({icon: 'draft', label: '编辑节点', key: "edit"})
  822. }
  823. if (HcIsButton('wbs_tree_copy')) {
  824. newArr.push({icon: 'file-copy-2', label: '复制节点', key: "copy"})
  825. }
  826. if (HcIsButton('wbs_tree_mark')) {
  827. newArr.push({icon: 'star', label: '标记为首件', key: "mark"})
  828. TreeMark.value = true
  829. }
  830. if (HcIsButton('wbs_tree_upload')) {
  831. newArr.push({icon: 'file-upload', label: '上传图纸', key: "upload"})
  832. }
  833. if (HcIsButton('wbs_tree_sort')) {
  834. newArr.push({icon: 'sort-asc', label: '调整排序', key: "sort"})
  835. }
  836. if (HcIsButton('wbs_tree_del')) {
  837. newArr.push({icon: 'delete-bin', label: '删除节点', key: "del"})
  838. }
  839. if (HcIsButton('wbs_views_division_btn')) {
  840. newArr.push({icon: 'folder-shared', label: '工程划分', key: "nodetree"})
  841. }
  842. } else if (contractType === 2) {
  843. if (HcIsButton('wbs_tree_add')) {
  844. newArr.push({icon: 'add-circle', label: '新增节点', key: "add"})
  845. }
  846. if (HcIsButton('wbs_tree_copy')) {
  847. newArr.push({icon: 'file-copy-2', label: '复制节点', key: "copy"})
  848. }
  849. }
  850. ElTreeMenu.value = newArr
  851. }
  852. //树相关变量
  853. const primaryKeyId = ref('')
  854. const nodeItemInfo = ref({})
  855. const nodeDataInfo = ref({})
  856. const searchTreeVal = ref('')
  857. const searchTreeData = ref([])
  858. //回车
  859. const searchTreeKeyUp = (e) => {
  860. if (e.key === "Enter") {
  861. searchTreeClick()
  862. }
  863. }
  864. const changeisSearch = () => {
  865. isSearchTree.value = false
  866. }
  867. const changetreelaod = (val) => {
  868. treeLoading.value = val
  869. }
  870. const treeLoading = ref(false)
  871. const searchTreeClick = async () => {
  872. searchTreeHeight.value = document.getElementById('hc-tree-scrollbar').offsetHeight;
  873. isSearchTree.value = true
  874. //treeLoading.value = true
  875. if (searchElTreeLoadNode.value === true) {
  876. treeLoading.value = true
  877. window?.$message?.warning('请加载完数据再次进行搜索')
  878. searchTreeVal.value=''
  879. } else {
  880. isSearchTree.value = true
  881. }
  882. }
  883. // if (searchTreeVal.value) {
  884. // isSearchTree.value = true
  885. // treeLoading.value = true
  886. // const {error, code, data} = await wbsApi.searchContractTree({
  887. // contractId: contractId.value,
  888. // queryValue: searchTreeVal.value
  889. // })
  890. // //判断状态
  891. // if (!error && code === 200) {
  892. // searchTreeData.value = getArrValue(data)
  893. // treeLoading.value = false
  894. // } else {
  895. // treeLoading.value = false
  896. // searchTreeData.value = []
  897. // }
  898. // } else {
  899. // treeLoading.value = false
  900. // isSearchTree.value = false
  901. // }
  902. //树被点击
  903. const wbsElTreeClick = ({node, data, keys}) => {
  904. nodeItemInfo.value = node
  905. nodeDataInfo.value = data
  906. primaryKeyId.value = data?.primaryKeyId || ''
  907. setStoreValue('wbsTreeExpandKeys', keys)
  908. TreeAutoExpandKeys.value = keys || []
  909. getTableDataAll()
  910. }
  911. //树加载完成
  912. const ElTreeNodeLoading = () => {
  913. treeLoading.value = false
  914. }
  915. //树菜单被点击
  916. const ElTreeMenuClick = async ({key, node, data, keys}) => {
  917. nodeItemInfo.value = node
  918. nodeDataInfo.value = data
  919. setStoreValue('wbsTreeExpandKeys', keys)
  920. setTreeMenuDataClick({key, node, data})
  921. }
  922. //导图结构数据
  923. const NodeTreeRef = ref(null)
  924. //鼠标左键单击事件
  925. const NodeTreeClick = ({keys}) => {
  926. setStoreValue('wbsTreeExpandKeys', keys)
  927. TreeAutoExpandKeys.value = keys || []
  928. }
  929. //双击事件
  930. const isDrawer = ref(false)
  931. const NodeTreeDblClick = ({node, data}) => {
  932. nodeItemInfo.value = node
  933. nodeDataInfo.value = data
  934. primaryKeyId.value = data?.primaryKeyId || ''
  935. isDrawer.value = true;
  936. getTableDataAll()
  937. }
  938. const drawerClose = () => {
  939. isDrawer.value = false;
  940. ListItemDatas.value = []
  941. }
  942. //导图树菜单被点击
  943. const NodeTreeMenuClick = async ({key, node, data}) => {
  944. nodeItemInfo.value = node
  945. nodeDataInfo.value = data
  946. setTreeMenuDataClick({key, node, data})
  947. }
  948. //处理菜单被点击数据
  949. const setTreeMenuDataClick = ({key, node, data}) => {
  950. const tabKey = wbsTypeTabKey.value
  951. if (key === 'mark' || key === 'cancel_mark') {
  952. firstItemBox()
  953. } else if (key === 'edit') {
  954. let form = {}
  955. if (tabKey === 'tree') {
  956. const parent = deepClone(node?.parent?.data || {})
  957. form = {...deepClone(data), parent: parent}
  958. } else if (tabKey === 'map') {
  959. const parent = deepClone(node?.parentNodes?.data || {})
  960. form = {...deepClone(data), parent: parent}
  961. }
  962. formEditNodeModel.value = form
  963. editNodeModal.value = true
  964. //处理路径
  965. let pathArr = [];
  966. getPathName(node, pathArr);
  967. form.position = pathArr.join("\\")
  968. formEditNodeModel.value = form
  969. } else if (key === 'copy') {
  970. if (tabKey === 'tree') {
  971. const parent = deepClone(node?.parent?.data || {})
  972. formCopyNodeModel.value = {...deepClone(data), parent: parent}
  973. } else if (tabKey === 'map') {
  974. const parent = deepClone(node?.parentNodes?.data || {})
  975. formCopyNodeModel.value = {...deepClone(data), parent: parent}
  976. }
  977. classifyType.value = authBtnTabKey.value
  978. copyNodeTabKey.value = '1'
  979. copyNodeTable.value = []
  980. copyNodeLoading.value = false
  981. copyNodeModal.value = true
  982. } else if (key === 'add') {
  983. console.log(data,'data');
  984. addTreeNodeId.value = data?.primaryKeyId
  985. addTreeNodeOldId.value = data?.oldId
  986. addNodeLoading.value = false
  987. addNodeModal.value = true
  988. } else if (key === 'upload') {
  989. document.getElementById('upload-drawing').click()
  990. } else if (key === 'del') {
  991. if (data['colorStatus'] === 1 || data['colorStatus'] === 2) {
  992. delModalClick()
  993. } else {
  994. window?.$message?.warning('该节点已存在上报数据,不允许删除')
  995. }
  996. } else if (key === 'sort') {
  997. let nodes = [], childNodes = []
  998. if (tabKey === 'tree') {
  999. childNodes = node?.parent?.childNodes || node?.parent?.children||[]
  1000. } else if (tabKey === 'map') {
  1001. childNodes = node?.parentNodes?.childrenNodes || []
  1002. }
  1003. for (let i = 0; i < childNodes.length; i++) {
  1004. const res = childNodes[i]?.data
  1005. nodes.push({
  1006. id: res?.primaryKeyId,
  1007. title: res?.title
  1008. })
  1009. }
  1010. sortNodeData.value = nodes
  1011. sortNodeModal.value = true
  1012. } else if (key === 'nodetree') {
  1013. divisionClick()
  1014. }
  1015. }
  1016. //获取节点的路径名字
  1017. const getPathName = (node, pathArr) => {
  1018. if (node.parent?.parent) {
  1019. pathArr.unshift(node.data?.title.replace(/(^\s*)|(\s*$)/g, "")); //去掉头尾空格
  1020. getPathName(node.parent, pathArr);
  1021. } else {
  1022. //根节点结束
  1023. pathArr.unshift(node.data?.title.replace(/(^\s*)|(\s*$)/g, "")); //去掉头尾空格
  1024. return pathArr;
  1025. }
  1026. }
  1027. //上传前
  1028. const loadingReactive = ref(null)
  1029. const beforeUpload = () => {
  1030. loadingReactive.value = window.$loading?.service({
  1031. lock: true,
  1032. text: '图纸上传中...',
  1033. background: 'rgba(0, 0, 0, 0.7)',
  1034. })
  1035. return true
  1036. }
  1037. //上传完成
  1038. const uploadFinish = async (response) => {
  1039. const res = getObjValue(response.data)
  1040. const info = nodeDataInfo.value;
  1041. if (res?.link) {
  1042. const {error, code, data} = await wbsApi.saveContractTreeDrawings({
  1043. fileUrl: res?.link,
  1044. id: info['drawingsId'],
  1045. primaryKeyId: info['primaryKeyId']
  1046. }, false)
  1047. //处理数据
  1048. loadingReactive.value.close();
  1049. if (!error && code === 200) {
  1050. nodeDataInfo.value['drawingsId'] = data
  1051. nodeDataInfo.value['fileUrl'] = res?.link
  1052. window?.$message?.success('图纸上传成功')
  1053. } else {
  1054. window?.$message?.error('图纸保存失败')
  1055. }
  1056. } else {
  1057. loadingReactive.value.close();
  1058. window?.$message?.error('图纸上传失败')
  1059. }
  1060. }
  1061. //上传失败
  1062. const uploadError = () => {
  1063. loadingReactive.value.close();
  1064. window?.$message?.error('图纸上传失败')
  1065. }
  1066. //确认标记为首件
  1067. const firstItemBox = () => {
  1068. const info = nodeDataInfo.value;
  1069. window?.$messageBox?.alert(`<div class="text-base font-bold">
  1070. <span>请确认将</span>
  1071. <span class="text-main">【${info['title']}】</span>
  1072. <span>${info['isFirst'] ? '取消' : ''}标记为首件</span>
  1073. </div>`, '标记首件制', {
  1074. showCancelButton: true,
  1075. dangerouslyUseHTMLString: true,
  1076. callback: (action) => {
  1077. if (action === 'confirm') {
  1078. firstItemHttp(info)
  1079. }
  1080. }
  1081. })
  1082. }
  1083. //首件请求
  1084. const firstItemHttp = async (info) => {
  1085. const {error, code} = await wbsApi.wbsTreeFirstSave({
  1086. primaryKeyId: info['primaryKeyId'],
  1087. saveOrDeleted: !!info['isFirst'] ? 1 : 0,
  1088. })
  1089. //处理数据
  1090. if (!error && code === 200) {
  1091. window?.$message?.success('操作成功')
  1092. window?.location?.reload() //刷新页面
  1093. }
  1094. }
  1095. //编辑节点
  1096. const editNodeModal = ref(false)
  1097. //获取节点类型
  1098. const nodeTypeData = ref([])
  1099. const getDictionaryApi = async () => {
  1100. const {data} = await getDictionary({
  1101. code: 'wbs_node_type'
  1102. })
  1103. //处理数据
  1104. let newArr = []
  1105. const newData = getArrValue(data)
  1106. for (let i = 0; i < newData.length; i++) {
  1107. newArr.push({
  1108. label: newData[i]['dictValue'],
  1109. value: Number(newData[i]['dictKey']),
  1110. })
  1111. }
  1112. nodeTypeData.value = newArr
  1113. }
  1114. const formEditNodeRef = ref(null)
  1115. const formEditNodeModel = ref({})
  1116. const formEditNodeRules = {
  1117. title: {
  1118. required: true,
  1119. trigger: 'blur',
  1120. message: "请输入节点名称"
  1121. },
  1122. }
  1123. const editNodeLoading = ref(false)
  1124. //保存编辑节点数据
  1125. const editNodeClick = async () => {
  1126. const validate = await formValidate(formEditNodeRef.value)
  1127. if (validate) {
  1128. //发起请求
  1129. editNodeLoading.value = true
  1130. const {primaryKeyId, title, partitionCode} = formEditNodeModel.value
  1131. const {error, code} = await wbsApi.wbsTreeUpdateNode({
  1132. nodeName: title || '',
  1133. pKeyId: primaryKeyId || '',
  1134. partitionCode: partitionCode || ''
  1135. })
  1136. //处理数据
  1137. editNodeLoading.value = false
  1138. if (!error && code === 200) {
  1139. window?.$message?.success('修改成功')
  1140. nodeDataInfo.value['title'] = title || ''
  1141. nodeDataInfo.value['partitionCode'] = partitionCode || ''
  1142. editNodeModal.value = false
  1143. window?.location?.reload() //刷新页面
  1144. }
  1145. }
  1146. }
  1147. //复制节点
  1148. const copyNodeModal = ref(false)
  1149. //复制节点类型tab数据和相关处理
  1150. const copyNodeTabKey = ref('')
  1151. const copyNodeTab = ref([
  1152. {key: '1', name: '单份复制'},
  1153. {key: '2', name: '多份复制'},
  1154. //{key: '3', name: '复制数据'}
  1155. ]);
  1156. const copyNodeTabChange = (key) => {
  1157. if (key !== copyNodeTabKey.value) {
  1158. copyNodeTabKey.value = key;
  1159. copyNodeTable.value = []
  1160. copyNodeLoading.value = false
  1161. }
  1162. }
  1163. //复制节点变量
  1164. const copyNodeLoading = ref(false)
  1165. const formCopyNodeModel = ref({})
  1166. const classifyList = ref([])
  1167. const copyNodeTable = ref([])
  1168. const isCopyData=ref(0)
  1169. //复制树被点击
  1170. const copyNodeElTreeClick = ({data,node}) => {
  1171. const TabKey = copyNodeTabKey.value;
  1172. const {title, type, partitionCode} = formCopyNodeModel.value;
  1173. if (TabKey === '2') {
  1174. // setCopyNodeTable(data, title, partitionCode)
  1175. //1 单位工程,2 分部工程,3 子分部工程,4 分项工程, 5 子分项工程,6 工序
  1176. // //不能复制到本身节点下
  1177. // //只能往上一级点击,不能跨层级点击
  1178. // //已上报的工序节点不能点击选择
  1179. // //如果选择的是父级节点,那不能复制到子级节点
  1180. if(data['colorStatus']===2||data['colorStatus']==1){//已上报的工序不能点击
  1181. if (data['id'] !== formCopyNodeModel.value.id) {//不能复制到本身节点下
  1182. //只能往上一级点击,不能跨层级点击
  1183. //如果选择的是父级节点,那不能复制到子级节点
  1184. if (type === 6 && (data['type'] === 4 || data['type'] === 5 || data['type'] == 6)) {
  1185. setCopyNodeTable(data, title)
  1186. }
  1187. if (type === 5 && data['type'] === 4) {
  1188. setCopyNodeTable(data, title, partitionCode)
  1189. }
  1190. if (type === 4 && (data['type'] === 2 || data['type'] === 3)) {
  1191. setCopyNodeTable(data, title, partitionCode)
  1192. }
  1193. if (type === 3 && data['type'] === 2) {
  1194. setCopyNodeTable(data, title, partitionCode)
  1195. }
  1196. if (type === 2 && data['type'] === 1) {
  1197. setCopyNodeTable(data, title, partitionCode)
  1198. }
  1199. if (type === 1 && data['type'] === 1) {
  1200. setCopyNodeTable(data, title, partitionCode)
  1201. }
  1202. }
  1203. }else{
  1204. window?.$message?.warning('该节点已存在上报数据,不允许复制')
  1205. }
  1206. } else if (TabKey === '3') {
  1207. console.log(1111111);
  1208. setCopyNodeTable(data, data?.title)
  1209. }
  1210. }
  1211. const setCopyNodeTable = (data, title) => {
  1212. copyNodeTable.value.push({
  1213. title: data?.title || '',
  1214. nodeName: title || '',
  1215. primaryKeyId: data?.primaryKeyId || '',
  1216. parentId: data?.parentId || '',
  1217. id: data?.id || '',
  1218. })
  1219. }
  1220. //节点表单
  1221. const formCopyNodeModelRef = ref(null)
  1222. const formCopyNodeModelRules = {
  1223. title: {
  1224. required: true,
  1225. trigger: "blur",
  1226. message: "请输入节点名称"
  1227. }
  1228. }
  1229. //表格节点表单
  1230. const copyNodeTableRef = ref(null)
  1231. const copyNodeTableRules = {
  1232. nodeName: {
  1233. required: true,
  1234. trigger: "blur",
  1235. message: "请输入节点名称"
  1236. }
  1237. }
  1238. //删除选中的节点
  1239. const copyNodeTableDel = (index) => {
  1240. copyNodeTable.value.splice(index, 1)
  1241. }
  1242. const classifyType = ref(authBtnTabKey.value)
  1243. const classifyTypeTabClick = ({key}) => {
  1244. classifyType.value = key
  1245. }
  1246. //复制节点
  1247. const copyNodeClick = async () => {
  1248. const type = copyNodeTabKey.value
  1249. const form = formCopyNodeModel.value
  1250. const table = copyNodeTable.value
  1251. let classify = ''
  1252. let arr = []
  1253. if (classifyList.value.length > 0) {
  1254. classifyList.value.forEach((item) => {
  1255. if (item === '施工') {
  1256. arr.push(1)
  1257. } else if (item === '监理') {
  1258. arr.push(2)
  1259. }
  1260. })
  1261. classify = arr.join(',')
  1262. }
  1263. //isSameNode 是否同节点 1=同节点,0=跨节点
  1264. if (table.length > 0) {
  1265. table.forEach((ele) => {
  1266. if (ele.parentId === formCopyNodeModel.value.parentId || ele.id === formCopyNodeModel.value.parentId) {
  1267. ele.isSameNode = 1
  1268. } else {
  1269. ele.isSameNode = 0
  1270. }
  1271. })
  1272. }
  1273. if(isCopyData.value===1){
  1274. if (classify) {
  1275. //效验数据
  1276. if (type === '1') {
  1277. const validate = await formValidate(formCopyNodeModelRef.value)
  1278. if (validate) await copyContractTreeNode(type, form, [], classify)
  1279. } else if (type === '2') {
  1280. if (table.length > 0) {
  1281. const validate = await formValidate(copyNodeTableRef.value)
  1282. if (validate) await copyContractTreeNode(type, form, table, classify)
  1283. } else {
  1284. window?.$message?.warning('请先在左侧选择要复制到的节点')
  1285. }
  1286. }
  1287. } else {
  1288. window?.$message?.warning('请选择所属方')
  1289. }
  1290. }else{
  1291. if (type === '1') {
  1292. const validate = await formValidate(formCopyNodeModelRef.value)
  1293. if (validate) await copyContractTreeNode(type, form, [], classify)
  1294. } else if (type === '2') {
  1295. if (table.length > 0) {
  1296. const validate = await formValidate(copyNodeTableRef.value)
  1297. if (validate) await copyContractTreeNode(type, form, table, classify)
  1298. } else {
  1299. window?.$message?.warning('请先在左侧选择要复制到的节点')
  1300. }
  1301. }
  1302. }
  1303. }
  1304. //单个复制、多份复制请求
  1305. const copyContractTreeNode = async (type, form, table, classify) => {
  1306. copyNodeLoading.value = true
  1307. if (type === '1') {
  1308. const {error, code} = await wbsApi.copyContractTreeNode({
  1309. copyType: type,
  1310. needCopyNodeName: form?.title || '',
  1311. partitionCode: form?.partitionCode || '',
  1312. needCopyPrimaryKeyId: form?.primaryKeyId || '',
  1313. parentPrimaryKeyId: form?.parent?.primaryKeyId || '',
  1314. copyBatchToPaths: table,
  1315. classifyType: classify,
  1316. isCopyData:isCopyData.value
  1317. })
  1318. //判断状态
  1319. copyNodeLoading.value = false
  1320. if (!error && code === 200) {
  1321. window?.$message?.success('复制成功')
  1322. copyNodeModal.value = false
  1323. window?.location?.reload() //刷新页面
  1324. }
  1325. } else {
  1326. const {error, code} = await wbsApi.copyContractTreeNode({
  1327. copyType: type,
  1328. needCopyNodeName: form?.title || '',
  1329. needCopyPrimaryKeyId: form?.primaryKeyId || '',
  1330. parentPrimaryKeyId: form?.parent?.primaryKeyId || '',
  1331. copyBatchToPaths: table,
  1332. classifyType: classify,
  1333. isCopyData:isCopyData.value
  1334. })
  1335. //判断状态
  1336. copyNodeLoading.value = false
  1337. if (!error && code === 200) {
  1338. window?.$message?.success('复制成功')
  1339. copyNodeModal.value = false
  1340. window?.location?.reload() //刷新页面
  1341. }
  1342. }
  1343. }
  1344. //复制数据
  1345. const copyContractNodeSubmitBusinessData = async (form, table, classify) => {
  1346. copyNodeLoading.value = true
  1347. const {error, code} = await wbsApi.copyContractNodeSubmitBusinessData({
  1348. needCopyPrimaryKeyId: form?.primaryKeyId || '',
  1349. copyBatchToPaths: table,
  1350. classify: classify
  1351. })
  1352. //判断状态
  1353. copyNodeLoading.value = false
  1354. if (!error && code === 200) {
  1355. window?.$message?.success('复制成功')
  1356. copyNodeModal.value = false
  1357. window?.location?.reload() //刷新页面
  1358. }
  1359. }
  1360. //新增节点
  1361. const addNodeModal = ref(false)
  1362. const addTreeNodeId = ref('')
  1363. const addTreeNodeOldId = ref('')
  1364. const addTreeNodeType = ref('1')
  1365. //选中的节点
  1366. const allSelectedList = ref([])
  1367. const halfSelectedList = ref([])
  1368. const addTreeNodeCheckChange = (nodes) => {
  1369. let NodesArr = [], halfArr = []
  1370. //全选数据
  1371. const keys = nodes.checkedNodes || []
  1372. console.log(keys,'keys');
  1373. for (let i = 0; i < keys.length; i++) {
  1374. NodesArr.push({
  1375. nodeName: keys[i].nodeName,
  1376. primaryKeyId: keys[i].pkeyId
  1377. })
  1378. }
  1379. allSelectedList.value = NodesArr
  1380. //半选数据
  1381. const halfNodes = nodes.halfCheckedNodes || []
  1382. for (let i = 0; i < halfNodes.length; i++) {
  1383. halfArr.push({
  1384. nodeName: halfNodes[i].nodeName,
  1385. primaryKeyId: halfNodes[i].pkeyId
  1386. })
  1387. }
  1388. halfSelectedList.value = halfArr
  1389. }
  1390. //新增节点
  1391. const addNodeLoading = ref(false)
  1392. const addNodeClick = async () => {
  1393. const keys = allSelectedList.value || []
  1394. if (keys.length <= 0) {
  1395. window?.$message?.warning('请先选择节点')
  1396. } else {
  1397. //发起请求
  1398. addNodeLoading.value = true
  1399. const primaryKeyId = nodeDataInfo.value?.primaryKeyId || ''
  1400. const {error, code} = await wbsApi.saveContractTreeNode({
  1401. projectId: projectId.value,
  1402. contractId: contractId.value,
  1403. saveType: addTreeNodeType.value,
  1404. allSelectedList: allSelectedList.value,
  1405. halfSelectedList: halfSelectedList.value,
  1406. currentNodePrimaryKeyId: primaryKeyId
  1407. })
  1408. //判断状态
  1409. addNodeLoading.value = false
  1410. if (!error && code === 200) {
  1411. window?.$message?.success('新增成功')
  1412. addNodeModal.value = false
  1413. window?.location?.reload() //刷新页面
  1414. }
  1415. }
  1416. }
  1417. //删除节点
  1418. const delModalClick = () => {
  1419. window?.$messageBox?.alert('请谨慎考虑后,确认是否需要删除?', '删除节点', {
  1420. showCancelButton: true,
  1421. confirmButtonText: '确认删除',
  1422. cancelButtonText: '取消',
  1423. callback: (action) => {
  1424. if (action === 'confirm') {
  1425. removeContractTreeNode()
  1426. }
  1427. }
  1428. })
  1429. }
  1430. const removeContractTreeNode = async () => {
  1431. const loadingInstance = window.$loading.service({
  1432. fullscreen: true,
  1433. text: '删除节点中,请耐心等待...',
  1434. background: 'rgba(0, 0, 0, 0.7)'
  1435. })
  1436. const {error, code} = await wbsApi.removeContractTreeNode({
  1437. ids: nodeDataInfo.value?.primaryKeyId || ''
  1438. })
  1439. //处理结果
  1440. loadingInstance.close()
  1441. if (!error && code === 200) {
  1442. window?.$message?.success('删除成功')
  1443. window?.location?.reload() //刷新页面
  1444. }
  1445. }
  1446. //调整排序
  1447. const sortNodeModal = ref(false)
  1448. const sortNodeLoading = ref(false)
  1449. const sortNodeData = ref([])
  1450. const sortNodeDrag = ref(false)
  1451. //向下
  1452. const downSortClick = (index) => {
  1453. const indexs = index + 1
  1454. const data = sortNodeData.value || []
  1455. if (indexs !== data.length) {
  1456. const tmp = data.splice(indexs, 1);
  1457. sortNodeData.value.splice(index, 0, tmp[0]);
  1458. } else {
  1459. window?.$message?.warning('已经处于置底,无法下移')
  1460. }
  1461. }
  1462. //向上
  1463. const upSortClick = (index) => {
  1464. const data = sortNodeData.value || []
  1465. if (index !== 0) {
  1466. const tmp = data.splice(index - 1, 1);
  1467. sortNodeData.value.splice(index, 0, tmp[0]);
  1468. } else {
  1469. window?.$message?.warning('已经处于置顶,无法上移')
  1470. }
  1471. }
  1472. //确认排序
  1473. const sortNodeClick = async () => {
  1474. const sortList = [];
  1475. const nodes = sortNodeData.value || []
  1476. nodes.forEach(item => {
  1477. sortList.push(item?.id)
  1478. })
  1479. //发起请求
  1480. sortNodeLoading.value = true
  1481. const {error, code} = await wbsApi.diySortTreeNode({sortList})
  1482. sortNodeLoading.value = false
  1483. //判断状态
  1484. if (!error && code === 200) {
  1485. window?.$message?.success('保存成功')
  1486. sortNodeModal.value = false
  1487. window?.location?.reload() //刷新页面
  1488. }
  1489. }
  1490. //查看图纸
  1491. const drawingsShow = ref(false);
  1492. const viewsDrawings = () => {
  1493. const {primaryKeyId, fileUrl} = nodeDataInfo.value
  1494. if (!primaryKeyId) {
  1495. window?.$message?.warning('请先选择树节点')
  1496. } else if (!fileUrl) {
  1497. window?.$message?.warning('该节点暂未上传图纸')
  1498. } else {
  1499. drawingsShow.value = true
  1500. }
  1501. }
  1502. const drawingsClose = (res) => {
  1503. drawingsShow.value = res
  1504. }
  1505. //设置滚动条位置
  1506. const ListItemScrollRef = ref(null)
  1507. const ListItemOffsetTop = (offsetTop) => {
  1508. if (offsetTop > 0) {
  1509. setTimeout(() => {
  1510. ListItemScrollRef.value?.setScrollTop(offsetTop)
  1511. }, 350)
  1512. } else {
  1513. ListItemScrollRef.value?.setScrollTop(offsetTop)
  1514. }
  1515. }
  1516. //获取数据列表
  1517. const ListItemDatas = ref([]);
  1518. const ListItemLoading = ref(false);
  1519. const searchNodeAllTable = async () => {
  1520. ListItemDatas.value = []
  1521. const info = nodeDataInfo.value;
  1522. ListItemLoading.value = true
  1523. const {error, code, data} = await wbsApi.searchNodeAllTable({
  1524. projectId: projectId.value,
  1525. contractId: contractId.value,
  1526. primaryKeyId: info['primaryKeyId'],
  1527. type: authBtnTabKey.value
  1528. })
  1529. //处理数据
  1530. ListItemLoading.value = false
  1531. if (!error && code === 200) {
  1532. ListItemDatas.value = getArrValue(data)
  1533. } else {
  1534. ListItemDatas.value = []
  1535. }
  1536. }
  1537. //查询状态
  1538. const NodeStatus = ref('1')
  1539. const queryNodeStatus = async () => {
  1540. const info = nodeDataInfo.value;
  1541. if (contractInfo.value?.contractType == 1) {
  1542. const {error, code, data} = await wbsApi.queryNodeStatus({
  1543. primaryKeyId: info['primaryKeyId'],
  1544. //classify:1
  1545. classify: authBtnTabKey.value
  1546. })
  1547. //1 未填报,2待上报,3已上报
  1548. if (!error && code === 200) {
  1549. NodeStatus.value = data ?? '1'
  1550. } else {
  1551. NodeStatus.value = '1'
  1552. }
  1553. } else {
  1554. const {error, code, data} = await wbsApi.queryNodeStatusJl({
  1555. // primaryKeyId: info['contractIdRelation'] ? info['id'] : info['primaryKeyId'],
  1556. primaryKeyId: info['primaryKeyId'],
  1557. //classify: 1
  1558. classify: authBtnTabKey.value
  1559. })
  1560. //1 未填报,2待上报,3已上报
  1561. if (!error && code === 200) {
  1562. NodeStatus.value = data ?? '1'
  1563. } else {
  1564. NodeStatus.value = '1'
  1565. }
  1566. }
  1567. }
  1568. //批量上报
  1569. const reportIds = ref('')
  1570. const reportTaskName = ref('')
  1571. const reportAddition = ref({})
  1572. const showReportModal = ref(false)
  1573. const reportLoading = ref(false)
  1574. const reportTypeData = ref([])
  1575. const reportModalClick = async () => {
  1576. const info = nodeDataInfo.value;
  1577. const rows = ListItemDatas.value;
  1578. if (rows.length > 0) {
  1579. reportLoading.value = true
  1580. const taskCheck = await eVisaTaskCheckApi({
  1581. projectId: projectId.value,
  1582. contractId: contractInfo.value?.contractType == 2 ? info?.contractIdRelation : contractId.value
  1583. // contractId: contractId.value
  1584. })
  1585. //处理数据
  1586. let newArr = [];
  1587. for (let i = 0; i < rows.length; i++) {
  1588. newArr.push(rows[i]['isTypePrivatePid'])
  1589. }
  1590. reportTypeData.value = newArr
  1591. reportLoading.value = false
  1592. if (taskCheck) {
  1593. //初始弹出弹窗,防呆
  1594. reportIds.value = info['primaryKeyId']
  1595. reportAddition.value = {
  1596. classify: authBtnTabKey.value,
  1597. contractIdRelation: info['contractIdRelation'],
  1598. }
  1599. showReportModal.value = true
  1600. //请求文件题名
  1601. const {data} = await wbsApi.queryDocumentTitle({
  1602. primaryKeyId: info['primaryKeyId'],
  1603. classify: authBtnTabKey.value
  1604. })
  1605. reportTaskName.value = isString(data) ? data : ''
  1606. }
  1607. } else {
  1608. window.$message?.warning('暂无相关数据')
  1609. }
  1610. }
  1611. //上报完成
  1612. const showReportFinish = () => {
  1613. showReportModal.value = false
  1614. getTableDataAll()
  1615. // window?.location?.reload() //刷新页面
  1616. }
  1617. //表单变量
  1618. const ListItemRef = ref(null)
  1619. const ListItemsRef = ref(null)
  1620. //保存
  1621. const tableFormSaveLoading = ref(false)
  1622. const tableFormSaveClick = async () => {
  1623. //获取数据
  1624. let FormData = [], FormRegExpJson = {};
  1625. if (isDrawer.value) {
  1626. FormData = await ListItemsRef.value?.getFormData()
  1627. FormRegExpJson = await ListItemsRef.value?.getFormRegExpJson()
  1628. } else {
  1629. FormData = await ListItemRef.value?.getFormData()
  1630. FormRegExpJson = await ListItemRef.value?.getFormRegExpJson()
  1631. }
  1632. //效验数据
  1633. if (getObjVal(FormRegExpJson)) {
  1634. setFormRegExpJson(FormRegExpJson)
  1635. } else if (FormData.length > 0) {
  1636. tableFormSaveLoading.value = true
  1637. console.log('FormData', FormData)
  1638. const {error, code} = await wbsApi.saveExcelBussData({
  1639. dataInfo: {orderList: FormData}
  1640. })
  1641. tableFormSaveLoading.value = false
  1642. if (!error && code === 200) {
  1643. window?.$message?.success('保存成功')
  1644. await bussPdfsClick()
  1645. getTableDataAll()
  1646. }
  1647. } else {
  1648. await bussPdfsClick()
  1649. }
  1650. }
  1651. //效验数据
  1652. const setFormRegExpJson = (FormRegExpJson) => {
  1653. let nodeName = '', itemId = '';
  1654. Object.keys(FormRegExpJson).forEach(key => {
  1655. const name = FormRegExpJson[key]?.nodeName ?? ''
  1656. if (name) {
  1657. if (nodeName) {
  1658. nodeName += ',' + name
  1659. } else {
  1660. nodeName = name
  1661. itemId = FormRegExpJson[key]?.itemId
  1662. }
  1663. }
  1664. })
  1665. //const activeKey = ListItemRef.value?.getActiveKey()
  1666. //弹出提示
  1667. const val = '<div style="font-size: 16px;">请先完善 <span style="color:#1ECC95;">' + nodeName + '</span> 的数据内容</div>'
  1668. window?.$messageBox?.alert(val, '表单完善提醒', {
  1669. confirmButtonText: '确定',
  1670. dangerouslyUseHTMLString: true,
  1671. callback: (action) => {
  1672. if (action === 'confirm') {
  1673. ListItemRef.value?.setActiveKey(itemId)
  1674. ListItemOffsetTop(0)
  1675. setTimeout(() => {
  1676. const offsetTop = document.getElementById(itemId)?.offsetTop
  1677. ListItemOffsetTop(offsetTop)
  1678. }, 350)
  1679. }
  1680. }
  1681. })
  1682. }
  1683. //多表预览
  1684. const bussPdfsLoading = ref(false)
  1685. const bussPdfsClick = async () => {
  1686. const info = nodeDataInfo.value;
  1687. bussPdfsLoading.value = true
  1688. const {error, code, data} = await wbsApi.getBussPdfs({
  1689. nodeId: info?.primaryKeyId || '',
  1690. classify: authBtnTabKey.value,
  1691. projectId: projectId.value,
  1692. // contractId: contractId.value
  1693. contractId: contractInfo.value?.contractType == 2 ? info?.contractIdRelation : contractId.value
  1694. })
  1695. tableFormSaveLoading.value = false
  1696. bussPdfsLoading.value = false
  1697. if (!error && code === 200) {
  1698. window.open(data, '_blank')
  1699. } else {
  1700. window.$message?.warning('获取PDF失败')
  1701. }
  1702. }
  1703. //撤回上报流程
  1704. const abolishOneClick = () => {
  1705. window?.$messageBox?.alert('请谨慎考虑后,是否确定撤回?', '撤回上报', {
  1706. showCancelButton: true,
  1707. confirmButtonText: '确定撤回',
  1708. cancelButtonText: '取消',
  1709. callback: (action) => {
  1710. if (action === 'confirm') {
  1711. abolishOneSave()
  1712. }
  1713. }
  1714. })
  1715. }
  1716. //撤回请求
  1717. const abolishOneSave = async () => {
  1718. const info = nodeDataInfo.value;
  1719. const {error, code} = await wbsApi.abolishOne({
  1720. primaryKeyId: info?.primaryKeyId || '',
  1721. classify: authBtnTabKey.value
  1722. })
  1723. if (!error && code === 200) {
  1724. window.$message?.success('撤回成功')
  1725. getTableDataAll()
  1726. window?.location?.reload() //刷新页面
  1727. }
  1728. }
  1729. //附件列表
  1730. const attachmentModal = ref(false)
  1731. const attachmentModalShow = () => {
  1732. attachmentModal.value = true
  1733. }
  1734. //划分变更
  1735. const divisionClick = () => {
  1736. router.push({
  1737. path: '/data-fill/division'
  1738. })
  1739. }
  1740. //树展开和收起
  1741. const isWbsTreeShow = ref(true)
  1742. const setWbsTreeShow = () => {
  1743. isWbsTreeShow.value = !isWbsTreeShow.value
  1744. }
  1745. //拷贝内容
  1746. const copyPositionText = (val) => {
  1747. if (val) {
  1748. //navigator.clipboard.writeText(val);
  1749. setCopyText(val).then(() => {
  1750. window.$message?.success('复制成功')
  1751. }).catch(() => {
  1752. window.$message?.error('复制失败,请手动复制')
  1753. });
  1754. } else {
  1755. window.$message?.warning('没有可复制的数据')
  1756. }
  1757. }
  1758. //左右拖动,改变树形结构宽度
  1759. const leftWidth = ref(382);
  1760. const isMouseTree = ref(false);
  1761. const onmousedown = () => {
  1762. const leftNum = isCollapse.value ? 142 : 272
  1763. isMouseTree.value = true;
  1764. document.onmousemove = (ve) => {
  1765. let diffVal = ve.clientX - leftNum;
  1766. if (diffVal >= 310 && diffVal <= 900) {
  1767. leftWidth.value = diffVal;
  1768. }
  1769. }
  1770. document.onmouseup = () => {
  1771. document.onmousemove = null;
  1772. document.onmouseup = null;
  1773. isMouseTree.value = false;
  1774. }
  1775. }
  1776. </script>
  1777. <style lang="scss" scoped>
  1778. @import "../../styles/data-fill/wbs.scss";
  1779. .hc-add-node-modal-foot-box {
  1780. position: relative;
  1781. display: flex;
  1782. align-items: center;
  1783. .left-box {
  1784. position: relative;
  1785. flex: 1;
  1786. display: flex;
  1787. align-items: center;
  1788. }
  1789. .right-box {
  1790. position: relative;
  1791. }
  1792. }
  1793. .hc-expansion-contraction-tree {
  1794. position: absolute;
  1795. left: -21px;
  1796. top: 0;
  1797. width: 18px;
  1798. height: 100%;
  1799. user-select: none;
  1800. cursor: pointer;
  1801. display: flex;
  1802. justify-content: center;
  1803. align-items: center;
  1804. color: #8c9099;
  1805. font-size: 22px;
  1806. border-radius: 5px;
  1807. transition: background 0.2s;
  1808. background: rgba(255, 255, 255, 0);
  1809. &:hover {
  1810. background: #f1f5f8;
  1811. color: var(--el-color-primary);
  1812. }
  1813. }
  1814. .hc-table-form-action-tip {
  1815. position: absolute;
  1816. bottom: 77px;
  1817. width: 100%;
  1818. }
  1819. html.theme-dark {
  1820. .bg-svg-xml {
  1821. background-color: initial;
  1822. background-image: initial;
  1823. }
  1824. .hc-layout-box .hc-layout-content-box .hc-card-max-h-box.node-tree .hc-tree-foot-tip-box {
  1825. border-top: 1px solid #303030;
  1826. }
  1827. }
  1828. </style>
  1829. <style lang="scss">
  1830. .data-fill-wbs-content {
  1831. position: relative;
  1832. height: 100%;
  1833. .n-drawer-container {
  1834. margin: -20px -24px;
  1835. }
  1836. .n-drawer.n-drawer--top-placement {
  1837. height: auto !important;
  1838. background-color: initial;
  1839. pointer-events: none;
  1840. bottom: 0;
  1841. }
  1842. .drawer-data-fill-content-box {
  1843. position: relative;
  1844. height: 100%;
  1845. padding: 24px;
  1846. .n-card {
  1847. pointer-events: auto;
  1848. height: 100%;
  1849. overflow: auto;
  1850. }
  1851. .data-fill-content {
  1852. position: relative;
  1853. height: 100%;
  1854. overflow-y: auto;
  1855. scroll-behavior: smooth;
  1856. .data-fill-list-box .data-fill-list-item-content {
  1857. height: calc(100vh - 470px);
  1858. .data-fill-table-form-box {
  1859. height: 100%;
  1860. }
  1861. }
  1862. }
  1863. .data-fill-foot {
  1864. position: relative;
  1865. text-align: center;
  1866. }
  1867. }
  1868. }
  1869. .n-card.hc-card-overflow-box .n-card__content {
  1870. padding: 24px;
  1871. }
  1872. .n-card.hc-custom-card > .n-card-header {
  1873. padding: 15px 24px;
  1874. }
  1875. .n-card.hc-custom-card.copy {
  1876. width: 1200px;
  1877. max-height: 90vh;
  1878. overflow: auto;
  1879. .n-card-header .n-card-header__close {
  1880. display: none;
  1881. }
  1882. &.one {
  1883. width: 600px;
  1884. }
  1885. &.many {
  1886. width: 1200px;
  1887. }
  1888. }
  1889. .img-preview-box {
  1890. position: relative;
  1891. height: 100%;
  1892. width: 100%;
  1893. }
  1894. .hc-layout-content-box {
  1895. position: relative;
  1896. }
  1897. .iscusor {
  1898. cursor: pointer;
  1899. }
  1900. .hc-table-form-action-tip .hc-alert {
  1901. background-color: #f1f5f8;
  1902. display: inline;
  1903. vertical-align: middle;
  1904. box-shadow: -2px 0 10px 0 rgba(32, 37, 50, 0.03), 0 10px 21px 20px rgba(32, 37, 50, 0.03);
  1905. }
  1906. .copy-node-form-box {
  1907. margin-top: 24px;
  1908. padding-top: 24px;
  1909. border-top: 1px solid #efeff5;
  1910. }
  1911. .hc-position-input-icon {
  1912. position: relative;
  1913. margin-bottom: 0;
  1914. .el-form-item__content {
  1915. position: relative;
  1916. .el-textarea .el-textarea__inner {
  1917. padding-right: 30px;
  1918. }
  1919. .hc-icon-i {
  1920. position: absolute;
  1921. right: 10px;
  1922. bottom: 0;
  1923. font-size: 20px;
  1924. cursor: pointer;
  1925. color: #0081ff;
  1926. opacity: 1;
  1927. transition: opacity 0.2s;
  1928. &:hover {
  1929. opacity: .5;
  1930. }
  1931. }
  1932. }
  1933. }
  1934. </style>