wbs.vue 76 KB

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