ProjectDetailDialog.vue 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315
  1. <template>
  2. <el-drawer
  3. :title="title"
  4. :visible.sync="visible"
  5. direction="rtl"
  6. :append-to-body="true"
  7. size="100%"
  8. >
  9. <el-row :gutter="5">
  10. <el-col :span="3">
  11. <el-card class="box-card" style="height: calc(100vh - 56px)">
  12. <AssetTree
  13. @handleNodeClick="handleNodeClick1"
  14. :defaultExpandAll="true"
  15. code="XM1"
  16. :isProjects="true"
  17. :isFirstRefreshTable="false"
  18. ref="treeList"
  19. :init="false"
  20. />
  21. </el-card>
  22. <!-- <div style="padding: 5px;">
  23. </div> -->
  24. </el-col>
  25. <el-col :span="21">
  26. <el-card class="box-card">
  27. <div style="width: 100%">
  28. <el-row style="font-size: 16px">
  29. <el-col :span="3" style="color: #1890ff"
  30. >项目名称:{{ rowData.name }}
  31. </el-col>
  32. <el-col :span="3"
  33. >项目预算:{{
  34. rowData.budget
  35. ? rowData.budget +
  36. this.getDictV('pro_projects_budget_unit', rowData.unit)
  37. : ''
  38. }}
  39. </el-col>
  40. <el-col :span="3"
  41. >项目经理:{{ rowData.responsibleUserName }}
  42. </el-col>
  43. <el-col :span="3">项目周期:{{ rowData.cycle }} </el-col>
  44. <el-col :span="3"
  45. >项目状态:
  46. {{ getDictV('pro_projects_status', rowData.status) }}</el-col
  47. >
  48. </el-row>
  49. </div>
  50. </el-card>
  51. <el-card class="card_2_box card" style="height: calc(100vh - 130px)">
  52. <el-row :gutter="24">
  53. <el-col :span="3" style="padding: 0">
  54. <div class="el_tree_box">
  55. <div
  56. style="
  57. margin-bottom: 6px;
  58. display: flex;
  59. justify-items: flex-start;
  60. "
  61. >
  62. <el-button
  63. style="width: 50%"
  64. type="primary"
  65. :class="{ current_button: leftTreeActiveName == 'BOM维度' }"
  66. size="small"
  67. plain
  68. @click="handleLeftTreeActiveName('BOM维度')"
  69. >BOM维度
  70. </el-button>
  71. <el-button
  72. style="width: 50%"
  73. type="primary"
  74. :class="{
  75. current_button: leftTreeActiveName == '阶段维度'
  76. }"
  77. size="small"
  78. plain
  79. @click="handleLeftTreeActiveName('阶段维度')"
  80. >阶段维度
  81. </el-button>
  82. </div>
  83. <el-input
  84. v-model="filterText"
  85. placeholder="在结构中查找"
  86. size="small"
  87. clearable
  88. style="margin-bottom: 3px"
  89. >
  90. </el-input>
  91. <el-tree
  92. class="project_tree"
  93. ref="treeRef"
  94. :data="treeList"
  95. :default-expanded-keys="
  96. currentNodeData && currentNodeData.id
  97. ? [currentNodeData.id]
  98. : []
  99. "
  100. :expand-on-click-node="false"
  101. :highlight-current="true"
  102. :indent="0"
  103. :props="defaultProps"
  104. node-key="id"
  105. style="height: 100%"
  106. :filter-node-method="filterNode"
  107. @node-click="handleNodeClick"
  108. >
  109. <div
  110. style="width: 100%; height: 100%; display: flex"
  111. slot-scope="{ node, data }"
  112. @contextmenu.stop="(e) => showRightMenu(e, node, data)"
  113. >
  114. <span class="custom-tree-node">
  115. <span
  116. :style="fontSize(node, data)"
  117. class="label_img"
  118. :class="getIconClass(node, data)"
  119. ></span>
  120. <span :style="fontSize(node, data)" class="label">{{
  121. node.label
  122. }}</span>
  123. </span>
  124. <vue-context-menu
  125. :transferIndex="0"
  126. :class="
  127. 'vue-contextmenuName-' +
  128. data.id +
  129. '_' +
  130. data.name +
  131. '_rightMenu'
  132. "
  133. v-if="
  134. data.id + '_' + data.name + '_rightMenu' ==
  135. contextMenuData.menuName
  136. "
  137. :contextMenuData="contextMenuData"
  138. @updateProject="
  139. () => handleUpdateProject(node, data, 'edit')
  140. "
  141. @removeBom="() => bomRemove(node, data)"
  142. @stageRemove="() => stageRemove(node, data)"
  143. @addBOM="() => addOrEditBOM('add', node, data)"
  144. @editBOM="() => addOrEditBOM('edit', node, data)"
  145. @addChildProject="
  146. () => handleUpdateProject(node, data, 'add')
  147. "
  148. @addStage="() => handleAddStage(node, data, 'add')"
  149. @addPlan="() => handleAddPlan('add', node, data)"
  150. @addTask="() => handleAddTask('add', node, data)"
  151. @handleTermination="
  152. () =>
  153. handleStatus(
  154. projectsTerminationAPI,
  155. '确定终止该项目吗?',
  156. node,
  157. data
  158. )
  159. "
  160. @handlePause="
  161. () =>
  162. handleStatus(
  163. projectsPauseAPI,
  164. '确定暂停该项目吗',
  165. node,
  166. data
  167. )
  168. "
  169. @handleStartup="
  170. () =>
  171. handleStatus(
  172. projectsStartupAPI,
  173. '确定启动该项目吗',
  174. node,
  175. data
  176. )
  177. "
  178. @handleFinish="
  179. () =>
  180. handleStatus(
  181. projectsFinishAPI,
  182. '确定完成该项目吗',
  183. node,
  184. data
  185. )
  186. "
  187. @handleBomTermination="
  188. () =>
  189. handleStatus(
  190. projectsBomTerminationAPI,
  191. '确定终止该BOM吗?',
  192. node,
  193. data
  194. )
  195. "
  196. @handleBomPause="
  197. () =>
  198. handleStatus(
  199. projectsBomPauseAPI,
  200. '确定暂停该BOM吗',
  201. node,
  202. data
  203. )
  204. "
  205. @handleBomStartup="
  206. () =>
  207. handleStatus(
  208. projectsBomStartupAPI,
  209. '确定启动该BOM吗',
  210. node,
  211. data
  212. )
  213. "
  214. @handleBomFinish="
  215. () =>
  216. handleStatus(
  217. projectsBomFinishAPI,
  218. '确定完成该BOM吗',
  219. node,
  220. data
  221. )
  222. "
  223. @handleStageTermination="
  224. () =>
  225. handleStatus(
  226. projectsStageTerminationAPI,
  227. '确定终止该项目阶段吗?',
  228. node,
  229. data
  230. )
  231. "
  232. @handleStagePause="
  233. () =>
  234. handleStatus(
  235. projectsStagePauseAPI,
  236. '确定暂停该项目阶段吗',
  237. node,
  238. data
  239. )
  240. "
  241. @handleStageStartup="
  242. () =>
  243. handleStatus(
  244. projectsStageStartupAPI,
  245. '确定启动该项目阶段吗',
  246. node,
  247. data
  248. )
  249. "
  250. @handleStageFinish="
  251. () =>
  252. handleStatus(
  253. projectsStageFinishAPI,
  254. '确定完成该项目阶段吗',
  255. node,
  256. data
  257. )
  258. "
  259. ></vue-context-menu>
  260. </div>
  261. </el-tree>
  262. </div>
  263. </el-col>
  264. <el-col :span="21" style="height: calc(100vh - 170px)">
  265. <ele-split-layout
  266. :left-style="{
  267. overflow: 'hidden',
  268. width: '100%'
  269. }"
  270. :vertical="true"
  271. style="height: calc(100vh - 180px)"
  272. :min-size="1"
  273. :resizable="true"
  274. :responsive="true"
  275. :width="activeName=='任务'||activeName=='计划'?'450px':'100%'"
  276. :right-style="{ overflow: 'hidden' }"
  277. :allow-collapse="false"
  278. >
  279. <div class="card_2_layout_content">
  280. <el-tabs
  281. v-model="activeName"
  282. class="tab-box_1"
  283. type="border-card"
  284. @tab-click="handleTabs1"
  285. >
  286. <el-tab-pane label="基本信息" name="基本信息">
  287. <div style="padding: 0 10px">
  288. <attribute
  289. v-if="currentNodeData.type == 1"
  290. ref="attributeRef"
  291. :dialog-type="dialogType"
  292. ></attribute>
  293. <project-form
  294. v-if="[0, 2].includes(currentNodeData.type)"
  295. ref="projectForm"
  296. :deptList="deptList"
  297. :deptTreeList="deptTreeList"
  298. :dialogForm="dialogForm"
  299. :teamList="teamList"
  300. dialog-type="view"
  301. ></project-form>
  302. </div>
  303. </el-tab-pane>
  304. <el-tab-pane
  305. v-if="[0, 2].includes(currentNodeData.type)"
  306. label="项目阶段"
  307. name="项目阶段"
  308. class="el-tab-pane-tree"
  309. >
  310. <project-info-table
  311. ref="projectInfoTable"
  312. :dialog-type="dialogType"
  313. :dialogForm="dialogForm"
  314. :deptList="deptList"
  315. :deptTreeList="deptTreeList"
  316. ></project-info-table>
  317. </el-tab-pane>
  318. <el-tab-pane
  319. label="计划"
  320. name="计划"
  321. class="el-tab-pane-tree"
  322. style="overflow: scroll"
  323. >
  324. <div style="padding: 0 10px">
  325. <planManageList
  326. :projectType="currentNodeData.type"
  327. :ids="currentNodeData.id"
  328. @handlePlanTableNodeClick="handlePlanTableNodeClick"
  329. v-if="refreshPlan"
  330. ></planManageList>
  331. </div>
  332. </el-tab-pane>
  333. <el-tab-pane
  334. label="任务"
  335. name="任务"
  336. class="el-tab-pane-tree"
  337. >
  338. <ele-pro-table
  339. class="el-table"
  340. ref="table"
  341. row-key="id"
  342. :columns="columns"
  343. :datasource="taskTree"
  344. height="100%"
  345. :max-height="500"
  346. @row-click="
  347. (row) => handleTableNodeClick({ ...row, type: 2 })
  348. "
  349. @row-contextmenu="
  350. (row, column, event) =>
  351. showTableRightMenu(
  352. { ...row, type: 2 },
  353. column,
  354. event
  355. )
  356. "
  357. :toolkit="[]"
  358. :default-expand-all="true"
  359. cache-key="project-initiationTable"
  360. :tree-props="{ children: 'children' }"
  361. :need-page="false"
  362. :indent="0"
  363. >
  364. <template v-slot:name="{ row }">
  365. <span
  366. v-if="!row.children.length && row.level == 1"
  367. style="margin-left: 25px; display: inline-block"
  368. ></span>
  369. <span class="dot" v-if="row.milepost == '1'"></span>
  370. <span class="name"> {{ row.name }}</span>
  371. </template>
  372. <template v-slot:type="{ row }">
  373. <el-tag type="info">任务</el-tag>
  374. </template>
  375. <template v-slot:speedPercent="{ row }">
  376. <el-progress
  377. style="padding: 0 5px"
  378. :stroke-width="20"
  379. text-color="#606266"
  380. :text-inside="true"
  381. :percentage="row.speedPercent || 0"
  382. :color="customColorMethod"
  383. ></el-progress>
  384. <vue-context-menu
  385. :transferIndex="0"
  386. :class="'vue-contextmenuName-' + row.name"
  387. v-if="row.name == contextTableMenuData.menuName"
  388. :contextMenuData="contextTableMenuData"
  389. @addTask="
  390. () =>
  391. handleAddTask(
  392. 'add',
  393. '',
  394. { ...row, type: 2 },
  395. 'plan'
  396. )
  397. "
  398. @updateTask="
  399. () =>
  400. handleAddTask(
  401. 'edit',
  402. '',
  403. { ...row, type: 2 },
  404. 'plan'
  405. )
  406. "
  407. @removeTask="() => handleRemoveTask([row.id])"
  408. @startTask="
  409. () =>
  410. handleStartTask(row, 1, '是否确定执行该任务?')
  411. "
  412. @finishTask="
  413. () =>
  414. handleStartTask(row, 3, '是否确定报工该任务?')
  415. "
  416. @pauseTask="
  417. () =>
  418. handleStartTask(row, 2, '是否确定暂停该任务?')
  419. "
  420. @terminationTask="
  421. () =>
  422. handleStartTask(row, 4, '是否确定终止该任务?')
  423. "
  424. @handleTransfer="() => handleTransfer(row)"
  425. @handleSubmitDeliverables="
  426. () => handleSubmitDeliverables(row)
  427. "
  428. ></vue-context-menu>
  429. </template>
  430. </ele-pro-table>
  431. </el-tab-pane>
  432. <el-tab-pane
  433. label="项目团队"
  434. name="项目团队"
  435. class="el-tab-pane-tree"
  436. >
  437. <team-info-table
  438. ref="deliverablesInfoTable"
  439. dialog-type="view"
  440. :dialogForm="teamForm"
  441. ></team-info-table>
  442. </el-tab-pane>
  443. <el-tab-pane
  444. label="项目看板"
  445. name="项目看板"
  446. class="el-tab-pane-tree"
  447. >
  448. <project-statistics></project-statistics>
  449. </el-tab-pane>
  450. <el-tab-pane
  451. label="项目审核流程"
  452. name="项目审核流程"
  453. class="el-tab-pane-tree"
  454. style="overflow: scroll; padding-bottom: 30px"
  455. >
  456. <bpmDetail
  457. v-if="dialogForm.processInstanceId && bpmDetailFlag"
  458. :id="dialogForm.processInstanceId"
  459. ></bpmDetail>
  460. </el-tab-pane>
  461. <el-tab-pane
  462. label="项目行事历"
  463. name="项目行事历"
  464. class="el-tab-pane-tree"
  465. style="overflow: scroll; padding-bottom: 30px"
  466. >
  467. <projectCalendar></projectCalendar>
  468. </el-tab-pane>
  469. </el-tabs>
  470. </div>
  471. <template v-slot:content>
  472. <el-tabs
  473. v-if="isShow"
  474. v-model="attrActiveName"
  475. class="tab-box_2"
  476. type="border-card"
  477. >
  478. <el-tab-pane label="属性" name="属性">
  479. <!--currentTableNodeData-->
  480. <plan-form
  481. ref="planForm"
  482. dialog-type="view"
  483. :dialogForm="rightForm"
  484. :deptList="deptList"
  485. :deptTreeList="deptTreeList"
  486. ></plan-form>
  487. <base-form
  488. ref="baseForm"
  489. v-if="[2].includes(currentTableNodeData.type)"
  490. dialog-type="view"
  491. :dialogForm="rightForm"
  492. :deptList="deptList"
  493. :deptTreeList="deptTreeList"
  494. ></base-form>
  495. </el-tab-pane>
  496. <el-tab-pane label="计划节点" name="计划节点">
  497. <plan-info-table
  498. ref="planInfoTable"
  499. dialog-type="view"
  500. :dialogForm="rightForm"
  501. :deptList="deptList"
  502. :deptTreeList="deptTreeList"
  503. ></plan-info-table>
  504. </el-tab-pane>
  505. <el-tab-pane
  506. v-if="[2].includes(currentTableNodeData.type)"
  507. label="交付物"
  508. name="交付物"
  509. class="el-tab-pane-tree"
  510. >
  511. <submit-deliverables-info-table
  512. ref="deliverablesInfoTable"
  513. :dictList="dictList"
  514. dialog-type="view"
  515. :dialogForm="rightForm"
  516. ></submit-deliverables-info-table>
  517. </el-tab-pane>
  518. </el-tabs>
  519. </template>
  520. </ele-split-layout>
  521. </el-col>
  522. </el-row>
  523. </el-card>
  524. </el-col>
  525. </el-row>
  526. <add-BOM-dialog
  527. v-if="addBOMDialogFlag"
  528. ref="addBOMDialogRef"
  529. :addBOMDialogFlag.sync="addBOMDialogFlag"
  530. :treeList="treeList"
  531. @reload="reload"
  532. ></add-BOM-dialog>
  533. <!-- 新增计划 -->
  534. <add-plan-dialog
  535. v-if="addPlanDialogFLag"
  536. @reload="reload"
  537. :addOrEditDialogFlag.sync="addPlanDialogFLag"
  538. ref="addPlanDialogRef"
  539. ></add-plan-dialog>
  540. <plan-detail-dialog
  541. v-if="planDetailDialogFlag"
  542. :detailDialogFlag.sync="planDetailDialogFlag"
  543. ref="planDetailDialogRef"
  544. ></plan-detail-dialog>
  545. <!-- 编辑弹窗 -->
  546. <add-task-dialog
  547. v-if="addTaskDialogFlag"
  548. @reload="reload"
  549. :addOrEditDialogFlag.sync="addTaskDialogFlag"
  550. ref="addTaskDialogRef"
  551. ></add-task-dialog>
  552. <task-detail-dialog
  553. v-if="taskDetailDialogFlag"
  554. :detailDialogFlag.sync="taskDetailDialogFlag"
  555. ref="taskDetailDialogRef"
  556. ></task-detail-dialog>
  557. <transfer-dialog
  558. ref="transferDialogRef"
  559. v-if="transferDialogFlag"
  560. @reload="reload"
  561. :transferDialogFlag.sync="transferDialogFlag"
  562. ></transfer-dialog>
  563. <submit-deliverables-dialog
  564. ref="submitDeliverablesDialogRef"
  565. v-if="submitDeliverablesDialogFlag"
  566. :submitDeliverablesDialogFlag.sync="submitDeliverablesDialogFlag"
  567. @reload="reload"
  568. ></submit-deliverables-dialog>
  569. <!-- 编辑弹窗 -->
  570. <addOrEditProjectDialog
  571. v-if="addOrEditProjectDialogFlag"
  572. @reload="reload"
  573. :addOrEditDialogFlag.sync="addOrEditProjectDialogFlag"
  574. ref="addOrEditProjectDialogRef"
  575. ></addOrEditProjectDialog>
  576. <!-- 阶段弹窗 -->
  577. <addOrEditStageDialog
  578. v-if="addOrEditDialogStageFlag"
  579. @reload="reload"
  580. :addOrEditDialogStageFlag.sync="addOrEditDialogStageFlag"
  581. ref="addOrEditStageDialogRef"
  582. ></addOrEditStageDialog>
  583. </el-drawer>
  584. </template>
  585. <script>
  586. import AssetTree from '@/components/AssetTree';
  587. import p_search from './p_search.vue';
  588. import {
  589. projectsBomDeleteAPI,
  590. projectsBomFinishAPI,
  591. projectsBomPauseAPI,
  592. projectsBomStartupAPI,
  593. projectsBomTerminationAPI
  594. } from '@/api/project-manage/BOM.js';
  595. import Attribute from '@/views/BOMmanage/components/attribute.vue';
  596. import BOMBaseForm from '@/views/BOMmanage/components/BOMBaseForm.vue';
  597. import addBOMDialog from '@/views/BOMmanage/components/addBOMDialog.vue';
  598. import {
  599. getMyProjectsPage,
  600. getByBomTreeAPI,
  601. getPlanAndTaskTreeById,
  602. getProjectStageTree,
  603. getTaskTreeById,
  604. projectsFinishAPI,
  605. projectsGetByIdDetailsAPI,
  606. projectsPauseAPI,
  607. projectsStageDeleteAPI,
  608. projectsStageFinishAPI,
  609. projectsStagePauseAPI,
  610. projectsStageStartupAPI,
  611. projectsStageTerminationAPI,
  612. projectsStartupAPI,
  613. projectsTerminationAPI
  614. } from '@/api/project-manage';
  615. import projectForm from '@/views/project-manage/project-initiation/components/project-form.vue';
  616. import { listOrganizations } from '@/api/system/organization';
  617. import {
  618. projectsTeamGetByIdAPI,
  619. projectsTeamPageAPI
  620. } from '@/api/project-manage/team';
  621. import PlanCard from '@/views/BOMmanage/components/planCard.vue';
  622. import addPlanDialog from '@/views/project-manage/planManage/components/addOrEditDialog.vue';
  623. import planDetailDialog from '@/views/project-manage/planManage/components/detailDialog.vue';
  624. import taskDetailDialog from '@/views/project-manage/task-manage/components/detailDialog.vue';
  625. import projectStatistics from '@/views/project-manage/project-statistics/index.vue';
  626. import planForm from '@/views/project-manage/planManage/components/plan-form.vue';
  627. import {
  628. planFinishAPI,
  629. planPauseAPI,
  630. planStageFinishAPI,
  631. planStagePauseAPI,
  632. planStageStartupAPI,
  633. planStageTerminationAPI,
  634. planStartupAPI,
  635. planTerminationAPI,
  636. projectsPlanDeleteAPI,
  637. projectsPlanGetByIdAPI
  638. } from '@/api/project-manage/plan';
  639. import { deepClone } from '@/utils';
  640. import planInfoTable from '@/views/project-manage/planManage/components/planInfoTable.vue';
  641. import BaseForm from '@/views/project-manage/task-manage/components/base-form.vue';
  642. import {
  643. projectsTaskDeleteAPI,
  644. projectsTaskGetByIdAPI,
  645. projectsTaskOpRation
  646. } from '@/api/project-manage/task';
  647. import submitDeliverablesInfoTable from '@/views/project-manage/task-manage/components/submitDeliverablesInfoTable.vue';
  648. import { getByCode } from '@/api/system/dictionary-data';
  649. import teamInfoTable from '@/views/project-manage/team-manage/components/team-Info-table.vue';
  650. import addTaskDialog from '@/views/project-manage/task-manage/components/addOrEditDialog.vue';
  651. import { proStatusEnum, reviewStatusEnum } from '@/enum/dict';
  652. import transferDialog from '@/views/project-manage/task-manage/components/transferDialog.vue';
  653. import submitDeliverablesDialog from '@/views/project-manage/task-manage/components/submitDeliverablesDialog.vue';
  654. import addOrEditProjectDialog from '@/views/project-manage/project-initiation/components/addOrEditDialog.vue';
  655. import bpmDetail from '@/views/bpm/processInstance/detail.vue';
  656. import projectCalendar from '@/views/project-manage/project-calendar/index.vue';
  657. import planManageList from '@/views/project-manage/planManage/index.vue';
  658. import addOrEditStageDialog from '@/views/project-manage/project-initiation/components/addOrEditStageDialog.vue';
  659. import projectInfoTable from '@/views/project-manage/project-initiation/components/projectInfoTable.vue';
  660. export default {
  661. props: {},
  662. components: {
  663. p_search,
  664. bpmDetail,
  665. addOrEditProjectDialog,
  666. submitDeliverablesDialog,
  667. transferDialog,
  668. addTaskDialog,
  669. teamInfoTable,
  670. submitDeliverablesInfoTable,
  671. BaseForm,
  672. planInfoTable,
  673. planForm,
  674. taskDetailDialog,
  675. planDetailDialog,
  676. addPlanDialog,
  677. PlanCard,
  678. projectForm,
  679. BOMBaseForm,
  680. Attribute,
  681. addBOMDialog,
  682. AssetTree,
  683. planManageList,
  684. projectCalendar,
  685. projectInfoTable,
  686. addOrEditStageDialog,projectStatistics
  687. },
  688. data() {
  689. return {
  690. visible: false,
  691. title: '项目信息',
  692. projectsFinishAPI,
  693. projectsPauseAPI,
  694. projectsStartupAPI,
  695. projectsTerminationAPI,
  696. projectsBomFinishAPI,
  697. projectsBomPauseAPI,
  698. projectsBomStartupAPI,
  699. projectsBomTerminationAPI,
  700. projectsStageFinishAPI,
  701. projectsStagePauseAPI,
  702. projectsStageStartupAPI,
  703. projectsStageTerminationAPI,
  704. planFinishAPI,
  705. planPauseAPI,
  706. planStartupAPI,
  707. planTerminationAPI,
  708. planStageFinishAPI,
  709. planStagePauseAPI,
  710. planStageStartupAPI,
  711. planStageTerminationAPI,
  712. activeName: '基本信息',
  713. attrActiveName: '属性',
  714. leftTreeActiveName: 'BOM维度',
  715. active: 0,
  716. contextMenuData: {
  717. menuName: '',
  718. axis: {
  719. x: null,
  720. y: null
  721. }, // 鼠标位置
  722. menulists: []
  723. },
  724. contextTableMenuData: {
  725. menuName: '',
  726. axis: {
  727. x: null,
  728. y: null
  729. }, // 鼠标位置
  730. menulists: []
  731. },
  732. currentNodeData: {},
  733. planAndTaskTree: [],
  734. taskTree: [],
  735. deptList: [],
  736. deptTreeList: [],
  737. projectStepList: ['待立项', '审核中', '执行中', '已完成'],
  738. teamList: [],
  739. current: {},
  740. dialogForm: {},
  741. rightForm: {},
  742. teamForm: {},
  743. dictList: {},
  744. currentTableNodeData: {},
  745. treeList: [],
  746. addOrEditDialogStageFlag: false,
  747. bpmDetailFlag: false,
  748. isShow: false,
  749. treeLoading: false,
  750. addBOMDialogFlag: false,
  751. addPlanDialogFLag: false,
  752. addTaskDialogFlag: false,
  753. planDetailDialogFlag: false,
  754. taskDetailDialogFlag: false,
  755. transferDialogFlag: false,
  756. submitDeliverablesDialogFlag: false,
  757. addOrEditProjectDialogFlag: false,
  758. defaultProps: {
  759. children: 'children',
  760. label: 'name'
  761. },
  762. loading: false,
  763. filterText: null,
  764. categoryId: 1,
  765. loadingInstance: null,
  766. treeId: null,
  767. dialogType: null,
  768. rowData: {},
  769. refreshPlan: true
  770. };
  771. },
  772. watch: {
  773. filterText(val) {
  774. this.$refs.treeRef.filter(val);
  775. }
  776. },
  777. computed: {
  778. columns() {
  779. return [
  780. {
  781. columnKey: 'index',
  782. label: '序号',
  783. type: 'index',
  784. width: 55,
  785. align: 'center',
  786. showOverflowTooltip: true
  787. },
  788. {
  789. label: '名称',
  790. prop: 'name',
  791. showOverflowTooltip: true,
  792. minWidth: 180,
  793. slot: 'name'
  794. },
  795. {
  796. label: '类型名称',
  797. prop: 'type',
  798. showOverflowTooltip: true,
  799. minWidth: 80,
  800. align: 'center',
  801. slot: 'type'
  802. },
  803. {
  804. label: '预计开始时间',
  805. prop: 'planStartDate',
  806. formatter: (val) => {
  807. return val.planStartDate?.split(' ')[0];
  808. },
  809. showOverflowTooltip: true,
  810. minWidth: 150,
  811. align: 'center'
  812. },
  813. {
  814. label: '预计结束时间',
  815. prop: 'planEndDate',
  816. formatter: (val) => {
  817. return val.planEndDate?.split(' ')[0];
  818. },
  819. showOverflowTooltip: true,
  820. minWidth: 150,
  821. align: 'center'
  822. },
  823. {
  824. label: '预计工期(天)',
  825. prop: 'planDay',
  826. showOverflowTooltip: true,
  827. minWidth: 150,
  828. align: 'center'
  829. },
  830. {
  831. label: '实际开始时间',
  832. prop: 'realStartTime',
  833. // formatter: (val) => {
  834. // return val.realStartTime?.split(' ')[0]
  835. // },
  836. showOverflowTooltip: true,
  837. minWidth: 150,
  838. align: 'center'
  839. },
  840. {
  841. label: '实际结束时间',
  842. prop: 'realEndTime',
  843. // formatter: (val) => {
  844. // return val.realEndTime?.split(' ')[0]
  845. // },
  846. showOverflowTooltip: true,
  847. minWidth: 150,
  848. align: 'center'
  849. },
  850. {
  851. label: '实际工期(天)',
  852. prop: 'realDay',
  853. showOverflowTooltip: true,
  854. minWidth: 150,
  855. align: 'center'
  856. },
  857. {
  858. label: '负责人',
  859. prop: 'responsibleUserName',
  860. showOverflowTooltip: true,
  861. minWidth: 100,
  862. align: 'center'
  863. },
  864. {
  865. prop: 'processStatus',
  866. label: '审核状态',
  867. align: 'center',
  868. showOverflowTooltip: true,
  869. minWidth: 100,
  870. formatter: (_row, _column, cellValue) => {
  871. return reviewStatusEnum[_row.processStatus]?.label;
  872. }
  873. },
  874. {
  875. prop: 'status',
  876. label: '状态',
  877. align: 'center',
  878. showOverflowTooltip: true,
  879. minWidth: 100,
  880. formatter: (_row, _column, cellValue) => {
  881. return proStatusEnum[_row.status]?.label;
  882. }
  883. },
  884. {
  885. label: '进度',
  886. prop: 'speedPercent',
  887. showOverflowTooltip: false,
  888. minWidth: 120,
  889. align: 'center',
  890. slot: 'speedPercent'
  891. }
  892. ];
  893. }
  894. },
  895. mounted() {
  896. this.leftTreeActiveName = 'BOM维度';
  897. this.activeName = '基本信息';
  898. this.attrActiveName = '属性';
  899. this.isShow = false;
  900. /* if (this.$route.query.id) {
  901. this.initData();
  902. this.dialogType = this.$route.query.type;
  903. } */
  904. this.getDeptList();
  905. this.getTeamList();
  906. this.getDictList('pro_files_approve_type');
  907. this.getDictList('deliverables_type');
  908. this.getDictList('pro_projects_status');
  909. this.getDictList('pro_projects_budget_unit');
  910. },
  911. /* activated() {
  912. if (this.$route.query.id) {
  913. this.initData();
  914. this.dialogType = this.$route.query.type;
  915. }
  916. }, */
  917. methods: {
  918. getDictV(code, val) {
  919. if (!this.dictList[code]) return '';
  920. return this.dictList[code].find((item) => item.value == val)?.label;
  921. },
  922. async getDictList(code) {
  923. let { data: res } = await getByCode(code);
  924. this.dictList[code] = res.map((item) => {
  925. let values = Object.keys(item);
  926. return {
  927. value: values[0],
  928. label: item[values[0]]
  929. };
  930. });
  931. },
  932. async open(row) {
  933. this.rowData = row;
  934. this.visible = true;
  935. if (this.rowData.id) {
  936. this.$nextTick(()=>{
  937. this.$refs.treeList.getTreeData('',this.rowData.id)
  938. })
  939. this.initData();
  940. this.dialogType = this.rowData.type;
  941. }
  942. // this.getLeftData();
  943. },
  944. // async getLeftData(where) {
  945. // let pp = {
  946. // pageNum: 1,
  947. // size: 999,
  948. // parentId: parent?.id ?? '0',
  949. // /* name: this.rowData.name ?? '', */
  950. // ...where
  951. // };
  952. // const res = await getMyProjectsPage(pp);
  953. // this.leftTreeData = res.list;
  954. // },
  955. cancel() {
  956. this.$nextTick(() => {
  957. this.visible = false;
  958. });
  959. },
  960. handleTabs1(val) {
  961. this.activeName = val.label;
  962. this.attrActiveName = '属性';
  963. this.isShow = false;
  964. this.bpmDetailFlag = false;
  965. this.$nextTick(() => {
  966. this.bpmDetailFlag = true;
  967. });
  968. },
  969. filterNode(value, data) {
  970. if (!value) return true;
  971. return data.name.indexOf(value) !== -1;
  972. },
  973. async getDictList(code) {
  974. let { data: res } = await getByCode(code);
  975. this.dictList[code] = res.map((item) => {
  976. let values = Object.keys(item);
  977. return {
  978. value: values[0],
  979. label: item[values[0]]
  980. };
  981. });
  982. },
  983. initData() {
  984. this.getTreeData();
  985. },
  986. // 获取部门数据
  987. getDeptList() {
  988. listOrganizations().then((list) => {
  989. this.deptList = list;
  990. this.deptTreeList = this.$util.toTreeData({
  991. data: list,
  992. idField: 'id',
  993. parentIdField: 'parentId'
  994. });
  995. console.log(this.deptTreeList);
  996. });
  997. },
  998. getTeamList() {
  999. projectsTeamPageAPI({
  1000. pageNum: 1,
  1001. size: 999
  1002. }).then((list) => {
  1003. this.teamList = list;
  1004. });
  1005. },
  1006. handleUpdateProject(node, data, type) {
  1007. this.addOrEditProjectDialogFlag = true;
  1008. this.$nextTick(() => {
  1009. this.$refs.addOrEditProjectDialogRef.init(data, type);
  1010. });
  1011. },
  1012. bomRemove(node, data) {
  1013. let message = data.children.length
  1014. ? '当前节点包含子节点,是否确认删除?'
  1015. : '是否确认删除?';
  1016. this.$confirm(message, '提示', {
  1017. confirmButtonText: '确定',
  1018. cancelButtonText: '取消',
  1019. type: 'warning'
  1020. })
  1021. .then(async () => {
  1022. const loading = this.$loading({ lock: true });
  1023. await projectsBomDeleteAPI([data.id]);
  1024. loading.close();
  1025. this.$message.success('删除成功');
  1026. await this.getTreeData();
  1027. })
  1028. .catch(() => {
  1029. this.$message({
  1030. type: 'info',
  1031. message: '已取消删除'
  1032. });
  1033. });
  1034. },
  1035. stageRemove(node, data) {
  1036. let message = data.children.length
  1037. ? '当前节点包含子节点,是否确认删除?'
  1038. : '是否确认删除?';
  1039. this.$confirm(message, '提示', {
  1040. confirmButtonText: '确定',
  1041. cancelButtonText: '取消',
  1042. type: 'warning'
  1043. })
  1044. .then(async () => {
  1045. const loading = this.$loading({ lock: true });
  1046. await projectsStageDeleteAPI([data.id]);
  1047. loading.close();
  1048. this.$message.success('删除成功');
  1049. await this.getTreeData();
  1050. })
  1051. .catch(() => {
  1052. this.$message({
  1053. type: 'info',
  1054. message: '已取消删除'
  1055. });
  1056. });
  1057. },
  1058. back() {
  1059. this.$router.go(-1);
  1060. },
  1061. async validateForm() {
  1062. return Promise.all([
  1063. new Promise((resolve, reject) => {
  1064. this.$refs.BOMBaseFormRef.getValidaValue((valid) => {
  1065. if (!valid) {
  1066. reject(false);
  1067. } else {
  1068. resolve(true);
  1069. }
  1070. });
  1071. })
  1072. ]).catch(() => {
  1073. this.$message.warning('请先填写完整信息');
  1074. return Promise.reject(false);
  1075. });
  1076. },
  1077. addChildProject() {},
  1078. addOrEditBOM(type, node, data) {
  1079. this.addBOMDialogFlag = true;
  1080. this.$nextTick(() => {
  1081. this.$refs.addBOMDialogRef.init(data, type);
  1082. });
  1083. },
  1084. handleAddStage(node, data, type) {
  1085. this.addOrEditDialogStageFlag = true;
  1086. this.$nextTick(() => {
  1087. this.$refs.addOrEditStageDialogRef.init(data, type);
  1088. });
  1089. },
  1090. handleAddPlan(type, node, data, sourceName = 'project') {
  1091. this.addPlanDialogFLag = true;
  1092. let params = {};
  1093. if (sourceName == 'plan') {
  1094. params = {
  1095. projectId: data.projectId,
  1096. projectStageId: data.projectStageId,
  1097. projectBomId: data.projectBomId,
  1098. parentPlanId: data.id,
  1099. id: data.id
  1100. };
  1101. } else {
  1102. switch (data.type) {
  1103. case 0:
  1104. params = {
  1105. projectId: data.id
  1106. };
  1107. break;
  1108. case 1:
  1109. params = {
  1110. projectId: data.projectId,
  1111. projectBomId: data.id
  1112. };
  1113. break;
  1114. case 2:
  1115. params = {
  1116. projectId: data.projectId,
  1117. projectStageId: data.id
  1118. };
  1119. break;
  1120. }
  1121. }
  1122. this.$nextTick(() => {
  1123. this.$refs.addPlanDialogRef.init(params, type);
  1124. this.$refs.refreshPlan.datasource();
  1125. });
  1126. },
  1127. async handleStatus(API, msg, node, row) {
  1128. this.$confirm(msg, '提示', {
  1129. type: 'warning'
  1130. })
  1131. .then(async () => {
  1132. await API(row.id);
  1133. this.$message.success('操作成功');
  1134. this.reload();
  1135. })
  1136. .catch(() => {});
  1137. },
  1138. //报工/执行
  1139. async handleStartTask(row, afterStatus, msg) {
  1140. this.$confirm(msg, '提示', {
  1141. confirmButtonText: '确定',
  1142. cancelButtonText: '取消',
  1143. type: 'warning'
  1144. })
  1145. .then(async () => {
  1146. let params = {
  1147. id: row.id,
  1148. afterStatus: afterStatus,
  1149. status: row.status
  1150. };
  1151. await projectsTaskOpRation(params);
  1152. this.$message.success('操作成功');
  1153. this.reload();
  1154. })
  1155. .catch(() => {});
  1156. },
  1157. handleRemovePlan(ids) {
  1158. this.$confirm('此操作将永久删除该计划, 是否继续?', '提示', {
  1159. confirmButtonText: '确定',
  1160. cancelButtonText: '取消',
  1161. type: 'warning'
  1162. }).then(async () => {
  1163. const loading = this.$loading({ lock: true });
  1164. projectsPlanDeleteAPI(ids)
  1165. .then((res) => {
  1166. loading.close();
  1167. this.$message.success('删除成功');
  1168. this.reload();
  1169. })
  1170. .catch((e) => {
  1171. loading.close();
  1172. // this.$message.error(e.message);
  1173. });
  1174. });
  1175. },
  1176. /* 删除 */
  1177. handleRemoveTask(ids) {
  1178. this.$confirm('此操作将永久删除该任务, 是否继续?', '提示', {
  1179. confirmButtonText: '确定',
  1180. cancelButtonText: '取消',
  1181. type: 'warning'
  1182. })
  1183. .then(async () => {
  1184. const loading = this.$loading({ lock: true });
  1185. projectsTaskDeleteAPI(ids)
  1186. .then((res) => {
  1187. loading.close();
  1188. this.$message.success('删除成功');
  1189. this.reload();
  1190. })
  1191. .catch((e) => {
  1192. loading.close();
  1193. // this.$message.error(e.message);
  1194. });
  1195. })
  1196. .catch(() => {});
  1197. },
  1198. /* */
  1199. handleAddTask(type, node, data, sourceName = 'project') {
  1200. this.addTaskDialogFlag = true;
  1201. let params = {};
  1202. if (sourceName == 'plan') {
  1203. switch (data.type) {
  1204. case 0:
  1205. params = {
  1206. targetPlanId: data.id,
  1207. projectId: data.projectId,
  1208. projectStageId: data.projectStageId
  1209. };
  1210. break;
  1211. case 1:
  1212. params = {
  1213. targetPlanId: data.parentId,
  1214. projectId: data.projectId,
  1215. projectStageId: data.projectStageId,
  1216. planStageId: data.id
  1217. };
  1218. break;
  1219. case 2:
  1220. params = {
  1221. targetPlanId: data.targetPlanId,
  1222. projectId: data.projectId,
  1223. projectStageId: data.projectStageId,
  1224. planStageId: data.planStageId,
  1225. taskId: data.id,
  1226. id: type !== 'add' ? data.id : ''
  1227. };
  1228. break;
  1229. }
  1230. } else {
  1231. switch (data.type) {
  1232. case 0:
  1233. params = {
  1234. projectId: data.id
  1235. };
  1236. break;
  1237. case 1:
  1238. params = {
  1239. projectId: data.projectId,
  1240. projectBomId: data.id
  1241. };
  1242. break;
  1243. case 2:
  1244. params = {
  1245. projectId: data.projectId,
  1246. projectStageId: data.id
  1247. };
  1248. break;
  1249. }
  1250. }
  1251. this.$nextTick(() => {
  1252. this.$refs.addTaskDialogRef.init(params, type);
  1253. });
  1254. },
  1255. async getTreeData() {
  1256. try {
  1257. this.treeLoading = true;
  1258. let API =
  1259. this.leftTreeActiveName == 'BOM维度'
  1260. ? getByBomTreeAPI
  1261. : getProjectStageTree;
  1262. const res = await API(this.rowData.id);
  1263. this.treeList = [res];
  1264. this.$nextTick(() => {
  1265. if (this.treeList.length) {
  1266. // 默认高亮第一个
  1267. this.$refs.treeRef.setCurrentKey(this.treeList[0]?.id);
  1268. this.handleNodeClick(this.treeList[0]);
  1269. }
  1270. });
  1271. } catch (error) {}
  1272. this.treeLoading = false;
  1273. },
  1274. async handleNodeClick1(data){
  1275. if(data.type=="projectType"){
  1276. this.rowData=this.dialogForm = await projectsGetByIdDetailsAPI(data.id);
  1277. this.getTreeData()
  1278. }
  1279. },
  1280. getIconClass(node, data) {
  1281. switch (data.type) {
  1282. case 2:
  1283. return node.expanded ? 'el-icon-document' : 'el-icon-tickets';
  1284. case 1:
  1285. return node.expanded ? 'el-icon-document' : 'el-icon-tickets';
  1286. case 0:
  1287. return node.expanded ? 'el-icon-folder-opened' : 'el-icon-folder';
  1288. default:
  1289. return '';
  1290. }
  1291. },
  1292. showRightMenu(event, node, data) {
  1293. if (this.dialogType == 'view') return;
  1294. this.contextMenuData.menuName =
  1295. data.id + '_' + data.name + '_rightMenu';
  1296. this.$nextTick(() => {
  1297. let menuList = [
  1298. ...document.querySelectorAll('.vue-contextmenu-listWrapper')
  1299. ];
  1300. menuList.forEach((item) => {
  1301. item.style.display = 'none';
  1302. });
  1303. event.preventDefault();
  1304. const x = event.clientX;
  1305. const y = event.clientY;
  1306. this.contextMenuData.axis = { x, y };
  1307. switch (data.type) {
  1308. case 0:
  1309. this.contextMenuData.menulists = [
  1310. {
  1311. fnHandler: 'addChildProject',
  1312. icoName: 'fa el-icon-plus',
  1313. btnName: '新建子项目',
  1314. disabled:
  1315. this.disableToAddBOM(data) &&
  1316. this.$hasPermission('pro:projects:save')
  1317. },
  1318. {
  1319. fnHandler: 'addStage',
  1320. icoName: 'fa el-icon-plus',
  1321. btnName: '新建阶段',
  1322. disabled:
  1323. this.disableToAddBOM(data) &&
  1324. this.$hasPermission('pro:projects:save')
  1325. },
  1326. {
  1327. fnHandler: 'addBOM',
  1328. icoName: 'fa el-icon-plus',
  1329. btnName: '新建BOM',
  1330. disabled:
  1331. this.disableToAddBOM(data) &&
  1332. this.$hasPermission('pro:projects:save')
  1333. },
  1334. {
  1335. fnHandler: 'addPlan',
  1336. icoName: 'fa el-icon-plus',
  1337. btnName: '新建计划',
  1338. disabled: this.disableToAddPlan(data)
  1339. },
  1340. {
  1341. fnHandler: 'addTask',
  1342. icoName: 'fa el-icon-plus',
  1343. btnName: '新建任务',
  1344. disabled: this.disableToAddTask(data)
  1345. },
  1346. {
  1347. fnHandler: 'updateProject',
  1348. icoName: 'fa el-icon-edit',
  1349. btnName: '修改',
  1350. disabled:
  1351. [1, 2].includes(data.processStatus) &&
  1352. this.$hasPermission('pro:projects:update')
  1353. },
  1354. {
  1355. fnHandler: 'onRemove',
  1356. icoName: 'fa el-icon-delete',
  1357. btnName: '删除',
  1358. disabled:
  1359. [1, 2].includes(data.processStatus) &&
  1360. this.$hasPermission('pro:projects:delete')
  1361. },
  1362. {
  1363. fnHandler: 'handleFinish',
  1364. icoName: 'fa el-icon-success',
  1365. btnName: '完成',
  1366. disabled:
  1367. this.disableToFinish(data) &&
  1368. this.$hasPermission('pro:projects:update')
  1369. },
  1370. {
  1371. fnHandler: 'handlePause',
  1372. icoName: 'fa el-icon-video-pause',
  1373. btnName: '暂停',
  1374. disabled:
  1375. this.disableToPause(data) &&
  1376. this.$hasPermission('pro:projects:update')
  1377. },
  1378. {
  1379. fnHandler: 'handleStartup',
  1380. icoName: 'fa el-icon-video-play',
  1381. btnName: '启动',
  1382. disabled:
  1383. this.disableToStartup(data) &&
  1384. this.$hasPermission('pro:projects:update')
  1385. },
  1386. {
  1387. fnHandler: 'handleTermination',
  1388. icoName: 'fa el-icon-error',
  1389. btnName: '终止',
  1390. disabled:
  1391. this.disableToTermination(data) &&
  1392. this.$hasPermission('pro:projects:update')
  1393. }
  1394. ];
  1395. break;
  1396. case 1:
  1397. this.contextMenuData.menulists = [
  1398. {
  1399. fnHandler: 'addBOM',
  1400. icoName: 'fa el-icon-plus',
  1401. btnName: '新建BOM',
  1402. disabled:
  1403. this.disableToAddBOM(data) &&
  1404. this.$hasPermission('pro:projects:save')
  1405. },
  1406. {
  1407. fnHandler: 'addPlan',
  1408. icoName: 'fa el-icon-plus',
  1409. btnName: '新建计划',
  1410. disabled: this.disableToAddPlan(data)
  1411. },
  1412. {
  1413. fnHandler: 'addTask',
  1414. icoName: 'fa el-icon-plus',
  1415. btnName: '新建任务',
  1416. disabled: this.disableToAddTask(data)
  1417. },
  1418. {
  1419. fnHandler: 'editBOM',
  1420. icoName: 'fa el-icon-edit',
  1421. btnName: '修改',
  1422. disabled:
  1423. ![0].includes(data.status) &&
  1424. this.$hasPermission('pro:projects:update')
  1425. },
  1426. {
  1427. fnHandler: 'removeBom',
  1428. icoName: 'fa el-icon-delete',
  1429. btnName: '删除',
  1430. disabled:
  1431. ![0].includes(data.status) &&
  1432. this.$hasPermission('pro:projects:delete')
  1433. },
  1434. {
  1435. fnHandler: 'handleBomFinish',
  1436. icoName: 'fa el-icon-success',
  1437. btnName: '完成',
  1438. disabled:
  1439. this.disableToFinish(data) &&
  1440. this.$hasPermission('pro:projects:update')
  1441. },
  1442. {
  1443. fnHandler: 'handleBomPause',
  1444. icoName: 'fa el-icon-video-pause',
  1445. btnName: '暂停',
  1446. disabled:
  1447. this.disableToPause(data) &&
  1448. this.$hasPermission('pro:projects:update')
  1449. },
  1450. {
  1451. fnHandler: 'handleBomStartup',
  1452. icoName: 'fa el-icon-video-play',
  1453. btnName: '启动',
  1454. disabled:
  1455. this.disableToStartup(data) &&
  1456. this.$hasPermission('pro:projects:update')
  1457. },
  1458. {
  1459. fnHandler: 'handleBomTermination',
  1460. icoName: 'fa el-icon-error',
  1461. btnName: '终止',
  1462. disabled:
  1463. this.disableToTermination(data) &&
  1464. this.$hasPermission('pro:projects:update')
  1465. }
  1466. ];
  1467. break;
  1468. case 2:
  1469. this.contextMenuData.menulists = [
  1470. {
  1471. fnHandler: 'addPlan',
  1472. icoName: 'fa el-icon-plus',
  1473. btnName: '新建计划',
  1474. disabled: this.disableToAddPlan(data)
  1475. },
  1476. {
  1477. fnHandler: 'addTask',
  1478. icoName: 'fa el-icon-plus',
  1479. btnName: '新建任务',
  1480. disabled: this.disableToAddTask(data)
  1481. },
  1482. // {fnHandler: 'onSave',
  1483. // icoName: 'fa el-icon-edit',
  1484. // btnName: '修改'
  1485. // },
  1486. // {fnHandler: 'stageRemove',
  1487. // icoName: 'fa el-icon-delete',
  1488. // btnName: '删除'
  1489. // },
  1490. {
  1491. fnHandler: 'handleStageFinish',
  1492. icoName: 'fa el-icon-success',
  1493. btnName: '完成',
  1494. disabled: this.disableToFinish(data)
  1495. },
  1496. {
  1497. fnHandler: 'handleStagePause',
  1498. icoName: 'fa el-icon-video-pause',
  1499. btnName: '暂停',
  1500. disabled: this.disableToPause(data)
  1501. },
  1502. {
  1503. fnHandler: 'handleStageStartup',
  1504. icoName: 'fa el-icon-video-play',
  1505. btnName: '启动',
  1506. disabled: this.disableToStartup(data)
  1507. },
  1508. {
  1509. fnHandler: 'handleStageTermination',
  1510. icoName: 'fa el-icon-error',
  1511. btnName: '终止',
  1512. disabled: this.disableToTermination(data)
  1513. }
  1514. ];
  1515. break;
  1516. }
  1517. });
  1518. },
  1519. disableToAddBOM(row) {
  1520. return (
  1521. ![0, 1, 2, 3].includes(row.processStatus) ||
  1522. ![0, 1].includes(row.status)
  1523. );
  1524. },
  1525. disableToAddPlan(row) {
  1526. return (
  1527. ![0, 1, 2, 3].includes(row.processStatus) ||
  1528. ![0, 1].includes(row.status)
  1529. );
  1530. },
  1531. disableToAddTask(row) {
  1532. return (
  1533. ![0, 1, 2, 3].includes(row.processStatus) ||
  1534. ![0, 1].includes(row.status)
  1535. );
  1536. },
  1537. disableToFinish(row) {
  1538. return (
  1539. ![2].includes(row.processStatus) || [4, 2, 3].includes(row.status)
  1540. );
  1541. },
  1542. disableToPause(row) {
  1543. return (
  1544. ![2].includes(row.processStatus) || [4, 2, 3].includes(row.status)
  1545. );
  1546. },
  1547. disableToStartup(row) {
  1548. return (
  1549. ![2].includes(row.processStatus) || [4, 1, 0, 3].includes(row.status)
  1550. );
  1551. },
  1552. disableToTermination(row) {
  1553. return ![2].includes(row.processStatus) || [4, 3].includes(row.status);
  1554. },
  1555. handleNodeClick(data) {
  1556. this.treeId = data.id;
  1557. this.currentNodeData = data;
  1558. this.$nextTick(async () => {
  1559. switch (data.type) {
  1560. case 1:
  1561. await this.$refs.attributeRef.setAttributeFormData(
  1562. this.currentNodeData
  1563. );
  1564. break;
  1565. case 2:
  1566. this.dialogForm = await projectsGetByIdDetailsAPI(data.parentId);
  1567. break;
  1568. case 0:
  1569. this.dialogForm = await projectsGetByIdDetailsAPI(data.id);
  1570. this.dialogForm.type = this.dialogForm.type + '';
  1571. this.dialogForm.level = this.dialogForm.level + '';
  1572. this.dialogForm.parentId =
  1573. this.dialogForm.parentId == 0 ? '' : this.dialogForm.parentId;
  1574. this.projectStepList = ['待立项', '审核中', '执行中', '已完成'];
  1575. if (data.processStatus == 0) {
  1576. this.active = 0;
  1577. break;
  1578. }
  1579. if ([1, 3].includes(data.processStatus)) {
  1580. let stepName =
  1581. data.processStatus == 3 ? '审核未通过' : '审核中';
  1582. this.projectStepList.splice(1, 1, stepName);
  1583. this.active = 1;
  1584. break;
  1585. }
  1586. if ([0, 1, 2].includes(data.status)) {
  1587. let stepName =
  1588. data.status == 1
  1589. ? '执行中'
  1590. : data.status == 2
  1591. ? '暂停中'
  1592. : '未开始';
  1593. this.projectStepList.splice(2, 1, stepName);
  1594. this.active = 2;
  1595. break;
  1596. }
  1597. if ([3, 4].includes(data.status)) {
  1598. let stepName = data.status == 3 ? '已完成' : '已终止';
  1599. this.projectStepList.splice(3, 1, stepName);
  1600. this.active = 4;
  1601. break;
  1602. }
  1603. break;
  1604. }
  1605. if ([0, 2].includes(data.type)) {
  1606. this.dialogForm.type = this.dialogForm.type + '';
  1607. this.dialogForm.level = this.dialogForm.level + '';
  1608. this.dialogForm.parentId =
  1609. this.dialogForm.parentId == 0 ? '' : this.dialogForm.parentId;
  1610. this.dialogForm.stageList = this.dialogForm.allStageList;
  1611. await this.getTeamInfo(this.dialogForm.teamId);
  1612. }
  1613. });
  1614. this.getPlanAndTaskTree(data);
  1615. this.getTaskTree(data);
  1616. },
  1617. async getPlanAndTaskTree(data) {
  1618. let paramAttr = '';
  1619. switch (data.type) {
  1620. case 1:
  1621. paramAttr = 'projectBomId';
  1622. break;
  1623. case 2:
  1624. paramAttr = 'projectStageId';
  1625. break;
  1626. default:
  1627. paramAttr = 'projectId';
  1628. }
  1629. let params = {
  1630. [paramAttr]: data.id
  1631. };
  1632. this.planAndTaskTree = await getPlanAndTaskTreeById(params);
  1633. },
  1634. async getTaskTree(data) {
  1635. let paramAttr = '';
  1636. switch (data.type) {
  1637. case 1:
  1638. paramAttr = 'projectBomId';
  1639. break;
  1640. case 2:
  1641. paramAttr = 'projectStageId';
  1642. break;
  1643. default:
  1644. paramAttr = 'projectId';
  1645. }
  1646. let params = {
  1647. [paramAttr]: data.id
  1648. };
  1649. this.taskTree = await getTaskTreeById(params);
  1650. },
  1651. reload(where) {
  1652. this.getTreeData();
  1653. },
  1654. setTableCell({ row }) {
  1655. console.log(row.level);
  1656. if (row.level === 1) return ''; //
  1657. return { marginLeft: row.level + 3 + 'px' }; //
  1658. },
  1659. handleTableNodeClick(row) {
  1660. this.isShow = true;
  1661. this.attrActiveName = '属性';
  1662. this.currentTableNodeData = row;
  1663. console.log(row, 'row.type');
  1664. switch (row.type) {
  1665. case 0:
  1666. this.getProjectPlanInfo(row.id);
  1667. break;
  1668. case 1:
  1669. this.getProjectPlanInfo(row.targetPlanId);
  1670. break;
  1671. case 2:
  1672. this.getProjectTaskInfo(row.id);
  1673. break;
  1674. }
  1675. },
  1676. handlePlanTableNodeClick(row) {
  1677. console.log(row, '点击计划某一行');
  1678. this.isShow = true;
  1679. this.attrActiveName = '属性';
  1680. this.currentTableNodeData = row;
  1681. this.getProjectPlanInfo(row.id);
  1682. },
  1683. showTableRightMenu(row, column, event) {
  1684. if (this.dialogType == 'view') return;
  1685. this.contextTableMenuData.menuName = row.name;
  1686. this.$nextTick(() => {
  1687. let menuList = [
  1688. ...document.querySelectorAll('.vue-contextmenu-listWrapper')
  1689. ];
  1690. menuList.forEach((item) => {
  1691. item.style.display = 'none';
  1692. });
  1693. event.preventDefault();
  1694. const x = event.clientX;
  1695. const y = event.clientY;
  1696. this.contextTableMenuData.axis = { x, y };
  1697. switch (row.type) {
  1698. case 0:
  1699. this.contextTableMenuData.menulists = [
  1700. {
  1701. fnHandler: 'addPlan',
  1702. icoName: 'fa el-icon-plus',
  1703. btnName: '新建计划',
  1704. disabled: this.disableToAddPlan(row)
  1705. },
  1706. {
  1707. fnHandler: 'addTask',
  1708. icoName: 'fa el-icon-plus',
  1709. btnName: '新建任务',
  1710. disabled: this.disableToAddTask(row)
  1711. },
  1712. {
  1713. fnHandler: 'editPlan',
  1714. icoName: 'fa el-icon-edit',
  1715. btnName: '修改',
  1716. disabled:
  1717. [1, 2].includes(row.processStatus) ||
  1718. ![0].includes(row.status)
  1719. },
  1720. {
  1721. fnHandler: 'removePlan',
  1722. icoName: 'fa el-icon-delete',
  1723. btnName: '删除',
  1724. disabled:
  1725. [1, 2].includes(row.processStatus) ||
  1726. ![0].includes(row.status)
  1727. },
  1728. {
  1729. fnHandler: 'finishPlan',
  1730. icoName: 'fa el-icon-success',
  1731. btnName: '完成',
  1732. disabled: this.disableToFinish(row)
  1733. },
  1734. {
  1735. fnHandler: 'pausePlan',
  1736. icoName: 'fa el-icon-video-pause',
  1737. btnName: '暂停',
  1738. disabled: this.disableToPause(row)
  1739. },
  1740. {
  1741. fnHandler: 'startupPlan',
  1742. icoName: 'fa el-icon-video-play',
  1743. btnName: '启动',
  1744. disabled: this.disableToStartup(row)
  1745. },
  1746. {
  1747. fnHandler: 'terminationPlan',
  1748. icoName: 'fa el-icon-error',
  1749. btnName: '终止',
  1750. disabled: this.disableToTermination(row)
  1751. }
  1752. ];
  1753. break;
  1754. case 1:
  1755. this.contextTableMenuData.menulists = [
  1756. {
  1757. fnHandler: 'addTask',
  1758. icoName: 'fa el-icon-plus',
  1759. btnName: '新建任务',
  1760. disabled: this.disableToAddTask(row)
  1761. },
  1762. // {fnHandler: 'editBOM', icoName: 'fa el-icon-edit', btnName: '修改'},
  1763. // {fnHandler: 'removeBom', icoName: 'fa el-icon-delete', btnName: '删除'},
  1764. {
  1765. fnHandler: 'finishPlanStage',
  1766. icoName: 'fa el-icon-success',
  1767. btnName: '完成',
  1768. disabled: this.disableToFinish(row)
  1769. },
  1770. {
  1771. fnHandler: 'pausePlanStage',
  1772. icoName: 'fa el-icon-video-pause',
  1773. btnName: '暂停',
  1774. disabled: this.disableToPause(row)
  1775. },
  1776. {
  1777. fnHandler: 'startupPlanStage',
  1778. icoName: 'fa el-icon-video-play',
  1779. btnName: '启动',
  1780. disabled: this.disableToStartup(row)
  1781. },
  1782. {
  1783. fnHandler: 'terminationPlanStage',
  1784. icoName: 'fa el-icon-error',
  1785. btnName: '终止',
  1786. disabled: this.disableToTermination(row)
  1787. }
  1788. ];
  1789. break;
  1790. case 2:
  1791. this.contextTableMenuData.menulists = [
  1792. {
  1793. fnHandler: 'addTask',
  1794. icoName: 'fa el-icon-plus',
  1795. btnName: '新建任务',
  1796. disabled: [4, 2, 3].includes(row.status)
  1797. },
  1798. {
  1799. fnHandler: 'updateTask',
  1800. icoName: 'fa el-icon-edit',
  1801. btnName: '修改',
  1802. disabled: [4, 2, 3, 1].includes(row.status)
  1803. },
  1804. {
  1805. fnHandler: 'removeTask',
  1806. icoName: 'fa el-icon-delete',
  1807. btnName: '删除',
  1808. disabled: [4, 2, 3, 1].includes(row.status)
  1809. },
  1810. {
  1811. fnHandler: 'startTask',
  1812. icoName: 'fa el-icon-video-play',
  1813. btnName: '执行',
  1814. disabled: [4, 3, 1].includes(row.status)
  1815. },
  1816. {
  1817. fnHandler: 'handleSubmitDeliverables',
  1818. icoName: 'fa el-icon-folder-add',
  1819. btnName: '交付物提交',
  1820. disabled: [4, 3, 0, 2].includes(row.status)
  1821. },
  1822. {
  1823. fnHandler: 'finishTask',
  1824. icoName: 'fa el-icon-success',
  1825. btnName: '报工',
  1826. disabled: !(
  1827. [1].includes(row.status) && row.ifFilesAllFinish == 1
  1828. )
  1829. },
  1830. {
  1831. fnHandler: 'pauseTask',
  1832. icoName: 'fa el-icon-video-pause',
  1833. btnName: '暂停',
  1834. disabled: this.disableToPause(row)
  1835. },
  1836. {
  1837. fnHandler: 'terminationTask',
  1838. icoName: 'fa el-icon-error',
  1839. btnName: '终止',
  1840. disabled: this.disableToTermination(row)
  1841. },
  1842. {
  1843. fnHandler: 'handleTransfer',
  1844. icoName: 'fa el-icon-position',
  1845. btnName: '转派',
  1846. disabled: ![1].includes(row.status)
  1847. }
  1848. ];
  1849. break;
  1850. }
  1851. });
  1852. },
  1853. //转派
  1854. handleTransfer(row) {
  1855. this.transferDialogFlag = true;
  1856. this.$nextTick(() => {
  1857. this.$refs.transferDialogRef.init(row);
  1858. });
  1859. },
  1860. /* 交付物提交 */
  1861. handleSubmitDeliverables(row = {}, type) {
  1862. this.submitDeliverablesDialogFlag = true;
  1863. this.$nextTick(() => {
  1864. this.$refs.submitDeliverablesDialogRef.init(row, type);
  1865. });
  1866. },
  1867. async getProjectTaskInfo(id = '') {
  1868. this.rightForm = await projectsTaskGetByIdAPI(id);
  1869. this.rightForm.type = this.rightForm.type + '';
  1870. this.rightForm.responsibleUserIds =
  1871. this.rightForm.responsibleUserList?.map((i) => i.userName) || [];
  1872. },
  1873. async getProjectPlanInfo(id = '') {
  1874. let res = await projectsPlanGetByIdAPI(id);
  1875. this.rightForm = deepClone(res);
  1876. this.rightForm.responsibleUserIds =
  1877. this.rightForm.responsibleUserList?.map((i) => i.userName) || [];
  1878. this.rightForm.planStageList?.forEach((item, index) => {
  1879. let userNames = item.responsibleUserList.map((i) => i.userName) || [];
  1880. this.$set(item, 'responsibleUserNames', userNames.join(','));
  1881. });
  1882. // await this.changeProject(this.dialogForm.projectId)
  1883. },
  1884. async getTeamInfo(teamId) {
  1885. if (teamId) {
  1886. this.teamForm = await projectsTeamGetByIdAPI(teamId);
  1887. }
  1888. },
  1889. // 每一级字体变小
  1890. fontSize(node, data) {
  1891. if (node.level === 1 || node.level === 2) return 'font-size:14px'; // 一二级字体
  1892. return 'font-size:' + 13 + 'px'; // 三级以下字号减小
  1893. },
  1894. uploadFile() {
  1895. this.$refs.importDialogRef.open();
  1896. },
  1897. handleLeftTreeActiveName(val) {
  1898. console.log(val);
  1899. this.leftTreeActiveName = val;
  1900. this.getTreeData();
  1901. },
  1902. customColorMethod(percentage) {
  1903. if (percentage < 30) {
  1904. return '#b6b6b6';
  1905. } else if (percentage < 70) {
  1906. return '#b3e496';
  1907. } else {
  1908. return '#67c23a';
  1909. }
  1910. }
  1911. }
  1912. };
  1913. </script>
  1914. <style lang="scss" scoped>
  1915. :deep(.el-drawer__body) {
  1916. overflow: hidden;
  1917. }
  1918. .ele-body {
  1919. display: flex;
  1920. flex-direction: column;
  1921. height: 100%;
  1922. .card_2_box {
  1923. flex: 1;
  1924. ::v-deep .el-card__body {
  1925. height: 100%;
  1926. .card_2_box_content {
  1927. height: 100%;
  1928. .ele-split-panel {
  1929. height: 100%;
  1930. .el_tree_box {
  1931. padding: 0 4px 0 0;
  1932. height: 100%;
  1933. border: none;
  1934. border-right: 1px solid #e8eaec;
  1935. //border-radius: 3px;
  1936. .el-tree-node {
  1937. .el-tree-node__children {
  1938. height: 100%;
  1939. overflow: auto;
  1940. }
  1941. }
  1942. }
  1943. }
  1944. }
  1945. }
  1946. }
  1947. }
  1948. .card_2_layout_content {
  1949. display: flex;
  1950. flex-direction: column;
  1951. height: 100%;
  1952. ::v-deep .card_2_1_box {
  1953. height: 50px;
  1954. width: 100%;
  1955. margin-bottom: 10px;
  1956. .border-box-content {
  1957. height: 100%;
  1958. width: 100%;
  1959. background: rgba(203, 203, 203, 0.12);
  1960. border-radius: 3px;
  1961. display: flex;
  1962. flex-direction: row;
  1963. justify-content: space-between;
  1964. align-items: center;
  1965. .card_2_1_box_div_1 {
  1966. flex: 1;
  1967. height: 50px;
  1968. display: flex;
  1969. align-items: center;
  1970. .el-steps--simple {
  1971. border-radius: 0 !important;
  1972. background: none;
  1973. width: 100%;
  1974. padding: 10px 8%;
  1975. }
  1976. .is-success {
  1977. color: rgb(103, 103, 103) !important;
  1978. .el-step__icon {
  1979. border-color: rgb(103, 103, 103) !important;
  1980. }
  1981. .el-icon-check:before {
  1982. font-size: 14px;
  1983. line-height: 14px;
  1984. font-weight: bold;
  1985. color: rgb(103, 103, 103) !important;
  1986. }
  1987. }
  1988. .el-step__main {
  1989. .is-process:before {
  1990. content: '';
  1991. background: rgba(182, 182, 182, 0.26);
  1992. height: 30px;
  1993. width: 160px;
  1994. display: block;
  1995. position: absolute;
  1996. border-radius: 15px;
  1997. transform: translate(-40%, -18%);
  1998. }
  1999. }
  2000. .is-process {
  2001. border-color: #f8f8f8 !important;
  2002. font-weight: bold;
  2003. }
  2004. .is-success + .el-step__arrow:before {
  2005. background: rgb(202, 205, 212) !important;
  2006. }
  2007. .is-success + .el-step__arrow:after {
  2008. background: rgb(202, 205, 212) !important;
  2009. }
  2010. }
  2011. .card_2_1_box_div_2 {
  2012. width: 150px;
  2013. margin-right: 10px;
  2014. height: 100%;
  2015. display: flex;
  2016. align-items: center;
  2017. .dv-percent-pond text {
  2018. font-size: 20px !important;
  2019. transform: translate(0%, 10%);
  2020. }
  2021. }
  2022. }
  2023. }
  2024. ::v-deep .tab-box_1 {
  2025. flex: 1;
  2026. .el-tabs__content {
  2027. //padding: 10px;
  2028. height: calc(100% - 45px);
  2029. //overflow: auto;
  2030. padding: 0;
  2031. padding-top: 10px;
  2032. .el-tab-pane {
  2033. height: 100%;
  2034. }
  2035. }
  2036. }
  2037. }
  2038. ::v-deep .project_tree {
  2039. .custom-tree-node {
  2040. display: flex;
  2041. align-items: center;
  2042. .label_img {
  2043. width: 20px;
  2044. height: 20px;
  2045. margin-left: 5px;
  2046. }
  2047. }
  2048. .el-tree-node {
  2049. position: relative;
  2050. padding-left: 0px;
  2051. }
  2052. .el-tree-node__children {
  2053. padding-left: 22px;
  2054. }
  2055. // 自定义图标中隐藏自带箭头
  2056. //.el-tree-node__content > .el-tree-node__expand-icon {
  2057. // position: absolute;
  2058. // opacity: 0;
  2059. //}
  2060. .el-tree-node__content > .el-tree-node__expand-icon {
  2061. padding: 0;
  2062. }
  2063. // 禁止旋转
  2064. .el-tree .el-tree-node__expand-icon.expanded {
  2065. -webkit-transform: rotate(0deg);
  2066. transform: rotate(0deg);
  2067. }
  2068. // 节点高度与边距
  2069. .el-tree-node__content {
  2070. height: 30px;
  2071. }
  2072. .el-tree-node {
  2073. margin: 1px 0;
  2074. overflow: hidden;
  2075. text-overflow: ellipsis;
  2076. white-space: nowrap;
  2077. }
  2078. //高亮字体颜色
  2079. .el-tree--highlight-current
  2080. .el-tree-node.is-current
  2081. > .el-tree-node__content {
  2082. color: #ee7355 !important;
  2083. background-color: red !important; // 设置选中背景颜色
  2084. }
  2085. // 设置竖线
  2086. .el-tree-node .is-focusable:before {
  2087. content: '';
  2088. display: inline-block;
  2089. position: absolute;
  2090. left: -15px;
  2091. border-left: 1px solid #f8f8f8;
  2092. height: calc(100%);
  2093. }
  2094. .list-left {
  2095. width: 214px;
  2096. height: auto;
  2097. margin: 10px 0 20px 20px;
  2098. background-color: #fff;
  2099. border-radius: 10px;
  2100. padding: 20px;
  2101. }
  2102. // 鼠标移入高亮
  2103. .custom-tree-node:hover {
  2104. //color: #070a0c !important;
  2105. }
  2106. .el-icon-folder-opened,
  2107. .el-icon-folder,
  2108. .el-icon-document,
  2109. .el-icon-tickets {
  2110. display: flex;
  2111. align-items: center;
  2112. }
  2113. .el-icon-document,
  2114. .el-icon-folder-opened {
  2115. //color: #0e85fa;
  2116. }
  2117. //高亮字体颜色
  2118. .el-tree--highlight-current,
  2119. .el-tree-node.is-current > .el-tree-node__content {
  2120. color: #f8f8f8 !important;
  2121. background-color: #72b9ff !important; // 设置选中背景颜色
  2122. border-radius: 3px;
  2123. }
  2124. .el-tree-node__content:hover {
  2125. color: #f8f8f8 !important;
  2126. background-color: #b7d6f8 !important; // 设置选中背景颜色
  2127. border-radius: 3px;
  2128. }
  2129. }
  2130. ::v-deep .ele-table-tool-default {
  2131. display: none;
  2132. }
  2133. ::v-deep .ele-split-panel-body {
  2134. .ele-split-panel-side {
  2135. border-bottom: 1px solid #e8e8e8;
  2136. }
  2137. }
  2138. ::v-deep .ele-split-panel-side {
  2139. // border-bottom: 2px solid #e6e8ea;
  2140. height: 100%;
  2141. .tab-box_1 {
  2142. height: 100%;
  2143. .el-tabs__item {
  2144. background: rgba(246, 246, 247, 0.8);
  2145. border-bottom: 1px solid #e6e8ea;
  2146. }
  2147. .is-active.el-tabs__item {
  2148. background: #ffffff;
  2149. border-bottom: none;
  2150. }
  2151. .el-table {
  2152. height: calc(100% - 1px);
  2153. }
  2154. }
  2155. }
  2156. ::v-deep .tab-box_2 {
  2157. height: 100%;
  2158. overflow: auto;
  2159. display: flex;
  2160. flex-direction: column;
  2161. .el-tabs__content {
  2162. flex: 1;
  2163. .el-tab-pane {
  2164. height: 100%;
  2165. }
  2166. }
  2167. }
  2168. .current_button {
  2169. background: #096cd7;
  2170. border-color: #096cd7;
  2171. color: #ffffff;
  2172. }
  2173. ::v-deep .vue-contextmenu-listWrapper {
  2174. display: block;
  2175. background: #fff !important;
  2176. padding: 4px 0 !important;
  2177. border: 1px solid #dadada;
  2178. border-radius: 7px !important;
  2179. color: #606266;
  2180. .context-menu-list:hover {
  2181. background: rgba(156, 156, 156, 0.2) !important;
  2182. //color: #FFFFFF !important;
  2183. }
  2184. .context-menu-list {
  2185. background: #fff !important;
  2186. width: 100%;
  2187. height: 25px;
  2188. div {
  2189. display: flex;
  2190. flex-direction: row;
  2191. align-items: center;
  2192. justify-content: flex-start;
  2193. min-width: 120px;
  2194. width: 100%;
  2195. height: 100%;
  2196. i {
  2197. margin-left: 15px;
  2198. }
  2199. span {
  2200. margin: 0 !important;
  2201. margin-left: 25px !important;
  2202. }
  2203. }
  2204. }
  2205. }
  2206. ::v-deep tr[class^='el-table__row--level'] > td:nth-child(2) > .cell {
  2207. margin-left: 24px;
  2208. }
  2209. ::v-deep .el-table__header-wrapper .el-table__cell {
  2210. .cell {
  2211. text-align: center;
  2212. }
  2213. }
  2214. @for $i from 1 to 10 {
  2215. ::v-deep .el-table__row--level-#{$i} > td:nth-child(2) > .cell {
  2216. margin-left: #{$i * 4 +10}px;
  2217. display: flex;
  2218. flex-direction: row;
  2219. align-items: center;
  2220. }
  2221. }
  2222. .dot {
  2223. border-radius: 50%;
  2224. -webkit-background-clip: text;
  2225. color: #0e85fa;
  2226. display: inline-block;
  2227. width: 5px;
  2228. height: 5px;
  2229. margin-right: 2px;
  2230. text-align: center;
  2231. background: #0e85fa;
  2232. }
  2233. </style>