cost.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. <template>
  2. <section>
  3. <el-col :span="24" style="padding-bottom: 0px;text-align:center;margin-top:10px;">
  4. <el-date-picker
  5. v-model="dateRange" :editable="false"
  6. format="yyyy-MM-dd" value-format="yyyy-MM-dd"
  7. @change="getEchart"
  8. :clearable="true"
  9. range-separator="至"
  10. type="daterange"
  11. start-placeholder="开始日期"
  12. end-placeholder="结束日期"
  13. ></el-date-picker>
  14. <el-radio-group v-model="radio" @change="getEchart" style="margin-left:10px;">
  15. <el-radio-button label="项目"></el-radio-button>
  16. <el-radio-button label="部门"></el-radio-button>
  17. <el-radio-button label="人员"></el-radio-button>
  18. </el-radio-group>
  19. </el-col>
  20. <div id="container" :style="'height:'+containerHeight+'px'"></div>
  21. <div style="position:fixed;top:120px;right:150px;"><el-button @click="showExportDialog">报表导出</el-button></div>
  22. <!--导出报表条件选择 -->
  23. <el-dialog title="工时报表导出" v-if="exportDialog" :visible.sync="exportDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  24. <el-form ref="form3" :model="exportParam" >
  25. <el-form-item prop="projectId" label="选择项目">
  26. <el-select v-model="exportParam.projectId" placeholder="全部项目" clearable style="width:350px;">
  27. <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id"></el-option>
  28. </el-select>
  29. </el-form-item>
  30. <el-form-item prop="projectId" label="日期范围">
  31. <el-date-picker
  32. v-model="exportParam.dateRange" :editable="false"
  33. format="yyyy-MM-dd" value-format="yyyy-MM-dd"
  34. :clearable="true"
  35. range-separator="至"
  36. type="daterange"
  37. start-placeholder="开始日期"
  38. end-placeholder="结束日期"
  39. ></el-date-picker>
  40. </el-form-item>
  41. </el-form>
  42. <div slot="footer" class="dialog-footer">
  43. <el-button type="primary" @click="exportProjectData" style="width:100%;" >导出</el-button>
  44. </div>
  45. </el-dialog>
  46. </section>
  47. </template>
  48. <script>
  49. import util from "../../common/js/util";
  50. export default {
  51. data() {
  52. return {
  53. projectList:[],
  54. exportParam:{projectId:null,datRange:[]},
  55. exportDialog:false,
  56. dateRange:[],
  57. user: JSON.parse(sessionStorage.getItem("user")),
  58. radio: sessionStorage.radio!=null?sessionStorage.radio:'项目',
  59. containerHeight: 0,
  60. myChart: null,
  61. params: null,
  62. };
  63. },
  64. methods: {
  65. showExportDialog() {
  66. this.exportDialog = true;
  67. this.exportParam.dateRange = this.dateRange;
  68. },
  69. //获取我的项目列表
  70. getMyProjectList() {
  71. this.http.post('/project/getProjectList', {
  72. },
  73. res => {
  74. if (res.code == "ok") {
  75. this.projectList = res.data;
  76. } else {
  77. this.$message({
  78. message: res.msg,
  79. type: "error"
  80. });
  81. }
  82. },
  83. error => {
  84. this.$message({
  85. message: error,
  86. type: "error"
  87. });
  88. });
  89. },
  90. exportProjectData() {
  91. var param = {};
  92. if (this.exportParam.dateRange != null) {
  93. param = {startDate:this.dateRange[0], endDate: this.dateRange[1]};
  94. }
  95. if (this.exportParam.projectId != null) {
  96. param.projectId = this.exportParam.projectId;
  97. }
  98. this.http.post("/project/exportTimeCost", param,
  99. res => {
  100. this.listLoading = false;
  101. if (res.code == "ok") {
  102. var aTag = document.createElement('a');
  103. aTag.download = "项目工时成本统计.xls";
  104. aTag.href = res.data;
  105. aTag.click();
  106. } else {
  107. this.$message({
  108. message: res.msg,
  109. type: "error"
  110. });
  111. }
  112. },
  113. error => {
  114. this.listLoading = false;
  115. this.$message({
  116. message: error,
  117. type: "error"
  118. });
  119. });
  120. },
  121. getEchart(){
  122. sessionStorage.radio = this.radio;
  123. var _this = this;
  124. console.log(this.dateRange);
  125. var param = {};
  126. if (this.dateRange != null) {
  127. param = {startDate:this.dateRange[0], endDate: this.dateRange[1]};
  128. }
  129. var url = '';
  130. if (this.radio=='项目') {
  131. url = this.port.project.listCost;
  132. } else if (this.radio=='部门') {
  133. url = this.port.project.depCost;
  134. } else if (this.radio=='人员') {
  135. url = '/project/getAllMembCost';
  136. }
  137. this.http.post(url, param,
  138. res => {
  139. if (res.code == "ok") {
  140. var xList = [], yList = [], list = res.data.costList,
  141. totalMoneyCost = ((this.radio=='项目' || this.radio=='人员')?res.data.totalMoneyCost:res.data.totalCostMoney);
  142. for(var i in list) {
  143. if(this.radio=='项目' || this.radio == '人员') {
  144. xList.push(this.radio=='项目'?list[i].project:list[i].name);
  145. yList.push({
  146. "value": list[i].costMoney,
  147. "id": list[i].id,
  148. "cost": list[i].cost
  149. });
  150. } else {
  151. xList.push(list[i].departmentName);
  152. yList.push({
  153. "value": list[i].costMoney,
  154. "id": list[i].departmentId,
  155. "cost": list[i].costTime
  156. });
  157. }
  158. }
  159. var myChart = echarts.init(document.getElementById("container"));
  160. _this.myChart = myChart;
  161. var option = {
  162. title: {
  163. text: '工时成本总计' + totalMoneyCost.toFixed(2) + '元',
  164. left:'left',
  165. },
  166. // 工具箱
  167. toolbox: {
  168. show: true,
  169. feature:{
  170. saveAsImage:{
  171. show:true
  172. },
  173. restore:{
  174. show:true
  175. },
  176. // dataView:{
  177. // show:true
  178. // },
  179. // dataZoom:{
  180. // show:true
  181. // },
  182. magicType:{
  183. type:['line','bar']
  184. },
  185. }
  186. },
  187. tooltip:{
  188. trigger:'axis',
  189. formatter: function (params,ticket,callback) {
  190. var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.value
  191. + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
  192. _this.params = params;
  193. return res;
  194. }
  195. },
  196. xAxis: {
  197. data: xList,
  198. axisLabel: {
  199. interval:0,rotate:20
  200. }
  201. },
  202. yAxis: [{
  203. type : 'value',
  204. axisLabel: {
  205. formatter:'{value} (元)'
  206. }
  207. }],
  208. series: [{
  209. name: '工作成本(元)',
  210. type: 'bar',
  211. barMaxWidth: 30,
  212. data: yList,
  213. }]
  214. };
  215. myChart.setOption(option);
  216. // myChart.on('click', function(params) {
  217. // if(_this.radio=='项目') {
  218. // _this.$router.push("/cost/" + params.data.id + "/" + params.name);
  219. // } else {
  220. // _this.$router.push("/costDep/" + params.data.id + "/" + params.name);
  221. // }
  222. // });
  223. myChart.getZr().on('click', params => {
  224. const pointInPixel = [params.offsetX, params.offsetY];
  225. if (myChart.containPixel('grid', pointInPixel)) {
  226. console.log(_this.params)
  227. if(_this.radio=='项目') {
  228. if (_this.dateRange != null) {
  229. _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name
  230. +"?startDate="+_this.dateRange[0]+"&endDate="+_this.dateRange[1]);
  231. } else {
  232. _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name);
  233. }
  234. } else if (_this.radio=='部门') {
  235. if (_this.dateRange != null) {
  236. _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name
  237. +"?startDate="+_this.dateRange[0]+"&endDate="+_this.dateRange[1]);
  238. } else {
  239. _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name);
  240. }
  241. }
  242. }
  243. });
  244. } else {
  245. this.$message({
  246. message: res.msg,
  247. type: "error"
  248. });
  249. }
  250. },
  251. error => {
  252. this.$message({
  253. message: error,
  254. type: "error"
  255. });
  256. });
  257. },
  258. },
  259. created() {
  260. },
  261. mounted() {
  262. this.containerHeight = window.innerHeight - 140
  263. const that = this;
  264. window.onresize = function temp() {
  265. this.containerHeight = window.innerHeight - 100
  266. };
  267. if (this.$route.query.startDate != null) {
  268. this.dateRange = [this.$route.query.startDate, this.$route.query.endDate];
  269. } else {
  270. //默认查看本月
  271. var now = new Date();
  272. var t = util.formatDate.format(now, 'yyyy-MM-dd');
  273. var startStr = util.formatDate.format(new Date(), 'yyyy-MM') + "-01";
  274. this.dateRange = [startStr,t];
  275. }
  276. this.exportParam.dateRange = this.dateRange;
  277. this.getEchart();
  278. var _this = this;
  279. window.addEventListener("resize", function() {
  280. _this.myChart.resize();
  281. });
  282. this.getMyProjectList();
  283. }
  284. };
  285. </script>
  286. <style lang="scss" scoped>
  287. #container {
  288. display: inline-block;
  289. width: 100%;
  290. margin-top: 10px;
  291. }
  292. </style>
  293. <style lang="scss">
  294. </style>