cost.vue 47 KB

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