Browse Source

1.改为单体应用
2.优化样式

1 3 hours ago
parent
commit
8e654ba01f

+ 2 - 2
imwork-windows/imwork-silos/pom.xml

@@ -36,10 +36,10 @@
             <groupId>top.imwork</groupId>
             <artifactId>imwork-commons-dao</artifactId>
         </dependency>
-        <dependency>
+        <!--<dependency>
             <groupId>top.imwork</groupId>
             <artifactId>imwork-commons-alibaba</artifactId>
-        </dependency>
+        </dependency>-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-thymeleaf</artifactId>

+ 1 - 2
imwork-windows/imwork-silos/src/main/java/top/imwork/window/silos/SilosStart.java

@@ -3,7 +3,6 @@ package top.imwork.window.silos;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 
 /**
  * Copyright (C), 2015-2025
@@ -16,7 +15,7 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  * Since<版本号>: 1.0.0
  */
 @MapperScan(basePackages = "top.imwork.*.*.dao")
-@EnableDiscoveryClient
+//@EnableDiscoveryClient
 @SpringBootApplication
 public class SilosStart {
     public static void main(String[] args) {

+ 5 - 0
imwork-windows/imwork-silos/src/main/java/top/imwork/window/silos/controller/MainController.java

@@ -24,6 +24,11 @@ public class MainController {
         return "/main/welcome";
     }
 
+    @GetMapping("/dashboard.html")
+    public String dashboard() {
+        return "/main/dashboard";
+    }
+
     @PostMapping("/authentication/form")
     public String authentication() {
         return "/main/index";

+ 2 - 1
imwork-windows/imwork-silos/src/main/java/top/imwork/window/silos/security/config/SecurityConfig.java

@@ -94,7 +94,7 @@ public class SecurityConfig{
                         .disable()
                 )
                 .logout(logout -> logout
-                        .logoutUrl("/api/auth/logout")
+                        .logoutUrl("/auth/logout")
                         .logoutSuccessHandler(logoutSuccessHandler())
                         .invalidateHttpSession(true)
                         .deleteCookies("JSESSIONID")
@@ -122,6 +122,7 @@ public class SecurityConfig{
         return (request, response, authentication) -> {
             response.setContentType("application/json;charset=UTF-8");
             response.getWriter().write("{\"success\": true, \"message\": \"退出成功\"}");
+            response.sendRedirect("/login.html");
         };
     }
 

+ 18 - 18
imwork-windows/imwork-silos/src/main/resources/application.yml

@@ -1,27 +1,27 @@
 server:
-  port: 7002
+  port: 80
 spring:
   main:
     allow-bean-definition-overriding: true
   application:
     name: imwork-silos
-  config:
-    import: nacos:${spring.application.name}
-  cloud:
-    nacos:
-      config:
-        server-addr: 127.0.0.1:8848
-        namespace: imwork-silos
-        group: DEFAULT_GROUP
-        file-extension: yml
-        username: admin
-        password: zh.3417.JXW
-      discovery:
-        server-addr: 127.0.0.1:8848
-        namespace: imwork-silos
-        file-extension: yml
-        username: admin
-        password: zh.3417.JXW
+#  config:
+#    import: nacos:${spring.application.name}
+#  cloud:
+#    nacos:
+#      config:
+#        server-addr: 127.0.0.1:8848
+#        namespace: imwork-silos
+#        group: DEFAULT_GROUP
+#        file-extension: yml
+#        username: admin
+#        password: zh.3417.JXW
+#      discovery:
+#        server-addr: 127.0.0.1:8848
+#        namespace: imwork-silos
+#        file-extension: yml
+#        username: admin
+#        password: zh.3417.JXW
   mvc:
     pathmatch:
       matching-strategy: ant_path_matcher

+ 3 - 7
imwork-windows/imwork-silos/src/main/resources/static/assets/silos/css/admin.css

@@ -268,6 +268,9 @@
     font-weight: 400;
     white-space: nowrap;
 }
+.canvas-tabs-menu li span{
+    padding-left: 5px;
+}
 
 .canvas-tabs-menu li.active{
     height: 100%;
@@ -451,13 +454,6 @@
     display: block;
 }
 
-.x-iframe {
-    width: 100%;
-    height: 100%;
-    overflow-x: hidden;
-    overflow-y: scroll
-}
-
 .icon-close-padd {
     margin: 0;
     padding: 0px 0px;

+ 34 - 1
imwork-windows/imwork-silos/src/main/resources/static/assets/silos/css/core.css

@@ -47,4 +47,37 @@ p {
     transition: all .5s;
 }
 
-/*以上为初始化样式*/
+/*以上为初始化样式*/
+/* ===== IFRAME 样式 ===== */
+.x-iframe {
+    border: none;
+    background: transparent;
+    inline-size: 100%;
+    block-size: 100%;
+    display: block;
+    width: 100%;
+    height: 100%;
+    overflow-x: hidden;
+    overflow-y: scroll;
+    overscroll-behavior: contain;
+    scrollbar-width: thin;
+    scrollbar-color: #e5e7eb transparent;
+}
+
+.x-iframe::-webkit-scrollbar {
+    inline-size: 6px;
+    block-size: 6px;
+}
+
+.x-iframe::-webkit-scrollbar-track {
+    background: transparent;
+}
+
+.x-iframe::-webkit-scrollbar-thumb {
+    border: 2px solid transparent;
+    background-clip: content-box;
+}
+
+.x-iframe::-webkit-scrollbar-thumb:hover {
+    background-clip: content-box;
+}

+ 403 - 286
imwork-windows/imwork-silos/src/main/resources/static/assets/silos/js/admin.js

@@ -1,318 +1,435 @@
-//导航收缩展开
-bind_event($(".canvas-nav-item>a"), function () {
-    if (!$('.canvas-nav-item').hasClass('canvas-nav-small')) {
-        if ($(this).next().css('display') == "none") {
-            //展开未展开
-            $('.canvas-nav-item').children('ul').slideUp(300);
-            $(this).next('ul').slideDown(300);
-            $(this).parent('li').addClass('canvas-nav-show').siblings('li').removeClass('canvas-nav-show');
-        } else {
-            //收缩已展开
-            $(this).next('ul').slideUp(300);
-            $('.canvas-nav-item.canvas-nav-show').removeClass('canvas-nav-show');
+/**
+ * 工具函数模块
+ */
+const Utils = {
+    // 生成唯一 ID
+    generateId() {
+        return 'tab_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
+    },
+
+    // 判断元素是否可见(包括祖先)
+    isVisible(el) {
+        if (!el) return false;
+        let elem = el;
+        while (elem) {
+            if (window.getComputedStyle(elem).display === 'none') {
+                return false;
+            }
+            elem = elem.parentElement;
         }
-    }
-});
-// 收放导航列表
-bind_event($(".switch-list"), function () {
-    //收缩按钮切换
-    if ($(this).children("i").hasClass("layui-icon layui-icon-shrink-right")) {
-        $(this).children("i").removeClass("layui-icon layui-icon-shrink-right");
-        $(this).children("i").addClass("layui-icon layui-icon-spread-left");
-    } else {
-        $(this).children("i").removeClass("layui-icon layui-icon-spread-left");
-        $(this).children("i").addClass("layui-icon layui-icon-shrink-right");
-    }
+        return true;
+    },
 
-    /*canvas-nav-small切换*/
-    if ($('.layout-body').hasClass('canvas-nav-small')) {
-        $('.layout-body').removeClass('canvas-nav-small');
-    } else {
-        $('.canvas-nav-item').removeClass('canvas-nav-show');
-        $('.canvas-nav-item').children('ul').removeAttr('style');
-        $('.layout-body').addClass('canvas-nav-small');
-    }
-});
+    // 日志输出(带类型)
+    log(...args) {
+        args.forEach(arg => {
+            console.log(`[type => ${typeof arg}, content =>`, arg, ']');
+        });
+    },
 
+    // 删除节点(安全)
+    removeNode(...nodes) {
+        nodes.forEach(node => {
+            if (node && typeof node.remove === 'function') {
+                node.remove();
+            }
+        });
+    },
 
-//全屏
-function fullScreen(id) {
-    var el = document.documentElement;
-    var rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen;
-    if (typeof rfs != "undefined" && rfs) {
-        rfs.call(el);
-    } else {
-        msg("浏览器不支持全屏调用,请使用其他浏览器或按F11键切换全屏!");
-        return;
+    // 阻止事件冒泡(现代浏览器)
+    stopPropagation(e) {
+        e.stopPropagation();
     }
+};
+
+/**
+ * 消息提示模块
+ */
+const Message = {
+    // layer.tips 封装
+    tips(target, str) {
+        layer.tips(str, $(target), {
+            tips: [1, '#3595CC'],
+            time: 0
+        });
+    },
 
-    $("#" + id).attr("onclick", "exitScreen('" + id + "')");
-    $("#" + id).attr("onmouseenter", "getTips(this, '退出全屏')");
-    $("#" + id).find("i").attr("class", "fa fa-arrows");
-}
-
-//退出全屏
-function exitScreen(id) {
-    if (document.exitFullscreen) {
-        document.exitFullscreen();
-    } else if (document.mozCancelFullScreen) {
-        document.mozCancelFullScreen();
-    } else if (document.webkitCancelFullScreen) {
-        document.webkitCancelFullScreen();
-    } else if (document.msExitFullscreen) {
-        document.msExitFullscreen();
+    // layer.msg 封装(修复参数错误)
+    msg(str, icon, offset) {
+        const options = {
+            offset: offset || '20px'
+        };
+        if (icon !== undefined && icon !== null && icon !== '') {
+            options.icon = icon;
+        }
+        return layer.msg(str || '没有内容', options);
     }
-    if (typeof cfs != "undefined" && cfs) {
-        cfs.call(el);
+};
+
+/**
+ * 显示控制模块
+ */
+const Display = {
+    toggle(selector, displayValue = 'block') {
+        const el = typeof selector === 'string' ? document.querySelector(selector) : selector;
+        if (!el) return;
+        const isVisible = window.getComputedStyle(el).display !== 'none';
+        el.style.display = isVisible ? 'none' : displayValue;
+    },
+    adjustIframeHeight(iframe) {
+        try {
+            // 获取内嵌文档的实际高度
+            const width = iframe.contentWindow.document.body.scrollWidth;
+            iframe.style.width = `${width}px`;
+        } catch (e) {
+            console.warn("跨域限制无法自动调整高度");
+        }
     }
+};
+
+/**
+ * 全屏控制模块
+ */
+const Fullscreen = {
+    isFullscreen() {
+        return !!(document.fullscreenElement ||
+            document.webkitFullscreenElement ||
+            document.mozFullScreenElement ||
+            document.msFullscreenElement);
+    },
 
-    $("#" + id).find("i").attr("class", "fa fa-arrows-alt");
-    $("#" + id).attr("onclick", "fullScreen('" + id + "')");
-    $("#" + id).attr("onmouseenter", "getTips(this, '全屏')");
-}
-
-//判断是否IE浏览器
-function IEVersion() {
-    var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
-    var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
-    var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
-    var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
-    if(isIE) {
-        var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
-        reIE.test(userAgent);
-        var fIEVersion = parseFloat(RegExp["$1"]);
-        if(fIEVersion == 7) {
-            return 7;
-        } else if(fIEVersion == 8) {
-            return 8;
-        } else if(fIEVersion == 9) {
-            return 9;
-        } else if(fIEVersion == 10) {
-            return 10;
+    request(id) {
+        const el = document.documentElement;
+        if (el.requestFullscreen) {
+            el.requestFullscreen();
+        } else if (el.webkitRequestFullscreen) {
+            el.webkitRequestFullscreen();
+        } else if (el.mozRequestFullScreen) {
+            el.mozRequestFullScreen();
+        } else if (el.msRequestFullscreen) {
+            el.msRequestFullscreen();
         } else {
-            return 6;//IE版本<=7
+            Message.msg('浏览器不支持全屏,请按 F11 键手动全屏!');
+            return;
+        }
+
+        // 更新按钮状态
+        const $btn = $(`#${id}`);
+        $btn.attr('onclick', `Fullscreen.exit('${id}')`)
+            .attr('onmouseenter', `Message.tips(this, '退出全屏')`)
+            .find('i').attr('class', 'fa fa-arrows');
+    },
+
+    exit(id) {
+        if (document.exitFullscreen) {
+            document.exitFullscreen();
+        } else if (document.webkitExitFullscreen) {
+            document.webkitExitFullscreen();
+        } else if (document.mozCancelFullScreen) {
+            document.mozCancelFullScreen();
+        } else if (document.msExitFullscreen) {
+            document.msExitFullscreen();
         }
-    } else if(isEdge) {
-        return 'edge';//edge
-    } else if(isIE11) {
-        return 11; //IE11
-    }else{
-        return -1;//不是ie浏览器
+
+        // 更新按钮状态
+        const $btn = $(`#${id}`);
+        $btn.attr('onclick', `Fullscreen.request('${id}')`)
+            .attr('onmouseenter', `Message.tips(this, '全屏')`)
+            .find('i').attr('class', 'fa fa-arrows-alt');
     }
-}
+};
 
+/**
+ * 标签页管理模块
+ */
+const TabsManager = {
+    currentMenuId: null,
+    currentContentId: null,
 
-$(function () {
-    $('.tabs').on('click', function (event) {
-        event.preventDefault();
-        var $this = $(this), url = $this.attr('href'),
-            title = $.trim($this.text());
-        var id= $this.attr('id');
-        var icons = $this.attr('icons');
-        if (url && url !== 'javascript:;') {
-            addtabs(id,title,icons,url,true);
+    add(id, title, icons, url) {
+        const safeId = id || Utils.generateId();
+        const menuId = `tabs-menu-${safeId}`;
+        const contentId = `tabs-content-${safeId}`;
+
+        // 如果已存在,激活即可
+        if ($('#' + menuId).length) {
+            this.activate(menuId, contentId);
+            return;
         }
-    });
 
-    var currentTabMenuId = 'tabs-menu-0';
-    var currentTabContentId = 'tabs-content-0';
-    var pageCounter = 0;
-    /**
-     * id:       tab页签的html标签ID属性格式为"tab-"+id,内容容器的html标签ID格式为"tab-content-"+id
-     * title:     tab页签的显示文本
-     * url:      打开的iframe的url
-     * innerTab: 是否是内部弹出页(打开的tab页触发添加新的tab页),默认为undefined/false
-     */
-    function addtabs(id,title,icons,url,innerTab) {
-
-        //如果某个页面已经打开,则切换到该页显示即可,不会新添加tab页
-        if ($('#tabs-menu-' + id).length > 0) {
-            currentTabMenuId = "tabs-menu-"+id;
-            $('#tabs-menu-' + id).addClass('active').siblings().removeClass('active');
-            // 标签对应的内容容器切换
-            currentTabContentId = "tabs-content-"+id;
-            $(".canvas-tabs-content > div").eq($('#tabs-content-' + id).index()).addClass('active').siblings().removeClass('active');
+        // 创建菜单项
+        const $menu = $(`
+            <li id="${menuId}" data-target="${contentId}">
+                <div class="hover-box"></div>
+                <span>${icons ? `<i class="${icons}"></i>` : ''}${title}<i class="layui-icon layui-icon-close icon-close-padd"></i></span>
+                
+            </li>
+        `);
+
+        // 创建内容区
+        const $content = $(`
+            <div id="${contentId}" class="tab-content">
+                <iframe src="${url}" class="x-iframe" style="width:100%;height:100%"></iframe>
+            </div>
+        `);
+
+        // 激活新 tab
+        $('.canvas-tabs-menu li').removeClass('active');
+        $('.canvas-tabs-content > div').removeClass('active');
+
+        $menu.addClass('active');
+        $content.addClass('active');
+
+        $('.canvas-tabs-menu').append($menu);
+        $('.canvas-tabs-content').append($content);
+
+        this.currentMenuId = menuId;
+        this.currentContentId = contentId;
+    },
+
+    activate(menuId, contentId) {
+        $('.canvas-tabs-menu li').removeClass('active');
+        $('.canvas-tabs-content > div').removeClass('active');
+
+        $(`#${menuId}`).addClass('active');
+        $(`#${contentId}`).addClass('active');
+
+        this.currentMenuId = menuId;
+        this.currentContentId = contentId;
+    },
+
+    close(menuId) {
+        const $menu = $(`#${menuId}`);
+        const contentId = $menu.data('target');
+
+        // 销毁 iframe(关键!)
+        const $iframe = $(`#${contentId} iframe`);
+        if ($iframe.length) {
+            $iframe[0].src = 'about:blank'; // 强制卸载资源
+            $iframe.remove();
+        }
+
+        // 移除 DOM
+        $menu.remove();
+        $(`#${contentId}`).remove();
+
+        // 激活相邻 tab
+        const $prev = $menu.prev('li');
+        const $next = $menu.next('li');
+        if ($prev.length) {
+            this.activate($prev.attr('id'), $prev.data('target'));
+        } else if ($next.length) {
+            this.activate($next.attr('id'), $next.data('target'));
         } else {
-            var tab_id = "tabs-menu-" + id,
-                tab_content_id = "tabs-content-" + id;
-
-            currentTabMenuId = tab_id;
-            //添加tab页签
-            $(".canvas-tabs-menu > li").removeClass("active");
-            $(".canvas-tabs-menu").append("<li id='" + tab_id + "' class='active'><div class='hover-box'></div><i class=''></i>" + title + "<i class='layui-icon layui-icon-close icon-close-padd'></i></li>");
-
-            //添加新的内容显示
-            currentTabContentId = tab_content_id;
-            $(".canvas-tabs-content > div").removeClass("active");
-            $(".canvas-tabs-content").append("<div id='" + tab_content_id + "' class='active'>"
-                + "<iframe id='iframepage" + (pageCounter++) + "' name='iframepage" + (pageCounter++)
-                + "' width='100%' frameborder='0' scrolling='yes'  src='" + url + "' class='x-iframe'></iframe></div>");
+            // 回退到首页(假设 tabs-menu-0 存在)
+            if ($('#tabs-menu-0').length) {
+                this.activate('tabs-menu-0', 'tabs-content-0');
+            }
+        }
+    },
+
+    closeCurrent() {
+        if (this.currentMenuId && this.currentMenuId !== 'tabs-menu-0') {
+            this.close(this.currentMenuId);
+        }
+    },
+
+    closeOthers() {
+        if (this.currentMenuId === 'tabs-menu-0') {
+            $('.canvas-tabs-menu li:not(#tabs-menu-0)').remove();
+            $('.canvas-tabs-content div:not(#tabs-content-0)').remove();
+            this.activate('tabs-menu-0', 'tabs-content-0');
+        } else {
+            // 保留当前和首页
+            $('.canvas-tabs-menu li').each((_, el) => {
+                const id = el.id;
+                if (id !== this.currentMenuId && id !== 'tabs-menu-0') {
+                    $(el).remove();
+                }
+            });
+            $('.canvas-tabs-content div').each((_, el) => {
+                const id = el.id;
+                if (id !== this.currentContentId && id !== 'tabs-content-0') {
+                    $(el).remove();
+                }
+            });
+            this.activate(this.currentMenuId, this.currentContentId);
         }
+    },
+
+    closeAll() {
+        $('.canvas-tabs-menu li:not(#tabs-menu-0)').remove();
+        $('.canvas-tabs-content div:not(#tabs-content-0)').remove();
+        this.activate('tabs-menu-0', 'tabs-content-0');
+    }
+};
+
+/**
+ * 主初始化逻辑
+ */
+$(function () {
+    // 初始化首页(确保 tabs-menu-0 存在)
+    if (!$('#tabs-menu-0').length) {
+        $('.canvas-tabs-menu').append(`
+            <li id="tabs-menu-0" data-target="tabs-content-0" class="active">
+                <div class="hover-box"></div>
+                <span>首页</span>
+            </li>
+        `);
+        $('.canvas-tabs-content').append(`
+            <div id="tabs-content-0" class="tab-content active">
+                <iframe src="./welcome.html" class="x-iframe" style="width:100%;height:100%"></iframe>
+            </div>
+        `);
+        TabsManager.currentMenuId = 'tabs-menu-0';
+        TabsManager.currentContentId = 'tabs-content-0';
     }
 
-    //切换tab页的显示
+    // 点击链接添加 tab
+    $('.tabs').on('click', function (e) {
+        e.preventDefault();
+        const $this = $(this);
+        const url = $this.attr('href');
+        const title = $.trim($this.text());
+        const id = $this.attr('id') || Utils.generateId();
+        const icons = $this.attr('icons');
+        if (url && url !== 'javascript:;') {
+            TabsManager.add(id, title, icons, url);
+        }
+    });
+
+    // 切换 tab(点击菜单项)
     $(document).on('click', '.canvas-tabs-menu > li', function (e) {
-        //清除原来显示的tab页,设置新的显示tab页
-        var _this = $(this)
-        currentTabMenuId = _this.attr("id");
-        _this.addClass('active').siblings(_this).removeClass('active');
-        // 标签对应的内容容器切换
-        var t_id=currentTabMenuId.substr(currentTabMenuId.length-1,1);
-        currentTabContentId = "tabs-content-"+t_id;
-        $(".canvas-tabs-content > div").eq(_this.index()).addClass('active').siblings().removeClass('active');
-    })
-
-    //删除目标tab页的显示
-    $(document).on('click', '.canvas-tabs-menu .icon-close-padd', function (e) {
-        e.stopPropagation();
-        //获取tabs列表
-        var u_l = $(".canvas-tabs-menu > li");
-        //删除目标tab页
-        var _this = $(this);
-        //获取当前tabs索引
-        var num = _this.parent().index();
-        //获取当前tabs id
-        var id = _this.parent().attr('id');
-        //删除当前tabs
-        $("#"+id).remove();
-        // 删除目标内容容器
-        var t_id=id.substr(id.length-1,1);
-        $("#tabs-content-"+t_id).remove();
-
-        var u_t=u_l.eq(num-1).attr('id');
-        var flag = $("#"+u_t).hasClass("active");
-
-        if(flag){
-
-        }else{
-            currentTabMenuId = u_t;
-            $("#"+u_t).addClass("active").siblings($("#"+u_t)).removeClass('active');
-
-            var t_c_id=u_t.substr(u_t.length-1,1);
-            currentTabContentId = "tabs-content-"+t_c_id;
-            $("#tabs-content-"+t_c_id).addClass("active").siblings($("#tabs-content-"+t_c_id)).removeClass('active');
+        const id = $(this).closest('li').attr('id');
+        if (id === 'tabs-menu-0') {
+            return;
         }
-    })
+        if ($(e.target).hasClass('icon-close-padd')) return;
+        const menuId = this.id;
+        const contentId = $(this).data('target');
+        TabsManager.activate(menuId, contentId);
+    });
+
+    // 关闭 tab
+    $(document).on('click', '.icon-close-padd', function (e) {
+        Utils.stopPropagation(e);
+        const menuId = $(this).closest('li').attr('id');
+        TabsManager.close(menuId);
+    });
 
-    //删除当前页
+    // 关闭当前页
     $(document).on('click', '.closeNowPage', function (e) {
-        e.stopPropagation();
-        if(!(currentTabMenuId === 'tabs-menu-0')){
-            //获取tabs列表
-            var u_l = $(".canvas-tabs-menu > li");
-            //获取当前tabs索引
-            var num = $("#"+currentTabMenuId).index();
-            //删除当前tabs
-            $("#"+currentTabMenuId).remove();
-            // 删除目标内容容器
-            var t_id=currentTabMenuId.substr(currentTabMenuId.length-1,1);
-            $("#tabs-content-"+t_id).remove();
-
-            var u_t=u_l.eq(num-1).attr('id');
-            var flag = $("#"+u_t).hasClass("active");
-
-            if(!flag){
-                currentTabMenuId = u_t;
-                $("#"+u_t).addClass("active").siblings($("#"+u_t)).removeClass('active');
-
-                var t_c_id=u_t.substr(u_t.length-1,1);
-                currentTabContentId = "tabs-content-"+t_c_id;
-                $("#tabs-content-"+t_c_id).addClass("active").siblings($("#tabs-content-"+t_c_id)).removeClass('active');
-            }
-        }
-    })
+        Utils.stopPropagation(e);
+        TabsManager.closeCurrent();
+    });
 
-    //删除其它
+    // 关闭其他页
     $(document).on('click', '.closeOtherPage', function (e) {
-        e.stopPropagation();
-        if(currentTabMenuId === 'tabs-menu-0'){
-            //删除其它tabs
-            $("#tabs-menu-0").siblings($("#tabs-menu-0")).remove();
-            $("#tabs-content-0").siblings($("#tabs-content-0")).remove();
-            currentTabMenuId = "tabs-menu-0";
-            $("#tabs-menu-0").addClass("active")
-            currentTabContentId = "tabs-content-0";
-            $("#tabs-content-0").addClass("active")
-        }else{
-            $("#"+currentTabMenuId).nextAll().remove();
-            $("#"+currentTabMenuId).prevUntil($("#tabs-menu-0")).remove();
-
-            $("#"+currentTabContentId).nextAll().remove();
-            $("#"+currentTabContentId).prevUntil($("#tabs-content-0")).remove();
-        }
-    })
+        Utils.stopPropagation(e);
+        TabsManager.closeOthers();
+    });
 
-    //删除所有页
+    // 关闭所有页
     $(document).on('click', '.closeAllPage', function (e) {
-        e.stopPropagation();
-        //删除其它tabs
-        $("#tabs-menu-0").siblings($("#tabs-menu-0")).remove();
-        $("#tabs-content-0").siblings($("#tabs-content-0")).remove();
-        currentTabMenuId = "tabs-menu-0";
-        $("#tabs-menu-0").addClass("active")
-        currentTabContentId = "tabs-content-0";
-        $("#tabs-content-0").addClass("active")
-    })
-    // 呼出右侧列表
-    $(document).on('click', '.dashboard,.user-info', function (e) {
-        var bar = $(this).attr("tag");
-        if($(".right-bar").hasClass(bar)){
-            remove_node($(".right-bar").find($(".tpl-shade")));
-            if ($("."+bar).css("right") == "-1500px"){
-                $(".right-bar").css("right","-1500px");
-                $("."+bar).css("right",0);
-                $(".tpl-body").css("overflow","hidden");
-            } else {
-                $("."+bar).css("right","-1500px");
-                $(".tpl-body").css("overflow","auto");
-            }
-            // shade($("."+bar).find(".right-bar-fluid"),true);
-            stopPropagation(e);
-        }else{
-            msg("配置的tag目标为空");
+        Utils.stopPropagation(e);
+        TabsManager.closeAll();
+    });
+    // 刷新页面
+    $('.refresh').on('click', () => window.location.reload());
+
+    // 手风琴导航
+    $('.canvas-nav-item > a').on('click', function () {
+        if ($('.canvas-nav-item').hasClass('canvas-nav-small')) return;
+
+        const $parent = $(this).parent('li');
+        const $submenu = $(this).next('ul');
+
+        if ($submenu.is(':hidden')) {
+            $('.canvas-nav-item ul').slideUp(300);
+            $submenu.slideDown(300);
+            $parent.addClass('canvas-nav-show').siblings().removeClass('canvas-nav-show');
+        } else {
+            $submenu.slideUp(300);
+            $parent.removeClass('canvas-nav-show');
         }
-    })
-    $(document).on('click', '.right-bar', function (e) {
-        stopPropagation(e);
-    })
-    // 页面的点击冒泡
+    });
+
+    // 收放导航
+    $('.switch-list').on('click', function () {
+        const $icon = $(this).children('i');
+        if ($icon.hasClass('layui-icon-shrink-right')) {
+            $icon.removeClass('layui-icon-shrink-right').addClass('layui-icon-spread-left');
+        } else {
+            $icon.removeClass('layui-icon-spread-left').addClass('layui-icon-shrink-right');
+        }
+
+        $('.layout-body').toggleClass('canvas-nav-small');
+        if ($('.layout-body').hasClass('canvas-nav-small')) {
+            $('.canvas-nav-item').removeClass('canvas-nav-show').children('ul').removeAttr('style');
+        }
+    });
+
+    // 右侧抽屉栏
+    $(document).on('click', '.dashboard, .user-info', function (e) {
+        const barClass = $(this).attr('tag');
+        if (!barClass) {
+            Message.msg('配置的 tag 目标为空');
+            return;
+        }
+
+        const $bar = $('.' + barClass);
+        if ($bar.length === 0) {
+            Message.msg('未找到对应右侧栏元素');
+            return;
+        }
+
+        Utils.stopPropagation(e);
+        if ($bar.css('right') === '-1500px') {
+            $('.right-bar').css('right', '-1500px');
+            $bar.css('right', 0);
+            $('.tpl-body').css('overflow', 'hidden');
+        } else {
+            $bar.css('right', '-1500px');
+            $('.tpl-body').css('overflow', 'auto');
+        }
+    });
+
+    // 点击遮罩关闭右侧栏
+    $(document).on('click', function () {
+        $('.right-bar').css('right', '-1500px');
+        $('.tpl-body').css('overflow', 'auto');
+    });
+
+    // 阻止右侧栏内部点击关闭
     $(document).on('click', '.right-bar', function (e) {
-        $(".right-bar").css("right","-1500px");
-    })
-    bind_event($(document),function(){
-        $(".right-bar").css("right","-1500px");
-    })
-    // 点击更换页面主题
-    bind_event($("#style-list"),function(e){
-        var style = $(this).attr("theme-style");
-        var styleName = $(".theme-style").attr("style-name");
-        $(".theme-style").removeClass(styleName);
-        $(".theme-style").attr("style-name",style);
-        $(".theme-style").addClass(style);
-        /*$.ajax({ //使用服务器端session保存操作
-            url:"../index/view",
-            type:"post",
-            datatype:"json",
-            data:{
-                stylename:style // 传递到后台,用session保存即可
-            },
-            success:function(data){
-                l(data);
-            }
-        });*/
-        stopPropagation(e);
-    },"click","li");
+        Utils.stopPropagation(e);
+    });
+
+    // 主题切换
+    $('#style-list').on('click', 'li', function (e) {
+        const style = $(this).attr('canvas-theme-style');
+        if (!style) return;
+
+        const $theme = $('.canvas-theme-style');
+        const oldStyle = $theme.attr('style-name') || '';
+        $theme.removeClass(oldStyle).addClass(style).attr('style-name', style);
+
+        Utils.stopPropagation(e);
+    });
+
+    // 全局提示绑定(示例)
+    $('[data-tips]').each(function () {
+        const text = $(this).data('tips');
+        $(this).on('mouseenter', () => Message.tips(this, text));
+    });
 });
 
-layui.define(['layer', 'jquery', 'form', 'carousel', 'element', 'upload'], function (exports) {
-    var $ = layui.$, $body = $('body');
-    //弹出层组件
-    var layer = layui.layer;
-    //表单组件
-    var form = layui.form;
-    var element = layui.element;
-    //轮播组件
-    var carousel = layui.carousel;
-    // 文件上传组件
-    var upload = layui.upload;
-});
+// 暴露全局接口(如需在 HTML 中调用)
+window.fullScreen = Fullscreen.request;
+window.exitScreen = Fullscreen.exit;
+window.msg = Message.msg;
+window.getTips = Message.tips;
+window.toggleDisplay = Display.toggle;
+window.log = Utils.log;
+window.remove_node = Utils.removeNode;
+window.tabsManager = TabsManager

+ 453 - 0
imwork-windows/imwork-silos/src/main/resources/static/business/dashboard/dashboard.css

@@ -0,0 +1,453 @@
+:root {
+    --primary: #4361ee;
+    --secondary: #3f37c9;
+    --success: #4cc9f0;
+    --info: #4895ef;
+    --warning: #f72585;
+    --danger: #e63946;
+    --light: #f8f9fa;
+    --dark: #212529;
+    --sidebar-width: 250px;
+    --header-height: 60px;
+}
+
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+}
+
+body {
+    background-color: #f5f7fb;
+    color: #333;
+    display: flex;
+    min-height: 100vh;
+}
+
+/* 侧边栏样式 */
+.sidebar {
+    width: var(--sidebar-width);
+    background: linear-gradient(180deg, var(--primary), var(--secondary));
+    color: white;
+    height: 100vh;
+    position: fixed;
+    transition: all 0.3s;
+    box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
+    z-index: 1000;
+}
+
+.sidebar-header {
+    padding: 20px;
+    text-align: center;
+    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.sidebar-header h2 {
+    font-size: 1.5rem;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 10px;
+}
+
+.sidebar-menu {
+    padding: 15px 0;
+}
+
+.sidebar-menu ul {
+    list-style: none;
+}
+
+.sidebar-menu li {
+    padding: 12px 20px;
+    transition: all 0.3s;
+}
+
+.sidebar-menu li.active {
+    background-color: rgba(255, 255, 255, 0.1);
+    border-left: 4px solid white;
+}
+
+.sidebar-menu li:hover {
+    background-color: rgba(255, 255, 255, 0.1);
+    cursor: pointer;
+}
+
+.sidebar-menu i {
+    margin-right: 10px;
+    width: 20px;
+    text-align: center;
+}
+
+/* 主内容区样式 */
+.main-content {
+    flex: 1;
+    margin-left: 0;
+    padding: 20px;
+    transition: all 0.3s;
+}
+
+/* 顶部导航栏 */
+.top-nav {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    background: white;
+    padding: 15px 25px;
+    border-radius: 10px;
+    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
+    margin-bottom: 25px;
+}
+
+.search-bar {
+    display: flex;
+    align-items: center;
+    background: var(--light);
+    border-radius: 30px;
+    padding: 8px 15px;
+    width: 300px;
+}
+
+.search-bar input {
+    border: none;
+    background: transparent;
+    outline: none;
+    width: 100%;
+    margin-left: 8px;
+}
+
+.nav-icons {
+    display: flex;
+    gap: 20px;
+}
+
+.nav-icons .icon {
+    position: relative;
+    cursor: pointer;
+}
+
+.nav-icons .badge {
+    position: absolute;
+    top: -5px;
+    right: -5px;
+    background: var(--danger);
+    color: white;
+    border-radius: 50%;
+    width: 18px;
+    height: 18px;
+    font-size: 0.7rem;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.user-profile {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    cursor: pointer;
+}
+
+.user-profile img {
+    width: 40px;
+    height: 40px;
+    border-radius: 50%;
+    object-fit: cover;
+}
+
+/* 欢迎区域 */
+.welcome-section {
+    background: linear-gradient(135deg, var(--primary), var(--info));
+    color: white;
+    padding: 25px;
+    border-radius: 15px;
+    margin-bottom: 25px;
+    box-shadow: 0 10px 20px rgba(67, 97, 238, 0.3);
+}
+
+.welcome-section h1 {
+    font-size: 1.8rem;
+    margin-bottom: 10px;
+}
+
+.quick-actions {
+    display: flex;
+    gap: 15px;
+    margin-top: 20px;
+}
+
+.action-btn {
+    background: rgba(255, 255, 255, 0.2);
+    border: none;
+    color: white;
+    padding: 10px 20px;
+    border-radius: 30px;
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    cursor: pointer;
+    transition: all 0.3s;
+}
+
+.action-btn:hover {
+    background: rgba(255, 255, 255, 0.3);
+    transform: translateY(-2px);
+}
+
+/* KPI 卡片区域 */
+.kpi-cards {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
+    gap: 20px;
+    margin-bottom: 25px;
+}
+
+.kpi-card {
+    background: white;
+    border-radius: 10px;
+    padding: 20px;
+    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
+    transition: all 0.3s;
+    border-left: 4px solid var(--primary);
+}
+
+.kpi-card:hover {
+    transform: translateY(-5px);
+    box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
+}
+
+.kpi-card.sales {
+    border-left-color: var(--primary);
+}
+
+.kpi-card.users {
+    border-left-color: var(--success);
+}
+
+.kpi-card.orders {
+    border-left-color: var(--info);
+}
+
+.kpi-card.revenue {
+    border-left-color: var(--warning);
+}
+
+.kpi-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 15px;
+}
+
+.kpi-header i {
+    font-size: 1.5rem;
+    opacity: 0.7;
+}
+
+.kpi-value {
+    font-size: 1.8rem;
+    font-weight: bold;
+    margin-bottom: 5px;
+}
+
+.kpi-change {
+    font-size: 0.9rem;
+    display: flex;
+    align-items: center;
+    gap: 5px;
+}
+
+.kpi-change.positive {
+    color: #28a745;
+}
+
+.kpi-change.negative {
+    color: #dc3545;
+}
+
+/* 图表区域 */
+.charts-section {
+    display: grid;
+    grid-template-columns: 2fr 1fr;
+    gap: 20px;
+    margin-bottom: 25px;
+}
+
+.chart-container {
+    background: white;
+    border-radius: 10px;
+    padding: 20px;
+    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
+}
+
+.chart-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 15px;
+}
+
+.chart-actions {
+    display: flex;
+    gap: 10px;
+}
+
+.chart-actions select {
+    border: 1px solid #ddd;
+    border-radius: 5px;
+    padding: 5px 10px;
+    outline: none;
+}
+
+/* 动态信息区域 */
+.dynamic-info {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    gap: 20px;
+    margin-bottom: 25px;
+}
+
+.info-card {
+    background: white;
+    border-radius: 10px;
+    padding: 20px;
+    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
+}
+
+.info-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 15px;
+    padding-bottom: 10px;
+    border-bottom: 1px solid #eee;
+}
+
+.info-list {
+    list-style: none;
+}
+
+.info-item {
+    display: flex;
+    justify-content: space-between;
+    padding: 12px 0;
+    border-bottom: 1px solid #f5f5f5;
+}
+
+.info-item:last-child {
+    border-bottom: none;
+}
+
+.status {
+    padding: 4px 10px;
+    border-radius: 20px;
+    font-size: 0.8rem;
+    font-weight: bold;
+}
+
+.status.pending {
+    background: #fff3cd;
+    color: #856404;
+}
+
+.status.completed {
+    background: #d1ecf1;
+    color: #0c5460;
+}
+
+.status.processing {
+    background: #d4edda;
+    color: #155724;
+}
+
+/* 系统状态区域 */
+.system-status {
+    background: white;
+    border-radius: 10px;
+    padding: 20px;
+    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
+    margin-bottom: 25px;
+}
+
+.status-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+    gap: 15px;
+    margin-top: 15px;
+}
+
+.status-item {
+    display: flex;
+    flex-direction: column;
+    gap: 10px;
+}
+
+.status-header {
+    display: flex;
+    justify-content: space-between;
+}
+
+.progress-bar {
+    height: 8px;
+    background: #e9ecef;
+    border-radius: 4px;
+    overflow: hidden;
+}
+
+.progress {
+    height: 100%;
+    border-radius: 4px;
+}
+
+.progress.safe {
+    background: #28a745;
+}
+
+.progress.warning {
+    background: #ffc107;
+}
+
+.progress.danger {
+    background: #dc3545;
+}
+
+/* 响应式设计 */
+@media (max-width: 992px) {
+    .charts-section {
+        grid-template-columns: 1fr;
+    }
+
+    .dynamic-info {
+        grid-template-columns: 1fr;
+    }
+}
+
+@media (max-width: 1600px) {
+    .sidebar {
+        width: 70px;
+    }
+
+    .sidebar-header h2 span,
+    .sidebar-menu li span {
+        display: none;
+    }
+
+    .sidebar-menu li {
+        text-align: center;
+        padding: 15px 0;
+    }
+
+    .sidebar-menu i {
+        margin-right: 0;
+        font-size: 1.2rem;
+    }
+
+    .main-content {
+        margin-left: 0;
+    }
+
+    .quick-actions {
+        flex-wrap: wrap;
+    }
+}

+ 58 - 0
imwork-windows/imwork-silos/src/main/resources/static/business/dashboard/dashboard.js

@@ -0,0 +1,58 @@
+// 初始化销售趋势图表
+const salesCtx = document.getElementById('salesChart').getContext('2d');
+const salesChart = new Chart(salesCtx, {
+    type: 'line',
+    data: {
+        labels: ['10月1日', '10月5日', '10月10日', '10月15日', '10月20日', '10月25日'],
+        datasets: [{
+            label: '销售额 (万元)',
+            data: [12, 19, 15, 22, 18, 25],
+            borderColor: '#4361ee',
+            backgroundColor: 'rgba(67, 97, 238, 0.1)',
+            borderWidth: 2,
+            fill: true,
+            tension: 0.4
+        }]
+    },
+    options: {
+        responsive: true,
+        plugins: {
+            legend: {
+                position: 'top',
+            }
+        },
+        scales: {
+            y: {
+                beginAtZero: true
+            }
+        }
+    }
+});
+
+// 初始化用户来源图表
+const userSourceCtx = document.getElementById('userSourceChart').getContext('2d');
+const userSourceChart = new Chart(userSourceCtx, {
+    type: 'doughnut',
+    data: {
+        labels: ['直接访问', '搜索引擎', '社交媒体', '邮件营销', '合作伙伴'],
+        datasets: [{
+            data: [35, 25, 20, 12, 8],
+            backgroundColor: [
+                '#4361ee',
+                '#4cc9f0',
+                '#3f37c9',
+                '#4895ef',
+                '#f72585'
+            ],
+            borderWidth: 0
+        }]
+    },
+    options: {
+        responsive: true,
+        plugins: {
+            legend: {
+                position: 'bottom',
+            }
+        }
+    }
+});

+ 252 - 0
imwork-windows/imwork-silos/src/main/resources/templates/main/dashboard.html

@@ -0,0 +1,252 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>企业管理系统 - 仪表盘</title>
+    <link rel="shortcut icon" href="../../static/assets/silos/images/logo/logo.png" th:href="@{/assets/silos/images/logo/logo.png}"/>
+    <link rel="bookmark" href="../../static/assets/silos/images/logo/logo.png" th:href="@{/assets/silos/images/logo/logo.png}"/>
+    <link rel="stylesheet" href="../../static/assets/lib/layui/css/layui.css" th:href="@{/assets/lib/layui/css/layui.css}"/>
+    <link rel="stylesheet" href="../../static/assets/lib/fonts/fontawesome6/css/all.css" th:href="@{/assets/lib/fonts/fontawesome6/css/all.css}">
+    <link rel="stylesheet" href="../../static/business/dashboard/dashboard.css" th:href="@{/business/dashboard/dashboard.css}">
+
+</head>
+<body>
+<!-- 主内容区 -->
+<div class="main-content">
+    <!-- 顶部导航栏 -->
+    <div class="top-nav">
+        <div class="search-bar">
+            <i class="fas fa-search"></i>
+            <input type="text" placeholder="搜索...">
+        </div>
+        <div class="nav-icons">
+            <div class="icon">
+                <i class="far fa-bell"></i>
+                <div class="badge">5</div>
+            </div>
+            <div class="icon">
+                <i class="far fa-envelope"></i>
+                <div class="badge">3</div>
+            </div>
+            <div class="user-profile">
+                <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="用户头像">
+                <span>张经理</span>
+            </div>
+        </div>
+    </div>
+
+    <!-- 欢迎区域 -->
+    <div class="welcome-section">
+        <h1>早上好,张经理!</h1>
+        <p>今天是2023年10月26日,天气晴朗。以下是您的系统概览。</p>
+        <div class="quick-actions">
+            <button class="action-btn"><i class="fas fa-plus"></i> 新建订单</button>
+            <button class="action-btn"><i class="fas fa-user-plus"></i> 添加用户</button>
+            <button class="action-btn"><i class="fas fa-file-export"></i> 导出数据</button>
+            <button class="action-btn"><i class="fas fa-chart-pie"></i> 生成报告</button>
+        </div>
+    </div>
+
+    <!-- KPI 卡片区域 -->
+    <div class="kpi-cards">
+        <div class="kpi-card sales">
+            <div class="kpi-header">
+                <h3>总销售额</h3>
+                <i class="fas fa-shopping-cart"></i>
+            </div>
+            <div class="kpi-value">¥ 1,234,567</div>
+            <div class="kpi-change positive">
+                <i class="fas fa-arrow-up"></i> 12.5% 较上月
+            </div>
+        </div>
+        <div class="kpi-card users">
+            <div class="kpi-header">
+                <h3>新增用户</h3>
+                <i class="fas fa-users"></i>
+            </div>
+            <div class="kpi-value">1,234</div>
+            <div class="kpi-change positive">
+                <i class="fas fa-arrow-up"></i> 8.2% 较上月
+            </div>
+        </div>
+        <div class="kpi-card orders">
+            <div class="kpi-header">
+                <h3>订单总数</h3>
+                <i class="fas fa-clipboard-list"></i>
+            </div>
+            <div class="kpi-value">567</div>
+            <div class="kpi-change negative">
+                <i class="fas fa-arrow-down"></i> 2.1% 较上月
+            </div>
+        </div>
+        <div class="kpi-card revenue">
+            <div class="kpi-header">
+                <h3>平均客单价</h3>
+                <i class="fas fa-dollar-sign"></i>
+            </div>
+            <div class="kpi-value">¥ 245</div>
+            <div class="kpi-change positive">
+                <i class="fas fa-arrow-up"></i> 5.3% 较上月
+            </div>
+        </div>
+    </div>
+
+    <!-- 图表区域 -->
+    <div class="charts-section">
+        <div class="chart-container">
+            <div class="chart-header">
+                <h3>销售趋势</h3>
+                <div class="chart-actions">
+                    <select>
+                        <option>最近7天</option>
+                        <option>最近30天</option>
+                        <option>最近90天</option>
+                    </select>
+                </div>
+            </div>
+            <canvas id="salesChart"></canvas>
+        </div>
+        <div class="chart-container">
+            <div class="chart-header">
+                <h3>用户来源</h3>
+                <div class="chart-actions">
+                    <select>
+                        <option>本月</option>
+                        <option>上个月</option>
+                        <option>本季度</option>
+                    </select>
+                </div>
+            </div>
+            <canvas id="userSourceChart"></canvas>
+        </div>
+    </div>
+
+    <!-- 动态信息区域 -->
+    <div class="dynamic-info">
+        <div class="info-card">
+            <div class="info-header">
+                <h3>最新订单</h3>
+                <a href="#">查看全部</a>
+            </div>
+            <ul class="info-list">
+                <li class="info-item">
+                    <div>
+                        <div>#ORD-7845</div>
+                        <div class="text-muted">2023-10-26 10:23</div>
+                    </div>
+                    <div class="status pending">待处理</div>
+                </li>
+                <li class="info-item">
+                    <div>
+                        <div>#ORD-7844</div>
+                        <div class="text-muted">2023-10-26 09:45</div>
+                    </div>
+                    <div class="status processing">处理中</div>
+                </li>
+                <li class="info-item">
+                    <div>
+                        <div>#ORD-7843</div>
+                        <div class="text-muted">2023-10-26 08:12</div>
+                    </div>
+                    <div class="status completed">已完成</div>
+                </li>
+                <li class="info-item">
+                    <div>
+                        <div>#ORD-7842</div>
+                        <div class="text-muted">2023-10-25 16:33</div>
+                    </div>
+                    <div class="status completed">已完成</div>
+                </li>
+            </ul>
+        </div>
+        <div class="info-card">
+            <div class="info-header">
+                <h3>系统活动</h3>
+                <a href="#">查看全部</a>
+            </div>
+            <ul class="info-list">
+                <li class="info-item">
+                    <div>
+                        <div>新用户注册</div>
+                        <div class="text-muted">用户 "张三" 刚刚注册</div>
+                    </div>
+                    <div class="text-muted">2分钟前</div>
+                </li>
+                <li class="info-item">
+                    <div>
+                        <div>订单完成</div>
+                        <div class="text-muted">订单 #ORD-7841 已标记为完成</div>
+                    </div>
+                    <div class="text-muted">15分钟前</div>
+                </li>
+                <li class="info-item">
+                    <div>
+                        <div>库存预警</div>
+                        <div class="text-muted">产品 "智能手机" 库存不足</div>
+                    </div>
+                    <div class="text-muted">1小时前</div>
+                </li>
+                <li class="info-item">
+                    <div>
+                        <div>系统备份</div>
+                        <div class="text-muted">每日系统备份已完成</div>
+                    </div>
+                    <div class="text-muted">3小时前</div>
+                </li>
+            </ul>
+        </div>
+    </div>
+
+    <!-- 系统状态区域 -->
+    <div class="system-status">
+        <div class="info-header">
+            <h3>系统状态</h3>
+            <div class="text-muted">最后更新: 刚刚</div>
+        </div>
+        <div class="status-grid">
+            <div class="status-item">
+                <div class="status-header">
+                    <span>CPU 使用率</span>
+                    <span>42%</span>
+                </div>
+                <div class="progress-bar">
+                    <div class="progress safe" style="width: 42%"></div>
+                </div>
+            </div>
+            <div class="status-item">
+                <div class="status-header">
+                    <span>内存使用率</span>
+                    <span>67%</span>
+                </div>
+                <div class="progress-bar">
+                    <div class="progress warning" style="width: 67%"></div>
+                </div>
+            </div>
+            <div class="status-item">
+                <div class="status-header">
+                    <span>磁盘空间</span>
+                    <span>78%</span>
+                </div>
+                <div class="progress-bar">
+                    <div class="progress warning" style="width: 78%"></div>
+                </div>
+            </div>
+            <div class="status-item">
+                <div class="status-header">
+                    <span>数据库连接</span>
+                    <span>正常</span>
+                </div>
+                <div class="progress-bar">
+                    <div class="progress safe" style="width: 100%"></div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script src="../../static/assets/lib/jquery/jquery.js" th:src="@{/assets/lib/jquery/jquery.js}"></script>
+<script src="../../static/assets/lib/layui/layui.js" th:src="@{/assets/lib/layui/layui.js}"></script>
+<script src="../../static/assets/lib/jplus/chart/chart.js" th:src="@{/assets/lib/jplus/chart/chart.js}"></script>
+<script src="../../static/business/dashboard/dashboard.js" th:src="@{/business/dashboard/dashboard.js}"></script>
+</body>
+</html>

+ 2 - 2
imwork-windows/imwork-silos/src/main/resources/templates/main/index.html

@@ -123,7 +123,7 @@
                         </li>
                         <li>
                             <div class="hover-box-header"></div>
-                            <a href="../login/login.html" onclick="this.logout();" onmouseenter="getTips(this, '退出系统')" onmouseleave="layer.closeAll('tips')" class="ripple"><i class="fa fa-power-off"></i></a>
+                            <a href="../auth/logout" onclick="this.logout();" onmouseenter="getTips(this, '退出系统')" onmouseleave="layer.closeAll('tips')" class="ripple"><i class="fa fa-power-off"></i></a>
                         </li>
                     </ul>
                 </div>
@@ -151,7 +151,7 @@
             </div>
             <div class="canvas-tabs-content">
                 <div id="tabs-content-0" class="active">
-                    <iframe src='./welcome.html' frameborder="0" scrolling="yes" class="x-iframe"></iframe>
+                    <iframe src='./dashboard.html' class="x-iframe"></iframe>
                 </div>
             </div>
         </div>

+ 318 - 0
配套资料/模块/bak/admin.js

@@ -0,0 +1,318 @@
+//导航收缩展开
+bind_event($(".canvas-nav-item>a"), function () {
+    if (!$('.canvas-nav-item').hasClass('canvas-nav-small')) {
+        if ($(this).next().css('display') == "none") {
+            //展开未展开
+            $('.canvas-nav-item').children('ul').slideUp(300);
+            $(this).next('ul').slideDown(300);
+            $(this).parent('li').addClass('canvas-nav-show').siblings('li').removeClass('canvas-nav-show');
+        } else {
+            //收缩已展开
+            $(this).next('ul').slideUp(300);
+            $('.canvas-nav-item.canvas-nav-show').removeClass('canvas-nav-show');
+        }
+    }
+});
+// 收放导航列表
+bind_event($(".switch-list"), function () {
+    //收缩按钮切换
+    if ($(this).children("i").hasClass("layui-icon layui-icon-shrink-right")) {
+        $(this).children("i").removeClass("layui-icon layui-icon-shrink-right");
+        $(this).children("i").addClass("layui-icon layui-icon-spread-left");
+    } else {
+        $(this).children("i").removeClass("layui-icon layui-icon-spread-left");
+        $(this).children("i").addClass("layui-icon layui-icon-shrink-right");
+    }
+
+    /*canvas-nav-small切换*/
+    if ($('.layout-body').hasClass('canvas-nav-small')) {
+        $('.layout-body').removeClass('canvas-nav-small');
+    } else {
+        $('.canvas-nav-item').removeClass('canvas-nav-show');
+        $('.canvas-nav-item').children('ul').removeAttr('style');
+        $('.layout-body').addClass('canvas-nav-small');
+    }
+});
+
+
+//全屏
+function fullScreen(id) {
+    var el = document.documentElement;
+    var rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen;
+    if (typeof rfs != "undefined" && rfs) {
+        rfs.call(el);
+    } else {
+        msg("浏览器不支持全屏调用,请使用其他浏览器或按F11键切换全屏!");
+        return;
+    }
+
+    $("#" + id).attr("onclick", "exitScreen('" + id + "')");
+    $("#" + id).attr("onmouseenter", "getTips(this, '退出全屏')");
+    $("#" + id).find("i").attr("class", "fa fa-arrows");
+}
+
+//退出全屏
+function exitScreen(id) {
+    if (document.exitFullscreen) {
+        document.exitFullscreen();
+    } else if (document.mozCancelFullScreen) {
+        document.mozCancelFullScreen();
+    } else if (document.webkitCancelFullScreen) {
+        document.webkitCancelFullScreen();
+    } else if (document.msExitFullscreen) {
+        document.msExitFullscreen();
+    }
+    if (typeof cfs != "undefined" && cfs) {
+        cfs.call(el);
+    }
+
+    $("#" + id).find("i").attr("class", "fa fa-arrows-alt");
+    $("#" + id).attr("onclick", "fullScreen('" + id + "')");
+    $("#" + id).attr("onmouseenter", "getTips(this, '全屏')");
+}
+
+//判断是否IE浏览器
+function IEVersion() {
+    var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
+    var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
+    var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
+    var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
+    if(isIE) {
+        var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
+        reIE.test(userAgent);
+        var fIEVersion = parseFloat(RegExp["$1"]);
+        if(fIEVersion == 7) {
+            return 7;
+        } else if(fIEVersion == 8) {
+            return 8;
+        } else if(fIEVersion == 9) {
+            return 9;
+        } else if(fIEVersion == 10) {
+            return 10;
+        } else {
+            return 6;//IE版本<=7
+        }
+    } else if(isEdge) {
+        return 'edge';//edge
+    } else if(isIE11) {
+        return 11; //IE11
+    }else{
+        return -1;//不是ie浏览器
+    }
+}
+
+
+$(function () {
+    $('.tabs').on('click', function (event) {
+        event.preventDefault();
+        var $this = $(this), url = $this.attr('href'),
+            title = $.trim($this.text());
+        var id= $this.attr('id');
+        var icons = $this.attr('icons');
+        if (url && url !== 'javascript:;') {
+            addtabs(id,title,icons,url,true);
+        }
+    });
+
+    var currentTabMenuId = 'tabs-menu-0';
+    var currentTabContentId = 'tabs-content-0';
+    var pageCounter = 0;
+    /**
+     * id:       tab页签的html标签ID属性格式为"tab-"+id,内容容器的html标签ID格式为"tab-content-"+id
+     * title:     tab页签的显示文本
+     * url:      打开的iframe的url
+     * innerTab: 是否是内部弹出页(打开的tab页触发添加新的tab页),默认为undefined/false
+     */
+    function addtabs(id,title,icons,url,innerTab) {
+
+        //如果某个页面已经打开,则切换到该页显示即可,不会新添加tab页
+        if ($('#tabs-menu-' + id).length > 0) {
+            currentTabMenuId = "tabs-menu-"+id;
+            $('#tabs-menu-' + id).addClass('active').siblings().removeClass('active');
+            // 标签对应的内容容器切换
+            currentTabContentId = "tabs-content-"+id;
+            $(".canvas-tabs-content > div").eq($('#tabs-content-' + id).index()).addClass('active').siblings().removeClass('active');
+        } else {
+            var tab_id = "tabs-menu-" + id,
+                tab_content_id = "tabs-content-" + id;
+
+            currentTabMenuId = tab_id;
+            //添加tab页签
+            $(".canvas-tabs-menu > li").removeClass("active");
+            $(".canvas-tabs-menu").append("<li id='" + tab_id + "' class='active'><div class='hover-box'></div><i class=''></i>" + title + "<i class='layui-icon layui-icon-close icon-close-padd'></i></li>");
+
+            //添加新的内容显示
+            currentTabContentId = tab_content_id;
+            $(".canvas-tabs-content > div").removeClass("active");
+            $(".canvas-tabs-content").append("<div id='" + tab_content_id + "' class='active'>"
+                + "<iframe id='iframepage" + (pageCounter++) + "' name='iframepage" + (pageCounter++)
+                + "' width='100%' frameborder='0' scrolling='yes'  src='" + url + "' class='x-iframe'></iframe></div>");
+        }
+    }
+
+    //切换tab页的显示
+    $(document).on('click', '.canvas-tabs-menu > li', function (e) {
+        //清除原来显示的tab页,设置新的显示tab页
+        var _this = $(this)
+        currentTabMenuId = _this.attr("id");
+        _this.addClass('active').siblings(_this).removeClass('active');
+        // 标签对应的内容容器切换
+        var t_id=currentTabMenuId.substr(currentTabMenuId.length-1,1);
+        currentTabContentId = "tabs-content-"+t_id;
+        $(".canvas-tabs-content > div").eq(_this.index()).addClass('active').siblings().removeClass('active');
+    })
+
+    //删除目标tab页的显示
+    $(document).on('click', '.canvas-tabs-menu .icon-close-padd', function (e) {
+        e.stopPropagation();
+        //获取tabs列表
+        var u_l = $(".canvas-tabs-menu > li");
+        //删除目标tab页
+        var _this = $(this);
+        //获取当前tabs索引
+        var num = _this.parent().index();
+        //获取当前tabs id
+        var id = _this.parent().attr('id');
+        //删除当前tabs
+        $("#"+id).remove();
+        // 删除目标内容容器
+        var t_id=id.substr(id.length-1,1);
+        $("#tabs-content-"+t_id).remove();
+
+        var u_t=u_l.eq(num-1).attr('id');
+        var flag = $("#"+u_t).hasClass("active");
+
+        if(flag){
+
+        }else{
+            currentTabMenuId = u_t;
+            $("#"+u_t).addClass("active").siblings($("#"+u_t)).removeClass('active');
+
+            var t_c_id=u_t.substr(u_t.length-1,1);
+            currentTabContentId = "tabs-content-"+t_c_id;
+            $("#tabs-content-"+t_c_id).addClass("active").siblings($("#tabs-content-"+t_c_id)).removeClass('active');
+        }
+    })
+
+    //删除当前页
+    $(document).on('click', '.closeNowPage', function (e) {
+        e.stopPropagation();
+        if(!(currentTabMenuId === 'tabs-menu-0')){
+            //获取tabs列表
+            var u_l = $(".canvas-tabs-menu > li");
+            //获取当前tabs索引
+            var num = $("#"+currentTabMenuId).index();
+            //删除当前tabs
+            $("#"+currentTabMenuId).remove();
+            // 删除目标内容容器
+            var t_id=currentTabMenuId.substr(currentTabMenuId.length-1,1);
+            $("#tabs-content-"+t_id).remove();
+
+            var u_t=u_l.eq(num-1).attr('id');
+            var flag = $("#"+u_t).hasClass("active");
+
+            if(!flag){
+                currentTabMenuId = u_t;
+                $("#"+u_t).addClass("active").siblings($("#"+u_t)).removeClass('active');
+
+                var t_c_id=u_t.substr(u_t.length-1,1);
+                currentTabContentId = "tabs-content-"+t_c_id;
+                $("#tabs-content-"+t_c_id).addClass("active").siblings($("#tabs-content-"+t_c_id)).removeClass('active');
+            }
+        }
+    })
+
+    //删除其它页
+    $(document).on('click', '.closeOtherPage', function (e) {
+        e.stopPropagation();
+        if(currentTabMenuId === 'tabs-menu-0'){
+            //删除其它tabs
+            $("#tabs-menu-0").siblings($("#tabs-menu-0")).remove();
+            $("#tabs-content-0").siblings($("#tabs-content-0")).remove();
+            currentTabMenuId = "tabs-menu-0";
+            $("#tabs-menu-0").addClass("active")
+            currentTabContentId = "tabs-content-0";
+            $("#tabs-content-0").addClass("active")
+        }else{
+            $("#"+currentTabMenuId).nextAll().remove();
+            $("#"+currentTabMenuId).prevUntil($("#tabs-menu-0")).remove();
+
+            $("#"+currentTabContentId).nextAll().remove();
+            $("#"+currentTabContentId).prevUntil($("#tabs-content-0")).remove();
+        }
+    })
+
+    //删除所有页
+    $(document).on('click', '.closeAllPage', function (e) {
+        e.stopPropagation();
+        //删除其它tabs
+        $("#tabs-menu-0").siblings($("#tabs-menu-0")).remove();
+        $("#tabs-content-0").siblings($("#tabs-content-0")).remove();
+        currentTabMenuId = "tabs-menu-0";
+        $("#tabs-menu-0").addClass("active")
+        currentTabContentId = "tabs-content-0";
+        $("#tabs-content-0").addClass("active")
+    })
+    // 呼出右侧列表
+    $(document).on('click', '.dashboard,.user-info', function (e) {
+        var bar = $(this).attr("tag");
+        if($(".right-bar").hasClass(bar)){
+            remove_node($(".right-bar").find($(".tpl-shade")));
+            if ($("."+bar).css("right") == "-1500px"){
+                $(".right-bar").css("right","-1500px");
+                $("."+bar).css("right",0);
+                $(".tpl-body").css("overflow","hidden");
+            } else {
+                $("."+bar).css("right","-1500px");
+                $(".tpl-body").css("overflow","auto");
+            }
+            // shade($("."+bar).find(".right-bar-fluid"),true);
+            stopPropagation(e);
+        }else{
+            msg("配置的tag目标为空");
+        }
+    })
+    $(document).on('click', '.right-bar', function (e) {
+        stopPropagation(e);
+    })
+    // 页面的点击冒泡
+    $(document).on('click', '.right-bar', function (e) {
+        $(".right-bar").css("right","-1500px");
+    })
+    bind_event($(document),function(){
+        $(".right-bar").css("right","-1500px");
+    })
+    // 点击更换页面主题
+    bind_event($("#style-list"),function(e){
+        var style = $(this).attr("theme-style");
+        var styleName = $(".theme-style").attr("style-name");
+        $(".theme-style").removeClass(styleName);
+        $(".theme-style").attr("style-name",style);
+        $(".theme-style").addClass(style);
+        /*$.ajax({ //使用服务器端session保存操作
+            url:"../index/view",
+            type:"post",
+            datatype:"json",
+            data:{
+                stylename:style // 传递到后台,用session保存即可
+            },
+            success:function(data){
+                l(data);
+            }
+        });*/
+        stopPropagation(e);
+    },"click","li");
+});
+
+layui.define(['layer', 'jquery', 'form', 'carousel', 'element', 'upload'], function (exports) {
+    var $ = layui.$, $body = $('body');
+    //弹出层组件
+    var layer = layui.layer;
+    //表单组件
+    var form = layui.form;
+    var element = layui.element;
+    //轮播组件
+    var carousel = layui.carousel;
+    // 文件上传组件
+    var upload = layui.upload;
+});