You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1170 lines
34 KiB

4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
  1. <template>
  2. <section>
  3. <el-row class="padding" ref="table">
  4. <el-row class="row_1" style="margin-bottom:20px;">
  5. <div class="r r1">
  6. <span style="color: #4779F6">{{formatNum(xmBranch.projectCnt,0) || 0}}</span>
  7. <p>项目数</p>
  8. </div>
  9. <div class="r r2">
  10. <span style="color: #4779F6">{{formatNum(xmBranch.budgetWorkload,0) || 0}}</span>
  11. <p>项目总工时</p>
  12. </div>
  13. <div class="r r3">
  14. <span style="color: #F6AE47">{{formatNum(xmBranch.productCnt,0) || 0}}</span>
  15. <p>产品数</p>
  16. </div>
  17. <div class="r r4">
  18. <span style="color: #F6AE47">{{formatNum(xmBranch.productBudgetWorkload,0) || 0}}</span>
  19. <p>产品总工时</p>
  20. </div>
  21. <div class="r r5">
  22. <span style="color: #47CBF6">{{formatNum(xmBranch.phaseCnt,0) || 0}}</span>
  23. <p>计划数</p>
  24. </div>
  25. <div class="r r6">
  26. <span style="color: #47CBF6">{{formatNum(xmBranch.iterationCnt,0) || 0}}</span>
  27. <p>迭代数</p>
  28. </div>
  29. <div class="r r7">
  30. <span style="color: #F68D47">{{formatNum(xmBranch.planWorkerCnt,0) || 0}}</span>
  31. <p>总人数</p>
  32. </div>
  33. <div class="r r8">
  34. <span style="color: #7D7D7D">{{formatNum(xmBranch.taskCnt,0) || 0}}</span>
  35. <p>任务数</p>
  36. </div>
  37. <div class="r r9">
  38. <span style="color: #7D7D7D">{{formatNum(xmBranch.menuCnt,0) || 0}}</span>
  39. <p>需求数</p>
  40. </div>
  41. </el-row>
  42. <el-row :gutter="10" style="margin-bottom:10px">
  43. <el-col :span="8" >
  44. <el-card class="box-card" style="height:425px">
  45. <div slot="header">
  46. <span>企业</span>&nbsp;<span><b>{{userInfo.branchName}}</b></span>
  47. <el-popover
  48. placement="bottom"
  49. title="标题"
  50. width="200"
  51. trigger="click" >
  52. <el-row>
  53. <el-button type="primary" @click="loadProjectStateToXmBranchState" v-loading="load.calcProduct">计算企业汇总数据</el-button>
  54. <br>
  55. <font color="blue" style="font-size:10px;">将从项目任务及企业任务中汇总进度预算工作量实际工作量预算金额实际金额缺陷数需求数等数据到企业统计表</font>
  56. </el-row>
  57. <el-button slot="reference" circle plain style="float:right;" icon="el-icon-video-play" type="text"></el-button>
  58. </el-popover>
  59. </div>
  60. <el-row>
  61. <el-col :span="8">
  62. <div class="item">
  63. <div class="icon" style="background-color: rgb(79, 140, 255);">
  64. <i class="el-icon-right"></i>
  65. </div>
  66. <div class="info">
  67. <div v-text="totalTask"></div>
  68. <div class="title">总任务量</div>
  69. </div>
  70. </div>
  71. </el-col>
  72. <el-col :span="8">
  73. <div class="item">
  74. <div class="icon" style="background-color: rgb(255, 153, 51);">
  75. <i class="el-icon-loading"></i>
  76. </div>
  77. <div class="info">
  78. <div v-text="notStart">
  79. </div>
  80. <div class="title">待完成</div>
  81. </div>
  82. </div>
  83. </el-col>
  84. <el-col :span="8">
  85. <div class="item">
  86. <div class="icon" style="background-color: rgb(0, 153, 51);">
  87. <i class="el-icon-check"></i>
  88. </div>
  89. <div class="info">
  90. <div v-text="competeTasks" >
  91. </div>
  92. <div class="title">已完成</div>
  93. </div>
  94. </div>
  95. </el-col>
  96. </el-row>
  97. <el-row>
  98. <div class="item">
  99. <div class="icon2" style="background-color: rgb(204, 204, 204);">
  100. <i class="el-icon-date"></i>
  101. </div>
  102. <div class="info">
  103. <div v-text="xmBranch.calcTime">
  104. </div>
  105. <div class="title">企业数据更新日期</div>
  106. </div>
  107. </div>
  108. </el-row>
  109. <el-row>
  110. <div class="item">
  111. <div class="icon2" style="background-color: rgb(204, 204, 204);">
  112. <i class="el-icon-star-off"></i>
  113. </div>
  114. <div class="info">
  115. <div class="title"> 需求数 {{this.xmBranch.menuCnt||0}}</div>
  116. </div>
  117. </div>
  118. </el-row>
  119. <el-row>
  120. <div class="item">
  121. <div class="icon2" style="background-color: rgb(204, 204, 204);">
  122. <i class="el-icon-alarm-clock"></i>
  123. </div>
  124. <div>
  125. <div class="progress-item">
  126. <el-progress :percentage="realProgress">
  127. </el-progress>
  128. <el-tag v-if="planProgress>realProgress" type="danger" effect="dark">整体进度 落后{{ planProgress-realProgress }}%</el-tag>
  129. <el-tag v-else-if="planProgress<realProgress" type="warning" effect="dark">整体进度 超前{{ realProgress-planProgress }}%</el-tag>
  130. <el-tag v-else effect="dark" type="success">整体进度 理想</el-tag>
  131. <div class="title">
  132. </div>
  133. </div>
  134. </div>
  135. </div>
  136. </el-row>
  137. </el-card>
  138. </el-col>
  139. <el-col :span="8" >
  140. <el-card class="box-card" style="height:425px">
  141. <div slot="header" class="clearfix">
  142. <span>总预算情况</span>
  143. </div>
  144. <div>
  145. <div id="planTotalCostPie" :style="{width: '100%', height: '320px'}"></div>
  146. </div>
  147. </el-card>
  148. </el-col>
  149. <el-col :span="8" >
  150. <el-card class="box-card" style="height:425px">
  151. <div slot="header" class="clearfix">
  152. <span>产品项目迭代个数统计</span>
  153. </div>
  154. <div>
  155. <div id="iterationAndProduct" :style="{width: '100%', height: '350px'}"></div>
  156. </div>
  157. </el-card>
  158. </el-col>
  159. </el-row>
  160. <el-row :gutter="10" style="margin-bottom:10px">
  161. <el-col :span="16" >
  162. <el-card class="box-card" style="padding:0px ;height:425px">
  163. <div slot="header" class="clearfix">
  164. <span>企业工时</span>
  165. </div>
  166. <div>
  167. <el-row >
  168. <div class="item">
  169. <el-col :span="8">
  170. <div>
  171. <div style="text-align:center;">
  172. <span style="font-size:24px;" v-text="this.xmBranch.budgetWorkload"></span>
  173. <span style="font-size:5px;">h</span>
  174. </div>
  175. <div style="text-align:center;font-size:5px;">总估工时</div>
  176. </div>
  177. </el-col>
  178. <el-col :span="8">
  179. <div>
  180. <div style="text-align:center;">
  181. <span style="font-size:24px;" v-text="this.xmBranch.estimateWorkload"></span>
  182. <span style="font-size:5px;">h</span>
  183. </div>
  184. <div style="text-align:center;font-size:5px;">应完成工时</div>
  185. </div>
  186. </el-col>
  187. <el-col :span="8">
  188. <div>
  189. <div style="text-align:center;">
  190. <span style="font-size:24px;" v-text="this.xmBranch.actWorkload"></span>
  191. <span style="font-size:5px;">h</span>
  192. </div>
  193. <div style="text-align:center;font-size:5px;" title="已登记的工时">已完成工时</div>
  194. </div>
  195. </el-col>
  196. </div>
  197. </el-row>
  198. <el-row >
  199. <div class="item">
  200. <el-col :span="8">
  201. <div title="总估工时-已完成工时">
  202. <div style="text-align:center;">
  203. <span style="font-size:24px;" v-text="remainWorkload"></span>
  204. <span style="font-size:5px;">h</span>
  205. </div>
  206. <div style="text-align:center;font-size:5px;">剩余工时</div>
  207. </div>
  208. </el-col>
  209. <el-col :span="8">
  210. <div title="已完成工时-当前应完成工时">
  211. <div style="text-align:center;">
  212. <span style="font-size:24px;" v-text="deviation"></span>
  213. <span style="font-size:5px;">h</span>
  214. </div>
  215. <div style="text-align:center;font-size:5px;">预估偏差</div>
  216. </div>
  217. </el-col>
  218. <el-col :span="8">
  219. <div title="(已完成工时-当前应完成工时)/ 当前应完成工时">
  220. <div style="text-align:center;">
  221. <span style="font-size:24px;" v-text="deviationRate"></span>
  222. <span style="font-size:5px;">%</span>
  223. </div>
  224. <div style="text-align:center;font-size:5px;">预估偏差率</div>
  225. </div>
  226. </el-col>
  227. </div>
  228. </el-row>
  229. <el-row>
  230. <span style="margin-left:20px;" title="应完成工时/总预估工时">预计进度</span>
  231. <el-progress style="width: 90%;margin-left:20px;margin-top: 10px;margin-bottom: 20px;" :stroke-width="14" :percentage="planProgress"></el-progress>
  232. </el-row>
  233. <el-row>
  234. <span style="margin-left:20px;" title="实际工时/总预估工时">实际进度</span>
  235. <el-progress style="width: 90%;margin-left:20px;margin-top: 10px;" color="#47CBF6" :stroke-width="14" :percentage="realProgress"></el-progress>
  236. </el-row>
  237. </div>
  238. </el-card>
  239. </el-col>
  240. <el-col :span="8" >
  241. <el-card class="box-card" style="height:425px">
  242. <div slot="header" class="clearfix">
  243. <span>合作开发工作量分布</span>
  244. </div>
  245. <div>
  246. <div id="workloadDistribution" :style="{width: '100%', height: '320px'}"></div>
  247. </div>
  248. </el-card>
  249. </el-col>
  250. </el-row>
  251. <el-row :gutter="10" style="margin-bottom:10px">
  252. <el-col :span="8" >
  253. <el-card class="box-card" style="height:425px">
  254. <div slot="header" class="clearfix">
  255. <span>所有工作项数量分布</span>
  256. </div>
  257. <div>
  258. <div id="allChart" :style="{width: '100%', height: '350px'}"></div>
  259. </div>
  260. </el-card>
  261. </el-col>
  262. <el-col :span="8" >
  263. <el-card class="box-card" style="height:425px">
  264. <div slot="header" class="clearfix">
  265. <span>需求情况</span>
  266. </div>
  267. <div>
  268. <div id="menuChart" :style="{width: '100%', height: '320px'}"></div>
  269. </div>
  270. </el-card>
  271. </el-col>
  272. <el-col :span="8" >
  273. <el-card class="box-card" style="padding:0px ;height:425px">
  274. <div slot="header" class="clearfix">
  275. <span>任务状态分布</span>
  276. </div>
  277. <div>
  278. <div id="taskChart" :style="{width: '100%', height: '350px'}"></div>
  279. </div>
  280. </el-card>
  281. </el-col>
  282. </el-row>
  283. <el-row :gutter="10" style="margin-bottom:10px">
  284. <el-col :span="8" >
  285. <el-card class="box-card" style="height:425px">
  286. <div slot="header" class="clearfix">
  287. <span>测试用例情况</span>
  288. </div>
  289. <div>
  290. <div id="testCasePieChart" :style="{width: '100%', height: '320px'}"></div>
  291. </div>
  292. </el-card>
  293. </el-col>
  294. <el-col :span="8" >
  295. <el-card class="box-card" style="height:425px">
  296. <div slot="header" class="clearfix">
  297. <span>缺陷情况</span>
  298. </div>
  299. <div>
  300. <div id="bugPieChart" :style="{width: '100%', height: '320px'}"></div>
  301. </div>
  302. </el-card>
  303. </el-col>
  304. </el-row>
  305. </el-row>
  306. </section>
  307. </template>
  308. <script>
  309. import util from "@/common/js/util"; // 全局公共库
  310. import { mapGetters } from "vuex";
  311. import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询
  312. import { listXmBranchState} from '@/api/xm/core/xmBranchState';
  313. import { loadTasksToXmMenuState} from '@/api/xm/core/xmMenuState';
  314. import { loadProjectStateToXmBranchState} from '@/api/xm/core/xmBranchState';
  315. import store from '@/store'
  316. export default {
  317. computed: {
  318. ...mapGetters(["userInfo"]),
  319. competeTasks: function (){
  320. return this.xmBranch.taskCnt||0-this.xmBranch.taskUnstartCnt||0-this.xmBranch.taskExecCnt||0;
  321. },
  322. notStart: function() {
  323. return this.xmBranch.taskUnstartCnt||0+this.xmBranch.taskExecCnt||0;
  324. },
  325. totalTask: function() {
  326. return this.xmBranch.taskCnt||0;
  327. },
  328. taskStartTime: function (){
  329. return this.xmBranch.startTime?this.xmBranch.startTime.substring(0,10):'';
  330. },
  331. taskEndTime: function (){
  332. return this.xmBranch.endTime?this.xmBranch.endTime.substring(0,10):'';
  333. },
  334. pmUsername: function (){
  335. return this.xmBranch.pmUsername;
  336. },
  337. workloadProgress:function (){
  338. if(!this.xmBranch.actWorkload||!this.xmBranch.budgetWorkload){
  339. return 0;
  340. }
  341. return Math.round(this.xmBranch.actWorkload/this.xmBranch.budgetWorkload*100);
  342. },
  343. deviation:function (){
  344. return Math.round(this.xmBranch.actWorkload||0-this.xmBranch.estimateWorkload||0)
  345. },
  346. deviationRate:function (){
  347. if(!this.xmBranch.estimateWorkload||!this.deviation){
  348. return 0
  349. }
  350. return Math.round(this.deviation/this.xmBranch.estimateWorkload*100);
  351. },
  352. remainWorkload:function (){
  353. return Math.round(this.xmBranch.budgetWorkload||0 - this.xmBranch.actWorkload||0);
  354. },
  355. planProgress:function (){
  356. if(!this.xmBranch.estimateWorkload||!this.xmBranch.budgetWorkload){
  357. return 0;
  358. }
  359. return Math.round(this.xmBranch.estimateWorkload/this.xmBranch.budgetWorkload*100);
  360. },
  361. realProgress:function (){
  362. if(!this.xmBranch.actWorkload||!this.xmBranch.budgetWorkload){
  363. return 0;
  364. }
  365. if(this.xmBranch.actWorkload < this.xmBranch.budgetWorkload){
  366. return Math.round(this.xmBranch.actWorkload/this.xmBranch.budgetWorkload*100)
  367. }else{
  368. return 100;
  369. }
  370. },
  371. xmBranchStateCpd(){
  372. return this.xmBranch
  373. },
  374. },
  375. watch:{
  376. xmBranchStateCpd:function(){
  377. this.drawAllBar();
  378. this.drawTask();
  379. this.drawTestCasePie();
  380. this.drawPieBug();
  381. this.drawCostPie();
  382. this.drawWorkload();
  383. this.drawIterationProduct();
  384. }
  385. },
  386. data() {
  387. return {
  388. xmBranch:{},
  389. load:{list:false,add:false,calcProject:false,calcSettle:false},
  390. isActive: true,
  391. maxTableHeight:300,
  392. dicts:{
  393. xmBranchPstatus:[]
  394. },//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]}
  395. };
  396. },
  397. methods:{
  398. drawAllBar() {
  399. // 基于准备好的dom,初始化echarts实例
  400. let allChart = this.$echarts.init(document.getElementById("allChart"));
  401. let option = {
  402. tooltip: {
  403. trigger: 'axis',
  404. axisPointer: {
  405. type: 'shadow'
  406. }
  407. },
  408. grid: {
  409. left: '3%',
  410. right: '4%',
  411. bottom: '10%',
  412. containLabel: true
  413. },
  414. yAxis: {
  415. type: 'value'
  416. },
  417. xAxis: {
  418. type: 'category',
  419. data: ['需求', '任务','用例', '缺陷']
  420. },
  421. series: [
  422. {
  423. label: {
  424. normal:{
  425. show: true,
  426. position: 'top',
  427. color:'#000000',
  428. }
  429. },
  430. data: [
  431. {
  432. value: this.xmBranch.menuCnt,
  433. itemStyle: {
  434. normal:{
  435. color: '#91CC75'
  436. }
  437. }
  438. },
  439. {
  440. value: this.xmBranch.taskCnt,
  441. itemStyle: {
  442. normal:{
  443. color: '#FAC858'
  444. }
  445. }
  446. },
  447. {
  448. value: this.xmBranch.testCases,
  449. itemStyle: {
  450. normal:{
  451. color: '#99CCFF'
  452. }
  453. }
  454. },
  455. {
  456. value: this.xmBranch.bugCnt,
  457. itemStyle: {
  458. normal:{
  459. color: '#EE6666'
  460. }
  461. }
  462. },
  463. ],
  464. type: 'bar'
  465. }
  466. ]
  467. };
  468. // 绘制图表
  469. allChart.setOption(option);
  470. },
  471. drawMenuPie() {
  472. let taskChart = this.$echarts.init(document.getElementById("menuChart"));
  473. let option = {
  474. title: {
  475. left: 'center'
  476. },
  477. tooltip: {
  478. trigger: 'item',
  479. },
  480. calculable: true,
  481. legend:{
  482. show:true,
  483. bottom: 'bottom',
  484. data:['打开','执行中','已完成','已关闭'],
  485. },
  486. graphic: {
  487. type: 'text',
  488. left: 'center',
  489. top: '40%',
  490. style: {
  491. // text: '总数',
  492. text:
  493. '需求数'+this.xmBranch.menuCnt,
  494. textAlign: 'center',
  495. fill: '#333',
  496. width: 30,
  497. height: 30,
  498. fontSize: 14
  499. }
  500. },
  501. series: [
  502. {
  503. type: 'pie',
  504. center:['50%','40%'],
  505. radius: ['35%','60%'],
  506. data:[{name:'打开',value:this.xmBranch.menuUnstartCnt},{name:'执行中',value:this.xmBranch.menuExecCnt},{name:'已完成',value:this.xmBranch.menuFinishCnt},{name:'已关闭',value:this.xmBranch.menuCloseCnt}],
  507. emphasis: {
  508. itemStyle: {
  509. shadowBlur: 10,
  510. shadowOffsetX: 0,
  511. shadowColor: 'rgba(0, 0, 0, 0.5)'
  512. }
  513. },
  514. label: {
  515. show: true,
  516. formatter:'{b}: {c}  ({d}%)'
  517. },
  518. }
  519. ]
  520. };
  521. // 绘制图表
  522. taskChart.setOption(option);
  523. },
  524. drawTestCasePie() {
  525. let taskChart = this.$echarts.init(document.getElementById("testCasePieChart"));
  526. let option = {
  527. title: {
  528. left: 'center'
  529. },
  530. tooltip: {
  531. trigger: 'item',
  532. },
  533. calculable: true,
  534. legend:{
  535. show:true,
  536. bottom: 'bottom',
  537. data:['设计中','执行中','已完成'],
  538. },
  539. graphic: {
  540. type: 'text',
  541. left: 'center',
  542. top: '40%',
  543. style: {
  544. // text: '总数',
  545. text:
  546. '用例数'+this.xmBranch.testCases,
  547. textAlign: 'center',
  548. fill: '#333',
  549. width: 30,
  550. height: 30,
  551. fontSize: 14
  552. }
  553. },
  554. series: [
  555. {
  556. type: 'pie',
  557. center:['50%','40%'],
  558. radius: ['35%','60%'],
  559. data:[{name:'设计中',value:this.xmBranch.designCases},{name:'执行中',value:this.xmBranch.execCases},{name:'已完成',value:this.xmBranch.finishCases}],
  560. emphasis: {
  561. itemStyle: {
  562. shadowBlur: 10,
  563. shadowOffsetX: 0,
  564. shadowColor: 'rgba(0, 0, 0, 0.5)'
  565. }
  566. },
  567. label: {
  568. show: true,
  569. formatter:'{b}: {c}  ({d}%)'
  570. },
  571. }
  572. ]
  573. };
  574. // 绘制图表
  575. taskChart.setOption(option);
  576. },
  577. drawTask() {
  578. let taskChart = this.$echarts.init(document.getElementById("taskChart"));
  579. let option = {
  580. title: {
  581. left: 'center'
  582. },
  583. tooltip: {
  584. trigger: 'item',
  585. },
  586. calculable: true,
  587. grid: {
  588. left: '3%',
  589. right: '4%',
  590. bottom: '10%',
  591. containLabel: true
  592. },
  593. yAxis: {
  594. type: 'value'
  595. },
  596. xAxis: {
  597. type: 'category',
  598. data:['未开始','执行中','已完工','已结算','已关闭'],
  599. },
  600. series: [
  601. {
  602. label: {
  603. normal:{
  604. show: true,
  605. position: 'top',
  606. color:'#000000',
  607. }
  608. },
  609. type: 'bar',
  610. center:['50%','40%'],
  611. data:[
  612. {name:'未开始',value:this.xmBranch.taskUnstartCnt,
  613. itemStyle: {
  614. normal:{
  615. color: '#FAC858'
  616. }
  617. }
  618. },
  619. {name:'执行中',value:this.xmBranch.taskExecCnt,
  620. itemStyle: {
  621. normal:{
  622. color: '#91CC75'
  623. }
  624. }},
  625. {name:'已完工',value:this.xmBranch.taskFinishCnt,
  626. itemStyle: {
  627. normal:{
  628. color: '#FAC858'
  629. }
  630. }},
  631. {name:'已结算',value:this.xmBranch.taskSetCnt,
  632. itemStyle: {
  633. normal:{
  634. color: '#99CCFF'
  635. }
  636. }},
  637. {name:'已关闭',value:this.xmBranch.taskCloseCnt,
  638. itemStyle: {
  639. normal:{
  640. color: '#EE6666'
  641. }
  642. }}],
  643. }
  644. ]
  645. };
  646. // 绘制图表
  647. taskChart.setOption(option);
  648. },
  649. drawPieBug() {
  650. let bugPieChart = this.$echarts.init(document.getElementById("bugPieChart"));
  651. let option = {
  652. title: {
  653. left: 'center'
  654. },
  655. tooltip: {
  656. trigger: 'item',
  657. formatter: '{b} : {c} ({d}%)'
  658. },
  659. legend: {
  660. show:true,
  661. bottom: 'bottom',
  662. data:['已激活','已确认','已解决','已关闭']
  663. },
  664. graphic: {
  665. type: 'text',
  666. left: 'center',
  667. top: '40%',
  668. style: {
  669. // text: '总数',
  670. text:
  671. '缺陷数'+this.xmBranch.bugCnt,
  672. textAlign: 'center',
  673. fill: '#333',
  674. width: 30,
  675. height: 30,
  676. fontSize: 14
  677. }
  678. },
  679. series: [
  680. {
  681. type: 'pie',
  682. center:['50%','40%'],
  683. radius: ['35%','60%'],
  684. label:{
  685. show: true,
  686. formatter:'{b}: {c}  ({d}%)'
  687. },
  688. data: [
  689. {value: this.xmBranch.activeBugs,
  690. itemStyle: {
  691. normal:{
  692. color: '#FAC858'
  693. }
  694. },
  695. name: '已激活'},
  696. {value: this.xmBranch.confirmedBugs,
  697. itemStyle: {
  698. normal:{
  699. color: '#EE6666'
  700. }
  701. },
  702. name: '已确认'},
  703. {value: this.xmBranch.resolvedBugs,
  704. itemStyle: {
  705. normal:{
  706. color: '#91CC75'
  707. }
  708. },
  709. name: '已解决'},
  710. {value: this.xmBranch.closedBugs,
  711. itemStyle: {
  712. normal:{
  713. color: '#5470C6'
  714. }
  715. },
  716. name: '已关闭'},
  717. ],
  718. }
  719. ]
  720. };
  721. // 绘制图表
  722. bugPieChart.setOption(option);
  723. },
  724. drawCostPie() {
  725. let planTotalCostPie = this.$echarts.init(document.getElementById("planTotalCostPie"));
  726. let option = {
  727. tooltip: {
  728. trigger: 'item',
  729. formatter: '{b} : {c} ({d}%)'
  730. },
  731. legend: {
  732. bottom: 10,
  733. left: 'center',
  734. },
  735. series: [
  736. {
  737. center:['55%','40%'],//饼图位置
  738. type: 'pie',
  739. radius: '50%',//饼图半径大小
  740. label:{ //饼图图形上的文本标签
  741. normal:{
  742. show:true,
  743. position:'outer', //标签的位置:外部
  744. textStyle : {
  745. fontWeight : 100 ,
  746. fontSize: document.body.clientWidth / 120, //标签字体大小
  747. color: "#000000"
  748. },
  749. formatter:'{b}\n{c}({d}%)',//b:name,c:value,d:占比
  750. alignTo:'edge',
  751. margin:10
  752. }
  753. },
  754. data: [
  755. {value: this.xmBranch.budgetNouserAt,
  756. itemStyle: {
  757. normal:{
  758. color: '#FAC858'
  759. }
  760. },
  761. name: '非人力'},
  762. {value: this.xmBranch.budgetIuserAt,
  763. itemStyle: {
  764. normal:{
  765. color: '#73C0DE'
  766. }
  767. },
  768. name: '内部人力'},
  769. {value: this.xmBranch.budgetOuserAt,
  770. itemStyle: {
  771. normal:{
  772. color: '#5470C6'
  773. }
  774. },
  775. name: '外购人力'},
  776. ],
  777. emphasis: {
  778. itemStyle: {
  779. shadowBlur: 10,
  780. shadowOffsetX: 0,
  781. shadowColor: 'rgba(0, 0, 0, 0.5)'
  782. }
  783. }
  784. }
  785. ]
  786. };
  787. // 绘制图表
  788. planTotalCostPie.setOption(option);
  789. },
  790. drawWorkload() {
  791. let workloadDistribution = this.$echarts.init(document.getElementById("workloadDistribution"));
  792. let option = {
  793. tooltip: {
  794. trigger: 'item',
  795. formatter: '{b} :<br/> {c} ({d}%)'
  796. },
  797. legend: {
  798. bottom: 10,
  799. left: 'center',
  800. },
  801. graphic: {
  802. type: 'text',
  803. left: 'center',
  804. top: '40%',
  805. style: {
  806. // text: '总数',
  807. text:
  808. '总工时:'+this.xmBranch.budgetWorkload,
  809. textAlign: 'center',
  810. fill: '#333',
  811. width: 30,
  812. height: 30,
  813. fontSize: 14
  814. }
  815. },
  816. series: [
  817. {
  818. type: 'pie',
  819. center:['50%','40%'],
  820. radius: ['35%','60%'],
  821. label:{ //饼图图形上的文本标签
  822. normal:{
  823. show:true,
  824. position:'outer', //标签的位置:外部
  825. textStyle : {
  826. fontWeight : 100 ,
  827. fontSize: document.body.clientWidth / 120, //标签字体大小
  828. color: "#000000"
  829. },
  830. formatter:'{b}\n{c}({d}%)',//b:name,c:value,d:占比
  831. alignTo:'edge',
  832. margin:10
  833. }
  834. },
  835. data: [
  836. {value: this.xmBranch.budgetIuserWorkload,
  837. itemStyle: {
  838. normal:{
  839. color: '#91CC75'
  840. }
  841. },
  842. name: '内部人力'},
  843. {value: this.xmBranch.budgetOuserWorkload,
  844. itemStyle: {
  845. normal:{
  846. color: '#3BA272'
  847. }
  848. },
  849. name: '外购人力'},
  850. ],
  851. emphasis: {
  852. itemStyle: {
  853. shadowBlur: 10,
  854. shadowOffsetX: 0,
  855. shadowColor: 'rgba(0, 0, 0, 0.5)'
  856. }
  857. }
  858. }
  859. ]
  860. };
  861. // 绘制图表
  862. workloadDistribution.setOption(option);
  863. },
  864. drawIterationProduct() {
  865. let iterationAndProduct = this.$echarts.init(document.getElementById("iterationAndProduct"));
  866. let option = {
  867. tooltip: {
  868. trigger: 'axis',
  869. formatter: '{b} : {c}',
  870. axisPointer: { // 坐标轴指示器,坐标轴触发有效
  871. type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
  872. },
  873. },
  874. xAxis: {
  875. type: 'category',
  876. data: ['产品数','项目数', '迭代数']
  877. },
  878. yAxis: {
  879. type: 'value'
  880. },
  881. series: [{
  882. label: {
  883. normal:{
  884. show: true,
  885. position: 'top',
  886. color:'#000000',
  887. }
  888. },
  889. data: [
  890. {
  891. value: this.xmBranch.productCnt,
  892. itemStyle: {
  893. normal:{
  894. color: '#3BA272'
  895. }
  896. }
  897. },
  898. {
  899. value: this.xmBranch.projectCnt,
  900. itemStyle: {
  901. normal:{
  902. color: '#91CC75'
  903. }
  904. }
  905. },
  906. {
  907. value: this.xmBranch.iterationCnt,
  908. itemStyle: {
  909. normal:{
  910. color: '#FAC858'
  911. }
  912. }
  913. },
  914. ],
  915. type: 'bar',
  916. }]
  917. };
  918. // 绘制图表
  919. iterationAndProduct.setOption(option);
  920. },
  921. loadProjectStateToXmBranchState(){
  922. var row=this.xmBranch;
  923. var params={id:row.id}
  924. this.load.calcProject=true;
  925. loadProjectStateToXmBranchState(params).then((res1) => {
  926. this.load.calcProject=false;
  927. this.load.list=true;
  928. listXmBranchState({id:row.id}).then(res=>{
  929. this.load.list=false;
  930. var tips = res.data.tips;
  931. if(tips.isOk){
  932. this.xmBranch=res.data.data[0]
  933. }
  934. this.$notify({position:'bottom-left',showClose:true,message: tips.msg, type: tips.isOk?'success':'error'});
  935. })
  936. }).catch( err => this.load.calcProject=false );
  937. },
  938. loadTasksToXmMenuState(){
  939. var row=this.xmBranch;
  940. var params={productId:row.id}
  941. loadTasksToXmMenuState(params).then((res) => {
  942. this.load.calcProject=false;
  943. var tips=res.data.tips;
  944. this.$notify({position:'bottom-left',showClose:true,message: tips.msg, type: tips.isOk?'success':'error'});
  945. }).catch( err => this.load.calcProject=false );
  946. },
  947. formatNum(num,defVal){
  948. if(num){
  949. return parseInt(num)
  950. }else{
  951. return defVal
  952. }
  953. },
  954. },
  955. mounted() {
  956. listXmBranchState({id:this.userInfo.branchId}).then(res=>{
  957. this.load.list=false;
  958. var tips = res.data.tips;
  959. if(tips.isOk){
  960. this.xmBranch=res.data.data[0]
  961. this.drawAllBar();
  962. this.drawMenuPie();
  963. this.drawTask();
  964. this.drawTestCasePie();
  965. this.drawPieBug();
  966. this.drawCostPie();
  967. this.drawWorkload();
  968. this.drawIterationProduct();
  969. }
  970. })
  971. this.$nextTick(() => {
  972. this.maxTableHeight=util.calcTableMaxHeight(this.$refs.table.$el)
  973. });
  974. initSimpleDicts('all',['xmBranchPstatus']).then(res=>{
  975. this.dicts=res.data.data;
  976. })
  977. },
  978. };
  979. </script>
  980. <style scoped lang="scss">
  981. .container {
  982. margin: 10px;
  983. }
  984. .header {
  985. display: flex;
  986. justify-content: flex-start;
  987. padding: 10px;
  988. span {
  989. padding-right: 15px;
  990. }
  991. }
  992. .col {
  993. margin-bottom: 20px;
  994. }
  995. .icon {
  996. color: #fff;
  997. height: 30px;
  998. border-radius: 15px;
  999. text-align: center;
  1000. font-size: 20px;
  1001. display: inline-block;
  1002. margin-right: 5px;
  1003. }
  1004. .icon2 {
  1005. color: #000000;
  1006. width: 30px;
  1007. border-radius: 15px;
  1008. text-align: center;
  1009. font-size: 20px;
  1010. display: inline-block;
  1011. margin-right: 5px;
  1012. margin-left: 5px;
  1013. }
  1014. .item {
  1015. display: flex;
  1016. justify-content: flex-start;
  1017. position: relative;
  1018. .progress-item{
  1019. position:absolute; width:80%;
  1020. }
  1021. }
  1022. .card-font {
  1023. color: #000000;
  1024. font-size: 12px;
  1025. .el-col {
  1026. margin-bottom: 20px;
  1027. }
  1028. }
  1029. .calendar-header {
  1030. display: flex;
  1031. justify-content: space-between;
  1032. .cal-header-boxs {
  1033. flex: 1;
  1034. display: flex;
  1035. justify-content: flex-end;
  1036. .cal-header-box {
  1037. padding: 5px;
  1038. height: 45px;
  1039. margin-left: 10px;
  1040. }
  1041. .box-icon {
  1042. text-align: center;
  1043. }
  1044. .box-info {
  1045. text-align: center;
  1046. font-size: 12px;
  1047. color: #000000;
  1048. }
  1049. }
  1050. }
  1051. .el-tag:hover {
  1052. cursor: pointer;
  1053. }
  1054. .value {
  1055. cursor: pointer;
  1056. }
  1057. .reference {
  1058. margin-top: 10px;
  1059. font-size: 12px;
  1060. }
  1061. .click {
  1062. background: #e9f7ff;
  1063. }
  1064. .calendar-box {
  1065. display: flex;
  1066. justify-content: flex-start;
  1067. }
  1068. .row_1 {
  1069. background-color: #fff;
  1070. display: flex;
  1071. flex-direction: row;
  1072. height: 120px;
  1073. margin-top: 10px;
  1074. .r {
  1075. flex: 1;
  1076. display: flex;
  1077. flex-direction: column;
  1078. justify-content: center;
  1079. align-items: center;
  1080. span {
  1081. margin-bottom: 14px;
  1082. font-size: 24px;
  1083. font-weight: bold;
  1084. }
  1085. p {
  1086. font-size: 18px;
  1087. color: #7D7D7D;
  1088. font-weight: bold;
  1089. opacity: 0.55;
  1090. }
  1091. }
  1092. }
  1093. </style>