index.vue 31 KB

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