From 3071c572ff0b019abc53d89538791d5da81a06f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=AB=E7=8C=ABguowen?= <9290821+guowen-the-cat@user.noreply.gitee.com> Date: Sun, 28 Sep 2025 16:50:02 +0800 Subject: [PATCH] =?UTF-8?q?2D=E7=9B=91=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/ruoyi/RuoYiApplication.java | 11 +- .../controller/LargeScreenDdjController.java | 37 + .../service/ILargeScreenDdjService.java | 18 + .../impl/LargeScreenDdjServiceImpl.java | 51 + ruoyi-ui/public/monitor/css/style.css | 344 +++ ruoyi-ui/public/monitor/img/Gssj.png | Bin 0 -> 1486 bytes ruoyi-ui/public/monitor/img/Lssj.png | Bin 0 -> 6341 bytes ruoyi-ui/public/monitor/img/ddj.png | Bin 0 -> 5756 bytes ruoyi-ui/public/monitor/img/gd.png | Bin 0 -> 10662 bytes ruoyi-ui/public/monitor/img/rgv.png | Bin 0 -> 7724 bytes ruoyi-ui/public/monitor/index.html | 59 + ruoyi-ui/public/monitor/js/index.js | 1855 +++++++++++++++++ .../public/monitor/js/jquery-3.1.1.min.js | 4 + ruoyi-ui/public/monitor/js/main.js | 1337 ++++++++++++ ruoyi-ui/public/monitor/js/request.js | 52 + ruoyi-ui/public/monitor/json/Lssj.json | 69 + ruoyi-ui/public/monitor/json/alarm.json | 29 + ruoyi-ui/public/monitor/json/config.json | 349 ++++ ruoyi-ui/public/monitor/json/ddj.json | 55 + ruoyi-ui/public/monitor/json/rgv.json | 23 + ruoyi-ui/src/assets/styles/index.scss | 1 + .../src/views/largeScreen/monitor/index.vue | 24 + ruoyi-ui/vue.config.js | 107 +- 23 files changed, 4359 insertions(+), 66 deletions(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/largeScreen/controller/LargeScreenDdjController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/largeScreen/service/ILargeScreenDdjService.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/largeScreen/service/impl/LargeScreenDdjServiceImpl.java create mode 100644 ruoyi-ui/public/monitor/css/style.css create mode 100644 ruoyi-ui/public/monitor/img/Gssj.png create mode 100644 ruoyi-ui/public/monitor/img/Lssj.png create mode 100644 ruoyi-ui/public/monitor/img/ddj.png create mode 100644 ruoyi-ui/public/monitor/img/gd.png create mode 100644 ruoyi-ui/public/monitor/img/rgv.png create mode 100644 ruoyi-ui/public/monitor/index.html create mode 100644 ruoyi-ui/public/monitor/js/index.js create mode 100644 ruoyi-ui/public/monitor/js/jquery-3.1.1.min.js create mode 100644 ruoyi-ui/public/monitor/js/main.js create mode 100644 ruoyi-ui/public/monitor/js/request.js create mode 100644 ruoyi-ui/public/monitor/json/Lssj.json create mode 100644 ruoyi-ui/public/monitor/json/alarm.json create mode 100644 ruoyi-ui/public/monitor/json/config.json create mode 100644 ruoyi-ui/public/monitor/json/ddj.json create mode 100644 ruoyi-ui/public/monitor/json/rgv.json create mode 100644 ruoyi-ui/src/views/largeScreen/monitor/index.vue diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java index a5b62cd8..e95a574f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java @@ -21,15 +21,6 @@ public class RuoYiApplication { // System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(RuoYiApplication.class, args); - System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" + - " .-------. ____ __ \n" + - " | _ _ \\ \\ \\ / / \n" + - " | ( ' ) | \\ _. / ' \n" + - " |(_ o _) / _( )_ .' \n" + - " | (_,_).' __ ___(_ o _)' \n" + - " | |\\ \\ | || |(_,_)' \n" + - " | | \\ `' /| `-' / \n" + - " | | \\ / \\ / \n" + - " ''-' `'-' `-..-' "); + System.out.println("(♥◠‿◠)ノ゙ 福来瑞达WCS系统启动成功 ლ(´ڡ`ლ)゙ "); } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/largeScreen/controller/LargeScreenDdjController.java b/ruoyi-admin/src/main/java/com/ruoyi/largeScreen/controller/LargeScreenDdjController.java new file mode 100644 index 00000000..4e90d354 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/largeScreen/controller/LargeScreenDdjController.java @@ -0,0 +1,37 @@ +package com.ruoyi.largeScreen.controller; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.ruoyi.common.annotation.Anonymous; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.largeScreen.service.ILargeScreenDdjService; + +/** + * 大屏堆垛机数据Controller + * + * @author ruoyi + */ +@RestController +@RequestMapping("/largeScreen/ddj") +public class LargeScreenDdjController { + @Autowired + private ILargeScreenDdjService largeScreenDdjService; + + /** + * 查询堆垛机数据列表 + */ + @GetMapping("/list") + public AjaxResult list() { + Map result = new HashMap<>(); + result.put("msg", "操作成功"); + result.put("code", 0); + result.put("data", largeScreenDdjService.queryDdjList()); + return AjaxResult.success(result); + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/largeScreen/service/ILargeScreenDdjService.java b/ruoyi-admin/src/main/java/com/ruoyi/largeScreen/service/ILargeScreenDdjService.java new file mode 100644 index 00000000..c5091ea3 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/largeScreen/service/ILargeScreenDdjService.java @@ -0,0 +1,18 @@ +package com.ruoyi.largeScreen.service; + +import java.util.List; +import java.util.Map; + +/** + * 大屏堆垛机数据Service接口 + * + * @author ruoyi + */ +public interface ILargeScreenDdjService { + /** + * 查询堆垛机数据列表 + * + * @return 堆垛机数据列表 + */ + public List> queryDdjList(); +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/largeScreen/service/impl/LargeScreenDdjServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/largeScreen/service/impl/LargeScreenDdjServiceImpl.java new file mode 100644 index 00000000..1914ab6e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/largeScreen/service/impl/LargeScreenDdjServiceImpl.java @@ -0,0 +1,51 @@ +package com.ruoyi.largeScreen.service.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.device.ddj.domain.MsgDdj; +import com.ruoyi.device.ddj.mapper.MsgDdjMapper; +import com.ruoyi.largeScreen.service.ILargeScreenDdjService; + +/** + * 大屏堆垛机数据Service业务层处理 + * + * @author ruoyi + */ +@Service +public class LargeScreenDdjServiceImpl implements ILargeScreenDdjService { + @Autowired + private MsgDdjMapper msgDdjMapper; + + /** + * 查询堆垛机数据列表 + * + * @return 堆垛机数据列表 + */ + @Override + public List> queryDdjList() { + List ddjList = msgDdjMapper.selectMsgDdjList(null); + List> resultList = new ArrayList<>(); + + for (MsgDdj ddj : ddjList) { + Map map = new HashMap<>(); + map.put("id", ddj.getId().toString()); + map.put("name", ddj.getName()); + map.put("zxjd", ddj.getJdbz().toString()); + map.put("sbzt", ddj.getSbzt().toString()); + map.put("rwh", ddj.getRwh().toString()); + map.put("yp", ddj.getYph().toString()); + map.put("ywz", ddj.getYlh().toString()); + map.put("yc", ddj.getYch().toString()); + map.put("mbp", ddj.getMbph().toString()); + map.put("mbwz", ddj.getMblh().toString()); + map.put("mbc", ddj.getMbch().toString()); + resultList.add(map); + } + + return resultList; + } +} \ No newline at end of file diff --git a/ruoyi-ui/public/monitor/css/style.css b/ruoyi-ui/public/monitor/css/style.css new file mode 100644 index 00000000..4f6a70d6 --- /dev/null +++ b/ruoyi-ui/public/monitor/css/style.css @@ -0,0 +1,344 @@ +/* 页面基本样式 */ +body { + background-color: #f3f3f4; /* 设置背景色 */ + margin: 0; + padding: 0; + overflow: hidden; /* 防止出现滚动条 */ +} + +/* 主容器样式 */ +#main { + position: absolute; + margin-top: 0; + margin-left: 0; + z-index: -99; /* 确保在最底层 */ + height: 500px; + width: 500px; + transform: scale(0.9); + transform-origin: center center; + cursor: default; +} + +#main.dragging { + cursor: move; +} + +/* 小方块样式 */ +.small-box { + position: absolute; + background-color: #3c8dbc; + border: 2px solid #ffffff; + display: inline-block; + transition: all 0.3s ease; /* 添加过渡动画效果 */ +} + +/* 控制按钮容器样式 */ +.control-buttons { + position: fixed; + top: 20px; + right: 20px; + display: flex; + gap: 10px; + z-index: 1000; +} + +/* 控制按钮样式 */ +.control-buttons button { + padding: 10px 20px; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +#enableDragBtn { + background-color: #4CAF50; +} + +#enableDragBtn:hover:not(:disabled) { + background-color: #45a049; +} + +#disableDragBtn { + background-color: #f44336; +} + +#disableDragBtn:hover:not(:disabled) { + background-color: #da190b; +} + +.control-buttons button:disabled { + background-color: #cccccc; + cursor: not-allowed; + opacity: 0.7; +} + +/* 设备拖动控制按钮样式 */ +.drag-control-buttons { + display: flex; + gap: 10px; + margin-top: 5px; +} + +.drag-control-btn { + padding: 8px 16px; + border: none; + border-radius: 4px; + color: white; + cursor: pointer; + font-size: 14px; + transition: all 0.3s ease; +} + +.drag-control-btn:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.enable-drag { + background-color: #4CAF50; +} + +.enable-drag:hover:not(:disabled) { + background-color: #45a049; +} + +.disable-drag { + background-color: #f44336; +} + +.disable-drag:hover:not(:disabled) { + background-color: #da190b; +} + +/* 链条输送机样式 */ +.conveyor { + position: absolute; + background-image: url('../img/Lssj.png'); + background-size: 100% 100%; + background-repeat: no-repeat; + cursor: grab; + user-select: none; + transition: transform 0.1s ease; + z-index: 1; +} + +.conveyor:hover { + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); +} + +.conveyor:active { + cursor: grabbing; + transform: scale(1.02); +} + +.conveyor-center { + position: absolute; + width: 15px; + height: 15px; + background-color: #51bfff; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: none; +} + +/* 滚筒输送机样式 */ +.roller-conveyor { + position: absolute; + background-image: url('../img/Gssj.png'); + background-size: 100% 100%; + background-repeat: no-repeat; + cursor: grab; + user-select: none; + transition: transform 0.1s ease; + z-index: 2; +} + +.roller-conveyor:hover { + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); +} + +.roller-conveyor:active { + cursor: grabbing; + transform: scale(1.02); +} + +.roller-conveyor-center { + position: absolute; + width: 15px; + height: 15px; + background-color: #51bfff; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: none; +} + +/* 堆垛机样式 */ +.stacker { + position: absolute; + background-image: url('../img/ddj.png'); + background-size: 100% 100%; + background-repeat: no-repeat; + cursor: grab; + user-select: none; + transition: transform 0.1s ease, left 0.5s ease-in-out; +} + +.stacker:hover { + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); +} + +.stacker:active { + cursor: grabbing; + transform: scale(1.02); +} + +.stacker-center { + position: absolute; + width: 15px; + height: 15px; + background-color: #51bfff; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: none; +} + +/* RGV样式 */ +.rgv { + position: absolute; + background-image: url('../img/rgv.png'); + background-size: 100% 100%; + background-repeat: no-repeat; + cursor: grab; + user-select: none; + transition: transform 0.1s ease, left 0.5s ease-in-out; +} + +.rgv:hover { + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); +} + +.rgv:active { + cursor: grabbing; + transform: scale(1.02); +} + +.rgv-center { + position: absolute; + width: 15px; + height: 15px; + background-color: #51bfff; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: none; +} + +/* 堆垛机轨道样式 */ +.track { + position: absolute; + background-image: url('../img/gd.png'); + background-size: 100% 100%; + background-repeat: no-repeat; + cursor: grab; + user-select: none; + transition: transform 0.1s ease; +} + +.track:hover { + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); +} + +.track:active { + cursor: grabbing; + transform: scale(1.02); +} + +/* 报警闪红光 */ +.breathing-border { + border: 1px solid #ff0000; + box-sizing: border-box; + animation: breathing 1.5s ease-in-out infinite; +} + +@keyframes breathing { + 0% { + border-color: #ff0000; + box-shadow: 0 0 0px 0px rgb(255, 0, 0); + } + + 50% { + border-color: #ff0000; + box-shadow: 0 0 15px 15px rgba(0, 123, 255, 0); + } + + 100% { + border-color: #ff0000; + box-shadow: 0 0 0px 0px rgba(255, 0, 0, 0); + } +} + +/* 报警信息滚动动画 */ +@keyframes scroll-left { + 0% { + left: 20%; + } + 100% { + left: -150%; + } +} + +/* 慢速滚动动画 */ +@keyframes scroll-left-slow { + 0% { + left: 100%; + } + 100% { + left: -100%; + } +} + +/* 列位置显示样式 */ +.column-positions { + margin-top: 10px; + max-height: 300px; + overflow-y: auto; + background-color: #f5f5f5; + border-radius: 4px; + padding: 10px; +} + +.column-positions-info p { + margin: 0 0 10px 0; + font-weight: bold; +} + +.positions-list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); + gap: 8px; +} + +.position-item { + background-color: #fff; + padding: 8px; + border-radius: 4px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + display: flex; + justify-content: space-between; + align-items: center; +} + +.position-item span:first-child { + color: #666; + font-size: 0.9em; +} + +.position-item span:last-child { + font-weight: bold; + color: #333; +} diff --git a/ruoyi-ui/public/monitor/img/Gssj.png b/ruoyi-ui/public/monitor/img/Gssj.png new file mode 100644 index 0000000000000000000000000000000000000000..7a4c207022776bc46eafb3cf257676ec0610a1c1 GIT binary patch literal 1486 zcmV;<1u^=GP)|v%A^d?4CVmE^;>g7v>AYc{mRr=A4=D?>oO?kMA9r zKQ*UMtgh*wt+j9^#+Z--5A7P`ioN~Pt+o(8s1wE3v`(Etx$qb>an}S68;VoWxM9cE zh;g3NDscxTA6mt*^G6e^HBH)0K73C=r_3Ex2B@qmBx|}w#1cMt{;ahS#yI@EOn9)W zDTcV>v~$>m?;Seu*~ts$Bf#B40$B9QGku?JA7UX5=81&5c6wFgyF4@}Zifpps_ehm$eW#%XfU zgchWTK#RphDLHssuBY|{tZ@a*MsVt4h{=sgu~(nlRZTZO849Aru{p4{wR$)be_bOc zd<>6_l9Ym6J5sIQfSr>d#?W>nAp~HBJE#!wq(GKUNTn@1H#-X{39jQx=6qYUvNXBL zgdZOH;PA=+ng^Z66~=-W9~pdeVuFP!@Fxcec)!6Ywp?m^3&#bAX>`JB9H+!Wu;uz}9UoK;GxYyF( zmsGQN^S&qU>(Nuzkt4Omggmw+F@uFBU8{R)=B`I4qEJq_HixBR6~*NPihN(Pf&SjC zRH1!=y*#`Ycne){*@4t0ge7RJAJ)v~t)- zvYF#4WWkV(O6--z%SKA6UEAPlwI+vkYP0T2^zlz0eslcq+82%&Qt;B#!|!g}#3LH% zCt~sJ@j{{biOb#~05LPx^=?OJCy_FM^rPT`naF&9vgC|tj3L7UC=C!S1Lqun%~i4& z&Y%D^<5{j|;MQuC%O$>e&D|opE>SL(ke!$4-$fJmPwac@-aNKCE^XeKl0?HU#B`-1 zlRbAoIdz9eQ^w(zVdP__RKwEM0|`kY*4xtqlJ2`JBnZu-XvY;(Dp%1FdCJAe+ed5riQccad?5=P@V)KC5JG#LTO^@;LyJLsGJbbG0zBA&w#K-%`PmhoE zgwz#D-k0+hrpD!;|1P*`z2bWNb;st;>@3Wwl^Q?1E?;gj{jx+NbyC$?|ufH%|U7~$as+n?p83f4_ ze}{LhMyc`b&3ot1E&u=k07*qoM6N<$f>6Ne#sB~S literal 0 HcmV?d00001 diff --git a/ruoyi-ui/public/monitor/img/Lssj.png b/ruoyi-ui/public/monitor/img/Lssj.png new file mode 100644 index 0000000000000000000000000000000000000000..60d1a7e4ac5ec3de5284fdc30a0a3b60f77622d6 GIT binary patch literal 6341 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 Gxc5Jt`Er>6 literal 0 HcmV?d00001 diff --git a/ruoyi-ui/public/monitor/img/gd.png b/ruoyi-ui/public/monitor/img/gd.png new file mode 100644 index 0000000000000000000000000000000000000000..5c9e901372e7713b58cf32fffaf0ff7c19aaf756 GIT binary patch literal 10662 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 + + + + + 2D可视化监控系统 + + + + + +

2D可视化监控系统

+ + +
+
+
+ 🚨 0条报警 +
+
+
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-ui/public/monitor/js/index.js b/ruoyi-ui/public/monitor/js/index.js new file mode 100644 index 00000000..a8cb1ab9 --- /dev/null +++ b/ruoyi-ui/public/monitor/js/index.js @@ -0,0 +1,1855 @@ + +// 查询堆垛机数据列表 +function listDdj() { + request({ + url: '/largeScreen/ddj/list', + method: 'get' + }).then(response => { + console.log('接口返回数据:', response); + handleStackerDataSuccess(response) + }).catch(error => { + console.error('堆垛机数据获取失败:', error); + }); +} +// $.ajax({ +// url: API_URLS.stacker, +// type: 'GET', +// dataType: 'json', +// success: handleStackerDataSuccess, +// error: (xhr, status, error) => console.error('堆垛机数据获取失败:', error) +// }); +/** + * 2D可视化监控系统 - 数据同步和状态管理 + * 负责配置同步、设备状态更新、实时数据获取等功能 + */ + +// ==================== 全局变量 ==================== + +/** + * 配置编辑模式标识 + * @type {number} 1-编辑模式, 2-演示模式 + */ +let configEditMode = 2; + +// ==================== 配置同步功能 ==================== + +/** + * 获取系统配置并同步状态 + * 从服务器获取最新配置,更新本地状态和UI + */ +function getConfig() { + $.ajax({ + url: API_URLS.config, + type: 'GET', + dataType: 'json', + cache: false, + success: handleConfigSuccess, + error: handleConfigError + }); +} + +/** + * 处理配置获取成功 + * @param {Object} data 配置数据 + */ +function handleConfigSuccess(data) { + // 更新编辑模式状态 + updateEditMode(data.editMode); + + // 同步main.js中的全局配置 + syncMainConfig(data); + + // 更新组件拖拽状态 + updateDraggableStatus(data.deviceDraggable); +} + +/** + * 处理配置获取失败 + * @param {Object} xhr XMLHttpRequest对象 + * @param {string} status 状态信息 + * @param {string} error 错误信息 + */ +function handleConfigError(xhr, status, error) { + console.error('配置获取失败:', error); +} + +/** + * 更新编辑模式状态 + * @param {boolean} editMode 是否为编辑模式 + */ +function updateEditMode(editMode) { + configEditMode = editMode ? 1 : 2; + const modeText = editMode ? '编辑模式' : '演示模式'; +} + +/** + * 同步main.js中的全局配置 + * @param {Object} data 配置数据 + */ +function syncMainConfig(data) { + if (!window.config) return; + + // 更新所有配置项 + window.config.deviceDraggable = data.deviceDraggable; + window.config.editMode = data.editMode; + window.config.allowBackendAccess = data.allowBackendAccess; + window.config.labels = data.labels || []; + window.config.conveyors = data.conveyors || []; + window.config.stackers = data.stackers || []; + window.config.tracks = data.tracks || []; + window.config.rollerConveyors = data.rollerConveyors || []; + window.config.titleSettings = data.titleSettings; + + // 调用main.js中的更新函数 + if (typeof window.updateDevicesDraggableState === 'function') { + window.updateDevicesDraggableState(); + } + + // 更新标签显示 + if (typeof window.updateLabels === 'function') { + window.updateLabels(); + } + + // 更新页面标题样式 + if (typeof window.updatePageTitleStyle === 'function' && data.titleSettings) { + window.updatePageTitleStyle(data.titleSettings); + } +} + +// ==================== UI状态管理 ==================== + +/** + * 更新所有组件的拖拽状态 + * 根据配置更新设备元素的鼠标样式和拖拽能力 + * @param {boolean} isDraggable 是否允许拖拽 + */ +function updateDraggableStatus(isDraggable) { + const draggableElements = document.querySelectorAll('.conveyor, .roller-conveyor, .stacker, .label'); + + draggableElements.forEach(element => { + // 根据元素类型设置不同的鼠标样式 + const cursorStyle = isDraggable ? + (element.classList.contains('stacker') ? 'grab' : 'move') : + 'default'; + element.style.cursor = cursorStyle; + }); + + // 同步更新全局配置 + if (window.config) { + window.config.deviceDraggable = isDraggable; + } +} + +// ==================== 页面初始化 ==================== + +/** + * 页面加载完成后的初始化 + */ +$(document).ready(function() { + // 立即执行一次数据获取 + initializeData(); + + // 设置实时配置监听 + setupConfigListeners(); + + // 启动定时器 + startTimers(); +}); + +/** + * 初始化数据获取 + */ +function initializeData() { + getConfig(); + updateConveyorStatus(); + updateStackerStatus(); +} + +/** + * 设置配置变化监听器 + */ +function setupConfigListeners() { + // 监听localStorage变化(about页面通知) + setupLocalStorageListener(); + + // 监听BroadcastChannel消息(跨标签页通信) + setupBroadcastChannelListener(); +} + +/** + * 设置localStorage监听器 + */ +function setupLocalStorageListener() { + let lastRefreshTime = localStorage.getItem('refreshIndex'); + + setInterval(() => { + const currentRefreshTime = localStorage.getItem('refreshIndex'); + if (currentRefreshTime && currentRefreshTime !== lastRefreshTime) { + lastRefreshTime = currentRefreshTime; + getConfig(); + } + }, 100); +} + +/** + * 设置BroadcastChannel监听器 + */ +function setupBroadcastChannelListener() { + if (!window.BroadcastChannel) return; + + const broadcastChannel = new BroadcastChannel('index_refresh_channel'); + broadcastChannel.onmessage = (event) => { + if (event.data.refresh) { + getConfig(); + } + }; +} + +// 报警更新定时器ID +let alarmUpdateTimer = null; + +/** + * 启动定时器 + */ +function startTimers() { + // 设备状态更新定时器 + setInterval(updateConveyorStatus, 5000); + setInterval(updateStackerStatus, 5000); + setInterval(updateRgvStatus, 5000); + + // 配置同步定时器 + setInterval(getConfig, 1000); + + // 启动智能报警更新定时器 + startSmartAlarmTimer(); +} + +/** + * 启动报警系统 + */ +function startSmartAlarmTimer() { + // 立即执行一次 + updateAlarmStatus(); + console.log('报警系统已启动'); +} + +/** + * 安排下次报警更新 + * @param {number} delay 延迟时间(毫秒) + */ +function scheduleNextAlarmUpdate(delay) { + // 清除现有定时器 + if (alarmUpdateTimer) { + clearTimeout(alarmUpdateTimer); + } + + alarmUpdateTimer = setTimeout(() => { + updateAlarmStatus(); + // 递归安排下次更新 + scheduleNextAlarmUpdate(3000); + }, delay); +} + +// ==================== 设备状态更新 ==================== + +/** + * 更新输送机状态 + * 从服务器获取输送机实时数据并更新UI显示 + */ +function updateConveyorStatus() { + // 检查是否允许访问后台数据 + if (!canAccessBackendData()) { + return; + } + + $.ajax({ + url: API_URLS.conveyor, + type: 'GET', + dataType: 'json', + success: handleConveyorDataSuccess, + error: (xhr, status, error) => console.error('输送机数据获取失败:', error) + }); +} + +/** + * 处理输送机数据获取成功 + * @param {Object} response 服务器响应数据 + */ +function handleConveyorDataSuccess(response) { + if (!isValidResponse(response) || configEditMode !== 2) { + return; + } + + const conveyors = document.querySelectorAll('.conveyor, .roller-conveyor'); + + conveyors.forEach(conveyor => { + const conveyorId = conveyor.getAttribute('id'); + const deviceData = response.data.find(item => item.id === conveyorId); + + if (deviceData) { + updateConveyorDisplay(conveyor, deviceData); + } + }); +} + +/** + * 更新单个输送机的显示状态 + * @param {HTMLElement} conveyor 输送机DOM元素 + * @param {Object} data 设备数据 + */ +function updateConveyorDisplay(conveyor, data) { + // 更新中心方块显示状态 + const centerBlock = conveyor.querySelector('.conveyor-center, .roller-conveyor-center'); + if (centerBlock) { + centerBlock.style.display = data.dw === '1' ? 'block' : 'none'; + } + + // 更新设备状态指示(故障闪烁) + const hasError = parseInt(data.sbzt) > 100; + conveyor.classList.toggle('breathing-border', hasError); +} + + // ==================== 辅助函数 ==================== + + /** + * 检查是否允许访问后台数据 + * @returns {boolean} 是否允许访问 + */ + function canAccessBackendData() { + if (window.config && window.config.allowBackendAccess === false) { + return false; + } + return true; + } + + /** + * 验证服务器响应数据是否有效 + * @param {Object} response 服务器响应 + * @returns {boolean} 数据是否有效 + */ + function isValidResponse(response) { + return response && response.code === 0 && response.data; + } + + /** + * 更新堆垛机状态 + * 从服务器获取堆垛机实时数据并更新UI显示 + */ + function updateStackerStatus() { + // 检查是否允许访问后台数据 + if (!canAccessBackendData()) { + return; + } + listDdj() + +} + +/** + * 处理堆垛机数据获取成功 + * @param {Object} response 服务器响应数据 + */ +function handleStackerDataSuccess(response) { + if (!isValidResponse(response) || configEditMode !== 2) { + console.log(11111,response) + return; + } + + const stackers = document.querySelectorAll('.stacker'); + + stackers.forEach(stacker => { + const stackerId = stacker.getAttribute('id'); + const deviceData = response.data.find(item => item.id === stackerId); + + if (deviceData) { + updateStackerDisplay(stacker, deviceData); + } + }); +} + +/** + * 更新单个堆垛机的显示状态 + * @param {HTMLElement} stacker 堆垛机DOM元素 + * @param {Object} data 设备数据 + */ +function updateStackerDisplay(stacker, data) { + const centerBlock = stacker.querySelector('.stacker-center'); + const executionPhase = data.zxjd; + + // 根据执行阶段更新堆垛机状态 + switch(executionPhase) { + case '1': // 移动到原位置,隐藏货物 + updateStackerPosition(stacker, data.ywz, false); + break; + case '2': // 移动到原位置,显示货物 + updateStackerPosition(stacker, data.ywz, true); + break; + case '3': // 移动到目标位置,显示货物 + updateStackerPosition(stacker, data.mbwz, true); + break; + case '4': + case '5': // 移动到目标位置,隐藏货物 + updateStackerPosition(stacker, data.mbwz, false); + break; + } + + // 处理堆垛机报警状态(sbzt > 1000 时显示红光) + updateStackerAlarmStatus(stacker, data.sbzt); +} + +/** + * 更新堆垛机报警状态 + * @param {HTMLElement} stacker 堆垛机元素 + * @param {string|number} sbzt 设备状态值 + */ +function updateStackerAlarmStatus(stacker, sbzt) { + const statusValue = parseInt(sbzt); + + if (statusValue > 1000) { + // 添加报警样式 + stacker.classList.add('breathing-border'); + console.log(`堆垛机 ${stacker.getAttribute('id')} 报警,状态值: ${statusValue}`); + } else { + // 移除报警样式 + stacker.classList.remove('breathing-border'); + } +} + +/** + * 更新堆垛机位置和货物显示 + * @param {HTMLElement} stacker 堆垛机元素 + * @param {string} position 目标位置 + * @param {boolean} showCargo 是否显示货物 + */ +function updateStackerPosition(stacker, position, showCargo) { + const centerBlock = stacker.querySelector('.stacker-center'); + + // 更新货物显示状态 + if (centerBlock) { + centerBlock.style.display = showCargo ? 'block' : 'none'; + } + + // 计算并移动到目标位置 + const targetPosition = parseInt(position); + if (!isNaN(targetPosition)) { + // 获取配置信息以确定小方块总数 + const boxesPerRow = window.config ? window.config.boxesPerRow : 60; + + if (targetPosition === 0) { + // 位置为0时,移动到第一个小方块左侧 + moveStackerToColumn(stacker, -1); + } else if (targetPosition === boxesPerRow + 1) { + // 位置为小方块数量+1时,移动到最后一个小方块右侧 + moveStackerToColumn(stacker, boxesPerRow); + } else if (targetPosition > 0) { + // 正常位置处理 + moveStackerToColumn(stacker, targetPosition - 1); + } + } +} + +/** + * 移动堆垛机到指定列 + * @param {HTMLElement} stacker 堆垛机元素 + * @param {number} columnIndex 目标列索引 + */ +function moveStackerToColumn(stacker, columnIndex) { + // 获取堆垛机的ID和对应的货架ID + const stackerId = stacker.getAttribute('id'); + const stackerConfig = window.config.stackers.find(s => s.id === stackerId); + if (!stackerConfig || !stackerConfig.shelfId) { + console.warn(`堆垛机 ${stackerId} 未找到对应的货架ID`); + return; + } + + // 获取对应行的配置 + const rowConfig = window.config.boxRows.find(row => row.id === stackerConfig.shelfId); + if (!rowConfig) { + console.warn(`未找到货架ID ${stackerConfig.shelfId} 对应的方块行配置`); + return; + } + + // 获取该行的方块数量 + const boxesPerRow = rowConfig.boxCount; + let finalX; + + if (columnIndex === -1) { + // 位置为0时,移动到第一个小方块左侧一个方块距离 + const firstBox = document.querySelector(`.small-box[data-row="${stackerConfig.shelfId}"][data-column="0"]`); + if (!firstBox) { + console.warn(`未找到货架 ${stackerConfig.shelfId} 的第一个方块`); + return; + } + + const firstBoxX = parseInt(firstBox.style.left); + const boxSize = parseInt(firstBox.style.width); + const stackerWidth = parseInt(stacker.style.width); + const centerOffset = (stackerWidth - boxSize) / 2; + finalX = firstBoxX - boxSize - centerOffset; // 向左偏移一个方块距离 + + } else if (columnIndex === boxesPerRow) { + // 位置为小方块数量+1时,移动到最后一个小方块右侧一个方块距离 + const lastBox = document.querySelector(`.small-box[data-row="${stackerConfig.shelfId}"][data-column="${boxesPerRow - 1}"]`); + if (!lastBox) { + console.warn(`未找到货架 ${stackerConfig.shelfId} 的最后一个方块`); + return; + } + + const lastBoxX = parseInt(lastBox.style.left); + const boxSize = parseInt(lastBox.style.width); + const stackerWidth = parseInt(stacker.style.width); + const centerOffset = (stackerWidth - boxSize) / 2; + finalX = lastBoxX + boxSize - centerOffset; // 向右偏移一个方块距离 + + } else { + // 正常位置处理 + const targetBox = document.querySelector(`.small-box[data-row="${stackerConfig.shelfId}"][data-column="${columnIndex}"]`); + if (!targetBox) { + console.warn(`未找到货架 ${stackerConfig.shelfId} 的第 ${columnIndex} 个方块`); + return; + } + + const targetX = parseInt(targetBox.style.left); + const stackerWidth = parseInt(stacker.style.width); + const boxSize = parseInt(targetBox.style.width); + const centerOffset = (stackerWidth - boxSize) / 2; + finalX = targetX - centerOffset; + } + + // 添加平滑移动动画 + stacker.style.transition = 'left 2s ease-in-out'; + stacker.style.left = finalX + 'px'; +} + +// ==================== RGV状态管理 ==================== + +/** + * 更新RGV状态 + */ +function updateRgvStatus() { + // 检查是否允许访问后台数据 + if (!canAccessBackendData()) { + return; + } + + $.ajax({ + url: API_URLS.rgv, + type: 'GET', + dataType: 'json', + success: handleRgvDataSuccess, + error: (xhr, status, error) => console.error('RGV数据获取失败:', error) + }); +} + +/** + * 处理RGV数据获取成功 + * @param {Object} response 服务器响应数据 + */ +function handleRgvDataSuccess(response) { + if (!isValidResponse(response) || configEditMode !== 2) { + return; + } + + const rgvs = document.querySelectorAll('.rgv'); + + rgvs.forEach(rgv => { + const rgvId = rgv.getAttribute('id'); + const deviceData = response.data.find(item => item.id === rgvId); + + if (deviceData) { + updateRgvDisplay(rgv, deviceData); + } + }); +} + +/** + * 更新RGV显示状态 + * @param {HTMLElement} rgv RGV元素 + * @param {Object} data RGV数据 + */ +function updateRgvDisplay(rgv, data) { + const centerBlock = rgv.querySelector('.rgv-center'); + const executionPhase = data.zxjd; + + // 根据执行阶段更新RGV状态 + switch(executionPhase) { + case '1': // 移动到原位置,隐藏货物 + updateRgvPosition(rgv, data.ywz, false); + break; + case '2': // 移动到原位置,显示货物 + updateRgvPosition(rgv, data.ywz, true); + break; + case '3': // 移动到目标位置,显示货物 + updateRgvPosition(rgv, data.mbwz, true); + break; + case '4': + case '5': // 移动到目标位置,隐藏货物 + updateRgvPosition(rgv, data.mbwz, false); + break; + } + + // 处理RGV报警状态(sbzt > 1000 时显示红光) + updateRgvAlarmStatus(rgv, data.sbzt); +} + +/** + * 更新RGV报警状态 + * @param {HTMLElement} rgv RGV元素 + * @param {string|number} sbzt 设备状态值 + */ +function updateRgvAlarmStatus(rgv, sbzt) { + const statusValue = parseInt(sbzt); + + if (statusValue > 1000) { + // 添加报警样式 + rgv.classList.add('breathing-border'); + console.log(`RGV ${rgv.getAttribute('id')} 报警,状态值: ${statusValue}`); + } else { + // 移除报警样式 + rgv.classList.remove('breathing-border'); + } +} + +/** + * 更新RGV位置和货物显示 + * @param {HTMLElement} rgv RGV元素 + * @param {string} conveyorId 目标输送机ID + * @param {boolean} showCargo 是否显示货物 + */ +function updateRgvPosition(rgv, conveyorId, showCargo) { + const centerBlock = rgv.querySelector('.rgv-center'); + + // 更新货物显示状态 + if (centerBlock) { + centerBlock.style.display = showCargo ? 'block' : 'none'; + } + + // 移动到目标输送机位置 + if (conveyorId) { + moveRgvToConveyor(rgv, conveyorId); + } +} + +/** + * 移动RGV到指定输送机位置 + * @param {HTMLElement} rgv RGV元素 + * @param {string} conveyorId 目标输送机ID + */ +function moveRgvToConveyor(rgv, conveyorId) { + const targetConveyor = document.getElementById(conveyorId); + if (!targetConveyor) { + console.warn(`未找到输送机: ${conveyorId}`); + return; + } + + // 获取输送机的位置和尺寸 + const conveyorX = parseInt(targetConveyor.style.left); + const conveyorY = parseInt(targetConveyor.style.top); + const conveyorWidth = parseInt(targetConveyor.style.width); + const conveyorHeight = parseInt(targetConveyor.style.height); + + // 获取RGV的尺寸 + const rgvWidth = parseInt(rgv.style.width); + const rgvHeight = parseInt(rgv.style.height); + + // 计算RGV的目标位置(只调整y轴与输送机对齐,x轴保持不变) + const currentX = parseInt(rgv.style.left); // 保持当前x坐标 + const targetY = conveyorY + (conveyorHeight - rgvHeight) / 2; + + // 添加平滑移动动画(只动y轴) + rgv.style.transition = 'top 2s ease-in-out'; + rgv.style.top = targetY + 'px'; + + console.log(`RGV ${rgv.getAttribute('id')} 移动到输送机 ${conveyorId} Y轴位置: ${targetY}px (X轴保持: ${currentX}px)`); +} + +// 注意:此处的重复代码已被上面的优化函数替代 +// 旧的堆垛机处理逻辑已移至 updateStackerDisplay 等函数中 + +// 定时器设置已移至 startTimers 函数中 + +// ==================== 设备信息弹框功能 ==================== + +/** + * 显示设备信息弹框 + * @param {string} deviceType 设备类型 + * @param {string} deviceId 设备ID + * @param {Object} deviceConfig 设备配置信息 + */ +function showDeviceInfo(deviceType, deviceId, deviceConfig) { + const box = document.getElementById('box'); + const detailsDiv = document.getElementById('device-details'); + + if (!box || !detailsDiv) { + console.error('设备信息弹框元素未找到'); + return; + } + + // 获取设备实时数据 + getDeviceRealTimeData(deviceType, deviceId).then(realTimeData => { + // 构建设备信息HTML + const deviceInfo = buildDeviceInfoHTML(deviceType, deviceId, deviceConfig, realTimeData); + detailsDiv.innerHTML = deviceInfo; + + // 显示弹框 + box.style.display = 'block'; + }).catch(error => { + console.error('获取设备实时数据失败:', error); + // 即使获取实时数据失败,也显示基本配置信息 + const deviceInfo = buildDeviceInfoHTML(deviceType, deviceId, deviceConfig, null); + detailsDiv.innerHTML = deviceInfo; + box.style.display = 'block'; + }); +} + +/** + * 获取设备实时数据 + * @param {string} deviceType 设备类型 + * @param {string} deviceId 设备ID + * @returns {Promise} 设备实时数据 + */ +function getDeviceRealTimeData(deviceType, deviceId) { + return new Promise((resolve, reject) => { + + if (deviceType === 'stacker') { + // 获取堆垛机实时数据 - 使用配置的URL + $.ajax({ + url: API_URLS.stacker, + type: 'GET', + dataType: 'json', + success: function(response) { + if (response && response.data) { + const deviceData = response.data.find(item => item.id === deviceId); + resolve(deviceData || null); + } else { + resolve(null); + } + }, + error: function(xhr, status, error) { + console.error('获取堆垛机数据失败:', error); + reject('获取堆垛机数据失败'); + } + }); + } else if (deviceType === 'conveyor' || deviceType === 'rollerConveyor') { + // 获取输送机实时数据 - 使用配置的URL + $.ajax({ + url: API_URLS.conveyor, + type: 'GET', + dataType: 'json', + success: function(response) { + if (response && response.data) { + const deviceData = response.data.find(item => item.id === deviceId); + resolve(deviceData || null); + } else { + resolve(null); + } + }, + error: function(xhr, status, error) { + console.error('获取输送机数据失败:', error); + reject('获取输送机数据失败'); + } + }); + } else if (deviceType === 'rgv') { + // 获取RGV实时数据 - 使用配置的URL + $.ajax({ + url: API_URLS.rgv, + type: 'GET', + dataType: 'json', + success: function(response) { + if (response && response.data) { + const deviceData = response.data.find(item => item.id === deviceId); + resolve(deviceData || null); + } else { + resolve(null); + } + }, + error: function(xhr, status, error) { + console.error('获取RGV数据失败:', error); + reject('获取RGV数据失败'); + } + }); + } else { + // 其他设备类型暂无实时数据 + resolve(null); + } + }); +} + +/** + * 构建设备信息HTML + * @param {string} deviceType 设备类型 + * @param {string} deviceId 设备ID + * @param {Object} deviceConfig 设备配置信息 + * @param {Object} realTimeData 实时数据 + * @returns {string} HTML字符串 + */ +function buildDeviceInfoHTML(deviceType, deviceId, deviceConfig, realTimeData) { + const deviceTypeNames = { + 'conveyor': '链条输送机', + 'rollerConveyor': '滚筒输送机', + 'stacker': '堆垛机', + 'rgv': 'RGV', + 'track': '堆垛机轨道' + }; + + const typeName = deviceTypeNames[deviceType] || '未知设备'; + + // 使用后台数据中的ID,如果没有实时数据则使用配置ID + const displayId = realTimeData ? realTimeData.id : deviceId; + + // 设备类型图标 + const deviceIcons = { + 'conveyor': '', + 'rollerConveyor': '', + 'stacker': '', + 'rgv': '' }; + const deviceIcon = deviceIcons[deviceType] || '⚙️'; + + let html = ` +
+ +
+
${deviceIcon}
+

${typeName}

+
ID: ${displayId}
+
+ `; + + if (realTimeData) { + html += ` + +
+ `; + + if (deviceType === 'stacker') { + // 堆垛机字段:基于ddj.json + const statusValue = parseInt(realTimeData.sbzt); + const statusColor = statusValue > 1000 ? '#ff4444' : '#00aa00'; + const statusText = statusValue > 1000 ? '报警' : '正常'; + const statusBgColor = statusValue > 1000 ? 'rgba(255,68,68,0.1)' : 'rgba(0,170,0,0.1)'; + + // 执行阶段文字描述 + const executionPhases = { + '1': '取货行驶', + '2': '取货', + '3': '放货行驶', + '4': '放货', + '5': '完成' + }; + const phaseText = executionPhases[realTimeData.zxjd] || `未知阶段(${realTimeData.zxjd})`; + + html += ` +
+
设备信息
+
名称: ${realTimeData.name}
+
执行阶段: ${phaseText}
+
任务号: ${realTimeData.rwh}
+
+ +
+
运行状态
+
+ 状态: + ${statusText} +
+
状态值: ${realTimeData.sbzt}
+
+ +
+
位置信息
+
+
+
${realTimeData.yp}排${realTimeData.ywz}列${realTimeData.yc}层
+
原位置
+
+
→
+
+
${realTimeData.mbp}排${realTimeData.mbwz}列${realTimeData.mbc}层
+
目标位置
+
+
+
+ `; + } else if (deviceType === 'conveyor' || deviceType === 'rollerConveyor') { + // 输送机字段:基于Lssj.json + const statusValue = parseInt(realTimeData.sbzt); + const statusColor = statusValue > 100 ? '#ff4444' : '#00aa00'; + const statusText = statusValue > 100 ? '故障' : '正常'; + const statusBgColor = statusValue > 100 ? 'rgba(255,68,68,0.1)' : 'rgba(0,170,0,0.1)'; + const hasCargoText = realTimeData.dw === '1' ? '有货物' : '无货物'; + const kxText = realTimeData.kx === '1' ? '空闲' : '不空闲'; + const cargoColor = realTimeData.dw === '1' ? '#FF9800' : '#9E9E9E'; + const switchColor = realTimeData.kx === '1' ? '#4CAF50' : '#F44336'; + + html += ` +
+
设备信息
+
名称: ${realTimeData.name}
+
任务号: ${realTimeData.rwh}
+
托盘编码: ${realTimeData.trayCode}
+
+ +
+
运行状态
+
+ 状态: + ${statusText} +
+
状态值: ${realTimeData.sbzt}
+
+ +
+
开关状态
+
+
${kxText}
+
+
+ +
+
货物状态
+
+
${hasCargoText}
+
+
+ `; + } else if (deviceType === 'rgv') { + // RGV字段:基于rgv.json + const statusValue = parseInt(realTimeData.sbzt); + const statusColor = statusValue > 1000 ? '#ff4444' : '#00aa00'; + const statusText = statusValue > 1000 ? '报警' : '正常'; + const statusBgColor = statusValue > 1000 ? 'rgba(255,68,68,0.1)' : 'rgba(0,170,0,0.1)'; + // 执行阶段文字描述 + const executionPhases = { + '1': '取货行驶', + '2': '取货', + '3': '放货行驶', + '4': '放货', + '5': '完成' + }; + const phaseTextRgv = executionPhases[realTimeData.zxjd] || `未知阶段(${realTimeData.zxjd})`; + + // 执行阶段描述 + const phaseDescriptions = { + '1': '移动到原位置(无货物)', + '2': '移动到原位置(有货物)', + '3': '移动到目标位置(有货物)', + '4': '移动到目标位置(无货物)', + '5': '完成(无货物)' + }; + const phaseText = phaseDescriptions[realTimeData.zxjd] || '未知阶段'; + const phaseColor = realTimeData.zxjd === '1' || realTimeData.zxjd === '4' || realTimeData.zxjd === '5' ? '#9E9E9E' : '#FF9800'; + + html += ` +
+
设备信息
+
名称: ${realTimeData.name}
+
任务号: ${realTimeData.rwh}
+
执行阶段: ${phaseTextRgv}
+
+ +
+
运行状态
+
+ 状态: + ${statusText} +
+
状态值: ${realTimeData.sbzt}
+
+ +
+
执行阶段
+
+
${phaseText}
+
+
+ +
+
位置信息
+
+
+
${realTimeData.ywz}
+
原位置(输送机ID)
+
+
+
${realTimeData.mbwz}
+
目标位置(输送机ID)
+
+
+
+ `; + } + + html += `
`; + } else { + html += ` +
+
📊
+
暂无设备数据
+
请检查设备连接状态
+
+ `; + } + + html += ` + +
+ +
+
+ `; + + return html; +} + +/** + * 关闭设备信息弹框 + */ +function closeBox() { + const box = document.getElementById('box'); + if (box) { + box.style.display = 'none'; + } +} + +/** + * 初始化弹框拖动功能 + */ +function initBoxDrag() { + const box = document.getElementById('box'); + const header = document.getElementById('box-header'); + + if (!box || !header) return; + + let isDragging = false; + let startX = 0; + let startY = 0; + let initialLeft = 0; + let initialTop = 0; + + // 鼠标按下事件 + header.addEventListener('mousedown', function(e) { + e.preventDefault(); + isDragging = true; + + // 记录初始位置 + startX = e.clientX; + startY = e.clientY; + + // 获取弹框当前位置 + const rect = box.getBoundingClientRect(); + initialLeft = rect.left; + initialTop = rect.top; + + // 改变光标样式 + document.body.style.cursor = 'move'; + header.style.cursor = 'move'; + + // 添加全局事件监听 + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + }); + + function handleMouseMove(e) { + if (!isDragging) return; + + e.preventDefault(); + + // 计算移动距离 + const deltaX = e.clientX - startX; + const deltaY = e.clientY - startY; + + // 计算新位置 + let newLeft = initialLeft + deltaX; + let newTop = initialTop + deltaY; + + // 边界检查 + const boxWidth = box.offsetWidth; + const boxHeight = box.offsetHeight; + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + + // 限制在窗口范围内 + newLeft = Math.max(0, Math.min(newLeft, windowWidth - boxWidth)); + newTop = Math.max(0, Math.min(newTop, windowHeight - boxHeight)); + + // 应用新位置 + box.style.left = newLeft + 'px'; + box.style.top = newTop + 'px'; + box.style.transform = 'none'; // 移除居中变换 + } + + function handleMouseUp(e) { + if (!isDragging) return; + + isDragging = false; + + // 恢复光标样式 + document.body.style.cursor = ''; + header.style.cursor = 'move'; + + // 移除全局事件监听 + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + } +} + +// 将函数暴露到全局作用域 +window.showDeviceInfo = showDeviceInfo; +window.closeBox = closeBox; +window.initBoxDrag = initBoxDrag; + +// 页面加载完成后初始化拖动功能 +$(document).ready(function() { + initBoxDrag(); + // 初始化报警系统 + initAlarmSystem(); +}); + +// ==================== 报警信息系统 ==================== + +/** + * 初始化报警系统 + * 系统启动时调用,开始报警监控 + */ +function initAlarmSystem() { + // 先加载报警设置,检查是否有效 + loadAlarmSettings().then(() => { + // 只有在报警设置有效时才开始监控 + const container = document.getElementById('alarm-container'); + if (container && container.style.display !== 'none') { + updateAlarmStatus(); + } + }); +} + +/** + * 更新报警状态 + * 从后台获取最新的报警数据并更新显示 + */ +function updateAlarmStatus() { + // 检查是否允许访问后台数据 + if (!canAccessBackendData()) { + return; + } + + $.ajax({ + url: API_URLS.alarm, + type: 'GET', + dataType: 'json', + success: handleAlarmDataSuccess, + error: handleAlarmDataError + }); +} + +/** + * 处理报警数据获取成功的回调 + * @param {Object} response 服务器响应数据 + */ +function handleAlarmDataSuccess(response) { + // 验证响应数据有效性 + if (!isValidAlarmResponse(response)) { + showNoAlarmState(); + return; + } + + const alarms = response.alarm; + + // 根据报警数量决定显示方式 + if (alarms.length === 0) { + showNoAlarmState(); + } else { + showAlarmContainer(alarms); + } +} + +/** + * 处理报警数据获取失败的回调 + * @param {Object} xhr XMLHttpRequest对象 + * @param {string} status 状态文本 + * @param {string} error 错误信息 + */ +function handleAlarmDataError(xhr, status, error) { + console.error('报警数据获取失败:', { + status: status, + error: error, + responseText: xhr.responseText + }); + + // 网络错误时显示无报警状态,避免界面异常 + showNoAlarmState(); +} + +// ==================== 报警系统模块 ==================== + +// 报警系统配置(可通过设置页面修改) +let ALARM_CONFIG = { + // 样式配置 + STYLES: { + NORMAL: { + background: 'linear-gradient(135deg, #999999, #777777)', + boxShadow: '0 4px 15px rgba(153, 153, 153, 0.3)' + }, + ALARM: { + background: 'linear-gradient(135deg, #ff6b6b, #ee5a24)', + boxShadow: '0 4px 15px rgba(255, 107, 107, 0.3)' + } + }, + // 时间配置 + TIMING: { + NO_ALARM_CHECK_INTERVAL: 3000, // 无报警时检查间隔(毫秒) + SHORT_CONTENT_CHECK_INTERVAL: 3000, // 短内容检查间隔(毫秒) + SCROLL_SPEED: 50 // 滚动速度(像素/秒) + }, + // 文本配置 + TEXT: { + NO_ALARM: '暂无报警', + SEPARATOR: '    ' + }, + // 报警框设置 + CONTAINER: { + width: 400, + height: 60, + x: 20, + y: 20, + position: 'bottom-center' + } +}; + +// API接口配置(从config.json中的apiSettings读取) +let API_URLS = { + stacker: 'json/ddj.json', + conveyor: 'json/Lssj.json', + rgv: 'json/rgv.json', + alarm: 'json/alarm.json', + config: 'json/config.json' +}; +// 报警系统全局变量 +let alarmScrollTimer = null; // 滚动动画定时器 +let currentAlarmData = []; // 当前报警数据缓存 +let isScrolling = false; // 滚动状态标记 + +/** + * 显示报警容器并更新内容 + * @param {Array} alarms 报警数据数组 + */ +function showAlarmContainer(alarms) { + const elements = getAlarmElements(); + if (!elements) return; + + const { container, countElement, textElement } = elements; + + if (alarms.length === 0) { + setNoAlarmState(container, countElement, textElement); + return; + } + + setAlarmState(container, countElement, textElement, alarms); +} + +/** + * 显示无报警状态(灰色状态) + */ +function showNoAlarmState() { + const elements = getAlarmElements(); + if (!elements) return; + + const { container, countElement, textElement } = elements; + setNoAlarmState(container, countElement, textElement); +} + +/** + * 隐藏报警容器(仅在配置无效时使用) + */ +function hideAlarmContainer() { + const container = document.getElementById('alarm-container'); + if (container) { + // 完全隐藏报警框 + container.style.display = 'none'; + + // 停止所有报警相关的定时器和动画 + stopAlarmScroll(); + + // 清除报警更新定时器 + if (alarmUpdateTimer) { + clearTimeout(alarmUpdateTimer); + alarmUpdateTimer = null; + } + + console.log('报警框已隐藏'); + } +} + +/** + * 获取报警相关DOM元素 + * @returns {Object|null} 包含DOM元素的对象或null + */ +function getAlarmElements() { + const container = document.getElementById('alarm-container'); + const countElement = document.getElementById('alarm-count'); + const textElement = document.getElementById('alarm-text'); + + if (!container || !countElement || !textElement) { + console.error('报警显示元素未找到'); + return null; + } + + return { container, countElement, textElement }; +} + +/** + * 设置无报警状态的样式和内容 + * @param {HTMLElement} container 容器元素 + * @param {HTMLElement} countElement 计数元素 + * @param {HTMLElement} textElement 文本元素 + */ +function setNoAlarmState(container, countElement, textElement) { + // 更新内容 + countElement.textContent = '0'; + textElement.textContent = ALARM_CONFIG.TEXT.NO_ALARM; + + // 设置样式 + applyContainerStyle(container, ALARM_CONFIG.STYLES.NORMAL); + + // 停止滚动 + stopAlarmScroll(); + + // 显示容器 + container.style.display = 'block'; + + // 定时重新检查 + setTimeout(() => { + updateAlarmStatus(); + }, ALARM_CONFIG.TIMING.NO_ALARM_CHECK_INTERVAL); +} + +/** + * 设置有报警状态的样式和内容 + * @param {HTMLElement} container 容器元素 + * @param {HTMLElement} countElement 计数元素 + * @param {HTMLElement} textElement 文本元素 + * @param {Array} alarms 报警数据数组 + */ +function setAlarmState(container, countElement, textElement, alarms) { + // 更新报警数量 + countElement.textContent = alarms.length; + + // 设置报警样式 + applyContainerStyle(container, ALARM_CONFIG.STYLES.ALARM); + + // 构建滚动文本 + const scrollText = buildAlarmText(alarms); + + // 检查内容是否变化 + const contentChanged = JSON.stringify(alarms) !== JSON.stringify(currentAlarmData); + + if (contentChanged || !isScrolling) { + currentAlarmData = [...alarms]; + textElement.textContent = scrollText; + startAlarmScroll(textElement); + } + + // 显示容器 + container.style.display = 'block'; +} + +/** + * 应用容器样式 + * @param {HTMLElement} container 容器元素 + * @param {Object} style 样式对象 + */ +function applyContainerStyle(container, style) { + container.style.background = style.background; + container.style.boxShadow = style.boxShadow; +} + +/** + * 构建报警文本 + * @param {Array} alarms 报警数据数组 + * @returns {string} 格式化的报警文本 + */ +function buildAlarmText(alarms) { + const alarmTexts = alarms.map(alarm => { + const errorCode = alarm.code || alarm.type || '未知'; + return `【${alarm.id}${alarm.name}】错误代码: ${errorCode},报警信息:${alarm.content}`; + }); + return alarmTexts.join(ALARM_CONFIG.TEXT.SEPARATOR); +} + +/** + * 开始报警文本滚动 + * @param {HTMLElement} textElement 文本元素 + */ +function startAlarmScroll(textElement) { + // 停止当前滚动 + stopAlarmScroll(); + + // 获取滚动容器和测量尺寸 + const scrollContainer = document.getElementById('alarm-scroll'); + if (!scrollContainer) { + console.error('滚动容器未找到'); + return; + } + + const containerWidth = scrollContainer.offsetWidth; + const textWidth = textElement.scrollWidth; + + // 判断是否需要滚动 + if (textWidth <= containerWidth) { + // 短内容居中显示 + const centerPosition = (containerWidth - textWidth) / 2; + textElement.style.left = centerPosition + 'px'; + + isScrolling = false; + // 短内容定时重新检查 + setTimeout(() => { + updateAlarmStatus(); + }, ALARM_CONFIG.TIMING.SHORT_CONTENT_CHECK_INTERVAL); + return; + } + + // 计算居中起始位置,但不小于50px + const centerStartPosition = Math.max(50, (containerWidth - textWidth) / 2); + + // 设置初始居中位置 + textElement.style.left = centerStartPosition + 'px'; + + isScrolling = true; + + // 延迟2秒后开始滚动,让用户看清第一条信息 + setTimeout(() => { + if (isScrolling) { // 确保在延迟期间没有被停止 + // 计算滚动参数 - 只需要滚动到文字完全离开容器即可 + const scrollDistance = textWidth; + const scrollDuration = scrollDistance / ALARM_CONFIG.TIMING.SCROLL_SPEED; + + // 从居中位置开始滚动到文字完全离开容器 + animateScroll(textElement, centerStartPosition, -scrollDistance, scrollDuration * 1000); + } + }, 2000); // 2秒延迟 +} + +/** + * 执行滚动动画 + * @param {HTMLElement} element 文本元素 + * @param {number} startPos 开始位置(像素) + * @param {number} endPos 结束位置(像素) + * @param {number} duration 持续时间(毫秒) + */ +function animateScroll(element, startPos, endPos, duration) { + const startTime = Date.now(); + + function step() { + const elapsed = Date.now() - startTime; + const progress = Math.min(elapsed / duration, 1); + + // 线性插值计算当前位置 + const currentPos = startPos + (endPos - startPos) * progress; + element.style.left = currentPos + 'px'; + + if (progress < 1) { + // 继续动画 + alarmScrollTimer = requestAnimationFrame(step); + } else { + // 滚动完成,重新获取数据 + isScrolling = false; + updateAlarmStatus(); + } + } + + alarmScrollTimer = requestAnimationFrame(step); +} + +/** + * 停止报警滚动动画 + */ +function stopAlarmScroll() { + if (alarmScrollTimer) { + cancelAnimationFrame(alarmScrollTimer); + alarmScrollTimer = null; + } + isScrolling = false; +} + +/** + * 验证报警响应数据是否有效 + * @param {Object} response 响应数据 + * @returns {boolean} 数据是否有效 + */ +function isValidAlarmResponse(response) { + return response && + typeof response === 'object' && + Array.isArray(response.alarm); +} + +/** + * 从配置文件加载API设置 + */ +async function loadApiSettings() { + $.ajax({ + url: API_URLS.config, + type: 'GET', + dataType: 'json', + cache: false, + success(res){ + if (res.apiSettings){ + const settings = res.apiSettings; + + // 更新API URL配置 + API_URLS.stacker = settings.stackerApiUrl || 'json/ddj.json'; + API_URLS.conveyor = settings.conveyorApiUrl || 'json/Lssj.json'; + API_URLS.rgv = settings.rgvApiUrl || 'json/rgv.json'; + API_URLS.alarm = settings.alarmApiUrl || 'json/alarm.json'; + API_URLS.config = settings.configApiUrl || 'json/config.json'; + + console.log('API设置已更新:', API_URLS); + } + }, + error(error){ + console.error('加载API设置失败:', error); + } + }); + + +} + +/** + * 从配置文件加载报警设置 + */ +async function loadAlarmSettings() { + + $.ajax({ + url: API_URLS.config, + type: 'GET', + dataType: 'json', + cache: false, + success(res) { + if (res.alarmSettings) { + const settings = res.alarmSettings; + + // 检查报警设置是否有效(非空且非零) + const isValidSettings = settings.width > 0 && + settings.height > 0 && + settings.position && + settings.position.trim() !== ''; + + if (isValidSettings) { + // 更新配置 + ALARM_CONFIG.CONTAINER.width = settings.width; + ALARM_CONFIG.CONTAINER.height = settings.height; + ALARM_CONFIG.CONTAINER.x = settings.x || 20; + ALARM_CONFIG.CONTAINER.y = settings.y || 20; + ALARM_CONFIG.CONTAINER.position = settings.position; + ALARM_CONFIG.TIMING.SCROLL_SPEED = settings.scrollSpeed || 50; + + // 应用设置到报警框 + applyAlarmContainerSettings(); + + console.log('报警设置已加载并应用'); + } else { + // 报警设置无效,隐藏报警框 + hideAlarmContainer(); + console.log('报警设置无效,已隐藏报警框'); + } + } else { + // 没有报警设置,隐藏报警框 + hideAlarmContainer(); + console.log('未找到报警设置,已隐藏报警框'); + } + }, + error(error){ + console.error('加载报警设置失败:', error); + // 加载失败时也隐藏报警框 + hideAlarmContainer(); + } + }) +} + +/** + * 应用报警容器设置 + */ +function applyAlarmContainerSettings() { + const container = document.getElementById('alarm-container'); + if (!container) return; + + const settings = ALARM_CONFIG.CONTAINER; + + // 设置尺寸 + container.style.width = settings.width + 'px'; + container.style.height = settings.height + 'px'; + + // 设置位置 + switch (settings.position) { + case 'top-left': + container.style.top = settings.y + 'px'; + container.style.left = settings.x + 'px'; + container.style.bottom = 'auto'; + container.style.right = 'auto'; + container.style.transform = 'none'; + break; + case 'top-right': + container.style.top = settings.y + 'px'; + container.style.right = settings.x + 'px'; + container.style.bottom = 'auto'; + container.style.left = 'auto'; + container.style.transform = 'none'; + break; + case 'bottom-left': + container.style.bottom = settings.y + 'px'; + container.style.left = settings.x + 'px'; + container.style.top = 'auto'; + container.style.right = 'auto'; + container.style.transform = 'none'; + break; + case 'bottom-right': + container.style.bottom = settings.y + 'px'; + container.style.right = settings.x + 'px'; + container.style.top = 'auto'; + container.style.left = 'auto'; + container.style.transform = 'none'; + break; + case 'bottom-center': + default: + container.style.bottom = settings.y + 'px'; + container.style.left = '50%'; + container.style.top = 'auto'; + container.style.right = 'auto'; + container.style.transform = 'translateX(-50%)'; + break; + case 'custom': + container.style.left = settings.x + 'px'; + container.style.top = settings.y + 'px'; + container.style.bottom = 'auto'; + container.style.right = 'auto'; + container.style.transform = 'none'; + break; + } +} + +/** + * 监听配置设置更新 + */ +function setupConfigSettingsListener() { + if (window.BroadcastChannel) { + const bc = new BroadcastChannel('config_update_channel'); + bc.onmessage = (event) => { + if (event.data.type === 'alarm_settings_updated') { + console.log('收到报警设置更新通知'); + loadAlarmSettings(); + } else if (event.data.type === 'api_settings_updated') { + console.log('收到API设置更新通知'); + loadApiSettings(); + } + }; + } +} + +// 在页面加载时初始化配置设置 +$(document).ready(function() { + loadApiSettings(); + loadAlarmSettings(); + setupConfigSettingsListener(); +}); diff --git a/ruoyi-ui/public/monitor/js/jquery-3.1.1.min.js b/ruoyi-ui/public/monitor/js/jquery-3.1.1.min.js new file mode 100644 index 00000000..4c5be4c0 --- /dev/null +++ b/ruoyi-ui/public/monitor/js/jquery-3.1.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):C.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/[^\x20\t\r\n\f]+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R), +a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,ka=/^$|\/(?:java|ecma)script/i,la={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};la.optgroup=la.option,la.tbody=la.tfoot=la.colgroup=la.caption=la.thead,la.th=la.td;function ma(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function na(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=ma(l.appendChild(f),"script"),j&&na(g),c){k=0;while(f=g[k++])ka.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var qa=d.documentElement,ra=/^key/,sa=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ta=/^([^.]*)(?:\.(.+)|)/;function ua(){return!0}function va(){return!1}function wa(){try{return d.activeElement}catch(a){}}function xa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)xa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=va;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(qa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,za=/\s*$/g;function Da(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Ea(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Fa(a){var b=Ba.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ga(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Aa.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ia(f,b,c,d)});if(m&&(e=pa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(ma(e,"script"),Ea),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=ma(h),f=ma(a),d=0,e=f.length;d0&&na(g,!i&&ma(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ja(this,a,!0)},remove:function(a){return Ja(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.appendChild(a)}})},prepend:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(ma(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!za.test(a)&&!la[(ja.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function Ya(a,b,c,d,e){return new Ya.prototype.init(a,b,c,d,e)}r.Tween=Ya,Ya.prototype={constructor:Ya,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Ya.propHooks[this.prop];return a&&a.get?a.get(this):Ya.propHooks._default.get(this)},run:function(a){var b,c=Ya.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ya.propHooks._default.set(this),this}},Ya.prototype.init.prototype=Ya.prototype,Ya.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Ya.propHooks.scrollTop=Ya.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Ya.prototype.init,r.fx.step={};var Za,$a,_a=/^(?:toggle|show|hide)$/,ab=/queueHooks$/;function bb(){$a&&(a.requestAnimationFrame(bb),r.fx.tick())}function cb(){return a.setTimeout(function(){Za=void 0}),Za=r.now()}function db(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ba[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function eb(a,b,c){for(var d,e=(hb.tweeners[b]||[]).concat(hb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?ib:void 0)), +void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),ib={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=jb[b]||r.find.attr;jb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=jb[g],jb[g]=e,e=null!=c(a,b,d)?g:null,jb[g]=f),e}});var kb=/^(?:input|select|textarea|button)$/i,lb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):kb.test(a.nodeName)||lb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function mb(a){var b=a.match(K)||[];return b.join(" ")}function nb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,nb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,nb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,nb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=nb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(nb(c))+" ").indexOf(b)>-1)return!0;return!1}});var ob=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(ob,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:mb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ia.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,"$1"),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + + + diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js index 701de915..a1733b89 100644 --- a/ruoyi-ui/vue.config.js +++ b/ruoyi-ui/vue.config.js @@ -9,32 +9,22 @@ const CompressionPlugin = require('compression-webpack-plugin') const name = process.env.VUE_APP_TITLE || 'FORTUCKY WCS SYSTEM' // 网页标题 -const baseUrl = 'http://localhost:8081' // 后端接口 +const baseUrl = 'http://localhost:8081' // 后端接口地址(你的后端端口是8081) -const port = process.env.port || process.env.npm_config_port || 80 // 端口 +const port = process.env.port || process.env.npm_config_port || 80 // 前端端口 -// vue.config.js 配置说明 -//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions -// 这里只列一部分,具体配置参考文档 module.exports = { - // 部署生产环境和开发环境下的URL。 - // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上 - // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。 publicPath: process.env.NODE_ENV === "production" ? "/" : "/", - // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist) outputDir: 'dist', - // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下) assetsDir: 'static', - // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。 productionSourceMap: false, transpileDependencies: ['quill'], - // webpack-dev-server 相关配置 devServer: { host: '0.0.0.0', port: port, open: true, proxy: { - // detail: https://cli.vuejs.org/config/#devserver-proxy + // 保留原有的基础API代理(如 /api) [process.env.VUE_APP_BASE_API]: { target: baseUrl, changeOrigin: true, @@ -42,7 +32,14 @@ module.exports = { ['^' + process.env.VUE_APP_BASE_API]: '' } }, - // springdoc proxy + // 新增:转发 /largeScreen 开头的接口(你的堆垛机接口路径) + '/largeScreen': { + target: baseUrl, // 转发到后端地址 http://localhost:8081 + changeOrigin: true, + // 不需要 pathRewrite,因为后端接口本身就是 /largeScreen/ddj/list + // 转发后实际请求地址为:http://localhost:8081/largeScreen/ddj/list + }, + // 保留原有的springdoc proxy '^/v3/api-docs/(.*)': { target: baseUrl, changeOrigin: true @@ -65,22 +62,20 @@ module.exports = { } }, plugins: [ - // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件 new CompressionPlugin({ - cache: false, // 不启用文件缓存 - test: /\.(js|css|html|jpe?g|png|gif|svg)?$/i, // 压缩文件格式 - filename: '[path][base].gz[query]', // 压缩后的文件名 - algorithm: 'gzip', // 使用gzip压缩 - minRatio: 0.8, // 压缩比例,小于 80% 的文件不会被压缩 - deleteOriginalAssets: false // 压缩后删除原文件 + cache: false, + test: /\.(js|css|html|jpe?g|png|gif|svg)?$/i, + filename: '[path][base].gz[query]', + algorithm: 'gzip', + minRatio: 0.8, + deleteOriginalAssets: false }) ], }, chainWebpack(config) { - config.plugins.delete('preload') // TODO: need test - config.plugins.delete('prefetch') // TODO: need test + config.plugins.delete('preload') + config.plugins.delete('prefetch') - // set svg-sprite-loader config.module .rule('svg') .exclude.add(resolve('src/assets/icons')) @@ -98,39 +93,39 @@ module.exports = { .end() config.when(process.env.NODE_ENV !== 'development', config => { - config - .plugin('ScriptExtHtmlWebpackPlugin') - .after('html') - .use('script-ext-html-webpack-plugin', [{ - // `runtime` must same as runtimeChunk name. default is `runtime` - inline: /runtime\..*\.js$/ - }]) - .end() + config + .plugin('ScriptExtHtmlWebpackPlugin') + .after('html') + .use('script-ext-html-webpack-plugin', [{ + inline: /runtime\..*\.js$/ + }]) + .end() - config.optimization.splitChunks({ - chunks: 'all', - cacheGroups: { - libs: { - name: 'chunk-libs', - test: /[\\/]node_modules[\\/]/, - priority: 10, - chunks: 'initial' // only package third parties that are initially dependent - }, - elementUI: { - name: 'chunk-elementUI', // split elementUI into a single package - test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm - priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app - }, - commons: { - name: 'chunk-commons', - test: resolve('src/components'), // can customize your rules - minChunks: 3, // minimum common number - priority: 5, - reuseExistingChunk: true - } - } - }) - config.optimization.runtimeChunk('single') + config.optimization.splitChunks({ + chunks: 'all', + cacheGroups: { + libs: { + name: 'chunk-libs', + test: /[\\/]node_modules[\\/]/, + priority: 10, + chunks: 'initial' + }, + elementUI: { + name: 'chunk-elementUI', + test: /[\\/]node_modules[\\/]_?element-ui(.*)/, + priority: 20 + }, + commons: { + name: 'chunk-commons', + test: resolve('src/components'), + minChunks: 3, + priority: 5, + reuseExistingChunk: true + } + } + }) + config.optimization.runtimeChunk('single') }) } } +