升级:1、增加界面夜间模式

2、qtask 功能交互升级
     3、mysql连接管理增加心跳保活
     4、其他修改
This commit is contained in:
2024-03-31 00:34:26 +08:00
parent 8cc55c2c4b
commit 4dcebf32de
37 changed files with 1136 additions and 301 deletions

View 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;
}

View 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();
}
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);

View 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;
}

View File

@@ -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;