warehouseOne.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=1920" />
  6. <title>无人线边仓库看板</title>
  7. <link rel="stylesheet" href="./css/common.css" />
  8. <link rel="stylesheet" href="./css/board1.css" />
  9. <script type="text/javascript" src="./plugin/jquery.min.js"></script>
  10. <script type="text/javascript" src="./plugin/echarts.min.js"></script>
  11. <script type="text/javascript" src="./plugin/vue.min.js"></script>
  12. <script type="text/javascript" src="./js/util.js"></script>
  13. <script type="text/javascript" src="./js/common.js"></script>
  14. <script src="./plugin/datav.min.js"></script>
  15. <script type="text/javascript" src="./js/chart.js"></script>
  16. <script type="text/javascript" src="./js/testDatas.js"></script>
  17. </head>
  18. <script>
  19. $(window).load(function () {
  20. $(".loading").fadeOut();
  21. });
  22. //动态设置视口
  23. const setSize = () => {
  24. // 获取html元素
  25. const html = document.getElementsByTagName("html")[0];
  26. // 获取屏幕宽度
  27. const pageWidth = html.getBoundingClientRect().width;
  28. // 动态计算字体大小(rem)
  29. html.style.fontSize = pageWidth / 20 + "px";
  30. };
  31. setSize();
  32. window.addEventListener("resize", setSize, false);
  33. </script>
  34. <body>
  35. <div class="loading">
  36. <div class="load_box">
  37. <img src="./images/loading.gif" /> 看板加载中,请稍等...
  38. </div>
  39. </div>
  40. <div id="app" class="container">
  41. <div class="head">
  42. <h1>无人线边仓库看板</h1>
  43. <span id="showTime"></span>
  44. </div>
  45. <div class="box">
  46. <span class="title day-title">近七日出入库数据</span>
  47. <div
  48. style="
  49. height: 4rem;
  50. position: absolute;
  51. width: 4.6rem;
  52. top: 1rem;
  53. left: 0.4rem;
  54. "
  55. id="daysChart"
  56. ></div>
  57. </div>
  58. <div class="box">
  59. <span class="title position-title">今日出入库货位</span>
  60. <div
  61. style="
  62. height: 4.9rem;
  63. position: absolute;
  64. width: 4.6rem;
  65. top: 5.4rem;
  66. left: 0.4rem;
  67. "
  68. id="positionChart"
  69. ></div>
  70. </div>
  71. <div class="box">
  72. <span class="title quantity-title">库存数量</span>
  73. <span class="title count frock-title">工装库存</span>
  74. <span class="count-number clamp-quantity">{{clampQuantity}}</span>
  75. </div>
  76. <div class="box">
  77. <span class="title count total-title">总库存</span>
  78. <span class="count-number inventory-quantity"
  79. >{{inventoryQuantity}}</span
  80. >
  81. </div>
  82. <div class="box">
  83. <span class="title count device-title">设备库存</span>
  84. <span class="count-number instrument-quantity"
  85. >{{instrumentQuantity}}</span
  86. >
  87. </div>
  88. <div class="box">
  89. <span class="title year-title">年领用数据统计</span>
  90. <div
  91. style="
  92. height: 3rem;
  93. position: absolute;
  94. width: 9.2rem;
  95. top: 2.7rem;
  96. left: 5.2rem;
  97. "
  98. id="yearChart"
  99. ></div>
  100. </div>
  101. <div class="box">
  102. <span class="title goIn-title">出入库记录</span>
  103. <div>
  104. <dv-scroll-board
  105. ref="scrollBoard"
  106. style="
  107. height: 3.2rem;
  108. position: absolute;
  109. width: 8.8rem;
  110. top: 6.6rem;
  111. left: 5.5rem;
  112. "
  113. :config="recordConfig"
  114. />
  115. </div>
  116. </div>
  117. <div class="box">
  118. <span class="title type-title">今日出入库类型</span>
  119. <div
  120. style="
  121. height: 4.2rem;
  122. position: absolute;
  123. width: 5rem;
  124. top: 0.4rem;
  125. right: 0.3rem;
  126. "
  127. id="typeChart"
  128. ></div>
  129. </div>
  130. <div class="box">
  131. <span class="title hot-title">热门使用Top5</span>
  132. <div
  133. style="
  134. height: 2.8rem;
  135. position: absolute;
  136. width: 5rem;
  137. top: 4.7rem;
  138. right: 0.2rem;
  139. "
  140. id="hotChart"
  141. ></div>
  142. </div>
  143. <div class="box">
  144. <span class="title use-title">领用排行Top5</span>
  145. <div
  146. style="
  147. height: 2.7rem;
  148. position: absolute;
  149. width: 5rem;
  150. top: 7.6rem;
  151. right: 0.2rem;
  152. "
  153. id="useChart"
  154. ></div>
  155. </div>
  156. </div>
  157. <div class="back"></div>
  158. <script>
  159. var app = new Vue({
  160. el: "#app",
  161. data() {
  162. return {
  163. timer: null,
  164. clampQuantity: null,
  165. inventoryQuantity: null,
  166. instrumentQuantity: null,
  167. daysChart: null,
  168. positionChart: null,
  169. yearChart: null,
  170. typeChart: null,
  171. hotChart: null,
  172. useChart: null,
  173. recordConfig: {
  174. header: [
  175. '<span style="color:#3296f6;font-size:0.18rem">序号</span>',
  176. '<span style="color:#3296f6;font-size:0.18rem">名称</span>',
  177. '<span style="color:#3296f6;font-size:0.18rem">图号</span>',
  178. '<span style="color:#3296f6;font-size:0.18rem">类型</span>',
  179. '<span style="color:#3296f6;font-size:0.18rem">规格</span>',
  180. '<span style="color:#3296f6;font-size:0.18rem">操作时间</span>',
  181. '<span style="color:#3296f6;font-size:0.18rem">操作人</span>',
  182. ],
  183. columnWidth: [60, 140, 160, 90, 120, 160, 120],
  184. data: [],
  185. align: [
  186. "center",
  187. "center",
  188. "center",
  189. "center",
  190. "center",
  191. "center",
  192. "center",
  193. ],
  194. headerBGC: "transparent",
  195. oddRowBGC: "transparent",
  196. evenRowBGC: "transparent",
  197. },
  198. tableDatas: [],
  199. dayDatas: [],
  200. outStockDatas: [],
  201. inStockDatas: [],
  202. yearDatas: [],
  203. inTypeDatas: {},
  204. outTypeDatas: {},
  205. hotDatas: [],
  206. useDatas: [],
  207. outDatas: {},
  208. inDatas: {},
  209. };
  210. },
  211. methods: {
  212. // 获取当前展示的仓库id
  213. getWarehouseId() {
  214. const _self = this;
  215. const params = getQueryString();
  216. _self.warehouseId = params.warehouseId;
  217. },
  218. // 创建出入库柱状图
  219. createDaysChart() {
  220. const _self = this;
  221. const daysOption = drawDaysChart();
  222. initChart(_self.daysChart, daysOption);
  223. },
  224. createPositionChart() {
  225. const _self = this;
  226. const positionOption = drawPositionChart();
  227. initChart(_self.positionChart, positionOption);
  228. },
  229. createYearChart() {
  230. const _self = this;
  231. const yearOption = drawYearChart();
  232. initChart(_self.yearChart, yearOption);
  233. },
  234. createTypeChart() {
  235. const _self = this;
  236. const typeOption = drawTypeChart();
  237. initChart(_self.typeChart, typeOption);
  238. },
  239. createHotChart() {
  240. const _self = this;
  241. const hotOption = drawTopChart();
  242. initChart(_self.hotChart, hotOption);
  243. },
  244. createUseChart() {
  245. const _self = this;
  246. const useOption = drawTopChart();
  247. initChart(_self.useChart, useOption);
  248. },
  249. // 获取看板信息
  250. getWarehouseInfo() {
  251. const _self = this;
  252. const url = "/api/WmsResource/queryBoardStatistic";
  253. const params = [["warehouseId", _self.warehouseId]];
  254. // const success = oneDatas // 测试数据
  255. ajaxGet(url, params).then((success) => {
  256. if (success.errorCode === 0) {
  257. const { weekStatisticList, stockOutPosition } = success.data;
  258. const { stockInPosition, monthPickList } = success.data;
  259. const { inventoryQuantity, clampQuantity, instrumentQuantity } =
  260. success.data;
  261. const { stockInCategory, stockOutCategory } = success.data;
  262. const { popularInvList, popularUserList } = success.data;
  263. const { cfInAndOutResponses } = success.data;
  264. _self.clampQuantity = clampQuantity;
  265. _self.inventoryQuantity = inventoryQuantity;
  266. _self.instrumentQuantity = instrumentQuantity;
  267. _self.updateDaysChart(weekStatisticList);
  268. _self.updatePositionChart(stockOutPosition, stockInPosition);
  269. _self.updateYearChart(monthPickList);
  270. _self.updateTypeChart(stockInCategory, stockOutCategory);
  271. _self.updateHotChart(popularInvList);
  272. _self.updateInOutChart(cfInAndOutResponses);
  273. _self.updateUseChart(popularUserList);
  274. } else {
  275. console.log(success.errorMessage);
  276. }
  277. });
  278. },
  279. // 更新近七日出入库数据
  280. updateDaysChart(dto) {
  281. const _self = this;
  282. if (!isObjectEqual(dto, _self.dayDatas)) {
  283. const xDatas = dto.map((item) => {
  284. const date = new Date(item.day);
  285. const month = (date.getMonth() + 1).toString().padStart(2, "0");
  286. const day = date.getDate().toString().padStart(2, "0");
  287. return `${month}.${day}`;
  288. });
  289. const inDatas = dto.map((item) => item.inCount);
  290. const outDatas = dto.map((item) => item.outCount);
  291. _self.daysChart.setOption({
  292. xAxis: {
  293. data: xDatas,
  294. },
  295. series: [
  296. { name: "入库", data: inDatas },
  297. { name: "出库", data: outDatas },
  298. ],
  299. });
  300. _self.dayDatas = dto;
  301. }
  302. },
  303. // 更新货位数据
  304. updatePositionChart(outDto, inDto) {
  305. const _self = this;
  306. if (
  307. !isObjectEqual(outDto, _self.outDatas) ||
  308. !isObjectEqual(inDto, _self.inDatas)
  309. ) {
  310. const inDatas = [
  311. inDto.toolQuantity,
  312. inDto.equipmentQuantity,
  313. inDto.finishedQuantity,
  314. inDto.stereoscopicQuantity,
  315. inDto.groundQuantity,
  316. ];
  317. const outDatas = [
  318. outDto.toolQuantity,
  319. outDto.equipmentQuantity,
  320. outDto.finishedQuantity,
  321. outDto.stereoscopicQuantity,
  322. outDto.groundQuantity,
  323. ];
  324. _self.positionChart.setOption({
  325. series: [
  326. { name: "入库", data: inDatas },
  327. { name: "出库", data: outDatas },
  328. ],
  329. });
  330. _self.outStockDatas = outDto;
  331. _self.inStockDatas = inDto;
  332. }
  333. },
  334. // 更新年领用数据
  335. updateYearChart(dto) {
  336. const _self = this;
  337. if (!isObjectEqual(dto, _self.yearDatas)) {
  338. const xDatas = dto.map((item) => item.month);
  339. const pickCount = dto.map((item) => item.pickCount);
  340. const clampCount = dto.map((item) => item.clampCount);
  341. const instrumentCount = dto.map((item) => item.instrumentCount);
  342. _self.yearChart.setOption({
  343. xAxis: { data: xDatas },
  344. series: [
  345. { name: "总领用", data: pickCount },
  346. { name: "设备领用", data: clampCount },
  347. { name: "工装领用", data: instrumentCount },
  348. ],
  349. });
  350. _self.yearDatas = dto;
  351. }
  352. },
  353. // 更新出入库类型数据
  354. updateTypeChart(inDto, outDto) {
  355. const _self = this;
  356. if (
  357. !isObjectEqual(inDto, _self.inTypeDatas) ||
  358. !isObjectEqual(outDto, _self.outTypeDatas)
  359. ) {
  360. const seriesData = [
  361. {
  362. name: "工装入库数",
  363. value: inDto.clampQuantity,
  364. },
  365. {
  366. name: "工装出库数",
  367. value: outDto.clampQuantity,
  368. },
  369. {
  370. name: "设备入库数",
  371. value: inDto.instrumentQuantity,
  372. },
  373. {
  374. name: "设备出库数",
  375. value: outDto.instrumentQuantity,
  376. },
  377. {
  378. name: "成品入库数",
  379. value: inDto.productQuantity,
  380. },
  381. {
  382. name: "成品出库数",
  383. value: outDto.productQuantity,
  384. },
  385. ];
  386. _self.typeChart.setOption({
  387. series: [{ name: "类型", data: seriesData }],
  388. });
  389. _self.inTypeDatas = inDto;
  390. _self.outTypeDatas = outDto;
  391. }
  392. },
  393. // 更新热门数据
  394. updateHotChart(dto) {
  395. const _self = this;
  396. if (!isObjectEqual(dto, _self.hotDatas)) {
  397. const datas = dto.slice(0, 5);
  398. const names = datas.map((item) => item.invName || "");
  399. const values = datas.map((item) => Number(item.count) || 0);
  400. while (names.length < 5) names.push("");
  401. while (values.length < 5) values.push(0);
  402. _self.hotChart.setOption({
  403. yAxis: [{ name: "", data: names }],
  404. series: [{ name: "值", data: values }],
  405. });
  406. _self.hotDatas = dto;
  407. }
  408. },
  409. // 更新领用排行数据
  410. updateUseChart(dto) {
  411. const _self = this;
  412. if (!isObjectEqual(dto, _self.useDatas)) {
  413. const datas = dto.slice(0, 5);
  414. const names = datas.map((item) => item.userName || "");
  415. const values = datas.map((item) => Number(item.count) || 0);
  416. while (names.length < 5) names.push("");
  417. while (values.length < 5) values.push(0);
  418. _self.useChart.setOption({
  419. yAxis: [{ name: "", data: names }],
  420. series: [{ name: "值", data: values }],
  421. });
  422. _self.useDatas = dto;
  423. }
  424. },
  425. // 更新出入库数据
  426. updateInOutChart(dtos) {
  427. const _self = this;
  428. if (!dtos || dtos.length === 0) {
  429. _self.recordConfig.data = [];
  430. return;
  431. }
  432. if (!isArrayEqual(dtos, _self.tableDatas)) {
  433. const processedData = dtos.map((item, index) => {
  434. return [
  435. index + 1,
  436. item.name || "",
  437. item.drawNo || "",
  438. item.type || "",
  439. item.inventoryType || "",
  440. item.time || "",
  441. item.userName || "",
  442. ];
  443. });
  444. _self.tableDatas = dtos;
  445. _self.recordConfig.data = JSON.parse(
  446. JSON.stringify(processedData),
  447. );
  448. // 强制更新组件
  449. _self.$nextTick(() => {
  450. if (_self.$refs.scrollBoard) {
  451. _self.$refs.scrollBoard.updateRows(_self.recordConfig.data);
  452. }
  453. });
  454. }
  455. },
  456. // 屏幕自适应
  457. resizeChart() {
  458. const _self = this;
  459. _self.daysChart && _self.daysChart.resize();
  460. _self.positionChart && _self.positionChart.resize();
  461. _self.yearChart && _self.yearChart.resize();
  462. _self.typeChart && _self.typeChart.resize();
  463. _self.hotChart && _self.hotChart.resize();
  464. _self.useChart && _self.useChart.resize();
  465. },
  466. cancalDebounce: debounce(function () {
  467. this.resizeChart();
  468. }, 200),
  469. },
  470. mounted() {
  471. const _self = this;
  472. _self.getWarehouseId();
  473. _self.daysChart = getElement("daysChart");
  474. _self.positionChart = getElement("positionChart");
  475. _self.yearChart = getElement("yearChart");
  476. _self.typeChart = getElement("typeChart");
  477. _self.hotChart = getElement("hotChart");
  478. _self.useChart = getElement("useChart");
  479. _self.$nextTick(() => {
  480. _self.createDaysChart();
  481. _self.createPositionChart();
  482. _self.createYearChart();
  483. _self.createTypeChart();
  484. _self.createHotChart();
  485. _self.createUseChart();
  486. _self.getWarehouseInfo();
  487. window.addEventListener("resize", _self.cancalDebounce);
  488. });
  489. _self.timer = setInterval(() => {
  490. _self.getWarehouseInfo();
  491. }, 3000);
  492. },
  493. beforeUnmount() {
  494. const _self = this;
  495. clearInterval(_self.timer);
  496. _self.timer = null;
  497. },
  498. });
  499. </script>
  500. </body>
  501. </html>