|
@@ -1,22 +1,26 @@
|
|
|
package mingsoft;
|
|
package mingsoft;
|
|
|
|
|
|
|
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
|
|
+import cn.hutool.core.bean.copier.CopyOptions;
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
import cn.hutool.core.lang.Assert;
|
|
import cn.hutool.core.lang.Assert;
|
|
|
import cn.hutool.core.util.ArrayUtil;
|
|
import cn.hutool.core.util.ArrayUtil;
|
|
|
-import cn.hutool.core.util.EnumUtil;
|
|
|
|
|
-import cn.hutool.json.JSONArray;
|
|
|
|
|
-import cn.hutool.json.JSONObject;
|
|
|
|
|
|
|
+import cn.hutool.db.DbUtil;
|
|
|
|
|
+import cn.hutool.db.ds.pooled.DbConfig;
|
|
|
|
|
+import cn.hutool.db.ds.pooled.PooledDataSource;
|
|
|
|
|
+import lombok.SneakyThrows;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import mingsoft.client.Info;
|
|
import mingsoft.client.Info;
|
|
|
import mingsoft.client.MingsoftClient;
|
|
import mingsoft.client.MingsoftClient;
|
|
|
import mingsoft.client.MingsoftData;
|
|
import mingsoft.client.MingsoftData;
|
|
|
import mingsoft.client.MingsoftPreView;
|
|
import mingsoft.client.MingsoftPreView;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
import java.io.File;
|
|
|
|
|
+import java.util.Comparator;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
|
+import java.util.Objects;
|
|
|
import java.util.Optional;
|
|
import java.util.Optional;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
-import java.util.stream.Stream;
|
|
|
|
|
-import java.util.stream.StreamSupport;
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 操作封装
|
|
* 操作封装
|
|
@@ -26,6 +30,7 @@ import java.util.stream.StreamSupport;
|
|
|
* @author hosea
|
|
* @author hosea
|
|
|
* @date 2025-12-24
|
|
* @date 2025-12-24
|
|
|
*/
|
|
*/
|
|
|
|
|
+@Slf4j(topic = "Service")
|
|
|
public record MingsoftService(MingsoftClient client, Map<Info, MingsoftData> codes) {
|
|
public record MingsoftService(MingsoftClient client, Map<Info, MingsoftData> codes) {
|
|
|
public MingsoftService {
|
|
public MingsoftService {
|
|
|
Assert.notNull(client, "客户端不能为空");
|
|
Assert.notNull(client, "客户端不能为空");
|
|
@@ -34,43 +39,64 @@ public record MingsoftService(MingsoftClient client, Map<Info, MingsoftData> cod
|
|
|
/**
|
|
/**
|
|
|
* 创建
|
|
* 创建
|
|
|
*
|
|
*
|
|
|
- * @param config 客户端配置
|
|
|
|
|
- * @param jsonFile 本地代码备份
|
|
|
|
|
|
|
+ * @param config 客户端配置
|
|
|
|
|
+ * @param dbFile 本地代码备份
|
|
|
*/
|
|
*/
|
|
|
- public static Optional<MingsoftService> of(String config, String jsonFile) {
|
|
|
|
|
|
|
+ public static Optional<MingsoftService> of(String config, String dbFile) {
|
|
|
return MingsoftClient.of(config)
|
|
return MingsoftClient.of(config)
|
|
|
- .flatMap(client -> of(client, jsonFile));
|
|
|
|
|
|
|
+ .flatMap(client -> of(client, dbFile));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 创建
|
|
* 创建
|
|
|
*
|
|
*
|
|
|
- * @param client 客户端
|
|
|
|
|
- * @param jsonFile 本地代码备份
|
|
|
|
|
|
|
+ * @param client 客户端
|
|
|
|
|
+ * @param dbFile 本地代码备份
|
|
|
*/
|
|
*/
|
|
|
- public static Optional<MingsoftService> of(MingsoftClient client, String jsonFile) {
|
|
|
|
|
- return loadLocalCodeBackup(jsonFile)
|
|
|
|
|
|
|
+ @SneakyThrows
|
|
|
|
|
+ public static Optional<MingsoftService> of(MingsoftClient client, String dbFile) {
|
|
|
|
|
+ return loadLocalCodeBackup(dbFile)
|
|
|
.map(codes -> new MingsoftService(client, codes));
|
|
.map(codes -> new MingsoftService(client, codes));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 加载本地代码备份
|
|
* 加载本地代码备份
|
|
|
*
|
|
*
|
|
|
- * @param jsonFile 备份代码的JSON文件
|
|
|
|
|
- */
|
|
|
|
|
- public static Optional<Map<Info, MingsoftData>> loadLocalCodeBackup(String jsonFile) {
|
|
|
|
|
- return Optional.ofNullable(jsonFile)
|
|
|
|
|
- .map(FileUtil::readUtf8String)
|
|
|
|
|
- .map(JSONObject::new)
|
|
|
|
|
- .map(json -> json.getJSONArray("data"))
|
|
|
|
|
- .map(MingsoftService::from);
|
|
|
|
|
|
|
+ * @param dbFile 备份代码的SQLite文件
|
|
|
|
|
+ */
|
|
|
|
|
+ public static Optional<Map<Info, MingsoftData>> loadLocalCodeBackup(String dbFile) throws Exception {
|
|
|
|
|
+ DbConfig config = new DbConfig();
|
|
|
|
|
+ config.setUrl("jdbc:sqlite:" + dbFile);
|
|
|
|
|
+ config.setMaxActive(2);
|
|
|
|
|
+ try (PooledDataSource ds = new PooledDataSource(config)) {
|
|
|
|
|
+ return Optional.of(DbUtil.use(ds)
|
|
|
|
|
+ .query("select * from ms where version is not null")
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .map(entity -> BeanUtil.fillBeanWithMap(entity, new MingsoftData(), CopyOptions.create().ignoreCase()))
|
|
|
|
|
+ .collect(Collectors.groupingBy(MingsoftData::toInfo, Collectors.maxBy(Comparator.comparing(MingsoftData::getVersion))))
|
|
|
|
|
+ .values()
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .map(opt -> opt.orElse(null))
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .collect(Collectors.toMap(MingsoftData::toInfo, v -> v)))
|
|
|
|
|
+ .map(list -> {
|
|
|
|
|
+ log.info("查到SQLite的代码 Size:{}", list.size());
|
|
|
|
|
+ return list;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 查服务器上的代码
|
|
* 查服务器上的代码
|
|
|
*/
|
|
*/
|
|
|
public Optional<Map<Info, MingsoftData>> queryCodes() {
|
|
public Optional<Map<Info, MingsoftData>> queryCodes() {
|
|
|
- return client.list().map(MingsoftService::from);
|
|
|
|
|
|
|
+ return Optional.of(client.list()
|
|
|
|
|
+ .map(json -> json.toBean(MingsoftData.class))
|
|
|
|
|
+ .collect(Collectors.toMap(MingsoftData::toInfo, v -> v)))
|
|
|
|
|
+ .map(map -> {
|
|
|
|
|
+ log.info("查到服务器上的代码 Size:{}", map.size());
|
|
|
|
|
+ return map;
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -134,6 +160,7 @@ public record MingsoftService(MingsoftClient client, Map<Info, MingsoftData> cod
|
|
|
* @param code 代码
|
|
* @param code 代码
|
|
|
*/
|
|
*/
|
|
|
public boolean update(String id, MingsoftData code) {
|
|
public boolean update(String id, MingsoftData code) {
|
|
|
|
|
+ log.info("修改 ID:{} Name:{} Table:{}", id, code.getPmoName(), code.getPmoTableName());
|
|
|
return client.update(code.clone().setId(id)).isPresent();
|
|
return client.update(code.clone().setId(id)).isPresent();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -152,7 +179,11 @@ public record MingsoftService(MingsoftClient client, Map<Info, MingsoftData> cod
|
|
|
public Optional<byte[]> downloadCode(String... ids) {
|
|
public Optional<byte[]> downloadCode(String... ids) {
|
|
|
return Optional.ofNullable(ids)
|
|
return Optional.ofNullable(ids)
|
|
|
.filter(ArrayUtil::isNotEmpty)
|
|
.filter(ArrayUtil::isNotEmpty)
|
|
|
- .flatMap(client::download);
|
|
|
|
|
|
|
+ .flatMap(client::download)
|
|
|
|
|
+ .map(bs -> {
|
|
|
|
|
+ log.info("下载代码 ID:{} Length:{}", ids, bs.length);
|
|
|
|
|
+ return bs;
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -177,13 +208,18 @@ public record MingsoftService(MingsoftClient client, Map<Info, MingsoftData> cod
|
|
|
FileUtil.mkParentDirs(file);
|
|
FileUtil.mkParentDirs(file);
|
|
|
return file;
|
|
return file;
|
|
|
})
|
|
})
|
|
|
- .flatMap(file -> downloadCode(ids).map(bytes -> FileUtil.writeBytes(bytes, file)));
|
|
|
|
|
|
|
+ .flatMap(file -> downloadCode(ids).map(bytes -> {
|
|
|
|
|
+ File f = FileUtil.writeBytes(bytes, file);
|
|
|
|
|
+ log.info("保存代码 ID:{} Length:{} File:{}", ids, bytes.length, f);
|
|
|
|
|
+ return f;
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 预览{@link Info#FORM_ID}代码
|
|
* 预览{@link Info#FORM_ID}代码
|
|
|
*/
|
|
*/
|
|
|
- public Stream<MingsoftPreView> previewCode() {
|
|
|
|
|
|
|
+ public Optional<Map<String, MingsoftPreView>> previewCode() {
|
|
|
return previewCode(Info.FORM_ID);
|
|
return previewCode(Info.FORM_ID);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -192,21 +228,13 @@ public record MingsoftService(MingsoftClient client, Map<Info, MingsoftData> cod
|
|
|
*
|
|
*
|
|
|
* @param id 表单ID
|
|
* @param id 表单ID
|
|
|
*/
|
|
*/
|
|
|
- public Stream<MingsoftPreView> previewCode(String id) {
|
|
|
|
|
- return client.preview(id)
|
|
|
|
|
- .stream()
|
|
|
|
|
- .map(JSONArray::jsonIter)
|
|
|
|
|
- .map(Iterable::spliterator)
|
|
|
|
|
- .flatMap(iter -> StreamSupport.stream(iter, false))
|
|
|
|
|
- .map(item -> item.toBean(MingsoftPreView.class));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 把JSON格式化转实体
|
|
|
|
|
- */
|
|
|
|
|
- private static Map<Info, MingsoftData> from(JSONArray array) {
|
|
|
|
|
- return StreamSupport.stream(array.jsonIter().spliterator(), false)
|
|
|
|
|
- .map(item -> item.toBean(MingsoftData.class))
|
|
|
|
|
- .collect(Collectors.toMap(mingsoftData -> EnumUtil.fromStringQuietly(Info.class, mingsoftData.getPmoTableName().toUpperCase()), v -> v));
|
|
|
|
|
|
|
+ public Optional<Map<String, MingsoftPreView>> previewCode(String id) {
|
|
|
|
|
+ return Optional.of(client.preview(id)
|
|
|
|
|
+ .map(item -> item.toBean(MingsoftPreView.class))
|
|
|
|
|
+ .collect(Collectors.toMap(MingsoftPreView::getCode, v -> v)))
|
|
|
|
|
+ .map(map -> {
|
|
|
|
|
+ log.info("预览代码 Size:{}", map.size());
|
|
|
|
|
+ return map;
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|