From 928abd3b09e96d21967b5dfbdadb4bcc77e8e6dd Mon Sep 17 00:00:00 2001 From: wenjy Date: Sun, 24 Apr 2022 15:59:36 +0800 Subject: [PATCH] =?UTF-8?q?change=20-=20=E9=97=A8=E4=BD=93=E5=BA=93?= =?UTF-8?q?=E5=8F=AF=E8=A7=86=E5=8C=96=E7=9C=8B=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/StorageController.java | 55 ++++ .../resources/static/css/storage/style.css | 72 +++++ .../resources/static/js/common/scrollTable.js | 245 ++++++++++++++++++ .../main/resources/static/js/storage/index.js | 41 +++ .../resources/templates/storage/index.html | 15 ++ 5 files changed, 428 insertions(+) create mode 100644 productionboard/src/main/resources/static/js/common/scrollTable.js diff --git a/productionboard/src/main/java/com/productionboard/controller/StorageController.java b/productionboard/src/main/java/com/productionboard/controller/StorageController.java index afca7a6..65bc498 100644 --- a/productionboard/src/main/java/com/productionboard/controller/StorageController.java +++ b/productionboard/src/main/java/com/productionboard/controller/StorageController.java @@ -3,6 +3,7 @@ package com.productionboard.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; /** * 门体库仓储看板 @@ -19,4 +20,58 @@ public class StorageController { { return prefix; } + + @GetMapping("/getProductionPlan") + @ResponseBody() + public String productionPlan(){ + String info = + "{\n" + + " \"header\":[\n" + + " \"计划型号\",\n" + + " \"计划数量\",\n" + + "\t\t\"完成数量\",\n" + + " \"差异值\",\n" + + " \"计划进度\"\n" + + " ],\n" + + " \"data\":[\n" + + " [\n" + + " \"20210\",\n" + + " \"50\",\n" + + " \"25\",\n" + + " \"25\",\n" + + " \"50%\"\n" + + " ],\n" + + " [\n" + + " \"20210\",\n" + + " \"50\",\n" + + " \"25\",\n" + + " \"25\",\n" + + " \"50%\"\n" + + " ],\n" + + " [\n" + + " \"20210\",\n" + + " \"50\",\n" + + " \"25\",\n" + + " \"25\",\n" + + " \"50%\"\n" + + " ],\n" + + " [\n" + + " \"20210\",\n" + + " \"50\",\n" + + " \"25\",\n" + + " \"25\",\n" + + " \"50%\"\n" + + " ],\n" + + " [\n" + + " \"20210\",\n" + + " \"50\",\n" + + " \"25\",\n" + + " \"25\",\n" + + " \"50%\"\n" + + " ]\n" + + " ]\n" + + "}"; + + return info; + } } diff --git a/productionboard/src/main/resources/static/css/storage/style.css b/productionboard/src/main/resources/static/css/storage/style.css index 3122ab0..dacdf34 100644 --- a/productionboard/src/main/resources/static/css/storage/style.css +++ b/productionboard/src/main/resources/static/css/storage/style.css @@ -35,4 +35,76 @@ body { .differenceValue { left: 82.9%; color:#A0FF00; +} + +.productionPlan{ + position: absolute; + border: 0px solid red; + width: 33%; + height: 36%; + top: 14.5%; + left: 3.5%; + font-size: 12%; +} + +.theCurrentInventory{ + position: absolute; + border: 0px solid red; + width: 33%; + height: 36%; + bottom: 5%; + left: 3.5%; + font-size: 12%; +} + +.emptyLocation{ + position: absolute; + border: 0px solid red; + width: 4%; + height: 4%; + top: 48.3%; + color:#6BFF71; + font-size: 14%; + display: flex; + align-items: center; + justify-content: center; +} + +.haveUsedLocation{ + position: absolute; + border: 0px solid red; + width: 4%; + height: 4%; + top: 65%; + color:#FF9768; + font-size: 14%; + display: flex; + align-items: center; + justify-content: center; +} + +.emptyLocationRatio{ + position: absolute; + border: 0px solid red; + width: 4%; + height: 4%; + bottom: 10%; + color:#FF9768; + font-size: 14%; + display: flex; + align-items: center; + justify-content: center; +} + +.haveUsedLocationRatio{ + position: absolute; + border: 0px solid red; + width: 4%; + height: 4%; + bottom: 10%; + color:#FF9768; + font-size: 14%; + display: flex; + align-items: center; + justify-content: center; } \ No newline at end of file diff --git a/productionboard/src/main/resources/static/js/common/scrollTable.js b/productionboard/src/main/resources/static/js/common/scrollTable.js new file mode 100644 index 0000000..950975a --- /dev/null +++ b/productionboard/src/main/resources/static/js/common/scrollTable.js @@ -0,0 +1,245 @@ +/** + * dynamicTable 动态表格 + * @param { Object } resource + * @param { String } el : 指定元素 + * @param { Array } header : 表头 + * @param { Array } data : 数据行 + * @param { Number } rowNum : 显示行数 + * @param { Boolean } index : 是否显示索引列 + * @param { Number } timeout : 滚动动画延时 + * @param { String } headerBGC : 标题栏背景颜色 + * @param { String } oddRowBGC : 奇数行背景颜色 + * @param { String } evenRowBGC : 偶数行背景颜色 + * @param { String } fontColor : 字体颜色 + * @param { String } indexBGC : 索引列背景颜色 + * @param { Array } colWidth : 每列的宽度 + */ +let dynamicTable = resource => { + 'use strict'; + + //检查参数类型 + if (typeof resource !== 'object') { + console.error('未传入参数,或者参数不是Object类型'); + return + } + + // 检查是否传入元素 + const ele = resource.el; + if (!ele) { + console.error('元素获取不正确!'); + return + } + /** + * 检查是否传入动画触发时长 + * 当时间小于 10 计算为秒级单位, + * 大于 10 计算为毫秒级单位 + */ + let timeout = resource.timeout; + if (!timeout) { + timeout = 2000 + } else if (timeout < 10) { + timeout = timeout * 1000 + } + + // 检查 配置元素是否传入数据 + const colName = resource.header === undefined ? '' : resource.header; + const rowData = resource.data === undefined ? '' : resource.data; + const rowNum = resource.rowNum === undefined ? '20%' : 100 / resource.rowNum + '%'; + const headerBGC = resource.headerBGC === undefined ? '#999' : resource.headerBGC; + const oddRowBGC = resource.oddRowBGC === undefined ? '#bbb' : resource.oddRowBGC; + const evenRowBGC = resource.evenRowBGC === undefined ? '#ddd' : resource.evenRowBGC; + const fontColor = resource.fontColor === undefined ? 'black' : resource.fontColor; + const indexBGC = resource.indexBGC === undefined ? '#555' : resource.indexBGC; + const colIndex = resource.index === undefined ? true : resource.index; + const colWidth = resource.colWidth === undefined ? false : resource.colWidth; + const indexColor = fontColor.search(/('black')|(0{3,6})/) ? "white" : fontColor; + + //基本table html + const html = ` +
+
+
+
+
+
+ `; + //Css样式集 + const boxCSS = { + overflow: 'hidden', + background: headerBGC + }; + const tableCSS = { + color: fontColor, + width: '100%', + height: '100%' + }; + const theadCSS = { + width: '100%', + height: '20%' + }; + const thead_trCSS = { + display: "flex", + flexWrap: "nowrap", + width: "100%", + height: "100%", + background: headerBGC, + justifyContent: "space-around" + }; + const thCSS = { + justifyContent: "space-around", + fontWeight: "bold" + }; + const tbodyCSS = { + width: "100%", + height: '80%', + boxSizing: 'border-box' + }; + const tbody_trCSS = { + flexWrap: "nowrap", + width: "100%", + height: rowNum, + justifyContent: "space-around" + }; + const trOddCSS = { + display: "flex", + background: oddRowBGC + }; + const trEvenCSS = { + display: "flex", + background: evenRowBGC + }; + const th_tdCSS = { + margin: 'auto', + whiteSpace: 'nowrap', + overflow: "hidden", + textOverflow: 'ellipsis', + textAlign: 'center', + padding: '0 4px 0 4px' + }; + const indexCSS = { + display: 'inline-block', + width: '90%', + height: "90%", + background: indexBGC, + color: indexColor, + borderRadius: '20%', + margin: 'auto' + }; + //插入table元素 + $(ele).append(html); + + //核心代码 + //遍历插入数据 表头 + if (colIndex) { + $(ele + '>.table>.thead>.tr').append('
#
') + } + colName.forEach(element => { + $(ele + '>.table>.thead>.tr').append(`
${element}
`) + }); + + //遍历插入数据 数据行 + for (let i = 0; i < rowData.length; i++) { + + $(ele + '>.table>.tbody').append('
'); + if (colIndex) { + $(ele + '>.table>.tbody>.tr:eq(' + i + ')').append( + `
${i+1}
`) + } + rowData[i].forEach(element => { + if (element == "一级") { + $(ele + '>.table>.tbody>.tr:eq(' + i + ')').append( + `
一级报警
` + ) + } else if (element == "二级") { + $(ele + '>.table>.tbody>.tr:eq(' + i + ')').append( + `
二级报警
` + ) + } else if (element == "三级") { + $(ele + '>.table>.tbody>.tr:eq(' + i + ')').append( + `
三级报警
` + ) + } else if (element == "未处理") { + $(ele + '>.table>.tbody>.tr:eq(' + i + ')').append( + `
${element}
` + ) + } else if (element == "处理中") { + $(ele + '>.table>.tbody>.tr:eq(' + i + ')').append( + `
${element}
` + ) + } else if (element == "已结束") { + $(ele + '>.table>.tbody>.tr:eq(' + i + ')').append( + `
${element}
` + ) + } else { + $(ele + '>.table>.tbody>.tr:eq(' + i + ')').append(`
${element}
`) + } + + }) + + } + + //设置CSS样式 + $(ele).css(boxCSS); + $(ele + '>.table').css(tableCSS); + $(ele + '>.table>.thead').css(theadCSS); + $(ele + '>.table>.thead>.tr').css(thead_trCSS); + $(ele + '>.table>.thead>.tr>.th').css(th_tdCSS).css(thCSS); + $(ele + '>.table>.tbody').css(tbodyCSS); + $(ele + '>.table>.tbody>.tr').css(tbody_trCSS); + $(ele + '>.table>.tbody>.tr:odd').css(trOddCSS); + $(ele + '>.table>.tbody>.tr:even').css(trEvenCSS); + $(ele + '>.table>.tbody>.tr>.td').css(th_tdCSS); + $(ele + '>.table span.index').css(indexCSS) + + //统一计量单位 + const emptyUnit = element => element.replace(/[^0-9]/g, ''); + const hendlen = $(`${ele}>.table>.thead>.tr>.th`).length; + const bodylen = $(`${ele}>.table>.tbody>.tr:nth-child(1)>.td`).length; + const ceil = Math.ceil; + + /** + * 设置每列的宽度 + * eq() 是在匹配的元素中取下标为n的元素 + * nth-child() 是在匹配元素的父元素中选择第n个元素 + */ + if (!colWidth) { + $(`${ele}>.table>.thead>.tr>.th`).css({ + width: ceil(100 / hendlen) + '%' + }); + $(`${ele}>.table>.tbody>.tr>.td`).css({ + width: ceil(100 / bodylen) + '%' + }); + } else { + for (let i = 0; i < colWidth.length; i++) { + let emptyUnitColWidth = emptyUnit(colWidth[i]); + $(`${ele}>.table>.thead>.tr>.th:nth-child(${i+1})`).width(emptyUnitColWidth); + $(`${ele}>.table>.tbody>.tr>.td:nth-child(${i+1})`).width(emptyUnitColWidth); + } + } + + //奇偶校验 --> 处理最后一行是奇数的问题 + let oddORevenCheck = $(`${ele}>.table>.tbody>.tr`).length % 2 == 0 ? 'even' : 'odd'; + //滚动动画 + setInterval(function() { + $(ele + '>.table>.tbody>.tr:eq(0)').slideToggle(100, function() { + switch (oddORevenCheck) { + case 'even': + $(this).clone().css(trEvenCSS).appendTo(ele + '>.table>.tbody'); + oddORevenCheck = 'odd'; + break; + case 'odd': + $(this).clone().css(trOddCSS).appendTo(ele + '>.table>.tbody'); + oddORevenCheck = 'even'; + break; + } + $(this).remove(); + }); + }, timeout); + + // 组件销毁钩子 + $(`${ele}`).bind('DOMNodeRemoved', (e) => { + if (e.target.classList[0] === 'asit-table') { + clearInterval(timer); + } + }); +} diff --git a/productionboard/src/main/resources/static/js/storage/index.js b/productionboard/src/main/resources/static/js/storage/index.js index 44d61bc..8632fd2 100644 --- a/productionboard/src/main/resources/static/js/storage/index.js +++ b/productionboard/src/main/resources/static/js/storage/index.js @@ -1,4 +1,45 @@ $(()=>{ //单日出入库统计 storageStatistics(123,233,211,124); + + //生产计划 + $.ajax({ + url: '/storage/getProductionPlan', + type: 'GET', + dataType: 'JSON', + success: function(res) { + dynamicTable({ + el: '#productionPlan', + rowNum: 5, + timeout: 0, + header: res.header, + data: res.data, + index: false, + fontColor: '#B4B7BF ', + indexBGC: '#86F3FF', + headerBGC: 'rgba(8,36,75,0.2)', + oddRowBGC: 'rgba(8,36,75,0.2)', + evenRowBGC: 'rgba(6,25,57,0.2)', + colWidth: ['100%', '100%', '100%', '100%','100%'] + }); + }, + error: function(e) { + console.log(e) + } + }); + + //当前库存统计 + multipleThreeDimensionalCylindrical(null,document.getElementById("theCurrentInventory")); + + //库存统计 + $("#emptyLocation-left").text(123); + $("#emptyLocation-right").text(456); + $("#haveUsedLocation-left").text(789); + $("#haveUsedLocation-right").text(1234); + + //库位占比 + $("#emptyLocationNumber").text(68); + $("#emptyLocationRatio").text("39%"); + $("#haveUsedLocationNumber").text(132); + $("#haveUsedLocationRatio").text("61%"); }) \ No newline at end of file diff --git a/productionboard/src/main/resources/templates/storage/index.html b/productionboard/src/main/resources/templates/storage/index.html index 1ae0f63..50d9641 100644 --- a/productionboard/src/main/resources/templates/storage/index.html +++ b/productionboard/src/main/resources/templates/storage/index.html @@ -11,17 +11,32 @@ + +
+
+
+
+
+
+ + +
+
+ +
+
+ \ No newline at end of file