cpm-project.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. <template>
  2. <a-layout :class="$style.page">
  3. <a-layout-header :class="$style.header">
  4. <div :class="$style.headerTitle" :title="projectName"
  5. >{{ projectName }}
  6. <!-- <a-button
  7. v-if="moduleflag"
  8. type="link"
  9. size="small"
  10. :title="'关闭'"
  11. :class="$style.optbutton"
  12. @click="fndeal"
  13. > -->
  14. <!-- <img src="./gb.png" alt="" style="width: 15px;margin-top: -5px;" /> -->
  15. <!-- </a-button> -->
  16. </div>
  17. <a-menu
  18. v-if="loadShow"
  19. mode="horizontal"
  20. :default-selected-keys="defaultselectedkey"
  21. :style="{
  22. lineHeight: '48px',
  23. background: 'transparent',
  24. color: '#FFFFFF',
  25. }"
  26. @click="menuClick"
  27. >
  28. <a-menu-item key="1"> 项目作业</a-menu-item>
  29. <a-menu-item key="2"> 项目成员</a-menu-item>
  30. <a-menu-item v-if="showSubProject" key="3"> 项目分组</a-menu-item>
  31. </a-menu>
  32. <!-- <div>
  33. <a-icon type="close" :class="$style.closeBtn" @click="close"></a-icon>
  34. </div> -->
  35. </a-layout-header>
  36. <a-layout v-if="!iframeTag" style="padding:20px;background: #fff;" class="sd-has-table">
  37. <router-view></router-view>
  38. </a-layout>
  39. <a-layout v-if="iframeTag" style="padding:20px 20px 20px 0">
  40. <a-layout-sider
  41. theme="light"
  42. width="200"
  43. :class="[
  44. fold ? $style.leftSiderHidden : null,
  45. $style.leftSider,
  46. { [$style.leftOver]: !fold },
  47. ]"
  48. style="padding:0;background: #fff;"
  49. >
  50. <div :class="$style.siderContent">
  51. <div :class="$style.siderTitleDivFirst">
  52. <div :class="$style.siderTitle">
  53. <a-icon type="file-done" style="color:#7c7c7c" />
  54. 准备阶段
  55. </div>
  56. </div>
  57. <a-spin :spinning="spinning">
  58. <a-timeline :class="[spinning ? $style.timeline : '']">
  59. <div
  60. v-for="node in preparaNodes"
  61. :key="node.id"
  62. :class="[$style.siderUlDiv, { checked: checkedId === node.nodePeriod }]"
  63. @click="setChecked(node.nodePeriod, node.nodeUrl, node, 1)"
  64. >
  65. <a-timeline-item :class="$style.siderLi">{{ node.nodeName }}</a-timeline-item>
  66. </div>
  67. </a-timeline>
  68. </a-spin>
  69. </div>
  70. <div :class="$style.siderContent">
  71. <div :class="$style.siderTitleDiv">
  72. <div :class="$style.siderTitle">
  73. <a-icon type="profile" style="color:#7c7c7c" />
  74. 实施阶段
  75. <a-icon
  76. v-show="projectStage === 1 && showChangeStatus"
  77. type="swap"
  78. :class="$style.changeStatus"
  79. @click="changeStatus('effect')"
  80. />
  81. </div>
  82. </div>
  83. <a-spin :spinning="spinning">
  84. <a-timeline :class="[spinning ? $style.timeline : '']">
  85. <div
  86. v-for="node in effectNodes"
  87. :key="node.id"
  88. :class="[$style.siderUlDiv, { checked: checkedId === node.nodePeriod }]"
  89. @click="setChecked(node.nodePeriod, node.nodeUrl, node, 2)"
  90. >
  91. <a-timeline-item :class="$style.siderLi">{{ node.nodeName }}</a-timeline-item>
  92. </div>
  93. </a-timeline>
  94. </a-spin>
  95. </div>
  96. <div :class="$style.siderContent">
  97. <div :class="$style.siderTitleDiv">
  98. <div :class="$style.siderTitle">
  99. <a-icon type="file-text" style="color:#7c7c7c" />
  100. 报告阶段
  101. <a-icon
  102. v-show="projectStage === 2 && showChangeStatus"
  103. type="swap"
  104. :class="$style.changeStatus"
  105. @click="changeStatus('report')"
  106. />
  107. </div>
  108. </div>
  109. <a-spin :spinning="spinning">
  110. <a-timeline>
  111. <div
  112. v-for="node in reportNodes"
  113. :key="node.id"
  114. :class="[$style.siderUlDiv, { checked: checkedId === node.nodePeriod }]"
  115. @click="setChecked(node.nodePeriod, node.nodeUrl, node, 3)"
  116. >
  117. <a-timeline-item :class="$style.siderLi">{{ node.nodeName }}</a-timeline-item>
  118. </div>
  119. </a-timeline>
  120. </a-spin>
  121. </div>
  122. </a-layout-sider>
  123. <a-layout-sider width="20" style="background: #f0f2f5">
  124. <a-button type="primary" :class="$style.fold" @click="foldClick">
  125. <a-icon :type="fold ? 'right' : 'left'" />
  126. </a-button>
  127. </a-layout-sider>
  128. <a-layout :class="['sd-has-table', $style.xmCpmProject]">
  129. <!-- <iframe ref="rightfrm" :class="$style.rightfrm" frameborder="0"></iframe> -->
  130. <router-view
  131. v-if="ifRouterView"
  132. name="rightfrm"
  133. :module-id="moduleId"
  134. :form-list-id="formListId"
  135. :custom-values="customValues"
  136. :filter="Expressions"
  137. ></router-view>
  138. </a-layout>
  139. </a-layout>
  140. </a-layout>
  141. </template>
  142. <script>
  143. import { getUserInfo } from '@/common/store-mixin'
  144. import CpmService from '../cpm-service'
  145. import components from './_import-components/cpm-project-import'
  146. export default {
  147. name: 'CpmProject',
  148. metaInfo: {
  149. title: '合规项目',
  150. },
  151. components: {
  152. ...components,
  153. },
  154. mixins: [],
  155. provide() {
  156. return {
  157. reload: this.reload,
  158. }
  159. },
  160. data() {
  161. return {
  162. ifRouterView: true,
  163. menuId: '',
  164. defaultselectedkey: ['1'],
  165. fold: false,
  166. spinning: true, // 左侧节点加载状态
  167. iframeTag: true,
  168. projectId: '', // 项目Id
  169. groupId: '', // 分组Id
  170. projectStatus: '',
  171. checkedId: '', // 默认选中节点id
  172. preparaNodes: [
  173. {
  174. id: 1,
  175. nodePeriod: 'cpm-check-plan',
  176. nodeUrl: 'moduleId=267018022657347584&formListId=267018023269715968',
  177. nodeName: '合规检查方案',
  178. moduleId: '267018022657347584',
  179. formListId: '267018023269715968',
  180. },
  181. {
  182. id: 2,
  183. nodePeriod: 'cpm-check-notice',
  184. nodeUrl: 'moduleId=267018517979484160&formListId=267018518503772160',
  185. nodeName: '合规检查通知',
  186. moduleId: '267018517979484160',
  187. formListId: '267018518503772160',
  188. },
  189. ], // 准备极端
  190. effectNodes: [
  191. {
  192. id: 1,
  193. nodePeriod: 'cpm-check-self',
  194. nodeUrl: 'moduleId=261598158822875136&formListId=261598159410077696',
  195. nodeName: '合规自查',
  196. moduleId: '261598158822875136',
  197. formListId: '261598159410077696',
  198. },
  199. {
  200. id: 2,
  201. nodePeriod: 'cpm-work-papre',
  202. nodeUrl: 'moduleId=260200672874090496&formListId=260200678972608512',
  203. nodeName: '工作底稿',
  204. moduleId: '260200672874090496',
  205. formListId: '260200678972608512',
  206. },
  207. {
  208. id: 3,
  209. nodePeriod: 'cpm-confirm-list',
  210. nodeUrl: 'moduleId=272824893662429184&formListId=273908685835730944',
  211. nodeName: '问题清单确认',
  212. moduleId: '272824893662429184',
  213. formListId: '273908685835730944',
  214. },
  215. ], // 实施阶段
  216. reportNodes: [
  217. {
  218. id: 1,
  219. nodePeriod: 'cpm-work-report',
  220. nodeUrl: 'moduleId=269255411016146944&formListId=269255416636514304',
  221. nodeName: '报告管理',
  222. moduleId: '269255411016146944',
  223. formListId: '269255416636514304',
  224. },
  225. ], // 报告
  226. projectStage: 1, // 项目阶段1准备2实施3报告
  227. projectName: '', // 项目名称,
  228. currentUserType: [], // 当前登录人所在项目角色
  229. loadShow: true,
  230. showChangeStatus: false, // 切换阶段按钮显示
  231. type: '',
  232. moduleflag: false,
  233. todoId: '',
  234. moduleId: '',
  235. formListId: '',
  236. customValues: null,
  237. Expressions: [],
  238. showSubProject: false, // 是否显示项目分组
  239. }
  240. },
  241. created() {
  242. const projectId = this.$route.query.projectId
  243. this.projectId = projectId
  244. const groupId = this.$route.query.groupId
  245. this.groupId = groupId
  246. this.moduleId = this.$route.query.moduleId
  247. this.formListId = this.$route.query.formListId
  248. this.initData(this.projectId)
  249. if (
  250. this.$route.path.indexOf('cpm-check-user') > -1 ||
  251. this.$route.path.indexOf('cpm-check-group') > -1
  252. ) {
  253. if (this.$route.path.indexOf('cpm-check-user') > -1) {
  254. this.defaultselectedkey = ['2']
  255. this.menuId = '2'
  256. } else if (this.$route.path.indexOf('cpm-check-group') > -1) {
  257. this.defaultselectedkey = ['3']
  258. this.menuId = '3'
  259. }
  260. }
  261. if (this.groupId !== '') {
  262. this.customValues = { sdCustomField1: this.projectId, sdCustomField2: this.groupId }
  263. } else {
  264. this.customValues = { sdCustomField1: this.projectId, sdCustomField2: null }
  265. }
  266. },
  267. mounted() {
  268. this.spinning = !this.spinning
  269. var arr = []
  270. arr = arr.concat(this.preparaNodes)
  271. arr = arr.concat(this.effectNodes)
  272. arr = arr.concat(this.reportNodes)
  273. arr.forEach((i) => {
  274. if (this.$route.fullPath.indexOf(i.nodeUrl) > -1) {
  275. this.checkedId = i.nodePeriod
  276. }
  277. })
  278. },
  279. destroyed() {
  280. window.removeEventListener('hasLeaderAuthority', this.hasLeaderAuthority)
  281. },
  282. methods: {
  283. // 初始化项目信息
  284. initData(projectId) {
  285. if (projectId) {
  286. // 获取项目信息
  287. CpmService.getProjectData(projectId).then((res) => {
  288. this.projectName = res.data[0].title
  289. // 判断是否显示项目分组
  290. const userId = res.data[0].submitterAccounts.split(',')
  291. const userInfo = getUserInfo()
  292. if (this.groupId === '1' && userId.includes(userInfo.account)) {
  293. this.showSubProject = true
  294. } else {
  295. this.showSubProject = false
  296. }
  297. })
  298. }
  299. },
  300. reload() {
  301. this.ifRouterView = false
  302. this.$nextTick(() => {
  303. this.ifRouterView = true
  304. })
  305. },
  306. // // 隐藏左侧节点
  307. foldClick() {
  308. this.fold = !this.fold
  309. },
  310. // // 是否拥有项目组长和项目副组长的权限
  311. // hasLeaderAuthority() {
  312. // if (this.currentUserType.indexOf('01') > -1 || this.currentUserType.indexOf('05') > -1) {
  313. // return true
  314. // }
  315. // return false
  316. // },
  317. setChecked(val, url, node, stage) {
  318. // 如果点击的阶段大于当前阶段,则不能点击
  319. this.projectId = this.$route.query.projectId
  320. this.groupId = this.$route.query.groupId
  321. this.moduleId = node.moduleId
  322. this.formListId = node.formListId
  323. url = url + '&projectId=' + this.projectId + '&groupId=' + this.groupId
  324. this.checkedId = val
  325. // if (
  326. // node.nodeName === '工作底稿' ||
  327. // node.nodeName === '合规自查' ||
  328. // node.nodeName === '问题清单确认' ||
  329. // node.nodeName === '报告管理'
  330. // ) {
  331. if (this.groupId !== '') {
  332. this.customValues = { sdCustomField1: this.projectId, sdCustomField2: this.groupId }
  333. this.Expressions = []
  334. } else {
  335. this.customValues = { sdCustomField1: this.projectId, sdCustomField2: null }
  336. this.Expressions = []
  337. }
  338. // } else {
  339. // this.customValues = { sdCustomField1: this.projectId }
  340. // this.Expressions = []
  341. // }
  342. this.$router.push('/cpm-project/' + val + '?' + url)
  343. this.reload()
  344. },
  345. // close() {
  346. // crossWindowWatcher.notifyChange(true)
  347. // window.close()
  348. // },
  349. menuClick(val) {
  350. this.menuId = val.key
  351. if (val.key === '1') {
  352. // 评价作业
  353. this.iframeTag = true
  354. setTimeout(() => {
  355. // 调整左侧节点选中状态
  356. this.checkedId = this.preparaNodes[0].nodePeriod
  357. // 修改跳转路由
  358. this.$router.push(
  359. '/cpm-project/' +
  360. this.preparaNodes[0].nodePeriod +
  361. '?' +
  362. this.preparaNodes[0].nodeUrl +
  363. '&projectId=' +
  364. this.projectId +
  365. '&groupId=' +
  366. this.groupId
  367. )
  368. }, 0)
  369. }
  370. if (val.key === '2') {
  371. // 成员
  372. this.iframeTag = false
  373. setTimeout(() => {
  374. // onl%3Acd78040cdda84c6b90b2c688d9bfbaa1
  375. // bdd32992af534987b2e6e4818972bb77
  376. this.$router.push(
  377. '/cpm-project/cpm-check-user?pageId=onl:cd78040cdda84c6b90b2c688d9bfbaa1&projectId=' +
  378. this.projectId +
  379. '&groupId=' +
  380. this.groupId // 新页面要打开的路由地址
  381. )
  382. }, 0)
  383. }
  384. if (val.key === '3') {
  385. // 分组
  386. this.iframeTag = false
  387. setTimeout(() => {
  388. this.$router.push(
  389. '/cpm-project/cpm-check-group?pageId=onl:cd78040cdda84c6b90b2c688d9bfbaa1&projectId=' +
  390. this.projectId +
  391. '&groupId=' +
  392. this.groupId // 新页面要打开的路由地址
  393. )
  394. }, 0)
  395. }
  396. },
  397. },
  398. }
  399. </script>
  400. <style module lang="scss">
  401. @use '@/common/design' as *;
  402. .fold {
  403. position: absolute;
  404. top: calc(50% - 30px);
  405. right: 5px;
  406. z-index: 2;
  407. width: 15px;
  408. height: 75px;
  409. padding: 0;
  410. border-radius: 0 10px 10px 0;
  411. }
  412. .audit-table {
  413. :global(.sd-readonly) {
  414. margin-bottom: 24px;
  415. }
  416. }
  417. .close-btn {
  418. font-size: 15px;
  419. color: #ffffff;
  420. position: absolute;
  421. right: 15px;
  422. top: 25px;
  423. cursor: pointer;
  424. }
  425. $link-icon-size: 22px;
  426. $line-height-theme: 66px;
  427. $theme-check: #fff;
  428. $icon-size: 15px;
  429. .page {
  430. // 表格样式
  431. :global(div.sd-has-table) {
  432. :global(.ant-table-wrapper) {
  433. margin-top: -8px;
  434. }
  435. :global(.ant-card-body) {
  436. padding: 20px;
  437. :global(.ant-table-wrapper) {
  438. margin-top: -8px;
  439. }
  440. }
  441. }
  442. :global(.sd-has-table) {
  443. :global(.ant-table-wrapper) {
  444. margin-top: -8px;
  445. }
  446. }
  447. height: 100%;
  448. .left-sider {
  449. overflow: hidden;
  450. white-space: nowrap;
  451. :global(.ant-layout-sider-children) {
  452. overflow: auto;
  453. }
  454. }
  455. .left-sider-hidden {
  456. flex: 0 0 0 !important;
  457. max-width: 0 !important;
  458. min-width: 0 !important;
  459. width: 0 !important;
  460. padding: 0px;
  461. background: rgb(255, 255, 255);
  462. :global(.ant-layout-sider-children) {
  463. overflow: hidden;
  464. }
  465. }
  466. .left-over {
  467. margin-left: 20px;
  468. }
  469. .trigger {
  470. display: inline-block;
  471. padding: 0 15px;
  472. vertical-align: top;
  473. cursor: pointer;
  474. transition: color 0.3s;
  475. &:hover {
  476. color: $text-color-inverse;
  477. }
  478. }
  479. aside {
  480. overflow: auto;
  481. }
  482. :global(.sd-frame-main) {
  483. height: 100%;
  484. padding: $padding-lg;
  485. overflow: auto;
  486. }
  487. :global(sd-readonly) {
  488. margin-bottom: 24px;
  489. }
  490. }
  491. .title {
  492. display: inline-block;
  493. margin-left: -35px;
  494. font-weight: 600;
  495. line-height: inherit;
  496. text-align: center;
  497. vertical-align: top;
  498. > i {
  499. // 固定大小的logo
  500. /* stylelint-disable-next-line */
  501. font-size: 20px;
  502. transform: scale(10);
  503. }
  504. }
  505. // 主内容区的Card白色背景要占满
  506. :global .sd-frame-main > .ant-card {
  507. min-height: 100%;
  508. }
  509. .header {
  510. background: linear-gradient(to right, #3f9bff, #0e7df6);
  511. height: 48px;
  512. line-height: 48px;
  513. padding: 0 20px 0 20px;
  514. :global .ant-menu {
  515. float: right;
  516. }
  517. :global(.ant-menu-item-selected) {
  518. color: #ffffff;
  519. background: #1366c1;
  520. border-bottom: 0 !important;
  521. top: 0;
  522. }
  523. :global(.ant-menu-item) {
  524. border-bottom: 2px solid #ffffff;
  525. border-bottom: 0 !important;
  526. top: 0;
  527. }
  528. :global(.ant-menu-item-active) {
  529. color: #ffffff !important;
  530. background: #1366c1 !important;
  531. border-bottom: 0 !important;
  532. top: 0;
  533. }
  534. .header-title {
  535. color: #ffffff;
  536. font-size: 25px;
  537. font-weight: 400;
  538. display: inline-block;
  539. width: 40%;
  540. overflow: hidden;
  541. text-overflow: ellipsis;
  542. white-space: nowrap;
  543. }
  544. }
  545. .header > div:last-child {
  546. width: calc(100% - 200px);
  547. }
  548. .links {
  549. display: flex;
  550. align-items: center;
  551. margin: 0 $link-icon-size / 2;
  552. li:global(.ant-menu-item) {
  553. padding: 0;
  554. }
  555. i:global(.anticon) {
  556. padding: 0 $link-icon-size / 2;
  557. margin: 0;
  558. font-size: $link-icon-size;
  559. line-height: $layout-header-height;
  560. vertical-align: middle;
  561. &:hover {
  562. // 悬浮的颜色,与主题无关
  563. /* stylelint-disable-next-line */
  564. background-color: rgba(0, 0, 0, 0.2);
  565. }
  566. }
  567. }
  568. .tools {
  569. display: flex;
  570. float: right;
  571. }
  572. .headerbadge {
  573. bottom: $line-height-theme / 6;
  574. left: -$link-icon-size / 2 - 5;
  575. }
  576. .sider-content {
  577. padding: 0 0;
  578. .sider-title {
  579. position: relative;
  580. margin-left: 23px;
  581. i {
  582. color: #1890ff;
  583. position: absolute;
  584. font-size: 18px;
  585. left: -27px;
  586. top: 3px;
  587. }
  588. font-weight: bold;
  589. }
  590. .sider-li {
  591. :global(.ant-timeline-item-content) {
  592. margin: 0 0 0 15px;
  593. }
  594. :global(.ant-timeline-item-head-blue) {
  595. color: #9f9f9f;
  596. border-color: #9f9f9f;
  597. background-color: #9f9f9f;
  598. top: 4px;
  599. left: 3px;
  600. width: 3px;
  601. height: 3px;
  602. }
  603. :global(.ant-timeline-item-tail) {
  604. height: calc(100% - -18px);
  605. border-left: 2px solid #f5f5f5;
  606. display: none;
  607. }
  608. }
  609. .sider-title-div-first {
  610. padding: 10px 0 10px 20px;
  611. margin-bottom: 10px;
  612. border-bottom: 2px solid #e8e8e8;
  613. }
  614. .sider-title-div {
  615. padding: 10px 0 10px 20px;
  616. margin-bottom: 10px;
  617. border-top: 2px solid #e8e8e8;
  618. border-bottom: 2px solid #e8e8e8;
  619. }
  620. ul {
  621. margin-left: 0;
  622. padding-bottom: 5px;
  623. }
  624. .sider-ul-div {
  625. padding: 13px 0px 0px 12px;
  626. width: 100%;
  627. margin: 3px auto;
  628. border-radius: 0px;
  629. cursor: pointer;
  630. :global(.ant-timeline-item) {
  631. padding: 0;
  632. margin-left: 3px;
  633. }
  634. }
  635. .node-readonly {
  636. cursor: normal;
  637. color: #b6b6b6;
  638. }
  639. :global(.checked) {
  640. background: linear-gradient(to right, #13c2c2, #2db7f5);
  641. color: #fff;
  642. :global(.ant-timeline-item-head-blue) {
  643. background-color: #ffffff;
  644. border-color: #ffffff !important;
  645. top: 4px;
  646. left: 3px;
  647. width: 3px;
  648. height: 3px;
  649. }
  650. }
  651. :global(.ant-timeline-item-last .ant-timeline-item-tail) {
  652. display: none;
  653. }
  654. .timeline {
  655. min-height: 150px;
  656. }
  657. }
  658. :global(.ant-tabs) {
  659. overflow-y: auto;
  660. }
  661. .rightfrm {
  662. height: 100%;
  663. width: 100%;
  664. }
  665. .change-status {
  666. margin-left: 150px;
  667. font-size: 20px !important;
  668. color: #28baeb !important;
  669. cursor: pointer;
  670. }
  671. .xmCpmProject {
  672. }
  673. </style>