analysis.component.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. import { Component, ChangeDetectionStrategy, OnInit, ChangeDetectorRef, ElementRef } from '@angular/core';
  2. import { NzMessageService } from 'ng-zorro-antd';
  3. import { STColumn, XlsxService } from '@delon/abc';
  4. import { getTimeDistance } from '@delon/util';
  5. import { _HttpClient } from '@delon/theme';
  6. import { I18NService } from '@core';
  7. import { yuan } from '@shared';
  8. import { ProjectFileService } from 'app/services/projectFile/project-file.service';
  9. import { FbsWorkshopDispatchListService } from 'app/services/fbs/fbs-workshop-dispatch-list.service';
  10. import { FbsAbnormalWorkingHoursService } from 'app/services/fbs/fbs-abnormal-working-hours.service';
  11. import { FbsWorkshopDispatchList } from 'app/entity/fbs/fbs-workshop-dispatch-list';
  12. import { convertingNumbers } from '@shared/utils/shared';
  13. @Component({
  14. selector: 'app-dashboard-analysis',
  15. templateUrl: './analysis.component.html',
  16. styleUrls: ['./analysis.component.less'],
  17. styles:[
  18. `
  19. table{
  20. border-collapse:collapse;border:none;
  21. }
  22. th{
  23. border:solid#000 1px;
  24. }
  25. td{
  26. border:solid#000 1px;
  27. }
  28. .bolder{
  29. font-weight:bolder;
  30. }
  31. `
  32. ]
  33. // changeDetection: ChangeDetectionStrategy.OnPush,
  34. })
  35. export class DashboardAnalysisComponent implements OnInit {
  36. data: any = {};
  37. loading = true;
  38. date_range: Date[] = [];
  39. rankingListData: any[] = Array(7)
  40. .fill({})
  41. .map((item, i) => {
  42. return {
  43. title: this.i18n.fanyi('app.analysis.test', { no: i }),
  44. total: 323234,
  45. };
  46. });
  47. titleMap = {
  48. y1: this.i18n.fanyi('app.analysis.traffic'),
  49. y2: this.i18n.fanyi('app.analysis.payments'),
  50. };
  51. searchColumn: STColumn[] = [
  52. { title: '排名', i18n: 'app.analysis.table.rank', index: 'index' },
  53. {
  54. title: '搜索关键词',
  55. i18n: 'app.analysis.table.search-keyword',
  56. index: 'keyword',
  57. click: (item: any) => this.msg.success(item.keyword),
  58. },
  59. {
  60. type: 'number',
  61. title: '用户数',
  62. i18n: 'app.analysis.table.users',
  63. index: 'count',
  64. sorter: (a, b) => a.count - b.count,
  65. },
  66. {
  67. type: 'number',
  68. title: '周涨幅',
  69. i18n: 'app.analysis.table.weekly-range',
  70. index: 'range',
  71. render: 'range',
  72. sorter: (a, b) => a.range - b.range,
  73. },
  74. ];
  75. constructor(
  76. private http: _HttpClient,
  77. public msg: NzMessageService,
  78. private i18n: I18NService,
  79. private cdr: ChangeDetectorRef,
  80. private projectFileService: ProjectFileService,
  81. private fbsWorkshopDispatchListService:FbsWorkshopDispatchListService,
  82. private fbsAbnormalWorkingHoursService:FbsAbnormalWorkingHoursService,
  83. private xlsx: XlsxService
  84. ) { }
  85. ngOnInit() {
  86. // const offlineData: any[] = [];
  87. // for (let i = 0; i < 10; i += 1) {
  88. // offlineData.push({
  89. // name: `门店${i}`,
  90. // cvr: Math.ceil(Math.random() * 9) / 10,
  91. // });
  92. // };
  93. // offlineData.forEach((item: any, idx: number) => {
  94. // item.show = idx === 0;
  95. // item.chart = Object.assign([], offlineData);
  96. // });
  97. // this.http.get('/chart').subscribe((res: any) => {
  98. // res.offlineData.forEach((item: any, idx: number) => {
  99. // item.show = idx === 0;
  100. // item.chart = Object.assign([], res.offlineChartData);
  101. // });
  102. // this.data = res;
  103. // this.loading = false;
  104. // });
  105. this.getCircleChartData();
  106. this.feeTotal = `&yen ${this.feeData.reduce((pre, now) => now.y + pre, 0).toFixed(2)}`;
  107. this.alertTotal = `&yen ${this.feeData.reduce((pre, now) => now.y + pre, 0).toFixed(2)}`;
  108. this.getNow();
  109. this.getSumDispatchReport();
  110. this.getAbnormalWorkingHoursReport();
  111. this.getPlanningReport();
  112. }
  113. /**
  114. * @description: 获取数据
  115. * @param {type}
  116. * @author: 段亚鑫
  117. */
  118. isVisible = false;
  119. getCircleChartData() {
  120. this.projectFileService.queryStatusNum().then((response) => {
  121. this.projectFeeData = response.result.statusList;
  122. this.projectFeeTotal = response.result.sum;
  123. this.isVisible = true;
  124. this.loading = false;
  125. // this.chart.render();
  126. })
  127. }
  128. /**
  129. * @description: 渲染图表
  130. * @param {type}
  131. * @author: 段亚鑫
  132. */
  133. chart: any;
  134. render(el: ElementRef) {
  135. const data = [{
  136. item: '事例一',
  137. count: 40,
  138. percent: 0.4
  139. }, {
  140. item: '事例二',
  141. count: 21,
  142. percent: 0.21
  143. }, {
  144. item: '事例三',
  145. count: 17,
  146. percent: 0.17
  147. }, {
  148. item: '事例四',
  149. count: 13,
  150. percent: 0.13
  151. }, {
  152. item: '事例五',
  153. count: 9,
  154. percent: 0.09
  155. }];
  156. this.chart = new G2.Chart({
  157. container: el.nativeElement,
  158. forceFit: true,
  159. height: 450,
  160. animate: false
  161. });
  162. this.chart.source(data, {
  163. percent: {
  164. formatter: function formatter(val) {
  165. val = val * 100 + '%';
  166. return val;
  167. }
  168. }
  169. });
  170. this.chart.coord('theta', {
  171. radius: 0.75,
  172. innerRadius: 0.6
  173. });
  174. this.chart.tooltip({
  175. showTitle: false,
  176. itemTpl: '<li><span style="background-color:{color};" class="g2-tooltip-marker"></span>{name}: {value}</li>'
  177. });
  178. // 文本
  179. this.chart.guide().html({
  180. position: ['50%', '50%'],
  181. html: '<div style="color:#8c8c8c;font-size: 14px;text-align: center;width: 10em;">主机<br><span style="color:#8c8c8c;font-size:20px">200</span>台</div>',
  182. alignX: 'middle',
  183. alignY: 'middle'
  184. });
  185. const interval = this.chart.intervalStack().position('percent').color('item').label('percent', {
  186. formatter: function formatter(val, item) {
  187. return item.point.item + ': ' + val;
  188. }
  189. }).tooltip('item*percent', function (item, percent) {
  190. percent = percent * 100 + '%';
  191. return {
  192. name: item,
  193. value: percent
  194. };
  195. }).style({
  196. lineWidth: 1,
  197. stroke: '#fff'
  198. });
  199. // this.chart.render();
  200. interval.setSelected(data[0]);
  201. }
  202. setDate(type: any) {
  203. this.date_range = getTimeDistance(type);
  204. setTimeout(() => this.cdr.detectChanges());
  205. }
  206. salesType = 'all';
  207. salesPieData: any;
  208. salesTotal = 0;
  209. changeSaleType() {
  210. this.salesPieData =
  211. this.salesType === 'all'
  212. ? this.data.salesTypeData
  213. : this.salesType === 'online'
  214. ? this.data.salesTypeDataOnline
  215. : this.data.salesTypeDataOffline;
  216. if (this.salesPieData) {
  217. this.salesTotal = this.salesPieData.reduce((pre, now) => now.y + pre, 0);
  218. }
  219. this.cdr.detectChanges();
  220. }
  221. handlePieValueFormat(value: any) {
  222. return yuan(value);
  223. }
  224. saleTabs: any[] = [{ key: 'sales', show: true }, { key: 'visits' }];
  225. salesChange(idx: number) {
  226. if (this.saleTabs[idx].show !== true) {
  227. this.saleTabs[idx].show = true;
  228. this.cdr.detectChanges();
  229. }
  230. }
  231. offlineIdx = 0;
  232. offlineChange(idx: number) {
  233. if (this.data.offlineData[idx].show !== true) {
  234. this.data.offlineData[idx].show = true;
  235. this.cdr.detectChanges();
  236. }
  237. }
  238. projectFeeTotal: any = null;
  239. projectFeeData = [
  240. // {x:'试剂/PD01',y:5.0,},
  241. // {x:'试剂/PDA',y:2.5,},
  242. // {x:'试剂/PR02',y:1.5,},
  243. // {x:'检测/PD01',y:5.5,},
  244. // {x:'检测/PDA',y:2.2,},
  245. // {x:'检测/PR02',y:1.6,},
  246. // {x:'会议/PD01',y:0.8,},
  247. // {x:'会议/PDA',y:3.2,},
  248. // {x:'会议/PR02',y:1.5,},
  249. // {x:'培训/PD01',y:2.5,},
  250. // {x:'培训/PDA',y:7.6,},
  251. // {x:'培训/PR02',y:1.8,},
  252. // {x:'会议/PD01',y:0.8,},
  253. // {x:'会议/PDA',y:3.2,},
  254. // {x:'人工/PR02',y:4.2,},
  255. ];
  256. projectFeeFormat(val: number) {
  257. // console.error(val)
  258. return val+"/个";
  259. }
  260. feeTotal: string;
  261. feeData = [
  262. { x: '一季度', y: 10000, },
  263. { x: '二季度', y: 40000, },
  264. { x: '三季度', y: 80000, },
  265. { x: '四季度', y: 30000, },
  266. ];
  267. feeFormat(val: number) {
  268. return `&yen ${val.toFixed(2)}`;
  269. }
  270. alertTotal: string;
  271. alertData = [
  272. { x: '办公费', y: 8000, },
  273. { x: '检测费', y: 12000, },
  274. { x: '设备采购费', y: 66000, },
  275. { x: '培训费', y: 45000, },
  276. ];
  277. alertFormat(val: number) {
  278. return `&yen ${val.toFixed(2)}`;
  279. }
  280. saveLoading=false;
  281. /**
  282. * 获取报表数据
  283. */
  284. listOfDataSelect=null;
  285. getSumDispatchReport(){
  286. this.saveLoading=true;
  287. this.fbsWorkshopDispatchListService.getSumDispatchReport(this.fbsWorkshopDispatchList).then((response)=>{
  288. this.listOfData=response.result;
  289. this.defaultSwitch();
  290. this.isSwitchChange();
  291. if(this.listOfDataSelect===null){
  292. this.listOfDataSelect=JSON.parse(JSON.stringify(response.result));
  293. }
  294. //获取时间集合数据
  295. this.getDateList();
  296. //总效率
  297. this.getEfficiencyTotal()
  298. this.saveLoading=false;
  299. })
  300. }
  301. achievementRateTotal="";//总达成率
  302. productivityTotal="";//生产率
  303. getEfficiencyTotal(){
  304. this.listOfData.forEach(element => {
  305. let numberOfTasksTotal=element.numberOfTasksTotal;//计划数量
  306. let standardWorkingHoursActualTotal=element.standardWorkingHoursActualTotal;//实际标准工时
  307. let quantityCompletedTotal=element.quantityCompletedTotal;//完成数量
  308. let manHoursCompletedTotal=element.manHoursCompletedTotal;//完成工时
  309. if(element.projectName==="统计"){
  310. this.achievementRateTotal=((Number(quantityCompletedTotal)/Number(numberOfTasksTotal))*100).toFixed(1);
  311. console.log(standardWorkingHoursActualTotal)
  312. this.productivityTotal=((Number(standardWorkingHoursActualTotal)/Number(manHoursCompletedTotal))*100).toFixed(1)
  313. }
  314. });
  315. }
  316. /**
  317. * 获取时间列集合数据
  318. */
  319. widthLength=0;
  320. dateList=[];
  321. getDateList(){
  322. if(this.listOfData&&this.listOfData.length>0){
  323. this.dateList=this.listOfData[0].fbsWorkshopDispatchListList
  324. // this.widthLength=(this.listOfData[0].fbsWorkshopDispatchListList.length*700)+890;
  325. this.widthLength=(this.listOfData[0].fbsWorkshopDispatchListList.length*600)+840;
  326. }
  327. }
  328. /**
  329. * 异常工时统计
  330. */
  331. abnormalWorkingHoursList:any=[];
  332. AbnormalWorkingHoursTotal:any={}
  333. getAbnormalWorkingHoursReport(){
  334. this.fbsAbnormalWorkingHoursService.getAbnormalWorkingHoursReport().then((response)=>{
  335. this.abnormalWorkingHoursList=response.result.fbsAbnormalWorkingHoursList;
  336. let attendanceHours=0;//出勤总工时
  337. let overtimeHours=0;//加班总工时
  338. let train=0;//其他总工时
  339. let abnormalWorkingHours=0;//异常总工时统计
  340. let warehouse=0;//仓库总工时统计
  341. this.abnormalWorkingHoursList.forEach(element => {
  342. if(element.attendanceHours){
  343. attendanceHours=attendanceHours+Number(element.attendanceHours);
  344. }
  345. if(element.overtimeHours){
  346. overtimeHours=overtimeHours+Number(element.overtimeHours);
  347. }
  348. train=train+Number(element.train)+Number(element.meeting)+Number(element.fiveS)+Number(element.researchAndDevelopment);
  349. abnormalWorkingHours=abnormalWorkingHours+Number(element.quality)+Number(element.design)+Number(element.rework)+Number(element.materiel)+Number(element.energy)+Number(element.other)+Number(element.equipment)+Number(element.plan);
  350. warehouse=warehouse+Number(element.mixedIngredients)+Number(element.warehousing)+Number(element.pack)+Number(element.warehouseOthers)
  351. });
  352. this.AbnormalWorkingHoursTotal.attendanceHours=attendanceHours;
  353. this.AbnormalWorkingHoursTotal.overtimeHours=overtimeHours;
  354. this.AbnormalWorkingHoursTotal.train=train;
  355. this.AbnormalWorkingHoursTotal.abnormalWorkingHours=abnormalWorkingHours;
  356. this.AbnormalWorkingHoursTotal.warehouse=warehouse;
  357. })
  358. }
  359. fbsWorkshopDispatchList:FbsWorkshopDispatchList={};
  360. listOfData=[]
  361. isSwitch=false;//是否显示已完成订单
  362. isSwitchChange(){
  363. this.listOfData.forEach(element => {
  364. if(element.status===4){
  365. if(this.isSwitch===false){
  366. element.isSwitch=false;
  367. }else{
  368. element.isSwitch=true;
  369. }
  370. }
  371. });
  372. }
  373. defaultSwitch(){
  374. this.listOfData.forEach(element => {
  375. if(element.status===4){
  376. element.isSwitch=false;
  377. }else{
  378. element.isSwitch=true;
  379. }
  380. });
  381. }
  382. /**
  383. * 导出
  384. */
  385. year="0";
  386. month="0";
  387. //初始化年月 默认当前年月
  388. getNow(){
  389. let date = new Date();
  390. this.fbsWorkshopDispatchList.year=date.getFullYear()+"";
  391. if(date.getMonth()<10){
  392. this.fbsWorkshopDispatchList.month="0"+(date.getMonth()+1)
  393. }else{
  394. this.fbsWorkshopDispatchList.month=(date.getMonth()+1)+"";
  395. }
  396. }
  397. exportLoading=false;
  398. export(){
  399. // let month=this.year.substring(2,4)+this.month;
  400. // this.fbsWorkshopDispatchListService.export(month).then((response)=>{
  401. // let list=[];
  402. // list=response.result
  403. // this.exportLoading=true;
  404. let data = [];
  405. let title = [
  406. ['项目名称'], // 项目名称
  407. ['生产订单号'], // 生产订单号
  408. ['物料编码'], // 物料编码
  409. ['物料名称'], // 物料名称
  410. ['月度计划'], // 月度计划
  411. ['标准工时'], // 标准工时
  412. ['累计完成数量'], // 累计完成数量
  413. ['累计完成工时'], // 累计完成工时
  414. ];
  415. data.push(title);
  416. this.listOfData.forEach(element => {
  417. let row=[];
  418. row.push(element.projectName)
  419. row.push(element.productionOrderNumberName)
  420. row.push(element.productId)
  421. row.push(element.product)
  422. row.push(convertingNumbers(element.numberOfTasksTotal))
  423. row.push(convertingNumbers(element.standardWorkingHoursTotal))
  424. row.push(element.quantityCompletedTotal)//quantityCompletedTotal//latestCompletedQuantity
  425. row.push(convertingNumbers(element.manHoursCompletedTotal))
  426. data.push(row);
  427. });
  428. let efficiencyTotal=[
  429. ['总达成率'],
  430. [this.achievementRateTotal+'%'],
  431. ['总生产效率'],
  432. [this.productivityTotal+'%'],
  433. ['出勤总工时'],
  434. [this.AbnormalWorkingHoursTotal.attendanceHours],
  435. ['加班总工时'],
  436. [this.AbnormalWorkingHoursTotal.overtimeHours],
  437. ['其他总工时'],
  438. [this.AbnormalWorkingHoursTotal.train],
  439. ['异常总工时统计'],
  440. [this.AbnormalWorkingHoursTotal.abnormalWorkingHours],
  441. ['仓库总工时统计'],
  442. [this.AbnormalWorkingHoursTotal.warehouse]
  443. ];
  444. data.push(efficiencyTotal);
  445. // 导出
  446. this.xlsx.export({
  447. sheets: [
  448. {
  449. data: data,
  450. name: '生产订单汇总导出',
  451. },
  452. ],
  453. filename: '生产订单汇总导出.xlsx',
  454. });
  455. // this.exportLoading=false;
  456. // })
  457. }
  458. planningReportList=[]
  459. planningReportLoading=false;
  460. fbsWorkshopDispatchListPlanningReport:FbsWorkshopDispatchList={}
  461. columnTable2Width=0;
  462. getPlanningReport(){
  463. this.planningReportLoading=true;
  464. this.fbsWorkshopDispatchListService.getPlanningReport().then((response)=>{
  465. this.fbsWorkshopDispatchListPlanningReport=response.result;
  466. this.planningReportList=response.result.fbsWorkshopDispatchListList;
  467. this.columnTable2Width=response.result.dayList.length*25+360
  468. this.planningReportLoading=false;
  469. })
  470. }
  471. }