summary.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. <template>
  2. <div :style="'padding:10px;background:#f7f7f7;min-height:'+tableHeight+'px;'">
  3. <div style="margin: 0 auto;width:1120px;">
  4. <!-- <label>项目统计</label> -->
  5. <el-row :gutter="10">
  6. <!-- 任务数量总计 -->
  7. <el-col :span="12">
  8. <div class="box">
  9. <div >
  10. <div class="lableTxt">项目概览表</div>
  11. <el-divider></el-divider>
  12. <el-row :gutter="10">
  13. <el-col :span="6" style="text-align:center;">
  14. <p style="color:#666;font-size:12px;">全部</p>
  15. <p style="font-size:28px;font-weight:bold;color:black;">{{taskSum.total}}</p>
  16. </el-col>
  17. <el-col :span="6" style="text-align:center;">
  18. <p style="color:#666;font-size:12px;">已完成</p>
  19. <p style="font-size:28px;font-weight:bold;color:green;">{{taskSum.finishCount}}</p>
  20. </el-col>
  21. <el-col :span="6" style="text-align:center;">
  22. <p style="color:#666;font-size:12px;">未完成</p>
  23. <p style="font-size:28px;color:blue;font-weight:bold;">{{taskSum.unfinishCount}}</p>
  24. </el-col>
  25. <el-col :span="6" style="text-align:center;">
  26. <p style="color:#666;font-size:12px;">已逾期</p>
  27. <p style="font-size:28px;color:red;font-weight:bold;">{{taskSum.timeupCount}}</p>
  28. </el-col>
  29. </el-row>
  30. <el-row :gutter="10">
  31. <el-col :span="6" style="text-align:center;">
  32. <p style="color:#666;font-size:12px;">待认领</p>
  33. <p style="font-size:28px;color:#orange;font-weight:bold;">{{taskSum.unassignCount}}</p>
  34. </el-col>
  35. <el-col :span="6" style="text-align:center;">
  36. <p style="color:#666;font-size:12px;">今日到期</p>
  37. <p style="font-size:28px;font-weight:bold;color:pink;">{{taskSum.todayTimeupCount}}</p>
  38. </el-col>
  39. <el-col :span="6" style="text-align:center;">
  40. <p style="color:#666;font-size:12px;">逾期完成</p>
  41. <p style="font-size:28px;font-weight:bold;color:gray;">{{taskSum.timeupFinishCount}}</p>
  42. </el-col>
  43. <el-col :span="6" style="text-align:center;">
  44. <p style="color:#666;font-size:12px;">时间待定</p>
  45. <p style="font-size:28px;font-weight:bold;color:black;">{{taskSum.timeunsetCount}}</p>
  46. </el-col>
  47. </el-row>
  48. </div>
  49. </div>
  50. </el-col>
  51. <el-col :span="12">
  52. <div class="box">
  53. <div class="lableTxt">执行人分配</div>
  54. <el-divider></el-divider>
  55. <div id="executorPanel" style="height:300px;width:500px;"></div>
  56. </div>
  57. </el-col>
  58. </el-row>
  59. <el-row :gutter="10">
  60. <el-col :span="12">
  61. <div class="box">
  62. <div class="lableTxt">耗时最多任务</div>
  63. <el-divider></el-divider>
  64. <div id="costPanel" style="height:300px;width:500px;"></div>
  65. </div>
  66. </el-col>
  67. <el-col :span="12">
  68. <div class="box">
  69. <div class="lableTxt">按任务列表统计</div>
  70. <el-divider></el-divider>
  71. <div id="stagesPanel" style="height:300px;width:500px;"></div>
  72. </div>
  73. </el-col>
  74. </el-row>
  75. <el-row :gutter="10">
  76. <el-col :span="24">
  77. <div class="box" style="height:550px;">
  78. <div class="lableTxt">任务 计划工时 VS 实际工时 <el-link @click="exportTaskCompare" style="float:right;"><i class="iconfont firerock-iconexport"></i>导出</el-link></div>
  79. <el-divider></el-divider>
  80. <div id="taskTimeComparePanel" style="height:500px;width:1100px;"></div>
  81. </div>
  82. </el-col>
  83. </el-row>
  84. </div>
  85. </div>
  86. </template>
  87. <style scoped>
  88. #executorPanel {
  89. display: inline-block;
  90. width: 100%;
  91. }
  92. .el-divider--horizontal {
  93. margin: 10px 0;
  94. height: 0.5px;
  95. }
  96. .box {
  97. background:#fff;border: 1px solid #eeeeee;border-radius:5px;padding:10px;
  98. height:303.7px;margin-top:10px;
  99. }
  100. .info span {
  101. color:#303133;
  102. }
  103. .gray_label {
  104. color:#999 !important;
  105. }
  106. .el-row {
  107. margin-top:10px;
  108. }
  109. .lableTxt {
  110. color:#666;
  111. }
  112. </style>
  113. <script>
  114. import util from "../../common/js/util";
  115. export default {
  116. data() {
  117. return {
  118. compareChart:null,
  119. costChart:null,
  120. stagesChart: null,
  121. executorChart: null,
  122. pVisible:false,
  123. taskSum:{},
  124. users:[],
  125. importanceList:[{id:1,label:'一般'},{id:2,label:'紧急'},{id:3,label:'重要'},{id:4,label:'重要且紧急'}],
  126. //1-一般,2-紧急,3-重要,4-重要且紧急
  127. levelTxt:["全部","一般","紧急","重要","重要且紧急"],
  128. //1-进行中,2-已完成,3-已撤销
  129. statusTxt: ["全部","进行中","已完成","已撤销"],
  130. addFolderDialog: false,
  131. upLoading:false,
  132. user: JSON.parse(sessionStorage.getItem("user")),
  133. addLoading: false,
  134. curProjectId:null,
  135. title: "",
  136. };
  137. },
  138. methods: {
  139. exportTaskCompare() {
  140. let _this = this;
  141. this.http.post('/task/exportTaskTimeCompare', {projectId: this.curProjectId},
  142. res => {
  143. if (res.code == "ok") {
  144. location.href = res.data;
  145. } else {
  146. this.$message({
  147. message: res.msg,
  148. type: "error"
  149. });
  150. }
  151. }
  152. );
  153. },
  154. getTaskTimeCompare() {
  155. let _this = this;
  156. this.http.post('/task/getTaskTimeCompare', {projectId: this.curProjectId},
  157. res => {
  158. if (res.code == "ok") {
  159. var xList1 = [], xList2 = [], list = res.data.reverse();
  160. var taskNames = [];
  161. for(var i in list) {
  162. xList1.push({
  163. "value": list[i].workHours,
  164. "id": list[i].id,
  165. "fullName":list[i].name,
  166. });
  167. xList2.push({
  168. "value": list[i].planHours,
  169. "id": list[i].id,
  170. "fullName":list[i].name,
  171. });
  172. taskNames.push(list[i].name.length>12?list[i].name.substring(0,12)+'..':list[i].name);
  173. }
  174. var myChart = echarts.init(document.getElementById("taskTimeComparePanel"));
  175. _this.compareChart = myChart;
  176. var option = {
  177. // 全局调色盘。
  178. color: ["#409EFF","#71C671"],
  179. title: {
  180. show:list.length == 0,
  181. textStyle: {
  182. color: "#666666",
  183.   fontSize: 18,
  184. fontWeight: 'normal',
  185.  },
  186.   text: list.length == 0?"暂无数据":"工时对比",
  187.   left: "center",
  188.   top: "center"
  189. },
  190. toolbox: {
  191. show: true,
  192. feature:{
  193. saveAsImage:{
  194. show:true
  195. },
  196. restore:{
  197. show:true
  198. },
  199. magicType:{
  200. type:['line','bar']
  201. },
  202. }
  203. },
  204. legend: {
  205. data: ['实际工时', '计划工时']
  206. },
  207. grid: {
  208. left: '3%',
  209. right: '4%',
  210. bottom: '3%',
  211. containLabel: true
  212. },
  213. tooltip: {
  214. trigger: 'axis',
  215. axisPointer: {
  216. type: 'shadow'
  217. },
  218. },
  219. xAxis: {
  220. type: 'value',
  221. boundaryGap: [0, 1],
  222. axisLabel: {
  223. formatter:'{value} 小时'
  224. }
  225. },
  226. yAxis: [{
  227. type: 'category',
  228. data: taskNames
  229. }],
  230. series: [{
  231. name: '实际工时',
  232. type: 'bar',
  233. data: xList1
  234. },
  235. {
  236. name: '计划工时',
  237. type: 'bar',
  238. data: xList2
  239. }]
  240. };
  241. myChart.setOption(option,{notMerge: true});
  242. } else {
  243. this.$message({
  244. message: res.msg,
  245. type: "error"
  246. });
  247. }
  248. },
  249. error => {
  250. this.$message({
  251. message: error,
  252. type: "error"
  253. });
  254. });
  255. },
  256. getTopCostTask() {
  257. let _this = this;
  258. this.http.post('/task/getTopCostTask', {projectId: this.curProjectId},
  259. res => {
  260. if (res.code == "ok") {
  261. var xList = [], yList = [], list = res.data;
  262. for(var i in list) {
  263. xList.push(list[i].name.length>6?list[i].name.substring(0,6)+'..':list[i].name);
  264. yList.push({
  265. "value": list[i].value,
  266. "id": list[i].id,
  267. "fullName":list[i].name,
  268. });
  269. }
  270. var myChart = echarts.init(document.getElementById("costPanel"));
  271. _this.costChart = myChart;
  272. var option = {
  273. title: {
  274. show:list.length == 0,
  275. textStyle: {
  276. color: "#666666",
  277.   fontSize: 18,
  278. fontWeight: 'normal',
  279.  },
  280.   text: list.length == 0?"暂无数据":"耗时最多任务图",
  281.   left: "center",
  282.   top: "center"
  283. },
  284. toolbox: {
  285. show: true,
  286. feature:{
  287. saveAsImage:{
  288. show:true
  289. },
  290. restore:{
  291. show:true
  292. },
  293. magicType:{
  294. type:['line','bar']
  295. },
  296. }
  297. },
  298. tooltip:{
  299. trigger:'axis',
  300. formatter: function (params,ticket,callback) {
  301. var res = params[0].data.fullName + ""+" : " + params[0].data.value
  302. + "小时";
  303. _this.params = params;
  304. return res;
  305. }
  306. },
  307. xAxis: {
  308. data: xList,
  309. axisLabel: {
  310. interval:0,rotate:20
  311. }
  312. },
  313. yAxis: [{
  314. type : 'value',
  315. axisLabel: {
  316. formatter:'{value} 小时'
  317. }
  318. }],
  319. series: [{
  320. name: '耗时(小时)',
  321. type: 'bar',
  322. barMaxWidth: 30,
  323. data: yList,
  324. }]
  325. };
  326. myChart.setOption(option,{notMerge: true});
  327. } else {
  328. this.$message({
  329. message: res.msg,
  330. type: "error"
  331. });
  332. }
  333. },
  334. error => {
  335. this.$message({
  336. message: error,
  337. type: "error"
  338. });
  339. });
  340. },
  341. getStagesPanel(){
  342. let _this = this;
  343. this.http.post('/task/getStagesPanel', {projectId: this.curProjectId},
  344. res => {
  345. if (res.code == "ok") {
  346. var list = res.data;
  347. var myChart = echarts.init(document.getElementById("stagesPanel"));
  348. _this.stagesChart = myChart;
  349. myChart.setOption({
  350. title: {
  351. show:list.length == 0,
  352. textStyle: {
  353. color: "#666666",
  354.   fontSize: 18,
  355. fontWeight: 'normal',
  356.  },
  357.   text: list.length == 0?"暂无数据":"任务列表统计",
  358.   left: "center",
  359.   top: "center"
  360. },
  361. toolbox: {
  362. show: true,
  363. feature:{
  364. saveAsImage:{
  365. show:true
  366. },
  367. }
  368. },
  369. tooltip:{
  370. trigger:'item',
  371. formatter: "{b}<br/>任务数:{c} ({d}%)",
  372. },
  373. series : [
  374. {
  375. name: '任务列表',
  376. type: 'pie',
  377. radius: '55%',
  378. data:list
  379. }
  380. ]
  381. },{notMerge: true})
  382. } else {
  383. this.$message({
  384. message: res.msg,
  385. type: "error"
  386. });
  387. }
  388. },
  389. error => {
  390. this.$message({
  391. message: error,
  392. type: "error"
  393. });
  394. });
  395. },
  396. getExecutorPanel(){
  397. let _this = this;
  398. this.http.post('/task/getExecutorPanel', {projectId: this.curProjectId},
  399. res => {
  400. if (res.code == "ok") {
  401. var xList = [], yList = [], list = res.data;
  402. for(var i in list) {
  403. xList.push(list[i].executorName);
  404. yList.push({
  405. "value": list[i].taskCount,
  406. "id": list[i].executorId
  407. });
  408. }
  409. var myChart = echarts.init(document.getElementById("executorPanel"));
  410. _this.executorChart = myChart;
  411. var option = {
  412. color: ["#409EFF","#71C671"],
  413. title: {
  414. show:list.length == 0,
  415. textStyle: {
  416. color: "#666666",
  417.   fontSize: 18,
  418. fontWeight: 'normal',
  419.  },
  420.   text: list.length == 0?"暂无数据":"执行人分配图",
  421.   left: "center",
  422.   top: "center"
  423. },
  424. toolbox: {
  425. show: true,
  426. feature:{
  427. saveAsImage:{
  428. show:true
  429. },
  430. restore:{
  431. show:true
  432. },
  433. magicType:{
  434. type:['line','bar']
  435. },
  436. }
  437. },
  438. tooltip:{
  439. trigger:'axis',
  440. formatter: function (params,ticket,callback) {
  441. var res = params[0].name + ""+" : " + params[0].data.value
  442. + "个";
  443. _this.params = params;
  444. return res;
  445. }
  446. },
  447. xAxis: {
  448. data: xList,
  449. axisLabel: {
  450. interval:0,rotate:20
  451. }
  452. },
  453. yAxis: [{
  454. type : 'value',
  455. axisLabel: {
  456. formatter:'{value} '
  457. }
  458. }],
  459. series: [{
  460. name: '任务数量(个)',
  461. type: 'bar',
  462. barMaxWidth: 30,
  463. data: yList,
  464. }]
  465. };
  466. myChart.setOption(option,{notMerge: true});
  467. } else {
  468. this.$message({
  469. message: res.msg,
  470. type: "error"
  471. });
  472. }
  473. },
  474. error => {
  475. this.$message({
  476. message: error,
  477. type: "error"
  478. });
  479. });
  480. },
  481. getProjectTaskSum() {
  482. this.http.post('/project/taskSum', {
  483. id: this.curProjectId
  484. },
  485. res => {
  486. if (res.code == "ok") {
  487. this.taskSum = res.data;
  488. } else {
  489. this.$message({
  490. message: res.msg,
  491. type: "error"
  492. });
  493. }
  494. },
  495. error => {
  496. this.$message({
  497. message: error,
  498. type: "error"
  499. });
  500. });
  501. },
  502. refreshPage() {
  503. this.curProjectId = parseInt(this.$route.params.id);
  504. this.getProjectTaskSum();
  505. this.getExecutorPanel();
  506. this.getTopCostTask();
  507. this.getStagesPanel();
  508. this.getTaskTimeCompare();
  509. }
  510. },
  511. created() {
  512. let height = window.innerHeight;
  513. this.tableHeight = height - 160;
  514. const that = this;
  515. window.onresize = function temp() {
  516. that.tableHeight = window.innerHeight - 160;
  517. };
  518. },
  519. mounted() {
  520. this.curProjectId = parseInt(this.$route.params.id);
  521. var _this = this;
  522. window.addEventListener("resize", function() {
  523. if (_this.executorChart != null) {
  524. _this.executorChart.resize();
  525. }
  526. if (_this.stagesChart != null) {
  527. _this.stagesChart.resize();
  528. }
  529. if (_this.costChart != null) {
  530. _this.costChart.resize();
  531. }
  532. if (_this.compareChart != null) {
  533. _this.compareChart.resize();
  534. }
  535. });
  536. this.getProjectTaskSum();
  537. this.getExecutorPanel();
  538. this.getStagesPanel();
  539. this.getTopCostTask();
  540. this.getTaskTimeCompare();
  541. }
  542. };
  543. </script>