382 lines
19 KiB
Java
382 lines
19 KiB
Java
package com.kaidi.oa.seed;
|
|
|
|
import com.kaidi.oa.domain.ItAsset;
|
|
import com.kaidi.oa.domain.ItAssetEvent;
|
|
import com.kaidi.oa.domain.ItInspection;
|
|
import com.kaidi.oa.domain.ItMonitorItem;
|
|
import com.kaidi.oa.domain.ItNetworkDevice;
|
|
import com.kaidi.oa.domain.ItSecPolicyConfig;
|
|
import com.kaidi.oa.repository.ItAssetEventRepository;
|
|
import com.kaidi.oa.repository.ItAssetRepository;
|
|
import com.kaidi.oa.repository.ItInspectionRepository;
|
|
import com.kaidi.oa.repository.ItMonitorItemRepository;
|
|
import com.kaidi.oa.repository.ItNetworkDeviceRepository;
|
|
import com.kaidi.oa.repository.ItSecPolicyConfigRepository;
|
|
import org.springframework.boot.ApplicationArguments;
|
|
import org.springframework.boot.ApplicationRunner;
|
|
import org.springframework.core.annotation.Order;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.time.Instant;
|
|
import java.time.LocalDate;
|
|
import java.time.ZoneOffset;
|
|
|
|
/**
|
|
* 信息部演示数据Seeder:补全监控项/巡检读数/网络设备/安全策略零数据演示缺口。
|
|
* @Order(204) 在所有主数据Seeder后运行,幂等(count > 0 则跳过)。
|
|
*/
|
|
@Order(204)
|
|
@DemoSeed
|
|
public class ItDeptDemoSeeder implements ApplicationRunner {
|
|
|
|
private final ItMonitorItemRepository monitorRepo;
|
|
private final ItInspectionRepository inspectionRepo;
|
|
private final ItNetworkDeviceRepository networkRepo;
|
|
private final ItSecPolicyConfigRepository policyRepo;
|
|
private final ItAssetRepository assetRepo;
|
|
private final ItAssetEventRepository assetEventRepo;
|
|
|
|
public ItDeptDemoSeeder(ItMonitorItemRepository monitorRepo,
|
|
ItInspectionRepository inspectionRepo,
|
|
ItNetworkDeviceRepository networkRepo,
|
|
ItSecPolicyConfigRepository policyRepo,
|
|
ItAssetRepository assetRepo,
|
|
ItAssetEventRepository assetEventRepo) {
|
|
this.monitorRepo = monitorRepo;
|
|
this.inspectionRepo = inspectionRepo;
|
|
this.networkRepo = networkRepo;
|
|
this.policyRepo = policyRepo;
|
|
this.assetRepo = assetRepo;
|
|
this.assetEventRepo = assetEventRepo;
|
|
}
|
|
|
|
@Override
|
|
public void run(ApplicationArguments args) {
|
|
seedMonitorItems();
|
|
seedNetworkDevices();
|
|
seedSecPolicies();
|
|
seedAssetAmounts();
|
|
seedAssetEvents();
|
|
}
|
|
|
|
// -------- 监控项 + 巡检读数 --------
|
|
|
|
private void seedMonitorItems() {
|
|
if (monitorRepo.count() > 0) return;
|
|
|
|
// ERP应用服务器 CPU
|
|
ItMonitorItem m1 = monitor("ERP应用服务器", "CPU使用率", "%", "above", 75.0, 90.0, "张伟");
|
|
addInspection(m1, 45.2, "正常", false, "张伟", "-3");
|
|
addInspection(m1, 68.5, "正常", false, "张伟", "-2");
|
|
addInspection(m1, 82.1, "告警", true, "张伟", "-1");
|
|
addInspection(m1, 55.3, "正常", false, "张伟", "0");
|
|
|
|
// ERP应用服务器 内存
|
|
ItMonitorItem m2 = monitor("ERP应用服务器", "内存使用率", "%", "above", 80.0, 92.0, "张伟");
|
|
addInspection(m2, 71.0, "正常", false, "系统", "-2");
|
|
addInspection(m2, 88.5, "告警", true, "系统", "-1");
|
|
addInspection(m2, 93.2, "故障", true, "系统", "0");
|
|
|
|
// 数据库主库
|
|
ItMonitorItem m3 = monitor("数据库主库", "磁盘使用率", "%", "above", 70.0, 85.0, "李娜");
|
|
addInspection(m3, 52.3, "正常", false, "李娜", "-5");
|
|
addInspection(m3, 65.7, "正常", false, "李娜", "-2");
|
|
addInspection(m3, 73.4, "告警", true, "李娜", "0");
|
|
|
|
// 数据库连接数
|
|
ItMonitorItem m4 = monitor("数据库主库", "连接数", "个", "above", 150.0, 200.0, "李娜");
|
|
addInspection(m4, 87.0, "正常", false, "李娜", "-3");
|
|
addInspection(m4, 134.0, "正常", false, "李娜", "-1");
|
|
addInspection(m4, 112.0, "正常", false, "李娜", "0");
|
|
|
|
// OA服务响应时间
|
|
ItMonitorItem m5 = monitor("OA应用系统", "响应时间", "ms", "above", 500.0, 2000.0, "陈静");
|
|
addInspection(m5, 235.0, "正常", false, "系统", "-4");
|
|
addInspection(m5, 312.0, "正常", false, "系统", "-2");
|
|
addInspection(m5, 648.0, "告警", true, "系统", "0");
|
|
|
|
// 核心交换机 网络流量
|
|
ItMonitorItem m6 = monitor("核心交换机", "网络流量", "Mbps", "above", 800.0, 950.0, "张伟");
|
|
addInspection(m6, 452.0, "正常", false, "张伟", "-6");
|
|
addInspection(m6, 623.0, "正常", false, "张伟", "-3");
|
|
addInspection(m6, 712.0, "正常", false, "张伟", "0");
|
|
|
|
// 存储阵列 可用空间
|
|
ItMonitorItem m7 = monitor("存储阵列", "可用空间率", "%", "below", 20.0, 10.0, "李娜");
|
|
addInspection(m7, 45.0, "正常", false, "李娜", "-7");
|
|
addInspection(m7, 28.5, "正常", false, "李娜", "-3");
|
|
addInspection(m7, 18.2, "告警", true, "李娜", "0");
|
|
}
|
|
|
|
private ItMonitorItem monitor(String target, String metric, String unit,
|
|
String direction, Double warn, Double crit, String owner) {
|
|
ItMonitorItem m = new ItMonitorItem();
|
|
m.setTarget(target);
|
|
m.setMetric(metric);
|
|
m.setUnit(unit);
|
|
m.setDirection(direction);
|
|
m.setWarnThreshold(warn);
|
|
m.setCritThreshold(crit);
|
|
m.setOwner(owner);
|
|
m.setEnabled(Boolean.TRUE);
|
|
m.setLastStatus("未采集");
|
|
m.setCreatedAt(Instant.now());
|
|
return monitorRepo.save(m);
|
|
}
|
|
|
|
private void addInspection(ItMonitorItem m, double value, String result,
|
|
boolean alerted, String inspector, String daysAgo) {
|
|
int days = Integer.parseInt(daysAgo);
|
|
LocalDate date = LocalDate.now().plusDays(days);
|
|
ItInspection ins = new ItInspection();
|
|
ins.setMonitorItemId(m.getId());
|
|
ins.setTarget(m.getTarget());
|
|
ins.setMetric(m.getMetric());
|
|
ins.setValue(value);
|
|
ins.setResult(result);
|
|
ins.setAlerted(alerted);
|
|
ins.setInspector(inspector);
|
|
ins.setCheckDate(date.toString());
|
|
ins.setCheckedAt(date.atStartOfDay(ZoneOffset.UTC).toInstant());
|
|
ins.setCreatedAt(Instant.now());
|
|
ItInspection saved = inspectionRepo.save(ins);
|
|
// 回写监控项最近状态
|
|
m.setLastValue(value);
|
|
m.setLastStatus(result);
|
|
m.setLastCheckAt(saved.getCheckedAt());
|
|
monitorRepo.save(m);
|
|
}
|
|
|
|
// -------- 网络设备 --------
|
|
|
|
private void seedNetworkDevices() {
|
|
if (networkRepo.count() > 0) return;
|
|
|
|
netdev("深信服AF-2000防火墙", "防火墙", "深信服 AF-2000",
|
|
"192.168.1.1", "全网", "机房A", "V5.5.0.6", "张伟",
|
|
"2025-01-20", "2028-01-20", "VLAN10-管理区/VLAN20-业务区/VLAN30-DMZ区;安全策略48条", "正常", "2026-05-15");
|
|
netdev("华为S5720核心交换机", "交换机", "华为 S5720-52X",
|
|
"192.168.1.2", "VLAN10/20/30/40", "机房A", "V200R020C10", "张伟",
|
|
"2024-06-15", "2027-06-15", "24口PoE+4个SFP+上行口;VLAN间路由已配置", "正常", "2026-05-20");
|
|
netdev("华为S5700接入交换机-1F", "交换机", "华为 S5700-28X",
|
|
"192.168.1.3", "VLAN20/40", "1楼弱电箱", "V200R019C10", "李娜",
|
|
"2024-08-10", "2027-08-10", "负责1楼24个信息点接入", "正常", "2026-04-18");
|
|
netdev("深信服VPN网关", "VPN网关", "深信服 SSL-VPN 2000",
|
|
"192.168.1.4", "VPN-Pool/10.8.0.0/24", "机房B", "V5.2.3", "张伟",
|
|
"2024-12-01", "2027-12-01", "IKEv2 AES-256-GCM/SHA2-256;在线用户峰值50人", "正常", "2026-06-01");
|
|
netdev("深信服IPS-2000入侵防御", "IDS/IPS", "深信服 IPS-2000",
|
|
"192.168.1.5", "旁路检测", "机房A", "IPS-V4.1.2", "张伟",
|
|
"2024-03-15", "2027-03-15", "特征库版本2026.06.01;每日自动更新;高风险告警即时阻断", "正常", "2026-06-01");
|
|
netdev("华为AR路由器", "路由器", "华为 AR3260",
|
|
"10.0.0.1", "外网/内网边界", "机房B", "V200R009C10", "张伟",
|
|
"2024-05-01", "2027-05-01", "双ISP链路,主链路电信100M,备链路联通50M", "正常", "2026-05-28");
|
|
netdev("360天擎防病毒服务器", "防病毒服务器", "360天擎 v4.5",
|
|
"192.168.1.10", "VLAN20/40", "机房A", "V4.5.11.0", "李娜",
|
|
"2023-09-01", "2026-09-01", "病毒库2026-06-15;全网200终端已接入", "正常", "2026-06-15");
|
|
netdev("SANGFOR上网行为管理", "上网行为管理", "深信服 AC-3000",
|
|
"192.168.1.6", "出口前", "机房A", "V12.0.73", "张伟",
|
|
"2023-11-10", "2026-11-10", "违规内容拦截/带宽管理/行为审计;日均报表已启用", "告警", null);
|
|
}
|
|
|
|
private void netdev(String name, String deviceType, String model,
|
|
String ip, String vlan, String location, String firmware,
|
|
String admin, String purchase, String warranty, String note,
|
|
String runStatus, String lastBackup) {
|
|
ItNetworkDevice d = new ItNetworkDevice();
|
|
d.setName(name);
|
|
d.setDeviceType(deviceType);
|
|
d.setModel(model);
|
|
d.setManagementIp(ip);
|
|
d.setVlanSegment(vlan);
|
|
d.setLocation(location);
|
|
d.setFirmwareVersion(firmware);
|
|
d.setAdmin(admin);
|
|
d.setPurchaseDate(purchase);
|
|
d.setWarrantyDate(warranty);
|
|
d.setNote(note);
|
|
d.setRunStatus(runStatus);
|
|
d.setConfigBackupStatus(lastBackup != null ? "已备份" : "未备份");
|
|
d.setLastConfigBackupDate(lastBackup);
|
|
d.setCreatedAt(Instant.now());
|
|
networkRepo.save(d);
|
|
}
|
|
|
|
// -------- 安全策略配置 --------
|
|
|
|
private void seedSecPolicies() {
|
|
if (policyRepo.count() > 0) return;
|
|
|
|
// VPN策略
|
|
policy(null, "深信服VPN网关", "VPN策略", "总部-远程访问VPN",
|
|
"VPN-001", "外网→内网", "任意", "192.168.0.0/16", "TCP/443,UDP/500-4500",
|
|
"允许", 1, "IKEv2/AES-256-GCM/SHA2-256;证书认证;MFA双因子;最大并发500用户");
|
|
policy(null, "深信服VPN网关", "VPN策略", "分公司点对点VPN",
|
|
"VPN-002", "分公司→总部", "10.2.0.0/24", "192.168.0.0/16", "ANY",
|
|
"允许", 2, "分公司岳阳(10.2.0.0/24)通过IPSEC VPN访问总部内网;预共享密钥AES-256");
|
|
|
|
// 防火墙规则
|
|
policy(null, "深信服AF-2000防火墙", "防火墙规则", "拒绝外网访问内网管理口",
|
|
"FW-001", "外网→内网", "ANY", "192.168.1.0/24", "TCP/22,TCP/23,TCP/3389",
|
|
"拒绝", 1, "安全基线:禁止外网直接SSH/Telnet/RDP到内网管理设备");
|
|
policy(null, "深信服AF-2000防火墙", "防火墙规则", "允许内网访问外网HTTP/HTTPS",
|
|
"FW-002", "内网→外网", "192.168.0.0/16", "ANY", "TCP/80,TCP/443",
|
|
"允许", 10, "员工上网;经上网行为管理过滤后允许");
|
|
policy(null, "深信服AF-2000防火墙", "防火墙规则", "DMZ区发布ERP对外服务",
|
|
"FW-003", "外网→DMZ", "ANY", "192.168.30.100", "TCP/443",
|
|
"允许", 5, "ERP系统移动端访问入口;仅开放HTTPS 443端口");
|
|
|
|
// IPS规则
|
|
policy(null, "深信服IPS-2000入侵防御", "IPS规则", "SQL注入攻击拦截",
|
|
"IPS-001", "双向", "ANY", "任意", "TCP/80,TCP/443,TCP/8080",
|
|
"阻断", 1, "特征库SQL注入检测;严格模式;每日告警统计");
|
|
policy(null, "深信服IPS-2000入侵防御", "IPS规则", "暴力破解攻击防护",
|
|
"IPS-002", "入站", "ANY", "任意", "TCP/22,TCP/3389,TCP/8090",
|
|
"阻断", 2, "5次/分钟触发阻断;IP封锁1小时;通知管理员");
|
|
policy(null, "深信服IPS-2000入侵防御", "IPS规则", "Web漏洞利用检测",
|
|
"IPS-003", "入站", "ANY", "任意", "TCP/80,TCP/443",
|
|
"告警", 3, "XSS/文件包含/目录遍历检测;告警模式记录日志");
|
|
|
|
// IDS特征
|
|
policy(null, "深信服IPS-2000入侵防御", "IDS特征", "异常流量基线检测",
|
|
"IDS-001", "双向", "内网", "内网", "ANY",
|
|
"告警", 1, "基于流量基线的异常检测:单IP流量超基线3倍触发告警");
|
|
|
|
// 上网行为
|
|
policy(null, "SANGFOR上网行为管理", "上网行为", "禁止访问非工作网站",
|
|
"AC-001", "内网→外网", "192.168.0.0/16", "ANY", "TCP/80,TCP/443",
|
|
"拒绝", 5, "工作时间(9:00-18:00)拦截娱乐/游戏/社交类网站;白名单放行业务系统");
|
|
policy(null, "SANGFOR上网行为管理", "上网行为", "带宽QoS策略",
|
|
"AC-002", "内网→外网", "192.168.0.0/16", "ANY", "ANY",
|
|
"允许", 10, "业务系统优先级最高;视频流媒体限速2Mbps/人;总出口100M按部门分配");
|
|
}
|
|
|
|
private void policy(Long deviceId, String deviceName, String policyType, String policyName,
|
|
String policyNo, String trafficDir, String srcAddr, String dstAddr,
|
|
String portProto, String policyAction, Integer priority, String remark) {
|
|
ItSecPolicyConfig c = new ItSecPolicyConfig();
|
|
c.setDeviceId(deviceId);
|
|
c.setDeviceName(deviceName);
|
|
c.setPolicyType(policyType);
|
|
c.setPolicyName(policyName);
|
|
c.setPolicyNo(policyNo);
|
|
c.setTrafficDir(trafficDir);
|
|
c.setSrcAddress(srcAddr);
|
|
c.setDstAddress(dstAddr);
|
|
c.setPortProto(portProto);
|
|
c.setPolicyAction(policyAction);
|
|
c.setEnabled(Boolean.TRUE);
|
|
c.setPriority(priority);
|
|
c.setRemark(remark);
|
|
c.setLastSyncDate(LocalDate.now().toString());
|
|
c.setOperator("张伟");
|
|
c.setCreatedAt(Instant.now());
|
|
policyRepo.save(c);
|
|
}
|
|
|
|
// -------- 回填IT资产采购金额(让折旧能算出真实金额)--------
|
|
|
|
private void seedAssetAmounts() {
|
|
// 为现有IT资产补全采购金额、折旧年限,让折旧端点能返回真实金额。
|
|
for (ItAsset a : assetRepo.findAll()) {
|
|
if (a.getPurchaseAmount() != null && a.getPurchaseAmount().compareTo(BigDecimal.ZERO) > 0) {
|
|
continue; // 已有金额跳过
|
|
}
|
|
// 根据类型设置参考采购金额
|
|
BigDecimal amount;
|
|
int depYears;
|
|
int residual;
|
|
switch (a.getCategory() != null ? a.getCategory() : "") {
|
|
case "服务器" -> { amount = new BigDecimal("55000.00"); depYears = 5; residual = 5; }
|
|
case "网络设备" -> { amount = new BigDecimal("18000.00"); depYears = 5; residual = 5; }
|
|
case "终端" -> { amount = new BigDecimal("8500.00"); depYears = 3; residual = 5; }
|
|
case "软件" -> { amount = new BigDecimal("25000.00"); depYears = 3; residual = 0; }
|
|
case "办公设备" -> { amount = new BigDecimal("6500.00"); depYears = 5; residual = 5; }
|
|
default -> { amount = new BigDecimal("5000.00"); depYears = 5; residual = 5; }
|
|
}
|
|
// 根据资产编号微调真实感
|
|
if ("IT-001".equals(a.getAssetNo())) amount = new BigDecimal("62800.00");
|
|
if ("IT-002".equals(a.getAssetNo())) amount = new BigDecimal("128000.00");
|
|
if ("IT-008".equals(a.getAssetNo())) amount = new BigDecimal("180000.00");
|
|
if ("IT-009".equals(a.getAssetNo())) amount = new BigDecimal("68000.00");
|
|
|
|
a.setPurchaseAmount(amount);
|
|
if (a.getDepreciationYears() == null) a.setDepreciationYears(depYears);
|
|
if (a.getResidualRatePct() == null) a.setResidualRatePct(residual);
|
|
if (a.getSerialNo() == null) {
|
|
a.setSerialNo("SN" + a.getAssetNo().replace("-", "") + "2024");
|
|
}
|
|
if (a.getBarcode() == null) {
|
|
a.setBarcode("BC" + a.getAssetNo().replace("-", ""));
|
|
}
|
|
assetRepo.save(a);
|
|
}
|
|
}
|
|
|
|
// -------- 资产生命周期事件演示数据 --------
|
|
|
|
private void seedAssetEvents() {
|
|
if (assetEventRepo.count() > 0) return;
|
|
// 为IT-007 (闲置惠普笔记本) 生成一条历史调拨记录
|
|
for (ItAsset a : assetRepo.findAll()) {
|
|
if (!"IT-007".equals(a.getAssetNo())) continue;
|
|
ItAssetEvent ev = new ItAssetEvent();
|
|
ev.setAssetId(a.getId());
|
|
ev.setAssetNo(a.getAssetNo());
|
|
ev.setAssetName(a.getName());
|
|
ev.setEventType("调拨");
|
|
ev.setEventNo("TR-20250618-0001");
|
|
ev.setFromHolder("设计研究中心");
|
|
ev.setToHolder("");
|
|
ev.setFromLocation("设计室");
|
|
ev.setToLocation("信息部库房");
|
|
ev.setReason("项目结束,设备归还信息部统一管理");
|
|
ev.setOperator("陈静");
|
|
ev.setStatus("已完成");
|
|
ev.setEventDate("2025-06-18");
|
|
ev.setCreatedAt(Instant.now());
|
|
assetEventRepo.save(ev);
|
|
break;
|
|
}
|
|
// 为IT-010 (维修复印机) 生成维修工单
|
|
for (ItAsset a : assetRepo.findAll()) {
|
|
if (!"IT-010".equals(a.getAssetNo())) continue;
|
|
ItAssetEvent ev = new ItAssetEvent();
|
|
ev.setAssetId(a.getId());
|
|
ev.setAssetNo(a.getAssetNo());
|
|
ev.setAssetName(a.getName());
|
|
ev.setEventType("维修");
|
|
ev.setEventNo("WO-20260608-0001");
|
|
ev.setFromHolder("行政部");
|
|
ev.setVendor("佳能维修服务中心(长沙)");
|
|
ev.setReason("定影器故障,打印出现竖向条纹");
|
|
ev.setExpectedReturnDate("2026-06-20");
|
|
ev.setOperator("李娜");
|
|
ev.setStatus("处理中");
|
|
ev.setEventDate("2026-06-08");
|
|
ev.setCreatedAt(Instant.now());
|
|
assetEventRepo.save(ev);
|
|
break;
|
|
}
|
|
// 为IT-011 (已报废爱普生投影仪) 生成报废记录
|
|
for (ItAsset a : assetRepo.findAll()) {
|
|
if (!"IT-011".equals(a.getAssetNo())) continue;
|
|
ItAssetEvent ev = new ItAssetEvent();
|
|
ev.setAssetId(a.getId());
|
|
ev.setAssetNo(a.getAssetNo());
|
|
ev.setAssetName(a.getName());
|
|
ev.setEventType("报废");
|
|
ev.setEventNo("SC-20260101-0001");
|
|
ev.setFromHolder("行政部");
|
|
ev.setReason("灯泡寿命耗尽,维修费用超过设备残值,申请报废");
|
|
ev.setOperator("陈静");
|
|
ev.setStatus("已完成");
|
|
ev.setResult("报废处置");
|
|
ev.setCompletedDate("2026-01-05");
|
|
ev.setEventDate("2026-01-02");
|
|
ev.setCreatedAt(Instant.now());
|
|
assetEventRepo.save(ev);
|
|
break;
|
|
}
|
|
}
|
|
}
|