cost.vue 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. <template>
  2. <section>
  3. <el-row style="padding-bottom: 0px;text-align:center;margin-top:20px;z-index: 999;">
  4. <el-col :span="6" >
  5. <div ><span style="color:#999;">图表Y轴: </span>
  6. <el-radio-group v-model="yAxisValue" @change="onYAxisChange">
  7. <el-radio-button label="0">显示成本</el-radio-button>
  8. <el-radio-button label="1">显示工时</el-radio-button>
  9. </el-radio-group></div>
  10. </el-col>
  11. <el-col :span="14" style="display: flex;flex-wrap: wrap;">
  12. <div style="width:100%;display:flex">
  13. <el-date-picker v-show="user.timeType.fixMonthcost==0"
  14. v-model="dateRange" :editable="false"
  15. format="yyyy-MM-dd" value-format="yyyy-MM-dd"
  16. @change="getEchart"
  17. :clearable="true"
  18. range-separator="至"
  19. type="daterange"
  20. start-placeholder="开始日期"
  21. end-placeholder="结束日期"
  22. ></el-date-picker>
  23. <el-date-picker v-show="user.timeType.fixMonthcost==1"
  24. v-model="dateRange" :editable="false"
  25. format="yyyy-MM" value-format="yyyy-MM"
  26. @change="getEchart"
  27. :clearable="false"
  28. type="month"
  29. ></el-date-picker>
  30. <el-radio-group v-model="radio" @change="getEchart" style="margin-left:10px;">
  31. <el-radio-button label="项目"></el-radio-button>
  32. <el-radio-button label="部门"></el-radio-button>
  33. <el-radio-button label="人员"></el-radio-button>
  34. <el-radio-button :label="namess" v-if="jichu.customDegreeActive == 1"></el-radio-button>
  35. </el-radio-group>
  36. </div>
  37. <div style="width:100%;display:flex">
  38. <el-select v-model="personnelValue" filterable clearable placeholder="请选择人员" style="margin-top: 10px;width: 350px" v-if="radio == '人员'" @change="personnel()">
  39. <el-option v-for="item in hasReportUserList" :key="item.id" :label="item.name" :value="item.name"></el-option>
  40. </el-select>
  41. </div>
  42. </el-col>
  43. <el-col :span="4">
  44. <el-button @click="showExportDialog">报表导出</el-button>
  45. </el-col>
  46. </el-row>
  47. <!-- <div id="clearfix" :style="'width:'+widthHtval+'px;position: relative; height:'+containerHeight+'px;'">
  48. <div id="container" :style="'height:'+containerHeight+'px;width:100%'"></div>
  49. </div> -->
  50. <div id="clearfix" :class="radio == '人员' ? 'ryuans' : ''" :style="'overflow-x: auto;width:100%;padding-bottom: 100px; position: relative; height:'+containerHeight+'px;'">
  51. <div id="container" :style="'height:'+containerHeight+'px;width:100%'"></div>
  52. </div>
  53. <!-- <div>
  54. <div id="container" :style="'height:'+containerHeight+'px;width:100%'"></div>
  55. </div> -->
  56. <div style="position:fixed;top:170px;left:600px;" v-show="radio=='部门' && parentDeptId != null">
  57. <el-button @click="backToParentDept">返回上级</el-button>
  58. </div>
  59. <!--导出报表条件选择 -->
  60. <el-dialog title="工时报表导出" v-if="exportDialog" :visible.sync="exportDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  61. <el-form ref="form3" :model="exportParam" >
  62. <el-form-item prop="projectId" label="选择项目" v-if="radio != '人员'">
  63. <el-select v-model="exportParam.projectId" placeholder="全部项目" clearable style="width:350px;" filterable="true">
  64. <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id"></el-option>
  65. </el-select>
  66. </el-form-item>
  67. <el-form-item prop="userIds" label="选择人员" v-if="radio == '人员'">
  68. <el-select v-model="exportParam.userIds" placeholder="全部人员" multiple="true" clearable style="width:350px;" filterable="true">
  69. <el-option v-for="item in hasReportUserList" :key="item.id" :label="item.name" :value="item.id"></el-option>
  70. </el-select>
  71. </el-form-item>
  72. <el-form-item prop="projectId" :label="user.timeType.fixMonthcost==0?'日期范围':'选择月份'">
  73. <el-date-picker v-show="user.timeType.fixMonthcost==0"
  74. v-model="exportParam.dateRange" :editable="false"
  75. format="yyyy-MM-dd" value-format="yyyy-MM-dd"
  76. :clearable="false"
  77. range-separator="至"
  78. type="daterange"
  79. start-placeholder="开始日期"
  80. end-placeholder="结束日期"
  81. ></el-date-picker>
  82. <el-date-picker v-show="user.timeType.fixMonthcost==1"
  83. v-model="dateRange" :editable="false"
  84. format="yyyy-MM" value-format="yyyy-MM"
  85. @change="getEchart"
  86. :clearable="true"
  87. type="month"
  88. ></el-date-picker>
  89. </el-form-item>
  90. <el-form-item label="选择人员" v-if="radio == '项目' || radio == '部门'">
  91. <el-select v-model="exportParam.userId" placeholder="请选择人员" style="width: 350px" filterable="true" clearable="true">
  92. <span v-for="(item, index) in users" :key="index">
  93. <el-option :label="item.name" :value="item.id"></el-option>
  94. </span>
  95. </el-select>
  96. </el-form-item>
  97. <el-form-item v-if="radio == '项目' || radio == '部门'">
  98. <el-checkbox v-model="exportParam.projectSum" >含单个项目数据汇总</el-checkbox>
  99. </el-form-item>
  100. </el-form>
  101. <div slot="footer" class="dialog-footer">
  102. <el-button type="primary" @click="exportProjectData" style="width:100%;" >导出</el-button>
  103. </div>
  104. </el-dialog>
  105. </section>
  106. </template>
  107. <script>
  108. import util from "../../common/js/util";
  109. export default {
  110. data() {
  111. return {
  112. personnelValue: '',
  113. personnelAll: [],
  114. yAxisValue: localStorage.yAxisValue?localStorage.yAxisValue:0,
  115. parentDeptStack:[],
  116. parentDeptId:null,
  117. hasReportUserList:[],
  118. projectList:[],
  119. exportParam:{projectId:null,dateRange:[],userId: null},
  120. exportDialog:false,
  121. dateRange:[],
  122. user: JSON.parse(sessionStorage.getItem("user")),
  123. radio: sessionStorage.radio!=null?sessionStorage.radio:'项目',
  124. containerHeight: 0,
  125. myChart: null,
  126. params: null,
  127. widthHtval: document.body.clientWidth - 230,
  128. users: [],
  129. jichu: [],
  130. namess: '',
  131. timers: null, // 点击的时间
  132. zhishin: 0
  133. };
  134. },
  135. methods: {
  136. //Y轴点击改变显示的数据
  137. onYAxisChange() {
  138. localStorage.yAxisValue = this.yAxisValue;
  139. this.jieliu();
  140. },
  141. jutishez() {
  142. this.http.post('/time-type/getCompanyTimeSetting', {
  143. companyId: this.user.companyId,
  144. },
  145. res => {
  146. if (res.code == "ok") {
  147. this.jichu = res.data
  148. if(res.data.customDegreeActive == 1) {
  149. this.namess = res.data.customDegreeName
  150. }
  151. } else {
  152. this.$message({
  153. message: res.msg,
  154. type: "error"
  155. });
  156. }
  157. },
  158. error => {
  159. this.$message({
  160. message: error,
  161. type: "error"
  162. });
  163. });
  164. },
  165. getUsers() {
  166. console.log(this.port.manage.list)
  167. this.http.post(this.port.manage.list, {
  168. departmentId: -1,
  169. pageIndex: 1,
  170. pageSize: 99999
  171. },
  172. res => {
  173. if (res.code == "ok") {
  174. this.users = res.data.records;
  175. } else {
  176. this.$message({
  177. message: res.msg,
  178. type: "error"
  179. });
  180. }
  181. },
  182. error => {
  183. this.$message({
  184. message: error,
  185. type: "error"
  186. });
  187. });
  188. },
  189. showExportDialog() {
  190. console.log(12345)
  191. this.exportDialog = true;
  192. this.exportParam.dateRange = this.dateRange;
  193. console.log(this.hasReportUserList)
  194. if (this.radio == '人员') {
  195. // this.exportParam.userIds = [];
  196. }
  197. },
  198. //获取我的项目列表
  199. getMyProjectList() {
  200. this.http.post('/project/getProjectList', {
  201. },
  202. res => {
  203. if (res.code == "ok") {
  204. this.projectList = res.data;
  205. } else {
  206. this.$message({
  207. message: res.msg,
  208. type: "error"
  209. });
  210. }
  211. },
  212. error => {
  213. this.$message({
  214. message: error,
  215. type: "error"
  216. });
  217. });
  218. },
  219. exportProjectData() {
  220. var param = {};
  221. if (this.exportParam.dateRange != null) {
  222. param = {startDate:this.exportParam.dateRange[0], endDate: this.exportParam.dateRange[1]};
  223. }
  224. var url = "/project/exportTimeCost";
  225. var fileName = '项目工时成本统计.xls';
  226. if (this.radio == '人员' ) {
  227. console.log(this.exportParam.userIds);
  228. fileName = '人员工时成本统计.xls';
  229. url = '/department/exportUserStatistic';
  230. if (this.exportParam.userIds != null && this.exportParam.userIds.length > 0) {
  231. var ids = '';
  232. this.exportParam.userIds.forEach(u=>{
  233. ids += u+',';
  234. })
  235. param.userIds = ids;
  236. }
  237. }
  238. if (this.exportParam.projectId) {
  239. param.projectId = this.exportParam.projectId;
  240. }
  241. if (this.exportParam.userId) {
  242. if(this.radio == '项目' || this.radio == '部门' || this.radio == '人员'){
  243. param.userId = this.exportParam.userId;
  244. }
  245. }
  246. if (this.exportParam.projectSum != null) {
  247. if(this.radio == '项目' || this.radio == '部门'){
  248. param.projectSum = this.exportParam.projectSum;
  249. }
  250. }
  251. this.http.post(url, param,
  252. res => {
  253. this.listLoading = false;
  254. if (res.code == "ok") {
  255. this.exportDialog = false;
  256. var aTag = document.createElement('a');
  257. aTag.download = fileName;
  258. aTag.href = res.data;
  259. aTag.click();
  260. } else {
  261. this.$message({
  262. message: res.msg,
  263. type: "error"
  264. });
  265. }
  266. },
  267. error => {
  268. this.listLoading = false;
  269. this.$message({
  270. message: error,
  271. type: "error"
  272. });
  273. });
  274. },
  275. // 人员筛选
  276. personnel() {
  277. if(this.personnelValue) {
  278. var arrlist = JSON.parse(JSON.stringify(this.personnelAll))
  279. var arr = []
  280. for(var i in arrlist.list) {
  281. if(arrlist.list[i].name == this.personnelValue) {
  282. arr.push(arrlist.list[i])
  283. }
  284. }
  285. arrlist.list = arr
  286. this.gtff(arrlist)
  287. } else {
  288. this.gtff(this.personnelAll)
  289. }
  290. },
  291. //获取人员成本统计列表
  292. getUserCostList() {
  293. this.listLoading = true;
  294. console.log(this.port.project.userCost, '获取人员成本统计列表')
  295. this.http.post(this.port.project.userCost, {
  296. startDate:this.user.timeType.fixMonthcost==0?this.dateRange[0]:this.dateRange,
  297. endDate: this.user.timeType.fixMonthcost==0?this.dateRange[1]:this.dateRange
  298. },
  299. res => {
  300. this.listLoading = false;
  301. var _this = this;
  302. this.hasReportUserList = [];
  303. if (res.code == "ok") {
  304. //
  305. // var sss = []
  306. // var ddd = []
  307. // for(var i = 0; i < 120; i++) {
  308. // sss.push(res.data.list[0])
  309. // ddd.push(res.data.userList[0])
  310. // }
  311. // res.data.list = sss
  312. // res.data.userList = ddd
  313. for(var i in res.data.list) {
  314. if(i>20) {
  315. // this.widthHtval = +this.widthHtval + 2
  316. this.widthHtval = +this.widthHtval + 40
  317. } else {
  318. this.widthHtval = document.body.clientWidth - 230
  319. }
  320. }
  321. //
  322. this.personnelAll = res.data
  323. this.gtff(res.data)
  324. //工时总成本
  325. // this.hasReportUserList = res.data.userList;
  326. // var xList = [] yList = [] , list = res.data.list, array = [] , series = [];
  327. // var totalMoneyCost = res.data.totalCostMoney;
  328. // var totalHours = 0.0;
  329. // if (list.length > 0) {
  330. // var num = list.length==0?0:list[0].project.length;
  331. // for(var i in list) {
  332. // xList.push(list[i].name);
  333. // var pro = list[i].project;
  334. // for(var j in pro) {
  335. // if(array.indexOf(pro[j].project) == -1) {
  336. // array.push(pro[j].project)
  337. // }
  338. // }
  339. // }
  340. // for(var i in array) {
  341. // yList.push(array[i]);
  342. // var dataList = [];
  343. // for(var j in list) {
  344. // var project = list[j].project , num = 0;
  345. // if(project.length != 0) {
  346. // for(var k in project) {
  347. // if(project[k].project == array[i]) {
  348. // dataList.push({
  349. // "value": this.yAxisValue==0?project[k].money:project[k].time,
  350. // "cost": project[k].time,
  351. // "money":project[k].money
  352. // })
  353. // totalHours += parseFloat(project[k].time);
  354. // } else {
  355. // num++;
  356. // }
  357. // if(k == project.length-1 && num != project.length-1) {
  358. // dataList.push({
  359. // "value": 0,
  360. // "cost": 0,
  361. // "money":0,
  362. // })
  363. // }
  364. // }
  365. // } else {
  366. // dataList.push({
  367. // "value": 0,
  368. // "cost": 0,
  369. // "money":0,
  370. // })
  371. // }
  372. // }
  373. // series.push({
  374. // name: array[i],
  375. // type: 'bar',
  376. // stack:'1',
  377. // barMaxWidth: 30,
  378. // data: dataList,
  379. // })
  380. // }
  381. // }
  382. // var myChart = echarts.init(document.getElementById("container"));
  383. // totalHours = totalHours.toFixed(1);
  384. // // 设置宽度
  385. // myChart.resize({
  386. // width: this.widthHtval
  387. // })
  388. // // 设置宽度
  389. // _this.myChart = myChart;
  390. // var option = {
  391. // //总成本
  392. // title: {
  393. // text: '工时成本总计' + totalMoneyCost.toFixed(2) + '元, 时长'+totalHours+'小时',
  394. // left:'left',
  395. // },
  396. // // 工具箱
  397. // legend: {
  398. // x: 80,
  399. // y: 10,
  400. // data: yList,
  401. // show: true,
  402. //        top:"5%",//与上方的距离 可百分比% 可像素px
  403. // },
  404. // grid : {
  405. // top : 80, //距离容器上边界40像素
  406. // // bottom: 100, //距离容器下边界30像素
  407. // bottom: 35, //距离容器下边界30像素
  408. // left: 150,
  409. // right: 150
  410. // },
  411. // toolbox: {
  412. // show: true,
  413. // feature:{
  414. // saveAsImage:{
  415. // show:true
  416. // },
  417. // restore:{
  418. // show:true
  419. // },
  420. // // dataView:{
  421. // // show:true
  422. // // },
  423. // // dataZoom:{
  424. // // show:true
  425. // // },
  426. // magicType:{
  427. // type:['line','bar']
  428. // }
  429. // }
  430. // },
  431. // tooltip:{
  432. // trigger:'axis',
  433. // formatter: function (params,ticket,callback) {
  434. // var totalTime = 0;
  435. // var totalCost = 0;
  436. // var res = "";
  437. // for(var i in params) {
  438. // if (params[i].data.value > 0) {
  439. // res += "<div style='margin-top:3px;font-size:12px;'><font color='#ddd'>项目名称:" + params[i].seriesName
  440. // + "</font><br/>工作成本 : " + params[i].data.money
  441. // + "元 <br/>工作时长"+" : " + params[i].data.cost + "小时</br></div>";
  442. // totalTime += Number(params[i].data.cost);
  443. // totalCost += Number(params[i].data.money);
  444. // }
  445. // }
  446. // res = res +'<br/>'+ params[0].name+ '<br/>总计: ' + totalTime.toFixed(1)+'小时 '+totalCost.toFixed(2) + "元<br/>";
  447. // return res;
  448. // }
  449. // },
  450. // xAxis: {
  451. // data: xList,
  452. // axisLabel: {
  453. // interval:0,rotate:20
  454. // }
  455. // },
  456. // yAxis: [{
  457. // type : 'value',
  458. // axisLabel: {
  459. // formatter:this.yAxisValue==0?'{value} (元)':'{value} (小时)'
  460. // }
  461. // }],
  462. // series: series,
  463. // };
  464. // myChart.setOption(option,{notMerge:true});
  465. } else {
  466. this.$message({
  467. message: res.msg,
  468. type: "error"
  469. });
  470. }
  471. },
  472. error => {
  473. this.listLoading = false;
  474. this.$message({
  475. message: error,
  476. type: "error"
  477. });
  478. });
  479. },
  480. // 共同方法
  481. gtff(data) {
  482. var _this = this;
  483. this.hasReportUserList = data.userList;
  484. var xList = [] , yList = [] , list = data.list, array = [] , series = [];
  485. var totalMoneyCost = data.totalCostMoney;
  486. var totalHours = 0.0;
  487. if (list.length > 0) {
  488. var num = list.length==0?0:list[0].project.length;
  489. for(var i in list) {
  490. xList.push(list[i].name);
  491. var pro = list[i].project;
  492. for(var j in pro) {
  493. if(array.indexOf(pro[j].project) == -1) {
  494. array.push(pro[j].project)
  495. }
  496. }
  497. }
  498. for(var i in array) {
  499. yList.push(array[i]);
  500. var dataList = [];
  501. for(var j in list) {
  502. var project = list[j].project , num = 0;
  503. if(project.length != 0) {
  504. for(var k in project) {
  505. if(project[k].project == array[i]) {
  506. dataList.push({
  507. "value": this.yAxisValue==0?project[k].money:project[k].time,
  508. "cost": project[k].time,
  509. "money":project[k].money
  510. })
  511. totalHours += parseFloat(project[k].time);
  512. } else {
  513. num++;
  514. }
  515. if(k == project.length-1 && num != project.length-1) {
  516. dataList.push({
  517. "value": 0,
  518. "cost": 0,
  519. "money":0,
  520. })
  521. }
  522. }
  523. } else {
  524. dataList.push({
  525. "value": 0,
  526. "cost": 0,
  527. "money":0,
  528. })
  529. }
  530. }
  531. series.push({
  532. name: array[i],
  533. type: 'bar',
  534. stack:'1',
  535. barMaxWidth: 30,
  536. data: dataList,
  537. })
  538. }
  539. }
  540. var myChart = echarts.init(document.getElementById("container"));
  541. totalHours = totalHours.toFixed(1);
  542. // 设置宽度
  543. myChart.resize({
  544. width: this.widthHtval
  545. })
  546. // 设置宽度
  547. _this.myChart = myChart;
  548. var option = {
  549. //总成本
  550. title: {
  551. text: '工时成本总计' + totalMoneyCost.toFixed(2) + '元, 时长'+totalHours+'小时',
  552. left:'left',
  553. },
  554. // 工具箱
  555. legend: {
  556. x: 80,
  557. y: 10,
  558. data: yList,
  559. show: true,
  560.       top:"5%",//与上方的距离 可百分比% 可像素px
  561. },
  562. grid : {
  563. top : 80, //距离容器上边界40像素
  564. // bottom: 100, //距离容器下边界30像素
  565. bottom: 35, //距离容器下边界30像素
  566. left: 150,
  567. right: 150
  568. },
  569. toolbox: {
  570. show: true,
  571. feature:{
  572. saveAsImage:{
  573. show:true
  574. },
  575. restore:{
  576. show:true
  577. },
  578. // dataView:{
  579. // show:true
  580. // },
  581. // dataZoom:{
  582. // show:true
  583. // },
  584. magicType:{
  585. type:['line','bar']
  586. }
  587. }
  588. },
  589. tooltip:{
  590. trigger:'axis',
  591. formatter: function (params,ticket,callback) {
  592. var totalTime = 0;
  593. var totalCost = 0;
  594. var res = "";
  595. for(var i in params) {
  596. if (params[i].data.value > 0) {
  597. res += "<div style='margin-top:3px;font-size:12px;'><font color='#ddd'>项目名称:" + params[i].seriesName
  598. + "</font><br/>工作成本 : " + params[i].data.money
  599. + "元 <br/>工作时长"+" : " + params[i].data.cost + "小时</br></div>";
  600. totalTime += Number(params[i].data.cost);
  601. totalCost += Number(params[i].data.money);
  602. }
  603. }
  604. res = res +'<br/>'+ params[0].name+ '<br/>总计: ' + totalTime.toFixed(1)+'小时 '+totalCost.toFixed(2) + "元<br/>";
  605. return res;
  606. }
  607. },
  608. xAxis: {
  609. data: xList,
  610. axisLabel: {
  611. interval:0,rotate:20
  612. }
  613. },
  614. yAxis: [{
  615. type : 'value',
  616. axisLabel: {
  617. formatter:this.yAxisValue==0?'{value} (元)':'{value} (小时)'
  618. }
  619. }],
  620. series: series,
  621. };
  622. myChart.setOption(option,{notMerge:true});
  623. },
  624. yanjiu() {
  625. console.log('触发')
  626. },
  627. getEchart(){
  628. var that = this
  629. // that.timers = setTimeout(()=>{
  630. // clearTimeout(that.timers)
  631. // console.log(that.timers)
  632. that.jieliu()
  633. // },100);
  634. // this.jieliu()
  635. },
  636. backToParentDept() {
  637. if (this.radio == '部门') {
  638. if (this.parentDeptStack.length > 0) {
  639. this.parentDeptStack.pop();
  640. if (this.parentDeptStack.length > 0) {
  641. this.parentDeptId = this.parentDeptStack[this.parentDeptStack.length -1];
  642. } else {
  643. this.parentDeptId = null;
  644. }
  645. this.jieliu();
  646. }
  647. }
  648. },
  649. // 脱离出来的方法
  650. jieliu() {
  651. sessionStorage.radio = this.radio;
  652. var _this = this;
  653. var param = {};
  654. if (this.dateRange != null) {
  655. param = {startDate:this.user.timeType.fixMonthcost==0?this.dateRange[0]:this.dateRange,
  656. endDate: this.user.timeType.fixMonthcost==0?this.dateRange[1]:this.dateRange};
  657. console.log(param);
  658. }
  659. var url = '';
  660. if (this.radio=='项目') {
  661. url = this.port.project.listCost;
  662. } else if (this.radio=='部门') {
  663. url = this.port.project.depCost;
  664. param.parentDeptId = this.parentDeptId;
  665. } else if (this.radio=='人员') {
  666. this.getUserCostList();
  667. return;
  668. } else if (this.radio == this.namess) {
  669. url = '/project/getDegreeCost'
  670. }
  671. this.http.post(url, param,
  672. res => {
  673. if (res.code == "ok") {
  674. for(var i in res.data.costList) {
  675. if(i>20) {
  676. // this.widthHtval = +this.widthHtval + 2
  677. this.widthHtval = +this.widthHtval + 40
  678. } else {
  679. this.widthHtval = document.body.clientWidth - 230
  680. }
  681. }
  682. // 测试写的
  683. var xList = []
  684. var yList = []
  685. var list
  686. var totalMoneyCost;
  687. var totalHours = 0.0;
  688. if(this.radio == '项目' || this.radio=='部门') {
  689. list = res.data.costList
  690. totalMoneyCost = ((this.radio=='项目')?res.data.totalMoneyCost:res.data.totalCostMoney);
  691. for(var i in list) {
  692. if(this.radio=='项目') {
  693. xList.push(this.radio=='项目'?list[i].project:list[i].name);
  694. yList.push({
  695. "value": this.yAxisValue==0?list[i].costMoney.toFixed(2) || list[i].costMoney:list[i].cost.toFixed(1),
  696. "id": list[i].id || i,
  697. "cost": list[i].cost,
  698. "money":list[i].costMoney.toFixed(2)
  699. });
  700. totalHours += parseFloat(list[i].cost);
  701. } else {
  702. xList.push(list[i].departmentName);
  703. yList.push({
  704. "value": this.yAxisValue==0? list[i].costMoney.toFixed(2) || list[i].costMoney: list[i].costTime.toFixed(1),
  705. "id": list[i].departmentId,
  706. "cost": list[i].costTime,
  707. "hasSubDept": list[i].hasSubDept,
  708. "money":list[i].costMoney.toFixed(2)
  709. });
  710. totalHours += parseFloat(list[i].costTime);
  711. }
  712. }
  713. } else {
  714. list = res.data
  715. var totalMoneyCost = 0;
  716. for(var i in list) {
  717. console.log(list[i].name, list[i].costMoney, list[i].cost)
  718. xList.push(list[i].name);
  719. yList.push({
  720. "value": this.yAxisValue==0?list[i].costMoney:list[i].cost,
  721. "id": list[i].id || i,
  722. "cost": list[i].cost,
  723. "money":list[i].costMoney.toFixed(2)
  724. });
  725. totalHours += parseFloat(list[i].cost);
  726. totalMoneyCost += parseFloat(list[i].costMoney);
  727. }
  728. }
  729. totalHours = totalHours.toFixed(1);
  730. var myChart = echarts.init(document.getElementById("container"));
  731. myChart.resize({
  732. width: this.widthHtval
  733. })
  734. _this.myChart = myChart;
  735. // console.log(totalMoneyCost.toFixed(2), '看看', totalMoneyCost)
  736. // var chengbentongji = totalMoneyCost.toFixed(2) || totalMoneyCost
  737. if(totalMoneyCost) {
  738. this.zhishin = totalMoneyCost.toFixed(2)
  739. }
  740. if(this.radio == '项目' || this.radio == '人员' || this.radio=='部门') {
  741. var option = {
  742. title: {
  743. text: '工时成本总计' + this.zhishin + '元, 时长'+totalHours+'小时',
  744. left:'left',
  745. },
  746. // 工具箱
  747. toolbox: {
  748. show: true,
  749. feature:{
  750. saveAsImage:{show:true},restore:{show:true}, magicType:{ type:['line','bar']},
  751. }
  752. },
  753. tooltip:{
  754. trigger:'axis',
  755. formatter: function (params,ticket,callback) {
  756. var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.money
  757. + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
  758. _this.params = params;
  759. return res;
  760. }
  761. },
  762. xAxis: {
  763. data: xList,
  764. axisLabel: {
  765. interval:0,rotate:20
  766. }
  767. },
  768. yAxis: [{
  769. type : 'value',
  770. axisLabel: {
  771. formatter:this.yAxisValue==0?'{value} (元)':'{value}小时'
  772. }
  773. }],
  774. series: [{
  775. name: this.yAxisValue==0?'工作成本(元)':'工作时长(小时)',
  776. type: 'bar',
  777. barMaxWidth: 30,
  778. data: yList,
  779. }]
  780. };
  781. } else {
  782. var option = {
  783. title: {
  784. text: '工时成本总计' + this.zhishin + '元, 时长'+totalHours+'小时',
  785. left:'left',
  786. },
  787. // 工具箱
  788. toolbox: {
  789. show: true,
  790. feature:{
  791. saveAsImage:{show:true},restore:{show:true}, magicType:{ type:['line','bar']},
  792. }
  793. },
  794. tooltip:{
  795. trigger:'axis',
  796. formatter: function (params,ticket,callback) {
  797. var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.money
  798. + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
  799. _this.params = params;
  800. return res;
  801. }
  802. },
  803. xAxis: {
  804. data: xList,
  805. axisLabel: {
  806. interval:0,rotate:20
  807. }
  808. },
  809. yAxis: [{
  810. type : 'value',
  811. axisLabel: {
  812. formatter:this.yAxisValue==0?'{value} (元)':'{value}小时'
  813. }
  814. }],
  815. series: [{
  816. name: this.yAxisValue==0?'工作成本(元)':'工作时长(小时)',
  817. type: 'bar',
  818. barMaxWidth: 30,
  819. data: yList,
  820. }]
  821. };
  822. }
  823. myChart.setOption(option,{notMerge: true});
  824. myChart.getZr().on('click', params => {
  825. const pointInPixel = [params.offsetX, params.offsetY];
  826. if (myChart.containPixel('grid', pointInPixel)) {
  827. console.log(_this.params)
  828. if(_this.radio=='项目') {
  829. if (_this.dateRange != null) {
  830. if (this.user.timeType.fixMonthcost == 0) {
  831. _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name
  832. +"?startDate="+_this.dateRange[0]+"&endDate="+_this.dateRange[1]);
  833. } else {
  834. _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name
  835. +"?startDate="+_this.dateRange+"&endDate="+_this.dateRange);
  836. }
  837. } else {
  838. _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name);
  839. }
  840. } else if (_this.radio=='部门') {
  841. if (_this.params[0].data.hasSubDept) {
  842. if (_this.parentDeptId != _this.params[0].data.id) {
  843. _this.parentDeptId = _this.params[0].data.id;
  844. _this.parentDeptStack.push(_this.parentDeptId);
  845. _this.jieliu();
  846. }
  847. // _this.jieliu();
  848. } else {
  849. if (_this.dateRange != null) {
  850. _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name
  851. +"?startDate="+_this.dateRange[0]+"&endDate="+_this.dateRange[1]);
  852. } else {
  853. _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name);
  854. }
  855. }
  856. }
  857. }
  858. });
  859. } else {
  860. this.$message({
  861. message: res.msg,
  862. type: "error"
  863. });
  864. }
  865. },
  866. error => {
  867. this.$message({
  868. message: error,
  869. type: "error"
  870. });
  871. });
  872. },
  873. // 左右滚动
  874. scrollFunction () {
  875. this.domObj = document.getElementById('clearfix') // 通过id获取要设置的div
  876. if (this.domObj.attachEvent) { // IE
  877. this.domObj.attachEvent('onmousewheel', this.mouseScroll)
  878. } else if (this.domObj.addEventListener) {
  879. this.domObj.addEventListener('DOMMouseScroll', this.mouseScroll, false)
  880. }
  881. this.domObj.onmousewheel = this.domObj.onmousewheel = this.mouseScroll
  882. },
  883. mouseScroll(event) { // google 浏览器下
  884. let detail = event.wheelDelta || event.detail
  885. let moveForwardStep = -1
  886. let moveBackStep = 1
  887. let step = 0
  888. step = detail > 0 ? moveForwardStep * 100 : moveBackStep * 100
  889. event.preventDefault() // 阻止浏览器默认事件
  890. this.domObj.scrollLeft = this.domObj.scrollLeft + step
  891. },
  892. },
  893. created() {
  894. },
  895. mounted() {
  896. this.containerHeight = window.innerHeight - 200
  897. // this.containerHeight = window.innerHeight - 130
  898. const that = this;
  899. window.onresize = function temp() {
  900. this.containerHeight = window.innerHeight - 130
  901. // this.containerHeight = window.innerHeight - 200
  902. };
  903. if (this.user.timeType.fixMonthcost == 0) {
  904. if (this.$route.query.startDate != null) {
  905. this.dateRange = [this.$route.query.startDate, this.$route.query.endDate];
  906. } else {
  907. //默认查看本月
  908. var now = new Date();
  909. var t = util.formatDate.format(now, 'yyyy-MM-dd');
  910. var startStr = util.formatDate.format(new Date(), 'yyyy-MM') + "-01";
  911. this.dateRange = [startStr,t];
  912. }
  913. this.exportParam.dateRange = this.dateRange;
  914. } else if (this.user.timeType.fixMonthcost == 1) {
  915. if (this.$route.query.startDate != null) {
  916. this.dateRange = this.$route.query.startDate;
  917. } else {
  918. //默认查看本月
  919. var startStr = util.formatDate.format(new Date(), 'yyyy-MM');
  920. this.dateRange = startStr;
  921. }
  922. this.exportParam.dateRange = this.dateRange;
  923. }
  924. this.radio = '项目'
  925. this.getEchart();
  926. var _this = this;
  927. window.addEventListener("resize", function() {
  928. _this.myChart.resize();
  929. });
  930. // this.getDepartment();
  931. this.getMyProjectList();
  932. this.getUsers()
  933. this.jutishez()
  934. this.scrollFunction()
  935. },
  936. };
  937. </script>
  938. <style lang="scss" scoped>
  939. #container {
  940. // display: inline-block;
  941. display: block;
  942. position: absolute;
  943. // width: 100% !important;
  944. margin-top: 60px;
  945. }
  946. .ryuans {
  947. top: -50px;
  948. }
  949. </style>
  950. <style lang="scss">
  951. </style>