| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- 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.lang.Assert;
- import cn.hutool.core.util.ArrayUtil;
- 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.MingsoftClient;
- import mingsoft.client.MingsoftData;
- import mingsoft.client.MingsoftPreView;
- import java.io.File;
- import java.util.Comparator;
- import java.util.Map;
- import java.util.Objects;
- import java.util.Optional;
- import java.util.stream.Collectors;
- /**
- * 操作封装
- *
- * @param client 客户端
- * @param codes 本地代码备份
- * @author hosea
- * @date 2025-12-24
- */
- @Slf4j(topic = "Service")
- public record MingsoftService(MingsoftClient client, Map<Info, MingsoftData> codes) {
- public MingsoftService {
- Assert.notNull(client, "客户端不能为空");
- }
- /**
- * 创建
- *
- * @param config 客户端配置
- * @param dbFile 本地代码备份
- */
- public static Optional<MingsoftService> of(String config, String dbFile) {
- return MingsoftClient.of(config)
- .flatMap(client -> of(client, dbFile));
- }
- /**
- * 创建
- *
- * @param client 客户端
- * @param dbFile 本地代码备份
- */
- @SneakyThrows
- public static Optional<MingsoftService> of(MingsoftClient client, String dbFile) {
- return loadLocalCodeBackup(dbFile)
- .map(codes -> new MingsoftService(client, codes));
- }
- /**
- * 加载本地代码备份
- *
- * @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() {
- 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;
- });
- }
- /**
- * 复制代码,永远还原到{@link Info#FORM_ID}这个表单ID
- * <p>
- * {@link #copy(Info, Info, String)}
- *
- * @param old 旧的
- * @param news 新的
- */
- public boolean copy(Info old, Info news) {
- return copy(old, news, Info.FORM_ID);
- }
- /**
- * 复制代码
- * <p>
- * 从{@link #codes}备份中取是旧的代码
- * <p>
- * 然后设置新的信息进去
- * <p>
- * 还原到服务器上指定ID的表单
- *
- * @param old 旧的
- * @param news 新的
- * @param id 表单ID
- */
- public boolean copy(Info old, Info news, String id) {
- return update(id, codes.get(old).clone().info(news));
- }
- /**
- * 还原代码,永远还原到{@link Info#FORM_ID}这个表单ID
- * <p>
- * {@link #restore(Info, String)}
- *
- * @param old 旧的
- */
- public boolean restore(Info old) {
- return restore(old, Info.FORM_ID);
- }
- /**
- * 还原代码
- * <p>
- * 从{@link #codes}备份中取是旧的代码
- * <p>
- * 还原到服务器上指定ID的表单
- *
- * @param old 旧的
- * @param id 表单ID
- */
- public boolean restore(Info old, String id) {
- return update(id, codes.get(old));
- }
- /**
- * 修改指定表单ID的代码
- *
- * @param id 表单ID
- * @param 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();
- }
- /**
- * 下载{@link Info#FORM_ID}代码
- */
- public Optional<byte[]> downloadCode() {
- return downloadCode(Info.FORM_ID);
- }
- /**
- * 下载代码
- *
- * @param ids 表单ID
- */
- public Optional<byte[]> downloadCode(String... ids) {
- return Optional.ofNullable(ids)
- .filter(ArrayUtil::isNotEmpty)
- .flatMap(client::download)
- .map(bs -> {
- log.info("下载代码 ID:{} Length:{}", ids, bs.length);
- return bs;
- });
- }
- /**
- * 保存下载{@link Info#FORM_ID}代码
- *
- * @param saveFile 保存的文件,如果已经存在,则不会保存
- */
- public Optional<File> saveDownloadCode(File saveFile) {
- return saveDownloadCode(saveFile, Info.FORM_ID);
- }
- /**
- * 保存下载代码
- *
- * @param saveFile 保存的文件,如果已经存在,则不会保存
- * @param ids 表单ID
- */
- public Optional<File> saveDownloadCode(File saveFile, String... ids) {
- return Optional.ofNullable(saveFile)
- .filter(file -> !file.exists())
- .map(file -> {
- FileUtil.mkParentDirs(file);
- return 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}代码
- */
- public Optional<Map<String, MingsoftPreView>> previewCode() {
- return previewCode(Info.FORM_ID);
- }
- /**
- * 预览代码
- *
- * @param id 表单ID
- */
- 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;
- });
- }
- }
|