finance.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. <template>
  2. <section>
  3. <!--工具条-->
  4. <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
  5. <el-form :inline="true">
  6. <el-form-item label="财务核算成本 | 月份选择" style="margin-top:5px;">
  7. <el-date-picker size="small" v-model="date" :editable="false" format="yyyy-MM" value-format="yyyy-MM" @change="changeMonth" :clearable="false" type="month" placeholder="选择月份"></el-date-picker>
  8. </el-form-item>
  9. <el-form-item style="float:right;">
  10. <el-link type="primary" :underline="false" href="./upload/财务人员成本模板.xlsx" download="财务人员成本模板.xlsx">财务模板下载</el-link>
  11. </el-form-item>
  12. <el-form-item style="float:right;">
  13. <el-upload ref="upload" action="#" :limit="1" :http-request="importFinance" :show-file-list="false">
  14. <el-link type="primary" :underline="false" >财务数据上传</el-link>
  15. </el-upload>
  16. </el-form-item>
  17. </el-form>
  18. </el-col>
  19. <!--列表-->
  20. <el-table :data="list" highlight-current-row v-loading="listLoading"
  21. show-summary=true
  22. ref="table"
  23. height="300" style="width: 100%;">
  24. <el-table-column prop="name" label="姓名" sortable width="150"></el-table-column>
  25. <el-table-column prop="monthCost" label="工资" width="150"></el-table-column>
  26. <el-table-column prop="bonus" label="奖金" ></el-table-column>
  27. <el-table-column prop="allowance" label="津贴" ></el-table-column>
  28. <el-table-column prop="insuranceOld" label="养老保险" ></el-table-column>
  29. <el-table-column prop="insuranceMedical" label="医疗保险" ></el-table-column>
  30. <el-table-column prop="insuranceLosejob" label="失业保险" ></el-table-column>
  31. <el-table-column prop="houseFund" label="住房公积金" ></el-table-column>
  32. <el-table-column prop="others" label="其他" ></el-table-column>
  33. <el-table-column prop="totalCost" label="总成本" ></el-table-column>
  34. </el-table>
  35. <el-form :inline="true" >
  36. <el-form-item >
  37. <el-link type="primary" :underline="false" @click="assignToProject">查看项目成本分配</el-link>
  38. </el-form-item>
  39. <el-form-item style="float:right;">
  40. <el-link type="primary" :underline="false" @click="exportData">导出数据</el-link>
  41. </el-form-item>
  42. </el-form>
  43. <div id="container" style="height:300px"></div>
  44. <!--新增界面-->
  45. <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="600px">
  46. <el-form ref="form1" :model="addForm" :rules="rules" label-width="100px">
  47. <el-form-item label="项目编号" >
  48. <el-input v-model="addForm.code" placeholder="请输入项目编号" clearable></el-input>
  49. </el-form-item>
  50. <el-form-item label="项目名称" prop="name">
  51. <el-input v-model="addForm.name" placeholder="请输入项目名称" clearable></el-input>
  52. </el-form-item>
  53. <el-form-item label="全部参与者">
  54. <el-select v-model="addForm.userId" multiple filterable placeholder="请选择参与者" style="width:100%;" @change="changeParticipator">
  55. <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
  56. </el-select>
  57. </el-form-item>
  58. <el-form-item label="主要负责人" >
  59. <el-select v-model="addForm.inchargerId" :disabled="addForm.userId.length==0" filterable placeholder="请选择负责人" style="width:100%;" @change="changeIncharger">
  60. <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id"></el-option>
  61. </el-select>
  62. </el-form-item>
  63. </el-form>
  64. <div slot="footer" class="dialog-footer">
  65. <el-button @click.native="addFormVisible = false">取消</el-button>
  66. <el-button type="primary" @click="submitInsert" :loading="addLoading">提交</el-button>
  67. </div>
  68. </el-dialog>
  69. <!--用户详细信息弹出框-->
  70. <el-dialog title="查看详情" v-if="userDetailVisible" :visible.sync="userDetailVisible" :close-on-click-modal="false" customClass="customWidth" width="400px">
  71. <div class="line"><span>姓名</span><span>{{userDetail.name}}</span></div>
  72. <div class="line"><span>手机号码</span><span>{{userDetail.phone}}</span></div>
  73. <div class="line"><span>部门</span><span>{{userDetail.departmentName}}</span></div>
  74. <div class="line"><span>成本</span><span>{{userDetail.cost}}元/小时</span></div>
  75. <div slot="footer" class="dialog-footer">
  76. <el-button type="primary" @click="userDetailVisible = false" >确定</el-button>
  77. </div>
  78. </el-dialog>
  79. </section>
  80. </template>
  81. <style scoped>
  82. .line {
  83. padding:10px;
  84. }
  85. .line span{
  86. font-size:18px;
  87. }
  88. .line span:nth-child(even){
  89. float:right;
  90. }
  91. </style>
  92. <script>
  93. import util from "../../common/js/util";
  94. export default {
  95. data() {
  96. return {
  97. user: JSON.parse(sessionStorage.getItem("user")),
  98. userDetailVisible: false,
  99. userDetail:{},
  100. date: null,
  101. tableHeight: 0,
  102. listLoading: false,
  103. list: [],
  104. addLoading: false,
  105. myChart: null,
  106. params: null,
  107. };
  108. },
  109. methods: {
  110. assignToProject(){
  111. var _this = this;
  112. this.http.post('/finance/getTimeCost', {yearMonth: this.date},
  113. res => {
  114. if (res.code == "ok") {
  115. var xList = [], yList = [], list = res.data.costList,
  116. totalMoneyCost = res.data.totalMoneyCost;
  117. for(var i in list) {
  118. xList.push(list[i].project);
  119. yList.push({
  120. "value": list[i].cost,
  121. "id": list[i].id,
  122. "time": list[i].workingTime
  123. });
  124. }
  125. var myChart = echarts.init(document.getElementById("container"));
  126. _this.myChart = myChart;
  127. var option = {
  128. title: {
  129. text: '项目成本统计 总计' + totalMoneyCost + '元',
  130. left:'left',
  131. },
  132. // 工具箱
  133. toolbox: {
  134. show: true,
  135. feature:{
  136. saveAsImage:{
  137. show:true
  138. },
  139. restore:{
  140. show:true
  141. },
  142. magicType:{
  143. type:['line','bar']
  144. },
  145. }
  146. },
  147. tooltip:{
  148. trigger:'axis',
  149. formatter: function (params,ticket,callback) {
  150. var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.value
  151. + "元 <br/>工作时长"+" : " + params[0].data.time + "小时";
  152. _this.params = params;
  153. return res;
  154. }
  155. },
  156. xAxis: {
  157. data: xList,
  158. axisLabel: {
  159. interval:0,rotate:20
  160. }
  161. },
  162. yAxis: [{
  163. type : 'value',
  164. axisLabel: {
  165. formatter:'{value} (元)'
  166. }
  167. }],
  168. series: [{
  169. name: '工作时长(h)',
  170. type: 'bar',
  171. barMaxWidth: 30,
  172. data: yList,
  173. }]
  174. };
  175. myChart.setOption(option);
  176. // myChart.getZr().on('click', params => {
  177. // const pointInPixel = [params.offsetX, params.offsetY];
  178. // if (myChart.containPixel('grid', pointInPixel)) {
  179. // console.log(_this.params)
  180. // if(_this.radio=='项目') {
  181. // _this.$router.push("/cost/" + _this.params[0].data.id + "/" + _this.params[0].name);
  182. // }
  183. // }
  184. // });
  185. } else {
  186. this.$message({
  187. message: res.msg,
  188. type: "error"
  189. });
  190. }
  191. },
  192. error => {
  193. this.$message({
  194. message: error,
  195. type: "error"
  196. });
  197. });
  198. },
  199. //导出财务数据
  200. exportData() {
  201. this.listLoading = true;
  202. this.http.post('/finance/exportData', {
  203. date: this.date
  204. },
  205. res => {
  206. this.listLoading = false;
  207. if (res.code == "ok") {
  208. var aTag = document.createElement('a');
  209. aTag.download = "财务成本统计.xls";
  210. aTag.href = res.data;
  211. aTag.click();
  212. } else {
  213. this.$message({
  214. message: res.msg,
  215. type: "error"
  216. });
  217. }
  218. },
  219. error => {
  220. this.listLoading = false;
  221. this.$message({
  222. message: error,
  223. type: "error"
  224. });
  225. });
  226. },
  227. getSummaries(param) {
  228. const { columns, data } = param;
  229. const sums = [];
  230. columns.forEach((column, index) => {
  231. if (index === 0) {
  232. sums[index] = '总价';
  233. return;
  234. }
  235. const values = data.map(item => Number(item[column.property]));
  236. if (!values.every(value => isNaN(value))) {
  237. sums[index] = values.reduce((prev, curr) => {
  238. const value = Number(curr);
  239. if (!isNaN(value)) {
  240. return prev + curr;
  241. } else {
  242. return prev;
  243. }
  244. }, 0);
  245. sums[index] += ' 元';
  246. } else {
  247. sums[index] = 'N/A';
  248. }
  249. });
  250. return sums;
  251. },
  252. changeMonth() {
  253. //改变月份
  254. this.getList();
  255. },
  256. // 批量导入人员
  257. importFinance(item) {
  258. //首先判断文件类型
  259. let str = item.file.name.split(".");
  260. let format = str[str.length - 1];
  261. if (format != "xls" && format != "xlsx") {
  262. this.$message({
  263. message: "请选择.xls或.xlsx文件",
  264. type: "error"
  265. });
  266. } else {
  267. this.listLoading = true;
  268. let formData = new FormData();
  269. formData.append("file", item.file);
  270. formData.append("companyId", this.user.companyId);
  271. console.log('date====='+this.date);
  272. formData.append("yearMonth", this.date);
  273. this.http.uploadFile('/finance/importData', formData,
  274. res => {
  275. this.$refs.upload.clearFiles();
  276. this.listLoading = false;
  277. if (res.code == "ok") {
  278. this.$message({
  279. message: "导入成功",
  280. type: "success"
  281. });
  282. //重新读取列表
  283. this.getList();
  284. } else {
  285. this.$message({
  286. message: res.msg,
  287. type: "error"
  288. });
  289. }
  290. },
  291. error => {
  292. this.$refs.upload.clearFiles();
  293. this.listLoading = false;
  294. this.$message({
  295. message: error,
  296. type: "error"
  297. });
  298. });
  299. }
  300. },
  301. //获取项目列表
  302. getList() {
  303. this.listLoading = true;
  304. this.http.post('/finance/getByMonth', {
  305. companyId: this.user.companyId,
  306. yearMonth: this.date
  307. },
  308. res => {
  309. this.listLoading = false;
  310. if (res.code == "ok") {
  311. var list = res.data;
  312. this.list = list;
  313. } else {
  314. this.$message({
  315. message: res.msg,
  316. type: "error"
  317. });
  318. }
  319. },
  320. error => {
  321. this.listLoading = false;
  322. this.$message({
  323. message: error,
  324. type: "error"
  325. });
  326. });
  327. },
  328. },
  329. created() {
  330. var d = new Date();
  331. this.date = d.getFullYear() +'-'+ ((d.getMonth()+1) < 10? '0'+(d.getMonth()+1):d.getMonth()+1);
  332. },
  333. mounted() {
  334. let height = window.innerHeight;
  335. this.tableHeight = height - 245;
  336. const that = this;
  337. window.onresize = function temp() {
  338. that.tableHeight = window.innerHeight - 245;
  339. };
  340. this.getList();
  341. },
  342. updated() {
  343. this.$nextTick(() => {
  344. this.$refs['table'].doLayout();
  345. })
  346. }
  347. };
  348. </script>
  349. <style lang="scss" scoped>
  350. </style>