index.vue 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. <template>
  2. <el-drawer
  3. :modal="false"
  4. size="100%"
  5. :class="drawerBox"
  6. destroy-on-close
  7. :visible.sync="drawer"
  8. :before-close="handleClose"
  9. @click.stop
  10. @open="setBoxShadow('')"
  11. @opened="setBoxShadow"
  12. @close="setBoxShadow('')"
  13. >
  14. <template slot="title">
  15. <div v-if="title" @click.stop>{{ title }}<span class="sub-title">{{ subTitle }}</span></div>
  16. </template>
  17. <!-- 时间线 -->
  18. <div
  19. v-if="openDrawer && isTimeLine(1)"
  20. class="qz-drawer-padding qz-drawer-header"
  21. :style="{paddingTop: !isTimeLine(2) ? '30px':'20px'}"
  22. @click.stop
  23. >
  24. <div ref="timeline1" class="qz-drawer-scll">
  25. <timeline
  26. :num="timelineData.firstActive"
  27. bgmargin
  28. :data="timelineData.first"
  29. @update="(params) => timeLineClick(params, 1)"
  30. />
  31. </div>
  32. <div v-if="isTimeLine(2)" ref="timeline2" class="qz-drawer-scll">
  33. <timeline
  34. :num="timelineData.secondActive"
  35. :data="timelineData.second"
  36. :bgmargin="true"
  37. @update="(params)=>timeLineClick(params, 2)"
  38. />
  39. </div>
  40. </div>
  41. <!-- 表格 -->
  42. <dmTable
  43. v-if="openDrawer"
  44. v-loading="loading"
  45. :table-list="tableList"
  46. :total="tableList"
  47. :column="column"
  48. :table-height="tableHeight"
  49. @click.stop
  50. @change="dmTableChange"
  51. >
  52. <template #bugStatusNameSlot="{scope}">
  53. <div @click.stop="print(scope)">自定义</div>
  54. </template>
  55. <!-- 报告名称 -->
  56. <template #returnReasonSlot="{scope}">
  57. <div v-if="scope.row.reportName" @click.stop>
  58. <div class="drawer-name" @click.stop="jumper(scope.row,'提测')">{{ scope.row.reportName }}</div>
  59. <div v-if="scope.row.returnReason" style="color: red">打开报告:{{ scope.row.returnReason }}</div>
  60. </div>
  61. </template>
  62. <!-- 报告人 -->
  63. <template #creatorObjectSlot="{scope}">
  64. <div v-if="scope && scope.row && scope.row.creatorObject" @click.stop>{{ scope.row.creatorObject.name }}</div>
  65. </template>
  66. <!-- 质量:线上问题_改进方案 -->
  67. <template #starFlowerDoneSlot="{scope}">
  68. <div @click.stop>
  69. <div>{{ scope.row.done + scope.row.undone }}项任务</div>
  70. <div
  71. v-if="scope.row.done === scope.row.done + scope.row.undone"
  72. class="antdv3-tag antdv3-tag-green"
  73. >
  74. 已完成:{{ scope.row.done }}项
  75. </div>
  76. <div v-else class="antdv3-tag antdv3-tag-orange">已完成:{{ scope.row.done }}项</div>
  77. </div>
  78. </template>
  79. <!-- 质量:线上问题_改进方案 -->
  80. <template #gmtCreateSlot="{scope}">
  81. <div @click.stop>
  82. <div>{{ rTime(scope.row.gmtCreate) }}</div>
  83. </div>
  84. </template>
  85. </dmTable>
  86. <!-- 下拉 -->
  87. <div class="qz-footer-laout" @click.stop>
  88. <div style="line-height: 60px;">
  89. <!-- <el-button type="primary" size="mini" @click="exportTable">导 出</el-button>-->
  90. </div>
  91. <el-pagination
  92. :current-page.sync="paging.curIndex"
  93. :page-size="paging.pageSize"
  94. :pager-count="5"
  95. layout="total, sizes, prev, pager, next, jumper"
  96. :page-sizes="[10, 15, 20, 30]"
  97. :total="paging.pageTotal"
  98. @size-change="handleSizeChange"
  99. @current-change="handleCurrentChange"
  100. />
  101. </div>
  102. </el-drawer>
  103. </template>
  104. <script>
  105. // import { mapGetters } from 'vuex'
  106. import { bugList } from '@/api/defectManage'
  107. import _ from 'lodash'
  108. import { getReportList } from '@/api/reportTemplate'
  109. import dmTable from './components/table.vue'
  110. import timeline from './components/timeline'
  111. import { columns, timelineList } from './drawerModalData'
  112. import { EncryptId } from '@/utils/crypto-js'
  113. import Clickoutside from 'element-ui/src/utils/clickoutside'
  114. import { requirementQueryRequirementInfoList, taskList } from '@/api/projectIndex'
  115. import {
  116. // 质量
  117. getRequireAvgData, // 需求平均交付周期
  118. getTaskData, // 任务平均交付周期
  119. getRequirePeopleData, // 平均需求使用人力
  120. getDelayLaunchData, // 延期提测率
  121. getDelayReleaseData, // 延期准出率
  122. bugRepairData, // 缺陷24小时修复率
  123. bugRepair2Data, // 缺陷平均修复时长
  124. getStarFlowerList, // 线上问题:半浮层 列表
  125. getProjectList // 需求任务项目列表: 半浮层
  126. } from '@/api/dataMarket'
  127. export default {
  128. name: 'DrawerModal',
  129. components: {
  130. dmTable, timeline
  131. },
  132. directives: { Clickoutside },
  133. props: {
  134. // title: {
  135. // type: String,
  136. // required: false,
  137. // default: ''
  138. // },
  139. // subTitle: {
  140. // type: String,
  141. // required: false,
  142. // default: ''
  143. // },
  144. openDrawer: {
  145. type: Boolean,
  146. required: false,
  147. default: false
  148. },
  149. drawerData: {
  150. type: Object,
  151. required: false,
  152. default: () => {}
  153. }
  154. },
  155. data() {
  156. return {
  157. drawer: false,
  158. loading: false,
  159. title: '',
  160. headerTitle: '',
  161. // timelineData,
  162. tableList: [],
  163. tableListOld: [],
  164. tableHeight: 'auto',
  165. column: [],
  166. ids: [],
  167. label: '',
  168. activeLabel: '',
  169. drawerBox: '',
  170. subTitle: '',
  171. sourceData: null,
  172. timelineData: {
  173. first: [],
  174. firstActive: 0,
  175. second: [],
  176. secondActive: 0
  177. },
  178. paging: {
  179. curIndex: 1,
  180. pageTotal: 0,
  181. pageSize: 10
  182. }
  183. }
  184. },
  185. watch: {
  186. drawerData() {
  187. this.init()
  188. },
  189. openDrawer(value) {
  190. this.drawer = value
  191. // if (value) {
  192. // this.init()
  193. // }
  194. }
  195. },
  196. created() {
  197. this.drawer = false
  198. },
  199. mounted() {
  200. this.drawer = false
  201. },
  202. methods: {
  203. print(slotProp) {
  204. console.log(slotProp)
  205. },
  206. init() {
  207. this.headerTitle = this.drawerData.headerTitle
  208. this.title = this.headerTitle.search(/质量|效率/) > -1 ? this.drawerData.label || '' : this.drawerData.activeLabel
  209. if (this.headerTitle && this.title) {
  210. // console.log(this.drawerData)
  211. this.pagingInit()
  212. this.setPageSize()
  213. this.column = []
  214. this.tableList = []
  215. this.drawer = this.openDrawer
  216. this.setTitle()
  217. this.setIds() // 设置ids
  218. this.setTimeLineData()
  219. this.setTitleHeight()
  220. this.setTimeLine()
  221. this.setColumn()
  222. this.setTableList()
  223. } else {
  224. this.handleClose()
  225. }
  226. },
  227. // 设置页数
  228. setPageSize() {
  229. const pageSize = window.localStorage.getItem('pageSize') || 10
  230. // this.paging.pageSize = pageSize
  231. const paging = _.cloneDeep(this.paging)
  232. paging.pageSize = Number.parseInt(pageSize)
  233. this.paging = _.cloneDeep(paging)
  234. },
  235. // 设置标题
  236. setTitle() {
  237. // this.title = this.headerTitle.search(/质量|效率/) > -1 ? this.drawerData.label : this.drawerData.activeLabel
  238. if (this.headerTitle === '质量') {
  239. if (this.drawerData.label === '提测打回率') {
  240. this.title = '提测报告'
  241. }
  242. if (this.drawerData.label === '准出不通过率') {
  243. this.title = '准出记录'
  244. }
  245. }
  246. if (this.headerTitle === '效率') {
  247. this.activeLabel = this.drawerData.activeLabel
  248. if (this.drawerData.label === '需求平均交付周期') {
  249. this.title = '需求周期'
  250. }
  251. if (this.drawerData.label === '任务平均交付周期') {
  252. this.title = '任务周期'
  253. }
  254. if (this.drawerData.label === '平均需求使用人力') {
  255. this.title = '需求人力'
  256. }
  257. if (this.drawerData.label === '缺陷平均修复时长') {
  258. this.title = '缺陷修复时长'
  259. }
  260. }
  261. this.sourceData = this.drawerData.list
  262. if (this.headerTitle === '效率' && this.title && this.title.search(/延期准出率|延期提测率/) < 0) {
  263. this.sourceData = [
  264. {
  265. label: this.drawerData.label === '缺陷24小时修复率' ? '全部' : this.drawerData.label,
  266. IdList: this.drawerData.idList
  267. },
  268. ...this.drawerData.subCountList
  269. ]
  270. }
  271. },
  272. // 处理日期格式:JS - 2020-01-01T00:00:00.000000Z 日期格式转换
  273. rTime(date) {
  274. if (!date) return ''
  275. var json_date = new Date(date).toJSON()
  276. return new Date(new Date(json_date) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '')
  277. },
  278. // 设置ids
  279. setIds() {
  280. if (this.headerTitle === '质量') {
  281. this.ids = this.drawerData.IdList.map(e => e)
  282. }
  283. if (this.headerTitle === '吞吐量') {
  284. this.drawerData.list.forEach(elm => {
  285. if (elm.label === this.drawerData.activeLabel && elm.idList) {
  286. this.ids = elm.idList.map(e => e)
  287. }
  288. })
  289. }
  290. if (this.headerTitle === '效率') {
  291. this.ids = this.drawerData.idList.map(e => e) // 提测报告
  292. }
  293. },
  294. // 设置时间轴
  295. setTimeLineData() {
  296. let { firstActive, first, secondActive, second } = this.timelineData
  297. if (this.title.search(/新增问题|新增缺陷|reopen|提测报告|准出记录/) < 0) {
  298. if (this.headerTitle === '吞吐量') {
  299. secondActive = 0
  300. firstActive = 0
  301. first = []
  302. this.sourceData.forEach((elm, index) => {
  303. if (this.title.indexOf(elm.label) > -1) {
  304. firstActive = index
  305. }
  306. first.push(elm.label)
  307. })
  308. if (this.title.search(/需求/) > -1) {
  309. first = timelineList.requirementData.map(e => e)
  310. }
  311. }
  312. if (this.headerTitle === '效率') {
  313. secondActive = 0
  314. firstActive = 0
  315. first = []
  316. second = []
  317. if (this.title === '缺陷24小时修复率') {
  318. first = [...timelineList.time]
  319. }
  320. if (this.title === '延期提测率') {
  321. first = [...timelineList.delayLaunchData]
  322. }
  323. if (this.title === '延期准出率') {
  324. first = [...timelineList.delayLaunchData2]
  325. }
  326. if (this.title.search(/延期提测率|延期准出率/) < 0) {
  327. this.sourceData.forEach((elm, index) => {
  328. let label = `${elm.label}`
  329. if (this.activeLabel === label) {
  330. if (this.title === '缺陷24小时修复率') {
  331. secondActive = index
  332. } else {
  333. firstActive = index
  334. }
  335. }
  336. if (this.title === '缺陷24小时修复率') {
  337. second.push(label)
  338. } else {
  339. if (index === 0) {
  340. if (label === '需求平均交付周期') {
  341. label = '需求交付周期'
  342. }
  343. if (label === '任务平均交付周期') {
  344. label = '任务交付周期'
  345. }
  346. if (label === '平均需求使用人力') {
  347. label = '需求使用人力'
  348. }
  349. if (this.drawerData.label === '缺陷平均修复时长') {
  350. label = '全部'
  351. }
  352. }
  353. first.push(label)
  354. }
  355. })
  356. }
  357. }
  358. this.timelineData = { firstActive, first, secondActive, second }
  359. }
  360. },
  361. handleClose() {
  362. this.drawer = false
  363. this.$emit('update:openDrawer', this.drawer)
  364. },
  365. handleSizeChange(value) {
  366. this.paging.pageSize = value
  367. const paging = _.cloneDeep(this.paging)
  368. paging.pageSize = value
  369. this.paging = _.cloneDeep(paging)
  370. window.localStorage.setItem('pageSize', value)
  371. if (this.headerTitle === '效率' && this.title !== '需求人力') {
  372. this.tableListPagination()
  373. } else {
  374. this.setTableList()
  375. }
  376. },
  377. handleCurrentChange(value) {
  378. // this.paging.curIndex = value
  379. const paging = _.cloneDeep(this.paging)
  380. paging.curIndex = value
  381. this.paging = _.cloneDeep(paging)
  382. // console.log(this.title)
  383. if (this.headerTitle === '效率' && this.title !== '需求人力') {
  384. this.tableListPagination()
  385. } else {
  386. this.setTableList()
  387. }
  388. },
  389. // 导出
  390. exportTable() {
  391. },
  392. // 设置表格头
  393. setColumn() {
  394. if (this.title.search(/新增缺陷|reopen|缺陷24小时修复率/) > -1) {
  395. this.column = columns.bugColumn.map(e => e)
  396. }
  397. if (this.title.search(/新增问题/) > -1) {
  398. this.column = columns.newQuestionColumns.map(e => e)
  399. }
  400. if (this.title.search(/提测报告|准出记录/) > -1) {
  401. this.column = columns.deliverTestReportIdListColumns.map(e => e)
  402. }
  403. if (this.headerTitle === '吞吐量') {
  404. if (this.title.search(/需求/) > -1) {
  405. this.column = columns.requirementListColumns.map(e => e)
  406. }
  407. if (this.title.search(/任务/) > -1) {
  408. this.column = columns.taskListColumns.map(e => e)
  409. }
  410. if (this.title.search(/项目/) > -1) {
  411. this.column = columns.projectListColumns.map(e => e)
  412. }
  413. }
  414. if (this.headerTitle === '效率') {
  415. let columnsKey = 'requirementColumns'
  416. if (this.title === '任务周期') {
  417. columnsKey = 'taskColumns'
  418. }
  419. if (this.title === '需求人力') {
  420. columnsKey = 'requirementPeopleColumns'
  421. }
  422. if (this.title === '延期提测率') {
  423. columnsKey = 'delayLaunchDataColumns'
  424. }
  425. if (this.title === '延期准出率') {
  426. columnsKey = 'delayReleaseData2Columns'
  427. }
  428. if (this.title.search(/缺陷修复时长|缺陷24小时修复率/) > -1) {
  429. columnsKey = 'bugRepairDataColumns'
  430. }
  431. const columnsTipsKey = `${columnsKey}Tips`
  432. this.column = columns.efficiency[columnsKey].map((elm, index) => {
  433. if (index === 2 && this.title.search(/任务周期|需求人力|需求周期/) > -1) {
  434. return columns.efficiency[columnsTipsKey][this.timelineData.firstActive || 0]
  435. }
  436. return elm
  437. })
  438. }
  439. },
  440. // 时间轴点击事件
  441. timeLineClick({ value, name }, index) {
  442. this.pagingInit()
  443. this.ids = []
  444. if (index === 1) {
  445. if (this.headerTitle === '吞吐量') {
  446. this.timelineData.firstActive = value || 0
  447. if (this.sourceData[value || 0] && this.sourceData[value || 0].idList) {
  448. this.ids = this.sourceData[value || 0].idList
  449. this.title = name
  450. }
  451. }
  452. if (this.headerTitle === '效率') {
  453. this.timelineData.firstActive = value || 0
  454. if (this.title.search(/延期准出率|延期提测率/) > -1) {
  455. // this.ids = this.sourceData[value].IdList
  456. } else {
  457. this.timelineData.firstActive = value || 0
  458. this.ids = this.sourceData[value || 0].IdList
  459. }
  460. this.setColumn()
  461. }
  462. this.setTableList()
  463. }
  464. if (index === 2) {
  465. this.timelineData.secondActive = value || 0
  466. this.ids = this.sourceData[value || 0].IdList
  467. this.setTableList()
  468. }
  469. },
  470. // 设置列表数据
  471. setTableList() {
  472. // console.log(439)
  473. this.tableList = []
  474. if (this.headerTitle === '质量') {
  475. if (this.title.search(/新增缺陷|reopen/) > -1) {
  476. if (this.ids.length) {
  477. this.loading = true
  478. this.getBugStatisticData()
  479. }
  480. }
  481. if (this.title.search(/新增问题/) > -1) {
  482. if (this.ids.length) {
  483. this.loading = true
  484. this.setStarFlowerList()
  485. }
  486. }
  487. if (this.title.search(/提测报告|准出记录/) > -1) {
  488. if (this.ids.length) {
  489. this.loading = true
  490. this.setReportList()
  491. }
  492. }
  493. }
  494. if (this.headerTitle === '吞吐量') {
  495. if (this.title.search(/需求/) > -1) {
  496. if (this.ids.length) {
  497. this.loading = true
  498. this.getRequirementList()
  499. }
  500. }
  501. if (this.title.search(/任务/) > -1) {
  502. if (this.ids.length) {
  503. this.loading = true
  504. this.getTaskList()
  505. }
  506. }
  507. if (this.title.search(/项目/) > -1 && this.ids.length) {
  508. if (this.ids.length) {
  509. this.loading = true
  510. this.setProjectList()
  511. }
  512. }
  513. }
  514. if (this.headerTitle === '效率') {
  515. if (this.title === '需求周期') {
  516. if (this.sourceData[0].IdList.length) {
  517. this.loading = true
  518. this.setRequireAvgData()
  519. }
  520. }
  521. if (this.title === '任务周期') {
  522. this.loading = true
  523. this.setTaskData()
  524. if (this.sourceData[0].IdList.length) {
  525. this.loading = true
  526. this.setTaskData()
  527. }
  528. }
  529. if (this.title === '需求人力') {
  530. if (this.sourceData[0].IdList.length) {
  531. this.loading = true
  532. this.setRequirePeopleData()
  533. }
  534. }
  535. if (this.title === '缺陷修复时长') {
  536. if (this.sourceData[0].IdList.length) {
  537. this.loading = true
  538. this.setbugRepair2Data()
  539. }
  540. }
  541. if (this.title === '缺陷24小时修复率') {
  542. if (this.sourceData[0].IdList.length) {
  543. this.loading = true
  544. this.setbugRepairData()
  545. }
  546. }
  547. if (this.title === '延期提测率') {
  548. if (this.drawerData.idList.length) {
  549. this.loading = true
  550. this.setDelayLaunchData()
  551. }
  552. }
  553. if (this.title === '延期准出率') {
  554. if (this.drawerData.idList.length) {
  555. this.loading = true
  556. this.setDelayReleaseData()
  557. }
  558. }
  559. }
  560. },
  561. // 获取需求
  562. async getRequirementList() {
  563. const paging = this.paging
  564. // {"ids":[14952,15453,15988,16182,17445,17447,17735,18062,18064,18067,18134,18137,18138,18140],"curIndex":2,"pageSize":10}
  565. const res = await requirementQueryRequirementInfoList({
  566. ids: this.ids,
  567. curIndex: this.paging.curIndex,
  568. pageSize: this.paging.pageSize
  569. })
  570. if (res.code === 200) {
  571. this.tableList = res.data.list
  572. this.paging.pageTotal = res.data.total
  573. this.paging = { ...paging }
  574. this.loading = false
  575. }
  576. },
  577. // 获取任务
  578. async getTaskList() {
  579. const paging = this.paging
  580. // {"ids":[14952,15453,15988,16182,17445,17447,17735,18062,18064,18067,18134,18137,18138,18140],"curIndex":2,"pageSize":10}
  581. const res = await taskList({
  582. ids: this.ids,
  583. curIndex: this.paging.curIndex,
  584. pageSize: this.paging.pageSize
  585. })
  586. if (res.code === 200) {
  587. this.tableList = res.data
  588. this.paging.pageTotal = res.total
  589. this.paging = { ...paging }
  590. this.loading = false
  591. }
  592. },
  593. // getStarFlowerList, // 线上问题:半浮层 列表
  594. async setStarFlowerList() {
  595. if (!this.ids.length) {
  596. this.loading = false
  597. return
  598. }
  599. const paging = this.paging
  600. // {"ids":[14952,15453,15988,16182,17445,17447,17735,18062,18064,18067,18134,18137,18138,18140],"curIndex":2,"pageSize":10}
  601. const res = await getStarFlowerList({
  602. idList: this.ids,
  603. curIndex: this.paging.curIndex,
  604. pageSize: this.paging.pageSize
  605. })
  606. if (res.code === 200) {
  607. this.tableList = res.data.result
  608. this.paging.pageTotal = res.data.total
  609. this.paging = { ...paging }
  610. this.loading = false
  611. }
  612. },
  613. // getProjectList // 需求任务项目列表: 半浮层
  614. async setProjectList() {
  615. const paging = this.paging
  616. // {"ids":[14952,15453,15988,16182,17445,17447,17735,18062,18064,18067,18134,18137,18138,18140],"curIndex":2,"pageSize":10}
  617. const res = await getProjectList({
  618. idList: this.ids.length ? this.ids : [],
  619. curIndex: this.paging.curIndex,
  620. pageSize: this.paging.pageSize
  621. })
  622. if (res.code === 200) {
  623. // console.log(res)
  624. this.tableList = res.data.result
  625. paging.pageTotal = res.data.total
  626. this.paging = { ...paging }
  627. this.loading = false
  628. }
  629. },
  630. // 累计新增缺陷
  631. async getBugStatisticData() {
  632. const paging = this.paging
  633. // {"ids":[14952,15453,15988,16182,17445,17447,17735,18062,18064,18067,18134,18137,18138,18140],"curIndex":2,"pageSize":10}
  634. const res = await bugList({
  635. ids: this.ids,
  636. curIndex: this.paging.curIndex,
  637. pageSize: this.paging.pageSize
  638. })
  639. if (res.code === 200) {
  640. this.tableList = res.data
  641. this.paging.pageTotal = res.total
  642. this.paging = { ...paging }
  643. this.loading = false
  644. }
  645. },
  646. // 提测报告 deliverTestReportIdList 准出记录 releaseReportIdList
  647. async setReportList() {
  648. const key = this.title === '提测报告' ? 'deliverTestReportIdList' : 'releaseReportIdList'
  649. const paging = this.paging
  650. const params = {
  651. ...paging,
  652. [key]: this.ids
  653. }
  654. delete params.pageTotal
  655. const res = await getReportList(params)
  656. if (res.code === 200) {
  657. this.tableList = res.data
  658. paging.pageTotal = res.total
  659. this.paging = { ...paging }
  660. this.loading = false
  661. }
  662. },
  663. /* S 效率:半浮层数据接口 */
  664. // 需求平均交付周期
  665. async setRequireAvgData() {
  666. const paging = this.paging
  667. const params = {
  668. ...paging,
  669. title: this.timelineData.first[this.timelineData.firstActive],
  670. ids: this.sourceData[0].IdList
  671. }
  672. delete params.pageTotal
  673. const res = await getRequireAvgData(params)
  674. if (res.code === 200) {
  675. // this.tableList = res.data
  676. this.tableListOld = res.data.length && res.data.map(e => e)
  677. this.tableListPagination()
  678. paging.pageTotal = this.tableListOld.length
  679. this.paging = { ...paging }
  680. this.loading = false
  681. }
  682. },
  683. // 任务平均交付周期
  684. async setTaskData() {
  685. const paging = this.paging
  686. const params = {
  687. ...paging,
  688. title: this.timelineData.first[this.timelineData.firstActive],
  689. ids: this.sourceData[0].IdList
  690. }
  691. delete params.pageTotal
  692. const res = await getTaskData(params)
  693. if (res.code === 200) {
  694. // this.tableList = res.data
  695. this.tableListOld = res.data.length && res.data.map(e => e)
  696. this.tableListPagination()
  697. paging.pageTotal = this.tableListOld.length
  698. this.paging = { ...paging }
  699. this.loading = false
  700. }
  701. },
  702. // 平均需求使用人力
  703. async setRequirePeopleData() {
  704. const paging = this.paging
  705. const params = {
  706. ...paging,
  707. title: this.timelineData.first[this.timelineData.firstActive],
  708. ids: this.sourceData[0].IdList
  709. }
  710. delete params.pageTotal
  711. const res = await getRequirePeopleData(params)
  712. if (res.code === 200) {
  713. // console.log(res.data)
  714. this.tableList = res.data
  715. // this.tableListOld = res.data.length && res.data.map(e => e)
  716. // this.tableListPagination()
  717. paging.pageTotal = this.sourceData[0].IdList.length
  718. this.paging = { ...paging }
  719. this.loading = false
  720. }
  721. },
  722. // 缺陷平均修复时长
  723. async setbugRepair2Data() {
  724. const paging = this.paging
  725. const params = {
  726. ...paging,
  727. title: this.timelineData.first[this.timelineData.firstActive],
  728. ids: this.sourceData[0].IdList
  729. }
  730. delete params.pageTotal
  731. const res = await bugRepair2Data(params)
  732. if (res.code === 200) {
  733. // this.tableList = res.data
  734. this.tableListOld = res.data.length && res.data.map(e => e)
  735. this.tableListPagination()
  736. paging.pageTotal = this.tableListOld.length
  737. this.paging = { ...paging }
  738. this.loading = false
  739. }
  740. },
  741. // 缺陷24小时修复率
  742. async setbugRepairData() {
  743. const priorityList = [[0, 1, 2, 3], [0, 1], [2, 3]]
  744. const paging = this.paging
  745. const params = {
  746. // ...paging,
  747. title: this.timelineData.first[this.timelineData.firstActive],
  748. priorityList: priorityList[this.timelineData.secondActive],
  749. ids: this.sourceData[0].IdList
  750. }
  751. delete params.pageTotal
  752. const res = await bugRepairData(params)
  753. if (res.code === 200) {
  754. this.tableList = res.data
  755. this.tableListOld = res.data.length && this.tableList.map(e => e)
  756. paging.pageTotal = this.tableListOld.length
  757. this.paging = { ...paging }
  758. this.loading = false
  759. }
  760. },
  761. // getDelayLaunchData, // 延期提测率
  762. async setDelayLaunchData() {
  763. const paging = this.paging
  764. const params = {
  765. ...paging,
  766. title: this.timelineData.first[this.timelineData.firstActive],
  767. ids: this.drawerData.idList
  768. }
  769. delete params.pageTotal
  770. const res = await getDelayLaunchData(params)
  771. if (res.code === 200) {
  772. this.tableList = res.data
  773. this.tableListOld = res.data.length && res.data.map(e => e)
  774. this.tableListPagination()
  775. paging.pageTotal = this.tableListOld.length
  776. this.paging = { ...paging }
  777. this.loading = false
  778. }
  779. },
  780. // getDelayReleaseData, // 延期准出率
  781. async setDelayReleaseData() {
  782. const paging = this.paging
  783. const params = {
  784. ...paging,
  785. title: this.timelineData.first[this.timelineData.firstActive],
  786. ids: this.drawerData.idList
  787. }
  788. delete params.pageTotal
  789. const res = await getDelayReleaseData(params)
  790. if (res.code === 200) {
  791. // this.tableList = res.data
  792. this.tableListOld = res.data.length && res.data.map(e => e)
  793. this.tableListPagination()
  794. paging.pageTotal = this.tableListOld.length
  795. this.paging = { ...paging }
  796. this.loading = false
  797. }
  798. },
  799. // 分页
  800. tableListPagination() {
  801. if (this.tableListOld.length) {
  802. if (this.paging.curIndex - 1) {
  803. this.tableList = this.tableListOld.map(e => e).splice((this.paging.curIndex - 1 || 0) * this.paging.pageSize, this.paging.pageSize)
  804. } else {
  805. this.tableList = this.tableListOld.map(e => e) || []
  806. }
  807. }
  808. },
  809. /* E 效率:半浮层数据接口 */
  810. // 分页数据初始化
  811. pagingInit() {
  812. const pageSize = window.localStorage.getItem('pageSize') || 10
  813. this.paging = {
  814. curIndex: 1,
  815. pageTotal: 0,
  816. pageSize: Number.parseInt(pageSize)
  817. }
  818. },
  819. // 设置表格高度
  820. setTitleHeight() {
  821. if (this.title.search(/状态停留分布图数据|状态累积流量图数据/) > -1) {
  822. this.tableHeight = 'calc(100vh - 363px)'
  823. } else if (this.title.search(/需求周期|新增项目|新增任务|需求人力|任务周期|缺陷修复时长|延期准出率|延期提测率/) > -1) {
  824. this.tableHeight = 'calc(100vh - 288px)'
  825. } else if (this.title.search(/需求|任务|项目/) > -1) {
  826. // 吞吐量: 需求
  827. this.tableHeight = 'calc(100vh - 188px)'
  828. } else if (this.title === '缺陷24小时修复率') {
  829. this.tableHeight = 'calc(100vh - 328px)'
  830. } else {
  831. this.tableHeight = 'calc(100vh - 136px)'
  832. }
  833. if (this.headerTitle === '质量') {
  834. this.tableHeight = 'calc(100vh - 136px)'
  835. }
  836. if (this.headerTitle === '吞吐量') {
  837. this.tableHeight = 'calc(100vh - 288px)'
  838. }
  839. },
  840. // 设置表头
  841. // 表格跳转
  842. dmTableChange({ column, row }) {
  843. if (this.headerTitle === '质量' && this.drawerData.label === '新增问题') {
  844. const url = `http://odin.xiaojukeji.com/#/risk/starflower/casedetail?id=${row.id}&name=${row.title}`
  845. window.open(url, '_blank')
  846. } else if (this.headerTitle === '质量' && this.drawerData.label.search(/^(提测报告|准出记录)/) > -1) {
  847. this.jumper(row, '报告')
  848. } else if (this.headerTitle === '吞吐量') {
  849. if (this.title.search(/需求/) > -1) {
  850. this.jumper(row, '需求')
  851. }
  852. if (this.title.search(/任务/) > -1) {
  853. this.jumper(row, '任务')
  854. }
  855. if (this.title.search(/项目/) > -1) {
  856. this.jumper(row, '项目')
  857. }
  858. } else if (this.headerTitle === '效率') {
  859. if (column.label.search(/需求/) > -1) {
  860. this.jumper(row, '需求')
  861. }
  862. if (column.label.search(/任务/) > -1) {
  863. this.jumper(row, '任务')
  864. }
  865. if (column.label.search(/缺陷/) > -1) {
  866. this.jumper(row, '缺陷')
  867. }
  868. } else {
  869. this.jumper(row, '缺陷')
  870. }
  871. },
  872. // 设置表格样式
  873. setBoxShadow(key = 'drawer-box') {
  874. if (key) {
  875. setTimeout(() => {
  876. this.drawerBox = key
  877. }, 300)
  878. } else {
  879. this.drawerBox = key
  880. }
  881. },
  882. // 设置时间轴自动滚动
  883. setTimeLine() {
  884. this.$nextTick(() => {
  885. if (this.isTimeLine(1)) {
  886. // Number(this.defaultKey) * 109 - 60
  887. // this.$refs.timeline1.scrollLeft = 100
  888. }
  889. if (this.isTimeLine(2)) {
  890. // Number(this.defaultKey2) * 100 - 60
  891. // this.$refs.timeline2.scrollLeft = 256
  892. }
  893. })
  894. },
  895. jumper(val, name) { // 需求、任务、缺陷跳转
  896. const { bizId = null } = this.$store.state.global || {}
  897. const bizId_id = EncryptId(`${bizId}_${val.id}`)
  898. const newTab = this.$router.resolve({ name: name + '详情', query: { bizId_id: bizId_id }})
  899. window.open(newTab.href, '_blank')
  900. },
  901. // 设置时间轴自动滚动
  902. isTimeLine(index = 1) {
  903. // 是第一条
  904. if (index === 1) {
  905. return this.headerTitle.search(/吞吐量|效率/) > -1
  906. }
  907. // 是第二条
  908. if (index === 2) {
  909. return this.title.search(/缺陷24小时修复率/) > -1
  910. }
  911. }
  912. }
  913. }
  914. </script>
  915. <style scoped lang='less'>
  916. /deep/ .el-drawer__header {
  917. color: #444;
  918. font-size: 20px;
  919. font-weight: 500;
  920. margin-bottom: 0;
  921. padding: 20px 30px;
  922. border-bottom: 1px solid #E2E2E2;
  923. .sub-title {
  924. color: #444;
  925. font-size: 14px;
  926. margin-left: 20px;
  927. font-weight: 400;
  928. }
  929. }
  930. .drawer-box {
  931. box-shadow: 0 8px 10px -5px rgba(0, 0, 0, .2), 0 16px 24px 2px rgba(0, 0, 0, .14), 0 6px 30px 5px rgba(0, 0, 0, .12);
  932. }
  933. .el-drawer-fade-enter-active {
  934. animation: el-drawer-fade-in 10ms;
  935. }
  936. .el-drawer-fade-leave-active {
  937. animation: el-drawer-fade-in 10ms reverse;
  938. }
  939. .el-drawer__wrapper {
  940. width: 100%;
  941. position: fixed;
  942. top: 0;
  943. right: 0;
  944. bottom: 0;
  945. left: 50%;
  946. overflow: hidden;
  947. margin: 0;
  948. }
  949. /deep/.el-drawer__container {
  950. left: 0;
  951. right: 0;
  952. width: 50%;
  953. }
  954. /* S 时间轴 */
  955. .qz-drawer-header {
  956. text-align: center;
  957. background: #F7F7F7;
  958. border-radius: 4px;
  959. min-height: 120px;
  960. margin: 20px 30px;
  961. overflow: hidden;
  962. }
  963. .qz-drawer-padding {
  964. padding: 20px 0;
  965. }
  966. .qz-drawer-padding-s {
  967. padding: 1px 0;
  968. }
  969. .qz-drawer-scll {
  970. overflow-x: scroll;
  971. }
  972. .qz-drawer-scll::-webkit-scrollbar { width: 0 !important; height: 0 !important }
  973. .qz-drawer-H {
  974. font-size: 16px;
  975. margin: 0 30px;
  976. color: #444444;
  977. }
  978. .qz-drawer-scll {
  979. overflow-x: scroll;
  980. }
  981. .qz-drawer-scll::-webkit-scrollbar { width: 0 !important; height: 0 !important }
  982. .qz-drawer-H {
  983. font-size: 16px;
  984. margin: 0 30px;
  985. color: #444444;
  986. }
  987. /* E 时间轴 */
  988. /* S 质量:线上问题_改进方案 */
  989. .antdv3-tag{
  990. box-sizing: border-box;
  991. color: rgba(0,0,0,.65);
  992. font-variant: tabular-nums;
  993. list-style: none;
  994. font-feature-settings: "tnum";
  995. display: inline-block;
  996. height: auto;
  997. margin: 0 8px 0 0;
  998. padding: 0 7px;
  999. font-size: 12px;
  1000. line-height: 20px;
  1001. white-space: nowrap;
  1002. background: #fafafa;
  1003. border: 1px solid #d9d9d9;
  1004. border-radius: 2px;
  1005. cursor: default;
  1006. opacity: 1;
  1007. transition: all .3s cubic-bezier(.78,.14,.15,.86);
  1008. }
  1009. .antdv3-tag-orange {
  1010. color: #fa8c16;
  1011. background: #fff7e6;
  1012. border-color: #ffd591;
  1013. }
  1014. .antdv3-tag-green {
  1015. color: #52c41a;
  1016. background: #f6ffed;
  1017. border-color: #b7eb8f;
  1018. }
  1019. /* E 质量:线上问题_改进方案 */
  1020. .qz-footer-laout {
  1021. display: flex;
  1022. justify-content: space-between;
  1023. margin: 0 30px;
  1024. }
  1025. .drawer-name:hover {
  1026. color: #409eff;
  1027. cursor: pointer;
  1028. }
  1029. </style>