|
@@ -4,56 +4,106 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.usky.common.core.bean.CommonPage;
|
|
import com.usky.common.core.bean.CommonPage;
|
|
|
|
|
+import com.usky.sas.domain.SasSystemActivation;
|
|
|
|
|
+import com.usky.sas.domain.SasSystemTypeCode;
|
|
|
import com.usky.sas.domain.SasVersionAdmin;
|
|
import com.usky.sas.domain.SasVersionAdmin;
|
|
|
|
|
+import com.usky.sas.mapper.SasSystemActivationMapper;
|
|
|
|
|
+import com.usky.sas.mapper.SasSystemTypeCodeMapper;
|
|
|
import com.usky.sas.mapper.SasVersionAdminMapper;
|
|
import com.usky.sas.mapper.SasVersionAdminMapper;
|
|
|
import com.usky.sas.service.SasSystemService;
|
|
import com.usky.sas.service.SasSystemService;
|
|
|
import com.usky.sas.service.vo.*;
|
|
import com.usky.sas.service.vo.*;
|
|
|
|
|
+import com.usky.sas.util.DatabaseBackupUtil;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
+import java.io.File;
|
|
|
|
|
+import java.io.IOException;
|
|
|
|
|
+import java.sql.SQLException;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
-import java.util.Collections;
|
|
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 系统信息 / 版本 / 备份 服务实现
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
@Service
|
|
@Service
|
|
|
public class SasSystemServiceImpl implements SasSystemService {
|
|
public class SasSystemServiceImpl implements SasSystemService {
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private SasSystemActivationMapper sasSystemActivationMapper;
|
|
|
|
|
+
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private SasVersionAdminMapper sasVersionAdminMapper;
|
|
private SasVersionAdminMapper sasVersionAdminMapper;
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private SasSystemTypeCodeMapper sasSystemTypeCodeMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private DatabaseBackupUtil databaseBackupUtil;
|
|
|
|
|
+
|
|
|
|
|
+ private static final String MANUFACTURER = "上海觉大计算机科技有限公司";
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public SystemInfoResponse getSystemInfo() {
|
|
public SystemInfoResponse getSystemInfo() {
|
|
|
- SystemInfoResponse resp = new SystemInfoResponse();
|
|
|
|
|
-
|
|
|
|
|
- // systemInfo 占位实现
|
|
|
|
|
- SystemInfoResponse.SystemInfo systemInfo = new SystemInfoResponse.SystemInfo();
|
|
|
|
|
- systemInfo.setId("client_001");
|
|
|
|
|
- systemInfo.setName("系统客户端");
|
|
|
|
|
- systemInfo.setCreateTime(LocalDateTime.now());
|
|
|
|
|
- systemInfo.setUpdateTime(LocalDateTime.now());
|
|
|
|
|
- resp.setSystemInfo(systemInfo);
|
|
|
|
|
-
|
|
|
|
|
- // versionInfo 从 sas_version_admin 取第一条
|
|
|
|
|
- VersionInfoResponse version = getVersionInfo();
|
|
|
|
|
- if (version != null) {
|
|
|
|
|
- SystemInfoResponse.VersionInfo vi = new SystemInfoResponse.VersionInfo();
|
|
|
|
|
- vi.setId(version.getId());
|
|
|
|
|
- vi.setJarVersion(version.getJarVersion());
|
|
|
|
|
- vi.setVueVersion(version.getVueVersion());
|
|
|
|
|
- vi.setDurationOfUpdate(version.getDurationOfUpdate());
|
|
|
|
|
- vi.setCreateTime(version.getCreateTime());
|
|
|
|
|
- vi.setUpdateTime(version.getUpdateTime());
|
|
|
|
|
- resp.setVersionInfo(vi);
|
|
|
|
|
|
|
+ SystemInfoResponse response = new SystemInfoResponse();
|
|
|
|
|
+
|
|
|
|
|
+ // 从系统激活表获取信息
|
|
|
|
|
+ LambdaQueryWrapper<SasSystemActivation> wrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ wrapper.orderByDesc(SasSystemActivation::getUpdateTime).last("limit 1");
|
|
|
|
|
+ List<SasSystemActivation> activationList = sasSystemActivationMapper.selectList(wrapper);
|
|
|
|
|
+
|
|
|
|
|
+ SasSystemActivation activation = null;
|
|
|
|
|
+ if (activationList != null && !activationList.isEmpty()) {
|
|
|
|
|
+ activation = activationList.get(0);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return response;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ response.setClientId(activation.getClientId());
|
|
|
|
|
+ response.setIsPerpetual(activation.getIsPerpetual());
|
|
|
|
|
+ response.setValidityTime(activation.getValidityTime());
|
|
|
|
|
+ response.setCreateTime(activation.getCreateTime());
|
|
|
|
|
+ response.setUpdateTime(activation.getUpdateTime());
|
|
|
|
|
+
|
|
|
|
|
+ // 解析授权模块
|
|
|
|
|
+ List<SasSystemTypeCode> modules = parseAuthorizationModules(activation.getAuthorizationModule());
|
|
|
|
|
+ response.setAuthorizationModules(modules);
|
|
|
|
|
+
|
|
|
|
|
+ response.setManufacturer(MANUFACTURER);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取当前系统版本
|
|
|
|
|
+ VersionInfoResponse versionInfo = getVersionInfo();
|
|
|
|
|
+ if (versionInfo != null && versionInfo.getCurrentVersion() != null) {
|
|
|
|
|
+ response.setSystemVersion(versionInfo.getCurrentVersion());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ response.setSystemVersion("v5A13");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // backupInfo 占位实现:目前仅返回空列表
|
|
|
|
|
- SystemInfoResponse.BackupInfo backupInfo = new SystemInfoResponse.BackupInfo();
|
|
|
|
|
- backupInfo.setLastBackupTime(null);
|
|
|
|
|
- backupInfo.setBackupFiles(Collections.emptyList());
|
|
|
|
|
- resp.setBackupInfo(backupInfo);
|
|
|
|
|
|
|
+ return response;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 解析授权模块字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<SasSystemTypeCode> parseAuthorizationModules(String moduleStr) {
|
|
|
|
|
+ if (StringUtils.isEmpty(moduleStr)) {
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- return resp;
|
|
|
|
|
|
|
+ // 格式为:"1001,1002,1003" 表示启用的模块编码
|
|
|
|
|
+ List<Integer> enabledCodes = Arrays.stream(moduleStr.split(","))
|
|
|
|
|
+ .map(String::trim)
|
|
|
|
|
+ .filter(s -> !s.isEmpty())
|
|
|
|
|
+ .map(Integer::parseInt)
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ return sasSystemTypeCodeMapper.selectList(new LambdaQueryWrapper<SasSystemTypeCode>().in(SasSystemTypeCode::getCode, enabledCodes));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -61,66 +111,155 @@ public class SasSystemServiceImpl implements SasSystemService {
|
|
|
LambdaQueryWrapper<SasVersionAdmin> wrapper = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<SasVersionAdmin> wrapper = new LambdaQueryWrapper<>();
|
|
|
wrapper.orderByDesc(SasVersionAdmin::getUpdateTime).last("limit 1");
|
|
wrapper.orderByDesc(SasVersionAdmin::getUpdateTime).last("limit 1");
|
|
|
List<SasVersionAdmin> list = sasVersionAdminMapper.selectList(wrapper);
|
|
List<SasVersionAdmin> list = sasVersionAdminMapper.selectList(wrapper);
|
|
|
- if (list == null || list.isEmpty()) {
|
|
|
|
|
- return null;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ VersionInfoResponse response = new VersionInfoResponse();
|
|
|
|
|
+
|
|
|
|
|
+ if (list != null && !list.isEmpty()) {
|
|
|
|
|
+ SasVersionAdmin entity = list.get(0);
|
|
|
|
|
+ response.setCurrentVersion(formatVersion(entity.getJarVersion()));
|
|
|
|
|
+ response.setJarVersion(entity.getJarVersion());
|
|
|
|
|
+ response.setVueVersion(entity.getVueVersion());
|
|
|
|
|
+ response.setLastUpgradeVersion(formatVersion(entity.getJarVersion()));
|
|
|
|
|
+ response.setLastUpgradeTime(entity.getUpdateTime());
|
|
|
|
|
+ response.setDurationOfUpdate(entity.getDurationOfUpdate());
|
|
|
}
|
|
}
|
|
|
- SasVersionAdmin entity = list.get(0);
|
|
|
|
|
- VersionInfoResponse resp = new VersionInfoResponse();
|
|
|
|
|
- resp.setId(entity.getId());
|
|
|
|
|
- resp.setJarVersion(entity.getJarVersion());
|
|
|
|
|
- resp.setVueVersion(entity.getVueVersion());
|
|
|
|
|
- resp.setDurationOfUpdate(entity.getDurationOfUpdate());
|
|
|
|
|
- resp.setCreateTime(entity.getCreateTime());
|
|
|
|
|
- resp.setUpdateTime(entity.getUpdateTime());
|
|
|
|
|
- return resp;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否有新版本(模拟实现,实际应从版本服务器获取)
|
|
|
|
|
+ response.setHasNewVersion(false);
|
|
|
|
|
+ response.setLatestVersion(null);
|
|
|
|
|
+ response.setReleaseNotes(null);
|
|
|
|
|
+
|
|
|
|
|
+ return response;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public VersionInfoResponse upgradeVersion() {
|
|
|
|
|
- // 占位实现:简单创建/更新一条版本记录为“最新版本”
|
|
|
|
|
- SasVersionAdmin entity = new SasVersionAdmin();
|
|
|
|
|
- entity.setJarVersion("1.0.1");
|
|
|
|
|
- entity.setVueVersion("1.0.1");
|
|
|
|
|
- entity.setDurationOfUpdate("5分钟");
|
|
|
|
|
- entity.setUpdateTime(LocalDateTime.now());
|
|
|
|
|
- entity.setCreateTime(LocalDateTime.now());
|
|
|
|
|
- sasVersionAdminMapper.insert(entity);
|
|
|
|
|
- VersionInfoResponse resp = new VersionInfoResponse();
|
|
|
|
|
- resp.setId(entity.getId());
|
|
|
|
|
- resp.setJarVersion(entity.getJarVersion());
|
|
|
|
|
- resp.setVueVersion(entity.getVueVersion());
|
|
|
|
|
- resp.setDurationOfUpdate(entity.getDurationOfUpdate());
|
|
|
|
|
- resp.setCreateTime(entity.getCreateTime());
|
|
|
|
|
- resp.setUpdateTime(entity.getUpdateTime());
|
|
|
|
|
- return resp;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 格式化版本号,例如 5.13.0 -> v5A13
|
|
|
|
|
+ */
|
|
|
|
|
+ private String formatVersion(String jarVersion) {
|
|
|
|
|
+ if (jarVersion == null || jarVersion.isEmpty()) {
|
|
|
|
|
+ return "v5A13";
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ String[] parts = jarVersion.split("\\.");
|
|
|
|
|
+ if (parts.length >= 2) {
|
|
|
|
|
+ return "v" + parts[0] + "A" + parts[1];
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("格式化版本号失败:{}", jarVersion, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ return "v" + jarVersion.replace(".", "");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public BackupDbResponse backupDatabase() {
|
|
|
|
|
- // 占位实现:仅返回一个示例结果
|
|
|
|
|
- BackupDbResponse resp = new BackupDbResponse();
|
|
|
|
|
- resp.setFileName("backup_" + LocalDateTime.now().toString().replace(":", "").replace("-", "") + ".sql");
|
|
|
|
|
- resp.setFilePath("/backup/" + resp.getFileName());
|
|
|
|
|
- resp.setFileSize("0MB");
|
|
|
|
|
- return resp;
|
|
|
|
|
|
|
+ public CommonPage<VersionHistoryItem> getVersionHistory(VersionHistoryPageRequest request) {
|
|
|
|
|
+ // 参数校验
|
|
|
|
|
+ if (request.getCurrent() == null || request.getCurrent() < 1) {
|
|
|
|
|
+ request.setCurrent(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request.getSize() == null || request.getSize() < 1) {
|
|
|
|
|
+ request.setSize(10);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建分页查询
|
|
|
|
|
+ Page<SasVersionAdmin> page = new Page<>(request.getCurrent(), request.getSize());
|
|
|
|
|
+ LambdaQueryWrapper<SasVersionAdmin> wrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ wrapper.orderByDesc(SasVersionAdmin::getUpdateTime);
|
|
|
|
|
+
|
|
|
|
|
+ IPage<SasVersionAdmin> resultPage = sasVersionAdminMapper.selectPage(page, wrapper);
|
|
|
|
|
+
|
|
|
|
|
+ List<VersionHistoryItem> items = resultPage.getRecords().stream()
|
|
|
|
|
+ .map(this::convertToVersionHistoryItem)
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ return new CommonPage<>(items, resultPage.getTotal(), resultPage.getCurrent(), resultPage.getSize());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public CommonPage<BackupFileItem> backupList(BackupListPageRequest request) {
|
|
|
|
|
- // 占位实现:返回空列表
|
|
|
|
|
- List<BackupFileItem> list = Collections.emptyList();
|
|
|
|
|
- return new CommonPage<>(list, 0L, request.getCurrent().longValue(), request.getSize().longValue());
|
|
|
|
|
|
|
+ private VersionHistoryItem convertToVersionHistoryItem(SasVersionAdmin entity) {
|
|
|
|
|
+ VersionHistoryItem item = new VersionHistoryItem();
|
|
|
|
|
+ item.setId(entity.getId());
|
|
|
|
|
+ item.setVersion(formatVersion(entity.getJarVersion()));
|
|
|
|
|
+ item.setJarVersion(entity.getJarVersion());
|
|
|
|
|
+ item.setVueVersion(entity.getVueVersion());
|
|
|
|
|
+ item.setDurationOfUpdate(entity.getDurationOfUpdate());
|
|
|
|
|
+ item.setUpgradeTime(entity.getUpdateTime());
|
|
|
|
|
+ item.setReleaseNotes("优化系统性能,修复已知问题");
|
|
|
|
|
+ return item;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public void restoreDatabase(BackupRestoreRequest request) {
|
|
|
|
|
- // 占位实现:不做任何操作
|
|
|
|
|
|
|
+ public void createBackup(BackupRequest request, HttpServletResponse response) {
|
|
|
|
|
+ // 参数校验
|
|
|
|
|
+ if (request.getBackupType() == null || request.getBackupType() < 1 || request.getBackupType() > 3) {
|
|
|
|
|
+ throw new IllegalArgumentException("备份类型无效,必须是 1、2 或 3");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 使用备份工具类执行实际的数据库备份
|
|
|
|
|
+ databaseBackupUtil.backupDatabase(request.getBackupType(), response, null);
|
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
|
+ log.error("备份过程中发生 IO 错误", e);
|
|
|
|
|
+ throw new RuntimeException("备份失败:" + e.getMessage(), e);
|
|
|
|
|
+ } catch (SQLException e) {
|
|
|
|
|
+ log.error("备份过程中发生数据库错误", e);
|
|
|
|
|
+ throw new RuntimeException("备份失败:" + e.getMessage(), e);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("备份失败", e);
|
|
|
|
|
+ throw new RuntimeException("备份失败:" + e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public String downloadBackup(String fileName) {
|
|
|
|
|
- // 占位实现:返回文件的预期路径
|
|
|
|
|
- return "/backup/" + fileName;
|
|
|
|
|
|
|
+ public BackupRestoreResponse restoreSystemData(BackupRestoreRequest request) {
|
|
|
|
|
+ // 参数校验
|
|
|
|
|
+ if (request.getFilePath() == null || request.getFilePath().isEmpty()) {
|
|
|
|
|
+ throw new IllegalArgumentException("备份文件路径不能为空");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ File backupFile = new File(request.getFilePath());
|
|
|
|
|
+ if (!backupFile.exists()) {
|
|
|
|
|
+ throw new IllegalArgumentException("备份文件不存在或已损坏");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LocalDateTime startTime = LocalDateTime.now();
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // TODO: 实现实际的数据库恢复逻辑
|
|
|
|
|
+ log.info("开始恢复系统数据,文件:{}", request.getFilePath());
|
|
|
|
|
+ Thread.sleep(2000); // 模拟 2 秒恢复时间
|
|
|
|
|
+
|
|
|
|
|
+ LocalDateTime endTime = LocalDateTime.now();
|
|
|
|
|
+ String duration = calculateDuration(startTime, endTime);
|
|
|
|
|
+
|
|
|
|
|
+ BackupRestoreResponse response = new BackupRestoreResponse();
|
|
|
|
|
+ response.setFileName(backupFile.getName());
|
|
|
|
|
+ response.setRestoreTime(endTime);
|
|
|
|
|
+ response.setDuration(duration);
|
|
|
|
|
+ response.setNeedRestart(true);
|
|
|
|
|
+
|
|
|
|
|
+ log.info("系统数据恢复成功,耗时:{}", duration);
|
|
|
|
|
+ return response;
|
|
|
|
|
+
|
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
|
|
+ throw new RuntimeException("恢复过程被中断", e);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("恢复系统数据失败", e);
|
|
|
|
|
+ throw new RuntimeException("恢复失败:" + e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 计算持续时间
|
|
|
|
|
+ */
|
|
|
|
|
+ private String calculateDuration(LocalDateTime start, LocalDateTime end) {
|
|
|
|
|
+ long seconds = java.time.Duration.between(start, end).getSeconds();
|
|
|
|
|
+ long minutes = seconds / 60;
|
|
|
|
|
+ seconds = seconds % 60;
|
|
|
|
|
+
|
|
|
|
|
+ if (minutes > 0) {
|
|
|
|
|
+ return minutes + "分" + seconds + "秒";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return seconds + "秒";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|