index.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px" style="background: #ededed;">
  4. <el-form-item label="时间" prop="empDate" style="margin-top: 18px;">
  5. <el-date-picker clearable
  6. v-model="queryParams.empDate"
  7. type="month"
  8. value-format="YYYY-MM"
  9. placeholder="请选择月份">
  10. </el-date-picker>
  11. </el-form-item>
  12. <el-form-item style="margin-top: 18px;">
  13. <el-button type="primary" icon="Search" @click="handleQuery">统计</el-button>
  14. </el-form-item>
  15. </el-form>
  16. <div style="display: flex;">
  17. <div style="width: 33.3%;">
  18. <div class="caption">金额-月趋势统计曲线</div>
  19. <div ref="price_echarts_line" class="echarts_area"></div>
  20. <div class="caption">稼动率-月趋势统计曲线</div>
  21. <div ref="efficiency_echarts_line" class="echarts_area"></div>
  22. <div class="caption">产出米数-月趋势统计曲线</div>
  23. <div ref="lenght_echarts_line" class="echarts_area"></div>
  24. </div>
  25. <div style="width: 33%;margin-left: 0.3%;height: 700px;">
  26. <div class="caption">四分位分析</div>
  27. <div ref="echarts41" class="echarts_4"></div>
  28. <div ref="echarts42" class="echarts_4"></div>
  29. <div ref="echarts43" class="echarts_4"></div>
  30. </div>
  31. <div style="width: 33%;margin-left: 0.3%;">
  32. <div class="caption">员工排名</div>
  33. <el-table :data="empToplist" height="680px">
  34. <el-table-column prop="empName" align="center" label="姓名"/>
  35. <el-table-column prop="totalPrice" align="center" label="金额"/>
  36. <el-table-column prop="length" align="center" label="米数"/>
  37. <el-table-column prop="efficiency" align="center" label="平均嫁动">
  38. <template #default="scope">
  39. {{ scope.row.efficiency*100 }} %
  40. </template>
  41. </el-table-column>
  42. </el-table>
  43. </div>
  44. </div>
  45. </div>
  46. </template>
  47. <style>
  48. .caption{
  49. width: 100%;
  50. margin-left: 0px;
  51. margin-top: 10px;
  52. margin-bottom: 10px;
  53. height: 30px;
  54. line-height: 30px;
  55. font-weight: bold;
  56. color: #666;
  57. border-left: 3px solid #8282bd;
  58. padding-left: 5px;
  59. }
  60. .echarts_area{
  61. width: 100%;height: 200px;padding: 15px;
  62. border: 1px solid #ededed;
  63. border-radius: 4px;
  64. background-color: #f3f0f078;
  65. }
  66. .echarts_4{
  67. width: 100%;
  68. height: 33%;
  69. padding: 15px;
  70. border: 1px solid #ededed;
  71. border-radius: 4px;
  72. background-color: #f3f0f078;
  73. }
  74. </style>
  75. <script setup name="Emp">
  76. import {ref,reactive} from "vue";
  77. import { ElMessage } from 'element-plus';
  78. import {monthCalc} from "@/api/emp/empCalc";
  79. import * as echarts from 'echarts';
  80. let queryParams=reactive({empDate:''});
  81. const price_echarts_line=ref(null);
  82. const efficiency_echarts_line=ref(null);
  83. const lenght_echarts_line=ref(null);
  84. const echarts41 = ref(null);
  85. const echarts42 = ref(null);
  86. const echarts43 = ref(null);
  87. let empToplist =ref([]);
  88. function init(){
  89. queryParams.empDate=new Date().Format('yyyy-MM');
  90. getData();
  91. }
  92. /** 搜索按钮操作 */
  93. function handleQuery() {
  94. getData();
  95. }
  96. function getData(){
  97. if(queryParams.empDate==null || queryParams.empDate==''){
  98. let msg = ElMessage({
  99. message: "请选择月份!",
  100. type: "error",
  101. })
  102. return;
  103. }
  104. let msg = ElMessage({
  105. message: "正在查询数据中...",
  106. type: "info",
  107. duration:0,
  108. })
  109. console.log('queryParams.value.empDate:',queryParams.empDate)
  110. monthCalc(queryParams.empDate).then((res)=>{
  111. msg.close();
  112. if(res.code!=200){
  113. ElMessage({
  114. message: "数据查询失败!",
  115. type: "error"
  116. })
  117. return;
  118. }
  119. let tmpLst = [];
  120. for(let i=0;i<res.data.emp.length;i++){
  121. var x = res.data.emp[i];
  122. var tmpItem=x;
  123. for(let k in x){
  124. if(k=='empName') tmpItem[k] = x[k];
  125. else tmpItem[k] = (x[k]*1).toFixed(2);
  126. }
  127. tmpLst.push(tmpItem);
  128. }
  129. empToplist.value = tmpLst;
  130. loadLine(res.data.trend);
  131. load4(res.data.trend);
  132. }).catch(()=>{
  133. msg.close();
  134. ElMessage({
  135. message: "数据查询时发生错误!",
  136. type: "error"
  137. })
  138. })
  139. }
  140. function loadLine(data){
  141. var v_series = [];
  142. var v_series_efficiency = [];
  143. var v_series_length = [];
  144. var times = [];
  145. //总计曲线
  146. var price=[];
  147. var efficiency=[];
  148. var length=[];
  149. var priceA=[];
  150. var efficiencyA=[];
  151. var lengthA=[];
  152. var priceB=[];
  153. var efficiencyB=[];
  154. var lengthB=[];
  155. for (var i = 0; i < data.length; i++) {
  156. var tv = data[i]['empDate'].split("-")
  157. times.push(tv[1] + "-" + tv[2])
  158. price.push(data[i]['totalPrice']);
  159. efficiency.push(data[i]['efficiency']);
  160. length.push(data[i]['length']);
  161. priceA.push(data[i]['totalPriceA']);
  162. efficiencyA.push(data[i]['efficiencyA']);
  163. lengthA.push(data[i]['lengthA']);
  164. priceB.push(data[i]['totalPriceB']);
  165. efficiencyB.push(data[i]['efficiencyB']);
  166. lengthB.push(data[i]['lengthB']);
  167. }
  168. v_series.push({name: "总金额",type: 'line',smooth: true,
  169. //symbol: 'none',
  170. data: price,
  171. itemStyle: {
  172. normal: {
  173. color: 'red', // 这里设置折线的颜色
  174. lineStyle: {
  175. color: 'red' // 这里同时设置线头的颜色
  176. }
  177. }
  178. }});
  179. v_series.push({name: "A班金额",type: 'line',smooth: true,
  180. //symbol: 'none',
  181. data: priceA,
  182. itemStyle: {
  183. normal: {
  184. color: 'black', // 这里设置折线的颜色
  185. lineStyle: {
  186. color: 'black' // 这里同时设置线头的颜色
  187. }
  188. }
  189. }});
  190. v_series.push({name: "B班金额",type: 'line',smooth: true,
  191. //symbol: 'none',
  192. data: priceB,
  193. itemStyle: {
  194. normal: {
  195. color: 'blue', // 这里设置折线的颜色
  196. lineStyle: {
  197. color: 'blue' // 这里同时设置线头的颜色
  198. }
  199. }
  200. }
  201. });
  202. v_series_efficiency.push(
  203. {name: "总稼动率",type: 'line',smooth: true,
  204. //symbol: 'none',
  205. data: efficiency,
  206. itemStyle: {
  207. normal: {
  208. color: 'red', // 这里设置折线的颜色
  209. lineStyle: {
  210. color: 'red' // 这里同时设置线头的颜色
  211. }
  212. }
  213. }}
  214. );
  215. v_series_efficiency.push(
  216. {name: "A班稼动率",type: 'line',smooth: true,
  217. //symbol: 'none',
  218. data: efficiencyA,
  219. itemStyle: {
  220. normal: {
  221. color: 'black', // 这里设置折线的颜色
  222. lineStyle: {
  223. color: 'black' // 这里同时设置线头的颜色
  224. }
  225. }
  226. }}
  227. );
  228. v_series_efficiency.push(
  229. {name: "B班稼动率",type: 'line',smooth: true,
  230. //symbol: 'none',
  231. data: efficiencyB,
  232. itemStyle: {
  233. normal: {
  234. color: 'blue', // 这里设置折线的颜色
  235. lineStyle: {
  236. color: 'blue' // 这里同时设置线头的颜色
  237. }
  238. }
  239. }}
  240. );
  241. v_series_length.push(
  242. {name: "总产出米数",type: 'line',smooth: true,
  243. //symbol: 'none',
  244. data: length,
  245. itemStyle: {
  246. normal: {
  247. color: 'red', // 这里设置折线的颜色
  248. lineStyle: {
  249. color: 'red' // 这里同时设置线头的颜色
  250. }
  251. }
  252. }}
  253. );
  254. v_series_length.push(
  255. {name: "A班产出米数",type: 'line',smooth: true,
  256. //symbol: 'none',
  257. data: lengthA,
  258. itemStyle: {
  259. normal: {
  260. color: 'black', // 这里设置折线的颜色
  261. lineStyle: {
  262. color: 'black' // 这里同时设置线头的颜色
  263. }
  264. }
  265. }}
  266. );
  267. v_series_length.push(
  268. {name: "B班产出米数",type: 'line',smooth: true,
  269. //symbol: 'none',
  270. data: lengthB,
  271. itemStyle: {
  272. normal: {
  273. color: 'blue', // 这里设置折线的颜色
  274. lineStyle: {
  275. color: 'blue' // 这里同时设置线头的颜色
  276. }
  277. }
  278. }}
  279. );
  280. var opt = {
  281. title: {
  282. show: false, //不显示标题
  283. text: '',
  284. textStyle: {
  285. color: "rgb(89, 151, 229)",
  286. fontWeight: "bold"
  287. },
  288. top: "0px",
  289. left: "30px"
  290. },
  291. tooltip: {
  292. trigger: 'axis',
  293. formatter: function (params) {
  294. let xv='';
  295. let result = '';
  296. params.forEach(function (item) {
  297. xv=`${item.name}<br/>`;
  298. result += ` ${item.marker} ${item.value}<br/>`;
  299. });
  300. return xv+result;
  301. }
  302. },
  303. legend: {
  304. show: true, //不显示图例
  305. inactiveColor: "#04417A",
  306. data: ["总金额","A班金额","B班金额"],
  307. textStyle: {color: "#999",fontSize:16},
  308. top: "0px"
  309. },
  310. grid: {
  311. left: '1%',
  312. right: '1%',
  313. bottom: '2%',
  314. top: '16%',
  315. containLabel: true
  316. },
  317. xAxis: {
  318. type: 'category',
  319. boundaryGap: false,
  320. axisLabel: {
  321. rotate: 45,
  322. color: "#999"
  323. },
  324. data: times
  325. },
  326. yAxis: {
  327. type: 'value',
  328. nameTextStyle: {
  329. color: "#999"
  330. },
  331. axisLabel: {
  332. color: "#999"
  333. },
  334. splitLine: {
  335. lineStyle: {
  336. color: "#7DA7CD",
  337. type: "dashed",
  338. width: 1
  339. }
  340. }
  341. },
  342. series: v_series
  343. };
  344. var opt_efficiency = {
  345. title: {
  346. show: false, //不显示标题
  347. text: '',
  348. textStyle: {
  349. color: "rgb(89, 151, 229)",
  350. fontWeight: "bold"
  351. },
  352. top: "0px",
  353. left: "30px"
  354. },
  355. tooltip: {
  356. trigger: 'axis',
  357. formatter: function (params) {
  358. let xv='';
  359. let result = '';
  360. params.forEach(function (item) {
  361. xv=`${item.name}<br/>`;
  362. result += ` ${item.marker} ${item.value}<br/>`;
  363. });
  364. return xv+result;
  365. }
  366. },
  367. legend: {
  368. show: true, //不显示图例
  369. inactiveColor: "#04417A",
  370. data: ["总稼动率","A班稼动率","B班稼动率"],
  371. textStyle: {color: "#999",fontSize:16},
  372. top: "0px"
  373. },
  374. grid: {
  375. left: '1%',
  376. right: '1%',
  377. bottom: '2%',
  378. top: '16%',
  379. containLabel: true
  380. },
  381. xAxis: {
  382. type: 'category',
  383. boundaryGap: false,
  384. axisLabel: {
  385. rotate: 45,
  386. color: "#999"
  387. },
  388. data: times
  389. },
  390. yAxis: {
  391. type: 'value',
  392. nameTextStyle: {
  393. color: "#999"
  394. },
  395. axisLabel: {
  396. color: "#999"
  397. },
  398. splitLine: {
  399. lineStyle: {
  400. color: "#7DA7CD",
  401. type: "dashed",
  402. width: 1
  403. }
  404. }
  405. },
  406. series: v_series_efficiency
  407. };
  408. var opt_length = {
  409. title: {
  410. show: false, //不显示标题
  411. text: '',
  412. textStyle: {
  413. color: "rgb(89, 151, 229)",
  414. fontWeight: "bold"
  415. },
  416. top: "0px",
  417. left: "30px"
  418. },
  419. tooltip: {
  420. trigger: 'axis',
  421. formatter: function (params) {
  422. let xv='';
  423. let result = '';
  424. params.forEach(function (item) {
  425. xv=`${item.name}<br/>`;
  426. result += ` ${item.marker} ${item.value}<br/>`;
  427. });
  428. return xv+result;
  429. }
  430. },
  431. legend: {
  432. show: true, //不显示图例
  433. inactiveColor: "#04417A",
  434. data: ["总产出米数","A班产出米数","B班产出米数"],
  435. textStyle: {color: "#999",fontSize:16},
  436. top: "0px"
  437. },
  438. grid: {
  439. left: '1%',
  440. right: '1%',
  441. bottom: '2%',
  442. top: '16%',
  443. containLabel: true
  444. },
  445. xAxis: {
  446. type: 'category',
  447. boundaryGap: false,
  448. axisLabel: {
  449. rotate: 45,
  450. color: "#999"
  451. },
  452. data: times
  453. },
  454. yAxis: {
  455. type: 'value',
  456. nameTextStyle: {
  457. color: "#999"
  458. },
  459. axisLabel: {
  460. color: "#999"
  461. },
  462. splitLine: {
  463. lineStyle: {
  464. color: "#7DA7CD",
  465. type: "dashed",
  466. width: 1
  467. }
  468. }
  469. },
  470. series: v_series_length
  471. };
  472. setTimeout(() => {
  473. var echartsEle = echarts.init(price_echarts_line.value);
  474. echartsEle.setOption(opt);
  475. var echartsEle2 = echarts.init(efficiency_echarts_line.value);
  476. echartsEle2.setOption(opt_efficiency);
  477. var echartsEle3 = echarts.init(lenght_echarts_line.value);
  478. echartsEle3.setOption(opt_length);
  479. },500);
  480. }
  481. function load4(data){
  482. var price=[];
  483. var efficiency=[];
  484. var length=[];
  485. var priceA=[];
  486. var efficiencyA=[];
  487. var lengthA=[];
  488. var priceB=[];
  489. var efficiencyB=[];
  490. var lengthB=[];
  491. for (var i = 0; i < data.length; i++) {
  492. price.push(data[i]['totalPrice']);
  493. efficiency.push(data[i]['efficiency']);
  494. length.push(data[i]['length']);
  495. priceA.push(data[i]['totalPriceA']);
  496. efficiencyA.push(data[i]['efficiencyA']);
  497. lengthA.push(data[i]['lengthA']);
  498. priceB.push(data[i]['totalPriceB']);
  499. efficiencyB.push(data[i]['efficiencyB']);
  500. lengthB.push(data[i]['lengthB']);
  501. }
  502. var option = {
  503. title: {
  504. show: true, //不显示标题
  505. text: '金额分析',
  506. textStyle: {
  507. color: "#666",
  508. fontWeight: "bold"
  509. },
  510. top: "0px",
  511. left: "center"
  512. },
  513. grid: {
  514. left: '1%',
  515. right: '1%',
  516. bottom: '2%',
  517. top: '16%',
  518. containLabel: true
  519. },
  520. tooltip: {
  521. trigger: 'item',
  522. formatter: function (params) {
  523. var res = '';
  524. res += '最&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;小&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;值:' + params.data[0].toFixed(2) + '<br/>';
  525. res += '第一四分位数:' + params.data[1].toFixed(2) + '<br/>';
  526. res += '中&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;位&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数:' + params.data[2].toFixed(2) + '<br/>';
  527. res += '第三四分位数:' + params.data[3].toFixed(2) + '<br/>';
  528. res += '最&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;大&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;值:' + params.data[4].toFixed(2);
  529. return res;
  530. },
  531. axisPointer: {
  532. type: 'shadow'
  533. }
  534. },
  535. xAxis: {
  536. type: 'category',
  537. data: ['总金额', 'A班金额', 'B班金额'] // X轴数据,每个项目对应一个箱形图
  538. },
  539. yAxis: {},
  540. series: [
  541. {
  542. name: '箱形图',
  543. type: 'boxplot',
  544. data: [
  545. price, // 项目A的数据
  546. priceA, // 项目B的数据
  547. priceB, // 项目C的数据
  548. ]
  549. }
  550. ]
  551. };
  552. var option2 = {
  553. title: {
  554. show: true, //不显示标题
  555. text: '产出米数分析',
  556. textStyle: {
  557. color: "#666",
  558. fontWeight: "bold"
  559. },
  560. top: "0px",
  561. left: "center"
  562. },
  563. grid: {
  564. left: '1%',
  565. right: '1%',
  566. bottom: '2%',
  567. top: '16%',
  568. containLabel: true
  569. },
  570. tooltip: {
  571. trigger: 'item',
  572. formatter: function (params) {
  573. var res = '';
  574. res += '最&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;小&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;值:' + params.data[0].toFixed(2) + '<br/>';
  575. res += '第一四分位数:' + params.data[1].toFixed(2) + '<br/>';
  576. res += '中&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;位&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数:' + params.data[2].toFixed(2) + '<br/>';
  577. res += '第三四分位数:' + params.data[3].toFixed(2) + '<br/>';
  578. res += '最&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;大&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;值:' + params.data[4].toFixed(2);
  579. return res;
  580. },
  581. axisPointer: {
  582. type: 'shadow'
  583. }
  584. },
  585. xAxis: {
  586. type: 'category',
  587. data: ['总产出', 'A班产出', 'B班产出'] // X轴数据,每个项目对应一个箱形图
  588. },
  589. yAxis: {},
  590. series: [
  591. {
  592. name: '箱形图',
  593. type: 'boxplot',
  594. data: [
  595. length, // 项目A的数据
  596. lengthA, // 项目B的数据
  597. lengthB, // 项目C的数据
  598. ]
  599. }
  600. ]
  601. };
  602. var option3 = {
  603. title: {
  604. show: true, //不显示标题
  605. text: '嫁动率分析',
  606. textStyle: {
  607. color: "#666",
  608. fontWeight: "bold"
  609. },
  610. top: "0px",
  611. left: "center"
  612. },
  613. grid: {
  614. left: '1%',
  615. right: '1%',
  616. bottom: '2%',
  617. top: '16%',
  618. containLabel: true
  619. },
  620. tooltip: {
  621. trigger: 'item',
  622. formatter: function (params) {
  623. var res = '';
  624. res += '最&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;小&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;值:' + params.data[0].toFixed(2) + '<br/>';
  625. res += '第一四分位数:' + params.data[1].toFixed(2) + '<br/>';
  626. res += '中&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;位&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数:' + params.data[2].toFixed(2) + '<br/>';
  627. res += '第三四分位数:' + params.data[3].toFixed(2) + '<br/>';
  628. res += '最&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;大&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;值:' + params.data[4].toFixed(2);
  629. return res;
  630. },
  631. axisPointer: {
  632. type: 'shadow'
  633. }
  634. },
  635. xAxis: {
  636. type: 'category',
  637. data: ['总嫁动率', 'A班嫁动率', 'B班嫁动率'] // X轴数据,每个项目对应一个箱形图
  638. },
  639. yAxis: {},
  640. series: [
  641. {
  642. name: '箱形图',
  643. type: 'boxplot',
  644. data: [
  645. efficiency, // 项目A的数据
  646. efficiencyA, // 项目B的数据
  647. efficiencyB, // 项目C的数据
  648. ]
  649. }
  650. ]
  651. };
  652. setTimeout(() => {
  653. var echartsEle = echarts.init(echarts41.value);
  654. echartsEle.setOption(option);
  655. var echartsEle2 = echarts.init(echarts42.value);
  656. echartsEle2.setOption(option2);
  657. var echartsEle3 = echarts.init(echarts43.value);
  658. echartsEle3.setOption(option3);
  659. },500);
  660. }
  661. init();
  662. </script>