升级:1、增加界面夜间模式
2、qtask 功能交互升级
3、mysql连接管理增加心跳保活
4、其他修改
This commit is contained in:
47
src/main/java/dev/zhub/mk/qtask/QTask.java
Normal file
47
src/main/java/dev/zhub/mk/qtask/QTask.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package dev.zhub.mk.qtask;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.redkale.annotation.Comment;
|
||||
import org.redkale.persistence.Column;
|
||||
import org.redkale.persistence.Entity;
|
||||
import org.redkale.persistence.Id;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
public class QTask {
|
||||
|
||||
@Id
|
||||
@Comment("[记录ID]")
|
||||
private Integer qtaskid;
|
||||
|
||||
@Comment("[查询默认参数]")
|
||||
private String para = "{}";
|
||||
|
||||
@Comment("[CATALOG]")
|
||||
private String catalog = "";
|
||||
|
||||
@Comment("[数据平台ID]")
|
||||
private String dbplatid = "";
|
||||
|
||||
@Comment("[标识名称KEY]")
|
||||
// @Column(updatable = false)
|
||||
private String name = "";
|
||||
|
||||
@Comment("[所属平台ID]")
|
||||
@Column(updatable = false)
|
||||
private String platid;
|
||||
|
||||
@Comment("[业务名称]")
|
||||
private String title = "";
|
||||
|
||||
@Comment("[SQL模板]")
|
||||
private String content;
|
||||
|
||||
@Comment("[备注]")
|
||||
private String remark = "";
|
||||
|
||||
@Comment("[状态]10正常,80删除")
|
||||
private int status = 10;
|
||||
}
|
||||
61
src/main/java/dev/zhub/mk/qtask/QTaskService.java
Normal file
61
src/main/java/dev/zhub/mk/qtask/QTaskService.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package dev.zhub.mk.qtask;
|
||||
|
||||
import net.tccn.base.BaseService;
|
||||
import net.tccn.base.Utils;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.net.http.RestHeader;
|
||||
import org.redkale.net.http.RestMapping;
|
||||
import org.redkale.net.http.RestService;
|
||||
import org.redkale.service.RetResult;
|
||||
import org.redkale.source.FilterNode;
|
||||
import org.redkale.source.Flipper;
|
||||
import org.redkale.util.AnyValue;
|
||||
import org.redkale.util.Sheet;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestService(name = "qtask", comment = "qtask服务")
|
||||
public class QTaskService extends BaseService {
|
||||
|
||||
@Override
|
||||
public void init(AnyValue config) {
|
||||
super.init(config);
|
||||
/*List<QTask> qTasks = metaSource.queryList(QTask.class);
|
||||
for (QTask xTask : qTasks) {
|
||||
System.out.println(JsonConvert.root().convertTo(xTask));
|
||||
}*/
|
||||
}
|
||||
|
||||
@RestMapping(name = "list", comment = "qtask列表")
|
||||
public RetResult<Sheet<QTask>> list(@RestHeader(name = "platid") String platid,
|
||||
Flipper flipper, Map<String, String> params) {
|
||||
FilterNode node = FilterNode.create("platid", platid);
|
||||
Sheet<QTask> sheet = metaSource.querySheet(QTask.class, flipper, node);
|
||||
return RetResult.success(sheet);
|
||||
}
|
||||
|
||||
@RestMapping(name = "create", comment = "qtask创建")
|
||||
public RetResult create(@RestHeader(name = "platid") String platid,
|
||||
QTask bean) {
|
||||
// -- 数据检查 --
|
||||
// 1. name 不可为空、 content 不可以为空
|
||||
if (Utils.isEmpty(bean.getName())) {
|
||||
return retError("名称不能为空");
|
||||
}
|
||||
if (Utils.isEmpty(bean.getContent())) {
|
||||
return retError("内容不能为空");
|
||||
}
|
||||
|
||||
// 2. bean.name 标识名称KEY唯一性检查
|
||||
FilterNode node = FilterNode.create("name", bean.getName())
|
||||
.and("platid", platid);
|
||||
if (metaSource.exists(QTask.class, node)) {
|
||||
return retError("名称重复");
|
||||
}
|
||||
|
||||
// -- 数据保存 --
|
||||
metaSource.insert(bean);
|
||||
return render();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
package net.tccn.base;
|
||||
|
||||
import org.redkale.annotation.Resource;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.service.RetResult;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.source.CacheMemorySource;
|
||||
import org.redkale.source.DataSource;
|
||||
import org.redkale.util.Sheet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Logger;
|
||||
@@ -29,12 +33,33 @@ public class BaseService implements Service {
|
||||
|
||||
@Resource(name = "APP_HOME")
|
||||
protected File APP_HOME;
|
||||
|
||||
@Resource(name = "meta")
|
||||
protected DataSource metaSource;
|
||||
protected static Properties prop = new Properties();
|
||||
protected static TplKit tplKit = TplKit.use(true);
|
||||
|
||||
private static boolean tplInit = false;
|
||||
|
||||
protected final static RetResult RET_SUCCESS = RetResult.success();
|
||||
protected final static RetResult RET_EMPTY_SHEET = RetResult.success(new Sheet<>(0, List.of()));
|
||||
protected final static RetResult RET_EMPTY_LIST = RetResult.success(List.of());
|
||||
|
||||
protected RetResult retError(String info) {
|
||||
return new RetResult<>(100, info);
|
||||
}
|
||||
|
||||
protected RetResult retError(int code, String info) {
|
||||
return new RetResult<>(code, info);
|
||||
}
|
||||
|
||||
protected <T> RetResult<T> render(T obj) {
|
||||
return new RetResult<>(obj);
|
||||
}
|
||||
|
||||
protected RetResult render() {
|
||||
return RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
protected <T> T getT(String key, Class<T> clazz, Supplier<T> supplier) {
|
||||
Object obj = cacheSource.getAndRefresh(key, 1000 * 60 * 3, clazz);
|
||||
if (obj != null) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.redkale.net.http.HttpServlet;
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
@@ -33,6 +34,15 @@ public class BaseServlet extends HttpServlet {
|
||||
if (sessionid == null) {
|
||||
sessionid = request.getSessionid(true);
|
||||
}
|
||||
if (sessionid == null) {
|
||||
Map<String, String> headers = request.getHeaders();
|
||||
for (String key : headers.keySet()) {
|
||||
if ("token".equalsIgnoreCase(key)) {
|
||||
sessionid = headers.get(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sessionid != null) {
|
||||
MetaUser user = userService.current(sessionid);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.tccn.base;
|
||||
|
||||
import dev.zhub.mk.qtask.QTask;
|
||||
import lombok.Getter;
|
||||
import net.tccn.base.arango.Doc;
|
||||
import net.tccn.base.dbq.jdbc.api.DbAccount;
|
||||
@@ -12,7 +13,11 @@ import net.tccn.plat.MetaPlat;
|
||||
import net.tccn.qtask.DbTask;
|
||||
import net.tccn.qtask.TaskKit;
|
||||
import net.tccn.user.MetaUser;
|
||||
import org.redkale.annotation.Resource;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.service.AbstractService;
|
||||
import org.redkale.source.DataSource;
|
||||
import org.redkale.util.AnyValue;
|
||||
import org.redkale.util.Comment;
|
||||
import org.redkale.util.TypeToken;
|
||||
|
||||
@@ -29,7 +34,7 @@ import static java.util.Arrays.asList;
|
||||
/**
|
||||
* Created by liangxianyou at 2019/1/7 13:31.
|
||||
*/
|
||||
public final class MetaKit {
|
||||
public class MetaKit extends AbstractService {
|
||||
//基础数据缓存
|
||||
@Getter
|
||||
private static List<MetaTable> metaTables;
|
||||
@@ -44,7 +49,7 @@ public final class MetaKit {
|
||||
@Getter
|
||||
private static List<MetaUser> users;
|
||||
@Getter
|
||||
private static List<DbTask> taskEntities;
|
||||
private static List<QTask> taskEntities;
|
||||
@Getter
|
||||
private static List<Dict> dicts;
|
||||
|
||||
@@ -52,6 +57,15 @@ public final class MetaKit {
|
||||
protected static String dataPath;
|
||||
private static final JsonConvert convert = JsonConvert.root();
|
||||
|
||||
@Resource(name = "meta")
|
||||
protected DataSource metaSource;
|
||||
|
||||
@Override
|
||||
public void init(AnyValue config) {
|
||||
taskEntities = metaSource.queryList(QTask.class);
|
||||
TaskKit.init();
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
public static void init() {
|
||||
reload(MetaTable.class);
|
||||
@@ -60,9 +74,20 @@ public final class MetaKit {
|
||||
reload(DbAccount.class);
|
||||
reload(MetaPlat.class);
|
||||
reload(MetaUser.class);
|
||||
reload(DbTask.class);
|
||||
// reload(DbTask.class);
|
||||
reload(Dict.class);
|
||||
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
reload(MetaUser.class);
|
||||
Thread.sleep(15000);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
/*
|
||||
同步 本地文件配置数据到 数据库
|
||||
List<List<? extends Doc>> list = asList(metaTables, metaLinks, metaServices, dbPlats, sysPlats, users, taskEntities, dicts);
|
||||
@@ -140,8 +165,8 @@ public final class MetaKit {
|
||||
else if (MetaPlat.class == clazz) sysPlats = MetaPlat.dao.find();
|
||||
else if (MetaUser.class == clazz) users = MetaUser.dao.find();
|
||||
else if (DbTask.class == clazz) {
|
||||
taskEntities = DbTask.dao.find();
|
||||
TaskKit.init();
|
||||
// taskEntities = DbTask.dao.find();
|
||||
// TaskKit.init();
|
||||
} else if (Dict.class == clazz) {
|
||||
dicts = Dict.dao.find();
|
||||
}
|
||||
|
||||
@@ -250,7 +250,9 @@ public class Utils {
|
||||
sqlCount += " " + join;
|
||||
}
|
||||
}
|
||||
sqlCount += " WHERE " + where;
|
||||
if (!Utils.isEmpty(where)) {
|
||||
sqlCount += " WHERE " + where;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public class ArangoSource {
|
||||
private ArangoSource() {
|
||||
MetaListenter.resourceFactory.inject(this);
|
||||
|
||||
arangoDb = new ArangoDB.Builder().host(host, port).user(user).password(password).build();
|
||||
arangoDb = new ArangoDB.Builder().host(host, port).user(user).password(password).timeout(1000*15).build();
|
||||
}
|
||||
|
||||
private ArangoSource(ArangoDB arangoDb) {
|
||||
|
||||
@@ -28,7 +28,7 @@ public class DbExecutors {
|
||||
MetaService metaService = MetaKit.getMetaService(fBean.getName(), fBean.getPlatToken());
|
||||
MetaTable mainTable = MetaKit.getMetaTableByAlias(metaService.getTable());
|
||||
DbKit dbKit = MetaKit.getDbKit(mainTable.getDbPlatId(), mainTable.getCatalog());
|
||||
//System.out.printf("----------------%n countSql:%s%n findSql:%s%n----------------%n", sqls[0], sqls[1]);
|
||||
System.out.printf("----------------%n countSql:%s%n findSql:%s%n----------------%n", sqls[0], sqls[1]);
|
||||
|
||||
CompletableFuture<Integer> countFuture = CompletableFuture.supplyAsync(() -> dbKit.findColumn(sqls[0], int.class));
|
||||
CompletableFuture<List<Map>> listFuture = CompletableFuture.supplyAsync(() -> dbKit.queryList(sqls[1], Map.class));
|
||||
|
||||
@@ -24,6 +24,49 @@ public class DbSourceMysql implements DbSource {
|
||||
private DbAccount dbAccount;
|
||||
private String catalog;
|
||||
|
||||
private static boolean ping;
|
||||
|
||||
static {
|
||||
// MYSQL PING
|
||||
synchronized (DbSourceMysql.class) {
|
||||
if (!ping) {
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
conns.forEach((k, vs) -> {
|
||||
if (vs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for (int i = 0; i < counter.get(k).get(); i++) {
|
||||
Connection conn = vs.poll();
|
||||
if (conn == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
conn.prepareStatement("SELECT 1").executeQuery();
|
||||
vs.put(conn);
|
||||
} catch (SQLException e) {
|
||||
counter.get(k).decrementAndGet(); // 连接总数减去1
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
Thread.sleep(1000 * 60);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
ping = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DbSourceMysql() {
|
||||
|
||||
}
|
||||
@@ -179,21 +222,34 @@ public class DbSourceMysql implements DbSource {
|
||||
}
|
||||
|
||||
private synchronized Connection connection(int n) throws InterruptedException, SQLException {
|
||||
LinkedBlockingQueue<Connection> queue = conns.getOrDefault(accountKey, new LinkedBlockingQueue<>(15));
|
||||
LinkedBlockingQueue<Connection> queue = conns.get(accountKey);
|
||||
if (queue == null) {
|
||||
queue = new LinkedBlockingQueue<>(15);
|
||||
conns.put(accountKey, queue);
|
||||
}
|
||||
AtomicInteger num = counter.get(accountKey);
|
||||
if (num == null) {
|
||||
num = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
Connection conn = null;
|
||||
AtomicInteger num = counter.getOrDefault(accountKey, new AtomicInteger(0));
|
||||
if (queue.size() == 0 && num.get() < 15) { // 创建总连接数小于15,且暂无可用连接
|
||||
conn = DriverManager.getConnection(dbAccount.getUrl(), dbAccount.getUser(), dbAccount.getPwd());
|
||||
if (queue.isEmpty() && num.get() < 15) { // 创建总连接数小于15,且暂无可用连接
|
||||
String url = dbAccount.getUrl();
|
||||
String user = dbAccount.getUser();
|
||||
String pwd = dbAccount.getPwd();
|
||||
|
||||
conn = DriverManager.getConnection(url, user, pwd);
|
||||
int x = num.incrementAndGet();
|
||||
counter.put(accountKey, num);
|
||||
System.out.println("创建新的连接:" + x);
|
||||
System.out.printf("创建新的连接[%s]:%s\n", x, url + "@" + user);
|
||||
|
||||
} else {
|
||||
conn = queue.take();
|
||||
if (!conn.isValid(5)) {
|
||||
conn = connection(++n);
|
||||
}
|
||||
}
|
||||
conns.put(accountKey, queue);
|
||||
//conns.put(accountKey, queue);
|
||||
return conn;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.tccn.qtask;
|
||||
|
||||
import dev.zhub.mk.qtask.QTask;
|
||||
import net.tccn.base.Kv;
|
||||
import net.tccn.base.MetaKit;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
@@ -14,7 +15,7 @@ import java.util.Optional;
|
||||
*/
|
||||
public class TaskKit {
|
||||
static final JsonConvert convert = JsonConvert.root();
|
||||
private static List<DbTask> taskEntities;
|
||||
private static List<QTask> taskEntities;
|
||||
|
||||
static {
|
||||
init();
|
||||
@@ -25,16 +26,16 @@ public class TaskKit {
|
||||
}
|
||||
|
||||
public static Task buildTask(String name, String platToken, Kv para) {
|
||||
DbTask taskEntity = getTaskEntity(name, platToken);
|
||||
QTask taskEntity = getTaskEntity(name, platToken);
|
||||
return buildTask(taskEntity, para);
|
||||
}
|
||||
|
||||
public static Task buildTask(DbTask taskEntity, Kv para) {
|
||||
public static Task buildTask(dev.zhub.mk.qtask.QTask taskEntity, Kv para) {
|
||||
Task task = new Task();
|
||||
task.setName(taskEntity.getName());
|
||||
task.setTitle(taskEntity.getTitle());
|
||||
task.setContent(taskEntity.getContent());
|
||||
task.setDbPlatId(taskEntity.getDbPlatId());
|
||||
task.setDbPlatId(taskEntity.getDbplatid());
|
||||
task.setCatalog(taskEntity.getCatalog());
|
||||
|
||||
Kv _para = Kv.of().putAll(para);
|
||||
@@ -47,16 +48,16 @@ public class TaskKit {
|
||||
}
|
||||
}
|
||||
task.setPara(_para);
|
||||
task.setDbAccount(MetaKit.getDbPlat(taskEntity.getDbPlatId()));
|
||||
task.setDbAccount(MetaKit.getDbPlat(taskEntity.getDbplatid()));
|
||||
return task;
|
||||
}
|
||||
|
||||
public static DbTask getTaskEntity(String name, String platToken) {
|
||||
public static QTask getTaskEntity(String name, String platToken) {
|
||||
Objects.requireNonNull(name);
|
||||
Objects.requireNonNull(platToken);
|
||||
|
||||
Optional<DbTask> any = taskEntities.stream()
|
||||
.filter(x -> name.equals(x.getName()) && MetaKit.getPlatId(platToken).equals(x.getSysPlatId()))
|
||||
Optional<QTask> any = taskEntities.stream()
|
||||
.filter(x -> name.equals(x.getName()) && MetaKit.getPlatId(platToken).equals(x.getPlatid()))
|
||||
.findAny();
|
||||
return any.get();
|
||||
}
|
||||
@@ -66,7 +67,7 @@ public class TaskKit {
|
||||
return QRuner.query(task);
|
||||
}
|
||||
|
||||
public static Object taskRun(DbTask entity) {
|
||||
public static Object taskRun(QTask entity) {
|
||||
Task task = buildTask(entity, Kv.of());
|
||||
return QRuner.query(task);
|
||||
}
|
||||
|
||||
@@ -1,29 +1,68 @@
|
||||
package net.tccn.qtask;
|
||||
|
||||
import dev.zhub.mk.qtask.QTask;
|
||||
import net.tccn.base.BaseService;
|
||||
import net.tccn.base.JBean;
|
||||
import net.tccn.base.MetaKit;
|
||||
import net.tccn.base.PageBean;
|
||||
import org.redkale.net.http.RestBody;
|
||||
import org.redkale.net.http.RestHeader;
|
||||
import org.redkale.net.http.RestParam;
|
||||
import org.redkale.net.http.RestService;
|
||||
import org.redkale.service.RetResult;
|
||||
import org.redkale.source.ColumnValue;
|
||||
import org.redkale.source.FilterNode;
|
||||
import org.redkale.source.Flipper;
|
||||
import org.redkale.util.Comment;
|
||||
import org.redkale.util.Sheet;
|
||||
|
||||
@RestService(automapping = true)
|
||||
public class _QtaskService extends BaseService {
|
||||
|
||||
@Comment("qtask列表")
|
||||
public JBean list(DbTask task, Flipper flipper, @RestParam(name = "platToken") String token) {
|
||||
if (task == null) {
|
||||
public RetResult<Sheet<QTask>> list(Flipper flipper, @RestHeader(name = "plattoken") String token) {
|
||||
flipper.sort("qtaskid DESC");
|
||||
/*if (task == null) {
|
||||
task = new DbTask();
|
||||
}
|
||||
task.setSysPlatId(platId(token));
|
||||
PageBean<DbTask> page = DbTask.dao.findPage(task, flipper);
|
||||
|
||||
|
||||
return JBean.by(0, "", page);
|
||||
PageBean<DbTask> page = DbTask.dao.findPage(task, flipper);*/
|
||||
|
||||
FilterNode node = FilterNode.create("platid", platId(token)).and("status", 10);
|
||||
Sheet<QTask> sheet = metaSource.querySheet(QTask.class, flipper, node);
|
||||
return RetResult.success(sheet);
|
||||
}
|
||||
|
||||
public RetResult create(@RestHeader(name = "plattoken") String token,
|
||||
@RestBody QTask task) {
|
||||
|
||||
FilterNode node = FilterNode.create("name", task.getName()).and("platid", platId(token));
|
||||
if (metaSource.exists(QTask.class, node)) {
|
||||
return retError("qtask 标识不能重复");
|
||||
}
|
||||
task.setPlatid(platId(token));
|
||||
|
||||
metaSource.insert(task);
|
||||
return render();
|
||||
}
|
||||
|
||||
public RetResult update(@RestHeader(name = "plattoken") String token,
|
||||
@RestBody QTask task) {
|
||||
|
||||
metaSource.update(task);
|
||||
return render();
|
||||
}
|
||||
|
||||
public RetResult delete(@RestHeader(name = "plattoken") String token,
|
||||
@RestBody QTask task) {
|
||||
|
||||
metaSource.updateColumn(QTask.class, task.getQtaskid(), ColumnValue.create("status", 80));
|
||||
return render();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Comment("qtask保存")
|
||||
public JBean save(DbTask task, @RestParam(name = "platToken") String token) {
|
||||
JBean jBean = new JBean();
|
||||
@@ -60,7 +99,7 @@ public class _QtaskService extends BaseService {
|
||||
}
|
||||
|
||||
@Comment("debug调试接口")
|
||||
public JBean debug(DbTask task, @RestParam(name = "platToken") String token) {
|
||||
public JBean debug(QTask task, @RestParam(name = "platToken") String token) {
|
||||
JBean jBean = new JBean();
|
||||
|
||||
Object res = TaskKit.taskRun(task);
|
||||
|
||||
11
src/main/java/net/tccn/user/LoginBean.java
Normal file
11
src/main/java/net/tccn/user/LoginBean.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package net.tccn.user;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class LoginBean {
|
||||
private String username;
|
||||
private String pwd;
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package net.tccn.user;
|
||||
import net.tccn.base.BaseService;
|
||||
import net.tccn.base.JBean;
|
||||
import net.tccn.base.MetaKit;
|
||||
import org.redkale.net.http.RestBody;
|
||||
import org.redkale.net.http.RestMapping;
|
||||
import org.redkale.net.http.RestService;
|
||||
import org.redkale.net.http.RestSessionid;
|
||||
|
||||
Reference in New Issue
Block a user