cost.vue 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530
  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;">{{ $t('chartY') }} </span>
  6. <el-radio-group v-model="yAxisValue" @change="onYAxisChange" size="small">
  7. <el-radio-button label="1" v-if="permissions.countHours">{{ $t('accordingtoworkinghours') }}</el-radio-button>
  8. <el-radio-button label="0" v-if="permissions.countCost">{{ $t('accordingtothecost') }}</el-radio-button>
  9. </el-radio-group></div>
  10. </el-col>
  11. <el-col :span="14" style="display: flex;flex-wrap: wrap;justify-content: flex-end;">
  12. <el-date-picker v-show="user.timeType.fixMonthcost==0" size="small"
  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="$t('other.to')"
  18. type="daterange"
  19. :start-placeholder="$t('time.startDate')"
  20. :end-placeholder="$t('time.endDate')"
  21. ></el-date-picker>
  22. <el-date-picker v-show="user.timeType.fixMonthcost==1"
  23. v-model="dateRange" :editable="false" size="small"
  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;" size="small" :disabled="radioLoading">
  30. <el-radio-button :label="$t('other.project')"></el-radio-button>
  31. <el-radio-button :label="$t('zhu-xiang-mu')" v-if="user.timeType.mainProjectState"></el-radio-button>
  32. <el-radio-button :label="$t('projectclassification')" v-if="user.companyId != '1071'"></el-radio-button>
  33. <el-radio-button :label="$t('lable.department')" v-if="(permissions.viewAllSummary || permissions.viewMagDeptSummary) && !user.dingdingUserid"></el-radio-button>
  34. <el-radio-button :label="$t('ren-yuan')" v-if="permissions.countPersonnel && !user.dingdingUserid"></el-radio-button>
  35. <el-radio-button :label="namess" v-if="jichu.customDegreeActive == 1 && !jichu.customDegreeMultiple"></el-radio-button>
  36. <el-radio-button v-for="item in theCustomList" :key="item.id" :label="item.name"></el-radio-button>
  37. </el-radio-group>
  38. <el-select v-if="radio == $t('other.project')||radio == namess " v-model="proJuctId" :placeholder="$t('defaultText.pleaseSelectSnItem')" clearable filterable size="small" @change="getEchart" style="margin-left:10px">
  39. <el-option v-for="(item) in projectList" :key="item.id" :label="item.projectName + (item.projectCode ? item.projectCode : '')" :value="item.id">
  40. <span style="float: left;color: #8492a6;">{{ item.projectCode }}</span>
  41. <span style="float: right;font-size: 13px;margin-left: 20px">{{ item.projectName }}</span>
  42. </el-option>
  43. </el-select>
  44. <!--
  45. <el-select v-model="customName" filterable placeholder="请选择" style="margin-top: 10px;width: 350px" v-if="theCustomListFlg" @change="jieliu()">
  46. <el-option v-for="item in customList" :key="item.id" :label="item.name" :value="item.name"></el-option>
  47. </el-select> -->
  48. <el-select v-model="personnelValue" filterable clearable :placeholder="hasReportUserList.length == 0 ? $t('nodata') : $t('pleaseselectpersonnel')" size="small" style="margin-top: 10px;width: 350px" v-if="(radio == $t('ren-yuan'))&& user.userNameNeedTranslate != '1'" @change="personnel()"
  49. :disabled="hasReportUserList.length == 0 ? true : false">
  50. <el-option v-for="item in hasReportUserList" :key="item.id" :label="item.name" :value="item.name">
  51. <span style="float: left">{{ item.name }}</span>
  52. <span style="float: right; color: #8492a6; font-size: 13px;margin-left: 20px" v-if="item.jobNumber">{{ item.jobNumber }}</span>
  53. </el-option>
  54. </el-select>
  55. <span style="text-align: left">
  56. <selectCat v-if="radio == $t('ren-yuan') && user.userNameNeedTranslate == '1'" :searchBoxTop="'1'" :filterable="true" :size="'small'" :widthStr="'350'" :distinction="'2'" :subject="hasReportUserList" :clearable="true" @selectCal="selectCal" :disabled="hasReportUserList.length == 0 ? true : false"></selectCat>
  57. </span>
  58. </el-col>
  59. <el-col :span="4">
  60. <el-button @click="exportProjectData" v-if="theCustomListFlg" size="small">{{ $t('reporderived') }}</el-button>
  61. <el-button @click="showExportDialog" v-else size="small">{{ $t('reporderived') }}</el-button>
  62. </el-col>
  63. </el-row>
  64. <!-- <div id="clearfix" :style="'width:'+widthHtval+'px;position: relative; height:'+containerHeight+'px;'">
  65. <div id="container" :style="'height:'+containerHeight+'px;width:100%'"></div>
  66. </div> -->
  67. <div id="clearfix" :class="radio == $t('ren-yuan') ? 'ryuans' : ''" :style="'overflow-x: auto;width:100%;padding-bottom: 100px; position: relative; height:'+containerHeight+'px;'" v-loading="radioLoading">
  68. <div id="container" :style="'height:'+(containerHeight - 20)+'px;width:100%'"></div>
  69. <div class="poss">
  70. <el-pagination
  71. @size-change="echartsSizeChange"
  72. @current-change="echartsCurrentChange"
  73. :current-page="page"
  74. :page-sizes="[50]"
  75. :page-size="50"
  76. layout="total, sizes, prev, pager, next"
  77. :total="total">
  78. </el-pagination>
  79. </div>
  80. </div>
  81. <!-- <div>
  82. <div id="container" :style="'height:'+containerHeight+'px;width:100%'"></div>
  83. </div> -->
  84. <div style="position:fixed;top:170px;left:600px;" v-show="radio==$t('lable.department') && parentDeptId != null">
  85. <el-button @click="backToParentDept">{{ $t('returnsuperior') }}</el-button>
  86. </div>
  87. <!--导出报表条件选择 -->
  88. <el-dialog :title="$t('timeReportExport')" v-if="exportDialog" :visible.sync="exportDialog" :close-on-click-modal="false" customClass="customWidth" width="500px">
  89. <el-form ref="form3" :model="exportParam" >
  90. <el-form-item prop="projectCategoryId" :label="$t('projectclassification')" v-if="radio == $t('projectclassification')||radio==$t('other.project')">
  91. <el-select v-model="exportParam.projectCategoryId" :placeholder="$t('classificationitems')" clearable style="width:350px;" filterable="true">
  92. <el-option v-for="item in categoryList" :key="item.id" :label="item.name" :value="item.id">
  93. </el-option>
  94. </el-select>
  95. </el-form-item>
  96. <el-form-item prop="projectId" :label="$t('defaultText.selectProject')" v-if="radio != $t('ren-yuan') && radio != $t('projectclassification') && radio != $t('lable.department') && radio != $t('zhu-xiang-mu')">
  97. <el-select v-model="exportParam.projectId" :placeholder="$t('other.allProject')" clearable style="width:350px;" filterable="true" popper-class="projectSelectPopperClass">
  98. <el-option v-for="item in projectList" :key="item.id" :label="item.projectName + '/'+ item.projectCode" :value="item.id">
  99. <span style="float: left;color: #8492a6;">{{ item.projectCode }}</span>
  100. <span style="float: right;font-size: 13px;">{{ item.projectName }}</span>
  101. </el-option>
  102. </el-select>
  103. </el-form-item>
  104. <el-form-item prop="exportContent" label="导出内容" v-if="permissions.countCost && permissions.countHours && (radio == $t('other.project') || radio == $t('projectclassification'))">
  105. <el-select v-model="exportParam.exportContent" style="width:350px;" filterable="true" popper-class="projectSelectPopperClass">
  106. <el-option label="工时和成本" value="hoursAndCost"></el-option>
  107. <el-option label="仅工时" value="hours"></el-option>
  108. <el-option label="仅成本" value="cost"></el-option>
  109. </el-select>
  110. </el-form-item>
  111. <el-form-item :label="$t('departmentchoice')" v-if="radio == $t('other.project')">
  112. <el-cascader v-if="user.userNameNeedTranslate != 1" v-model="exportParam.deptId" :options="departmentList" :placeholder="$t('defaultText.pleaseChoose')"
  113. :props="{ checkStrictly: true, expandTrigger: 'hover' }" clearable filterable style="width:350px;"
  114. ></el-cascader>
  115. <vueCascader :size="'medium'" :widthStr="'350'" :clearable="true" :subject="departmentList" :radios="true" :distinction="'1'" @vueCasader="vueCasader" v-if="user.userNameNeedTranslate == 1"></vueCascader>
  116. </el-form-item>
  117. <el-form-item prop="userIds" :label="$t('screening.selectPeople')" v-if="radio == $t('ren-yuan')">
  118. <el-select v-if="user.userNameNeedTranslate != '1'" v-model="exportParam.userIds" :placeholder="$t('lable.allStaff')" multiple="true" clearable style="width:350px;" filterable="true">
  119. <el-option v-for="item in hasReportUserList" :key="item.id" :label="item.name" :value="item.id"></el-option>
  120. </el-select>
  121. <selectCat v-if="user.userNameNeedTranslate == '1'" :size="'medium'" :widthStr="'350'" :filterable="true" :subject="hasReportUserList" :clearable="true" :multiSelect="true" @selectCal="selectCal" :distinction="'1'"></selectCat>
  122. </el-form-item>
  123. <el-form-item prop="userIds" :label="$t('screening.selectPeople')" v-if="radio == $t('other.project') || radio == $t('projectclassification')">
  124. <el-select v-if="user.userNameNeedTranslate != '1'" v-model="exportParam.userIds" :placeholder="$t('lable.allStaff')" multiple="true" clearable style="width:350px;" filterable="true">
  125. <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
  126. </el-select>
  127. <selectCat v-if="user.userNameNeedTranslate == '1'" :size="'medium'" :widthStr="'350'" :filterable="true" :subject="users" :clearable="true" :multiSelect="true" @selectCal="selectCal" :distinction="'1'"></selectCat>
  128. </el-form-item>
  129. <el-form-item prop="projectId" :label="user.timeType.fixMonthcost==0?$t('time.dateRange'):$t('Selectmonth')">
  130. <el-date-picker v-show="user.timeType.fixMonthcost==0"
  131. v-model="exportParam.dateRange" :editable="false"
  132. format="yyyy-MM-dd" value-format="yyyy-MM-dd"
  133. :clearable="false"
  134. :range-separator="$t('other.to')"
  135. type="daterange"
  136. :start-placeholder="$t('time.startDate')"
  137. :end-placeholder="$t('time.endDate')"
  138. ></el-date-picker>
  139. <el-date-picker v-show="user.timeType.fixMonthcost==1"
  140. v-model="dateRange" :editable="false"
  141. format="yyyy-MM" value-format="yyyy-MM"
  142. @change="getEchart"
  143. :clearable="true"
  144. type="month"
  145. ></el-date-picker>
  146. </el-form-item>
  147. <el-form-item :label="$t('screening.selectPeople')" v-if="false">
  148. <el-select v-if="user.userNameNeedTranslate != '1'" v-model="exportParam.userId" :placeholder="$t('lable.allStaff')" style="width: 350px" filterable="true" clearable="true">
  149. <span v-for="(item, index) in users" :key="index">
  150. <el-option :label="item.name" :value="item.id"></el-option>
  151. </span>
  152. </el-select>
  153. <selectCat v-if="user.userNameNeedTranslate == '1'" :size="'medium'" :distinction="'4'" :widthStr="'350'" :subject="users" :clearable="true" @selectCal="selectCal"></selectCat>
  154. </el-form-item>
  155. <el-form-item prop="type" :label="$t('choosethestyle')" v-if="radio == $t('other.project') || radio == $t('projectclassification')">
  156. <el-select v-model="exportParam.type" :placeholder="$t('choosethestyle')" style="width:350px;" >
  157. <el-option :label="radio == $t('projectclassification') ? $t('classifiedontheline') : $t('Itemontheline')" value="0"></el-option>
  158. <el-option :label="radio == $t('projectclassification') ? $t('classifiedcolumns') : $t('itemisonthecolumn')" value="1"></el-option>
  159. </el-select>
  160. <div class="prompt">
  161. <el-popover placement="top" width="1200" trigger="hover">
  162. <img src="../../assets/image/hanglie.png" alt="" width="100%" v-if="this.radio != $t('projectclassification')">
  163. <img src="../../assets/image/hanglie_corp.png" alt="" width="100%" v-else>
  164. <i class="el-icon-question" slot="reference" />
  165. </el-popover>
  166. </div>
  167. </el-form-item>
  168. <el-form-item v-if="exportParam.type == 1 && permissions.countHours && (radio == $t('other.project'))">
  169. <el-checkbox v-model="exportParam.withPercent" >含项目工时占比</el-checkbox>
  170. </el-form-item>
  171. <el-form-item v-if="radio == $t('zhu-xiang-mu') || ((radio == $t('other.project') || radio == $t('projectclassification')) && exportParam.type == '0')">
  172. <el-checkbox v-model="exportParam.projectSum" >{{ $t('individualprojectdata') }}</el-checkbox>
  173. </el-form-item>
  174. <el-form-item v-if="radio == $t('ren-yuan') && user.timeType.mainProjectState == 1">
  175. <el-checkbox v-model="exportParam.mainProjectColumn" >含主项目</el-checkbox>
  176. </el-form-item>
  177. </el-form>
  178. <div slot="footer" class="dialog-footer">
  179. <el-button type="primary" @click="exportProjectData" style="width:100%;" :loading="exporting">{{ $t('export.export') }}</el-button>
  180. </div>
  181. </el-dialog>
  182. </section>
  183. </template>
  184. <script>
  185. // 引入自定义组件
  186. import selectCat from "@/components/select.vue"
  187. //引入自定义级联组件
  188. import vueCascader from "@/components/cascader.vue"
  189. import util from "../../common/js/util";
  190. export default {
  191. components: {
  192. selectCat,
  193. vueCascader
  194. },
  195. data() {
  196. return {
  197. exporting: false,
  198. totalTime111: 0,
  199. allListData: [],
  200. page: 1,
  201. size: 50,
  202. total: 0,
  203. personnelValue: '',
  204. personnelAll: [],
  205. personnelAllPlly: [],
  206. yAxisValue: '1',
  207. parentDeptStack:[],
  208. parentDeptId:null,
  209. hasReportUserList:[],
  210. projectList:[],
  211. categoryList: [],
  212. exportParam:{projectId:null,dateRange:[],userId: null,type: '0', withPercent: false},
  213. exportDialog:false,
  214. dateRange:[],
  215. user: JSON.parse(sessionStorage.getItem("user")),
  216. permissions: JSON.parse(sessionStorage.getItem("permissions")),
  217. radio: sessionStorage.radio!=null?sessionStorage.radio:this.$t('other.project'),
  218. containerHeight: 0,
  219. // myChart: null,
  220. params: null,
  221. widthHtval: document.body.clientWidth - 230,
  222. users: [],
  223. jichu: [],
  224. namess: '',
  225. timers: null, // 点击的时间
  226. zhishin: 0,
  227. theCustomList: [], // 自定义数据来源
  228. theCustomListFlg: false, // 判断是否点击的是自定义配置的数据来源
  229. theCustomListId: '',
  230. theCustomListPlantLIst: [],
  231. theCustomListPlant: '',
  232. customId: '',
  233. customName: '',
  234. customList: [],
  235. departmentList: [],
  236. radioLoading: false,
  237. proJuctId:'',
  238. };
  239. },
  240. methods: {
  241. echartsCurrentChange(val){
  242. this.page = val
  243. if(this.radio == this.$t('ren-yuan')){
  244. this.gtff()
  245. }else{
  246. this.jieliu_echarts()
  247. }
  248. },
  249. //Y轴点击改变显示的数据
  250. onYAxisChange() {
  251. this.jieliu();
  252. },
  253. jutishez() {
  254. this.http.post('/time-type/getCompanyTimeSetting', {
  255. companyId: this.user.companyId,
  256. },
  257. res => {
  258. if (res.code == "ok") {
  259. this.jichu = res.data
  260. if(res.data.customDegreeActive == 1) {
  261. this.namess = res.data.customDegreeName
  262. }
  263. } else {
  264. this.$message({
  265. message: res.msg,
  266. type: "error"
  267. });
  268. }
  269. },
  270. error => {
  271. this.$message({
  272. message: error,
  273. type: "error"
  274. });
  275. });
  276. },
  277. getUsers() {
  278. this.http.post('/user/getSimpleActiveUserList', {},
  279. res => {
  280. if (res.code == "ok") {
  281. this.users = res.data;
  282. } else {
  283. this.$message({
  284. message: res.msg,
  285. type: "error"
  286. });
  287. }
  288. },
  289. error => {
  290. this.$message({
  291. message: error,
  292. type: "error"
  293. });
  294. });
  295. },
  296. showExportDialog() {
  297. // console.log(12345)
  298. // 清空选择的人
  299. if(this.radio == this.$t('ren-yuan')) {
  300. this.exportParam.userIds = new Array()
  301. }
  302. console.log(this.exportParam)
  303. this.exportDialog = true;
  304. this.exportParam.dateRange = this.dateRange;
  305. // console.log(this.hasReportUserList)
  306. if (this.radio == this.$t('ren-yuan')) {
  307. // this.exportParam.userIds = [];
  308. }
  309. if (this.radio == this.$t('other.project')) {
  310. this.exportParam.deptId = []
  311. }
  312. if(this.permissions.countCost && this.permissions.countHours && (this.radio == this.$t('other.project') || this.radio == this.$t('projectclassification'))){
  313. this.$set(this.exportParam, 'exportContent', 'hoursAndCost')
  314. }
  315. },
  316. //获取我的项目列表
  317. getMyProjectList() {
  318. this.http.post('/project/getProjectList', {
  319. },
  320. res => {
  321. if (res.code == "ok") {
  322. this.projectList = res.data;
  323. } else {
  324. this.$message({
  325. message: res.msg,
  326. type: "error"
  327. });
  328. }
  329. },
  330. error => {
  331. this.$message({
  332. message: error,
  333. type: "error"
  334. });
  335. });
  336. },
  337. exportProjectData() {
  338. var param = {stateKey: 1};
  339. if (this.exportParam.dateRange != null) {
  340. param = {startDate:this.exportParam.dateRange[0], endDate: this.exportParam.dateRange[1],stateKey: 1};
  341. }
  342. var url = "/project/exportTimeCost";
  343. var fileName = this.$t('projectmanhourcoststatistics')+ '.xlsx';
  344. if (this.radio == this.$t('zhu-xiang-mu')) {
  345. param.withMainProject = 1;
  346. }
  347. if(this.radio == this.$t('other.project')){
  348. if (this.exportParam.userIds != null && this.exportParam.userIds.length > 0) {
  349. var ids = '';
  350. this.exportParam.userIds.forEach(u=>{
  351. ids += u+',';
  352. })
  353. param.userIds = ids.substring(0,ids.length-1);
  354. }
  355. if(this.exportParam.projectCategoryId){
  356. param.projectCategoryId = this.exportParam.projectCategoryId
  357. }
  358. //是否含工时占比显示
  359. if (this.exportParam.withPercent) {
  360. param.withPercent = 1;
  361. }
  362. }
  363. if (this.radio == this.$t('ren-yuan') ) {
  364. // console.log(this.exportParam.userIds);
  365. fileName = this.$t('labortimecoststatistics')+ '.xlsx';
  366. url = '/department/exportUserStatistic';
  367. if (this.exportParam.userIds != null && this.exportParam.userIds.length > 0) {
  368. var ids = '';
  369. this.exportParam.userIds.forEach(u=>{
  370. ids += u+',';
  371. })
  372. param.userIds = ids.substring(0,ids.length-1);
  373. }
  374. param.mainProjectColumn = this.exportParam.mainProjectColumn;
  375. }
  376. if(this.radio == this.$t('projectclassification')){
  377. fileName = this.$t('projectclassificationlaborosttatistics')+ '.xlsx';
  378. url = '/project/exportTimeCostByCategory'
  379. if(this.exportParam.projectCategoryId){
  380. param.projectCategoryId = this.exportParam.projectCategoryId
  381. }
  382. if (this.exportParam.userIds != null && this.exportParam.userIds.length > 0) {
  383. var ids = '';
  384. this.exportParam.userIds.forEach(u=>{
  385. ids += u+',';
  386. })
  387. param.userIds = ids.substring(0,ids.length-1);
  388. }
  389. }
  390. if(this.radio == this.$t('lable.department')){
  391. fileName = this.$t('departmenthourscoststatistics')+ '.xlsx'
  392. url = '/department/exportDeptStatistic'
  393. }
  394. if (this.exportParam.projectId && this.radio != this.$t('ren-yuan') && this.radio != this.$t('projectclassification')) {
  395. param.projectId = this.exportParam.projectId;
  396. }
  397. if (this.exportParam.userId) {
  398. if(this.radio == this.$t('lable.department') || this.radio == this.$t('ren-yuan')){
  399. param.userId = this.exportParam.userId;
  400. }
  401. }
  402. if (this.exportParam.type == 1) {
  403. this.exportParam.projectSum = null
  404. }
  405. if (this.exportParam.projectSum != null) {
  406. if(this.radio == this.$t('other.project') || this.radio == this.$t('lable.department') || this.radio == this.$t('projectclassification') || this.radio == this.$t('zhu-xiang-mu')){
  407. param.projectSum = this.exportParam.projectSum;
  408. }
  409. }
  410. if(!this.theCustomListFlg) {
  411. param.type = this.exportParam.type*1
  412. }
  413. console.log(this.radio)
  414. if(this.theCustomListFlg) {
  415. url = '/project/exportTimeCostByUserCustom'
  416. fileName = this.radio + this.$t('statistical') + '.xlsx'
  417. // param.subCustomName = this.customName
  418. param.customId = this.theCustomListId
  419. param.fieldName = this.theCustomListPlant
  420. }
  421. if(this.exportParam.deptId) {
  422. if(this.exportParam.deptId.length > 0) {
  423. param.deptId = this.exportParam.deptId[this.exportParam.deptId.length - 1]
  424. }
  425. }
  426. if(this.permissions.countCost && this.permissions.countHours && (this.radio == this.$t('other.project') || this.radio == this.$t('projectclassification'))){
  427. param.exportContent = this.exportParam.exportContent
  428. }
  429. if(this.radio == this.namess) {
  430. url = '/project/exportDegreeCost'
  431. param = {
  432. startDate:this.exportParam.dateRange[0],
  433. endDate: this.exportParam.dateRange[1],
  434. projectId: this.exportParam.projectId,
  435. }
  436. fileName = this.radio + '成本统计' + '.xlsx'
  437. }
  438. this.exporting = true;
  439. this.http.post(url, param,
  440. res => {
  441. this.exporting = false;
  442. if (res.code == "ok") {
  443. this.exportDialog = false;
  444. var aTag = document.createElement('a');
  445. aTag.download = fileName;
  446. aTag.href = res.data;
  447. aTag.click();
  448. } else {
  449. this.$message({
  450. message: res.msg,
  451. type: "error"
  452. });
  453. }
  454. },
  455. error => {
  456. this.$message({
  457. message: error,
  458. type: "error"
  459. });
  460. this.exporting = false;
  461. });
  462. },
  463. // 人员筛选
  464. personnel() {
  465. this.page = 1
  466. if(this.personnelValue) {
  467. var arrlist = JSON.parse(JSON.stringify(this.personnelAllPlly))
  468. var arr = []
  469. for(var i in arrlist.list) {
  470. // console.log(arrlist.list[i].name, this.personnelValue)
  471. if(arrlist.list[i].name == this.personnelValue) {
  472. arr.push(arrlist.list[i])
  473. }
  474. }
  475. arrlist.list = arr
  476. this.allListData = arrlist
  477. // this.gtff()
  478. if(this.user.userNameNeedTranslate == '1') {
  479. if(arrlist.list.length > 0) {
  480. let list = arrlist.list
  481. let dealWithList = []
  482. for(var i in list) {
  483. let obj = {}
  484. obj.type = list[i].type
  485. obj.id = list[i].name
  486. dealWithList.push(obj)
  487. }
  488. this.dealWithTranslationPlone(dealWithList)
  489. } else {
  490. this.getUserCostList()
  491. }
  492. } else {
  493. this.allListData = arrlist
  494. this.gtff()
  495. }
  496. } else {
  497. this.allListData = this.personnelAllPlly
  498. this.gtff()
  499. }
  500. },
  501. //获取人员成本统计列表
  502. getUserCostList() {
  503. // console.log(this.port.project.userCost, '获取人员成本统计列表')
  504. // console.log(this.user.timeType.fixMonthcost)
  505. // console.log(Boolean(this.dateRange))
  506. let startDateNum = ''
  507. let endDateNum = ''
  508. if(this.dateRange) {
  509. startDateNum = this.user.timeType.fixMonthcost==0?this.dateRange[0]:this.dateRange
  510. endDateNum = this.user.timeType.fixMonthcost==0?this.dateRange[1]:this.dateRange
  511. }
  512. // return
  513. this.http.post(this.port.project.userCost, {
  514. // startDate:this.user.timeType.fixMonthcost==0?this.dateRange[0]:this.dateRange,
  515. // endDate: this.user.timeType.fixMonthcost==0?this.dateRange[1]:this.dateRange
  516. startDate: startDateNum,
  517. endDate: endDateNum
  518. },
  519. res => {
  520. this.radioLoading = false
  521. var _this = this;
  522. this.hasReportUserList = [];
  523. if (res.code == "ok") {
  524. let alltime = 0
  525. for(let i in res.data.list){
  526. for(let m in res.data.list[i].project){
  527. alltime += parseFloat(res.data.list[i].project[m].time)
  528. }
  529. }
  530. this.totalTime111 = alltime
  531. //
  532. //
  533. this.personnelAll = res.data
  534. this.allListData = res.data
  535. this.personnelAllPlly = JSON.parse(JSON.stringify(res.data))
  536. if(this.user.userNameNeedTranslate == '1') {
  537. let list = res.data.list
  538. let dealWithList = []
  539. for(var i in list) {
  540. let obj = {}
  541. obj.type = list[i].type
  542. obj.id = list[i].name
  543. dealWithList.push(obj)
  544. }
  545. this.dealWithTranslationPlone(dealWithList, res.data.list)
  546. } else {
  547. this.personnelAll = res.data
  548. this.allListData = res.data
  549. // console.log('人员返回', this.allListData);
  550. this.gtff()
  551. }
  552. } else {
  553. this.$message({
  554. message: res.msg + '里面',
  555. type: "error"
  556. });
  557. }
  558. },
  559. error => {
  560. this.radioLoading = false
  561. this.$message({
  562. message: error + '外面',
  563. type: "error"
  564. });
  565. });
  566. },
  567. // 共同方法
  568. gtff() {
  569. let data = this.allListData
  570. var _this = this;
  571. this.hasReportUserList = data.userList;
  572. this.total = data.list ? data.list.length : 0
  573. var totalHours = 0.0;
  574. var xList = [] , yList = [] , list = data.list.slice(0+50*(this.page-1),49+50*(this.page-1)), array = [] , series = [];
  575. var totalMoneyCost = data.totalCostMoney;
  576. for(var i in list) {
  577. if(i>20) {
  578. this.widthHtval = +this.widthHtval + 60
  579. } else {
  580. this.widthHtval = document.body.clientWidth - 230
  581. }
  582. }
  583. if (list.length > 0) {
  584. var num = list.length==0?0:list[0].project.length;
  585. // console.log('for 1');
  586. for(var i in list) {
  587. xList.push(list[i].name);
  588. var pro = list[i].project;
  589. for(var j in pro) {
  590. if(array.indexOf(pro[j].project) == -1) {
  591. array.push(pro[j].project)
  592. }
  593. }
  594. }
  595. // console.log('for 2');
  596. for(var i in array) {
  597. yList.push(array[i]);
  598. var dataList = [];
  599. let nameObj = {}
  600. list.forEach(item => {
  601. let moneyTol = 0;
  602. let timeTol = 0;
  603. item.project.forEach((project, index) => {
  604. moneyTol += +project.money;
  605. timeTol += +project.time;
  606. });
  607. // 假设每个 item.project 都至少有一个元素
  608. if (item.project.length > 0) {
  609. const lastProject = item.project[item.project.length - 1];
  610. nameObj[item.name] = {moneyTol: moneyTol, timeTol: timeTol}
  611. lastProject.moneyTol = moneyTol;
  612. lastProject.timeTol = timeTol;
  613. }
  614. });
  615. // console.log('==================>', list, nameObj);
  616. for(var j in list) {
  617. var project = list[j].project , num = 0;
  618. if(project.length != 0) {
  619. // console.log('for 2 1 1');
  620. for(var k in project) {
  621. if(project[k].project == array[i]) {
  622. let item = {
  623. "value": this.yAxisValue==0?project[k].money:project[k].time,
  624. }
  625. if(this.permissions.countCost){
  626. item.money = project[k].money
  627. }
  628. if(this.permissions.countHours){
  629. item.cost = project[k].time
  630. // totalHours += parseFloat(project[k].time);
  631. }
  632. if(project[k].moneyTol) {
  633. item.moneyTol = project[k].moneyTol
  634. item.timeTol = project[k].timeTol
  635. }
  636. dataList.push(item)
  637. } else {
  638. num++;
  639. }
  640. if(k == project.length-1 && num != project.length-1) {
  641. dataList.push({
  642. "value": 0,
  643. "cost": 0,
  644. "money":0,
  645. })
  646. }
  647. }
  648. } else {
  649. dataList.push({
  650. "value": 0,
  651. "cost": 0,
  652. "money":0,
  653. })
  654. }
  655. }
  656. // console.log(array[i], dataList, array, '《==============看看数据')
  657. let cerName = array[array.length - 1] // 最后一个项目
  658. let yAxisValue = this.yAxisValue
  659. series.push({
  660. name: array[i],
  661. type: 'bar',
  662. stack: '1',
  663. barMaxWidth: 30,
  664. data: dataList,
  665. label: {
  666. normal: {
  667. show: true,
  668. position: 'top',
  669. formatter: function(params) {
  670. const { seriesName, data, name} = params
  671. if(!name) {
  672. return ''
  673. }
  674. const unit = yAxisValue == 0 ? '元' : '小时';
  675. console.log(nameObj, name, nameObj[name], params)
  676. const totalValue = yAxisValue == 0 ? nameObj[name].moneyTol : nameObj[name].timeTol;
  677. return seriesName === cerName ? `${totalValue ? totalValue.toFixed(0) : 0} ${unit}` : '';
  678. }
  679. }
  680. }
  681. });
  682. }
  683. }
  684. var myChart = echarts.init(document.getElementById("container"));
  685. totalHours = this.totalTime111.toFixed(1);
  686. // 设置宽度
  687. myChart.resize({
  688. width: this.widthHtval
  689. })
  690. // console.log('设置宽度');
  691. // 设置宽度
  692. _this.myChart = myChart;
  693. var option = {
  694. //总成本
  695. title: {
  696. // text: '工时成本总计' + totalMoneyCost.toFixed(2) + '元, 时长'+totalHours+'小时',
  697. text: this.$t('otalhourscost')+ ':' +
  698. ((this.permissions.countCost) ? this.$t('costof') + ' ' + totalMoneyCost.toFixed(2) + ' ' + this.$t('yuan') + ',' : '') +
  699. ((this.permissions.countHours) ? this.$t('time.duration') + ' ' +totalHours + ' ' + this.$t('time.hour') : ''),
  700. left:'left',
  701. },
  702. // 工具箱
  703. legend: {
  704. x: 80,
  705. y: 10,
  706. data: yList,
  707. show: true,
  708.       top:"5%",//与上方的距离 可百分比% 可像素px
  709. },
  710. grid : {
  711. top : 80, //距离容器上边界40像素
  712. // bottom: 100, //距离容器下边界30像素
  713. bottom: 35, //距离容器下边界30像素
  714. left: 150,
  715. right: 150
  716. },
  717. toolbox: {
  718. show: true,
  719. feature:{
  720. saveAsImage:{
  721. show: this.user.userNameNeedTranslate == 1 ? false : true
  722. },
  723. restore:{
  724. show:true
  725. },
  726. magicType:{
  727. type:['line','bar']
  728. }
  729. }
  730. },
  731. tooltip:{
  732. trigger:'axis',
  733. formatter: function (params,ticket,callback) {
  734. var totalTime = 0;
  735. var totalCost = 0;
  736. var res = "";
  737. for(var i in params) {
  738. if (params[i].data.value > 0) {
  739. res += "<div style='margin-top:3px;font-size:12px;'><font color='#ddd'>" + _this.$t('headerTop.projectName') + ":" + params[i].seriesName
  740. + "</font><br/>" +
  741. ((_this.permissions.countCost) ? _this.$t('workcost')+ ":" + params[i].data.money + _this.$t('yuan') + "</br>" : '') +
  742. ((_this.permissions.countHours) ? _this.$t('screening.workTime') + ":" + params[i].data.cost + _this.$t('time.hour') + "</br>" : '') + "</div>";
  743. totalTime += Number(params[i].data.cost);
  744. totalCost += Number(params[i].data.money);
  745. }
  746. }
  747. if(_this.user.userNameNeedTranslate != 1) {
  748. res = res +'<br/>'+ params[0].name+ '<br/>' + _this.$t('zong-ji') + ':' +
  749. ((_this.permissions.countHours) ? totalTime.toFixed(1) + _this.$t('time.hour') : '') +
  750. ((_this.permissions.countCost) ? totalCost.toFixed(2) + _this.$t('yuan') : '') +
  751. "<br/>";
  752. } else {
  753. res = res +'<br/>'+ '' + '<br/>' + _this.$t('zong-ji') + ':' +
  754. ((_this.permissions.countHours) ? totalTime.toFixed(1) + _this.$t('time.hour') : '') +
  755. ((_this.permissions.countCost) ? totalCost.toFixed(2) + _this.$t('yuan') : '') +
  756. "<br/>";
  757. }
  758. return res;
  759. }
  760. },
  761. xAxis: {
  762. data: xList,
  763. axisLabel: {
  764. interval:0,rotate:20
  765. }
  766. },
  767. yAxis: [{
  768. type : 'value',
  769. axisLabel: {
  770. formatter:this.yAxisValue==0?'{value} ('+this.$t('yuan')+')':'{value} ('+this.$t('time.hour')+')'
  771. // formatter:this.yAxisValue==0?'{value} (元)':'{value} (小时)'
  772. }
  773. }],
  774. series: series,
  775. };
  776. console.log('人员=======>', series)
  777. // console.log('setoption');
  778. myChart.setOption(option,{notMerge:true});
  779. },
  780. yanjiu() {
  781. // console.log('触发')
  782. },
  783. getEchart(e){
  784. var that = this
  785. // 更具选中的名字筛选出对应的自定义id
  786. that.theCustomListFlg = false
  787. let ints = null
  788. for(var i in that.theCustomList) {
  789. if(that.radio == that.theCustomList[i].name) {
  790. that.theCustomListId = that.theCustomList[i].id
  791. that.theCustomListPlant = that.theCustomListPlantLIst[i]
  792. that.theCustomListFlg = true
  793. ints = i
  794. }
  795. }
  796. if(that.theCustomListFlg) {
  797. that.customList = that.theCustomList[ints].subUserCustomList
  798. that.customName = that.theCustomList[ints].subUserCustomList[0].name
  799. // that.getCusTom()
  800. }
  801. that.jieliu()
  802. },
  803. getCusTom() {
  804. this.http.post('/sub-user-custom/list',{
  805. userCustomId: this.theCustomListId
  806. },res => {
  807. if(res.code == 'ok'){
  808. this.customList = res.data
  809. this.customName = res.data[0].name
  810. }else {
  811. this.$message({
  812. message: res.msg,
  813. type: 'error'
  814. })
  815. }
  816. },error => {
  817. this.$message({
  818. message: error,
  819. type: 'error'
  820. })
  821. })
  822. },
  823. getCategoryList(){
  824. this.http.post('/project-category/list',{},
  825. res => {
  826. if(res.code == 'ok'){
  827. this.categoryList = res.data
  828. }else {
  829. this.$message({
  830. message: res.msg,
  831. type: 'error'
  832. })
  833. }
  834. },err => {
  835. this.$message({
  836. message: err,
  837. type: 'error'
  838. })
  839. })
  840. },
  841. backToParentDept() {
  842. if (this.radio == this.$t('lable.department')) {
  843. if (this.parentDeptStack.length > 0) {
  844. this.parentDeptStack.pop();
  845. if (this.parentDeptStack.length > 0) {
  846. this.parentDeptId = this.parentDeptStack[this.parentDeptStack.length -1];
  847. } else {
  848. this.parentDeptId = null;
  849. }
  850. this.jieliu();
  851. }
  852. }
  853. },
  854. // 脱离出来的方法
  855. jieliu() {
  856. sessionStorage.radio = this.radio;
  857. this.radioLoading = true
  858. var param = {};
  859. if (this.dateRange != null) {
  860. param = {
  861. startDate:this.user.timeType.fixMonthcost==0?this.dateRange[0]:this.dateRange,
  862. endDate: this.user.timeType.fixMonthcost==0?this.dateRange[1]:this.dateRange
  863. };
  864. // console.log(param);
  865. }
  866. var url = '';
  867. if (this.radio==this.$t('other.project')) {
  868. url = this.port.project.listCost;
  869. param.projectId=this.proJuctId
  870. param.type=this.yAxisValue
  871. }else if(this.radio == this.$t('zhu-xiang-mu')){
  872. url = '/project/getTimeCostByMainProject'
  873. // param.userId = this.user.id
  874. }else if (this.radio==this.$t('projectclassification')) {
  875. url = '/project/getTimeCostByCategory';
  876. // param.parentDeptId = this.parentDeptId;
  877. // param.userId = this.user.id
  878. } else if (this.radio==this.$t('lable.department')) {
  879. url = this.port.project.depCost;
  880. param.parentDeptId = this.parentDeptId;
  881. } else if (this.radio==this.$t('ren-yuan')) {
  882. this.getUserCostList();
  883. return;
  884. } else if (this.radio == this.namess) {
  885. url = '/project/getDegreeCost'
  886. param.projectId=this.proJuctId
  887. } else if (this.theCustomListFlg) {
  888. url = '/project/getTimeCostByUserCustom'
  889. // param.subCustomName = this.customName
  890. param.customId = this.theCustomListId
  891. param.fieldName = this.theCustomListPlant
  892. // console.log(param, '要传的数据')
  893. }
  894. this.http.post(url, param,
  895. res => {
  896. if (res.code == "ok") {
  897. this.radioLoading = false
  898. let alltime = 0
  899. if(this.radio==this.$t('other.project') || this.radio == this.$t('zhu-xiang-mu') || this.radio==this.$t('projectclassification')){
  900. for(let i in res.data.costList){
  901. alltime += parseFloat(res.data.costList[i].cost)
  902. }
  903. }else if(this.radio==this.$t('lable.department')){
  904. for(let i in res.data.costList){
  905. alltime += parseFloat(res.data.costList[i].costTime)
  906. }
  907. }else if(this.radio == this.namess){
  908. for(let i in res.data){
  909. alltime += parseFloat(res.data[i].cost)
  910. }
  911. }else if(this.theCustomListFlg){
  912. for(let i in res.data.list){
  913. alltime += parseFloat(res.data.list[i].cost)
  914. }
  915. }
  916. this.totalTime111 = alltime
  917. // additionName // 未转译的数据另外存储一份,用作 DOM 上渲染
  918. if(this.user.userNameNeedTranslate == '1') {
  919. for(var i in res.data.costList) {
  920. res.data.costList[i].additionName = res.data.costList[i].departmentName
  921. }
  922. }
  923. this.allListData = res.data
  924. this.page = 1
  925. if(this.user.userNameNeedTranslate == '1' && this.radio == this.$t('lable.department')) {
  926. let arr = []
  927. for(var i in this.allListData.costList) {
  928. let obj = {}
  929. obj.type = this.allListData.costList[i].type
  930. obj.id = this.allListData.costList[i].departmentName
  931. arr.push(obj)
  932. }
  933. this.dealWithTranslation(arr)
  934. } else {
  935. this.jieliu_echarts()
  936. }
  937. } else {
  938. this.radioLoading = false
  939. this.$message({
  940. message: res.msg,
  941. type: "error"
  942. });
  943. }
  944. },
  945. error => {
  946. this.radioLoading = false
  947. this.$message({
  948. message: error,
  949. type: "error"
  950. });
  951. });
  952. },
  953. dealWithTranslation(items) {
  954. if (WWOpenData.initCanvas) {
  955. WWOpenData.initCanvas()
  956. }
  957. const myFunOne = async () => {
  958. const result = await new Promise((resolve, reject) => {
  959. if(WWOpenData.prefetch) {
  960. WWOpenData.prefetch({ items }, (err, data) => {
  961. if (err) { return reject(err) }
  962. resolve(data)
  963. })
  964. }
  965. })
  966. for(var i in this.allListData.costList) {
  967. this.allListData.costList[i].departmentName = result.items[i].data
  968. }
  969. this.jieliu_echarts()
  970. }
  971. myFunOne()
  972. },
  973. dealWithTranslationPlone(items, dataList) {
  974. if (WWOpenData.initCanvas) {
  975. WWOpenData.initCanvas()
  976. }
  977. const myFunOne = async () => {
  978. const result = await new Promise((resolve, reject) => {
  979. if(WWOpenData.prefetch) {
  980. WWOpenData.prefetch({ items }, (err, data) => {
  981. if (err) { return reject(err) }
  982. resolve(data)
  983. })
  984. }
  985. })
  986. for(var i in this.allListData.list) {
  987. if(result.items[i]) {
  988. this.allListData.list[i].name = result.items[i].data
  989. }
  990. }
  991. this.gtff()
  992. }
  993. myFunOne()
  994. },
  995. jieliu_echarts(){
  996. var _this = this;
  997. // 更具数据的长度去加每个柱子的间距
  998. var xList = []
  999. var yList = []
  1000. var list
  1001. var totalMoneyCost;
  1002. var totalHours = 0.0;
  1003. if(this.radio == this.$t('other.project') || this.radio == this.$t('projectclassification') || this.radio==this.$t('lable.department') || this.radio == this.$t('zhu-xiang-mu')) {
  1004. // this.allListData = res.data.costList
  1005. this.total = this.allListData.costList ? this.allListData.costList.length : 0
  1006. list = this.allListData.costList.slice(0+50*(this.page-1),49+50*(this.page-1))
  1007. for(var i in list) {
  1008. if(i>20) {
  1009. this.widthHtval = +this.widthHtval + 60
  1010. } else {
  1011. this.widthHtval = document.body.clientWidth - 230
  1012. }
  1013. }
  1014. // list = res.data.costList
  1015. totalMoneyCost = ((this.radio==this.$t('other.project') || this.radio == this.$t('projectclassification'))?this.allListData.totalMoneyCost:this.allListData.totalCostMoney);
  1016. for(var i in list) {
  1017. if(this.radio==this.$t('other.project') || this.radio == this.$t('zhu-xiang-mu')) {
  1018. if(this.radio == this.$t('other.project')){
  1019. xList.push(list[i].project);
  1020. }else{
  1021. xList.push(list[i].mainProjectName);
  1022. }
  1023. let item = {
  1024. "value": this.yAxisValue==0?(list[i].costMoney ? list[i].costMoney.toFixed(2) : 0) || list[i].costMoney:(list[i].cost ? list[i].cost.toFixed(1) : 0),
  1025. "id": list[i].id || i,
  1026. }
  1027. if(this.permissions.countCost){
  1028. // item.money = list[i].costMoney.toFixed(2)
  1029. item.money = (list[i].costMoney ? list[i].costMoney.toFixed(2) : 0)
  1030. }
  1031. if(this.permissions.countHours){
  1032. item.cost = list[i].cost
  1033. totalHours += parseFloat(list[i].cost);
  1034. }
  1035. yList.push(item);
  1036. } else if(this.radio == this.$t('lable.department')){
  1037. xList.push(list[i].departmentName);
  1038. let item = {
  1039. // "value": this.yAxisValue==0 ? list[i].costMoney.toFixed(2) || list[i].costMoney: list[i].costTime.toFixed(1),
  1040. "value": this.yAxisValue==0 ? (list[i].costMoney ? list[i].costMoney.toFixed(2) : 0) || list[i].costMoney: (list[i].costTime ? list[i].costTime.toFixed(1) : 0),
  1041. "id": list[i].departmentId,
  1042. "hasSubDept": list[i].hasSubDept
  1043. }
  1044. if(this.permissions.countCost){
  1045. // item.money = list[i].costMoney.toFixed(2)
  1046. item.money = (list[i].costMoney ? list[i].costMoney.toFixed(2) : 0)
  1047. }
  1048. if(this.permissions.countHours){
  1049. item.cost = list[i].costTime
  1050. totalHours += parseFloat(list[i].costTime);
  1051. }
  1052. yList.push(item);
  1053. }else {
  1054. xList.push(list[i].categoryName);
  1055. let item = {
  1056. // "value": this.yAxisValue==0?list[i].costMoney.toFixed(2) || list[i].costMoney:list[i].cost.toFixed(1),
  1057. "value": this.yAxisValue==0?(list[i].costMoney ? list[i].costMoney.toFixed(2) : 0) || list[i].costMoney:(list[i].cost ? list[i].cost.toFixed(1) : 0),
  1058. "id": list[i].id || i,
  1059. }
  1060. if(this.permissions.countCost){
  1061. // item.money = list[i].costMoney.toFixed(2)
  1062. item.money = (list[i].costMoney ? list[i].costMoney.toFixed(2) : 0)
  1063. }
  1064. if(this.permissions.countHours){
  1065. item.cost = list[i].cost
  1066. totalHours += parseFloat(list[i].cost);
  1067. }
  1068. yList.push(item);
  1069. }
  1070. }
  1071. }
  1072. else if(this.theCustomListFlg) {
  1073. // this.allListData = res.data.list ? res.data.list : []
  1074. this.total = this.allListData.list ? this.allListData.list.length : 0
  1075. list = this.total ? this.allListData.list.slice(0+50*(this.page-1),49+50*(this.page-1)) : []
  1076. // list = res.data.list
  1077. for(var i in list) {
  1078. xList.push(list[i].name);
  1079. let item = {
  1080. "value": this.yAxisValue==0?list[i].costMoney:list[i].cost,
  1081. "id": list[i].id || i,
  1082. }
  1083. if(this.permissions.countCost){
  1084. // item.money = list[i].costMoney.toFixed(2)
  1085. item.money = list[i].costMoney ? list[i].costMoney.toFixed(2) : 0
  1086. totalMoneyCost += parseFloat(list[i].costMoney);
  1087. }
  1088. if(this.permissions.countHours){
  1089. item.cost = list[i].cost
  1090. totalHours += parseFloat(list[i].cost);
  1091. }
  1092. yList.push(item);
  1093. }
  1094. }
  1095. else {
  1096. //自定义列表:data:{cost:3, costMoney:222}
  1097. this.total = this.allListData ? this.allListData.length : 0
  1098. // if(this.total){
  1099. list = this.allListData.slice(0+50*(this.page-1),49+50*(this.page-1))
  1100. // }else{
  1101. // list =
  1102. // }
  1103. // list = this.total ? : []
  1104. for(var i in list) {
  1105. xList.push(list[i].name);
  1106. let item = {
  1107. "value": this.yAxisValue==0?list[i].costMoney:list[i].cost,
  1108. "id": list[i].id || i,
  1109. }
  1110. if(this.permissions.countCost){
  1111. // item.money = list[i].costMoney.toFixed(2)
  1112. item.money = list[i].costMoney ? list[i].costMoney.toFixed(2) : 0
  1113. totalMoneyCost += parseFloat(list[i].costMoney);
  1114. }
  1115. if(this.permissions.countHours){
  1116. item.cost = list[i].cost
  1117. totalHours += parseFloat(list[i].cost);
  1118. }
  1119. yList.push(item);
  1120. }
  1121. }
  1122. totalHours = this.totalTime111.toFixed(1);
  1123. var myChart = echarts.init(document.getElementById("container"));
  1124. myChart.resize({
  1125. width: this.widthHtval
  1126. })
  1127. _this.myChart = myChart;
  1128. if(totalMoneyCost) {
  1129. this.zhishin = totalMoneyCost.toFixed(2)
  1130. } else {
  1131. this.zhishin = 0
  1132. }
  1133. if(this.radio == this.$t('other.project') || this.radio == this.$t('zhu-xiang-mu') || this.radio == this.$t('ren-yuan') || this.radio == this.$t('projectclassification') || this.radio==this.$t('lable.department')) {
  1134. var option = {
  1135. title: {
  1136. text: this.$t('otalhourscost') + ':' + ((this.permissions.countCost) ? this.$t('costof') + ' ' + this.zhishin + ' ' +this.$t('yuan') + ',' : '') + ((this.permissions.countHours) ? this.$t('time.duration') + ' ' +totalHours+ ' ' +this.$t('time.hour') : ''),
  1137. left:'left',
  1138. },
  1139. // 工具箱
  1140. toolbox: {
  1141. show: true,
  1142. feature:{
  1143. saveAsImage:{show:this.user.userNameNeedTranslate == 1 ? false : true},restore:{show:true}, magicType:{ type:['line','bar']},
  1144. }
  1145. },
  1146. tooltip:{
  1147. trigger:'axis',
  1148. formatter: function (params,ticket,callback) {
  1149. _this.params = params;
  1150. var res
  1151. if(_this.user.userNameNeedTranslate != '1') {
  1152. var res = params[0].name + "<br/>" +
  1153. ((_this.permissions.countCost) ? _this.$t('workcost')+" : " + params[0].data.money
  1154. + _this.$t('yuan')+"<br/>" : '') +
  1155. ((_this.permissions.countHours) ? _this.$t('screening.workTime')+" : " + params[0].data.cost + _this.$t('time.hour') : '');
  1156. } else {
  1157. var res = "<TranslationOpenDataText type='departmentName' :openid='"+ _this.allListData.costList[params[0].dataIndex].additionName +"'></TranslationOpenDataText>" + "<br/>" +
  1158. ((_this.permissions.countCost) ? _this.$t('workcost')+" : " + params[0].data.money
  1159. + _this.$t('yuan')+"<br/>" : '') +
  1160. ((_this.permissions.countHours) ? _this.$t('screening.workTime')+" : " + params[0].data.cost + _this.$t('time.hour') : '');
  1161. }
  1162. return res;
  1163. }
  1164. },
  1165. xAxis: {
  1166. data: xList,
  1167. axisLabel: {
  1168. interval:0,rotate:20
  1169. }
  1170. },
  1171. yAxis: [{
  1172. type : 'value',
  1173. axisLabel: {
  1174. formatter:this.yAxisValue==0?'{value} ('+this.$t('yuan')+')':'{value}'+this.$t('time.hour')
  1175. }
  1176. }],
  1177. series: [{
  1178. name: this.yAxisValue==0?this.$t('workcost')+'('+this.$t('yuan')+')':this.$t('screening.workTime')+'('+this.$t('time.hour')+')',
  1179. type: 'bar',
  1180. barMaxWidth: 30,
  1181. data: yList,
  1182. label: {
  1183. normal: {
  1184. show: true,
  1185. position: 'top',
  1186. formatter: `{c} ${this.yAxisValue==0 ? '元' : '小时'}`,
  1187. }
  1188. }
  1189. }],
  1190. grid: {
  1191. left: '100px',
  1192. }
  1193. };
  1194. } else {
  1195. var option = {
  1196. title: {
  1197. // text: '工时成本总计' + this.zhishin + '元, 时长'+totalHours+'小时',
  1198. text: this.$t('otalhourscost')+ ':' + ((this.permissions.countCost) ? this.$t('costof') + ' ' + this.zhishin + ' ' + this.$t('yuan')+ ',' : '') + ((this.permissions.countHours) ? this.$t('time.duration') + ' ' + totalHours + ' ' + this.$t('time.hour') : ''),
  1199. left:'left',
  1200. },
  1201. // 工具箱
  1202. toolbox: {
  1203. show: true,
  1204. feature:{
  1205. saveAsImage:{show:this.user.userNameNeedTranslate == 1 ? false : true},restore:{show:true}, magicType:{ type:['line','bar']},
  1206. }
  1207. },
  1208. tooltip:{
  1209. trigger:'axis',
  1210. formatter: function (params,ticket,callback) {
  1211. var res = params[0].name + "<br/>" +
  1212. ((_this.permissions.countCost) ? _this.$t('workcost')+" : " + params[0].data.money
  1213. + _this.$t('yuan')+"<br/>" : '') +
  1214. ((_this.permissions.countHours) ? _this.$t('screening.workTime')+" : " + params[0].data.cost + _this.$t('time.hour') : '');
  1215. _this.params = params;
  1216. return res;
  1217. }
  1218. },
  1219. xAxis: {
  1220. data: xList,
  1221. axisLabel: {
  1222. interval:0,rotate:20
  1223. }
  1224. },
  1225. yAxis: [{
  1226. type : 'value',
  1227. axisLabel: {
  1228. formatter:this.yAxisValue==0?'{value} ('+this.$t('yuan')+')':'{value}'+this.$t('time.hour')
  1229. }
  1230. }],
  1231. series: [{
  1232. name: this.yAxisValue==0?this.$t('workcost')+'('+this.$t('yuan')+')':this.$t('screening.workTime')+'('+this.$t('time.hour')+')',
  1233. type: 'bar',
  1234. barMaxWidth: 30,
  1235. data: yList,
  1236. label: {
  1237. normal: {
  1238. show: true,
  1239. position: 'top',
  1240. formatter: `{c} ${this.yAxisValue==0 ? '元' : '小时'}`,
  1241. }
  1242. }
  1243. }],
  1244. grid: {
  1245. left: '100px',
  1246. }
  1247. };
  1248. }
  1249. myChart.setOption(option,{notMerge: true});
  1250. myChart.getZr().on('click', params => {
  1251. const pointInPixel = [params.offsetX, params.offsetY];
  1252. if (myChart.containPixel('grid', pointInPixel)) {
  1253. if(_this.radio==this.$t('other.project')) {
  1254. if (_this.dateRange != null) {
  1255. if (this.user.timeType.fixMonthcost == 0) {
  1256. _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name
  1257. +"?startDate="+_this.dateRange[0]+"&endDate="+_this.dateRange[1]);
  1258. } else {
  1259. _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name
  1260. +"?startDate="+_this.dateRange+"&endDate="+_this.dateRange);
  1261. }
  1262. } else {
  1263. _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name);
  1264. }
  1265. } else if (_this.radio==this.$t('lable.department')) {
  1266. if (_this.params[0].data.hasSubDept) {
  1267. if (_this.parentDeptId != _this.params[0].data.id) {
  1268. _this.parentDeptId = _this.params[0].data.id;
  1269. _this.parentDeptStack.push(_this.parentDeptId);
  1270. _this.jieliu();
  1271. }
  1272. // _this.jieliu();
  1273. } else {
  1274. if (_this.dateRange != null) {
  1275. _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name
  1276. +"?startDate="+_this.dateRange[0]+"&endDate="+_this.dateRange[1]);
  1277. } else {
  1278. _this.$router.push("/costDep/" + _this.params[0].data.id + "/" + _this.params[0].name);
  1279. }
  1280. }
  1281. }
  1282. }
  1283. });
  1284. },
  1285. // 左右滚动
  1286. scrollFunction () {
  1287. this.domObj = document.getElementById('clearfix') // 通过id获取要设置的div
  1288. if (this.domObj.attachEvent) { // IE
  1289. this.domObj.attachEvent('onmousewheel', this.mouseScroll)
  1290. } else if (this.domObj.addEventListener) {
  1291. this.domObj.addEventListener('DOMMouseScroll', this.mouseScroll, false)
  1292. }
  1293. this.domObj.onmousewheel = this.domObj.onmousewheel = this.mouseScroll
  1294. },
  1295. mouseScroll(event) { // google 浏览器下
  1296. let detail = event.wheelDelta || event.detail
  1297. let moveForwardStep = -1
  1298. let moveBackStep = 1
  1299. let step = 0
  1300. step = detail > 0 ? moveForwardStep * 100 : moveBackStep * 100
  1301. event.preventDefault() // 阻止浏览器默认事件
  1302. this.domObj.scrollLeft = this.domObj.scrollLeft + step
  1303. },
  1304. // 判断后端给的字段
  1305. // 获取自定义
  1306. getZDY() {
  1307. this.http.post('/user-custom/getUserCustomTitle',{},res => {
  1308. if(res.code == 'ok'){
  1309. this.theCustomList = res.data.result
  1310. this.theCustomListPlantLIst = res.data.field
  1311. }else {
  1312. this.$message({
  1313. message: res.msg,
  1314. type: 'error'
  1315. })
  1316. }
  1317. },error => {
  1318. this.$message({
  1319. message: error,
  1320. type: 'error'
  1321. })
  1322. })
  1323. },
  1324. // 获取部门
  1325. getDepartmentList() {
  1326. this.http.post( this.port.manage.depList, {},
  1327. res => {
  1328. if (res.code == "ok") {
  1329. let dptlist = JSON.parse(JSON.stringify(res.data));
  1330. this.departmentList = this.changeArr(dptlist);
  1331. } else {
  1332. this.$message({
  1333. message: res.msg,
  1334. type: "error"
  1335. });
  1336. }
  1337. },error => {
  1338. this.$message({
  1339. message: error,
  1340. type: "error"
  1341. });
  1342. });
  1343. },
  1344. changeArr(arr) {
  1345. for (var i = 0; i < arr.length; i++) {
  1346. if(arr[i].id != -1 && arr[i].id != 0) {
  1347. if (arr[i].children != null && arr[i].children.length>0) {
  1348. arr[i].children = this.changeArr(arr[i].children);
  1349. }
  1350. arr[i].id && (arr[i].value = arr[i].id);
  1351. delete arr[i].id;
  1352. }
  1353. }
  1354. for(var i in arr) {
  1355. if(arr[i].id == -1 || arr[i].id == 0) {
  1356. arr.splice(i,1)
  1357. }
  1358. }
  1359. return arr;
  1360. },
  1361. // 自定义事件
  1362. selectCal(obj) {
  1363. if(obj.distinction == 1) {
  1364. let arr = []
  1365. for(var i in obj.arrUserList) {
  1366. arr.push(obj.arrUserList[i].id)
  1367. }
  1368. this.exportParam.userIds = arr
  1369. } else if(obj.distinction == 2) {
  1370. this.personnelValue = obj.name
  1371. this.personnel()
  1372. } else if(obj.distinction == 4) {
  1373. this.exportParam.userId = obj.id
  1374. }
  1375. },
  1376. vueCasader(obj) {
  1377. if(obj.distinction == 1) {
  1378. let arr = []
  1379. arr.push(obj.id)
  1380. this.exportParam.deptId = arr
  1381. }
  1382. }
  1383. },
  1384. created() {
  1385. this.myChart = null
  1386. },
  1387. mounted() {
  1388. this.containerHeight = window.innerHeight - 200
  1389. // this.containerHeight = window.innerHeight - 130
  1390. const that = this;
  1391. window.onresize = function temp() {
  1392. this.containerHeight = window.innerHeight - 130
  1393. // this.containerHeight = window.innerHeight - 200
  1394. };
  1395. if(this.permissions.countCost && !this.permissions.countHours){
  1396. this.yAxisValue = '0'
  1397. }else {
  1398. this.yAxisValue = '1'
  1399. }
  1400. if (this.user.timeType.fixMonthcost == 0) {
  1401. if (this.$route.query.startDate != null) {
  1402. this.dateRange = [this.$route.query.startDate, this.$route.query.endDate];
  1403. } else {
  1404. //默认查看本月
  1405. var now = new Date();
  1406. var t = util.formatDate.format(now, 'yyyy-MM-dd');
  1407. var startStr = util.formatDate.format(new Date(), 'yyyy-MM') + "-01";
  1408. this.dateRange = [startStr,t];
  1409. }
  1410. this.exportParam.dateRange = this.dateRange;
  1411. } else if (this.user.timeType.fixMonthcost == 1) {
  1412. if (this.$route.query.startDate != null) {
  1413. this.dateRange = this.$route.query.startDate;
  1414. } else {
  1415. //默认查看本月
  1416. var startStr = util.formatDate.format(new Date(), 'yyyy-MM');
  1417. this.dateRange = startStr;
  1418. }
  1419. this.exportParam.dateRange = this.dateRange;
  1420. }
  1421. if(this.$route.query && this.$route.query.endDate && this.$route.query.startDate) {
  1422. const { endDate, startDate } = this.$route.query
  1423. const lastDay = this.dayjs(`${endDate}-01`).endOf('month').format('YYYY-MM-DD');
  1424. this.dateRange = [startDate+'-01', lastDay];
  1425. }
  1426. this.radio = this.$t('other.project')
  1427. this.getEchart();
  1428. var _this = this;
  1429. window.addEventListener("resize", function() {
  1430. _this.myChart.resize();
  1431. });
  1432. // this.getDepartment();
  1433. this.getMyProjectList();
  1434. this.getCategoryList();
  1435. this.getUsers()
  1436. this.jutishez()
  1437. this.scrollFunction()
  1438. // 判断
  1439. if(this.user.timeType.userCustomStatic) {
  1440. this.getZDY()
  1441. }
  1442. this.getDepartmentList()
  1443. },
  1444. beforeDestroy () {
  1445. var myChart = echarts.init(document.getElementById("container"));
  1446. myChart.clear()
  1447. },
  1448. };
  1449. </script>
  1450. <style lang="scss" scoped>
  1451. #container {
  1452. // display: inline-block;
  1453. display: block;
  1454. position: absolute;
  1455. // width: 100% !important;
  1456. margin-top: 60px;
  1457. }
  1458. .ryuans {
  1459. top: -50px;
  1460. }
  1461. .prompt {
  1462. position: absolute;
  1463. right: 10px;
  1464. top: 0;
  1465. }
  1466. .poss {
  1467. position: fixed;
  1468. bottom: 10px;
  1469. right: 1%;
  1470. box-sizing: border-box;
  1471. }
  1472. </style>
  1473. <style lang="scss">
  1474. </style>