| | |
| | | * API接口测试:http://localhost:8080/task/swagger-ui.html |
| | | */ |
| | | @SpringBootApplication |
| | | @ComponentScan(basePackages = {"com.itstyle.mdm","com.itstyle.quartz"}) |
| | | @ComponentScan(basePackages = {"com.itstyle.mdm","com.itstyle.quartz","com.itstyle.log"}) |
| | | public class Application { |
| | | private static final Logger logger = LoggerFactory.getLogger(Application.class); |
| | | |
| New file |
| | |
| | | package com.itstyle.log.controller; |
| | | |
| | | import com.itstyle.log.entity.InterfaceLogEntity; |
| | | import com.itstyle.log.service.InterfaceLogService; |
| | | import com.itstyle.quartz.entity.Result; |
| | | import com.itstyle.quartz.web.JobController; |
| | | import org.quartz.SchedulerException; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * 接口日志controller |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/interface") |
| | | public class InterfaceLogController { |
| | | private final static Logger LOGGER = LoggerFactory.getLogger(JobController.class); |
| | | @Autowired |
| | | private InterfaceLogService interfaceLogService; |
| | | |
| | | @PostMapping("/list") |
| | | public Result list(InterfaceLogEntity interfaceLog, Integer pageNo, Integer pageSize) throws SchedulerException { |
| | | LOGGER.info("接口日志列表"); |
| | | return interfaceLogService.list(interfaceLog, pageNo, pageSize); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.itstyle.log.entity; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import javax.persistence.Entity; |
| | | import javax.persistence.Id; |
| | | import javax.persistence.Table; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 接口日志实体类 |
| | | */ |
| | | @Data |
| | | @Entity |
| | | @Table(name="interface_log") |
| | | public class InterfaceLogEntity { |
| | | String uuid; |
| | | String interfaceName; |
| | | String url; |
| | | Date createTime; |
| | | String prams; |
| | | String result; |
| | | |
| | | public void setUuid(String uuid) { |
| | | this.uuid = uuid; |
| | | } |
| | | |
| | | @Id |
| | | public String getUuid() { |
| | | return uuid; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.itstyle.log.service; |
| | | |
| | | import com.itstyle.log.entity.InterfaceLogEntity; |
| | | import com.itstyle.quartz.entity.Result; |
| | | import com.itstyle.quartz.entity.SysConfigEntity; |
| | | import org.quartz.SchedulerException; |
| | | |
| | | public interface InterfaceLogService { |
| | | /** |
| | | * 获取接口日志列表 |
| | | * @param interfaceLog |
| | | * @param pageNo |
| | | * @param pageSize |
| | | * @return |
| | | * @throws SchedulerException |
| | | */ |
| | | Result list(InterfaceLogEntity interfaceLog, Integer pageNo, Integer pageSize) throws SchedulerException; |
| | | } |
| New file |
| | |
| | | package com.itstyle.log.service.impl; |
| | | |
| | | import com.itstyle.log.entity.InterfaceLogEntity; |
| | | import com.itstyle.log.service.InterfaceLogService; |
| | | import com.itstyle.quartz.dynamicquery.DynamicQuery; |
| | | import com.itstyle.quartz.entity.PageBean; |
| | | import com.itstyle.quartz.entity.QuartzEntity; |
| | | import com.itstyle.quartz.entity.Result; |
| | | import com.itstyle.quartz.entity.SysConfigEntity; |
| | | import org.quartz.SchedulerException; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.PageRequest; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.StringUtils; |
| | | import java.util.List; |
| | | |
| | | @Service("interfaceLogService") |
| | | public class InterfaceLogServiceImpl implements InterfaceLogService { |
| | | |
| | | @Autowired |
| | | private DynamicQuery dynamicQuery; |
| | | |
| | | @Override |
| | | public Result list(InterfaceLogEntity interfaceLog, Integer pageNo, Integer pageSize) throws SchedulerException { |
| | | String countSql = "SELECT COUNT(*) FROM interface_log AS sys "; |
| | | if(!StringUtils.isEmpty(interfaceLog.getInterfaceName())){ |
| | | countSql+=" WHERE sys.interfaceName = "+interfaceLog.getInterfaceName(); |
| | | } |
| | | Long totalCount = dynamicQuery.nativeQueryCount(countSql); |
| | | PageBean<QuartzEntity> data = new PageBean<>(); |
| | | if(totalCount>0){ |
| | | StringBuffer nativeSql = new StringBuffer(); |
| | | nativeSql.append("SELECT sys.uuid,sys.interfaceName,sys.url,sys.createTime,sys.prams,sys.result "); |
| | | nativeSql.append("FROM interface_log AS sys "); |
| | | Object[] params = new Object[]{}; |
| | | if(!StringUtils.isEmpty(interfaceLog.getInterfaceName())){ |
| | | nativeSql.append(" AND sys.interfaceName = ?"); |
| | | params = new Object[]{interfaceLog.getInterfaceName()}; |
| | | } |
| | | Pageable pageable = PageRequest.of(pageNo-1,pageSize); |
| | | List<InterfaceLogEntity> list = dynamicQuery.nativeQueryPagingList(InterfaceLogEntity.class,pageable, nativeSql.toString(), params); |
| | | data = new PageBean(list, totalCount); |
| | | } |
| | | return Result.ok(data); |
| | | } |
| | | } |
| New file |
| | |
| | | <!DOCTYPE html> |
| | | <html xmlns:th="http://www.thymeleaf.org"> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1"> |
| | | <title>任务首页</title> |
| | | <meta name="author" content="小柒2012" /> |
| | | <meta name="site" content="https://blog.52itstyle.com" /> |
| | | <link rel="stylesheet" th:href="@{/iview/iview.css}"> |
| | | <script th:src="@{/libs/jquery-3.2.1.min.js}" type="text/javascript"></script> |
| | | <script th:src="@{/libs/vue.min.js}" type="text/javascript"></script> |
| | | <script th:src="@{/layer/layer.js}" type="text/javascript"></script> |
| | | <script th:src="@{/iview/iview.min.js}" type="text/javascript"></script> |
| | | <script th:src="@{/common.js}" type="text/javascript"></script> |
| | | <style type="text/css"> |
| | | [v-cloak] { |
| | | display: none; |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <div id="app" v-cloak> |
| | | <div style="margin-bottom: 6px;margin: 30px"> |
| | | <i-input v-model="content" placeholder="数据分发日志" style="width: 300px"></i-input> |
| | | <i-button type="primary" @click="search()" icon="ios-search">搜索</i-button> |
| | | <i-button type="primary" @click="empty()" icon="ios-close-empty">清空</i-button> |
| | | </div> |
| | | <div style="margin-bottom: 6px;margin: 30px"> |
| | | <template> |
| | | <i-table border :content="self" :columns="tableTitle" :data="JobData"></i-table> |
| | | <br> |
| | | <Page style="float: right;" :current="pageNo" :total="tableSize" :page-size="pageSize" @on-change="changePage" @on-page-size-change="changePageSize" show-elevator show-sizer show-total></Page> |
| | | </template> |
| | | </div> |
| | | </div> |
| | | <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> |
| | | <script type="text/javascript"> |
| | | var vm = new Vue({ |
| | | el : '#app', |
| | | data : { |
| | | content : '', |
| | | pageNo : 1, |
| | | pageSize : 10, |
| | | jobName : "", |
| | | JobData : [], |
| | | tableSize : 50, |
| | | tableTitle:[ { |
| | | key : "interfaceName", |
| | | title : "分发接口名称" |
| | | }, { |
| | | key : "url", |
| | | title : "分发地址" |
| | | }, { |
| | | key : "createTime", |
| | | title : "发送时间" |
| | | }, { |
| | | key : "prams", |
| | | title : "请求参数" |
| | | }, { |
| | | key : "result", |
| | | title : "响应结果" |
| | | },{ |
| | | title : '操作', |
| | | key : 'action', |
| | | width : 300, |
| | | align : 'left', |
| | | render : function(h, params) { |
| | | var functionList = []; |
| | | //查看 |
| | | var show = h('Button', { |
| | | props : { |
| | | type : 'primary', |
| | | size : 'small', |
| | | icon : 'edit' |
| | | }, |
| | | style : { |
| | | marginRight : '8px' |
| | | }, |
| | | on : { |
| | | click : function() { |
| | | vm.show(params.row); |
| | | } |
| | | } |
| | | }, '查看'); |
| | | functionList.push(show); |
| | | // 返回方法集合 |
| | | return h('div', functionList); |
| | | } |
| | | }] |
| | | |
| | | }, |
| | | methods : { |
| | | //搜索 |
| | | search : function(){ |
| | | $.ajax({ |
| | | url:"../interface/list", |
| | | type:"post", |
| | | data:{'sysName':this.content,"pageNo":this.pageNo,'pageSize':this.pageSize}, |
| | | success: function(result) { |
| | | |
| | | } |
| | | }); |
| | | }, |
| | | empty : function(){ |
| | | vm.content = ''; |
| | | this.list(); |
| | | }, |
| | | //任务列表(自行实现分页) |
| | | list : function() { |
| | | $.ajax({ |
| | | url:"../interface/list", |
| | | type:"post", |
| | | data:{'time':(new Date()).toString(),"pageNo":this.pageNo,'pageSize':this.pageSize}, |
| | | success: function(result) { |
| | | vm.JobData = result.msg.pageData; |
| | | vm.tableSize = result.msg.totalCount; |
| | | } |
| | | }); |
| | | }, |
| | | show : function(log){ |
| | | dialogOpen({ |
| | | title: '查看', |
| | | url: 'log/showLog.shtml', |
| | | scroll : true, |
| | | width: '1200px', |
| | | height: '800px', |
| | | success : function(iframeId){ |
| | | top.frames[iframeId].vm.formQuartz=log; |
| | | const params = Process(log.prams); |
| | | const result = Process(log.result); |
| | | top.frames[iframeId].document.getElementById("fromParam").innerHTML = params; |
| | | top.frames[iframeId].document.getElementById("fromResule").innerHTML = result; |
| | | }, |
| | | }); |
| | | }, |
| | | reload : function(){ |
| | | this.load(); |
| | | }, |
| | | changePage : function(pageNo) { |
| | | vm.pageNo = pageNo; |
| | | vm.load(); |
| | | }, |
| | | changePageSize : function(pageSize) { |
| | | vm.pageSize = pageSize; |
| | | vm.load(); |
| | | } |
| | | }, |
| | | created : function() { |
| | | this.list(); |
| | | } |
| | | }) |
| | | |
| | | //格式化代码函数,已经用原生方式写好了不需要改动,直接引用就好 |
| | | function formatJson(json, options) { |
| | | var reg = null, |
| | | formatted = '', |
| | | pad = 0, |
| | | PADDING = ' '; |
| | | options = options || {}; |
| | | options.newlineAfterColonIfBeforeBraceOrBracket = (options.newlineAfterColonIfBeforeBraceOrBracket === true) ? true : false; |
| | | options.spaceAfterColon = (options.spaceAfterColon === false) ? false : true; |
| | | if (typeof json !== 'string') { |
| | | json = JSON.stringify(json); |
| | | } else { |
| | | json = JSON.parse(json); |
| | | json = JSON.stringify(json); |
| | | } |
| | | reg = /([\{\}])/g; |
| | | json = json.replace(reg, '\r\n$1\r\n'); |
| | | reg = /([\[\]])/g; |
| | | json = json.replace(reg, '\r\n$1\r\n'); |
| | | reg = /(\,)/g; |
| | | json = json.replace(reg, '$1\r\n'); |
| | | reg = /(\r\n\r\n)/g; |
| | | json = json.replace(reg, '\r\n'); |
| | | reg = /\r\n\,/g; |
| | | json = json.replace(reg, ','); |
| | | if (!options.newlineAfterColonIfBeforeBraceOrBracket) { |
| | | reg = /\:\r\n\{/g; |
| | | json = json.replace(reg, ':{'); |
| | | reg = /\:\r\n\[/g; |
| | | json = json.replace(reg, ':['); |
| | | } |
| | | if (options.spaceAfterColon) { |
| | | reg = /\:/g; |
| | | json = json.replace(reg, ':'); |
| | | } |
| | | (json.split('\r\n')).forEach(function (node, index) { |
| | | //console.log(node); |
| | | var i = 0, |
| | | indent = 0, |
| | | padding = ''; |
| | | |
| | | if (node.match(/\{$/) || node.match(/\[$/)) { |
| | | indent = 1; |
| | | } else if (node.match(/\}/) || node.match(/\]/)) { |
| | | if (pad !== 0) { |
| | | pad -= 1; |
| | | } |
| | | } else { |
| | | indent = 0; |
| | | } |
| | | |
| | | for (i = 0; i < pad; i++) { |
| | | padding += PADDING; |
| | | } |
| | | |
| | | formatted += padding + node + '\r\n'; |
| | | pad += indent; |
| | | }); |
| | | return formatted; |
| | | }; |
| | | //引用示例部分 |
| | | //(1)创建json格式或者从后台拿到对应的json格式 |
| | | //var originalJson = {"name": "binginsist", "sex": "男", "age": "25"}; |
| | | //下面用一个真实的json数据做测试 |
| | | //var originalJson = { |
| | | // "_errmsg":"ok", |
| | | // "result":[ |
| | | // ], |
| | | // "stat":"wechat", |
| | | // "_token":"", |
| | | // "weixinId":"900504", |
| | | // "_errcode":"0", |
| | | // "regionId":"00000000" |
| | | //} |
| | | // |
| | | //(2)调用formatJson函数,将json格式进行格式化 |
| | | //var resultJson = formatJson(originalJson); |
| | | //将格式化好后的json写入页面中 |
| | | //document.getElementById("writePlace").innerHTML = '<pre>' +resultJson + '<pre/>'; |
| | | |
| | | //着色 |
| | | function IsArray(obj) { |
| | | return obj && |
| | | typeof obj === 'object' && typeof obj.length === 'number' && !(obj.propertyIsEnumerable('length')); |
| | | } |
| | | function Process(params) { |
| | | var json = params; |
| | | var html = ""; |
| | | try { |
| | | if (json == "") { |
| | | json = '""'; |
| | | } |
| | | var obj = eval("[" + json + "]"); |
| | | html = ProcessObject(obj[0], 0, false, false, false); |
| | | return html; |
| | | } catch(e) { |
| | | } |
| | | } |
| | | function ProcessObject(obj, indent, addComma, isArray, isPropertyContent) { |
| | | var html = ""; |
| | | var comma = (addComma) ? "<span class='Comma'>,</span> ": ""; |
| | | var type = typeof obj; |
| | | if (IsArray(obj)) { |
| | | if (obj.length == 0) { |
| | | html += GetRow(indent, "<span class='ArrayBrace'>[ ]</span>" + comma, isPropertyContent); |
| | | } else { |
| | | html += GetRow(indent, "<span class='ArrayBrace'>[</span>", isPropertyContent); |
| | | for (var i = 0; i < obj.length; i++) { |
| | | html += ProcessObject(obj[i], indent + 1, i < (obj.length - 1), true, false); |
| | | } |
| | | html += GetRow(indent, "<span class='ArrayBrace'>]</span>" + comma); |
| | | } |
| | | } else { |
| | | if (type == "object" && obj == null) { |
| | | html += FormatLiteral("null", "", comma, indent, isArray, "Null"); |
| | | } else { |
| | | if (type == "object") { |
| | | var numProps = 0; |
| | | for (var prop in obj) { |
| | | numProps++; |
| | | } |
| | | if (numProps == 0) { |
| | | html += GetRow(indent, "<span class='ObjectBrace'>{ }</span>" + comma, isPropertyContent) |
| | | } else { |
| | | html += GetRow(indent, "<span class='ObjectBrace'>{</span>", isPropertyContent); |
| | | var j = 0; |
| | | for (var prop in obj) { |
| | | html += GetRow(indent + 1, '<span class="PropertyName">"' + prop + '"</span>: ' + ProcessObject(obj[prop], indent + 1, ++j < numProps, false, true)) |
| | | } |
| | | html += GetRow(indent, "<span class='ObjectBrace'>}</span>" + comma); |
| | | } |
| | | } else { |
| | | if (type == "number") { |
| | | html += FormatLiteral(obj, "", comma, indent, isArray, "Number"); |
| | | } else { |
| | | if (type == "boolean") { |
| | | html += FormatLiteral(obj, "", comma, indent, isArray, "Boolean"); |
| | | } else { |
| | | if (type == "function") { |
| | | obj = FormatFunction(indent, obj); |
| | | html += FormatLiteral(obj, "", comma, indent, isArray, "Function"); |
| | | } else { |
| | | if (type == "undefined") { |
| | | html += FormatLiteral("undefined", "", comma, indent, isArray, "Null"); |
| | | } else { |
| | | html += FormatLiteral(obj, '"', comma, indent, isArray, "String"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return html; |
| | | }; |
| | | |
| | | function FormatLiteral(literal, quote, comma, indent, isArray, style) { |
| | | if (typeof literal == "string") { |
| | | literal = literal.split("<").join("<").split(">").join(">"); |
| | | } |
| | | var str = "<span class='" + style + "'>" + quote + literal + quote + comma + "</span>"; |
| | | if (isArray) { |
| | | str = GetRow(indent, str); |
| | | } |
| | | return str; |
| | | } |
| | | function FormatFunction(indent, obj) { |
| | | var tabs = ""; |
| | | for (var i = 0; i < indent; i++) { |
| | | tabs += " "; |
| | | } |
| | | var funcStrArray = obj.toString().split("\n"); |
| | | var str = ""; |
| | | for (var i = 0; i < funcStrArray.length; i++) { |
| | | str += ((i == 0) ? "": tabs) + funcStrArray[i] + "\n"; |
| | | } |
| | | return str; |
| | | } |
| | | function GetRow(indent, data, isPropertyContent) { |
| | | var tabs = ""; |
| | | for (var i = 0; i < indent && !isPropertyContent; i++) { |
| | | tabs += " "; |
| | | } |
| | | if (data != null && data.length > 0 && data.charAt(data.length - 1) != "\n") { |
| | | data = data + "\n"; |
| | | } |
| | | return tabs + data; |
| | | }; |
| | | </script> |
| | | </body> |
| | | </html> |
| New file |
| | |
| | | <!DOCTYPE html> |
| | | <html xmlns:th="http://www.thymeleaf.org"> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1"> |
| | | |
| | | <title>任务首页</title> |
| | | <meta name="author" content="小柒2012" /> |
| | | <meta name="site" content="https://blog.52itstyle.com" /> |
| | | <link rel="stylesheet" th:href="@{/iview/iview.css}"> |
| | | <script th:src="@{/libs/jquery-3.2.1.min.js}" type="text/javascript"></script> |
| | | <script th:src="@{/libs/vue.min.js}" type="text/javascript"></script> |
| | | <script th:src="@{/layer/layer.js}" type="text/javascript"></script> |
| | | <script th:src="@{/iview/iview.min.js}" type="text/javascript"></script> |
| | | <style type="text/css"> |
| | | [v-cloak] { |
| | | display: none; |
| | | } |
| | | body {font-size:14px;font-family:consolas;} |
| | | pre {font-family:'consolas';} |
| | | .Canvas { |
| | | font:14px/18px 'consolas'; |
| | | background-color: #ECECEC; |
| | | color: #000000; |
| | | border: solid 1px #CECECE; |
| | | } |
| | | .ObjectBrace { |
| | | color: #00AA00; |
| | | font-weight: bold; |
| | | } |
| | | .ArrayBrace { |
| | | color: #0033FF; |
| | | font-weight: bold; |
| | | } |
| | | .PropertyName { |
| | | color: #CC0000; |
| | | font-weight: bold; |
| | | } |
| | | .String { |
| | | color: #007777; |
| | | } |
| | | .Number { |
| | | color: #AA00AA; |
| | | } |
| | | .Boolean { |
| | | color: #0000FF; |
| | | } |
| | | .Function { |
| | | color: #AA6633; |
| | | text-decoration: "italic"; |
| | | } |
| | | .Null { |
| | | color: #0000FF; |
| | | } |
| | | .Comma { |
| | | color: #000000; |
| | | font-weight: bold; |
| | | } |
| | | PRE.CodeContainer { |
| | | margin-top: 0px; |
| | | margin-bottom: 0px; |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <div id="app" v-cloak style="margin: 30px"> |
| | | <template> |
| | | <i-form v-ref:form-quartz :model="formQuartz" :rules="ruleValidate" :label-width="120"> |
| | | <Form-item label="分发接口名称" prop="interfaceName"> |
| | | <i-input v-model="formQuartz.interfaceName" :value.sync="formQuartz.interfaceName" disabled="disabled"></i-input> |
| | | </Form-item> |
| | | <Form-item label="分发地址" prop="url" > |
| | | <i-input v-model="formQuartz.url" :value.sync="formQuartz.url" disabled="disabled"></i-input> |
| | | </Form-item> |
| | | <Form-item label="发送时间" prop="createTime"> |
| | | <i-input v-model="formQuartz.createTime" :value.sync="formQuartz.createTime" disabled="disabled"></i-input> |
| | | </Form-item> |
| | | <Form-item label="请求参数" prop="prams"> |
| | | <pre id = "fromParam" class="CodeContainer" style=" width: 100%;min-height: 600px;height: 100%;"></pre> |
| | | <!--<div ref="fromParam" id="fromParam" v-model="formQuartz.prams"></div>--> |
| | | </Form-item> |
| | | <Form-item label="响应结果" prop="result"> |
| | | <pre id = "fromResule" class="CodeContainer" style=" width: 100%;min-height: 600px;height: 100%;"></pre> |
| | | <!--<div ref="fromParam" id="fromResule" v-model="formQuartz.result"></div>--> |
| | | </Form-item> |
| | | </i-form> |
| | | </template> |
| | | </div> |
| | | <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> |
| | | <script type="text/javascript"> |
| | | var vm = new Vue({ |
| | | el : '#app', |
| | | data : { |
| | | formQuartz: { |
| | | interfaceName : '', |
| | | url : '', |
| | | createTime : '' |
| | | }, |
| | | ruleValidate: { |
| | | |
| | | } |
| | | }, |
| | | methods : { |
| | | }, |
| | | created : function() { |
| | | } |
| | | }) |
| | | </script> |
| | | </body> |
| | | </html> |
| | |
| | | <li data-src="task/index.shtml"><a href="#task/index.shtml"><i class="fa fa-circle-o"></i>任务列表</a></li> |
| | | <li data-src="sysConfig/distribute.shtml"><a href="#sysConfig/distribute.shtml"><i class="fa fa-circle-o"></i>异构系统分发配置</a></li> |
| | | </ul> |
| | | </li> |
| | | <li class="active treeview menu-open"> |
| | | <a href="#"> |
| | | <i class="fa fa-dashboard"></i> <span>日志管理</span> |
| | | <span class="pull-right-container"> |
| | | <i class="fa fa-angle-left pull-right"></i> |
| | | </span> |
| | | </a> |
| | | <ul class="treeview-menu"> |
| | | <li data-src="log/listlog.shtml"><a href="#log/listlog.shtml"><i class="fa fa-circle-o"></i>数据分发日志</a></li> |
| | | <!--<li data-src="sysConfig/distribute.shtml"><a href="#sysConfig/distribute.shtml"><i class="fa fa-circle-o"></i>异构系统分发配置</a></li>--> |
| | | </ul> |
| | | </li> |
| | | <li class="active treeview menu-open"> |
| | | <a href="#"> |
| | | <i class="fa fa-dashboard"></i> <span>表达式生成器</span> |
| | | <span class="pull-right-container"> |
| | | <i class="fa fa-angle-left pull-right"></i> |
| | | </span> |
| | | </a> |
| | | <ul class="treeview-menu"> |
| | | <li data-src="task/cron.shtml"><a href="#task/cron.shtml"><i class="fa fa-circle-o"></i>表达式生成器</a></li> |
| | | </ul> |
| | |
| | | <div class="content-wrapper"> |
| | | <section class="content-header"> |
| | | <h1> |
| | | Dashboard |
| | | 仪表板 |
| | | </h1> |
| | | <ol class="breadcrumb"> |
| | | <li><a href="main.shtml"><i class="fa fa-dashboard"></i> Home</a></li> |
| | | <li class="active">Dashboard</li> |
| | | <li class="active">仪表板</li> |
| | | </ol> |
| | | </section> |
| | | <!-- 主页 --> |