mirror of
https://github.com/dqjdda/Aurora.git
synced 2018-11-06 05:33:29 +00:00
新增Redis终端管理,修复菜单管理删除失败的BUG
This commit is contained in:
@@ -26,15 +26,15 @@ Aurora是一个简单高效的后台管理系统。项目基础框架采用全
|
||||
│ ├─角色管理
|
||||
│ └─权限管理
|
||||
├─系统监控
|
||||
│ ├─在线用户(开发中)
|
||||
│ ├─Redis终端
|
||||
│ ├─在线用户
|
||||
│ └─系统日志
|
||||
│─网络资源(开发中)
|
||||
│ ├─ 开发中
|
||||
│ │ ├─散文
|
||||
│ │ ├─绘画
|
||||
│ │ └─语文
|
||||
│ ├─天气查询
|
||||
│ └─每日一文
|
||||
│─网络资源
|
||||
│ ├─天气查询(开发中)
|
||||
│ └─图床管理
|
||||
│─第三方工具(开发中)
|
||||
│ │-支付宝支付
|
||||
│ └─云储存
|
||||
└─任务调度(开发中)
|
||||
├─定时任务
|
||||
└─调度日志
|
||||
@@ -122,6 +122,10 @@ Aurora是一个简单高效的后台管理系统。项目基础框架采用全
|
||||
|
||||

|
||||
|
||||
- Redis终端
|
||||
|
||||

|
||||
|
||||
- sql日志打印使用log4jdbc+logback,效果如下
|
||||
|
||||

|
||||
|
||||
@@ -126,7 +126,8 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<scope>provided</scope>
|
||||
<!--<scope>provided</scope>-->
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- shiro-spring -->
|
||||
|
||||
+9
-7
@@ -11,7 +11,7 @@
|
||||
Target Server Version : 50559
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 21/09/2018 16:47:46
|
||||
Date: 22/09/2018 13:06:32
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@@ -34,7 +34,7 @@ CREATE TABLE `zj_menu` (
|
||||
`level_number` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `UK_cbhg0bi3f1emxkhqqtvca9btx`(`soft`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_menu
|
||||
@@ -43,16 +43,17 @@ INSERT INTO `zj_menu` VALUES (1, 'layui-icon-unlink', 0, 1, '异常页', 40, '',
|
||||
INSERT INTO `zj_menu` VALUES (2, 'layui-icon-tree', 1, 2, '403', 41, '/exception/403', '2018-08-29 11:40:17', '2018-09-20 11:36:24', 0);
|
||||
INSERT INTO `zj_menu` VALUES (3, 'layui-icon-tree', 1, 2, '404', 42, '/exception/404', '2018-08-29 11:40:17', '2018-09-20 11:36:32', 0);
|
||||
INSERT INTO `zj_menu` VALUES (4, 'layui-icon-tree', 1, 2, '500', 43, '/exception/500', '2018-08-29 11:40:17', '2018-09-20 11:36:40', 0);
|
||||
INSERT INTO `zj_menu` VALUES (5, 'layui-icon-chart', 0, 1, '系统监控', 10, '', '2018-08-29 11:40:17', '2018-09-21 16:09:38', 2);
|
||||
INSERT INTO `zj_menu` VALUES (5, 'layui-icon-chart', 0, 1, '系统监控', 10, '', '2018-08-29 11:40:17', '2018-09-22 11:18:21', 4);
|
||||
INSERT INTO `zj_menu` VALUES (6, 'layui-icon-tree', 7, 2, '用户管理', 2, '/user/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (7, 'layui-icon-util', 0, 1, '系统管理', 1, '', '2018-08-29 11:40:17', '2018-09-20 19:02:05', 4);
|
||||
INSERT INTO `zj_menu` VALUES (8, 'layui-icon-tree', 7, 2, '菜单管理', 6, '/menu/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (9, 'layui-icon-tree', 5, 2, '日志管理', 11, '/sysLog/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (9, 'layui-icon-tree', 5, 2, '系统日志', 11, '/sysLog/index', '2018-08-29 11:40:17', '2018-09-22 10:17:02', 0);
|
||||
INSERT INTO `zj_menu` VALUES (10, 'layui-icon-tree', 7, 2, '权限管理', 4, '/permission/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (11, 'layui-icon-tree', 7, 2, '角色管理', 3, '/role/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (12, 'layui-icon-website', 0, 1, '网络资源', 30, '', '2018-09-20 11:35:56', '2018-09-20 11:40:53', 1);
|
||||
INSERT INTO `zj_menu` VALUES (13, 'layui-icon-tree', 12, 2, '图床管理', 31, '/picture/index', '2018-09-20 11:40:53', '2018-09-20 11:40:53', 0);
|
||||
INSERT INTO `zj_menu` VALUES (14, 'layui-icon-tree', 5, 2, '在线用户管理', 12, '/online/index', '2018-09-21 16:09:38', '2018-09-21 16:09:38', 0);
|
||||
INSERT INTO `zj_menu` VALUES (14, 'layui-icon-tree', 5, 2, '在线用户', 12, '/online/index', '2018-09-21 16:09:38', '2018-09-22 10:17:09', 0);
|
||||
INSERT INTO `zj_menu` VALUES (16, 'layui-icon-tree', 5, 2, 'Redis终端', 14, '/redis/terminal', '2018-09-22 11:18:21', '2018-09-22 11:37:28', 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_menus_roles
|
||||
@@ -84,6 +85,7 @@ INSERT INTO `zj_menus_roles` VALUES (11, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (12, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (13, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (14, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (16, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (1, 2);
|
||||
INSERT INTO `zj_menus_roles` VALUES (2, 2);
|
||||
INSERT INTO `zj_menus_roles` VALUES (3, 2);
|
||||
@@ -233,12 +235,12 @@ CREATE TABLE `zj_user` (
|
||||
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `UK_kpubos9gc2cvtkb0thktkbkes`(`email`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `zj_user` VALUES (1, 'https://www.zhengjie.me/images/avatar.jpg', '2018-08-23 09:11:56', 'zhengjie@tom.com', 1, '2018-09-21 16:26:05', '65a674ce6632479005ea7a9071234cfb', 'aurora');
|
||||
INSERT INTO `zj_user` VALUES (1, 'https://www.zhengjie.me/images/avatar.jpg', '2018-08-23 09:11:56', 'zhengjie@tom.com', 1, '2018-09-22 13:00:04', '65a674ce6632479005ea7a9071234cfb', 'aurora');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_user_pictures
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
package me.aurora.app.rest.system;
|
||||
|
||||
import me.aurora.annotation.Log;
|
||||
import me.aurora.domain.ResponseEntity;
|
||||
import me.aurora.service.RedisService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/09/22 10:48:11
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("redis")
|
||||
public class RedisController {
|
||||
|
||||
private static final String INTEGER_PREFIX = "(integer)";
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@GetMapping("terminal")
|
||||
@RequiresPermissions (value={"admin", "redis:all","redis:terminal"}, logical= Logical.OR)
|
||||
public ModelAndView redisTerminal(Model model) {
|
||||
String osName = System.getProperty("os.name");
|
||||
model.addAttribute("osName", osName);
|
||||
return new ModelAndView("/system/redis/terminal");
|
||||
}
|
||||
|
||||
@Log("执行Redis keys命令")
|
||||
@RequestMapping("keys")
|
||||
public ResponseEntity keys(String arg) {
|
||||
try {
|
||||
Set<String> set = this.redisService.getKeys(arg);
|
||||
return ResponseEntity.ok(set);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Log("执行Redis get命令")
|
||||
@GetMapping("get")
|
||||
public ResponseEntity get(String arg) {
|
||||
try {
|
||||
String result = this.redisService.get(arg);
|
||||
return ResponseEntity.ok(result == null ? "" : result);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Log("执行Redis set命令")
|
||||
@GetMapping("set")
|
||||
public ResponseEntity set(String arg) {
|
||||
try {
|
||||
String[] args = arg.split(",");
|
||||
if (args.length == 1){
|
||||
return ResponseEntity.error("(error) ERR wrong number of arguments for 'set' command");
|
||||
} else if(args.length != 2){
|
||||
return ResponseEntity.error("(error) ERR syntax error");
|
||||
}
|
||||
String result = this.redisService.set(args[0], args[1]);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Log("执行Redis del命令")
|
||||
@GetMapping("del")
|
||||
public ResponseEntity del(String arg) {
|
||||
try {
|
||||
String[] args = arg.split(",");
|
||||
Long result = this.redisService.del(args);
|
||||
return ResponseEntity.ok(INTEGER_PREFIX + result);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Log("执行Redis exists命令")
|
||||
@GetMapping("exists")
|
||||
public ResponseEntity exists(String arg) {
|
||||
try {
|
||||
int count = 0;
|
||||
String[] arr = arg.split(",");
|
||||
for (String key : arr) {
|
||||
if (this.redisService.exists(key)){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return ResponseEntity.ok(INTEGER_PREFIX + count);
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Log("执行Redis pttl命令")
|
||||
@GetMapping("pttl")
|
||||
public ResponseEntity pttl(String arg) {
|
||||
try {
|
||||
return ResponseEntity.ok(INTEGER_PREFIX + this.redisService.pttl(arg));
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Log("执行Redis pexpire命令")
|
||||
@GetMapping("pexpire")
|
||||
public ResponseEntity pexpire(String arg) {
|
||||
try {
|
||||
String[] arr = arg.split(",");
|
||||
if (arr.length != 2 || !isValidLong(arr[1])) {
|
||||
return ResponseEntity.error("(error) ERR wrong number of arguments for 'pexpire' command");
|
||||
}
|
||||
return ResponseEntity.ok(INTEGER_PREFIX + this.redisService.pexpire(arr[0], Long.valueOf(arr[1])));
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Log("执行flushdb命令")
|
||||
@GetMapping("flushdb")
|
||||
public ResponseEntity flushdb() {
|
||||
try {
|
||||
return ResponseEntity.ok(INTEGER_PREFIX + this.redisService.flushdb());
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Log("执行flushall命令")
|
||||
@GetMapping("flushall")
|
||||
public ResponseEntity flushall() {
|
||||
try {
|
||||
return ResponseEntity.ok(INTEGER_PREFIX + this.redisService.flushall());
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidLong(String str) {
|
||||
try {
|
||||
Long.parseLong(str);
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package me.aurora.config.redis;
|
||||
import afu.org.checkerframework.checker.oigj.qual.O;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cache.CacheManager;
|
||||
@@ -21,6 +22,9 @@ import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSeriali
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.SerializationException;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -67,6 +71,18 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration.build());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JedisPool redisPoolFactory() {
|
||||
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
|
||||
jedisPoolConfig.setMaxIdle(maxIdle);
|
||||
jedisPoolConfig.setMaxWaitMillis(Long.parseLong(maxWaitMillis.replace("ms","")));
|
||||
if (StringUtils.isNotBlank(password)) {
|
||||
return new JedisPool(jedisPoolConfig, host, port, Integer.parseInt(timeout.replace("ms","")), password);
|
||||
} else {
|
||||
return new JedisPool(jedisPoolConfig, host, port, Integer.parseInt(timeout.replace("ms","")));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化
|
||||
* @param redisConnectionFactory
|
||||
|
||||
@@ -29,6 +29,13 @@ public class ResponseEntity extends HashMap<String, Object>{
|
||||
return responseEntity;
|
||||
}
|
||||
|
||||
public static ResponseEntity ok(Object msg) {
|
||||
ResponseEntity responseBo = new ResponseEntity();
|
||||
responseBo.put("code", 0);
|
||||
responseBo.put("msg", msg);
|
||||
return responseBo;
|
||||
}
|
||||
|
||||
public static ResponseEntity ok(String msg) {
|
||||
ResponseEntity responseEntity = new ResponseEntity();
|
||||
responseEntity.put("msg", msg);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package me.aurora.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import lombok.Data;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
@@ -12,8 +10,7 @@ import java.util.Date;
|
||||
* @author 郑杰
|
||||
* @date 2018/09/21 15:38:06
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Data
|
||||
public class UserOnline implements Serializable{
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package me.aurora.service;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
* @date 2018/09/22 10:42:52
|
||||
*/
|
||||
public interface RedisService {
|
||||
|
||||
/**
|
||||
* 获取 key
|
||||
* @param pattern 正则
|
||||
* @return Set
|
||||
*/
|
||||
Set<String> getKeys(String pattern);
|
||||
|
||||
/**
|
||||
* get命令
|
||||
*
|
||||
* @param key key
|
||||
* @return String
|
||||
*/
|
||||
String get(String key);
|
||||
|
||||
/**
|
||||
* set命令
|
||||
*
|
||||
* @param key key
|
||||
* @param value value
|
||||
* @return String
|
||||
*/
|
||||
String set(String key, String value);
|
||||
|
||||
/**
|
||||
* del命令
|
||||
*
|
||||
* @param key key
|
||||
* @return Long
|
||||
*/
|
||||
Long del(String... key);
|
||||
|
||||
/**
|
||||
* exists命令
|
||||
*
|
||||
* @param key key
|
||||
* @return Boolean
|
||||
*/
|
||||
Boolean exists(String key);
|
||||
|
||||
/**
|
||||
* pttl命令
|
||||
*
|
||||
* @param key key
|
||||
* @return Long
|
||||
*/
|
||||
Long pttl(String key);
|
||||
|
||||
/**
|
||||
* pexpire命令
|
||||
*
|
||||
* @param key key
|
||||
* @param milliscends 毫秒
|
||||
* @return Long
|
||||
*/
|
||||
Long pexpire(String key, Long milliscends);
|
||||
|
||||
/**
|
||||
* flushdb 命令
|
||||
* @return
|
||||
*/
|
||||
String flushdb();
|
||||
|
||||
/**
|
||||
* flushall 命令
|
||||
* @return
|
||||
*/
|
||||
String flushall();
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 郑杰
|
||||
@@ -100,12 +101,14 @@ public class MenuServiceImpl implements MenuService {
|
||||
|
||||
@Override
|
||||
public void delete(Menu menu) {
|
||||
List<Menu> menus = menuRepo.findByPid(menu.getPid());
|
||||
if(menus !=null && menus.size()!=0){
|
||||
menuRepo.deleteAll(menus);
|
||||
if(menu.getLevelNum() == 0){
|
||||
menuRepo.delete(menu);
|
||||
} else {
|
||||
Set<Menu> menus = menuRepo.findByPid(menu.getPid()).stream().collect(Collectors.toSet());
|
||||
if(menus !=null && menus.size()!=0){
|
||||
menuRepo.deleteAll(menus);
|
||||
}
|
||||
}
|
||||
menuRepo.delete(menu);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package me.aurora.service.impl;
|
||||
|
||||
import me.aurora.service.RedisService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Redis 工具类,只封装了几个常用的 redis 命令,
|
||||
* 可根据实际需要按类似的方式扩展即可。
|
||||
* @author 郑杰
|
||||
* @date 2018/09/22 10:42:52
|
||||
*/
|
||||
@Service("redisService")
|
||||
@SuppressWarnings("unchecked")
|
||||
public class RedisServiceImpl implements RedisService {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
JedisPool jedisPool;
|
||||
|
||||
|
||||
/**
|
||||
* 处理jedis请求
|
||||
* @param f 处理逻辑,通过lambda行为参数化
|
||||
* @return 处理结果
|
||||
*/
|
||||
private Object excuteByJedis(Function<Jedis, Object> f) {
|
||||
try (Jedis jedis = jedisPool.getResource()) {
|
||||
return f.apply(jedis);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys(String pattern) {
|
||||
return (Set<String>) this.excuteByJedis(j -> j.keys(pattern));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(String key) {
|
||||
return (String) this.excuteByJedis(j -> j.get(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String set(String key, String value) {
|
||||
return (String) this.excuteByJedis(j -> j.set(key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long del(String... key) {
|
||||
return (Long) this.excuteByJedis(j -> j.del(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean exists(String key) {
|
||||
return (Boolean) this.excuteByJedis(j -> j.exists(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long pttl(String key) {
|
||||
return (Long) this.excuteByJedis(j -> j.pttl(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long pexpire(String key, Long milliseconds) { return (Long) this.excuteByJedis(j -> j.pexpire(key, milliseconds)); }
|
||||
|
||||
@Override
|
||||
public String flushdb() { return (String) this.excuteByJedis(j -> j.flushDB()); }
|
||||
|
||||
@Override
|
||||
public String flushall() { return (String) this.excuteByJedis(j -> j.flushAll()); }
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
Target Server Version : 50559
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 21/09/2018 16:47:46
|
||||
Date: 22/09/2018 13:06:32
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@@ -34,7 +34,7 @@ CREATE TABLE `zj_menu` (
|
||||
`level_number` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `UK_cbhg0bi3f1emxkhqqtvca9btx`(`soft`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_menu
|
||||
@@ -43,16 +43,17 @@ INSERT INTO `zj_menu` VALUES (1, 'layui-icon-unlink', 0, 1, '异常页', 40, '',
|
||||
INSERT INTO `zj_menu` VALUES (2, 'layui-icon-tree', 1, 2, '403', 41, '/exception/403', '2018-08-29 11:40:17', '2018-09-20 11:36:24', 0);
|
||||
INSERT INTO `zj_menu` VALUES (3, 'layui-icon-tree', 1, 2, '404', 42, '/exception/404', '2018-08-29 11:40:17', '2018-09-20 11:36:32', 0);
|
||||
INSERT INTO `zj_menu` VALUES (4, 'layui-icon-tree', 1, 2, '500', 43, '/exception/500', '2018-08-29 11:40:17', '2018-09-20 11:36:40', 0);
|
||||
INSERT INTO `zj_menu` VALUES (5, 'layui-icon-chart', 0, 1, '系统监控', 10, '', '2018-08-29 11:40:17', '2018-09-21 16:09:38', 2);
|
||||
INSERT INTO `zj_menu` VALUES (5, 'layui-icon-chart', 0, 1, '系统监控', 10, '', '2018-08-29 11:40:17', '2018-09-22 11:18:21', 4);
|
||||
INSERT INTO `zj_menu` VALUES (6, 'layui-icon-tree', 7, 2, '用户管理', 2, '/user/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (7, 'layui-icon-util', 0, 1, '系统管理', 1, '', '2018-08-29 11:40:17', '2018-09-20 19:02:05', 4);
|
||||
INSERT INTO `zj_menu` VALUES (8, 'layui-icon-tree', 7, 2, '菜单管理', 6, '/menu/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (9, 'layui-icon-tree', 5, 2, '日志管理', 11, '/sysLog/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (9, 'layui-icon-tree', 5, 2, '系统日志', 11, '/sysLog/index', '2018-08-29 11:40:17', '2018-09-22 10:17:02', 0);
|
||||
INSERT INTO `zj_menu` VALUES (10, 'layui-icon-tree', 7, 2, '权限管理', 4, '/permission/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (11, 'layui-icon-tree', 7, 2, '角色管理', 3, '/role/index', '2018-08-29 11:40:17', '2018-09-04 07:40:25', 0);
|
||||
INSERT INTO `zj_menu` VALUES (12, 'layui-icon-website', 0, 1, '网络资源', 30, '', '2018-09-20 11:35:56', '2018-09-20 11:40:53', 1);
|
||||
INSERT INTO `zj_menu` VALUES (13, 'layui-icon-tree', 12, 2, '图床管理', 31, '/picture/index', '2018-09-20 11:40:53', '2018-09-20 11:40:53', 0);
|
||||
INSERT INTO `zj_menu` VALUES (14, 'layui-icon-tree', 5, 2, '在线用户管理', 12, '/online/index', '2018-09-21 16:09:38', '2018-09-21 16:09:38', 0);
|
||||
INSERT INTO `zj_menu` VALUES (14, 'layui-icon-tree', 5, 2, '在线用户', 12, '/online/index', '2018-09-21 16:09:38', '2018-09-22 10:17:09', 0);
|
||||
INSERT INTO `zj_menu` VALUES (16, 'layui-icon-tree', 5, 2, 'Redis终端', 14, '/redis/terminal', '2018-09-22 11:18:21', '2018-09-22 11:37:28', 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_menus_roles
|
||||
@@ -84,6 +85,7 @@ INSERT INTO `zj_menus_roles` VALUES (11, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (12, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (13, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (14, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (16, 1);
|
||||
INSERT INTO `zj_menus_roles` VALUES (1, 2);
|
||||
INSERT INTO `zj_menus_roles` VALUES (2, 2);
|
||||
INSERT INTO `zj_menus_roles` VALUES (3, 2);
|
||||
@@ -218,23 +220,6 @@ INSERT INTO `zj_role` VALUES (1, '2018-08-23 09:13:54', '超级管理员', NULL,
|
||||
INSERT INTO `zj_role` VALUES (2, '2018-08-27 19:31:03', '普通用户', '', '2018-09-01 08:31:08');
|
||||
INSERT INTO `zj_role` VALUES (3, '2018-09-03 15:17:31', '测试', '1', '2018-09-20 17:28:03');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_syslog
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `zj_syslog`;
|
||||
CREATE TABLE `zj_syslog` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`createTime` datetime NULL DEFAULT NULL,
|
||||
`ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`location` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`operation` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`params` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
`time` int(11) NULL DEFAULT NULL,
|
||||
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_user
|
||||
-- ----------------------------
|
||||
@@ -250,12 +235,12 @@ CREATE TABLE `zj_user` (
|
||||
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `UK_kpubos9gc2cvtkb0thktkbkes`(`email`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of zj_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `zj_user` VALUES (1, 'https://www.zhengjie.me/images/avatar.jpg', '2018-08-23 09:11:56', 'zhengjie@tom.com', 1, '2018-09-21 16:26:05', '65a674ce6632479005ea7a9071234cfb', 'aurora');
|
||||
INSERT INTO `zj_user` VALUES (1, 'https://www.zhengjie.me/images/avatar.jpg', '2018-08-23 09:11:56', 'zhengjie@tom.com', 1, '2018-09-22 13:00:04', '65a674ce6632479005ea7a9071234cfb', 'aurora');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for zj_user_pictures
|
||||
|
||||
@@ -0,0 +1,382 @@
|
||||
var $MB_Redis_Bash = function () {
|
||||
$(document).ready(function () {
|
||||
var title = $(".title");
|
||||
var terminal = $(".terminal");
|
||||
var prompt = "➜";
|
||||
var path = "~";
|
||||
var commandHistory = [];
|
||||
var historyIndex = 0;
|
||||
var command = "";
|
||||
|
||||
title.text(userName + "@" + osName + ": ~ (redis-cli)");
|
||||
var date = new Date().toString();
|
||||
date = date.substr(0, date.indexOf("GMT") - 1);
|
||||
printf("Last login: " + date + " on aurora, type `help` for help\n");
|
||||
displayPrompt();
|
||||
|
||||
var commands = [{
|
||||
name: "clear",
|
||||
function: clear
|
||||
}, {
|
||||
name: "help",
|
||||
function: help
|
||||
}, {
|
||||
name: "echo",
|
||||
function: echo
|
||||
}, {
|
||||
name: "keys",
|
||||
function: keys
|
||||
}, {
|
||||
name: "get",
|
||||
function: get
|
||||
}, {
|
||||
name: "exists",
|
||||
function: exists
|
||||
}, {
|
||||
name: "pttl",
|
||||
function: pttl
|
||||
}, {
|
||||
name: "pexpire",
|
||||
function: pexpire
|
||||
}, {
|
||||
name: "set",
|
||||
function: set
|
||||
}, {
|
||||
name: "del",
|
||||
function: del
|
||||
}, {
|
||||
name: "flushdb",
|
||||
function: flushdb
|
||||
}, {
|
||||
name: "flushall",
|
||||
function: flushall
|
||||
}];
|
||||
|
||||
// system command
|
||||
|
||||
function clear() {
|
||||
terminal.text("");
|
||||
printc();
|
||||
}
|
||||
|
||||
function echo(args) {
|
||||
var str = args.join("");
|
||||
printf(str + "\n");
|
||||
printc();
|
||||
}
|
||||
|
||||
function erase(n) {
|
||||
command = command.slice(0, -n);
|
||||
terminal.html(terminal.html().slice(0, -n));
|
||||
}
|
||||
|
||||
function clearCommand() {
|
||||
if (command.length > 0) {
|
||||
erase(command.length);
|
||||
}
|
||||
}
|
||||
|
||||
// redis command
|
||||
function keys(args) {
|
||||
args = args.join("");
|
||||
if (!hasArgs(args)) {
|
||||
errorArgs('keys');
|
||||
} else $.get("/redis/keys", {
|
||||
'arg': args
|
||||
}, function (r) {
|
||||
console.log(r);
|
||||
var data = r.msg;
|
||||
if (r.code === 0) {
|
||||
if (data.length) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
printf('"' + data[i] + '"\n');
|
||||
}
|
||||
} else {
|
||||
printf("(empty list or set)\n");
|
||||
}
|
||||
} else {
|
||||
printf(data + "\n");
|
||||
}
|
||||
printc();
|
||||
});
|
||||
}
|
||||
|
||||
function get(args) {
|
||||
args = args.join("");
|
||||
if (!hasArgs(args)) {
|
||||
errorArgs('get');
|
||||
} else $.get("/redis/get", {
|
||||
'arg': args
|
||||
}, function (r) {
|
||||
var data = r.msg;
|
||||
if (r.code === 0 && data !== '') {
|
||||
printf(data + "\n");
|
||||
} else {
|
||||
printf("(nil)\n");
|
||||
}
|
||||
printc();
|
||||
});
|
||||
}
|
||||
|
||||
function set(args) {
|
||||
if (!hasArgs(args.join(""))) {
|
||||
errorArgs('set');
|
||||
} else $.get("/redis/set", {
|
||||
'arg': args.join(",")
|
||||
}, function (r) {
|
||||
printf(r.msg + "\n");
|
||||
printc();
|
||||
});
|
||||
}
|
||||
|
||||
function del(args) {
|
||||
if (!hasArgs(args.join(""))) {
|
||||
errorArgs('set');
|
||||
} else $.get("/redis/del", {
|
||||
'arg': args.join(",")
|
||||
}, function (r) {
|
||||
printf(r.msg + "\n");
|
||||
printc();
|
||||
});
|
||||
}
|
||||
|
||||
function exists(args) {
|
||||
if (!hasArgs(args.join(""))) {
|
||||
errorArgs('exists');
|
||||
} else {
|
||||
$.get("/redis/exists", {arg: args.join(",")}, function (r) {
|
||||
var data = r.msg;
|
||||
printf(data + "\n");
|
||||
printc();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function pttl(args) {
|
||||
args = args.join("");
|
||||
if (!hasArgs(args)) {
|
||||
errorArgs('pttl');
|
||||
} else {
|
||||
$.get("/redis/pttl", {arg: args}, function (r) {
|
||||
var data = r.msg;
|
||||
printf(data + "\n");
|
||||
printc();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function flushdb(args) {
|
||||
$.get("/redis/flushdb",{},function (r) {
|
||||
var data = r.msg;
|
||||
printf(data + "\n");
|
||||
printc();
|
||||
});
|
||||
}
|
||||
|
||||
function flushall(args) {
|
||||
$.get("/redis/flushall",{},function (r) {
|
||||
var data = r.msg;
|
||||
printf(data + "\n");
|
||||
printc();
|
||||
});
|
||||
}
|
||||
|
||||
function pexpire(args) {
|
||||
if (!hasArgs(args.join(""))) {
|
||||
errorArgs('pexpire');
|
||||
} else {
|
||||
$.get("/redis/pexpire", {arg: args.join(",")}, function (r) {
|
||||
var data = r.msg;
|
||||
printf(data + "\n");
|
||||
printc();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function help(arg) {
|
||||
arg = arg.join(" ");
|
||||
if (hasArgs(arg)) {
|
||||
switch (arg) {
|
||||
case "keys": {
|
||||
printf(" KEYS pattern\n");
|
||||
printf(" <span class='kw_a'>summary</span>: Find all keys matching the given pattern.\n");
|
||||
printf(" <span class='kw_a'>since</span>: 1.0.0\n");
|
||||
printf(" <span class='kw_a'>group</span>: generic\n");
|
||||
break;
|
||||
}
|
||||
|
||||
case "get": {
|
||||
printf(" GET key\n");
|
||||
printf(" <span class='kw_a'>summary</span>: Get the value of a key\n");
|
||||
printf(" <span class='kw_a'>since</span>: 1.0.0\n");
|
||||
printf(" <span class='kw_a'>group</span>: string\n");
|
||||
break;
|
||||
}
|
||||
case "set": {
|
||||
printf(" DEL key [key ...]\n");
|
||||
printf(" <span class='kw_a'>summary</span>: Delete a key\n");
|
||||
printf(" <span class='kw_a'>since</span>: 1.0.0\n");
|
||||
printf(" <span class='kw_a'>group</span>: generic\n");
|
||||
break;
|
||||
}
|
||||
case "del": {
|
||||
printf(" SET key value\n");
|
||||
printf(" <span class='kw_a'>summary</span>: Set the string value of a key\n");
|
||||
printf(" <span class='kw_a'>since</span>: 1.0.0\n");
|
||||
printf(" <span class='kw_a'>group</span>: string\n");
|
||||
break;
|
||||
}
|
||||
case "exists": {
|
||||
printf(" EXISTS key [key ...]\n");
|
||||
printf(" <span class='kw_a'>summary</span>: Determine if a key exists\n");
|
||||
printf(" <span class='kw_a'>since</span>: 1.0.0\n");
|
||||
printf(" <span class='kw_a'>group</span>: generic\n");
|
||||
break;
|
||||
}
|
||||
case "pttl": {
|
||||
printf(" PTTL key\n");
|
||||
printf(" <span class='kw_a'>summary</span>: Get the time to live for a key in milliseconds\n");
|
||||
printf(" <span class='kw_a'>since</span>: 2.6.0\n");
|
||||
printf(" <span class='kw_a'>group</span>: generic\n");
|
||||
break;
|
||||
}
|
||||
case "pexpire": {
|
||||
printf(" PEXPIRE key milliseconds\n");
|
||||
printf(" <span class='kw_a'>summary</span>: Set a key's time to live in milliseconds\n");
|
||||
printf(" <span class='kw_a'>since</span>: 2.6.0\n");
|
||||
printf(" <span class='kw_a'>group</span>: generic\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
printf(" no more messages about command `" + arg + "`\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf(" Redis bash with SpringBoot by <a href='https://mrbird.cc' class='kw_b'>MrBird</a>, version v0.0.1 - Snapshot \n");
|
||||
printf(" These shell commands are defined internally. Type `help` to see this list.\n");
|
||||
printf(" Type `help name` to find out more about the command `name`.\n");
|
||||
printf(" -------------------------------- \n");
|
||||
printf(" | system command | \n");
|
||||
printf(" -------------------------------- \n");
|
||||
printf(" clear help echo\n");
|
||||
printf(" -------------------------------- \n");
|
||||
printf(" | redis command | \n");
|
||||
printf(" -------------------------------- \n");
|
||||
printf(" keys get set \n");
|
||||
printf(" del exists pttl\n");
|
||||
printf(" -------------------------------- \n");
|
||||
printf(" | redis wipe cache | \n");
|
||||
printf(" -------------------------------- \n");
|
||||
printf(" flushall flushdb\n");
|
||||
}
|
||||
printc();
|
||||
}
|
||||
|
||||
|
||||
function processCommand() {
|
||||
var isValid = false;
|
||||
var args = command.split(" ");
|
||||
var cmd = args[0];
|
||||
args.shift();
|
||||
for (var i = 0; i < commands.length; i++) {
|
||||
if (cmd === commands[i].name) {
|
||||
commands[i].function(args);
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
printf("redis: command not found: `" + command + "`, type `help` for help.\n");
|
||||
printc();
|
||||
}
|
||||
commandHistory.push(command);
|
||||
historyIndex = commandHistory.length;
|
||||
command = "";
|
||||
}
|
||||
|
||||
function displayPrompt() {
|
||||
printf('<span class="prompt">' + prompt + "</span> ");
|
||||
printf('<span class="path">' + path + "</span> ");
|
||||
}
|
||||
|
||||
|
||||
function appendCommand(str) {
|
||||
terminal.append(str);
|
||||
command += str;
|
||||
}
|
||||
|
||||
$(document).keydown(function (e) {
|
||||
e = e || window.event;
|
||||
var keyCode = typeof e.which === "number" ? e.which : e.keyCode;
|
||||
if (keyCode === 8 && e.target.tagName !== "INPUT" && e.target.tagName !== "TEXTAREA") {
|
||||
e.preventDefault();
|
||||
if (command !== "") {
|
||||
erase(1);
|
||||
}
|
||||
}
|
||||
if (keyCode === 38 || keyCode === 40) {
|
||||
if (keyCode === 38) {
|
||||
historyIndex--;
|
||||
if (historyIndex < 0) {
|
||||
historyIndex++;
|
||||
}
|
||||
} else if (keyCode === 40) {
|
||||
historyIndex++;
|
||||
if (historyIndex > commandHistory.length - 1) {
|
||||
historyIndex--;
|
||||
}
|
||||
}
|
||||
var cmd = commandHistory[historyIndex];
|
||||
if (cmd !== undefined) {
|
||||
clearCommand();
|
||||
appendCommand(cmd);
|
||||
}
|
||||
}
|
||||
});
|
||||
$(document).keypress(function (e) {
|
||||
e = e || window.event;
|
||||
var keyCode = typeof e.which === "number" ? e.which : e.keyCode;
|
||||
switch (keyCode) {
|
||||
case 13: {
|
||||
printf("\n");
|
||||
processCommand();
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
appendCommand(String.fromCharCode(keyCode));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function scroll(o) {
|
||||
o = o[0];
|
||||
o.scrollTop = o.scrollHeight;
|
||||
}
|
||||
|
||||
function printf(msg) {
|
||||
terminal.append(msg);
|
||||
}
|
||||
|
||||
function printc() {
|
||||
displayPrompt();
|
||||
historyIndex++;
|
||||
scroll(terminal);
|
||||
}
|
||||
|
||||
function hasArgs(arg) {
|
||||
try {
|
||||
if (arg.length === 0) return 0;
|
||||
else return 1;
|
||||
} catch (e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function errorArgs(args) {
|
||||
printf("(error) ERR wrong number of arguments for '" + args + "' command\n");
|
||||
printc();
|
||||
}
|
||||
|
||||
});
|
||||
}($);
|
||||
@@ -144,6 +144,9 @@
|
||||
base: 'js/'
|
||||
}).use('index');
|
||||
</script>
|
||||
<script data-th-inline="javascript">
|
||||
var userName = [[${user.username}]];
|
||||
</script>
|
||||
<!-- endbuild -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,25 @@
|
||||
<style>
|
||||
textarea,input,button{outline:none}.window-button,.window .buttons .closes,.window .buttons .minimize,.window .buttons .maximize{padding:0;margin:0;margin-right:6px;width:12px;height:12px;background-color:gainsboro;border:1px solid rgba(0,0,0,0);border-radius:6px;color:rgba(0,0,0,0.5)}.window{width:100%}.window .handle{height:38px;background:#f9f9f9;border:1px solid #eee;border-top-left-radius:3px;border-top-right-radius:3px;color:rgba(0,0,0,0.7);font-family:'consolas';font-size:13px;line-height:38px;text-align:center}.window .buttons{position:absolute;float:left;margin:0 8px}.window .buttons .closes{background-color:#fc625d}.window .buttons .minimize{background-color:#fdbc40}.window .buttons .maximize{background-color:#35cd4b}.window .terminal{padding:4px;background-color:black;opacity:0.7;height:575px;color:white;font-family:'consolas';font-weight:200;font-size:13px;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;border-bottom-left-radius:3px;border-bottom-right-radius:3px;border-top-left-radius:1px;border-top-right-radius:1px;overflow-y:scroll}.window .terminal::after{content:"|";animation:blink 1.25s steps(1) infinite}.prompt{color:#bde371}.path{color:#5ed7ff}@keyframes blink{50%{color:transparent}}@keyframes bounceIn{0%{transform:translateY(-1000px)}60%{transform:translateY (200px)}100%{transform:translateY (0px)}}.kw_a{color:#E6DB74}.kw_b{color:#bde371}
|
||||
</style>
|
||||
<div class="card">
|
||||
<div class="card-header"></div>
|
||||
<div class="card-block">
|
||||
<div class="container">
|
||||
<div class="window">
|
||||
<div class="handle">
|
||||
<div class="buttons">
|
||||
<button class="closes"></button>
|
||||
<button class="minimize"></button>
|
||||
<button class="maximize"></button>
|
||||
</div>
|
||||
<span class="title"></span>
|
||||
</div>
|
||||
<div class="terminal"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script data-th-inline="javascript">
|
||||
var osName = [[${osName}]];
|
||||
</script>
|
||||
<script data-th-src="@{js/redis/terminal.js}"></script>
|
||||
Reference in New Issue
Block a user