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