New file |
| | |
| | | package com.zy.asrs.controller; |
| | | |
| | | import com.core.common.R; |
| | | import com.zy.common.utils.News; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping("/news") |
| | | public class NewsController { |
| | | @RequestMapping("/print") |
| | | public synchronized R print(){ |
| | | return R.ok().add(News.print()); |
| | | } |
| | | } |
New file |
| | |
| | | package com.zy.common.utils; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.lang.reflect.Array; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * news stories for zoneyung |
| | | * Created by vincent on 2022/12/22 |
| | | */ |
| | | @Slf4j |
| | | public class News { |
| | | |
| | | public static void main(String[] args) { |
| | | News.info("info{}", 1); |
| | | News.warn("warn{}", 2); |
| | | News.error("error{}", 3); |
| | | System.out.println(News.print()); |
| | | } |
| | | |
| | | interface NewsSupport<T> { boolean execute(T t); } |
| | | |
| | | private static final NewsQueue<NewsDomain> NEWS_QUEUE = new NewsQueue<>(NewsDomain.class, 1024); |
| | | |
| | | @SuppressWarnings({"unchecked"}) |
| | | static class NewsQueue<T> { |
| | | |
| | | private final transient Class<T> cls; |
| | | private final T[] arr; |
| | | private final int capacity; |
| | | private int head; |
| | | private int tail; |
| | | |
| | | { this.head = 0; this.tail = 0; } |
| | | |
| | | public NewsQueue(Class<T> cls, int capacity) { |
| | | this.cls = cls; |
| | | this.arr = (T[]) Array.newInstance(cls, capacity); |
| | | this.capacity = capacity; |
| | | } |
| | | |
| | | public synchronized boolean offer(T t) { |
| | | if (this.tail == this.capacity) { |
| | | this.peek(); |
| | | } |
| | | this.reform(); |
| | | this.arr[this.tail] = t; |
| | | this.tail ++; |
| | | return true; |
| | | } |
| | | |
| | | public synchronized boolean put(T t) { |
| | | if (this.tail == this.capacity) { |
| | | return false; |
| | | } else { |
| | | this.reform(); |
| | | } |
| | | this.arr[this.tail] = t; |
| | | this.tail ++; |
| | | return true; |
| | | } |
| | | |
| | | public synchronized T peek() { |
| | | if (this.head == this.tail) { |
| | | return null; |
| | | } |
| | | T t = this.arr[this.head]; |
| | | this.head ++; |
| | | this.reform(); |
| | | return t; |
| | | } |
| | | |
| | | private void reform() { |
| | | for (int i = this.head; i < this.tail; i++) { |
| | | this.arr[i-this.head] = this.arr[i]; |
| | | } |
| | | this.tail -= this.head; |
| | | this.head = 0; |
| | | } |
| | | |
| | | public synchronized int size() { |
| | | return this.tail - this.head; |
| | | } |
| | | |
| | | public synchronized List<T> data() { |
| | | T[] ts = (T[]) Array.newInstance(this.cls, size()); |
| | | if (this.tail - this.head >= 0) { |
| | | System.arraycopy(this.arr, this.head, ts, 0, this.tail - this.head); |
| | | } |
| | | return Arrays.asList(ts); |
| | | } |
| | | |
| | | } |
| | | |
| | | public static void info(String format, Object... arguments) { |
| | | log.info(format, arguments); |
| | | offer(NewsLevel.INFO, format, arguments); |
| | | } |
| | | |
| | | public static void warn(String format, Object... arguments) { |
| | | log.warn(format, arguments); |
| | | offer(NewsLevel.WARN, format, arguments); |
| | | } |
| | | |
| | | public static void error(String format, Object... arguments) { |
| | | log.error(format, arguments); |
| | | offer(NewsLevel.ERROR, format, arguments); |
| | | } |
| | | |
| | | public static void infoNoLog(String format, Object... arguments) { |
| | | offer(NewsLevel.INFO, format, arguments); |
| | | } |
| | | |
| | | public static void warnNoLog(String format, Object... arguments) { |
| | | offer(NewsLevel.WARN, format, arguments); |
| | | } |
| | | |
| | | public static void errorNoLog(String format, Object... arguments) { |
| | | offer(NewsLevel.ERROR, format, arguments); |
| | | } |
| | | |
| | | public static String printStr() { |
| | | StringBuilder sb = new StringBuilder("["); |
| | | List<NewsDomain> domains = NEWS_QUEUE.data(); |
| | | for (int i = 0; i < domains.size(); i++) { |
| | | NewsDomain domain = domains.get(i); |
| | | sb.append("{"); |
| | | sb.append("\"l\":").append(domain.level.idx).append(","); |
| | | sb.append("\"v\":\"").append(domain.content).append("\"").append(","); |
| | | sb.append("\"t\":\"").append(domain.date).append("\""); |
| | | sb.append("}"); |
| | | if (i < domains.size() - 1) { |
| | | sb.append(","); |
| | | } |
| | | } |
| | | sb.append("]"); |
| | | return sb.toString(); |
| | | } |
| | | |
| | | public static List<Map<String, Object>> print() { |
| | | List<Map<String, Object>> res = new ArrayList<>(); |
| | | for (NewsDomain datum : NEWS_QUEUE.data()) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("l", datum.level.idx); |
| | | map.put("v", datum.content); |
| | | map.put("t", datum.date); |
| | | res.add(map); |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | private static boolean offer(NewsLevel level, String msg, Object[] args) { |
| | | return NEWS_QUEUE.offer(new NewsDomain(level, replace(msg, args), (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()))); |
| | | } |
| | | |
| | | private static String replace(String str, Object[] objs){ |
| | | if (null == objs || objs.length == 0 || null == str || "".equals(str.trim())) { |
| | | return str; |
| | | } else { |
| | | StringBuilder sb = new StringBuilder(str); |
| | | for (Object obj : objs) { |
| | | int idx = sb.indexOf("{}"); |
| | | if (idx == -1) { break; } |
| | | sb.replace(idx, idx + 2, String.valueOf(obj)); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | } |
| | | |
| | | static class NewsDomain { |
| | | public NewsLevel level; |
| | | public String content; |
| | | public String date; |
| | | |
| | | public NewsDomain(NewsLevel level, String content, String date) { |
| | | this.level = level; |
| | | this.content = content; |
| | | this.date = date; |
| | | } |
| | | } |
| | | |
| | | enum NewsLevel { |
| | | INFO(1), |
| | | WARN(2), |
| | | ERROR(3), |
| | | ; |
| | | public int idx; |
| | | NewsLevel(int idx) { |
| | | this.idx = idx; |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | /** |
| | | * 工位1有物 |
| | | */ |
| | | public Short loaded1; |
| | | public boolean loaded1; |
| | | |
| | | /** |
| | | * RGV当前位置 |
| | |
| | | import com.core.common.SpringUtils; |
| | | import com.zy.asrs.entity.BasRgv; |
| | | |
| | | import com.zy.asrs.service.BasRgvErrService; |
| | | import com.zy.asrs.service.BasRgvService; |
| | | |
| | | import com.zy.common.utils.News; |
| | | import com.zy.core.RgvThread; |
| | | import com.zy.core.cache.MessageQueue; |
| | | import com.zy.core.cache.OutputQueue; |
| | |
| | | rgvProtocol.setStatus((short)-1); |
| | | rgvProtocol.setTaskNo1((short)0); |
| | | rgvProtocol.setStatus1((short)-1); |
| | | rgvProtocol.setLoaded1((short)0); |
| | | rgvProtocol.setLoaded1(false); |
| | | rgvProtocol.setWalkPos((short)0); |
| | | rgvProtocol.setRgvPos(0); |
| | | // rgvProtocol.setTaskNo2((short)0); |
| | |
| | | rgvProtocol.setAlarm(siemensNet.getByteTransform().TransInt16(result.Content, 8)); |
| | | rgvProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 10)); |
| | | rgvProtocol.setSpeed(siemensNet.getByteTransform().TransInt16(result.Content, 12)); |
| | | rgvProtocol.setRgvPos((int) siemensNet.getByteTransform().TransInt16(result.Content, 14)); |
| | | rgvProtocol.setRgvPos(siemensNet.getByteTransform().TransInt32(result.Content, 14)); |
| | | rgvProtocol.setLoaded1(siemensNet.getByteTransform().TransBool(result.Content,18)); |
| | | |
| | | |
| | | OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), slave.getId())); |
| | | if (rgvProtocol.getAlarm() > 0 ){ |
| | | BasRgvErrService basRgvErrService = SpringUtils.getBean(BasRgvErrService.class); |
| | | News.error("RGV 异常 ===>> [id:{}] [ip:{}],报警代码:{},报警文本",slave.getId(), slave.getIp(),rgvProtocol.getAlarm(),basRgvErrService.selectById(rgvProtocol.getAlarm())); |
| | | }else { |
| | | News.info("正常"); |
| | | } |
| | | |
| | | // 工位1复位信号 |
| | | // if (rgvProtocol.getStatusType1().equals(RgvStatusType.WAITING) |
| | |
| | | background-color: rgb(108,167,168); |
| | | } |
| | | .head { |
| | | height: 10%; |
| | | height: 5%; |
| | | width: 100%; |
| | | color: #FFFFFF; |
| | | } |
| | |
| | | "left": 401, |
| | | "width": 49, |
| | | "height": 20 |
| | | }, { |
| | | "type": "track", |
| | | "id": "lb_trCart21", |
| | | "text": "", |
| | | "top": 45, |
| | | "left": 1490, |
| | | "width": 6, |
| | | "height": 630 |
| | | }, { |
| | | "type": "track", |
| | | "id": "lb_trCart22", |
| | | "text": "", |
| | | "top": 45, |
| | | "left": 1544, |
| | | "width": 6, |
| | | "height": 630 |
| | | }, { |
| | | }, |
| | | // { |
| | | // "type": "track", |
| | | // "id": "lb_trCart21", |
| | | // "text": "", |
| | | // "top": 45, |
| | | // "left": 1490, |
| | | // "width": 6, |
| | | // "height": 630 |
| | | // }, { |
| | | // "type": "track", |
| | | // "id": "lb_trCart22", |
| | | // "text": "", |
| | | // "top": 45, |
| | | // "left": 1544, |
| | | // "width": 6, |
| | | // "height": 630 |
| | | // }, |
| | | { |
| | | "type": "stn", |
| | | "id": "site-403", |
| | | "text": "403", |
| | |
| | | "id": "lb_trCart21", |
| | | "text": "", |
| | | "top": 45, |
| | | "left": 1490, |
| | | "left": 1510, |
| | | "width": 6, |
| | | "height": 630 |
| | | "height": 800 |
| | | }, { |
| | | "type": "track", |
| | | "id": "lb_trCart22", |
| | | "text": "", |
| | | "top": 45, |
| | | "left": 1544, |
| | | "left": 1554, |
| | | "width": 6, |
| | | "height": 630 |
| | | "height": 800 |
| | | }, { |
| | | "type": "track", |
| | | "id": "lb_trCart23", |
| | | "text": "", |
| | | "top": 45, |
| | | "left": 1510, |
| | | "width": 44, |
| | | "height": 6 |
| | | }, { |
| | | "type": "track", |
| | | "id": "lb_trCart24", |
| | | "text": "", |
| | | "top": 839, |
| | | "left": 1510, |
| | | "width": 44, |
| | | "height": 6 |
| | | } |
| | | , { |
| | | "type": "stn", |
| | | "id": "site-407", |
| | | "text": "407", |
| | | "top": 480, |
| | | "left": 1554, |
| | | "top": 770, |
| | | "left": 1437, |
| | | "width": 49, |
| | | "height": 20 |
| | | }, { |
| | | "type": "stn", |
| | | "id": "site-406", |
| | | "text": "406", |
| | | "top": 528, |
| | | "left": 1554, |
| | | "top": 795, |
| | | "left": 1437, |
| | | "width": 49, |
| | | "height": 20 |
| | | }, { |
| | | "type": "stn", |
| | | "id": "site-307", |
| | | "text": "307", |
| | | "top": 594, |
| | | "left": 1554, |
| | | "top": 700, |
| | | "left": 1437, |
| | | "width": 49, |
| | | "height": 20 |
| | | }, { |
| | | "type": "stn", |
| | | "id": "site-306", |
| | | "text": "306", |
| | | "top": 642, |
| | | "left": 1554, |
| | | "top": 725, |
| | | "left": 1437, |
| | | "width": 49, |
| | | "height": 20 |
| | | }, { |
| | |
| | | "text": "1", |
| | | "top": 157, |
| | | "left": 1489, |
| | | "width": 62, |
| | | "width": 40, |
| | | "height": 20 |
| | | }, { |
| | | "type": "stn", |
| | |
| | | "text": "2", |
| | | "top": 257, |
| | | "left": 1489, |
| | | "width": 62, |
| | | "width": 40, |
| | | "height": 20 |
| | | }, { |
| | | "type": "stn", |
| | |
| | | "text": "3", |
| | | "top": 357, |
| | | "left": 1489, |
| | | "width": 62, |
| | | "width": 40, |
| | | "height": 20 |
| | | }, { |
| | | "type": "stn", |
| | |
| | | "text": "4", |
| | | "top": 457, |
| | | "left": 1489, |
| | | "width": 62, |
| | | "height": 20 |
| | | }, { |
| | | "type": "stn", |
| | | "id": "site-5", |
| | | "text": "5", |
| | | "top": 557, |
| | | "left": 1489, |
| | | "width": 62, |
| | | "width": 40, |
| | | "height": 20 |
| | | }] |
| | | }] |
| | |
| | | <span class="site-unauto">非自动/手动</span> |
| | | </div> |
| | | </div> |
| | | <div class="bar-code"> |
| | | <div class="body-head" id="code">条码扫描器</div> |
| | | <div class="tablebox"> |
| | | <div class="table-head"> |
| | | <li><span>条码名称</span><span class="right">扫码时间</span></li> |
| | | </div> |
| | | <div id="barcode1" class="table-body"> |
| | | <!-- <div class="bar-code">--> |
| | | <!-- <div class="body-head" id="code">条码扫描器</div>--> |
| | | <!-- <div class="tablebox">--> |
| | | <!-- <div class="table-head">--> |
| | | <!-- <li><span>条码名称</span><span class="right">扫码时间</span></li>--> |
| | | <!-- </div>--> |
| | | <!-- <div id="barcode1" class="table-body">--> |
| | | |
| | | </div> |
| | | </div> |
| | | <div class="tablebox"> |
| | | <div class="table-head"> |
| | | <li><span>条码名称</span><span class="right">扫码时间</span></li> |
| | | </div> |
| | | <div id="barcode2" class="table-body"> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="tablebox">--> |
| | | <!-- <div class="table-head">--> |
| | | <!-- <li><span>条码名称</span><span class="right">扫码时间</span></li>--> |
| | | <!-- </div>--> |
| | | <!-- <div id="barcode2" class="table-body">--> |
| | | |
| | | </div> |
| | | </div> |
| | | <div class="tablebox"> |
| | | <div class="table-head"> |
| | | <li><span>条码名称</span><span class="right">扫码时间</span></li> |
| | | </div> |
| | | <div id="barcode3" class="table-body"> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="tablebox">--> |
| | | <!-- <div class="table-head">--> |
| | | <!-- <li><span>条码名称</span><span class="right">扫码时间</span></li>--> |
| | | <!-- </div>--> |
| | | <!-- <div id="barcode3" class="table-body">--> |
| | | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | </div> |
| | | <!-- 堆垛机弹窗 --> |
| | | <div id="crnWindow" style="display: none;" class="animate__animated animate__fadeIn"> |
| | |
| | | var systemRunning = true; |
| | | |
| | | |
| | | // news();layx.min('wcs-news'); |
| | | // function news() { |
| | | // layx.iframe( |
| | | // 'wcs-news' // id |
| | | // , '系统分析报告' |
| | | // , "news.html" |
| | | // , { |
| | | // shadow:false |
| | | // , storeStatus:false |
| | | // // , skin: 'news' |
| | | // , width:800 |
| | | // , height:600 |
| | | // , position:'rb' |
| | | // // , control:false |
| | | // , opacity:0.9 |
| | | // , border:false |
| | | // , icon:'<img src="../../static/wcs/images/zy-logo.png" style="height:22px;display:block;" alt=""/>' |
| | | // , stickMenu:true |
| | | // , maxMenu:false |
| | | // , closeMenu:false |
| | | // , moveLimit:{ |
| | | // leftOut: false, |
| | | // rightOut: false, |
| | | // topOut: false, |
| | | // bottomOut: false, |
| | | // } |
| | | // , minWidth:300 |
| | | // , minHeight:300 |
| | | // , borderRadius: '8px' |
| | | // , shadeDestroy:true |
| | | // , escKey: false |
| | | // , event:{ |
| | | // onmin: { |
| | | // after: function () { |
| | | // $('.layx-min-statu').css("left", "inherit").css("right", "10px") |
| | | // } |
| | | // } |
| | | // , onrestore:{ |
| | | // after: function () { |
| | | // let win = layx.getFrameContext('wcs-news'); |
| | | // win.autoScroll = true |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // ); |
| | | // } |
| | | news();layx.open('wcs-news'); |
| | | function news() { |
| | | layx.iframe( |
| | | 'wcs-news' // id |
| | | , '系统分析报告' |
| | | , "news.html" |
| | | , { |
| | | shadow:false |
| | | , storeStatus:false |
| | | // , skin: 'news' |
| | | , width:600 |
| | | , height:400 |
| | | , position:'rb' |
| | | // , control:false |
| | | , opacity:0.9 |
| | | , border:false |
| | | , icon:'<img src="../../static/wcs/images/zy-logo.png" style="height:22px;display:block;" alt=""/>' |
| | | , stickMenu:true |
| | | , maxMenu:false |
| | | , closeMenu:false |
| | | , moveLimit:{ |
| | | leftOut: false, |
| | | rightOut: false, |
| | | topOut: false, |
| | | bottomOut: false, |
| | | } |
| | | , minWidth:300 |
| | | , minHeight:300 |
| | | , borderRadius: '8px' |
| | | , shadeDestroy:true |
| | | , escKey: false |
| | | , event:{ |
| | | onmin: { |
| | | after: function () { |
| | | $('.layx-min-statu').css("left", "inherit").css("right", "10px") |
| | | } |
| | | } |
| | | , onrestore:{ |
| | | after: function () { |
| | | let win = layx.getFrameContext('wcs-news'); |
| | | win.autoScroll = true |
| | | } |
| | | } |
| | | } |
| | | } |
| | | ); |
| | | } |
| | | </script> |
| | | </html> |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>NEWS</title> |
| | | <style> |
| | | /** {*/ |
| | | /* padding: 0;*/ |
| | | /* margin: 0;*/ |
| | | /*}*/ |
| | | .container { |
| | | height: 100%; |
| | | width: 100%; |
| | | } |
| | | /*=============== SCROLL UP ===============*/ |
| | | .scrollup { |
| | | text-decoration: none; |
| | | text-align: center; |
| | | width: 25px; |
| | | height: 18px; |
| | | position: fixed; |
| | | right: 1rem; |
| | | bottom: -55%; |
| | | background-color: rgb(108,167,168); |
| | | box-shadow: 0 8px 12px hsla(228, 66%, 45%, .1); |
| | | display: inline-flex; |
| | | padding: .35rem; |
| | | border-radius: .25rem; |
| | | color: #ffffff; |
| | | z-index: 10; |
| | | transition: .3s; |
| | | font-size: 8px; |
| | | } |
| | | .scrollup:hover { |
| | | transform: translateY(-.25rem); |
| | | } |
| | | /* Show Scroll Up*/ |
| | | .show-scroll { |
| | | bottom: 5%; |
| | | } |
| | | |
| | | .news-desc { |
| | | font-size: 14px; |
| | | } |
| | | .level-1 { |
| | | color: #333333; |
| | | } |
| | | .level-2 { |
| | | color: #0087ec; |
| | | } |
| | | .level-3 { |
| | | color: red; |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <div class="container"> |
| | | |
| | | </div> |
| | | <a class="scrollup" id="scroll-up"> |
| | | <span>顶部</span> |
| | | </a> |
| | | </body> |
| | | <script src="../../static/wcs/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script src="../../static/wcs/js/handlebars/handlebars-v4.5.3.js"></script> |
| | | <script src="../../static/wcs/js/common.js"></script> |
| | | <script> |
| | | var autoScroll = true; |
| | | |
| | | function scrollUp(){ |
| | | const scrollUp = document.getElementById('scroll-up'); |
| | | if(this.scrollY >= 100) scrollUp.classList.add('show-scroll'); else scrollUp.classList.remove('show-scroll') |
| | | } |
| | | window.addEventListener('scroll', scrollUp) |
| | | |
| | | $(document).on('click ','#scroll-up', function () { |
| | | window.scrollTo(0, 0); |
| | | autoScroll = false; |
| | | }) |
| | | |
| | | $(document).on('click ','body', function () { |
| | | autoScroll = false; |
| | | }) |
| | | |
| | | setInterval(()=>{ |
| | | $.ajax({ |
| | | url: baseUrl + "/news/print", |
| | | // headers: {'token': localStorage.getItem('token')}, |
| | | method: 'GET', |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | let template = Handlebars.compile($('#newsTpl').html()); |
| | | $('.container').html(template({list: res.data})); |
| | | if (autoScroll) { |
| | | window.scrollTo(0, document.body.scrollHeight) |
| | | } |
| | | } else if (res.code === 403) { |
| | | window.location.href = baseUrl + "/login"; |
| | | } else { |
| | | console.error(res.msg); |
| | | } |
| | | } |
| | | }) |
| | | }, 1000) |
| | | |
| | | </script> |
| | | <script type="text/template" id="newsTpl"> |
| | | {{#each list}} |
| | | <div class="news-desc level-{{l}}"> |
| | | <span>{{t}}</span> - <span>{{v}}</span> |
| | | </div> |
| | | {{/each}} |
| | | </script> |
| | | </html> |