detailDep.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <template>
  2. <section>
  3. <!--工具条-->
  4. <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
  5. <el-form :inline="true">
  6. <el-form-item>
  7. <el-button type="text" @click="backToList" icon="el-icon-back" class="back">返回</el-button>
  8. </el-form-item>
  9. <el-form-item class="divLine"></el-form-item>
  10. <el-form-item style="width: 500px">
  11. <!-- <div class="dipali"> -->
  12. <!-- <span class="workName">{{detailName}}</span> -->
  13. <el-cascader v-model="departmentId" placeholder="请选择部门" style="width: 180px;margin-left:10px;" @change="getList"
  14. :options="option" :props="{ checkStrictly: true }" :show-all-levels="false"></el-cascader>
  15. <!-- </div> -->
  16. </el-form-item>
  17. <el-form-item >
  18. <span style="color:#666;">时间段:{{startDate}}<span style="padding-left:5px;padding-right:5px;">至</span>{{endDate}}</span>
  19. </el-form-item>
  20. <el-form-item style="float:right;">
  21. <span style="font-size:18px;">部门成本:<span style="color:#20a0ff;">{{cost.toFixed(2)}}元</span></span>
  22. </el-form-item>
  23. </el-form>
  24. </el-col>
  25. <div id="clearfix" :style="'overflow-x: auto;width:100%;padding-bottom: 100px; position: relative; height:'+containerHeight+'px;'">
  26. <div id="container" :style="'height:' + tableHeight + 'px'"></div>
  27. </div>
  28. </section>
  29. </template>
  30. <script>
  31. import util from "../../common/js/util";
  32. export default {
  33. data() {
  34. return {
  35. yAxisValue: localStorage.yAxisValue,
  36. startDate:null,
  37. endDate: null,
  38. detailId: this.$route.params.id,
  39. detailName: this.$route.params.name,
  40. user: JSON.parse(sessionStorage.getItem("user")),
  41. cost: 0,
  42. tableHeight: 0,
  43. echart: null,
  44. option: [],
  45. departmentId: [].concat(parseInt(this.$route.params.id)),
  46. };
  47. },
  48. methods: {
  49. //返回
  50. backToList() {
  51. if (this.startDate != null) {
  52. this.$router.push("/cost?startDate="+this.startDate+"&endDate="+this.endDate);
  53. } else {
  54. this.$router.push("/cost");
  55. }
  56. },
  57. // 获取部门列表
  58. getDepartment() {
  59. this.http.post( this.port.manage.depList, {},
  60. res => {
  61. if (res.code == "ok") {
  62. var list = res.data , array = [];
  63. // for(var i in list) {
  64. // if(list[i].id == this.detailId) {
  65. // array.push(list[i])
  66. // }
  67. // }
  68. this.option = this.changeArr(list);
  69. } else {
  70. this.$message({
  71. message: res.msg,
  72. type: "error"
  73. });
  74. }
  75. },
  76. error => {
  77. this.$message({
  78. message: error,
  79. type: "error"
  80. });
  81. });
  82. },
  83. // 修改数组
  84. changeArr(arr) {
  85. for (var i = 0; i < arr.length; i++) {
  86. if(arr[i].id != -1 && arr[i].id != 0) {
  87. if (arr[i].children != null && arr[i].children.length>0) {
  88. arr[i].children = this.changeArr(arr[i].children);
  89. }
  90. arr[i].id && (arr[i].value = arr[i].id);
  91. delete arr[i].id;
  92. }
  93. }
  94. for(var i in arr) {
  95. if(arr[i].id == -1 || arr[i].id == 0) {
  96. arr.splice(i,1)
  97. }
  98. }
  99. return arr;
  100. },
  101. //获取部门人员工时统计
  102. getList() {
  103. this.listLoading = true;
  104. this.http.post(this.port.project.userCost, {
  105. departmentId: this.departmentId[this.departmentId.length-1],
  106. startDate: this.startDate,
  107. endDate: this.endDate,
  108. },
  109. res => {
  110. this.listLoading = false;
  111. var _this = this;
  112. if (res.code == "ok") {
  113. //
  114. for(var i in res.data.list) {
  115. if(i>20) {
  116. this.widthHtval = +this.widthHtval + 40
  117. } else {
  118. this.widthHtval = document.body.clientWidth - 230
  119. }
  120. }
  121. //
  122. var xList = [] , yList = [] , list = res.data.list, array = [] , series = [];
  123. if (list.length > 0) {
  124. this.cost = res.data.totalCostMoney;
  125. for(var i in list) {
  126. xList.push(list[i].name);
  127. var pro = list[i].project;
  128. for(var j in pro) {
  129. if(array.indexOf(pro[j].project) == -1) {
  130. array.push(pro[j].project)
  131. }
  132. }
  133. }
  134. for(var i in array) {
  135. yList.push(array[i]);
  136. var dataList = [];
  137. for(var j in list) {
  138. var curUser = list[j];
  139. var project = list[j].project;
  140. if(project.length != 0) {
  141. //找到当前用户对应的项目
  142. var findProject = project.filter(p=>p.project == array[i]);
  143. if (findProject.length > 0) {
  144. dataList.push({
  145. "value": this.yAxisValue==0?findProject[0].money:findProject[0].time,
  146. "cost": findProject[0].time,
  147. "money": findProject[0].money
  148. })
  149. } else {
  150. dataList.push({
  151. "value": 0,
  152. "cost": 0,
  153. "money": 0,
  154. })
  155. }
  156. } else {
  157. dataList.push({
  158. "value": 0,
  159. "cost": 0,
  160. "money": 0
  161. })
  162. }
  163. }
  164. series.push({
  165. name: array[i],
  166. type: 'bar',
  167. stack:'1',
  168. barMaxWidth: 30,
  169. data: dataList,
  170. })
  171. }
  172. var myChart = echarts.init(document.getElementById("container"));
  173. // 设置宽度
  174. myChart.resize({
  175. width: this.widthHtval
  176. })
  177. _this.myChart = myChart;
  178. var option = {
  179. // 工具箱
  180. legend: {
  181. x: 80,
  182. y: 10,
  183. data: yList
  184. },
  185. grid : {
  186. top : 80, //距离容器上边界40像素
  187. bottom: 35, //距离容器下边界30像素
  188. left: 150,
  189. right: 150
  190. },
  191. toolbox: {
  192. show: true,
  193. feature:{
  194. saveAsImage:{
  195. show:true
  196. },
  197. restore:{
  198. show:true
  199. },
  200. dataView:{
  201. show:true
  202. },
  203. dataZoom:{
  204. show:true
  205. },
  206. magicType:{
  207. type:['line','bar']
  208. }
  209. }
  210. },
  211. tooltip:{
  212. trigger:'axis',
  213. formatter: function (params,ticket,callback) {
  214. var totalTime = 0.0;
  215. for(var i in params) {
  216. totalTime += parseFloat(params[i].data.cost)
  217. }
  218. var res = params[0].name + " 工时 : " + totalTime.toFixed(1)+"小时<br/>";
  219. for(var i in params) {
  220. if (params[i].data.value > 0) {
  221. res += "<div style='margin-top:3px;font-size:12px;'><font color='#ddd'>项目名称:" + params[i].seriesName
  222. + "</font><br/>工作成本 : " + params[i].data.money
  223. + "元 <br/>工作时长"+" : " + params[i].data.cost + "小时</br></div>";
  224. }
  225. }
  226. return res;
  227. }
  228. },
  229. xAxis: {
  230. data: xList,
  231. axisLabel: {
  232. interval:0,rotate:20
  233. }
  234. },
  235. yAxis: [{
  236. type : 'value',
  237. axisLabel: {
  238. formatter:this.yAxisValue==0?'{value} (元)':'{value}(小时)'
  239. }
  240. }],
  241. series: series,
  242. };
  243. myChart.setOption(option, {notMerge: true});
  244. } else {
  245. this.$message({
  246. message: "暂无数据",
  247. type: "error"
  248. });
  249. }
  250. } else {
  251. this.$message({
  252. message: res.msg,
  253. type: "error"
  254. });
  255. }
  256. },
  257. error => {
  258. this.listLoading = false;
  259. this.$message({
  260. message: error,
  261. type: "error"
  262. });
  263. });
  264. },
  265. // 左右滚动
  266. scrollFunction () {
  267. this.domObj = document.getElementById('clearfix') // 通过id获取要设置的div
  268. if (this.domObj.attachEvent) { // IE
  269. this.domObj.attachEvent('onmousewheel', this.mouseScroll)
  270. } else if (this.domObj.addEventListener) {
  271. this.domObj.addEventListener('DOMMouseScroll', this.mouseScroll, false)
  272. }
  273. this.domObj.onmousewheel = this.domObj.onmousewheel = this.mouseScroll
  274. },
  275. mouseScroll(event) { // google 浏览器下
  276. let detail = event.wheelDelta || event.detail
  277. let moveForwardStep = -1
  278. let moveBackStep = 1
  279. let step = 0
  280. step = detail > 0 ? moveForwardStep * 100 : moveBackStep * 100
  281. event.preventDefault() // 阻止浏览器默认事件
  282. this.domObj.scrollLeft = this.domObj.scrollLeft + step
  283. },
  284. },
  285. created() {
  286. let height = window.innerHeight;
  287. this.tableHeight = height - 145;
  288. const that = this;
  289. window.onresize = function temp() {
  290. that.tableHeight = window.innerHeight - 145;
  291. };
  292. },
  293. mounted() {
  294. this.startDate = this.$route.query.startDate;
  295. this.endDate = this.$route.query.endDate;
  296. this.getDepartment();
  297. this.getList();
  298. var _this = this;
  299. window.addEventListener("resize", function() {
  300. _this.myChart.resize();
  301. });
  302. this.scrollFunction()
  303. }
  304. };
  305. </script>
  306. <style lang="scss" scoped>
  307. .toolbar {
  308. .el-form-item {
  309. font-size: 14px;
  310. vertical-align: middle;
  311. }
  312. .back {
  313. font-size: 16px;
  314. cursor: pointer;
  315. }
  316. .divLine {
  317. width: 2px;
  318. background: #c3c3c3;
  319. height: 100%;
  320. }
  321. .workName {
  322. color: #333;
  323. font-size: 18px;
  324. }
  325. .workHours {
  326. color: #20a0ff;
  327. font-size: 18px;
  328. }
  329. }
  330. #container {
  331. float: left;
  332. width: 100%;
  333. }
  334. .dipali {
  335. display: flex;
  336. width: 100%;
  337. }
  338. </style>
  339. <style lang="scss">
  340. </style>