3365 lines
190 KiB
Java
3365 lines
190 KiB
Java
package com.kaidi.oa.seed;
|
|
|
|
import com.kaidi.oa.common.Money;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.kaidi.oa.common.PasswordUtil;
|
|
import com.kaidi.oa.domain.Announcement;
|
|
import com.kaidi.oa.domain.Archive;
|
|
import com.kaidi.oa.domain.ArchiveComment;
|
|
import com.kaidi.oa.domain.BankAccount;
|
|
import com.kaidi.oa.domain.Bid;
|
|
import com.kaidi.oa.domain.BomItem;
|
|
import com.kaidi.oa.domain.Budget;
|
|
import com.kaidi.oa.domain.Certification;
|
|
import com.kaidi.oa.domain.CollabDoc;
|
|
import com.kaidi.oa.domain.CompanySubject;
|
|
import com.kaidi.oa.domain.Contract;
|
|
import com.kaidi.oa.domain.CrawlJob;
|
|
import com.kaidi.oa.domain.CrawlSource;
|
|
import com.kaidi.oa.domain.ContractChange;
|
|
import com.kaidi.oa.domain.ContractTemplate;
|
|
import com.kaidi.oa.domain.CostCenter;
|
|
import com.kaidi.oa.domain.Declaration;
|
|
import com.kaidi.oa.domain.DeclarationStep;
|
|
import com.kaidi.oa.domain.DeclarationTemplate;
|
|
import com.kaidi.oa.domain.Expert;
|
|
import com.kaidi.oa.domain.Handover;
|
|
import com.kaidi.oa.domain.RdExpense;
|
|
import com.kaidi.oa.domain.ContractMilestone;
|
|
import com.kaidi.oa.domain.Customer;
|
|
import com.kaidi.oa.domain.Discussion;
|
|
import com.kaidi.oa.domain.DocFile;
|
|
import com.kaidi.oa.domain.DocFolder;
|
|
import com.kaidi.oa.domain.FlowTask;
|
|
import com.kaidi.oa.domain.FlowTrace;
|
|
import com.kaidi.oa.domain.FormInstance;
|
|
import com.kaidi.oa.domain.FormTemplate;
|
|
import com.kaidi.oa.domain.HealthRecord;
|
|
import com.kaidi.oa.domain.Intel;
|
|
import com.kaidi.oa.domain.Invoice;
|
|
import com.kaidi.oa.domain.LeaderTrip;
|
|
import com.kaidi.oa.domain.Meeting;
|
|
import com.kaidi.oa.domain.MeetingMinute;
|
|
import com.kaidi.oa.domain.MeetingRoom;
|
|
import com.kaidi.oa.domain.Opportunity;
|
|
import com.kaidi.oa.domain.OpportunityFollowup;
|
|
import com.kaidi.oa.domain.Patent;
|
|
import com.kaidi.oa.domain.Payment;
|
|
import com.kaidi.oa.domain.PersonnelCert;
|
|
import com.kaidi.oa.domain.PriceItem;
|
|
import com.kaidi.oa.domain.Project;
|
|
import com.kaidi.oa.domain.QmsRecord;
|
|
import com.kaidi.oa.domain.ProjectTask;
|
|
import com.kaidi.oa.domain.RdProject;
|
|
import com.kaidi.oa.domain.SafetyCheck;
|
|
import com.kaidi.oa.domain.ScheduleEvent;
|
|
import com.kaidi.oa.domain.Seal;
|
|
import com.kaidi.oa.domain.SealUse;
|
|
import com.kaidi.oa.domain.Supplier;
|
|
import com.kaidi.oa.domain.Survey;
|
|
import com.kaidi.oa.domain.SysDept;
|
|
import com.kaidi.oa.domain.SysRole;
|
|
import com.kaidi.oa.domain.SysUser;
|
|
import com.kaidi.oa.domain.SysUserRole;
|
|
import com.kaidi.oa.domain.WorkPlan;
|
|
import com.kaidi.oa.domain.WastewaterClient;
|
|
import com.kaidi.oa.domain.WaterQualityRecord;
|
|
import com.kaidi.oa.domain.WorkOrder;
|
|
import com.kaidi.oa.domain.InventoryItem;
|
|
import com.kaidi.oa.domain.Account;
|
|
import com.kaidi.oa.domain.Voucher;
|
|
import com.kaidi.oa.domain.LabSample;
|
|
import com.kaidi.oa.domain.LabInstrument;
|
|
import com.kaidi.oa.domain.DesignDoc;
|
|
import com.kaidi.oa.domain.DesignChange;
|
|
import com.kaidi.oa.domain.SupervisionLog;
|
|
import com.kaidi.oa.domain.AuditProject;
|
|
import com.kaidi.oa.domain.ItAsset;
|
|
import com.kaidi.oa.repository.AnnouncementRepository;
|
|
import com.kaidi.oa.repository.ArchiveRepository;
|
|
import com.kaidi.oa.repository.ArchiveCommentRepository;
|
|
import com.kaidi.oa.repository.BankAccountRepository;
|
|
import com.kaidi.oa.repository.BidRepository;
|
|
import com.kaidi.oa.repository.BomItemRepository;
|
|
import com.kaidi.oa.repository.BudgetRepository;
|
|
import com.kaidi.oa.repository.CertificationRepository;
|
|
import com.kaidi.oa.repository.CollabDocRepository;
|
|
import com.kaidi.oa.repository.CompanySubjectRepository;
|
|
import com.kaidi.oa.repository.ContractChangeRepository;
|
|
import com.kaidi.oa.repository.ContractMilestoneRepository;
|
|
import com.kaidi.oa.repository.ContractRepository;
|
|
import com.kaidi.oa.repository.ContractTemplateRepository;
|
|
import com.kaidi.oa.repository.CostCenterRepository;
|
|
import com.kaidi.oa.repository.CrawlJobRepository;
|
|
import com.kaidi.oa.repository.CrawlSourceRepository;
|
|
import com.kaidi.oa.repository.CustomerRepository;
|
|
import com.kaidi.oa.repository.DeclarationRepository;
|
|
import com.kaidi.oa.repository.DeclarationStepRepository;
|
|
import com.kaidi.oa.repository.DeclarationTemplateRepository;
|
|
import com.kaidi.oa.repository.ExpertRepository;
|
|
import com.kaidi.oa.repository.HandoverRepository;
|
|
import com.kaidi.oa.repository.RdExpenseRepository;
|
|
import com.kaidi.oa.repository.DiscussionRepository;
|
|
import com.kaidi.oa.repository.DocFileRepository;
|
|
import com.kaidi.oa.repository.DocFolderRepository;
|
|
import com.kaidi.oa.repository.FlowTaskRepository;
|
|
import com.kaidi.oa.repository.FlowTraceRepository;
|
|
import com.kaidi.oa.repository.FormInstanceRepository;
|
|
import com.kaidi.oa.repository.FormTemplateRepository;
|
|
import com.kaidi.oa.repository.HealthRecordRepository;
|
|
import com.kaidi.oa.repository.IntelRepository;
|
|
import com.kaidi.oa.repository.InvoiceRepository;
|
|
import com.kaidi.oa.repository.LeaderTripRepository;
|
|
import com.kaidi.oa.repository.MeetingMinuteRepository;
|
|
import com.kaidi.oa.repository.MeetingRepository;
|
|
import com.kaidi.oa.repository.MeetingRoomRepository;
|
|
import com.kaidi.oa.repository.OpportunityFollowupRepository;
|
|
import com.kaidi.oa.repository.OpportunityRepository;
|
|
import com.kaidi.oa.repository.PatentRepository;
|
|
import com.kaidi.oa.repository.PaymentRepository;
|
|
import com.kaidi.oa.repository.PersonnelCertRepository;
|
|
import com.kaidi.oa.repository.PriceItemRepository;
|
|
import com.kaidi.oa.repository.ProjectRepository;
|
|
import com.kaidi.oa.repository.ProjectTaskRepository;
|
|
import com.kaidi.oa.repository.QmsRecordRepository;
|
|
import com.kaidi.oa.repository.RdProjectRepository;
|
|
import com.kaidi.oa.repository.SafetyCheckRepository;
|
|
import com.kaidi.oa.repository.ScheduleEventRepository;
|
|
import com.kaidi.oa.repository.SealRepository;
|
|
import com.kaidi.oa.repository.SealUseRepository;
|
|
import com.kaidi.oa.repository.SupplierRepository;
|
|
import com.kaidi.oa.repository.SurveyRepository;
|
|
import com.kaidi.oa.repository.SysDeptRepository;
|
|
import com.kaidi.oa.repository.SysRoleRepository;
|
|
import com.kaidi.oa.repository.SysUserRepository;
|
|
import com.kaidi.oa.repository.SysUserRoleRepository;
|
|
import com.kaidi.oa.repository.WorkPlanRepository;
|
|
import com.kaidi.oa.repository.WastewaterClientRepository;
|
|
import com.kaidi.oa.repository.WaterQualityRecordRepository;
|
|
import com.kaidi.oa.repository.WorkOrderRepository;
|
|
import com.kaidi.oa.repository.InventoryItemRepository;
|
|
import com.kaidi.oa.repository.AccountRepository;
|
|
import com.kaidi.oa.repository.VoucherRepository;
|
|
import com.kaidi.oa.repository.LabSampleRepository;
|
|
import com.kaidi.oa.repository.LabInstrumentRepository;
|
|
import com.kaidi.oa.repository.DesignDocRepository;
|
|
import com.kaidi.oa.repository.DesignChangeRepository;
|
|
import com.kaidi.oa.repository.SupervisionLogRepository;
|
|
import com.kaidi.oa.repository.AuditProjectRepository;
|
|
import com.kaidi.oa.repository.ItAssetRepository;
|
|
import com.kaidi.oa.domain.InventoryValuationConfig;
|
|
import com.kaidi.oa.domain.CostAdjustLog;
|
|
import com.kaidi.oa.repository.InventoryValuationConfigRepository;
|
|
import com.kaidi.oa.repository.CostAdjustLogRepository;
|
|
import com.kaidi.oa.service.WorkflowService;
|
|
import com.kaidi.oa.service.WorkflowService.ChainNode;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.boot.CommandLineRunner;
|
|
import org.springframework.core.annotation.Order;
|
|
|
|
import java.time.Duration;
|
|
import java.time.Instant;
|
|
import java.time.temporal.ChronoUnit;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Seeds demonstration data on first startup (runs only when the relevant tables
|
|
* are empty). Ports the frontend template catalog and a representative set of
|
|
* in-flight form instances, plus org/users/roles, meetings, documents,
|
|
* announcements and schedule events.
|
|
*/
|
|
@DemoSeed
|
|
@Order(1)
|
|
public class DataSeeder implements CommandLineRunner {
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(DataSeeder.class);
|
|
|
|
private static final String CURRENT_USER = "我(当前用户)";
|
|
|
|
private final SysDeptRepository deptRepo;
|
|
private final SysUserRepository userRepo;
|
|
private final SysRoleRepository roleRepo;
|
|
private final SysUserRoleRepository userRoleRepo;
|
|
private final FormTemplateRepository templateRepo;
|
|
private final FormInstanceRepository instanceRepo;
|
|
private final FlowTraceRepository traceRepo;
|
|
private final FlowTaskRepository taskRepo;
|
|
private final DocFolderRepository folderRepo;
|
|
private final DocFileRepository fileRepo;
|
|
private final MeetingRepository meetingRepo;
|
|
private final MeetingRoomRepository roomRepo;
|
|
private final MeetingMinuteRepository minuteRepo;
|
|
private final ScheduleEventRepository scheduleRepo;
|
|
private final AnnouncementRepository announcementRepo;
|
|
private final ProjectRepository projectRepo;
|
|
private final ProjectTaskRepository projectTaskRepo;
|
|
private final WorkPlanRepository workPlanRepo;
|
|
private final CollabDocRepository collabDocRepo;
|
|
private final DiscussionRepository discussionRepo;
|
|
private final SurveyRepository surveyRepo;
|
|
private final LeaderTripRepository leaderTripRepo;
|
|
private final CompanySubjectRepository companySubjectRepo;
|
|
private final ContractRepository contractRepo;
|
|
private final ContractMilestoneRepository contractMilestoneRepo;
|
|
private final ContractTemplateRepository contractTemplateRepo;
|
|
private final ContractChangeRepository contractChangeRepo;
|
|
private final SupplierRepository supplierRepo;
|
|
private final CustomerRepository customerRepo;
|
|
private final BankAccountRepository bankAccountRepo;
|
|
private final SealRepository sealRepo;
|
|
private final SealUseRepository sealUseRepo;
|
|
private final InvoiceRepository invoiceRepo;
|
|
private final PaymentRepository paymentRepo;
|
|
private final ArchiveRepository archiveRepo;
|
|
private final ArchiveCommentRepository archiveCommentRepo;
|
|
private final OpportunityRepository opportunityRepo;
|
|
private final OpportunityFollowupRepository opportunityFollowupRepo;
|
|
private final SafetyCheckRepository safetyCheckRepo;
|
|
private final CertificationRepository certificationRepo;
|
|
private final BudgetRepository budgetRepo;
|
|
private final BidRepository bidRepo;
|
|
private final IntelRepository intelRepo;
|
|
private final RdProjectRepository rdProjectRepo;
|
|
private final PatentRepository patentRepo;
|
|
private final DeclarationRepository declarationRepo;
|
|
private final DeclarationTemplateRepository declarationTemplateRepo;
|
|
private final RdExpenseRepository rdExpenseRepo;
|
|
private final CostCenterRepository costCenterRepo;
|
|
private final PriceItemRepository priceItemRepo;
|
|
private final PersonnelCertRepository personnelCertRepo;
|
|
private final CrawlSourceRepository crawlSourceRepo;
|
|
private final CrawlJobRepository crawlJobRepo;
|
|
private final BomItemRepository bomItemRepo;
|
|
private final HealthRecordRepository healthRecordRepo;
|
|
private final QmsRecordRepository qmsRecordRepo;
|
|
private final WastewaterClientRepository wastewaterClientRepo;
|
|
private final WaterQualityRecordRepository waterQualityRecordRepo;
|
|
private final WorkOrderRepository workOrderRepo;
|
|
private final InventoryItemRepository inventoryItemRepo;
|
|
private final AccountRepository accountRepo;
|
|
private final VoucherRepository voucherRepo;
|
|
private final LabSampleRepository labSampleRepo;
|
|
private final LabInstrumentRepository labInstrumentRepo;
|
|
private final DesignDocRepository designDocRepo;
|
|
private final DesignChangeRepository designChangeRepo;
|
|
private final SupervisionLogRepository supervisionLogRepo;
|
|
private final AuditProjectRepository auditProjectRepo;
|
|
private final ItAssetRepository itAssetRepo;
|
|
private final HandoverRepository handoverRepo;
|
|
private final DeclarationStepRepository declarationStepRepo;
|
|
private final ExpertRepository expertRepo;
|
|
private final InventoryValuationConfigRepository inventoryValuationConfigRepo;
|
|
private final CostAdjustLogRepository costAdjustLogRepo;
|
|
private final WorkflowService workflowService;
|
|
private final ObjectMapper objectMapper;
|
|
|
|
public DataSeeder(SysDeptRepository deptRepo, SysUserRepository userRepo, SysRoleRepository roleRepo,
|
|
SysUserRoleRepository userRoleRepo, FormTemplateRepository templateRepo,
|
|
FormInstanceRepository instanceRepo, FlowTraceRepository traceRepo,
|
|
FlowTaskRepository taskRepo, DocFolderRepository folderRepo, DocFileRepository fileRepo,
|
|
MeetingRepository meetingRepo, MeetingRoomRepository roomRepo,
|
|
MeetingMinuteRepository minuteRepo, ScheduleEventRepository scheduleRepo,
|
|
AnnouncementRepository announcementRepo, ProjectRepository projectRepo,
|
|
ProjectTaskRepository projectTaskRepo, WorkPlanRepository workPlanRepo,
|
|
CollabDocRepository collabDocRepo, DiscussionRepository discussionRepo,
|
|
SurveyRepository surveyRepo, LeaderTripRepository leaderTripRepo,
|
|
CompanySubjectRepository companySubjectRepo, ContractRepository contractRepo,
|
|
ContractMilestoneRepository contractMilestoneRepo,
|
|
ContractTemplateRepository contractTemplateRepo,
|
|
ContractChangeRepository contractChangeRepo,
|
|
SupplierRepository supplierRepo, CustomerRepository customerRepo,
|
|
BankAccountRepository bankAccountRepo, SealRepository sealRepo,
|
|
SealUseRepository sealUseRepo, InvoiceRepository invoiceRepo,
|
|
PaymentRepository paymentRepo, ArchiveRepository archiveRepo,
|
|
ArchiveCommentRepository archiveCommentRepo,
|
|
OpportunityRepository opportunityRepo,
|
|
OpportunityFollowupRepository opportunityFollowupRepo,
|
|
SafetyCheckRepository safetyCheckRepo,
|
|
CertificationRepository certificationRepo,
|
|
BudgetRepository budgetRepo,
|
|
BidRepository bidRepo,
|
|
IntelRepository intelRepo,
|
|
RdProjectRepository rdProjectRepo,
|
|
PatentRepository patentRepo,
|
|
DeclarationRepository declarationRepo,
|
|
DeclarationTemplateRepository declarationTemplateRepo,
|
|
RdExpenseRepository rdExpenseRepo,
|
|
CostCenterRepository costCenterRepo,
|
|
PriceItemRepository priceItemRepo,
|
|
PersonnelCertRepository personnelCertRepo,
|
|
CrawlSourceRepository crawlSourceRepo,
|
|
CrawlJobRepository crawlJobRepo,
|
|
BomItemRepository bomItemRepo,
|
|
HealthRecordRepository healthRecordRepo,
|
|
QmsRecordRepository qmsRecordRepo,
|
|
WastewaterClientRepository wastewaterClientRepo,
|
|
WaterQualityRecordRepository waterQualityRecordRepo,
|
|
WorkOrderRepository workOrderRepo,
|
|
InventoryItemRepository inventoryItemRepo,
|
|
AccountRepository accountRepo,
|
|
VoucherRepository voucherRepo,
|
|
LabSampleRepository labSampleRepo,
|
|
LabInstrumentRepository labInstrumentRepo,
|
|
DesignDocRepository designDocRepo,
|
|
DesignChangeRepository designChangeRepo,
|
|
SupervisionLogRepository supervisionLogRepo,
|
|
AuditProjectRepository auditProjectRepo,
|
|
ItAssetRepository itAssetRepo,
|
|
HandoverRepository handoverRepo,
|
|
DeclarationStepRepository declarationStepRepo,
|
|
ExpertRepository expertRepo,
|
|
InventoryValuationConfigRepository inventoryValuationConfigRepo,
|
|
CostAdjustLogRepository costAdjustLogRepo,
|
|
WorkflowService workflowService, ObjectMapper objectMapper) {
|
|
this.deptRepo = deptRepo;
|
|
this.userRepo = userRepo;
|
|
this.roleRepo = roleRepo;
|
|
this.userRoleRepo = userRoleRepo;
|
|
this.templateRepo = templateRepo;
|
|
this.instanceRepo = instanceRepo;
|
|
this.traceRepo = traceRepo;
|
|
this.taskRepo = taskRepo;
|
|
this.folderRepo = folderRepo;
|
|
this.fileRepo = fileRepo;
|
|
this.meetingRepo = meetingRepo;
|
|
this.roomRepo = roomRepo;
|
|
this.minuteRepo = minuteRepo;
|
|
this.scheduleRepo = scheduleRepo;
|
|
this.announcementRepo = announcementRepo;
|
|
this.projectRepo = projectRepo;
|
|
this.projectTaskRepo = projectTaskRepo;
|
|
this.workPlanRepo = workPlanRepo;
|
|
this.collabDocRepo = collabDocRepo;
|
|
this.discussionRepo = discussionRepo;
|
|
this.surveyRepo = surveyRepo;
|
|
this.leaderTripRepo = leaderTripRepo;
|
|
this.companySubjectRepo = companySubjectRepo;
|
|
this.contractRepo = contractRepo;
|
|
this.contractMilestoneRepo = contractMilestoneRepo;
|
|
this.contractTemplateRepo = contractTemplateRepo;
|
|
this.contractChangeRepo = contractChangeRepo;
|
|
this.supplierRepo = supplierRepo;
|
|
this.customerRepo = customerRepo;
|
|
this.bankAccountRepo = bankAccountRepo;
|
|
this.sealRepo = sealRepo;
|
|
this.sealUseRepo = sealUseRepo;
|
|
this.invoiceRepo = invoiceRepo;
|
|
this.paymentRepo = paymentRepo;
|
|
this.archiveRepo = archiveRepo;
|
|
this.archiveCommentRepo = archiveCommentRepo;
|
|
this.opportunityRepo = opportunityRepo;
|
|
this.opportunityFollowupRepo = opportunityFollowupRepo;
|
|
this.safetyCheckRepo = safetyCheckRepo;
|
|
this.certificationRepo = certificationRepo;
|
|
this.budgetRepo = budgetRepo;
|
|
this.bidRepo = bidRepo;
|
|
this.intelRepo = intelRepo;
|
|
this.rdProjectRepo = rdProjectRepo;
|
|
this.patentRepo = patentRepo;
|
|
this.declarationRepo = declarationRepo;
|
|
this.declarationTemplateRepo = declarationTemplateRepo;
|
|
this.rdExpenseRepo = rdExpenseRepo;
|
|
this.costCenterRepo = costCenterRepo;
|
|
this.priceItemRepo = priceItemRepo;
|
|
this.personnelCertRepo = personnelCertRepo;
|
|
this.crawlSourceRepo = crawlSourceRepo;
|
|
this.crawlJobRepo = crawlJobRepo;
|
|
this.bomItemRepo = bomItemRepo;
|
|
this.healthRecordRepo = healthRecordRepo;
|
|
this.qmsRecordRepo = qmsRecordRepo;
|
|
this.wastewaterClientRepo = wastewaterClientRepo;
|
|
this.waterQualityRecordRepo = waterQualityRecordRepo;
|
|
this.workOrderRepo = workOrderRepo;
|
|
this.inventoryItemRepo = inventoryItemRepo;
|
|
this.accountRepo = accountRepo;
|
|
this.voucherRepo = voucherRepo;
|
|
this.labSampleRepo = labSampleRepo;
|
|
this.labInstrumentRepo = labInstrumentRepo;
|
|
this.designDocRepo = designDocRepo;
|
|
this.designChangeRepo = designChangeRepo;
|
|
this.supervisionLogRepo = supervisionLogRepo;
|
|
this.auditProjectRepo = auditProjectRepo;
|
|
this.itAssetRepo = itAssetRepo;
|
|
this.handoverRepo = handoverRepo;
|
|
this.declarationStepRepo = declarationStepRepo;
|
|
this.expertRepo = expertRepo;
|
|
this.inventoryValuationConfigRepo = inventoryValuationConfigRepo;
|
|
this.costAdjustLogRepo = costAdjustLogRepo;
|
|
this.workflowService = workflowService;
|
|
this.objectMapper = objectMapper;
|
|
}
|
|
|
|
@Override
|
|
public void run(String... args) {
|
|
if (templateRepo.count() > 0 || userRepo.count() > 0) {
|
|
log.info("Seed data already present; skipping seeding.");
|
|
return;
|
|
}
|
|
log.info("Seeding OA demonstration data...");
|
|
seedOrg();
|
|
seedTemplates();
|
|
seedInstances();
|
|
seedDocuments();
|
|
seedMeetings();
|
|
seedSchedule();
|
|
seedAnnouncements();
|
|
seedProjects();
|
|
seedWorkPlans();
|
|
seedCollabDocs();
|
|
seedDiscussions();
|
|
seedSurveys();
|
|
seedLeaderTrips();
|
|
seedMasterData();
|
|
log.info("Seeding complete: {} templates, {} instances.",
|
|
templateRepo.count(), instanceRepo.count());
|
|
}
|
|
|
|
// ----- org / users / roles -----
|
|
|
|
private void seedOrg() {
|
|
SysDept root = dept("开迪集团", null, 1);
|
|
SysDept admin = dept("行政部", root.getId(), 3);
|
|
SysDept it = dept("信息中心", root.getId(), 4);
|
|
dept("采购部", root.getId(), 5);
|
|
|
|
// Two-level org expansion (Request.MD 2): 11 first-level centers under
|
|
// the group root, each carrying 1-3 second-level units.
|
|
SysDept market = dept("市场部", root.getId(), 6);
|
|
dept("经营部", market.getId(), 1);
|
|
dept("招投标部", market.getId(), 2);
|
|
dept("办事处管理", market.getId(), 3);
|
|
|
|
SysDept engMgmt = dept("工程管理中心", root.getId(), 7);
|
|
dept("项目管理部", engMgmt.getId(), 1);
|
|
dept("工程监理部", engMgmt.getId(), 2);
|
|
// Request.MD 2 (a): missing second-level units under engineering center.
|
|
dept("质安部", engMgmt.getId(), 3);
|
|
dept("专利工法办", engMgmt.getId(), 4);
|
|
|
|
SysDept rdCenter = dept("创新研发中心", root.getId(), 8);
|
|
dept("研发项目部", rdCenter.getId(), 1);
|
|
dept("知识产权部", rdCenter.getId(), 2);
|
|
|
|
// Request.MD 2 (c): design research center second-level units renamed.
|
|
SysDept designCenter = dept("设计研究中心", root.getId(), 9);
|
|
dept("咨询可研院", designCenter.getId(), 1);
|
|
dept("规划设计部", designCenter.getId(), 2);
|
|
|
|
SysDept mfgCenter = dept("制造管理中心", root.getId(), 10);
|
|
dept("生物质肥料制造中心", mfgCenter.getId(), 1);
|
|
dept("水处理药剂制造中心", mfgCenter.getId(), 2);
|
|
|
|
// Request.MD 2 (d): operation management center second-level units renamed.
|
|
SysDept opsCenter = dept("运营管理中心", root.getId(), 11);
|
|
dept("城镇污水运营中心", opsCenter.getId(), 1);
|
|
dept("工业废水运营中心", opsCenter.getId(), 2);
|
|
|
|
SysDept payCenter = dept("支付中心", root.getId(), 12);
|
|
dept("资金结算部", payCenter.getId(), 1);
|
|
dept("票据管理部", payCenter.getId(), 2);
|
|
// Request.MD 2 (b): finance department moved from top level under pay
|
|
// center; (a): cost control department added under pay center.
|
|
SysDept fin = dept("财务部", payCenter.getId(), 3);
|
|
dept("成本控制部", payCenter.getId(), 4);
|
|
|
|
SysDept internalControl = dept("内控部", root.getId(), 13);
|
|
dept("法务风险部", internalControl.getId(), 1);
|
|
dept("审计监察部", internalControl.getId(), 2);
|
|
|
|
SysDept adminOffice = dept("行政办公", root.getId(), 14);
|
|
dept("综合部", adminOffice.getId(), 1);
|
|
dept("后勤部", adminOffice.getId(), 2);
|
|
dept("信息部", adminOffice.getId(), 3);
|
|
dept("档案室", adminOffice.getId(), 4);
|
|
// Request.MD 2 (a): archives reading room added under admin office.
|
|
dept("资料室", adminOffice.getId(), 5);
|
|
|
|
SysDept brand = dept("品牌推广", root.getId(), 15);
|
|
dept("品牌策划部", brand.getId(), 1);
|
|
dept("媒体运营部", brand.getId(), 2);
|
|
|
|
SysDept dataCenter = dept("数据中心", root.getId(), 16);
|
|
dept("统一数据库", dataCenter.getId(), 1);
|
|
dept("情报采集", dataCenter.getId(), 2);
|
|
dept("数据分析", dataCenter.getId(), 3);
|
|
|
|
SysRole adminRole = role("系统管理员", "ADMIN");
|
|
SysRole userRole = role("普通用户", "USER");
|
|
SysRole approverRole = role("审批人", "APPROVER");
|
|
|
|
SysUser adminUser = user("admin", "系统管理员", it.getId(), "信息中心主任",
|
|
"13800000000", "admin@kaidi.com");
|
|
SysUser u1 = user("zhangwei", "张伟", fin.getId(), "财务部经理", "13800000001", "zhangwei@kaidi.com");
|
|
SysUser u2 = user("lina", "李娜", admin.getId(), "行政主管", "13800000002", "lina@kaidi.com");
|
|
SysUser u3 = user("wangfang", "王芳", it.getId(), "软件工程师", "13800000003", "wangfang@kaidi.com");
|
|
SysUser u4 = user("liuyang", "刘洋", fin.getId(), "会计", "13800000004", "liuyang@kaidi.com");
|
|
SysUser u5 = user("chenjing", "陈静", admin.getId(), "人事专员", "13800000005", "chenjing@kaidi.com");
|
|
|
|
link(adminUser.getId(), adminRole.getId());
|
|
link(u1.getId(), approverRole.getId());
|
|
link(u2.getId(), approverRole.getId());
|
|
link(u3.getId(), userRole.getId());
|
|
link(u4.getId(), userRole.getId());
|
|
link(u5.getId(), userRole.getId());
|
|
}
|
|
|
|
private SysDept dept(String name, Long parentId, int sortNo) {
|
|
SysDept d = new SysDept();
|
|
d.setName(name);
|
|
d.setParentId(parentId);
|
|
d.setSortNo(sortNo);
|
|
return deptRepo.save(d);
|
|
}
|
|
|
|
private SysRole role(String name, String code) {
|
|
SysRole r = new SysRole();
|
|
r.setName(name);
|
|
r.setCode(code);
|
|
return roleRepo.save(r);
|
|
}
|
|
|
|
private SysUser user(String loginName, String displayName, Long deptId, String title,
|
|
String phone, String email) {
|
|
SysUser u = new SysUser();
|
|
u.setLoginName(loginName);
|
|
u.setDisplayName(displayName);
|
|
u.setDeptId(deptId);
|
|
u.setTitle(title);
|
|
u.setPhone(phone);
|
|
u.setEmail(email);
|
|
u.setPassword(PasswordUtil.hash("123456"));
|
|
u.setEnabled(true);
|
|
return userRepo.save(u);
|
|
}
|
|
|
|
private void link(Long userId, Long roleId) {
|
|
userRoleRepo.save(new SysUserRole(userId, roleId));
|
|
}
|
|
|
|
// ----- form templates -----
|
|
|
|
private void seedTemplates() {
|
|
TemplateSeedData seed = new TemplateSeedData(objectMapper);
|
|
templateRepo.saveAll(seed.all());
|
|
}
|
|
|
|
// ----- form instances (mirror frontend seedDemoItems) -----
|
|
|
|
private void seedInstances() {
|
|
// In-flight items (待办 / 办理中 / 已退回).
|
|
seedInstance("baohan-payment", "关于投标保函付款的申请",
|
|
"{\"applicant\":\"我(当前用户)\",\"payType\":\"投标保函\",\"payUnit\":\"中国建设银行\",\"projectName\":\"滨江路桥工程\",\"payReason\":\"投标保函付款\"}",
|
|
0, CURRENT_USER, 2, false, false);
|
|
seedInstance("expense-reimburse", "市场部第二季度推广费用报销",
|
|
"{\"applicant\":\"我(当前用户)\",\"reimburseDept\":\"市场部\",\"expenseType\":\"差旅费\",\"amount\":12800}",
|
|
1, CURRENT_USER, 4, false, false);
|
|
seedInstance("leave-apply", "王芳的年假申请",
|
|
"{\"applicant\":\"王芳\",\"leaveType\":\"年假\",\"reason\":\"回乡探亲\"}",
|
|
0, "王芳", 1, false, false);
|
|
seedInstance("purchase-contract", "采购部办公设备采购合同会签",
|
|
"{\"title\":\"采购部办公设备采购合同会签\"}",
|
|
1, CURRENT_USER, 5, false, false);
|
|
seedInstance("seal-apply", "法务部对外合同用印申请",
|
|
"{\"applicant\":\"我(当前用户)\",\"sealType\":\"合同章\",\"copies\":2,\"docName\":\"战略合作框架协议\",\"reason\":\"对外签约用印\"}",
|
|
0, CURRENT_USER, 1, false, false);
|
|
seedInstance("business-trip", "研发部赴上海出差申请",
|
|
"{\"title\":\"研发部赴上海出差申请\"}",
|
|
0, "刘洋", 2, false, false);
|
|
seedInstance("payment-apply", "供应商货款付款申请",
|
|
"{\"title\":\"供应商货款付款申请\"}",
|
|
2, CURRENT_USER, 6, false, false);
|
|
seedInstance("overtime-apply", "陈静的周末加班申请",
|
|
"{\"title\":\"陈静的周末加班申请\"}",
|
|
0, "陈静", 1, false, false);
|
|
seedInstance("supplier-access", "新供应商资质准入会签",
|
|
"{\"title\":\"新供应商资质准入会签\"}",
|
|
1, CURRENT_USER, 3, false, false);
|
|
seedInstance("general-collab", "关于完善信息安全制度的请示",
|
|
"{\"title\":\"关于完善信息安全制度的请示\",\"applicant\":\"我(当前用户)\",\"content\":\"建议完善信息安全管理制度。\"}",
|
|
0, CURRENT_USER, 1, false, true);
|
|
|
|
// Finished items (已办结).
|
|
seedInstance("leave-apply", "我的事假申请",
|
|
"{\"applicant\":\"我(当前用户)\",\"leaveType\":\"事假\",\"reason\":\"处理家庭事务\"}",
|
|
0, CURRENT_USER, 8, true, false);
|
|
seedInstance("expense-reimburse", "办公用品报销",
|
|
"{\"applicant\":\"我(当前用户)\",\"reimburseDept\":\"行政部\",\"expenseType\":\"办公费\",\"amount\":3200}",
|
|
0, CURRENT_USER, 9, true, false);
|
|
seedInstance("seal-apply", "业务合同用印申请",
|
|
"{\"applicant\":\"黄磊\",\"sealType\":\"公章\",\"copies\":1,\"docName\":\"采购合同\",\"reason\":\"采购签约\"}",
|
|
0, "黄磊", 10, true, false);
|
|
seedInstance("general-collab", "关于季度经营分析会的通知",
|
|
"{\"title\":\"关于季度经营分析会的通知\",\"applicant\":\"我(当前用户)\",\"content\":\"定于本月下旬召开季度经营分析会。\"}",
|
|
0, CURRENT_USER, 11, true, false);
|
|
|
|
// One draft (草稿).
|
|
seedDraft("business-trip", "赴北京客户拜访出差申请(暂存)",
|
|
"{\"title\":\"赴北京客户拜访出差申请(暂存)\"}", CURRENT_USER);
|
|
}
|
|
|
|
/**
|
|
* Seed an instance at a given main-chain index, with prior 同意 trace steps
|
|
* filled in. finished -> jump to 已办结; returned -> mark 已退回.
|
|
*/
|
|
private void seedInstance(String templateId, String title, String dataJson, int atIndex,
|
|
String origin, int dayOffset, boolean finished, boolean returned) {
|
|
FormTemplate template = templateRepo.findById(templateId).orElse(null);
|
|
if (template == null) {
|
|
return;
|
|
}
|
|
List<ChainNode> chain = workflowService.mainChain(template.getFlowSchemaJson());
|
|
Instant startTs = daysAgo(dayOffset, 9, 15);
|
|
|
|
FormInstance inst = new FormInstance();
|
|
inst.setTemplateId(template.getId());
|
|
inst.setTemplateName(template.getName());
|
|
inst.setCategory(template.getCategory());
|
|
inst.setTitle(title);
|
|
inst.setDataJson(dataJson);
|
|
inst.setOriginUser(origin);
|
|
inst.setCreatedAt(startTs);
|
|
|
|
int idx = finished ? chain.size() : Math.min(atIndex, Math.max(0, chain.size() - 1));
|
|
if (finished) {
|
|
inst.setNodeIndex(chain.size());
|
|
inst.setStatus("已办结");
|
|
inst.setCurrentNode("办结");
|
|
inst.setCurrentNodeId(endId(template.getFlowSchemaJson()));
|
|
} else {
|
|
inst.setNodeIndex(idx);
|
|
ChainNode node = chain.isEmpty() ? null : chain.get(idx);
|
|
inst.setCurrentNode(node == null ? "办结" : node.label());
|
|
inst.setCurrentNodeId(node == null ? "end" : node.id());
|
|
inst.setStatus(returned ? "已退回" : (atIndex == 0 ? "待办" : "办理中"));
|
|
}
|
|
inst.setUpdatedAt(daysAgo(Math.max(0, dayOffset - atIndex), 11, 5));
|
|
instanceRepo.save(inst);
|
|
Long instId = inst.getId();
|
|
|
|
// Trace chain.
|
|
addTrace(instId, "发起", origin, "提交申请,请各级领导审批。", "发起", startTs);
|
|
for (int k = 0; k < idx && k < chain.size(); k++) {
|
|
addTrace(instId, chain.get(k).label(), CURRENT_USER,
|
|
"情况属实,同意,按流程办理。", "同意", daysAgo(Math.max(0, dayOffset - k - 1), 10 + k, 20));
|
|
}
|
|
if (finished) {
|
|
addTrace(instId, "办结", CURRENT_USER, "流程办结,归档。", "办结",
|
|
daysAgo(Math.max(0, dayOffset - chain.size() - 1), 16, 30));
|
|
}
|
|
if (returned) {
|
|
String nodeLabel = chain.isEmpty() ? "审批" : chain.get(idx).label();
|
|
addTrace(instId, nodeLabel, CURRENT_USER, "材料需补充,退回修改。", "退回",
|
|
daysAgo(Math.max(0, dayOffset - atIndex), 15, 0));
|
|
}
|
|
|
|
// Open task for the active node when in-flight.
|
|
if (!finished && !returned && !chain.isEmpty()) {
|
|
addTask(instId, chain.get(idx).label(), CURRENT_USER, inst.getUpdatedAt());
|
|
}
|
|
}
|
|
|
|
private void seedDraft(String templateId, String title, String dataJson, String origin) {
|
|
FormTemplate template = templateRepo.findById(templateId).orElse(null);
|
|
if (template == null) {
|
|
return;
|
|
}
|
|
List<ChainNode> chain = workflowService.mainChain(template.getFlowSchemaJson());
|
|
Instant ts = daysAgo(0, 9, 20);
|
|
FormInstance inst = new FormInstance();
|
|
inst.setTemplateId(template.getId());
|
|
inst.setTemplateName(template.getName());
|
|
inst.setCategory(template.getCategory());
|
|
inst.setTitle(title);
|
|
inst.setDataJson(dataJson);
|
|
inst.setOriginUser(origin);
|
|
inst.setStatus("草稿");
|
|
inst.setNodeIndex(0);
|
|
inst.setCurrentNode("草稿");
|
|
inst.setCurrentNodeId(chain.isEmpty() ? "start" : chain.get(0).id());
|
|
inst.setCreatedAt(ts);
|
|
inst.setUpdatedAt(ts);
|
|
instanceRepo.save(inst);
|
|
}
|
|
|
|
private void addTrace(Long instanceId, String node, String who, String opinion,
|
|
String type, Instant when) {
|
|
FlowTrace t = new FlowTrace();
|
|
t.setInstanceId(instanceId);
|
|
t.setNode(node);
|
|
t.setWho(who);
|
|
t.setOpinion(opinion);
|
|
t.setType(type);
|
|
t.setCreatedAt(when);
|
|
traceRepo.save(t);
|
|
}
|
|
|
|
private void addTask(Long instanceId, String nodeLabel, String assignee, Instant when) {
|
|
FlowTask task = new FlowTask();
|
|
task.setInstanceId(instanceId);
|
|
task.setNodeLabel(nodeLabel);
|
|
task.setAssignee(assignee);
|
|
task.setStatus("todo");
|
|
task.setCreatedAt(when);
|
|
taskRepo.save(task);
|
|
}
|
|
|
|
private String endId(String flowJson) {
|
|
try {
|
|
var nodes = objectMapper.readTree(flowJson).path("nodes");
|
|
if (nodes.isArray()) {
|
|
for (var n : nodes) {
|
|
if ("end".equals(n.path("type").asText(""))) {
|
|
return n.path("id").asText("end");
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception ignored) {
|
|
// fall through to default
|
|
}
|
|
return "end";
|
|
}
|
|
|
|
// ----- documents -----
|
|
|
|
private void seedDocuments() {
|
|
DocFolder root = folder("公司文档", null);
|
|
DocFolder policy = folder("规章制度", root.getId());
|
|
DocFolder finance = folder("财务资料", root.getId());
|
|
folder("项目档案", root.getId());
|
|
|
|
file(policy.getId(), "员工手册", "pdf", 2_400_000L, 3, "李娜", "已发布");
|
|
file(policy.getId(), "考勤管理办法", "docx", 180_000L, 2, "陈静", "已发布");
|
|
file(finance.getId(), "2025年度预算表", "xlsx", 540_000L, 1, "张伟", "草稿");
|
|
file(root.getId(), "公司组织架构图", "png", 320_000L, 1, "系统管理员", "已发布");
|
|
}
|
|
|
|
private DocFolder folder(String name, Long parentId) {
|
|
DocFolder f = new DocFolder();
|
|
f.setName(name);
|
|
f.setParentId(parentId);
|
|
return folderRepo.save(f);
|
|
}
|
|
|
|
private void file(Long folderId, String name, String ext, long size, int version,
|
|
String uploader, String status) {
|
|
DocFile f = new DocFile();
|
|
f.setFolderId(folderId);
|
|
f.setName(name);
|
|
f.setExt(ext);
|
|
f.setSize(size);
|
|
f.setVersion(version);
|
|
f.setUploader(uploader);
|
|
f.setStatus(status);
|
|
f.setUpdatedAt(Instant.now());
|
|
fileRepo.save(f);
|
|
}
|
|
|
|
// ----- meetings -----
|
|
|
|
private void seedMeetings() {
|
|
MeetingRoom r1 = room("第一会议室", 20, "A座3层");
|
|
MeetingRoom r2 = room("视频会议室", 10, "B座5层");
|
|
room("洽谈室", 6, "A座1层");
|
|
|
|
Instant base = Instant.now().plus(1, ChronoUnit.DAYS).truncatedTo(ChronoUnit.HOURS);
|
|
Meeting m1 = meeting("季度经营分析会", base, base.plus(2, ChronoUnit.HOURS),
|
|
r1.getId(), "张伟", "已预定");
|
|
meeting("产品迭代评审会", base.plus(1, ChronoUnit.DAYS), base.plus(1, ChronoUnit.DAYS).plus(90, ChronoUnit.MINUTES),
|
|
r2.getId(), "王芳", "已预定");
|
|
|
|
minute(m1.getId(), "季度经营分析会纪要", "一、上季度经营回顾;二、本季度目标分解;三、行动项与责任人。");
|
|
}
|
|
|
|
private MeetingRoom room(String name, int capacity, String location) {
|
|
MeetingRoom r = new MeetingRoom();
|
|
r.setName(name);
|
|
r.setCapacity(capacity);
|
|
r.setLocation(location);
|
|
return roomRepo.save(r);
|
|
}
|
|
|
|
private Meeting meeting(String subject, Instant start, Instant end, Long roomId,
|
|
String organizer, String status) {
|
|
Meeting m = new Meeting();
|
|
m.setSubject(subject);
|
|
m.setStartTime(start);
|
|
m.setEndTime(end);
|
|
m.setRoomId(roomId);
|
|
m.setOrganizer(organizer);
|
|
m.setStatus(status);
|
|
return meetingRepo.save(m);
|
|
}
|
|
|
|
private void minute(Long meetingId, String title, String content) {
|
|
MeetingMinute mm = new MeetingMinute();
|
|
mm.setMeetingId(meetingId);
|
|
mm.setTitle(title);
|
|
mm.setContent(content);
|
|
mm.setCreatedAt(Instant.now());
|
|
minuteRepo.save(mm);
|
|
}
|
|
|
|
// ----- schedule -----
|
|
|
|
private void seedSchedule() {
|
|
Instant base = Instant.now().truncatedTo(ChronoUnit.HOURS);
|
|
event("项目周例会", "会议", base.plus(2, ChronoUnit.HOURS), base.plus(3, ChronoUnit.HOURS), CURRENT_USER);
|
|
event("提交月度报表", "任务", base.plus(1, ChronoUnit.DAYS), base.plus(1, ChronoUnit.DAYS).plus(1, ChronoUnit.HOURS), "张伟");
|
|
event("客户拜访", "外出", base.plus(2, ChronoUnit.DAYS), base.plus(2, ChronoUnit.DAYS).plus(4, ChronoUnit.HOURS), "刘洋");
|
|
}
|
|
|
|
private void event(String title, String type, Instant start, Instant end, String owner) {
|
|
ScheduleEvent e = new ScheduleEvent();
|
|
e.setTitle(title);
|
|
e.setType(type);
|
|
e.setStartTime(start);
|
|
e.setEndTime(end);
|
|
e.setOwner(owner);
|
|
scheduleRepo.save(e);
|
|
}
|
|
|
|
// ----- announcements -----
|
|
|
|
private void seedAnnouncements() {
|
|
announcement("公告", "关于2025年端午节放假安排的通知",
|
|
"根据国家法定节假日安排,端午节放假三天,请各部门提前做好工作安排。", "行政部", true);
|
|
announcement("公告", "关于启用新版OA系统的通知",
|
|
"新版协同办公系统正式上线,原系统将于本月底停用,请及时迁移待办事项。", "信息中心", true);
|
|
announcement("新闻", "公司荣获年度优秀供应商称号",
|
|
"在年度供应链大会上,公司凭借稳定的交付质量荣获优秀供应商称号。", "市场部", false);
|
|
announcement("新闻", "第三季度经营业绩稳步增长",
|
|
"公司第三季度营收同比增长18%,各项业务指标稳中向好。", "财务部", false);
|
|
}
|
|
|
|
private void announcement(String category, String title, String content, String author, boolean top) {
|
|
Announcement a = new Announcement();
|
|
a.setCategory(category);
|
|
a.setTitle(title);
|
|
a.setContent(content);
|
|
a.setAuthor(author);
|
|
a.setTop(top);
|
|
a.setPublishedAt(Instant.now().minus(Duration.ofDays(1)));
|
|
announcementRepo.save(a);
|
|
}
|
|
|
|
// ----- projects -----
|
|
|
|
private void seedProjects() {
|
|
Project p1 = project("靖州供水项目工程信息化", "张伟", 4L, "2026-04-01", "2026-09-30", 65, "进行中", "执行");
|
|
Project p2 = project("新版OA系统上线推广", "王芳", 4L, "2026-05-10", "2026-06-30", 80, "进行中", "中标");
|
|
Project p3 = project("2026年度财务预算系统升级", "刘洋", 2L, "2026-03-01", "2026-05-31", 100, "已完成", "验收");
|
|
project("行政后勤管理平台建设", "李娜", 3L, "2026-02-01", "2026-04-30", 40, "已超期", "执行");
|
|
|
|
projectTask(p1.getId(), "完成现场管网数据采集", "王芳", "已完成", "2026-05-20", "高");
|
|
projectTask(p1.getId(), "搭建供水调度监控模块", "刘洋", "进行中", "2026-07-15", "高");
|
|
projectTask(p1.getId(), "编写运维操作手册", "陈静", "待办", "2026-08-31", "中");
|
|
projectTask(p2.getId(), "整理各部门待办迁移清单", "李娜", "进行中", "2026-06-18", "高");
|
|
projectTask(p2.getId(), "组织全员使用培训", "王芳", "待办", "2026-06-25", "中");
|
|
projectTask(p3.getId(), "预算模板字段重构", "刘洋", "已完成", "2026-04-30", "低");
|
|
}
|
|
|
|
private Project project(String name, String owner, Long deptId, String startDate,
|
|
String endDate, int progress, String status, String phase) {
|
|
Project p = new Project();
|
|
p.setName(name);
|
|
p.setOwner(owner);
|
|
p.setDeptId(deptId);
|
|
p.setStartDate(startDate);
|
|
p.setEndDate(endDate);
|
|
p.setProgress(progress);
|
|
p.setStatus(status);
|
|
p.setPhase(phase);
|
|
return projectRepo.save(p);
|
|
}
|
|
|
|
private void projectTask(Long projectId, String title, String assignee, String status,
|
|
String dueDate, String priority) {
|
|
ProjectTask t = new ProjectTask();
|
|
t.setProjectId(projectId);
|
|
t.setTitle(title);
|
|
t.setAssignee(assignee);
|
|
t.setStatus(status);
|
|
t.setDueDate(dueDate);
|
|
t.setPriority(priority);
|
|
projectTaskRepo.save(t);
|
|
}
|
|
|
|
// ----- work plans -----
|
|
|
|
private void seedWorkPlans() {
|
|
workPlan("信息中心本周工作计划", "王芳", "本周", "执行中",
|
|
"一、推进OA上线推广;二、完成供水项目数据采集;三、处理日常运维工单。");
|
|
workPlan("财务部六月工作计划", "张伟", "本月", "执行中",
|
|
"一、完成半年度结账;二、推进预算系统升级验收;三、组织费用报销专项核查。");
|
|
workPlan("行政部第二季度工作计划", "李娜", "本季", "已完成",
|
|
"一、完成办公场地调整;二、组织员工体检;三、修订考勤管理办法。");
|
|
workPlan("人事招聘月度计划", "陈静", "本月", "草稿",
|
|
"一、梳理各部门用人需求;二、发布社会招聘公告;三、安排面试与入职。");
|
|
}
|
|
|
|
private void workPlan(String title, String owner, String period, String status, String content) {
|
|
WorkPlan p = new WorkPlan();
|
|
p.setTitle(title);
|
|
p.setOwner(owner);
|
|
p.setPeriod(period);
|
|
p.setStatus(status);
|
|
p.setContent(content);
|
|
workPlanRepo.save(p);
|
|
}
|
|
|
|
// ----- collab docs -----
|
|
|
|
private void seedCollabDocs() {
|
|
collabDoc("OA上线推广方案", "王芳", "张伟,李娜,陈静", "编辑中",
|
|
"围绕新版OA系统上线,制定分阶段推广、培训与答疑计划,确保各部门平稳迁移。");
|
|
collabDoc("靖州供水项目实施方案", "张伟", "王芳,刘洋", "已定稿",
|
|
"明确供水项目信息化建设的范围、里程碑、责任分工与验收标准。");
|
|
collabDoc("公司年度经营分析报告", "刘洋", "张伟,李娜", "编辑中",
|
|
"汇总各部门经营数据,分析上半年经营成果与下半年改进方向。");
|
|
collabDoc("信息安全管理制度(修订稿)", "系统管理员", "王芳,陈静", "已定稿",
|
|
"对账号权限、数据备份、终端安全等条款进行修订,强化信息安全管理。");
|
|
}
|
|
|
|
private void collabDoc(String title, String owner, String participants, String status, String content) {
|
|
CollabDoc d = new CollabDoc();
|
|
d.setTitle(title);
|
|
d.setOwner(owner);
|
|
d.setParticipants(participants);
|
|
d.setStatus(status);
|
|
d.setContent(content);
|
|
d.setUpdatedAt(Instant.now().minus(Duration.ofDays(1)));
|
|
collabDocRepo.save(d);
|
|
}
|
|
|
|
// ----- discussions -----
|
|
|
|
private void seedDiscussions() {
|
|
discussion("关于新版OA的使用反馈", "李娜", "系统建议",
|
|
"新版OA整体体验不错,建议在待办列表增加批量处理功能,提高审批效率。", 8);
|
|
discussion("供水项目现场协作经验分享", "王芳", "项目交流",
|
|
"分享靖州供水项目现场数据采集的协作经验,欢迎大家补充改进建议。", 5);
|
|
discussion("食堂就餐时间调整讨论", "陈静", "行政事务",
|
|
"近期就餐高峰拥挤,提议错峰用餐,请各部门发表意见。", 12);
|
|
discussion("费用报销流程优化建议", "刘洋", "财务话题",
|
|
"建议简化小额报销审批环节,缩短到账周期,欢迎讨论。", 6);
|
|
}
|
|
|
|
private void discussion(String title, String author, String category, String content, int replyCount) {
|
|
Discussion d = new Discussion();
|
|
d.setTitle(title);
|
|
d.setAuthor(author);
|
|
d.setCategory(category);
|
|
d.setContent(content);
|
|
d.setReplyCount(replyCount);
|
|
d.setCreatedAt(Instant.now().minus(Duration.ofDays(2)));
|
|
discussionRepo.save(d);
|
|
}
|
|
|
|
// ----- surveys -----
|
|
|
|
private void seedSurveys() {
|
|
survey("OA满意度调查", "信息中心", "进行中",
|
|
"[{\"label\":\"非常满意\",\"votes\":18},{\"label\":\"满意\",\"votes\":24},{\"label\":\"一般\",\"votes\":9},{\"label\":\"不满意\",\"votes\":3}]",
|
|
54, "2026-06-20");
|
|
survey("年度团建活动地点投票", "行政部", "进行中",
|
|
"[{\"label\":\"张家界\",\"votes\":31},{\"label\":\"长沙周边\",\"votes\":15},{\"label\":\"省外自驾\",\"votes\":12}]",
|
|
58, "2026-06-15");
|
|
survey("员工培训需求调研", "陈静", "已结束",
|
|
"[{\"label\":\"办公软件技能\",\"votes\":22},{\"label\":\"项目管理\",\"votes\":17},{\"label\":\"财税知识\",\"votes\":11}]",
|
|
50, "2026-05-31");
|
|
}
|
|
|
|
private void survey(String title, String author, String status, String optionsJson,
|
|
int responseCount, String deadline) {
|
|
Survey s = new Survey();
|
|
s.setTitle(title);
|
|
s.setAuthor(author);
|
|
s.setStatus(status);
|
|
s.setOptionsJson(optionsJson);
|
|
s.setResponseCount(responseCount);
|
|
s.setDeadline(deadline);
|
|
surveyRepo.save(s);
|
|
}
|
|
|
|
// ----- leader trips -----
|
|
|
|
private void seedLeaderTrips() {
|
|
Instant base = Instant.now().truncatedTo(ChronoUnit.HOURS);
|
|
leaderTrip("张伟", "长沙", base.plus(2, ChronoUnit.DAYS), base.plus(3, ChronoUnit.DAYS),
|
|
"赴长沙参加行业峰会", "计划中");
|
|
leaderTrip("李娜", "靖州", base.plus(1, ChronoUnit.DAYS), base.plus(1, ChronoUnit.DAYS).plus(8, ChronoUnit.HOURS),
|
|
"现场调研供水项目进展", "计划中");
|
|
leaderTrip("王芳", "北京", base.minus(2, ChronoUnit.DAYS), base.plus(1, ChronoUnit.HOURS),
|
|
"参加信息化技术交流会", "进行中");
|
|
leaderTrip("刘洋", "广州", base.minus(6, ChronoUnit.DAYS), base.minus(4, ChronoUnit.DAYS),
|
|
"对接审计与财税合规事项", "已完成");
|
|
}
|
|
|
|
private void leaderTrip(String leader, String destination, Instant startTime, Instant endTime,
|
|
String purpose, String status) {
|
|
LeaderTrip t = new LeaderTrip();
|
|
t.setLeader(leader);
|
|
t.setDestination(destination);
|
|
t.setStartTime(startTime);
|
|
t.setEndTime(endTime);
|
|
t.setPurpose(purpose);
|
|
t.setStatus(status);
|
|
leaderTripRepo.save(t);
|
|
}
|
|
|
|
// ----- core master data -----
|
|
|
|
private void seedMasterData() {
|
|
seedCompanySubjects();
|
|
seedContracts();
|
|
seedContractTemplates();
|
|
seedContractChanges();
|
|
seedSuppliers();
|
|
seedCustomers();
|
|
seedBankAccounts();
|
|
seedSeals();
|
|
seedInvoices();
|
|
seedPayments();
|
|
seedSealUses();
|
|
seedArchives();
|
|
seedArchiveComments();
|
|
seedOpportunities();
|
|
seedOpportunityFollowups();
|
|
seedSafetyChecks();
|
|
seedCertifications();
|
|
seedBudgets();
|
|
seedBids();
|
|
seedIntel();
|
|
seedRd();
|
|
seedDeclarationTemplates();
|
|
seedRdExpenses();
|
|
seedCostCenters();
|
|
seedPriceItems();
|
|
seedPersonnelCerts();
|
|
seedCrawlSources();
|
|
seedCrawlJobs();
|
|
seedBomItems();
|
|
seedHealthRecords();
|
|
seedQmsRecords();
|
|
seedWastewaterClients();
|
|
seedWaterQualityRecords();
|
|
seedWorkOrders();
|
|
seedInventoryItems();
|
|
seedAccounts();
|
|
seedVouchers();
|
|
seedLabSamples();
|
|
seedLabInstruments();
|
|
seedDesignDocs();
|
|
seedDesignChanges();
|
|
seedSupervisionLogs();
|
|
seedAuditProjects();
|
|
seedItAssets();
|
|
seedHandovers();
|
|
seedDeclarationSteps();
|
|
seedExperts();
|
|
seedInventoryValuationConfigs();
|
|
seedCostAdjustLogs();
|
|
}
|
|
|
|
private void seedCompanySubjects() {
|
|
companySubject("湖南凯迪工程科技有限公司", "湖南凯迪", "总公司",
|
|
"91430100MA4L8K0X1A", "张伟", "正常");
|
|
companySubject("凯迪长沙办公室", "长沙办", "办事处",
|
|
"91430100MA4L8K0X2B", "李娜", "正常");
|
|
companySubject("智铖造(湖南)建设有限公司", "智铖造", "集团小公司",
|
|
"91430100MA4L8K0X3C", "王芳", "正常");
|
|
companySubject("江山春锦置业有限公司", "江山春锦", "集团小公司",
|
|
"91430100MA4L8K0X4D", "刘洋", "正常");
|
|
companySubject("湖南凯迪工程科技有限公司岳阳分公司", "岳阳分公司", "分公司",
|
|
"91430600MA4L8K0X5E", "陈静", "正常");
|
|
}
|
|
|
|
private CompanySubject companySubject(String name, String shortName, String type,
|
|
String creditCode, String legalPerson, String status) {
|
|
CompanySubject c = new CompanySubject();
|
|
c.setName(name);
|
|
c.setShortName(shortName);
|
|
c.setType(type);
|
|
c.setCreditCode(creditCode);
|
|
c.setLegalPerson(legalPerson);
|
|
c.setStatus(status);
|
|
return companySubjectRepo.save(c);
|
|
}
|
|
|
|
private void seedContracts() {
|
|
// paidAmount is kept self-consistent: it equals the sum of the 已付
|
|
// payments that reference this contract (see seedPayments). invoicedAmount
|
|
// equals the sum of the invoice amounts that reference this contract via
|
|
// Invoice.contractId (see seedInvoices). Pending/rejected payments and
|
|
// invoices without a contractId do not contribute.
|
|
// c1: no 已付 payment (FK-0004 is 待付) -> paid 0; invoice 00231001 amount.
|
|
Contract c1 = contract("KD-JY-2026-001", "靖州供水项目信息化建设合同", "经营合同",
|
|
"靖州县水利局", "湖南凯迪工程科技有限公司", 8600000d, 1L,
|
|
"湖南凯迪工程科技有限公司", "2026-04-01", "履约中",
|
|
0d, 1761467.89d, "李娜");
|
|
// c2: FK-0001 已付 1600000 (FK-0005 待付 excluded); invoice 00125679 amount.
|
|
Contract c2 = contract("KD-CB-2026-002", "供水调度监控设备成本合同", "成本合同",
|
|
"湖南凯迪工程科技有限公司", "智铖造(湖南)建设有限公司", 3200000d, 1L,
|
|
"湖南凯迪工程科技有限公司", "2026-04-15", "履约中",
|
|
1600000d, 283185.84d, "刘洋");
|
|
// c3: FK-0002 已付 480000; invoice 00125678 amount.
|
|
Contract c3 = contract("KD-CG-2026-003", "新版OA系统服务器采购合同", "采购合同",
|
|
"湖南凯迪工程科技有限公司", "长沙华信网络科技有限公司", 480000d, 2L,
|
|
"凯迪长沙办公室", "2026-05-12", "已结算",
|
|
480000d, 424778.76d, "陈静");
|
|
// c4: FK-0003 已付 600000 (FK-0009 待付 excluded); no invoice references it.
|
|
Contract c4 = contract("KD-JY-2026-004", "江山春锦项目工程咨询合同", "经营合同",
|
|
"江山春锦置业有限公司", "湖南凯迪工程科技有限公司", 1500000d, null,
|
|
"江山春锦置业有限公司", "2026-03-20", "履约中",
|
|
600000d, 0d, "李娜");
|
|
// c5: FK-0010 已付 130000; no invoice references it.
|
|
Contract c5 = contract("KD-CG-2026-005", "行政后勤平台软件采购合同", "采购合同",
|
|
"湖南凯迪工程科技有限公司", "湖南云图软件有限公司", 260000d, null,
|
|
"湖南凯迪工程科技有限公司", "2026-02-10", "已终止",
|
|
130000d, 0d, "陈静");
|
|
|
|
seedContractMilestones(c1, c2, c3, c4, c5);
|
|
}
|
|
|
|
private Contract contract(String code, String name, String type, String partyA, String partyB,
|
|
double amount, Long projectId, String companySubject, String signDate,
|
|
String status, double paidAmount, double invoicedAmount, String custodian) {
|
|
Contract c = new Contract();
|
|
c.setCode(code);
|
|
c.setName(name);
|
|
c.setType(type);
|
|
c.setPartyA(partyA);
|
|
c.setPartyB(partyB);
|
|
c.setAmount(Money.of(amount));
|
|
c.setProjectId(projectId);
|
|
c.setCompanySubject(companySubject);
|
|
c.setSignDate(signDate);
|
|
c.setStatus(status);
|
|
c.setPaidAmount(Money.of(paidAmount));
|
|
c.setInvoicedAmount(Money.of(invoicedAmount));
|
|
c.setCustodian(custodian);
|
|
return contractRepo.save(c);
|
|
}
|
|
|
|
private void seedContractMilestones(Contract c1, Contract c2, Contract c3, Contract c4, Contract c5) {
|
|
// c1 靖州供水项目信息化建设合同 (履约中) - 4 nodes.
|
|
milestone(c1.getId(), "合同签订", "2026-04-01", 0d, "已完成");
|
|
milestone(c1.getId(), "进场", "2026-04-20", 1720000d, "已完成");
|
|
milestone(c1.getId(), "中期验收", "2026-07-15", 3440000d, "待履约");
|
|
milestone(c1.getId(), "竣工验收", "2026-09-30", 3440000d, "待履约");
|
|
|
|
// c2 供水调度监控设备成本合同 (履约中) - 3 nodes, includes 逾期.
|
|
milestone(c2.getId(), "合同签订", "2026-04-15", 0d, "已完成");
|
|
milestone(c2.getId(), "设备进场", "2026-05-30", 1600000d, "逾期");
|
|
milestone(c2.getId(), "竣工验收", "2026-08-31", 1600000d, "待履约");
|
|
|
|
// c3 新版OA系统服务器采购合同 (已结算) - 3 nodes, all 已完成.
|
|
milestone(c3.getId(), "合同签订", "2026-05-12", 0d, "已完成");
|
|
milestone(c3.getId(), "到货验收", "2026-05-28", 480000d, "已完成");
|
|
milestone(c3.getId(), "质保到期", "2026-12-31", 0d, "待履约");
|
|
|
|
// c4 江山春锦项目工程咨询合同 (履约中) - 4 nodes, includes 逾期.
|
|
milestone(c4.getId(), "合同签订", "2026-03-20", 0d, "已完成");
|
|
milestone(c4.getId(), "中期成果提交", "2026-05-15", 750000d, "已完成");
|
|
milestone(c4.getId(), "终期成果提交", "2026-05-31", 750000d, "逾期");
|
|
milestone(c4.getId(), "竣工验收", "2026-10-31", 0d, "待履约");
|
|
|
|
// c5 行政后勤平台软件采购合同 (已终止) - 3 nodes.
|
|
milestone(c5.getId(), "合同签订", "2026-02-10", 0d, "已完成");
|
|
milestone(c5.getId(), "上线验收", "2026-04-30", 130000d, "已完成");
|
|
milestone(c5.getId(), "质保到期", "2027-04-30", 0d, "待履约");
|
|
}
|
|
|
|
private void milestone(Long contractId, String name, String dueDate, double amount, String status) {
|
|
ContractMilestone m = new ContractMilestone();
|
|
m.setContractId(contractId);
|
|
m.setName(name);
|
|
m.setDueDate(dueDate);
|
|
m.setAmount(Money.of(amount));
|
|
m.setStatus(status);
|
|
contractMilestoneRepo.save(m);
|
|
}
|
|
|
|
private void seedSuppliers() {
|
|
supplier("智铖造(湖南)建设有限公司", "91430100MA4L8K0X3C", "劳务", "王芳",
|
|
"13800000003", "中国建设银行长沙分行", "4300012345678900001", "合格");
|
|
supplier("长沙华信网络科技有限公司", "91430100MA4LX1234A", "设备", "周强",
|
|
"13900000001", "中国工商银行长沙分行", "6222021234567890001", "合格");
|
|
supplier("湖南云图软件有限公司", "91430100MA4LX5678B", "服务", "赵敏",
|
|
"13900000002", "招商银行长沙分行", "6225881234567890002", "准入中");
|
|
supplier("湖南宏发建材有限公司", "91430100MA4LX9012C", "材料", "孙磊",
|
|
"13900000003", "中国农业银行长沙分行", "6228481234567890003", "合格");
|
|
supplier("岳阳通达设备租赁有限公司", "91430600MA4LX3456D", "设备", "钱伟",
|
|
"13900000004", "中国银行岳阳分行", "6217001234567890004", "停用");
|
|
}
|
|
|
|
private Supplier supplier(String name, String creditCode, String category, String contact,
|
|
String phone, String bankName, String bankAccount, String status) {
|
|
Supplier s = new Supplier();
|
|
s.setName(name);
|
|
s.setCreditCode(creditCode);
|
|
s.setCategory(category);
|
|
s.setContact(contact);
|
|
s.setPhone(phone);
|
|
s.setBankName(bankName);
|
|
s.setBankAccount(bankAccount);
|
|
s.setStatus(status);
|
|
return supplierRepo.save(s);
|
|
}
|
|
|
|
private void seedCustomers() {
|
|
customer("靖州县水利局", "政府", "杨建国", "13700000001",
|
|
"湖南省怀化市靖州县渠阳镇政府路1号", "合作中");
|
|
customer("江山春锦置业有限公司", "企业", "胡敏", "13700000002",
|
|
"湖南省长沙市岳麓区滨江路88号", "合作中");
|
|
customer("湖南省交通建设投资集团", "企业", "罗成", "13700000003",
|
|
"湖南省长沙市芙蓉区五一大道100号", "合作中");
|
|
customer("岳阳市城乡建设事务中心", "事业单位", "彭辉", "13700000004",
|
|
"湖南省岳阳市岳阳楼区巴陵中路18号", "潜在");
|
|
customer("怀化市自然资源局", "政府", "唐勇", "13700000005",
|
|
"湖南省怀化市鹤城区迎丰中路66号", "停止");
|
|
}
|
|
|
|
private Customer customer(String name, String type, String contact, String phone,
|
|
String address, String status) {
|
|
Customer c = new Customer();
|
|
c.setName(name);
|
|
c.setType(type);
|
|
c.setContact(contact);
|
|
c.setPhone(phone);
|
|
c.setAddress(address);
|
|
c.setStatus(status);
|
|
return customerRepo.save(c);
|
|
}
|
|
|
|
private void seedBankAccounts() {
|
|
bankAccount("湖南凯迪工程科技有限公司", "中国建设银行长沙分行营业部", "4300012345678900088",
|
|
"湖南凯迪工程科技有限公司", "人民币", "基本户");
|
|
bankAccount("湖南凯迪工程科技有限公司", "中国工商银行长沙分行", "6222021234567899001",
|
|
"湖南凯迪工程科技有限公司", "人民币", "项目专用户");
|
|
bankAccount("智铖造(湖南)建设有限公司", "招商银行长沙分行", "6225881234567899002",
|
|
"智铖造(湖南)建设有限公司", "人民币", "一般户");
|
|
bankAccount("江山春锦置业有限公司", "中国农业银行长沙分行", "6228481234567899003",
|
|
"江山春锦置业有限公司", "人民币", "基本户");
|
|
bankAccount("湖南凯迪工程科技有限公司岳阳分公司", "中国银行岳阳分行", "6217001234567899004",
|
|
"湖南凯迪工程科技有限公司岳阳分公司", "人民币", "一般户");
|
|
}
|
|
|
|
private BankAccount bankAccount(String accountName, String bankName, String accountNo,
|
|
String companySubject, String currency, String purpose) {
|
|
BankAccount b = new BankAccount();
|
|
b.setAccountName(accountName);
|
|
b.setBankName(bankName);
|
|
b.setAccountNo(accountNo);
|
|
b.setCompanySubject(companySubject);
|
|
b.setCurrency(currency);
|
|
b.setPurpose(purpose);
|
|
return bankAccountRepo.save(b);
|
|
}
|
|
|
|
private void seedSeals() {
|
|
seal("湖南凯迪公章", "公章", "湖南凯迪工程科技有限公司", "李娜", "在用");
|
|
seal("湖南凯迪合同专用章", "合同章", "湖南凯迪工程科技有限公司", "陈静", "在用");
|
|
seal("湖南凯迪财务专用章", "财务章", "湖南凯迪工程科技有限公司", "刘洋", "在用");
|
|
// 法人代表章 must stay 在用: seal-use YZ-2026-0009 (法人授权用印) references
|
|
// it. The seal-use create endpoint now rejects 封存/停用 seals, so a sealed
|
|
// seal here would make the seed self-inconsistent with that validation.
|
|
seal("湖南凯迪法人代表章", "法人章", "湖南凯迪工程科技有限公司", "张伟", "在用");
|
|
seal("靖州供水项目部项目章", "项目章", "湖南凯迪工程科技有限公司", "王芳", "在用");
|
|
}
|
|
|
|
private Seal seal(String name, String type, String companySubject, String custodian, String status) {
|
|
Seal s = new Seal();
|
|
s.setName(name);
|
|
s.setType(type);
|
|
s.setCompanySubject(companySubject);
|
|
s.setCustodian(custodian);
|
|
s.setStatus(status);
|
|
return sealRepo.save(s);
|
|
}
|
|
|
|
private void seedInvoices() {
|
|
// contractId ties an invoice back to a contract so invoicedAmount is
|
|
// traceable. The contract invoicedAmount seed values equal the sum of the
|
|
// amounts of the invoices that reference each contract (see seedContracts):
|
|
// invoice 00125678 -> contract 3, invoice 00125679 -> contract 2,
|
|
// invoice 00231001 -> contract 1. Other invoices carry no contractId.
|
|
invoice("4300203130", "00125678", "进项", 424778.76d, 55221.24d, 480000d,
|
|
"长沙华信网络科技有限公司", 2L, 3L, "已认证", "2026-05-15");
|
|
invoice("4300203130", "00125679", "进项", 283185.84d, 36814.16d, 320000d,
|
|
"智铖造(湖南)建设有限公司", 1L, 2L, "已认证", "2026-04-20");
|
|
invoice("4300202130", "00231001", "销项", 1761467.89d, 158532.11d, 1920000d,
|
|
"靖州县水利局", 1L, 1L, "已开", "2026-05-28");
|
|
invoice("4300202130", "00231002", "销项", 137614.68d, 12385.32d, 150000d,
|
|
"江山春锦置业有限公司", null, null, "已开", "2026-04-30");
|
|
invoice("4300203130", "00125680", "进项", 230088.50d, 29911.50d, 260000d,
|
|
"湖南云图软件有限公司", null, null, "作废", "2026-02-18");
|
|
invoice("4300202130", "00231003", "销项", 91743.12d, 8256.88d, 100000d,
|
|
"湖南省交通建设投资集团", null, null, "已认证", "2026-06-05");
|
|
}
|
|
|
|
private Invoice invoice(String code, String number, String type, double amount, double taxAmount,
|
|
double total, String partyName, Long projectId, Long contractId,
|
|
String status, String issueDate) {
|
|
Invoice v = new Invoice();
|
|
v.setCode(code);
|
|
v.setNumber(number);
|
|
v.setType(type);
|
|
v.setAmount(Money.of(amount));
|
|
v.setTaxAmount(Money.of(taxAmount));
|
|
v.setTotal(Money.of(total));
|
|
v.setPartyName(partyName);
|
|
v.setProjectId(projectId);
|
|
v.setContractId(contractId);
|
|
v.setStatus(status);
|
|
v.setIssueDate(issueDate);
|
|
return invoiceRepo.save(v);
|
|
}
|
|
|
|
private void seedPayments() {
|
|
// Seed payments directly (no contract paidAmount write-back here); the
|
|
// contract seed values already reflect cumulative paid. Write-back only
|
|
// happens on the POST create endpoint.
|
|
payment("FK-2026-0001", "湖南凯迪工程科技有限公司", "进度款", "智铖造(湖南)建设有限公司",
|
|
1600000d, 2L, 2L, 1L, "6225881234567899002", "张伟", "已付", "2026-05-18");
|
|
payment("FK-2026-0002", "湖南凯迪工程科技有限公司", "货款", "长沙华信网络科技有限公司",
|
|
480000d, 1L, 3L, 2L, "6222021234567890001", "刘洋", "已付", "2026-05-20");
|
|
payment("FK-2026-0003", "江山春锦置业有限公司", "进度款", "湖南凯迪工程科技有限公司",
|
|
600000d, null, 4L, null, "6228481234567899003", "李娜", "已付", "2026-05-22");
|
|
payment("FK-2026-0004", "湖南凯迪工程科技有限公司", "进度款", "靖州供水项目施工队",
|
|
1720000d, null, 1L, 1L, "4300012345678900088", "张伟", "待付", "2026-06-15");
|
|
payment("FK-2026-0005", "智铖造(湖南)建设有限公司", "保函", "中国建设银行长沙分行",
|
|
32000d, null, 2L, 1L, "4300012345678900001", "刘洋", "待付", "2026-06-20");
|
|
payment("FK-2026-0006", "岳阳分公司", "费用报销", "陈静",
|
|
12800d, null, null, null, "6217001234567899004", "陈静", "待付", "2026-06-08");
|
|
payment("FK-2026-0007", "湖南凯迪工程科技有限公司岳阳分公司", "货款", "岳阳通达设备租赁有限公司",
|
|
88000d, null, null, null, "6217001234567890004", "陈静", "已付", "2026-05-30");
|
|
payment("FK-2026-0008", "智铖造(湖南)建设有限公司", "费用报销", "刘洋",
|
|
6400d, null, null, null, "6225881234567890002", "刘洋", "已驳回", "2026-06-03");
|
|
payment("FK-2026-0009", "江山春锦置业有限公司", "保函", "招商银行长沙分行",
|
|
15000d, null, 4L, null, "6225881234567899002", "李娜", "待付", "2026-06-12");
|
|
payment("FK-2026-0010", "湖南凯迪工程科技有限公司", "货款", "湖南宏发建材有限公司",
|
|
130000d, null, 5L, null, "6228481234567890003", "张伟", "已付", "2026-04-28");
|
|
}
|
|
|
|
private void payment(String code, String subject, String payType, String payeeName, double amount,
|
|
Long invoiceId, Long contractId, Long projectId, String bankAccountNo,
|
|
String applicant, String status, String payDate) {
|
|
Payment p = new Payment();
|
|
p.setCode(code);
|
|
p.setSubject(subject);
|
|
p.setPayType(payType);
|
|
p.setPayeeName(payeeName);
|
|
p.setAmount(Money.of(amount));
|
|
p.setInvoiceId(invoiceId);
|
|
p.setContractId(contractId);
|
|
p.setProjectId(projectId);
|
|
p.setBankAccountNo(bankAccountNo);
|
|
p.setApplicant(applicant);
|
|
p.setStatus(status);
|
|
p.setPayDate(payDate);
|
|
p.setCreatedAt(Instant.now());
|
|
paymentRepo.save(p);
|
|
}
|
|
|
|
private void seedSealUses() {
|
|
// sealId/sealName follow the seedSeals order: 1 湖南凯迪公章,
|
|
// 2 湖南凯迪合同专用章, 3 湖南凯迪财务专用章, 4 湖南凯迪法人代表章,
|
|
// 5 靖州供水项目部项目章. status is one of 已用印 / 待用印 / 已驳回.
|
|
sealUse("YZ-2026-0001", 2L, "湖南凯迪合同专用章", "湖南凯迪工程科技有限公司",
|
|
1L, 1L, "靖州供水项目施工合同", 2, "李娜", "对外签约用印", "2026-04-01", "已用印");
|
|
sealUse("YZ-2026-0002", 1L, "湖南凯迪公章", "湖南凯迪工程科技有限公司",
|
|
1L, null, "靖州供水项目中标通知书", 1, "张伟", "投标响应用印", "2026-03-28", "已用印");
|
|
sealUse("YZ-2026-0003", 2L, "湖南凯迪合同专用章", "智铖造(湖南)建设有限公司",
|
|
1L, 2L, "供水调度监控设备成本合同", 2, "刘洋", "采购签约用印", "2026-04-15", "已用印");
|
|
sealUse("YZ-2026-0004", 2L, "湖南凯迪合同专用章", "湖南凯迪工程科技有限公司",
|
|
2L, 3L, "新版OA系统服务器采购合同", 1, "陈静", "设备采购用印", "2026-05-12", "已用印");
|
|
sealUse("YZ-2026-0005", 3L, "湖南凯迪财务专用章", "湖南凯迪工程科技有限公司",
|
|
null, null, "银行开户申请", 1, "刘洋", "项目专用户开户用印", "2026-05-06", "待用印");
|
|
sealUse("YZ-2026-0006", 2L, "湖南凯迪合同专用章", "江山春锦置业有限公司",
|
|
null, 4L, "江山春锦项目工程咨询合同", 2, "李娜", "对外签约用印", "2026-03-20", "已用印");
|
|
sealUse("YZ-2026-0007", 5L, "靖州供水项目部项目章", "湖南凯迪工程科技有限公司",
|
|
1L, null, "靖州供水项目现场签证单", 3, "王芳", "现场签证用印", "2026-05-20", "已用印");
|
|
sealUse("YZ-2026-0008", 1L, "湖南凯迪公章", "湖南凯迪工程科技有限公司岳阳分公司",
|
|
null, null, "岳阳分公司资质申报材料", 2, "陈静", "资质申报用印", "2026-06-08", "待用印");
|
|
sealUse("YZ-2026-0009", 4L, "湖南凯迪法人代表章", "湖南凯迪工程科技有限公司",
|
|
null, null, "授权委托书", 1, "张伟", "法人授权用印", "2026-06-05", "已驳回");
|
|
sealUse("YZ-2026-0010", 2L, "湖南凯迪合同专用章", "智铖造(湖南)建设有限公司",
|
|
null, null, "劳务分包补充协议", 2, "刘洋", "对外签约用印", "2026-06-10", "待用印");
|
|
}
|
|
|
|
private void sealUse(String code, Long sealId, String sealName, String subject,
|
|
Long projectId, Long contractId, String docName, int copies,
|
|
String applicant, String purpose, String useDate, String status) {
|
|
SealUse s = new SealUse();
|
|
s.setCode(code);
|
|
s.setSealId(sealId);
|
|
s.setSealName(sealName);
|
|
s.setSubject(subject);
|
|
s.setProjectId(projectId);
|
|
s.setContractId(contractId);
|
|
s.setDocName(docName);
|
|
s.setCopies(copies);
|
|
s.setApplicant(applicant);
|
|
s.setPurpose(purpose);
|
|
s.setUseDate(useDate);
|
|
s.setStatus(status);
|
|
s.setCreatedAt(Instant.now());
|
|
sealUseRepo.save(s);
|
|
}
|
|
|
|
private void seedArchives() {
|
|
// sourceId links: contracts 1..5, projects 1,2, declarations are 手动.
|
|
// category covers 项目档案 / 合同档案 / 申报成果 / 制度文件 / 会议纪要 / 技术资料.
|
|
archive("项目档案", "靖州供水项目竣工验收报告", "项目", 1L,
|
|
"靖州供水项目竣工验收报告.pdf", "pdf", 4_820_000L, "张伟", "2026-06-05",
|
|
"靖州供水,竣工验收,2026", "靖州供水项目信息化建设完成竣工验收,各项指标合格。",
|
|
"内部", "https://oa.kaidi.com/files/jingzhou-acceptance-report.pdf");
|
|
archive("项目档案", "新版OA系统上线推广实施方案", "项目", 2L,
|
|
"OA上线推广实施方案.docx", "docx", 360_000L, "李娜", "2026-05-15",
|
|
"OA系统,上线推广,实施方案", "新版OA系统分阶段推广、培训与答疑的总体实施方案。",
|
|
"内部", "https://oa.kaidi.com/files/oa-rollout-plan.docx");
|
|
archive("项目档案", "靖州供水项目现场管网数据采集成果", "项目", 1L,
|
|
"供水管网数据采集汇总表.xlsx", "xlsx", 1_280_000L, "刘洋", "2026-05-22",
|
|
"靖州供水,管网数据,数据采集", "现场管网普查数据汇总,供调度监控模块建库使用。",
|
|
"内部", "https://oa.kaidi.com/files/pipeline-survey-data.xlsx");
|
|
|
|
archive("合同档案", "靖州供水项目信息化建设合同", "合同", 1L,
|
|
"KD-JY-2026-001-靖州供水信息化建设合同.pdf", "pdf", 2_640_000L, "李娜", "2026-04-02",
|
|
"靖州供水,经营合同,2026", "靖州县水利局与凯迪签订的供水项目信息化建设主合同。",
|
|
"机密", "https://oa.kaidi.com/files/kd-jy-2026-001-contract.pdf");
|
|
archive("合同档案", "供水调度监控设备成本合同", "合同", 2L,
|
|
"KD-CB-2026-002-供水调度监控设备成本合同.pdf", "pdf", 1_980_000L, "刘洋", "2026-04-16",
|
|
"供水调度,成本合同,设备采购", "凯迪与智铖造就供水调度监控设备签订的成本合同。",
|
|
"机密", "https://oa.kaidi.com/files/kd-cb-2026-002-contract.pdf");
|
|
archive("合同档案", "新版OA系统服务器采购合同", "合同", 3L,
|
|
"KD-CG-2026-003-服务器采购合同.pdf", "pdf", 1_120_000L, "陈静", "2026-05-13",
|
|
"OA系统,采购合同,服务器", "向长沙华信采购OA系统服务器的采购合同,已结算。",
|
|
"机密", "https://oa.kaidi.com/files/kd-cg-2026-003-contract.pdf");
|
|
|
|
archive("申报成果", "高新技术企业认定申报书", "申报", null,
|
|
"高新技术企业认定申报书.pdf", "pdf", 3_560_000L, "张伟", "2026-05-08",
|
|
"高新技术企业,申报,资质认定", "湖南凯迪高新技术企业认定整套申报材料。",
|
|
"内部", "https://oa.kaidi.com/files/hightech-application.pdf");
|
|
archive("申报成果", "供水智能调度系统软件著作权证书", "申报", null,
|
|
"软件著作权登记证书.png", "png", 680_000L, "王芳", "2026-04-26",
|
|
"软件著作权,申报成果,知识产权", "供水智能调度系统软件著作权登记证书扫描件。",
|
|
"公开", "https://oa.kaidi.com/files/software-copyright-cert.png");
|
|
archive("申报成果", "2026年度科技型中小企业评价申报材料", "申报", null,
|
|
"科技型中小企业评价申报材料.docx", "docx", 420_000L, "陈静", "2026-03-30",
|
|
"科技型中小企业,申报,2026", "科技型中小企业入库评价申报书及佐证材料。",
|
|
"内部", "https://oa.kaidi.com/files/sme-evaluation-application.docx");
|
|
|
|
archive("制度文件", "ISO9001质量管理体系文件", "手动", null,
|
|
"ISO9001质量管理体系文件.pdf", "pdf", 5_240_000L, "李娜", "2026-02-20",
|
|
"ISO9001,质量管理,体系文件", "公司质量管理体系程序文件与作业指导书汇编。",
|
|
"公开", "https://oa.kaidi.com/files/iso9001-quality-manual.pdf");
|
|
archive("制度文件", "信息安全管理制度(修订稿)", "手动", null,
|
|
"信息安全管理制度-修订稿.docx", "docx", 210_000L, "张伟", "2026-05-10",
|
|
"信息安全,管理制度,修订", "账号权限、数据备份、终端安全等条款的修订稿。",
|
|
"内部", "https://oa.kaidi.com/files/infosec-policy-revised.docx");
|
|
archive("制度文件", "费用报销管理办法", "手动", null,
|
|
"费用报销管理办法.pdf", "pdf", 290_000L, "刘洋", "2026-03-12",
|
|
"费用报销,管理办法,财务制度", "规范费用报销范围、标准与审批流程的管理办法。",
|
|
"机密", "https://oa.kaidi.com/files/expense-reimbursement-policy.pdf");
|
|
|
|
archive("会议纪要", "项目周例会纪要-2026年第23周", "会议", null,
|
|
"项目周例会纪要-2026W23.docx", "docx", 96_000L, "陈静", "2026-06-08",
|
|
"周例会,会议纪要,2026", "本周项目进展、风险与行动项汇总,明确责任人。",
|
|
"内部", "https://oa.kaidi.com/files/weekly-meeting-2026w23.docx");
|
|
archive("会议纪要", "季度经营分析会纪要", "会议", null,
|
|
"季度经营分析会纪要.docx", "docx", 132_000L, "李娜", "2026-04-10",
|
|
"经营分析,会议纪要,季度", "上季度经营回顾、本季度目标分解与行动项。",
|
|
"机密", "https://oa.kaidi.com/files/quarterly-business-review.docx");
|
|
|
|
archive("技术资料", "供水调度监控模块运维操作手册", "手动", 1L,
|
|
"供水调度监控运维操作手册.pdf", "pdf", 2_180_000L, "王芳", "2026-05-28",
|
|
"运维手册,供水调度,技术资料", "供水调度监控模块的部署、运维与故障处理操作手册。",
|
|
"公开", "https://oa.kaidi.com/files/dispatch-ops-manual.pdf");
|
|
}
|
|
|
|
private void archive(String category, String title, String sourceType, Long sourceId,
|
|
String fileName, String fileType, long fileSize, String uploader,
|
|
String archiveDate, String tags, String summary,
|
|
String accessLevel, String fileUrl) {
|
|
Archive a = new Archive();
|
|
a.setCategory(category);
|
|
a.setTitle(title);
|
|
a.setSourceType(sourceType);
|
|
a.setSourceId(sourceId);
|
|
a.setFileName(fileName);
|
|
a.setFileType(fileType);
|
|
a.setFileSize(fileSize);
|
|
a.setUploader(uploader);
|
|
a.setArchiveDate(archiveDate);
|
|
a.setTags(tags);
|
|
a.setSummary(summary);
|
|
a.setAccessLevel(accessLevel);
|
|
a.setFileUrl(fileUrl);
|
|
a.setCreatedAt(Instant.now());
|
|
archiveRepo.save(a);
|
|
}
|
|
|
|
private void seedArchiveComments() {
|
|
// archiveId points at the first few seeded archives (1..5).
|
|
archiveComment(1L, "张伟", "第3页竣工数据需与结算单核对,避免口径不一致。");
|
|
archiveComment(1L, "刘洋", "建议补充监理签字页,验收资料才算完整。");
|
|
archiveComment(2L, "王芳", "培训排期请提前同步到各部门,避免与月底结账冲突。");
|
|
archiveComment(3L, "刘洋", "管网坐标列有几处空值,请回到现场补测后再入库。");
|
|
archiveComment(5L, "张伟", "成本合同金额与采购台账存在差额,请核对后回复。");
|
|
archiveComment(5L, "王芳", "设备验收报告未见附件,麻烦补传一份扫描件。");
|
|
}
|
|
|
|
private void archiveComment(Long archiveId, String author, String content) {
|
|
ArchiveComment c = new ArchiveComment();
|
|
c.setArchiveId(archiveId);
|
|
c.setAuthor(author);
|
|
c.setContent(content);
|
|
c.setCreatedAt(Instant.now());
|
|
archiveCommentRepo.save(c);
|
|
}
|
|
|
|
// ----- CRM opportunities -----
|
|
|
|
private void seedOpportunities() {
|
|
// customerId follows the seedCustomers order: 1 靖州县水利局,
|
|
// 2 江山春锦置业有限公司, 3 湖南省交通建设投资集团,
|
|
// 4 岳阳市城乡建设事务中心, 5 怀化市自然资源局.
|
|
// stage covers 线索 / 初步接触 / 方案报价 / 商务谈判 / 赢单 / 输单;
|
|
// probability rises with stage (线索 10 -> 赢单 100); status is one of
|
|
// 进行中 / 已赢单 / 已输单.
|
|
// orgUnit (归属单位) covers 经营部 / 岳阳办事处 / 长沙办事处 / 湖南分公司 /
|
|
// 广东分公司 so the org-tree domain filter has multiple buckets.
|
|
opportunity("靖州县农村供水智能调度二期项目", 1L, "靖州县水利局", "污水运营",
|
|
12000000d, "商务谈判", 75, "张伟", "老客户", "2026-08-31", "进行中", "经营部");
|
|
opportunity("怀化市政道路智慧化改造项目", 5L, "怀化市自然资源局", "市政",
|
|
8600000d, "方案报价", 50, "刘洋", "招标网", "2026-09-30", "进行中", "湖南分公司");
|
|
opportunity("岳阳城乡污水处理厂运营服务项目", 4L, "岳阳市城乡建设事务中心", "污水运营",
|
|
26000000d, "初步接触", 30, "王芳", "转介绍", "2026-12-31", "进行中", "岳阳办事处");
|
|
opportunity("湖南省高速公路机电EPC总承包项目", 3L, "湖南省交通建设投资集团", "EPC",
|
|
58000000d, "线索", 10, "张伟", "官网", "2027-03-31", "进行中", "长沙办事处");
|
|
opportunity("江山春锦住宅小区房建工程", 2L, "江山春锦置业有限公司", "房建",
|
|
4300000d, "赢单", 100, "李娜", "老客户", "2026-05-20", "已赢单", "广东分公司");
|
|
opportunity("怀化经开区污水管网咨询服务项目", 5L, "怀化市自然资源局", "咨询",
|
|
760000d, "输单", 0, "刘洋", "招标网", "2026-04-15", "已输单", "湖南分公司");
|
|
opportunity("靖州县水利局环保设备采购项目", 1L, "靖州县水利局", "环保设备",
|
|
1850000d, "方案报价", 50, "王芳", "老客户", "2026-07-31", "进行中", "经营部");
|
|
opportunity("岳阳楼区市政排水管网改造项目", 4L, "岳阳市城乡建设事务中心", "市政",
|
|
3200000d, "初步接触", 30, "刘洋", "招标网", "2026-10-15", "进行中", "岳阳办事处");
|
|
opportunity("湖南交投园区道路工程信息化项目", 3L, "湖南省交通建设投资集团", "公路",
|
|
6700000d, "商务谈判", 75, "张伟", "转介绍", "2026-08-10", "进行中", "长沙办事处");
|
|
}
|
|
|
|
private void opportunity(String name, Long customerId, String customerName, String projectType,
|
|
double amount, String stage, int probability, String owner,
|
|
String source, String expectedDate, String status, String orgUnit) {
|
|
Opportunity o = new Opportunity();
|
|
o.setName(name);
|
|
o.setCustomerId(customerId);
|
|
o.setCustomerName(customerName);
|
|
o.setProjectType(projectType);
|
|
o.setAmount(Money.of(amount));
|
|
o.setStage(stage);
|
|
o.setProbability(probability);
|
|
o.setOwner(owner);
|
|
o.setSource(source);
|
|
o.setExpectedDate(expectedDate);
|
|
o.setStatus(status);
|
|
o.setOrgUnit(orgUnit);
|
|
o.setCreatedAt(Instant.now());
|
|
opportunityRepo.save(o);
|
|
}
|
|
|
|
private void seedOpportunityFollowups() {
|
|
// opportunityId links to the seedOpportunities order (1..9).
|
|
// type is one of 电话 / 拜访 / 邮件 / 其他.
|
|
followup(1L, "拜访", "现场拜访靖州县水利局,确认二期调度范围与预算上限。",
|
|
"2026-05-12", "张伟", "本月内提交正式商务方案并报价。");
|
|
followup(1L, "电话", "与业主对接负责人电话沟通付款节点,倾向分三期支付。",
|
|
"2026-05-28", "张伟", "下周准备合同条款初稿与业主法务对接。");
|
|
followup(2L, "邮件", "向怀化市自然资源局发送智慧化改造技术方案与报价清单。",
|
|
"2026-05-20", "刘洋", "等待评标反馈,准备答疑材料。");
|
|
followup(2L, "拜访", "走访项目现场,核实道路里程与机电点位数量。",
|
|
"2026-06-02", "刘洋", "据现场情况修订工程量清单后重新报价。");
|
|
followup(3L, "电话", "首次电话接触岳阳城乡建设事务中心,了解运营服务采购意向。",
|
|
"2026-05-15", "王芳", "约定下月上门做初步技术交流。");
|
|
followup(3L, "拜访", "上门做污水处理厂运营服务初步交流,介绍公司业绩。",
|
|
"2026-06-05", "王芳", "整理同类运营案例资料发对方参考。");
|
|
followup(4L, "邮件", "收到高速机电EPC项目招标预告,发送公司资质与意向函。",
|
|
"2026-05-30", "张伟", "持续跟踪招标公告发布时间。");
|
|
followup(5L, "拜访", "与江山春锦置业完成房建工程合同条款最终确认并签约。",
|
|
"2026-05-18", "李娜", "推进首期进度款开票与回款。");
|
|
followup(5L, "电话", "电话回访签约后施工进场安排,业主表示满意。",
|
|
"2026-05-25", "李娜", "建立项目跟进台账,定期回访。");
|
|
followup(6L, "邮件", "收到怀化经开区咨询项目落标通知,竞争对手报价更低。",
|
|
"2026-04-15", "刘洋", "复盘报价策略,维护客户关系备战后续标段。");
|
|
followup(7L, "拜访", "拜访靖州县水利局确认环保设备选型与技术参数。",
|
|
"2026-05-22", "王芳", "完成设备方案比选后提交正式报价。");
|
|
followup(8L, "电话", "电话初步接触岳阳楼区排水管网改造需求,了解资金来源。",
|
|
"2026-06-03", "刘洋", "约定现场踏勘时间,准备初步方案。");
|
|
followup(9L, "拜访", "与湖南交投就园区道路信息化项目进入商务谈判阶段。",
|
|
"2026-06-06", "张伟", "敲定付款方式与质保条款,争取本月内签约。");
|
|
followup(9L, "邮件", "发送商务谈判要点纪要及合同主要条款给业主确认。",
|
|
"2026-06-09", "张伟", "等待业主反馈后安排正式签约。");
|
|
}
|
|
|
|
private void followup(Long opportunityId, String type, String content, String followDate,
|
|
String operator, String nextPlan) {
|
|
OpportunityFollowup f = new OpportunityFollowup();
|
|
f.setOpportunityId(opportunityId);
|
|
f.setType(type);
|
|
f.setContent(content);
|
|
f.setFollowDate(followDate);
|
|
f.setOperator(operator);
|
|
f.setNextPlan(nextPlan);
|
|
f.setCreatedAt(Instant.now());
|
|
opportunityFollowupRepo.save(f);
|
|
}
|
|
|
|
// ----- EHS safety checks -----
|
|
|
|
private void seedSafetyChecks() {
|
|
// type covers 安全 / 质量 / 环境; result covers 合格 / 隐患 / 不合格;
|
|
// level matches result (合格=无, 隐患/不合格=一般 or 重大);
|
|
// rectifyStatus covers 待整改 / 整改中 / 已闭环. projectId 1,2 on part of them.
|
|
safetyCheck("EHS-2026-0001", "安全", "靖州供水项目部", 1L, "施工现场临时用电规范检查",
|
|
"隐患", "一般", "配电箱未配漏电保护装置,存在触电风险。", "刘洋",
|
|
"整改中", "2026-06-20", "2026-06-05");
|
|
safetyCheck("EHS-2026-0002", "安全", "靖州供水项目部", 1L, "高处作业安全防护检查",
|
|
"不合格", "重大", "管廊高处作业未设置安全网及生命线,作业人员未系安全带。", "张伟",
|
|
"待整改", "2026-06-18", "2026-06-06");
|
|
safetyCheck("EHS-2026-0003", "质量", "吉首武水水环境治理工程", 2L, "管道焊接质量抽检",
|
|
"合格", "无", null, "陈静",
|
|
"已闭环", null, "2026-05-28");
|
|
safetyCheck("EHS-2026-0004", "质量", "吉首武水水环境治理工程", 2L, "混凝土试块强度检测",
|
|
"隐患", "一般", "部分试块28天强度低于设计值,需复检并加强养护。", "欧经理",
|
|
"整改中", "2026-06-25", "2026-06-02");
|
|
safetyCheck("EHS-2026-0005", "环境", "城镇污水运营中心", null, "污水处理出水水质监测",
|
|
"合格", "无", null, "刘洋",
|
|
"已闭环", null, "2026-05-30");
|
|
safetyCheck("EHS-2026-0006", "环境", "城镇污水运营中心", null, "污泥外运处置台账核查",
|
|
"隐患", "一般", "污泥转运联单记录不完整,缺少接收单位签收回执。", "陈静",
|
|
"待整改", "2026-06-22", "2026-06-07");
|
|
safetyCheck("EHS-2026-0007", "安全", "城镇污水运营中心", null, "有限空间作业审批检查",
|
|
"不合格", "重大", "进入泵站集水井作业前未办理有限空间作业票、未做气体检测。", "欧经理",
|
|
"整改中", "2026-06-16", "2026-06-08");
|
|
safetyCheck("EHS-2026-0008", "安全", "靖州供水项目部", 1L, "消防器材配置与有效期检查",
|
|
"合格", "无", null, "张伟",
|
|
"已闭环", null, "2026-05-26");
|
|
safetyCheck("EHS-2026-0009", "质量", "靖州供水项目部", 1L, "原材料进场验收检查",
|
|
"隐患", "重大", "一批管材无出厂合格证及检测报告即进场,存在质量风险。", "欧经理",
|
|
"待整改", "2026-06-19", "2026-06-09");
|
|
safetyCheck("EHS-2026-0010", "环境", "吉首武水水环境治理工程", 2L, "施工扬尘与噪声防控检查",
|
|
"隐患", "一般", "现场裸土未覆盖、未配备喷淋降尘设备,扬尘超标。", "刘洋",
|
|
"已闭环", "2026-06-01", "2026-05-24");
|
|
}
|
|
|
|
private void safetyCheck(String code, String type, String location, Long projectId, String item,
|
|
String result, String level, String finding, String responsible,
|
|
String rectifyStatus, String dueDate, String checkDate) {
|
|
SafetyCheck s = new SafetyCheck();
|
|
s.setCode(code);
|
|
s.setType(type);
|
|
s.setLocation(location);
|
|
s.setProjectId(projectId);
|
|
s.setItem(item);
|
|
s.setResult(result);
|
|
s.setLevel(level);
|
|
s.setFinding(finding);
|
|
s.setResponsible(responsible);
|
|
s.setRectifyStatus(rectifyStatus);
|
|
s.setDueDate(dueDate);
|
|
s.setCheckDate(checkDate);
|
|
s.setCreatedAt(Instant.now());
|
|
safetyCheckRepo.save(s);
|
|
}
|
|
|
|
// ----- three-system certifications -----
|
|
|
|
private void seedCertifications() {
|
|
// name covers ISO9001 / ISO14001 / ISO45001 / 安全生产标准化 / 施工资质;
|
|
// status covers 有效 / 即将到期 (at least one 即将到期 expiring in 2026 H2).
|
|
certification("ISO9001质量管理体系", "00126Q31580R0M", "方圆标志认证集团有限公司",
|
|
"供水、污水处理及水环境治理工程的设计、施工与运营服务",
|
|
"2024-08-15", "2027-08-14", "有效");
|
|
certification("ISO14001环境管理体系", "00126E31581R0M", "方圆标志认证集团有限公司",
|
|
"供水、污水处理及水环境治理工程相关活动的环境管理",
|
|
"2024-08-15", "2027-08-14", "有效");
|
|
certification("ISO45001职业健康安全管理体系", "00126S31582R0M", "方圆标志认证集团有限公司",
|
|
"供水、污水处理及水环境治理工程施工与运营的职业健康安全管理",
|
|
"2023-11-10", "2026-11-09", "即将到期");
|
|
certification("安全生产标准化", "AQBZH-2023-HN-0428", "湖南省住房和城乡建设厅",
|
|
"市政公用工程施工安全生产标准化(二级)",
|
|
"2023-12-20", "2026-12-19", "即将到期");
|
|
certification("施工资质", "D243011568-SG-2022", "湖南省住房和城乡建设厅",
|
|
"市政公用工程施工总承包二级、水利水电工程施工总承包三级",
|
|
"2022-06-01", "2027-05-31", "有效");
|
|
}
|
|
|
|
private void certification(String name, String certNo, String issuer, String scope,
|
|
String issueDate, String expireDate, String status) {
|
|
Certification c = new Certification();
|
|
c.setName(name);
|
|
c.setCertNo(certNo);
|
|
c.setIssuer(issuer);
|
|
c.setScope(scope);
|
|
c.setIssueDate(issueDate);
|
|
c.setExpireDate(expireDate);
|
|
c.setStatus(status);
|
|
c.setCreatedAt(Instant.now());
|
|
certificationRepo.save(c);
|
|
}
|
|
|
|
// ----- unified budget / cost center -----
|
|
|
|
private void seedBudgets() {
|
|
// element covers 人工费 / 材料费 / 机械费 / 差旅费 / 管理费 / 外协费 / 分包费;
|
|
// period covers 年度 / 季度 / 月度; status covers 执行中 / 超支 / 已结.
|
|
// projectId 1,2 on part of them; companySubject covers
|
|
// 湖南凯迪工程科技有限公司 / 智铖造(湖南)建设有限公司 / 江山春锦置业有限公司.
|
|
// budgetAmount vs actualAmount designed so execution rate (actual/budget)
|
|
// spreads high and low; 3 rows are 超支 (actual>budget) and 2 are 已结.
|
|
budget("靖州供水项目人工费预算", 1L, "湖南凯迪工程科技有限公司", "人工费",
|
|
"2026", "年度", 1800000d, 1260000d, "张伟", "执行中");
|
|
budget("靖州供水项目材料费预算", 1L, "湖南凯迪工程科技有限公司", "材料费",
|
|
"2026", "年度", 2600000d, 2860000d, "刘洋", "超支");
|
|
budget("靖州供水项目机械费预算", 1L, "湖南凯迪工程科技有限公司", "机械费",
|
|
"2026", "季度", 760000d, 418000d, "刘洋", "执行中");
|
|
budget("靖州供水项目分包费预算", 1L, "智铖造(湖南)建设有限公司", "分包费",
|
|
"2026", "年度", 1600000d, 1600000d, "刘洋", "已结");
|
|
budget("新版OA推广项目外协费预算", 2L, "湖南凯迪工程科技有限公司", "外协费",
|
|
"2026", "季度", 480000d, 504000d, "陈静", "超支");
|
|
budget("新版OA推广项目差旅费预算", 2L, "湖南凯迪工程科技有限公司", "差旅费",
|
|
"2026", "月度", 60000d, 28500d, "龚丽娟", "执行中");
|
|
budget("江山春锦项目人工费预算", null, "江山春锦置业有限公司", "人工费",
|
|
"2026", "年度", 900000d, 612000d, "李娜", "执行中");
|
|
budget("江山春锦项目管理费预算", null, "江山春锦置业有限公司", "管理费",
|
|
"2026", "年度", 320000d, 352000d, "李娜", "超支");
|
|
budget("集团本部管理费预算", null, "湖南凯迪工程科技有限公司", "管理费",
|
|
"2026", "年度", 4200000d, 1890000d, "张伟", "执行中");
|
|
budget("集团本部差旅费预算", null, "湖南凯迪工程科技有限公司", "差旅费",
|
|
"2026", "季度", 240000d, 226800d, "龚丽娟", "执行中");
|
|
budget("智铖造劳务外协费预算", null, "智铖造(湖南)建设有限公司", "外协费",
|
|
"2026", "月度", 150000d, 97500d, "刘洋", "执行中");
|
|
budget("供水调度设备机械费预算", 1L, "智铖造(湖南)建设有限公司", "机械费",
|
|
"2026", "年度", 520000d, 520000d, "龚丽娟", "已结");
|
|
}
|
|
|
|
private void budget(String name, Long projectId, String companySubject, String element,
|
|
String year, String period, double budgetAmount, double actualAmount,
|
|
String owner, String status) {
|
|
Budget b = new Budget();
|
|
b.setName(name);
|
|
b.setProjectId(projectId);
|
|
b.setCompanySubject(companySubject);
|
|
b.setElement(element);
|
|
b.setYear(year);
|
|
b.setPeriod(period);
|
|
b.setBudgetAmount(Money.of(budgetAmount));
|
|
b.setActualAmount(Money.of(actualAmount));
|
|
b.setOwner(owner);
|
|
b.setStatus(status);
|
|
b.setCreatedAt(Instant.now());
|
|
budgetRepo.save(b);
|
|
}
|
|
|
|
// ----- unified bidding projects -----
|
|
|
|
private void seedBids() {
|
|
// projectType covers 房建 / 市政 / 公路 / EPC / 咨询 / 环保设备 / 污水运营;
|
|
// bidMethod covers 公开招标 / 邀请招标 / 竞争性谈判; status covers
|
|
// 投标准备 / 已投标 / 中标 / 未中标 / 废标 (中标 has 3 rows).
|
|
// tenderee uses 靖州县水利局 / 湖南省交通建设投资集团 / 岳阳市城乡建设事务中心 /
|
|
// 怀化市自然资源局. controlPrice spans millions to over 100M; bidAmount is
|
|
// slightly below controlPrice (winning bids quote more competitively);
|
|
// deposit is 1-2% of bidAmount. opportunityId links to seedOpportunities
|
|
// (1..9); winning bids link to projectId (1,2). owner uses 张伟/刘洋/王芳.
|
|
// orgUnit (归属单位) covers 经营部 / 岳阳办事处 / 长沙办事处 / 湖南分公司 /
|
|
// 广东分公司 so the org-tree domain filter has multiple buckets.
|
|
bid("靖州县农村供水智能调度二期项目", "JZSL-ZB-2026-018", "靖州县水利局", "污水运营",
|
|
12000000d, 11600000d, 232000d, "公开招标", "中标",
|
|
"2026-05-15", "2026-05-20", 1L, 1L, "张伟", "经营部");
|
|
bid("湖南省高速公路机电EPC总承包项目", "HNJT-ZB-2026-007", "湖南省交通建设投资集团", "EPC",
|
|
120000000d, 118500000d, 2370000d, "公开招标", "投标准备",
|
|
"2026-07-10", "2026-07-15", 4L, null, "张伟", "长沙办事处");
|
|
bid("岳阳城乡污水处理厂运营服务项目", "YYCX-ZB-2026-031", "岳阳市城乡建设事务中心", "污水运营",
|
|
26000000d, 25400000d, 508000d, "公开招标", "已投标",
|
|
"2026-06-02", "2026-06-08", 3L, null, "王芳", "岳阳办事处");
|
|
bid("怀化市政道路智慧化改造项目", "HHZR-ZB-2026-022", "怀化市自然资源局", "市政",
|
|
8600000d, 8450000d, 126750d, "公开招标", "已投标",
|
|
"2026-06-05", "2026-06-12", 2L, null, "刘洋", "湖南分公司");
|
|
bid("岳阳楼区市政排水管网改造项目", "YYCX-ZB-2026-040", "岳阳市城乡建设事务中心", "市政",
|
|
3200000d, 3120000d, 46800d, "邀请招标", "中标",
|
|
"2026-05-26", "2026-05-30", 8L, 2L, "刘洋", "岳阳办事处");
|
|
bid("靖州县水利局环保设备采购项目", "JZSL-ZB-2026-026", "靖州县水利局", "环保设备",
|
|
1850000d, 1788000d, 26820d, "竞争性谈判", "中标",
|
|
"2026-06-01", "2026-06-04", 7L, 1L, "王芳", "经营部");
|
|
bid("湖南交投园区道路工程信息化项目", "HNJT-ZB-2026-015", "湖南省交通建设投资集团", "公路",
|
|
6700000d, 6620000d, 99300d, "邀请招标", "投标准备",
|
|
"2026-08-05", "2026-08-10", 9L, null, "张伟", "长沙办事处");
|
|
bid("怀化经开区污水管网咨询服务项目", "HHZR-ZB-2026-009", "怀化市自然资源局", "咨询",
|
|
760000d, 745000d, 11175d, "公开招标", "未中标",
|
|
"2026-04-08", "2026-04-15", 6L, null, "刘洋", "湖南分公司");
|
|
bid("岳阳房建保障性住房工程项目", "YYCX-ZB-2026-013", "岳阳市城乡建设事务中心", "房建",
|
|
43000000d, 42600000d, 639000d, "公开招标", "未中标",
|
|
"2026-03-20", "2026-03-26", null, null, "王芳", "广东分公司");
|
|
bid("湖南交投绕城高速养护工程项目", "HNJT-ZB-2026-003", "湖南省交通建设投资集团", "公路",
|
|
9800000d, 9750000d, 146250d, "竞争性谈判", "废标",
|
|
"2026-02-18", "2026-02-22", null, null, "张伟", "长沙办事处");
|
|
}
|
|
|
|
private void bid(String projectName, String bidNo, String tenderee, String projectType,
|
|
double controlPrice, double bidAmount, double deposit, String bidMethod,
|
|
String status, String bidDate, String openDate, Long opportunityId,
|
|
Long projectId, String owner, String orgUnit) {
|
|
Bid b = new Bid();
|
|
b.setProjectName(projectName);
|
|
b.setBidNo(bidNo);
|
|
b.setTenderee(tenderee);
|
|
b.setProjectType(projectType);
|
|
b.setControlPrice(Money.of(controlPrice));
|
|
b.setBidAmount(Money.of(bidAmount));
|
|
b.setDeposit(Money.of(deposit));
|
|
b.setBidMethod(bidMethod);
|
|
b.setStatus(status);
|
|
b.setBidDate(bidDate);
|
|
b.setOpenDate(openDate);
|
|
b.setOpportunityId(opportunityId);
|
|
b.setProjectId(projectId);
|
|
b.setOwner(owner);
|
|
b.setOrgUnit(orgUnit);
|
|
b.setCreatedAt(Instant.now());
|
|
bidRepo.save(b);
|
|
}
|
|
|
|
// ----- unified intelligence center -----
|
|
|
|
private void seedIntel() {
|
|
// category covers 招标公告 / 中标公示 / 政策法规 / 竞品动态 / 客户动态 / 行业资讯
|
|
// (招标公告 has 5 rows around 凯迪主业: 农村供水 / 市政污水 / 水利EPC / 环保设备).
|
|
// status covers 待评估 / 跟进中 / 已转商机 / 已忽略; the 3 已转商机 rows carry
|
|
// opportunityId linking to seedOpportunities (1..3). source/region span
|
|
// 湖南省公共资源交易中心 / 中国政府采购网 / 全国公共资源交易平台 / 水利部网站 /
|
|
// 客户官网 and 湖南 / 怀化 / 岳阳 / 靖州 / 全国. owner uses 张伟 / 刘洋 / 王芳.
|
|
intel("靖州县2026年农村供水维修养护项目公开招标公告", "招标公告",
|
|
"湖南省公共资源交易中心", "靖州", "2026-06-03", "2026-06-04",
|
|
"农村供水",
|
|
"https://www.hnsggzy.com/jyxx/zbgg/2026/JZNCGS-018.html",
|
|
"靖州县2026年农村供水维修养护项目公开招标,预算约860万,投标截止6月底,要求具备市政或水利施工资质。",
|
|
"已转商机", 1L, "张伟");
|
|
intel("怀化市鹤城区市政污水管网改造工程招标公告", "招标公告",
|
|
"怀化市公共资源交易中心", "怀化", "2026-06-05", "2026-06-06",
|
|
"污水处理",
|
|
"https://www.hhggzy.gov.cn/jyxx/zbgg/2026/HHSZ-022.html",
|
|
"怀化市鹤城区市政污水管网改造工程公开招标,控制价约2300万,采用EPC总承包方式,重点考察同类业绩。",
|
|
"跟进中", null, "刘洋");
|
|
intel("岳阳市城乡污水处理厂运营服务项目采购公告", "招标公告",
|
|
"中国政府采购网", "岳阳", "2026-05-28", "2026-05-30",
|
|
"污水处理",
|
|
"https://www.ccgp.gov.cn/cggg/dfgg/gkzb/2026/YYCX-031.html",
|
|
"岳阳市城乡污水处理厂三年运营服务采购,年运营费约2600万,要求具备污水运营业绩与环保资质。",
|
|
"已转商机", 3L, "王芳");
|
|
intel("湖南省高速公路机电EPC总承包项目招标预公告", "招标公告",
|
|
"全国公共资源交易平台", "湖南", "2026-06-01", "2026-06-02",
|
|
"EPC",
|
|
"https://ggzy.hunan.gov.cn/jyxx/zbyg/2026/HNJT-007.html",
|
|
"湖南省高速公路机电系统EPC总承包项目发布招标预公告,估算投资约1.2亿,正式招标预计7月发布。",
|
|
"待评估", null, "张伟");
|
|
intel("靖州县水利局环保设备采购竞争性谈判公告", "招标公告",
|
|
"靖州县公共资源交易平台", "靖州", "2026-05-30", "2026-06-01",
|
|
"环保设备",
|
|
"https://www.hnsggzy.com/jyxx/jtgg/2026/JZSL-026.html",
|
|
"靖州县水利局拟采购一批水质监测与污水处理环保设备,预算约185万,采用竞争性谈判方式。",
|
|
"已转商机", 2L, "王芳");
|
|
|
|
intel("靖州县农村供水智能调度二期项目中标公示", "中标公示",
|
|
"湖南省公共资源交易中心", "靖州", "2026-05-22", "2026-05-23",
|
|
"农村供水",
|
|
"https://www.hnsggzy.com/jyxx/zbgs/2026/JZNCGS-018-result.html",
|
|
"靖州县农村供水智能调度二期项目中标公示,湖南凯迪工程科技有限公司以1160万中标,公示期三天。",
|
|
"已忽略", null, "张伟");
|
|
intel("怀化经开区污水管网咨询服务项目中标公示", "中标公示",
|
|
"怀化市公共资源交易中心", "怀化", "2026-04-16", "2026-04-17",
|
|
"污水处理",
|
|
"https://www.hhggzy.gov.cn/jyxx/zbgs/2026/HHZR-009-result.html",
|
|
"怀化经开区污水管网咨询服务项目由本地竞品以低价中标,凯迪未入围,可作为后续报价参考。",
|
|
"已忽略", null, "刘洋");
|
|
|
|
intel("水利部关于加快推进农村供水高质量发展的指导意见", "政策法规",
|
|
"水利部网站", "全国", "2026-05-18", "2026-05-19",
|
|
"农村供水",
|
|
"http://www.mwr.gov.cn/zwgk/zcfg/2026/ncgsfz.html",
|
|
"水利部印发指导意见,明确十四五末农村自来水普及率目标,鼓励城乡供水一体化与智能化运维,利好供水项目储备。",
|
|
"跟进中", null, "张伟");
|
|
intel("湖南省财政厅下达2026年城镇污水处理提质增效专项资金", "政策法规",
|
|
"中国政府采购网", "湖南", "2026-05-10", "2026-05-12",
|
|
"污水处理",
|
|
"https://www.ccgp.gov.cn/zcfg/dffg/2026/hncz-wszl.html",
|
|
"湖南省财政厅下达污水处理提质增效专项资金,重点支持市州污水管网与处理厂改造,相关招标有望陆续释放。",
|
|
"待评估", null, "刘洋");
|
|
|
|
intel("中国水利水电第八工程局中标怀化重点水利工程", "竞品动态",
|
|
"全国公共资源交易平台", "怀化", "2026-05-25", "2026-05-26",
|
|
"水利EPC",
|
|
"https://ggzy.hunan.gov.cn/jyxx/zbgs/2026/sdj-hh.html",
|
|
"竞品中国水利水电第八工程局中标怀化重点水利枢纽工程,金额约3.8亿,显示其在湘西水利市场持续发力。",
|
|
"待评估", null, "刘洋");
|
|
|
|
intel("靖州县水利局领导调研城乡供水一体化建设", "客户动态",
|
|
"客户官网", "靖州", "2026-06-06", "2026-06-07",
|
|
"农村供水",
|
|
"http://www.jingzhou.gov.cn/slj/dt/2026/cxgsyth.html",
|
|
"靖州县水利局主要领导调研城乡供水一体化建设,提出年内启动三期智能调度项目,建议提前对接需求。",
|
|
"跟进中", null, "张伟");
|
|
|
|
intel("2026年湖南省水务环保产业发展趋势研究报告发布", "行业资讯",
|
|
"中国政府采购网", "湖南", "2026-05-15", "2026-05-16",
|
|
"污水处理",
|
|
"https://www.ccgp.gov.cn/hyzx/2026/hnswhb-report.html",
|
|
"行业报告指出湖南县域供水与污水运营市场年增长超两成,PPP与EPC模式成为主流,建议加大区域布局。",
|
|
"待评估", null, "王芳");
|
|
}
|
|
|
|
private void intel(String title, String category, String source, String region,
|
|
String publishDate, String captureDate, String keyword, String refUrl,
|
|
String summary, String status, Long opportunityId, String owner) {
|
|
Intel i = new Intel();
|
|
i.setTitle(title);
|
|
i.setCategory(category);
|
|
i.setSource(source);
|
|
i.setRegion(region);
|
|
i.setPublishDate(publishDate);
|
|
i.setCaptureDate(captureDate);
|
|
i.setKeyword(keyword);
|
|
i.setRefUrl(refUrl);
|
|
i.setSummary(summary);
|
|
i.setStatus(status);
|
|
i.setOpportunityId(opportunityId);
|
|
i.setOwner(owner);
|
|
i.setCreatedAt(Instant.now());
|
|
intelRepo.save(i);
|
|
}
|
|
|
|
// ----- R&D innovation center (business chain 6) -----
|
|
|
|
private void seedRd() {
|
|
// Chain 6: RdProject (研发立项) -> Patent (知识产权/专利) ->
|
|
// Declaration (政府项目申报), linked by rdProjectId. RdProjects are saved
|
|
// first so their generated ids (1..8) can be referenced as foreign keys
|
|
// by the patents and declarations below.
|
|
// field covers 农村供水 / 污水处理 / 生物质能 / 智能装备 / 环保材料 /
|
|
// 水环境治理; stage covers 立项 / 研发中 / 中试 / 结题 / 验收; progress
|
|
// spans 20..100; budget spans hundreds of thousands to a few million;
|
|
// department uses 创新研发中心 / 设计研究中心 / 制造管理中心; leader uses
|
|
// 张伟 / 刘洋 / 王芳 / 欧阳明.
|
|
RdProject r1 = rdProject("农村供水智能调度算法研究", "RD-2026-001", "农村供水", "张伟",
|
|
"创新研发中心", 2600000d, "2025-09-01", "2026-12-31", "研发中", 55,
|
|
"已完成调度模型构建与仿真验证,进入算法迭代阶段。");
|
|
RdProject r2 = rdProject("村镇污水处理工艺优化研究", "RD-2026-002", "污水处理", "刘洋",
|
|
"创新研发中心", 1800000d, "2025-06-01", "2026-09-30", "中试", 70,
|
|
"新型组合工艺中试出水稳定达标,处理能耗下降约15%。");
|
|
RdProject r3 = rdProject("生物质燃料发酵工艺研究", "RD-2026-003", "生物质能", "欧阳明",
|
|
"设计研究中心", 3200000d, "2024-12-01", "2026-06-30", "验收", 100,
|
|
"完成发酵工艺定型与示范线建设,产气率达到设计指标,通过结题验收。");
|
|
RdProject r4 = rdProject("供水管网漏损监测装备研发", "RD-2026-004", "智能装备", "王芳",
|
|
"制造管理中心", 1500000d, "2025-08-15", "2027-03-31", "研发中", 45,
|
|
"完成监测终端样机与定位算法初版,进入现场试点准备。");
|
|
RdProject r5 = rdProject("环保滤料研发与产业化", "RD-2026-005", "环保材料", "刘洋",
|
|
"设计研究中心", 980000d, "2025-10-01", "2026-12-31", "中试", 60,
|
|
"新型复合滤料中试性能优于同类产品,启动量产工艺设计。");
|
|
RdProject r6 = rdProject("城乡水环境治理一体化技术研究", "RD-2026-006", "水环境治理", "张伟",
|
|
"创新研发中心", 4200000d, "2025-03-01", "2027-06-30", "研发中", 38,
|
|
"完成流域水环境模型搭建与方案比选,进入关键技术攻关。");
|
|
RdProject r7 = rdProject("农村供水水质在线监测系统", "RD-2026-007", "农村供水", "王芳",
|
|
"制造管理中心", 760000d, "2026-01-10", "2026-11-30", "立项", 20,
|
|
"完成需求分析与系统总体方案,启动核心模块设计。");
|
|
RdProject r8 = rdProject("污泥资源化处理装备开发", "RD-2026-008", "智能装备", "欧阳明",
|
|
"设计研究中心", 2100000d, "2025-05-01", "2026-08-31", "结题", 90,
|
|
"完成成套装备研制与连续运行考核,整理结题材料申请验收。");
|
|
|
|
// Patents: type covers 发明专利 / 实用新型 / 外观设计 / 软件著作权 / 商标;
|
|
// status covers 已授权 (4) / 申请中 / 已受理 / 已驳回; 8 carry a real
|
|
// rdProjectId (r1..r8) and 2 are null. applicant uses 湖南凯迪工程科技有限公司.
|
|
// feeDueDate / annualFee (专利年费) are filled for 已授权 patents only;
|
|
// some due dates fall in 2026 H2 (临近) and one is already past (已过期);
|
|
// not-yet-granted patents leave feeDueDate null and annualFee 0.
|
|
patent("一种农村供水智能调度方法及系统", "发明专利", "ZL2026100012345.6",
|
|
"湖南凯迪工程科技有限公司", "张伟,陈志强,刘洋", r1.getId(), "2026-02-18", "已授权",
|
|
"2026-09-30", 2700d);
|
|
patent("一种村镇污水处理组合工艺装置", "实用新型", "ZL2026200023456.7",
|
|
"湖南凯迪工程科技有限公司", "刘洋,王芳", r2.getId(), "2026-03-05", "已授权",
|
|
"2026-11-15", 900d);
|
|
patent("生物质燃料发酵反应器", "发明专利", "ZL2025100034567.8",
|
|
"湖南凯迪工程科技有限公司", "欧阳明,周敏", r3.getId(), "2025-08-12", "已授权",
|
|
"2026-03-31", 2400d);
|
|
patent("供水管网漏损监测终端外观设计", "外观设计", "ZL2026300045678.9",
|
|
"湖南凯迪工程科技有限公司", "王芳", r4.getId(), "2026-04-20", "申请中",
|
|
null, 0d);
|
|
patent("环保复合滤料制备方法", "发明专利", "ZL2026100056789.0",
|
|
"湖南凯迪工程科技有限公司", "刘洋,孙磊", r5.getId(), "2026-05-08", "已受理",
|
|
null, 0d);
|
|
patent("供水管网漏损监测分析软件", "软件著作权", "软著登字第8312456号",
|
|
"湖南凯迪工程科技有限公司", "王芳,赵敏", r4.getId(), "2026-03-28", "已授权",
|
|
"2026-12-20", 600d);
|
|
patent("水环境治理一体化调控平台", "软件著作权", "软著登字第8327891号",
|
|
"湖南凯迪工程科技有限公司", "张伟,陈志强", r6.getId(), "2026-04-15", "申请中",
|
|
null, 0d);
|
|
patent("一种农村供水水质在线监测仪", "实用新型", "ZL2026200067890.1",
|
|
"湖南凯迪工程科技有限公司", "王芳", r7.getId(), "2026-05-22", "已受理",
|
|
null, 0d);
|
|
patent("凯迪水务环保商标", "商标", "注册号62318745",
|
|
"湖南凯迪工程科技有限公司", "湖南凯迪工程科技有限公司", null, "2026-01-15", "申请中",
|
|
null, 0d);
|
|
patent("一种污泥脱水装置", "实用新型", "ZL2025200078901.2",
|
|
"湖南凯迪工程科技有限公司", "欧阳明", null, "2025-09-30", "已驳回",
|
|
null, 0d);
|
|
|
|
// Declarations: program covers all 5 categories 高新技术企业 /
|
|
// 科技型中小企业 / 省重点研发计划 / 专精特新 / 创新平台; status covers
|
|
// 准备中 / 已申报 / 已立项 / 已结题 / 未通过; most carry a real rdProjectId.
|
|
// authority uses 湖南省科技厅 / 湖南省工信厅 / 怀化市科技局 /
|
|
// 国家高新技术企业认定管理工作领导小组; amount spans 20万..500万; deadline
|
|
// in 2026. owner uses 张伟 / 王芳.
|
|
declaration("2026年度高新技术企业认定申报", "高新技术企业",
|
|
"国家高新技术企业认定管理工作领导小组", r1.getId(), 0d, "2026-08-31", "准备中", "张伟");
|
|
declaration("农村供水智能调度省重点研发计划项目申报", "省重点研发计划",
|
|
"湖南省科技厅", r1.getId(), 5000000d, "2026-04-30", "已立项", "张伟");
|
|
declaration("村镇污水处理工艺优化省重点研发计划申报", "省重点研发计划",
|
|
"湖南省科技厅", r2.getId(), 3000000d, "2026-03-31", "已结题", "张伟");
|
|
declaration("生物质能装备专精特新中小企业申报", "专精特新",
|
|
"湖南省工信厅", r3.getId(), 800000d, "2026-06-30", "已申报", "王芳");
|
|
declaration("2026年度科技型中小企业评价入库", "科技型中小企业",
|
|
"湖南省科技厅", r5.getId(), 200000d, "2026-09-30", "已申报", "王芳");
|
|
declaration("水环境治理工程技术研究中心创新平台申报", "创新平台",
|
|
"怀化市科技局", r6.getId(), 1500000d, "2026-05-31", "未通过", "张伟");
|
|
declaration("智能水务装备制造业创新平台申报", "创新平台",
|
|
"湖南省工信厅", r8.getId(), 2000000d, "2026-10-31", "准备中", "王芳");
|
|
}
|
|
|
|
private RdProject rdProject(String name, String code, String field, String leader,
|
|
String department, double budget, String startDate, String endDate,
|
|
String stage, int progress, String achievement) {
|
|
RdProject p = new RdProject();
|
|
p.setName(name);
|
|
p.setCode(code);
|
|
p.setField(field);
|
|
p.setLeader(leader);
|
|
p.setDepartment(department);
|
|
p.setBudget(Money.of(budget));
|
|
p.setStartDate(startDate);
|
|
p.setEndDate(endDate);
|
|
p.setStage(stage);
|
|
p.setProgress(progress);
|
|
p.setAchievement(achievement);
|
|
p.setCreatedAt(Instant.now());
|
|
return rdProjectRepo.save(p);
|
|
}
|
|
|
|
private void patent(String name, String type, String patentNo, String applicant,
|
|
String inventors, Long rdProjectId, String applyDate, String status,
|
|
String feeDueDate, double annualFee) {
|
|
Patent p = new Patent();
|
|
p.setName(name);
|
|
p.setType(type);
|
|
p.setPatentNo(patentNo);
|
|
p.setApplicant(applicant);
|
|
p.setInventors(inventors);
|
|
p.setRdProjectId(rdProjectId);
|
|
p.setApplyDate(applyDate);
|
|
p.setStatus(status);
|
|
p.setFeeDueDate(feeDueDate);
|
|
p.setAnnualFee(Money.of(annualFee));
|
|
p.setCreatedAt(Instant.now());
|
|
patentRepo.save(p);
|
|
}
|
|
|
|
private void declaration(String name, String program, String authority, Long rdProjectId,
|
|
double amount, String deadline, String status, String owner) {
|
|
Declaration d = new Declaration();
|
|
d.setName(name);
|
|
d.setProgram(program);
|
|
d.setAuthority(authority);
|
|
d.setRdProjectId(rdProjectId);
|
|
d.setAmount(Money.of(amount));
|
|
d.setDeadline(deadline);
|
|
d.setStatus(status);
|
|
d.setOwner(owner);
|
|
d.setCreatedAt(Instant.now());
|
|
declarationRepo.save(d);
|
|
}
|
|
|
|
// ----- declaration template library (申报模板自动搭建, business chain 6) -----
|
|
|
|
private void seedDeclarationTemplates() {
|
|
// program covers all 5 categories 高新技术企业 / 科技型中小企业 /
|
|
// 省重点研发计划 / 专精特新 / 创新平台; status is 启用 for 4 and 停用 for 1;
|
|
// version uses V1.0 / V2.0; updatedBy uses 王芳 / 张伟 / 知识产权部.
|
|
// requiredMaterials and autoCheckRules are comma-separated; bodyTemplate
|
|
// carries placeholders such as {企业名称} {申报年度} {研发投入}.
|
|
declarationTemplate("高新技术企业认定申报模板", "高新技术企业",
|
|
"国家高新技术企业认定管理工作领导小组",
|
|
"营业执照,审计报告,研发费用专项审计,高新技术产品收入专项审计,知识产权清单,科技人员名单,研发项目立项书",
|
|
"研发费用占比≥3%,科技人员占比≥10%,高新技术产品收入占比≥60%,知识产权≥1项,近三年研发费用归集完整",
|
|
"{企业名称}申请认定国家高新技术企业。{申报年度}企业研发投入为{研发投入}元,"
|
|
+ "拥有自主知识产权及核心技术,主营高新技术产品(服务)收入占比符合认定标准。",
|
|
"V2.0", "启用", "王芳");
|
|
declarationTemplate("科技型中小企业评价入库模板", "科技型中小企业",
|
|
"湖南省科技厅",
|
|
"营业执照,上年度财务报表,研发费用辅助账,科技人员名单,知识产权或科技成果证明",
|
|
"职工总数≤500人,年销售收入≤2亿元,研发费用占比达标,科技人员占比≥10%",
|
|
"{企业名称}申请{申报年度}科技型中小企业评价入库。企业研发投入{研发投入}元,"
|
|
+ "科技人员及研发费用占比符合评价指标要求。",
|
|
"V1.0", "启用", "张伟");
|
|
declarationTemplate("省重点研发计划项目申报模板", "省重点研发计划",
|
|
"湖南省科技厅",
|
|
"项目申报书,研发立项书,可行性研究报告,经费预算表,研发团队简历,前期成果证明,配套资金证明",
|
|
"立项研发项目≥1项,经费预算合理,研发团队人员齐备,前期成果支撑充分",
|
|
"{企业名称}申报{申报年度}省重点研发计划项目。项目总投入{研发投入}元,"
|
|
+ "围绕关键技术攻关设置研究内容、技术指标与考核节点。",
|
|
"V2.0", "启用", "张伟");
|
|
declarationTemplate("专精特新中小企业申报模板", "专精特新",
|
|
"湖南省工信厅",
|
|
"营业执照,近两年财务报表,主导产品说明,知识产权清单,质量管理体系认证,研发投入证明",
|
|
"主营业务收入占比≥70%,研发费用占比达标,有效知识产权≥2项,经营稳定无失信记录",
|
|
"{企业名称}申报专精特新中小企业。{申报年度}研发投入{研发投入}元,"
|
|
+ "主导产品市场占有率与专业化、精细化、特色化、新颖化水平突出。",
|
|
"V1.0", "启用", "知识产权部");
|
|
declarationTemplate("工程技术研究中心创新平台申报模板", "创新平台",
|
|
"湖南省工信厅",
|
|
"申报书,平台建设方案,研发场地及设备清单,研发人员名单,合作单位协议,已承担项目清单",
|
|
"研发场地及设备满足要求,固定研发人员≥10人,近三年承担研发项目≥3项,有产学研合作",
|
|
"{企业名称}申报工程技术研究中心创新平台。{申报年度}计划投入{研发投入}元,"
|
|
+ "围绕行业共性关键技术开展研发、中试与成果转化。",
|
|
"V1.0", "停用", "知识产权部");
|
|
}
|
|
|
|
private void declarationTemplate(String name, String program, String authority,
|
|
String requiredMaterials, String autoCheckRules,
|
|
String bodyTemplate, String version, String status,
|
|
String updatedBy) {
|
|
DeclarationTemplate t = new DeclarationTemplate();
|
|
t.setName(name);
|
|
t.setProgram(program);
|
|
t.setAuthority(authority);
|
|
t.setRequiredMaterials(requiredMaterials);
|
|
t.setAutoCheckRules(autoCheckRules);
|
|
t.setBodyTemplate(bodyTemplate);
|
|
t.setVersion(version);
|
|
t.setStatus(status);
|
|
t.setUpdatedBy(updatedBy);
|
|
t.setCreatedAt(Instant.now());
|
|
declarationTemplateRepo.save(t);
|
|
}
|
|
|
|
// ----- R&D expense collection (研发立项-费用-凭证 evidence chain, business chain 6) -----
|
|
|
|
private void seedRdExpenses() {
|
|
// rdProjectId points at the RdProjects seeded in seedRd (1..8);
|
|
// rdProjectName mirrors the linked project name. category covers all 6
|
|
// kinds 人工费 / 直接投入 / 折旧费用 / 无形资产摊销 / 设计费 / 其他; amount
|
|
// spans a few thousand to a few hundred thousand; occurDate is in 2026;
|
|
// voucher carries 凭证号 plus the supporting evidence (发票/工时单/合同);
|
|
// status covers 已归集 (7) / 待审核 (3) / 已驳回 (2); recorder uses
|
|
// 张伟 / 刘洋 / 王芳. Multiple expenses point at the same rdProject to form
|
|
// the 一个研发项目归集多笔费用 evidence chain (r1 carries 3, r2 carries 2).
|
|
rdExpense(1L, "农村供水智能调度算法研究", "人工费",
|
|
"研发团队2026年第一季度工时人工费", 186000d, "2026-03-31",
|
|
"PZ-2026-0101 + 工时单/工资表", "已归集", "张伟");
|
|
rdExpense(1L, "农村供水智能调度算法研究", "直接投入",
|
|
"算法仿真测试服务器及云资源采购", 92000d, "2026-02-18",
|
|
"PZ-2026-0112 + 发票/采购合同", "已归集", "刘洋");
|
|
rdExpense(1L, "农村供水智能调度算法研究", "设计费",
|
|
"外委调度模型外观与交互设计费", 45000d, "2026-04-10",
|
|
"PZ-2026-0156 + 发票/设计合同", "待审核", "王芳");
|
|
rdExpense(2L, "村镇污水处理工艺优化研究", "直接投入",
|
|
"中试装置药剂及耗材采购", 128000d, "2026-01-25",
|
|
"PZ-2026-0123 + 发票/工时单/合同", "已归集", "刘洋");
|
|
rdExpense(2L, "村镇污水处理工艺优化研究", "折旧费用",
|
|
"中试线设备2026年上半年折旧分摊", 76000d, "2026-06-30",
|
|
"PZ-2026-0210 + 折旧明细表", "已归集", "张伟");
|
|
rdExpense(3L, "生物质燃料发酵工艺研究", "人工费",
|
|
"发酵工艺研发人员人工费", 240000d, "2026-03-31",
|
|
"PZ-2026-0131 + 工时单/工资表", "已归集", "刘洋");
|
|
rdExpense(3L, "生物质燃料发酵工艺研究", "无形资产摊销",
|
|
"发酵工艺专利技术无形资产摊销", 58000d, "2026-05-20",
|
|
"PZ-2026-0188 + 摊销明细表", "待审核", "王芳");
|
|
rdExpense(4L, "供水管网漏损监测装备研发", "直接投入",
|
|
"监测终端样机元器件及试制材料", 153000d, "2026-04-08",
|
|
"PZ-2026-0162 + 发票/采购合同", "已归集", "王芳");
|
|
rdExpense(4L, "供水管网漏损监测装备研发", "设计费",
|
|
"漏损定位算法外委软件开发设计费", 88000d, "2026-05-15",
|
|
"PZ-2026-0199 + 发票/开发合同", "已驳回", "刘洋");
|
|
rdExpense(5L, "环保滤料研发与产业化", "直接投入",
|
|
"复合滤料原料及量产工艺试验材料", 67000d, "2026-03-12",
|
|
"PZ-2026-0145 + 发票/合同", "已归集", "张伟");
|
|
rdExpense(6L, "城乡水环境治理一体化技术研究", "其他",
|
|
"流域水环境治理方案专家评审及差旅费", 8500d, "2026-02-28",
|
|
"PZ-2026-0118 + 发票/费用单", "待审核", "王芳");
|
|
rdExpense(8L, "污泥资源化处理装备开发", "折旧费用",
|
|
"成套装备试制设备折旧分摊", 39000d, "2026-04-30",
|
|
"PZ-2026-0176 + 折旧明细表", "已驳回", "刘洋");
|
|
}
|
|
|
|
private void rdExpense(Long rdProjectId, String rdProjectName, String category,
|
|
String description, double amount, String occurDate, String voucher,
|
|
String status, String recorder) {
|
|
RdExpense e = new RdExpense();
|
|
e.setRdProjectId(rdProjectId);
|
|
e.setRdProjectName(rdProjectName);
|
|
e.setCategory(category);
|
|
e.setDescription(description);
|
|
e.setAmount(Money.of(amount));
|
|
e.setOccurDate(occurDate);
|
|
e.setVoucher(voucher);
|
|
e.setStatus(status);
|
|
e.setRecorder(recorder);
|
|
e.setCreatedAt(Instant.now());
|
|
rdExpenseRepo.save(e);
|
|
}
|
|
|
|
// ----- unified contract center: templates and changes (business chain 3) -----
|
|
|
|
private void seedContractTemplates() {
|
|
// contractType covers all 5 kinds 经营合同 / 采购合同 / 成本合同 / 销售合同 /
|
|
// 法务合同; applicableSubject spans 总公司 / 分公司 / 集团小公司 / 不限;
|
|
// version uses V1.0 / V2.0; status is 启用 for 4 and 停用 for 1; updatedBy
|
|
// uses 张伟 / 王芳 / 法务部. bodyTemplate carries placeholders such as
|
|
// {甲方} {乙方} {金额} {工期}; requiredClauses is comma-separated.
|
|
contractTemplate("经营合同标准模板", "经营合同", "总公司",
|
|
"本合同由{甲方}与{乙方}就供水信息化建设事宜,经友好协商,达成如下条款。"
|
|
+ "合同总价款为人民币{金额}元,工期为{工期}。乙方应按约定节点完成交付并通过验收。",
|
|
"标的范围,合同价款,质保期,违约责任,争议解决", "V2.0", "启用", "张伟");
|
|
contractTemplate("采购合同标准模板", "采购合同", "不限",
|
|
"本采购合同由{甲方}(采购方)与{乙方}(供货方)签订。采购标的及数量见附件,"
|
|
+ "合同金额{金额}元,交货期{工期},验收合格后付款。",
|
|
"采购清单,合同价款,交货期,质量标准,验收方式,违约责任", "V1.0", "启用", "王芳");
|
|
contractTemplate("成本合同标准模板", "成本合同", "集团小公司",
|
|
"本成本合同由{甲方}与{乙方}就劳务及设备投入达成约定。合同金额{金额}元,"
|
|
+ "履约期{工期},乙方应保证投入资源满足现场施工进度要求。",
|
|
"标的范围,合同价款,履约期限,安全责任,违约责任", "V1.0", "启用", "张伟");
|
|
contractTemplate("销售合同标准模板", "销售合同", "分公司",
|
|
"本销售合同由{甲方}(出卖方)与{乙方}(买受方)签订。标的产品及规格见清单,"
|
|
+ "销售总额{金额}元,交付周期{工期},款到发货。",
|
|
"标的范围,销售价款,交付方式,售后服务,违约责任", "V2.0", "启用", "王芳");
|
|
contractTemplate("法务合同审查模板", "法务合同", "不限",
|
|
"本模板用于{甲方}对外签署合同的法务审查。审查要点包括主体资格、权利义务对等、"
|
|
+ "金额{金额}与付款条件、工期{工期}及违约救济等条款的合规性。",
|
|
"主体资格,权利义务,合同价款,保密条款,违约责任,争议解决", "V1.0", "停用", "法务部");
|
|
}
|
|
|
|
private void contractTemplate(String name, String contractType, String applicableSubject,
|
|
String bodyTemplate, String requiredClauses, String version,
|
|
String status, String updatedBy) {
|
|
ContractTemplate t = new ContractTemplate();
|
|
t.setName(name);
|
|
t.setContractType(contractType);
|
|
t.setApplicableSubject(applicableSubject);
|
|
t.setBodyTemplate(bodyTemplate);
|
|
t.setRequiredClauses(requiredClauses);
|
|
t.setVersion(version);
|
|
t.setStatus(status);
|
|
t.setUpdatedBy(updatedBy);
|
|
t.setCreatedAt(Instant.now());
|
|
contractTemplateRepo.save(t);
|
|
}
|
|
|
|
private void seedContractChanges() {
|
|
// contractId points at the contracts seeded in seedContracts (1..5);
|
|
// contractName mirrors the linked contract name. changeType covers
|
|
// 变更 / 终止 / 续签. status uses only 审批中 / 草稿 / 已驳回 here so the
|
|
// seed never writes back onto the contracts (已生效 write-back is left to
|
|
// live POST testing). amountBefore equals the linked contract amount;
|
|
// effectiveDate is in 2026; applicant uses 张伟 / 刘洋.
|
|
contractChange(1L, "靖州供水项目信息化建设合同", "变更",
|
|
"新增管网数据采集子系统,合同范围扩大", 8600000d, 9200000d,
|
|
"2026-07-01", "审批中", "张伟");
|
|
contractChange(2L, "供水调度监控设备成本合同", "变更",
|
|
"设备选型升级,单价调整", 3200000d, 3450000d,
|
|
"2026-06-20", "草稿", "刘洋");
|
|
contractChange(4L, "江山春锦项目工程咨询合同", "终止",
|
|
"项目方调整建设计划,咨询服务提前终止", 1500000d, 0d,
|
|
"2026-08-15", "已驳回", "张伟");
|
|
contractChange(1L, "靖州供水项目信息化建设合同", "续签",
|
|
"一期运维到期,续签二期运维服务", 8600000d, 8600000d,
|
|
"2026-09-30", "审批中", "刘洋");
|
|
}
|
|
|
|
private void contractChange(Long contractId, String contractName, String changeType,
|
|
String reason, double amountBefore, double amountAfter,
|
|
String effectiveDate, String status, String applicant) {
|
|
ContractChange c = new ContractChange();
|
|
c.setContractId(contractId);
|
|
c.setContractName(contractName);
|
|
c.setChangeType(changeType);
|
|
c.setReason(reason);
|
|
c.setAmountBefore(Money.of(amountBefore));
|
|
c.setAmountAfter(Money.of(amountAfter));
|
|
c.setEffectiveDate(effectiveDate);
|
|
c.setStatus(status);
|
|
c.setApplicant(applicant);
|
|
c.setCreatedAt(Instant.now());
|
|
contractChangeRepo.save(c);
|
|
}
|
|
|
|
// ----- cost-center master data (成本中心主档) -----
|
|
|
|
private void seedCostCenters() {
|
|
// ccType covers all 4 kinds 项目 / 部门 / 公司 / 工序; owner uses
|
|
// 张伟 / 刘洋 / 王芳; parentName is filled on the lower-level centers and
|
|
// left null on the top-level ones; status is 启用 for most and 停用 for one.
|
|
// budgetTotal vs. actualTotal is kept realistic, with 2 centers overspent
|
|
// (actualTotal > budgetTotal) and the rest under budget.
|
|
costCenter("CC-XM-001", "靖州供水项目成本中心", "项目", "张伟",
|
|
"工程管理中心", 8600000d, 4820000d, "启用");
|
|
costCenter("CC-XM-002", "江山春锦项目成本中心", "项目", "刘洋",
|
|
"工程管理中心", 1500000d, 1680000d, "启用");
|
|
costCenter("CC-BM-001", "工程管理中心", "部门", "张伟",
|
|
"湖南凯迪工程科技有限公司", 3200000d, 2150000d, "启用");
|
|
costCenter("CC-BM-002", "财务部成本中心", "部门", "刘洋",
|
|
"湖南凯迪工程科技有限公司", 600000d, 410000d, "启用");
|
|
costCenter("CC-BM-003", "信息中心成本中心", "部门", "王芳",
|
|
"湖南凯迪工程科技有限公司", 800000d, 920000d, "启用");
|
|
costCenter("CC-GS-001", "总公司管理费", "公司", "张伟",
|
|
null, 5000000d, 3260000d, "启用");
|
|
costCenter("CC-GX-001", "管网施工工序成本中心", "工序", "刘洋",
|
|
"靖州供水项目成本中心", 2400000d, 1180000d, "启用");
|
|
costCenter("CC-GX-002", "顶管施工工序成本中心", "工序", "王芳",
|
|
"靖州供水项目成本中心", 900000d, 360000d, "停用");
|
|
}
|
|
|
|
private void costCenter(String code, String name, String ccType, String owner,
|
|
String parentName, double budgetTotal, double actualTotal, String status) {
|
|
CostCenter c = new CostCenter();
|
|
c.setCode(code);
|
|
c.setName(name);
|
|
c.setCcType(ccType);
|
|
c.setOwner(owner);
|
|
c.setParentName(parentName);
|
|
c.setBudgetTotal(Money.of(budgetTotal));
|
|
c.setActualTotal(Money.of(actualTotal));
|
|
c.setStatus(status);
|
|
c.setCreatedAt(Instant.now());
|
|
costCenterRepo.save(c);
|
|
}
|
|
|
|
// ----- labor / material / machinery price library (人材机价格库) -----
|
|
|
|
private void seedPriceItems() {
|
|
// category covers all 3 kinds with 4 人工 / 4 材料 / 4 机械; priceType
|
|
// covers all 4 kinds 信息价 / 市场价 / 历史中标价 / 企业标准价; region uses
|
|
// 湖南 / 怀化 / 全国; unit / spec / unitPrice are realistic; effectiveDate
|
|
// is in 2026.
|
|
// 人工 (labor): unit 工日.
|
|
priceItem("人工", "普工", "综合用工", "工日", 180d, "湖南",
|
|
"本地劳务", "信息价", "2026-01-01");
|
|
priceItem("人工", "钢筋工", "中级技工", "工日", 320d, "怀化",
|
|
"湘建劳务有限公司", "市场价", "2026-03-01");
|
|
priceItem("人工", "管道安装工", "中级技工", "工日", 300d, "湖南",
|
|
"本地劳务", "企业标准价", "2026-02-01");
|
|
priceItem("人工", "技术员", "现场技术管理", "工日", 450d, "湖南",
|
|
"公司内部", "企业标准价", "2026-01-01");
|
|
// 材料 (material).
|
|
priceItem("材料", "PE给水管", "dn200 PE100 SDR17", "米", 86.5d, "湖南",
|
|
"湖南振兴管业有限公司", "市场价", "2026-04-01");
|
|
priceItem("材料", "普通硅酸盐水泥", "P.O 42.5", "吨", 420d, "怀化",
|
|
"怀化南方水泥有限公司", "信息价", "2026-03-01");
|
|
priceItem("材料", "HRB400螺纹钢筋", "dn20", "吨", 3850d, "全国",
|
|
"华菱钢铁", "信息价", "2026-04-01");
|
|
priceItem("材料", "石英砂滤料", "0.5-1.0mm 过滤用", "吨", 680d, "湖南",
|
|
"巩义滤料厂", "历史中标价", "2026-02-15");
|
|
// 机械 (machinery): unit 台班.
|
|
priceItem("机械", "履带式挖掘机", "1.0立方米 斗容", "台班", 1350d, "湖南",
|
|
"三一重工租赁", "市场价", "2026-03-01");
|
|
priceItem("机械", "潜水排污泵", "100QW 流量100立方米每小时", "台班", 280d, "怀化",
|
|
"本地租赁", "企业标准价", "2026-02-01");
|
|
priceItem("机械", "汽车起重机", "25吨", "台班", 1600d, "湖南",
|
|
"中联重科租赁", "历史中标价", "2026-01-15");
|
|
priceItem("机械", "非开挖顶管设备", "dn800 泥水平衡", "台班", 4200d, "全国",
|
|
"顶管工程公司", "历史中标价", "2026-04-10");
|
|
}
|
|
|
|
private void priceItem(String category, String name, String spec, String unit,
|
|
double unitPrice, String region, String supplier, String priceType,
|
|
String effectiveDate) {
|
|
PriceItem p = new PriceItem();
|
|
p.setCategory(category);
|
|
p.setName(name);
|
|
p.setSpec(spec);
|
|
p.setUnit(unit);
|
|
p.setUnitPrice(Money.of(unitPrice));
|
|
p.setRegion(region);
|
|
p.setSupplier(supplier);
|
|
p.setPriceType(priceType);
|
|
p.setEffectiveDate(effectiveDate);
|
|
p.setCreatedAt(Instant.now());
|
|
priceItemRepo.save(p);
|
|
}
|
|
|
|
// ----- personnel certificate library (人员证件库) -----
|
|
|
|
private void seedPersonnelCerts() {
|
|
// certType covers all 7 kinds 身份证 / 一级建造师 / 二级建造师 /
|
|
// 安全员证 / 特种作业证 / 职称证书 / 学历证书; issuer is realistic
|
|
// (住房和城乡建设部 / 应急管理厅 / 人社厅 etc.); status is kept
|
|
// self-consistent with expireDate: 6 有效 / 2 即将到期 (expire in 2026
|
|
// 下半年) / 2 已过期 (expireDate already past). 身份证 / 学历证书 carry no
|
|
// expireDate (长期).
|
|
personnelCert("张伟", "工程管理中心", "一级建造师", "湘13201826",
|
|
"住房和城乡建设部", "2018-06-15", "2027-06-14", "有效");
|
|
personnelCert("刘洋", "工程管理中心", "二级建造师", "湘243010592",
|
|
"湖南省住房和城乡建设厅", "2020-09-01", "2026-09-30", "即将到期");
|
|
personnelCert("王芳", "信息中心", "职称证书", "高工202100783",
|
|
"湖南省人力资源和社会保障厅", "2021-12-20", null, "有效");
|
|
personnelCert("欧阳明", "设计研究中心", "一级建造师", "湘13205471",
|
|
"住房和城乡建设部", "2019-03-10", "2025-03-09", "已过期");
|
|
personnelCert("李娜", "行政部", "学历证书", "1043220190512345",
|
|
"教育部学位与研究生教育发展中心", "2012-07-01", null, "有效");
|
|
personnelCert("陈静", "行政部", "身份证", "430103199005120026",
|
|
"怀化市公安局", "2015-05-20", "2035-05-19", "有效");
|
|
personnelCert("孙磊", "工程管理中心", "安全员证", "湘建安C202300456",
|
|
"湖南省住房和城乡建设厅", "2023-04-18", "2026-10-17", "即将到期");
|
|
personnelCert("周敏", "工程管理中心", "特种作业证", "T430000202100987",
|
|
"湖南省应急管理厅", "2021-06-10", "2027-06-09", "有效");
|
|
personnelCert("赵敏", "信息中心", "特种作业证", "T430000202000321",
|
|
"湖南省应急管理厅", "2020-08-15", "2026-02-14", "已过期");
|
|
personnelCert("陈志强", "设计研究中心", "二级建造师", "湘243011267",
|
|
"湖南省住房和城乡建设厅", "2022-11-05", "2028-11-04", "有效");
|
|
}
|
|
|
|
private void personnelCert(String personName, String dept, String certType, String certNo,
|
|
String issuer, String issueDate, String expireDate, String status) {
|
|
PersonnelCert c = new PersonnelCert();
|
|
c.setPersonName(personName);
|
|
c.setDept(dept);
|
|
c.setCertType(certType);
|
|
c.setCertNo(certNo);
|
|
c.setIssuer(issuer);
|
|
c.setIssueDate(issueDate);
|
|
c.setExpireDate(expireDate);
|
|
c.setStatus(status);
|
|
c.setCreatedAt(Instant.now());
|
|
personnelCertRepo.save(c);
|
|
}
|
|
|
|
// ----- intelligence collection pipeline (查网爬取 + 人工筛选) -----
|
|
|
|
private void seedCrawlSources() {
|
|
// sourceType covers all four kinds 政府采购平台 / 公共资源交易中心 /
|
|
// 企业官网 / 行业门户; region uses 湖南 / 怀化 / 靖州 / 全国; keywords stick
|
|
// to the core business (农村供水 / 污水处理 / 水利EPC / 管网 / 环保设备);
|
|
// frequency varies across 每日 / 每周 / 手动; enabled is mostly true with one
|
|
// false; lastRunAt is filled for some 2026 sources and left empty for others.
|
|
crawlSource("湖南省公共资源交易中心", "https://www.hncgp.gov.cn", "公共资源交易中心",
|
|
"湖南", "农村供水,污水处理,水利EPC,管网", "每日", true, "2026-06-10 08:30");
|
|
crawlSource("中国政府采购网", "http://www.ccgp.gov.cn", "政府采购平台",
|
|
"全国", "农村供水,污水处理,环保设备", "每日", true, "2026-06-10 08:35");
|
|
crawlSource("怀化市公共资源交易中心", "https://www.hhggzy.gov.cn", "公共资源交易中心",
|
|
"怀化", "市政污水,管网,环保设备", "每周", true, "2026-06-08 09:10");
|
|
crawlSource("靖州县政府采购平台", "https://www.jingzhou.gov.cn/zfcg", "政府采购平台",
|
|
"靖州", "农村供水,水利EPC", "每周", true, null);
|
|
crawlSource("中国水利水电第八工程局官网", "https://www.sinohydro8.com", "企业官网",
|
|
"全国", "水利EPC,管网", "手动", false, null);
|
|
crawlSource("中国水利工程协会行业门户", "http://www.cweun.org.cn", "行业门户",
|
|
"全国", "农村供水,污水处理,环保设备", "每周", true, "2026-06-05 14:20");
|
|
}
|
|
|
|
private void crawlSource(String name, String url, String sourceType, String region,
|
|
String keywords, String frequency, boolean enabled, String lastRunAt) {
|
|
CrawlSource s = new CrawlSource();
|
|
s.setName(name);
|
|
s.setUrl(url);
|
|
s.setSourceType(sourceType);
|
|
s.setRegion(region);
|
|
s.setKeywords(keywords);
|
|
s.setFrequency(frequency);
|
|
s.setEnabled(enabled);
|
|
s.setLastRunAt(lastRunAt);
|
|
s.setCreatedAt(Instant.now());
|
|
crawlSourceRepo.save(s);
|
|
}
|
|
|
|
private void seedCrawlJobs() {
|
|
// sourceId points to the seeded sources (1..6) with the matching sourceName;
|
|
// runAt uses 2026 times; fetched / screened / newIntel decrease sensibly;
|
|
// status is mostly 成功 with one 部分失败; operator uses 系统RPA / 张伟.
|
|
crawlJob(1L, "湖南省公共资源交易中心", "2026-06-10 08:30", 32, 19, 8, "成功", "系统RPA");
|
|
crawlJob(2L, "中国政府采购网", "2026-06-10 08:35", 28, 16, 6, "成功", "系统RPA");
|
|
crawlJob(3L, "怀化市公共资源交易中心", "2026-06-08 09:10", 21, 12, 5, "部分失败", "张伟");
|
|
crawlJob(6L, "中国水利工程协会行业门户", "2026-06-05 14:20", 18, 10, 4, "成功", "系统RPA");
|
|
crawlJob(1L, "湖南省公共资源交易中心", "2026-06-03 08:28", 26, 15, 6, "成功", "系统RPA");
|
|
}
|
|
|
|
private void crawlJob(Long sourceId, String sourceName, String runAt, int fetched,
|
|
int screened, int newIntel, String status, String operator) {
|
|
CrawlJob j = new CrawlJob();
|
|
j.setSourceId(sourceId);
|
|
j.setSourceName(sourceName);
|
|
j.setRunAt(runAt);
|
|
j.setFetched(fetched);
|
|
j.setScreened(screened);
|
|
j.setNewIntel(newIntel);
|
|
j.setStatus(status);
|
|
j.setOperator(operator);
|
|
j.setCreatedAt(Instant.now());
|
|
crawlJobRepo.save(j);
|
|
}
|
|
|
|
// ----- bill-of-quantities / BOM comparison (工程量清单/BOM 比对) -----
|
|
|
|
private void seedBomItems() {
|
|
// projectId points to the seeded projects (1 靖州供水项目工程信息化,
|
|
// 2 新版OA系统上线推广); category covers 分部分项 / 措施 / 其他; status is
|
|
// set to 超量 when actualQty exceeds bidQty (3 rows) and 正常 otherwise.
|
|
bomItem(1L, "靖州供水项目工程信息化", "PE给水管DN200", "m",
|
|
3200d, 3450d, 86d, "分部分项");
|
|
bomItem(1L, "靖州供水项目工程信息化", "管沟土方开挖", "m3",
|
|
5800d, 6120d, 32d, "分部分项");
|
|
bomItem(1L, "靖州供水项目工程信息化", "C20混凝土管基", "m3",
|
|
420d, 405d, 480d, "分部分项");
|
|
bomItem(1L, "靖州供水项目工程信息化", "砂石垫层", "m3",
|
|
760d, 760d, 145d, "分部分项");
|
|
bomItem(1L, "靖州供水项目工程信息化", "砖砌检查井", "座",
|
|
48d, 53d, 1850d, "分部分项");
|
|
bomItem(1L, "靖州供水项目工程信息化", "潜水泵安装", "台",
|
|
12d, 12d, 6800d, "分部分项");
|
|
bomItem(1L, "靖州供水项目工程信息化", "施工围挡", "m",
|
|
560d, 560d, 95d, "措施");
|
|
bomItem(1L, "靖州供水项目工程信息化", "基坑降水", "天",
|
|
90d, 108d, 320d, "措施");
|
|
bomItem(2L, "新版OA系统上线推广", "球墨铸铁管DN300", "m",
|
|
1500d, 1500d, 260d, "分部分项");
|
|
bomItem(2L, "新版OA系统上线推广", "管道试压及冲洗消毒", "m",
|
|
1500d, 1500d, 18d, "其他");
|
|
}
|
|
|
|
private void bomItem(Long projectId, String projectName, String name, String unit,
|
|
double bidQty, double actualQty, double unitPrice, String category) {
|
|
BomItem b = new BomItem();
|
|
b.setProjectId(projectId);
|
|
b.setProjectName(projectName);
|
|
b.setName(name);
|
|
b.setUnit(unit);
|
|
b.setBidQty(bidQty);
|
|
b.setActualQty(actualQty);
|
|
b.setUnitPrice(Money.of(unitPrice));
|
|
b.setCategory(category);
|
|
b.setStatus(actualQty > bidQty ? "超量" : "正常");
|
|
b.setCreatedAt(Instant.now());
|
|
bomItemRepo.save(b);
|
|
}
|
|
|
|
// ----- occupational-health records (职业健康, HR) -----
|
|
|
|
private void seedHealthRecords() {
|
|
// hazardFactor covers 粉尘 / 噪声 / 高处作业 / 化学品 / 振动 / 无; examType
|
|
// covers 上岗前 / 在岗期间 / 离岗 (lifecycle 上岗前-在岗-离岗); result covers
|
|
// 正常 / 复查 / 疑似职业病; status covers 正常 (5) / 待复查 (2) / 重点监护 (1);
|
|
// some nextExamDate values fall in 2026 H2.
|
|
healthRecord("陈志强", "工程管理中心", "现场施工员", "粉尘", "在岗期间",
|
|
"2026-03-12", "正常", "2027-03-12", "正常");
|
|
healthRecord("周敏", "制造管理中心", "设备操作工", "噪声", "在岗期间",
|
|
"2026-02-28", "正常", "2026-08-28", "正常");
|
|
healthRecord("孙磊", "工程管理中心", "高处作业人员", "高处作业", "上岗前",
|
|
"2026-05-06", "正常", "2027-05-06", "正常");
|
|
healthRecord("赵敏", "创新研发中心", "化验分析员", "化学品", "在岗期间",
|
|
"2026-01-20", "复查", "2026-07-20", "待复查");
|
|
healthRecord("李建国", "制造管理中心", "钻探工", "振动", "在岗期间",
|
|
"2026-04-15", "复查", "2026-10-15", "待复查");
|
|
healthRecord("吴芳", "行政人事部", "办公室文员", "无", "上岗前",
|
|
"2026-05-22", "正常", null, "正常");
|
|
healthRecord("郑伟", "工程管理中心", "电焊工", "粉尘", "在岗期间",
|
|
"2026-02-10", "疑似职业病", "2026-09-10", "重点监护");
|
|
healthRecord("黄强", "制造管理中心", "装配钳工", "噪声", "离岗",
|
|
"2026-03-30", "正常", null, "正常");
|
|
}
|
|
|
|
private void healthRecord(String personName, String dept, String post, String hazardFactor,
|
|
String examType, String examDate, String result,
|
|
String nextExamDate, String status) {
|
|
HealthRecord h = new HealthRecord();
|
|
h.setPersonName(personName);
|
|
h.setDept(dept);
|
|
h.setPost(post);
|
|
h.setHazardFactor(hazardFactor);
|
|
h.setExamType(examType);
|
|
h.setExamDate(examDate);
|
|
h.setResult(result);
|
|
h.setNextExamDate(nextExamDate);
|
|
h.setStatus(status);
|
|
h.setCreatedAt(Instant.now());
|
|
healthRecordRepo.save(h);
|
|
}
|
|
|
|
// ----- quality-management-system records (质量管理体系, ISO9001) -----
|
|
|
|
private void seedQmsRecords() {
|
|
// type covers all 5 categories 内部审核 / 管理评审 / 不符合项 /
|
|
// 纠正预防措施 / 供方质量评价; status covers 开放 / 整改中 / 已关闭.
|
|
qmsRecord("内部审核", "2026年第一次质量体系内部审核", "质量管理部",
|
|
"对工程管理中心、制造管理中心等7个部门开展ISO9001内审,覆盖全部过程。",
|
|
"2026-07-31", "整改中", "李娜");
|
|
qmsRecord("管理评审", "2025年度质量管理体系管理评审", "总经理办公室",
|
|
"评审质量方针与目标达成情况,输出体系持续改进决议。",
|
|
"2026-04-30", "已关闭", "王芳");
|
|
qmsRecord("不符合项", "施工记录可追溯性不符合项", "工程管理中心",
|
|
"靖州供水项目部分隐蔽工程验收记录签字不全,不满足程序文件要求。",
|
|
"2026-07-15", "整改中", "陈志强");
|
|
qmsRecord("不符合项", "计量器具检定超期不符合项", "制造管理中心",
|
|
"2台压力表超过检定有效期仍在使用,不符合监视和测量资源控制要求。",
|
|
"2026-06-30", "开放", "周敏");
|
|
qmsRecord("纠正预防措施", "图纸会审遗漏纠正预防措施", "设计研究中心",
|
|
"针对图纸会审遗漏问题制定纠正措施并完善设计输出评审清单。",
|
|
"2026-08-20", "整改中", "刘洋");
|
|
qmsRecord("纠正预防措施", "客户投诉响应纠正预防措施", "市场经营部",
|
|
"针对客户对工期反馈制定预防措施,优化进度计划评审流程。",
|
|
"2026-05-31", "已关闭", "李娜");
|
|
qmsRecord("供方质量评价", "2026年上半年合格供方质量评价", "采购供应部",
|
|
"对管材、设备等关键供方进行质量、交付、服务综合评价并更新合格名录。",
|
|
"2026-09-30", "开放", "孙磊");
|
|
qmsRecord("供方质量评价", "土建分包商质量履约评价", "工程管理中心",
|
|
"对在建项目土建分包商履约质量评价,1家评定为限期整改。",
|
|
"2026-07-10", "已关闭", "陈志强");
|
|
}
|
|
|
|
private void qmsRecord(String type, String title, String dept, String finding,
|
|
String dueDate, String status, String owner) {
|
|
QmsRecord q = new QmsRecord();
|
|
q.setType(type);
|
|
q.setTitle(title);
|
|
q.setDept(dept);
|
|
q.setFinding(finding);
|
|
q.setDueDate(dueDate);
|
|
q.setStatus(status);
|
|
q.setOwner(owner);
|
|
q.setCreatedAt(Instant.now());
|
|
qmsRecordRepo.save(q);
|
|
}
|
|
|
|
// ----- operation management center: wastewater clients (运营管理中心, 污水运营) -----
|
|
|
|
private void seedWastewaterClients() {
|
|
// industry covers 印染 / 化工 / 食品 / 制药 / 电镀 / 造纸; dischargeType covers
|
|
// 工业废水 / 生活污水; pollutant (主要污染物) covers COD / 氨氮 / 总磷 / 重金属;
|
|
// serviceStatus covers 运营中 (5) / 停产 (1) / 欠费 (2). Seeded ids 1..8 are
|
|
// referenced by seedWaterQualityRecords via clientId. owner uses 王芳/刘洋/陈静.
|
|
wastewaterClient("岳阳恒昌印染有限公司", "印染", "工业废水", "WW-2026-001",
|
|
3200d, "COD", "运营中", "王芳");
|
|
wastewaterClient("湖南华盛化工股份有限公司", "化工", "工业废水", "WW-2026-002",
|
|
5800d, "重金属", "运营中", "刘洋");
|
|
wastewaterClient("怀化绿源食品加工厂", "食品", "工业废水", "WW-2026-003",
|
|
1500d, "COD", "运营中", "陈静");
|
|
wastewaterClient("靖州康宁制药有限公司", "制药", "工业废水", "WW-2026-004",
|
|
2100d, "氨氮", "欠费", "王芳");
|
|
wastewaterClient("长沙金属表面电镀厂", "电镀", "工业废水", "WW-2026-005",
|
|
900d, "重金属", "运营中", "刘洋");
|
|
wastewaterClient("岳阳纸业造纸有限公司", "造纸", "工业废水", "WW-2026-006",
|
|
7600d, "COD", "停产", "陈静");
|
|
wastewaterClient("湖南鸿运印染集团", "印染", "工业废水", "WW-2026-007",
|
|
4100d, "总磷", "运营中", "王芳");
|
|
wastewaterClient("怀化高新区生活污水处理站", "食品", "生活污水", "WW-2026-008",
|
|
12000d, "氨氮", "欠费", "刘洋");
|
|
}
|
|
|
|
private void wastewaterClient(String name, String industry, String dischargeType,
|
|
String contractNo, double dailyVolume, String pollutant,
|
|
String serviceStatus, String owner) {
|
|
WastewaterClient c = new WastewaterClient();
|
|
c.setName(name);
|
|
c.setIndustry(industry);
|
|
c.setDischargeType(dischargeType);
|
|
c.setContractNo(contractNo);
|
|
c.setDailyVolume(dailyVolume);
|
|
c.setPollutant(pollutant);
|
|
c.setServiceStatus(serviceStatus);
|
|
c.setOwner(owner);
|
|
c.setCreatedAt(Instant.now());
|
|
wastewaterClientRepo.save(c);
|
|
}
|
|
|
|
// ----- operation management center: water quality records (运营管理中心, 水质监测) -----
|
|
|
|
private void seedWaterQualityRecords() {
|
|
// clientId points to the seeded wastewater clients (1..8); result covers
|
|
// 达标 / 超标 (3 rows) / 预警 (2 rows). codValue is COD (mg/L), ammoniaValue
|
|
// is 氨氮, phValue is pH, tpValue is 总磷. inspector uses 王芳/刘洋/陈静.
|
|
waterQualityRecord(1L, "岳阳恒昌印染有限公司", "2026-05-08",
|
|
86d, 12.5d, 7.2d, 0.4d, "达标", "王芳");
|
|
waterQualityRecord(1L, "岳阳恒昌印染有限公司", "2026-06-08",
|
|
132d, 18.6d, 6.8d, 0.7d, "超标", "王芳");
|
|
waterQualityRecord(2L, "湖南华盛化工股份有限公司", "2026-05-12",
|
|
72d, 9.8d, 7.5d, 0.3d, "达标", "刘洋");
|
|
waterQualityRecord(2L, "湖南华盛化工股份有限公司", "2026-06-12",
|
|
95d, 14.2d, 7.0d, 0.55d, "预警", "刘洋");
|
|
waterQualityRecord(3L, "怀化绿源食品加工厂", "2026-05-15",
|
|
64d, 8.2d, 7.3d, 0.28d, "达标", "陈静");
|
|
waterQualityRecord(4L, "靖州康宁制药有限公司", "2026-05-18",
|
|
148d, 22.4d, 6.5d, 0.82d, "超标", "王芳");
|
|
waterQualityRecord(5L, "长沙金属表面电镀厂", "2026-05-20",
|
|
58d, 6.5d, 7.6d, 0.22d, "达标", "刘洋");
|
|
waterQualityRecord(5L, "长沙金属表面电镀厂", "2026-06-20",
|
|
91d, 13.1d, 7.1d, 0.49d, "预警", "刘洋");
|
|
waterQualityRecord(6L, "岳阳纸业造纸有限公司", "2026-04-28",
|
|
78d, 10.4d, 7.4d, 0.36d, "达标", "陈静");
|
|
waterQualityRecord(7L, "湖南鸿运印染集团", "2026-05-25",
|
|
156d, 24.8d, 6.3d, 0.95d, "超标", "王芳");
|
|
waterQualityRecord(7L, "湖南鸿运印染集团", "2026-06-25",
|
|
82d, 11.2d, 7.2d, 0.41d, "达标", "王芳");
|
|
waterQualityRecord(8L, "怀化高新区生活污水处理站", "2026-05-30",
|
|
68d, 9.1d, 7.5d, 0.31d, "达标", "刘洋");
|
|
}
|
|
|
|
private void waterQualityRecord(Long clientId, String clientName, String monitorDate,
|
|
double codValue, double ammoniaValue, double phValue,
|
|
double tpValue, String result, String inspector) {
|
|
WaterQualityRecord r = new WaterQualityRecord();
|
|
r.setClientId(clientId);
|
|
r.setClientName(clientName);
|
|
r.setMonitorDate(monitorDate);
|
|
r.setCodValue(codValue);
|
|
r.setAmmoniaValue(ammoniaValue);
|
|
r.setPhValue(phValue);
|
|
r.setTpValue(tpValue);
|
|
r.setResult(result);
|
|
r.setInspector(inspector);
|
|
r.setCreatedAt(Instant.now());
|
|
waterQualityRecordRepo.save(r);
|
|
}
|
|
|
|
// ----- manufacturing management center: work orders (制造管理中心, 生产工单) -----
|
|
|
|
private void seedWorkOrders() {
|
|
// productName covers 生物质有机肥 / 复合微生物肥 / 水处理药剂PAC / 缓释肥;
|
|
// unit covers 吨 / 袋; status covers all 5 stages
|
|
// 待生产 / 生产中 / 已完工 / 质检中 / 已入库. workshop covers
|
|
// 一号车间 / 二号车间 / 三号车间. owner uses 周敏/黄强/李建国.
|
|
workOrder("WO-2026-001", "生物质有机肥", 500d, 0d, "吨",
|
|
"2026-07-10", "待生产", "一号车间", "周敏");
|
|
workOrder("WO-2026-002", "复合微生物肥", 300d, 120d, "吨",
|
|
"2026-06-20", "生产中", "一号车间", "周敏");
|
|
workOrder("WO-2026-003", "水处理药剂PAC", 200d, 200d, "吨",
|
|
"2026-06-05", "已完工", "二号车间", "黄强");
|
|
workOrder("WO-2026-004", "缓释肥", 8000d, 8000d, "袋",
|
|
"2026-06-08", "质检中", "三号车间", "李建国");
|
|
workOrder("WO-2026-005", "生物质有机肥", 600d, 600d, "吨",
|
|
"2026-05-28", "已入库", "一号车间", "周敏");
|
|
workOrder("WO-2026-006", "复合微生物肥", 450d, 0d, "吨",
|
|
"2026-07-15", "待生产", "二号车间", "黄强");
|
|
workOrder("WO-2026-007", "水处理药剂PAC", 150d, 90d, "吨",
|
|
"2026-06-25", "生产中", "二号车间", "黄强");
|
|
workOrder("WO-2026-008", "缓释肥", 10000d, 10000d, "袋",
|
|
"2026-05-30", "已入库", "三号车间", "李建国");
|
|
}
|
|
|
|
private void workOrder(String orderNo, String productName, double planQty, double actualQty,
|
|
String unit, String plannedDate, String status, String workshop,
|
|
String owner) {
|
|
WorkOrder w = new WorkOrder();
|
|
w.setOrderNo(orderNo);
|
|
w.setProductName(productName);
|
|
w.setPlanQty(planQty);
|
|
w.setActualQty(actualQty);
|
|
w.setUnit(unit);
|
|
w.setPlannedDate(plannedDate);
|
|
w.setStatus(status);
|
|
w.setWorkshop(workshop);
|
|
w.setOwner(owner);
|
|
w.setCreatedAt(Instant.now());
|
|
workOrderRepo.save(w);
|
|
}
|
|
|
|
// ----- manufacturing management center: inventory items (制造管理中心, 库存) -----
|
|
|
|
private void seedInventoryItems() {
|
|
// category covers 原料 / 半成品 / 成品 / 辅料; status is set to 低于安全线 when
|
|
// quantity is below safetyStock (3 rows) and 正常 / 超储 otherwise. location
|
|
// (库位) covers multiple warehouse zones.
|
|
inventoryItem("腐殖酸原粉", "原料", "工业级", "吨",
|
|
85d, 30d, "A区-01", "正常");
|
|
inventoryItem("微生物菌剂", "原料", "活菌5亿/g", "kg",
|
|
120d, 200d, "A区-02", "低于安全线");
|
|
inventoryItem("氯化铝溶液", "原料", "含量30%", "吨",
|
|
42d, 20d, "A区-03", "正常");
|
|
inventoryItem("有机肥半成品料", "半成品", "发酵态", "吨",
|
|
60d, 40d, "B区-01", "正常");
|
|
inventoryItem("PAC浓缩液", "半成品", "液态", "吨",
|
|
15d, 25d, "B区-02", "低于安全线");
|
|
inventoryItem("生物质有机肥成品", "成品", "40kg/袋", "吨",
|
|
320d, 100d, "C区-01", "超储");
|
|
inventoryItem("复合微生物肥成品", "成品", "25kg/袋", "吨",
|
|
95d, 50d, "C区-02", "正常");
|
|
inventoryItem("缓释肥成品", "成品", "5kg/袋", "袋",
|
|
12000d, 4000d, "C区-03", "正常");
|
|
inventoryItem("编织包装袋", "辅料", "40kg规格", "条",
|
|
3500d, 5000d, "D区-01", "低于安全线");
|
|
inventoryItem("封口缝线", "辅料", "工业线轴", "卷",
|
|
280d, 100d, "D区-02", "正常");
|
|
}
|
|
|
|
private void inventoryItem(String materialName, String category, String spec, String unit,
|
|
double quantity, double safetyStock, String location, String status) {
|
|
InventoryItem i = new InventoryItem();
|
|
i.setMaterialName(materialName);
|
|
i.setCategory(category);
|
|
i.setSpec(spec);
|
|
i.setUnit(unit);
|
|
i.setQuantity(quantity);
|
|
i.setSafetyStock(safetyStock);
|
|
i.setLocation(location);
|
|
i.setStatus(quantity < safetyStock ? "低于安全线" : status);
|
|
i.setCreatedAt(Instant.now());
|
|
inventoryItemRepo.save(i);
|
|
}
|
|
|
|
// ----- finance general-ledger center: accounts (财务总账, 会计科目) -----
|
|
|
|
private void seedAccounts() {
|
|
// Standard top-level subjects covering all 5 categories
|
|
// 资产 / 负债 / 权益 / 成本 / 损益; direction (余额方向) is self-consistent
|
|
// with category (assets/costs/expenses 借, liabilities/equity/income 贷).
|
|
// All seeded subjects are level 1 with no parentCode.
|
|
account("1001", "库存现金", "资产", "借", null, 1, 58000d);
|
|
account("1002", "银行存款", "资产", "借", null, 1, 12600000d);
|
|
account("1122", "应收账款", "资产", "借", null, 1, 8450000d);
|
|
account("1403", "原材料", "资产", "借", null, 1, 2360000d);
|
|
account("1601", "固定资产", "资产", "借", null, 1, 18900000d);
|
|
account("2202", "应付账款", "负债", "贷", null, 1, 5320000d);
|
|
account("2211", "应付职工薪酬", "负债", "贷", null, 1, 1280000d);
|
|
account("2221", "应交税费", "负债", "贷", null, 1, 960000d);
|
|
account("4001", "实收资本", "权益", "贷", null, 1, 30000000d);
|
|
account("4104", "利润分配", "权益", "贷", null, 1, 4600000d);
|
|
account("6401", "主营业务成本", "成本", "借", null, 1, 21800000d);
|
|
account("6001", "主营业务收入", "损益", "贷", null, 1, 34500000d);
|
|
account("6601", "销售费用", "损益", "借", null, 1, 1860000d);
|
|
account("6602", "管理费用", "损益", "借", null, 1, 2740000d);
|
|
}
|
|
|
|
private void account(String code, String name, String category, String direction,
|
|
String parentCode, int level, double balance) {
|
|
Account a = new Account();
|
|
a.setCode(code);
|
|
a.setName(name);
|
|
a.setCategory(category);
|
|
a.setDirection(direction);
|
|
a.setParentCode(parentCode);
|
|
a.setLevel(level);
|
|
a.setBalance(Money.of(balance));
|
|
a.setCreatedAt(Instant.now());
|
|
accountRepo.save(a);
|
|
}
|
|
|
|
// ----- finance general-ledger center: vouchers (财务总账, 记账凭证) -----
|
|
|
|
private void seedVouchers() {
|
|
// voucherNo follows 记-2026-NNN; summary covers real business events
|
|
// (收到工程款 / 支付材料款 / 计提工资 / 缴纳税费 等); status covers
|
|
// 暂存 / 已审核 / 已记账. preparer uses 张伟/刘洋/陈静.
|
|
voucher("记-2026-001", "2026-06-01", "收到靖州供水项目工程款",
|
|
"银行存款", "应收账款", 2600000d, "已记账", "刘洋");
|
|
voucher("记-2026-002", "2026-06-02", "支付原材料采购款",
|
|
"应付账款", "银行存款", 860000d, "已记账", "刘洋");
|
|
voucher("记-2026-003", "2026-06-03", "计提本月职工工资",
|
|
"管理费用", "应付职工薪酬", 1280000d, "已审核", "陈静");
|
|
voucher("记-2026-004", "2026-06-05", "缴纳增值税及附加税费",
|
|
"应交税费", "银行存款", 960000d, "已审核", "张伟");
|
|
voucher("记-2026-005", "2026-06-08", "结转主营业务成本",
|
|
"主营业务成本", "原材料", 1540000d, "已记账", "刘洋");
|
|
voucher("记-2026-006", "2026-06-10", "确认岳阳排水管网项目收入",
|
|
"应收账款", "主营业务收入", 3120000d, "已记账", "刘洋");
|
|
voucher("记-2026-007", "2026-06-12", "报销销售部门差旅费",
|
|
"销售费用", "库存现金", 38000d, "暂存", "陈静");
|
|
voucher("记-2026-008", "2026-06-15", "支付办公管理费用",
|
|
"管理费用", "银行存款", 126000d, "暂存", "陈静");
|
|
voucher("记-2026-009", "2026-06-18", "购置生产设备入账",
|
|
"固定资产", "银行存款", 4200000d, "已审核", "张伟");
|
|
voucher("记-2026-010", "2026-06-20", "提现备用金",
|
|
"库存现金", "银行存款", 50000d, "已记账", "刘洋");
|
|
}
|
|
|
|
private void voucher(String voucherNo, String voucherDate, String summary, String debitAccount,
|
|
String creditAccount, double amount, String status, String preparer) {
|
|
Voucher v = new Voucher();
|
|
v.setVoucherNo(voucherNo);
|
|
v.setVoucherDate(voucherDate);
|
|
v.setSummary(summary);
|
|
v.setDebitAccount(debitAccount);
|
|
v.setCreditAccount(creditAccount);
|
|
v.setAmount(Money.of(amount));
|
|
v.setStatus(status);
|
|
v.setPreparer(preparer);
|
|
v.setCreatedAt(Instant.now());
|
|
voucherRepo.save(v);
|
|
}
|
|
|
|
// ----- laboratory center: test samples (实验室, 检测样品) -----
|
|
|
|
private void seedLabSamples() {
|
|
// sampleType covers 水样 / 泥样 / 气样 / 固废 / 土样; source covers
|
|
// 项目自检 / 客户委托 / 监督抽查; status covers 待检 / 检测中 / 已出报告 /
|
|
// 复检. sampleNo follows YP-2026-NNN.
|
|
labSample("YP-2026-001", "靖州污水厂进水水样", "水样", "项目自检", "2026-06-01",
|
|
"COD/氨氮/总磷/SS", "已出报告", "周敏");
|
|
labSample("YP-2026-002", "岳阳管网出水水样", "水样", "监督抽查", "2026-06-02",
|
|
"COD/总氮/pH", "检测中", "周敏");
|
|
labSample("YP-2026-003", "脱水污泥泥样", "泥样", "项目自检", "2026-06-03",
|
|
"含水率/有机质/重金属", "已出报告", "李强");
|
|
labSample("YP-2026-004", "生化池活性污泥泥样", "泥样", "项目自检", "2026-06-05",
|
|
"MLSS/SV30", "复检", "李强");
|
|
labSample("YP-2026-005", "锅炉烟气气样", "气样", "客户委托", "2026-06-06",
|
|
"二氧化硫/氮氧化物/颗粒物", "待检", "陈晨");
|
|
labSample("YP-2026-006", "厂界无组织废气气样", "气样", "监督抽查", "2026-06-07",
|
|
"硫化氢/氨/臭气浓度", "检测中", "陈晨");
|
|
labSample("YP-2026-007", "焚烧炉渣固废样", "固废", "客户委托", "2026-06-08",
|
|
"浸出毒性/重金属", "待检", "黄海");
|
|
labSample("YP-2026-008", "危废暂存间固废样", "固废", "监督抽查", "2026-06-09",
|
|
"腐蚀性/易燃性", "已出报告", "黄海");
|
|
labSample("YP-2026-009", "复绿区表层土样", "土样", "项目自检", "2026-06-10",
|
|
"pH/有机质/全氮/全磷", "检测中", "周敏");
|
|
labSample("YP-2026-010", "填埋场周边土样", "土样", "客户委托", "2026-06-10",
|
|
"重金属/有机污染物", "待检", "李强");
|
|
}
|
|
|
|
private void labSample(String sampleNo, String sampleName, String sampleType, String source,
|
|
String receiveDate, String testItems, String status, String assignee) {
|
|
LabSample s = new LabSample();
|
|
s.setSampleNo(sampleNo);
|
|
s.setSampleName(sampleName);
|
|
s.setSampleType(sampleType);
|
|
s.setSource(source);
|
|
s.setReceiveDate(receiveDate);
|
|
s.setTestItems(testItems);
|
|
s.setStatus(status);
|
|
s.setAssignee(assignee);
|
|
s.setCreatedAt(Instant.now());
|
|
labSampleRepo.save(s);
|
|
}
|
|
|
|
// ----- laboratory center: instruments (实验室, 仪器设备) -----
|
|
|
|
private void seedLabInstruments() {
|
|
// status covers 在用 / 维修 / 停用 / 待校准; nextCalibration of several
|
|
// instruments falls in the second half of 2026. assetNo follows YQ-NNN.
|
|
labInstrument("COD测定仪", "5B-3C", "YQ-001", "2026-01-15", "2027-01-15",
|
|
"在用", "化学分析室", "周敏");
|
|
labInstrument("原子吸收分光光度计", "AA-7000", "YQ-002", "2025-12-20", "2026-12-20",
|
|
"在用", "重金属分析室", "李强");
|
|
labInstrument("气相色谱仪", "GC-2030", "YQ-003", "2026-03-10", "2026-09-10",
|
|
"待校准", "有机分析室", "陈晨");
|
|
labInstrument("pH计", "PHS-3E", "YQ-004", "2026-05-01", "2026-11-01",
|
|
"在用", "化学分析室", "周敏");
|
|
labInstrument("紫外可见分光光度计", "UV-1900", "YQ-005", "2026-02-18", "2027-02-18",
|
|
"在用", "化学分析室", "黄海");
|
|
labInstrument("电子天平", "ME204", "YQ-006", "2026-04-22", "2026-10-22",
|
|
"维修", "天平室", "李强");
|
|
labInstrument("总有机碳分析仪", "TOC-L", "YQ-007", "2025-11-30", "2026-11-30",
|
|
"在用", "有机分析室", "陈晨");
|
|
labInstrument("烟气分析仪", "Testo 350", "YQ-008", "2026-03-25", "2026-09-25",
|
|
"停用", "废气检测组", "黄海");
|
|
}
|
|
|
|
private void labInstrument(String name, String model, String assetNo, String calibrationDate,
|
|
String nextCalibration, String status, String location, String manager) {
|
|
LabInstrument i = new LabInstrument();
|
|
i.setName(name);
|
|
i.setModel(model);
|
|
i.setAssetNo(assetNo);
|
|
i.setCalibrationDate(calibrationDate);
|
|
i.setNextCalibration(nextCalibration);
|
|
i.setStatus(status);
|
|
i.setLocation(location);
|
|
i.setManager(manager);
|
|
i.setCreatedAt(Instant.now());
|
|
labInstrumentRepo.save(i);
|
|
}
|
|
|
|
// ----- design research center: design documents (设计研究中心, 设计文档) -----
|
|
|
|
private void seedDesignDocs() {
|
|
// docType covers 可研报告 / 初步设计 / 施工图 / 计算书 / 专项方案;
|
|
// reviewStatus covers 编制中 / 校审中 / 已批准 / 已归档.
|
|
designDoc("靖州县污水处理厂可行性研究报告", "靖州县污水处理厂工程", "可研报告", "V2.0",
|
|
"王建国", "已批准", "2026-03-15");
|
|
designDoc("岳阳市排水管网初步设计", "岳阳市排水管网改造工程", "初步设计", "V1.1",
|
|
"刘志远", "已归档", "2026-02-20");
|
|
designDoc("怀化垃圾焚烧发电厂施工图", "怀化生活垃圾焚烧发电项目", "施工图", "V3.0",
|
|
"陈思", "校审中", "2026-05-10");
|
|
designDoc("污水厂工艺水力计算书", "靖州县污水处理厂工程", "计算书", "V1.0",
|
|
"赵敏", "已批准", "2026-04-01");
|
|
designDoc("深基坑开挖专项方案", "岳阳市排水管网改造工程", "专项方案", "V2.1",
|
|
"孙浩", "校审中", "2026-05-18");
|
|
designDoc("中水回用初步设计", "园区中水回用工程", "初步设计", "V1.0",
|
|
"周晴", "编制中", "");
|
|
designDoc("污泥处置施工图", "城西污泥处置中心项目", "施工图", "V1.2",
|
|
"陈思", "编制中", "");
|
|
designDoc("厂区总平面布置可研报告", "城西污泥处置中心项目", "可研报告", "V1.0",
|
|
"王建国", "已归档", "2026-01-12");
|
|
}
|
|
|
|
private void designDoc(String name, String projectName, String docType, String version,
|
|
String designer, String reviewStatus, String issueDate) {
|
|
DesignDoc d = new DesignDoc();
|
|
d.setName(name);
|
|
d.setProjectName(projectName);
|
|
d.setDocType(docType);
|
|
d.setVersion(version);
|
|
d.setDesigner(designer);
|
|
d.setReviewStatus(reviewStatus);
|
|
d.setIssueDate(issueDate);
|
|
d.setCreatedAt(Instant.now());
|
|
designDocRepo.save(d);
|
|
}
|
|
|
|
// ----- design research center: design changes (设计研究中心, 设计变更) -----
|
|
|
|
private void seedDesignChanges() {
|
|
// changeType covers 设计变更 / 技术核定 / 工程洽商; status covers
|
|
// 申请 / 审批中 / 已实施 / 已驳回.
|
|
designChange("怀化垃圾焚烧发电厂施工图", "怀化生活垃圾焚烧发电项目", "现场地质条件与勘察不符",
|
|
"设计变更", "桩基础形式调整, 增加造价约80万", "已实施", "陈思");
|
|
designChange("岳阳市排水管网初步设计", "岳阳市排水管网改造工程", "管线避让既有燃气管道",
|
|
"工程洽商", "局部管线改线120米", "审批中", "刘志远");
|
|
designChange("污水厂工艺水力计算书", "靖州县污水处理厂工程", "进水水质参数核定",
|
|
"技术核定", "调整生化池停留时间, 不影响出水", "已实施", "赵敏");
|
|
designChange("深基坑开挖专项方案", "岳阳市排水管网改造工程", "支护结构优化建议",
|
|
"设计变更", "改为钢板桩支护, 节省工期15天", "申请", "孙浩");
|
|
designChange("中水回用初步设计", "园区中水回用工程", "用户用水量预测偏差",
|
|
"技术核定", "回用规模由5000吨调整为3000吨", "审批中", "周晴");
|
|
designChange("污泥处置施工图", "城西污泥处置中心项目", "设备选型与场地冲突",
|
|
"工程洽商", "需重新核定设备布置, 暂缓实施", "已驳回", "陈思");
|
|
}
|
|
|
|
private void designChange(String docName, String projectName, String reason, String changeType,
|
|
String impact, String status, String applicant) {
|
|
DesignChange c = new DesignChange();
|
|
c.setDocName(docName);
|
|
c.setProjectName(projectName);
|
|
c.setReason(reason);
|
|
c.setChangeType(changeType);
|
|
c.setImpact(impact);
|
|
c.setStatus(status);
|
|
c.setApplicant(applicant);
|
|
c.setCreatedAt(Instant.now());
|
|
designChangeRepo.save(c);
|
|
}
|
|
|
|
// ----- engineering supervision center: supervision logs (工程监理, 监理记录) -----
|
|
|
|
private void seedSupervisionLogs() {
|
|
// logType covers 旁站 / 巡视 / 平行检验 / 监理通知 / 计量支付;
|
|
// handleStatus covers 待处理 / 处理中 / 已闭环.
|
|
supervisionLog("靖州县污水处理厂工程", "旁站", "生化池底板混凝土浇筑全程旁站",
|
|
"无", "已闭环", "李监理", "2026-06-01");
|
|
supervisionLog("靖州县污水处理厂工程", "巡视", "现场安全文明施工巡视",
|
|
"脚手架部分临边防护缺失", "处理中", "李监理", "2026-06-02");
|
|
supervisionLog("岳阳市排水管网改造工程", "平行检验", "回填土压实度平行检验",
|
|
"局部压实度未达标", "已闭环", "张监理", "2026-06-03");
|
|
supervisionLog("岳阳市排水管网改造工程", "监理通知", "下发雨季施工措施落实通知",
|
|
"排水沟未及时清理", "处理中", "张监理", "2026-06-04");
|
|
supervisionLog("怀化生活垃圾焚烧发电项目", "计量支付", "第6期工程进度计量审核",
|
|
"无", "已闭环", "王监理", "2026-06-05");
|
|
supervisionLog("怀化生活垃圾焚烧发电项目", "旁站", "钢结构主梁吊装旁站",
|
|
"吊装方案与现场不符", "待处理", "王监理", "2026-06-06");
|
|
supervisionLog("城西污泥处置中心项目", "巡视", "基坑降水运行情况巡视",
|
|
"降水井水位偏高", "处理中", "赵监理", "2026-06-07");
|
|
supervisionLog("城西污泥处置中心项目", "平行检验", "钢筋原材进场平行检验",
|
|
"无", "已闭环", "赵监理", "2026-06-08");
|
|
supervisionLog("园区中水回用工程", "监理通知", "下发隐蔽工程验收整改通知",
|
|
"管道接口未做闭水试验", "待处理", "孙监理", "2026-06-09");
|
|
supervisionLog("园区中水回用工程", "计量支付", "材料预付款支付审核",
|
|
"无", "已闭环", "孙监理", "2026-06-10");
|
|
}
|
|
|
|
private void supervisionLog(String projectName, String logType, String content, String problem,
|
|
String handleStatus, String supervisor, String logDate) {
|
|
SupervisionLog l = new SupervisionLog();
|
|
l.setProjectName(projectName);
|
|
l.setLogType(logType);
|
|
l.setContent(content);
|
|
l.setProblem(problem);
|
|
l.setHandleStatus(handleStatus);
|
|
l.setSupervisor(supervisor);
|
|
l.setLogDate(logDate);
|
|
l.setCreatedAt(Instant.now());
|
|
supervisionLogRepo.save(l);
|
|
}
|
|
|
|
// ----- audit and supervision center: audit projects (审计监察, 审计项目) -----
|
|
|
|
private void seedAuditProjects() {
|
|
// auditType covers 财务审计 / 工程审计 / 合规审计 / 内控评价 /
|
|
// 经济责任审计; status covers 计划 / 实施中 / 报告 / 整改 / 已结.
|
|
auditProject("2026年度财务收支审计", "财务审计", "财务部", "钱伟", "2025年度",
|
|
5, "已结");
|
|
auditProject("靖州污水厂工程结算审计", "工程审计", "工程管理中心", "孙立", "2026上半年",
|
|
8, "整改");
|
|
auditProject("招投标合规专项审计", "合规审计", "招投标中心", "周强", "2025-2026",
|
|
3, "报告");
|
|
auditProject("采购内部控制评价", "内控评价", "采购部", "钱伟", "2025年度",
|
|
4, "实施中");
|
|
auditProject("分公司负责人经济责任审计", "经济责任审计", "长沙分公司", "孙立", "2023-2025",
|
|
6, "实施中");
|
|
auditProject("2026年度合同管理合规审计", "合规审计", "法务部", "周强", "2025年度",
|
|
2, "计划");
|
|
auditProject("固定资产投资工程审计", "工程审计", "怀化项目部", "孙立", "2026上半年",
|
|
0, "计划");
|
|
auditProject("费用报销内控评价", "内控评价", "财务部", "钱伟", "2025年度",
|
|
7, "已结");
|
|
}
|
|
|
|
private void auditProject(String name, String auditType, String auditee, String leadAuditor,
|
|
String period, int findings, String status) {
|
|
AuditProject p = new AuditProject();
|
|
p.setName(name);
|
|
p.setAuditType(auditType);
|
|
p.setAuditee(auditee);
|
|
p.setLeadAuditor(leadAuditor);
|
|
p.setPeriod(period);
|
|
p.setFindings(findings);
|
|
p.setStatus(status);
|
|
p.setCreatedAt(Instant.now());
|
|
auditProjectRepo.save(p);
|
|
}
|
|
|
|
// ----- information department: IT assets (信息部, IT资产) -----
|
|
|
|
private void seedItAssets() {
|
|
// category covers 服务器 / 网络设备 / 终端 / 软件 / 办公设备; status covers
|
|
// 在用 / 闲置 / 维修 / 报废. assetNo follows IT-NNN; holder uses 字段 holder
|
|
// to avoid the SQL keyword user.
|
|
itAsset("IT-001", "Dell PowerEdge R750 服务器", "服务器", "2U/64G内存/4T",
|
|
"信息部机房", "信息中心", "2025-03-10", "在用", "总部机房A柜");
|
|
itAsset("IT-002", "华为 RH2288 服务器", "服务器", "2U/128G内存/8T",
|
|
"信息部机房", "信息中心", "2024-06-15", "在用", "总部机房A柜");
|
|
itAsset("IT-003", "华为 S5720 核心交换机", "网络设备", "48口千兆",
|
|
"信息部机房", "信息中心", "2024-06-15", "在用", "总部机房B柜");
|
|
itAsset("IT-004", "深信服 防火墙 AF-2000", "网络设备", "千兆下一代防火墙",
|
|
"信息部机房", "信息中心", "2025-01-20", "在用", "总部机房B柜");
|
|
itAsset("IT-005", "联想 ThinkPad T14 笔记本", "终端", "i7/16G/512G",
|
|
"王建国", "设计研究中心", "2025-04-08", "在用", "设计室");
|
|
itAsset("IT-006", "戴尔 OptiPlex 台式机", "终端", "i5/8G/256G",
|
|
"周敏", "实验室", "2024-09-12", "在用", "化学分析室");
|
|
itAsset("IT-007", "惠普 ProBook 笔记本", "终端", "i5/8G/256G",
|
|
"", "信息中心", "2023-05-30", "闲置", "信息部库房");
|
|
itAsset("IT-008", "用友 U8+ ERP 软件", "软件", "财务模块50用户",
|
|
"财务部", "财务部", "2024-01-10", "在用", "应用服务器");
|
|
itAsset("IT-009", "正版 Office 365 授权", "软件", "企业版200账号",
|
|
"信息部", "信息中心", "2025-02-01", "在用", "云端订阅");
|
|
itAsset("IT-010", "佳能 iR-ADV 复印机", "办公设备", "A3彩色多功能一体机",
|
|
"行政部", "行政部", "2023-07-22", "维修", "办公区打印间");
|
|
itAsset("IT-011", "爱普生 投影仪", "办公设备", "5000流明",
|
|
"行政部", "行政部", "2022-03-18", "报废", "信息部库房");
|
|
itAsset("IT-012", "TP-LINK 无线AP", "网络设备", "千兆双频吸顶式",
|
|
"信息部", "信息中心", "2025-05-06", "闲置", "信息部库房");
|
|
}
|
|
|
|
private void itAsset(String assetNo, String name, String category, String spec, String holder,
|
|
String dept, String purchaseDate, String status, String location) {
|
|
ItAsset a = new ItAsset();
|
|
a.setAssetNo(assetNo);
|
|
a.setName(name);
|
|
a.setCategory(category);
|
|
a.setSpec(spec);
|
|
a.setHolder(holder);
|
|
a.setDept(dept);
|
|
a.setPurchaseDate(purchaseDate);
|
|
a.setStatus(status);
|
|
a.setLocation(location);
|
|
a.setCreatedAt(Instant.now());
|
|
itAssetRepo.save(a);
|
|
}
|
|
|
|
// ----- work handover (工作交接) -----
|
|
|
|
private void seedHandovers() {
|
|
// handoverType covers 离职交接 / 调动交接 / 轮岗交接; status covers
|
|
// 进行中 / 已完成 / 已确认.
|
|
handover("刘洋", "陈静", "财务部", "离职交接",
|
|
"在手凭证移交, 网银U盾交回, 待报销单据清单", "进行中", "2026-06-05");
|
|
handover("王芳", "张伟", "信息中心", "调动交接",
|
|
"在研系统源码与文档, 服务器账号, 待办工单", "已完成", "2026-05-20");
|
|
handover("李娜", "陈静", "行政办公", "轮岗交接",
|
|
"印章保管登记本, 后勤合同台账, 车辆调度记录", "已确认", "2026-04-28");
|
|
handover("周敏", "孙磊", "创新研发中心", "离职交接",
|
|
"在研课题进度, 实验数据归档, 知识产权材料", "进行中", "2026-06-08");
|
|
handover("赵强", "钱进", "工程管理中心", "调动交接",
|
|
"在建项目台账, 监理资料, 安全检查整改单", "已完成", "2026-05-12");
|
|
handover("孙丽", "李娜", "支付中心", "轮岗交接",
|
|
"结算单据移交, 票据领用登记, 对账单清单", "已确认", "2026-03-30");
|
|
}
|
|
|
|
private void handover(String handoverPerson, String receiver, String dept,
|
|
String handoverType, String items, String status, String handoverDate) {
|
|
Handover h = new Handover();
|
|
h.setHandoverPerson(handoverPerson);
|
|
h.setReceiver(receiver);
|
|
h.setDept(dept);
|
|
h.setHandoverType(handoverType);
|
|
h.setItems(items);
|
|
h.setStatus(status);
|
|
h.setHandoverDate(handoverDate);
|
|
h.setCreatedAt(Instant.now());
|
|
handoverRepo.save(h);
|
|
}
|
|
|
|
// ----- declaration multi-step lifecycle (申报多步骤生命周期) -----
|
|
|
|
private void seedDeclarationSteps() {
|
|
// Two declarations (declarationId 1 and 2, names taken from the seeded
|
|
// Declaration list) each carry the full eight-step lifecycle. status
|
|
// reflects progress: early steps 已完成, a middle step 进行中, later
|
|
// steps 待办. Declaration 1 is further along than declaration 2.
|
|
String d1 = "2026年度高新技术企业认定申报";
|
|
declarationSteps(1L, d1, "张伟",
|
|
new String[]{"已完成", "已完成", "已完成", "已完成", "进行中", "待办", "待办", "待办"});
|
|
|
|
String d2 = "农村供水智能调度省重点研发计划项目申报";
|
|
declarationSteps(2L, d2, "王芳",
|
|
new String[]{"已完成", "已完成", "进行中", "待办", "待办", "待办", "待办", "待办"});
|
|
}
|
|
|
|
private void declarationSteps(Long declarationId, String declarationName, String owner,
|
|
String[] statuses) {
|
|
String[] names = {"立项", "材料协同", "数据采集", "内部审核",
|
|
"外部提交", "进度跟踪", "补正答辩", "结果登记"};
|
|
for (int i = 0; i < names.length; i++) {
|
|
DeclarationStep s = new DeclarationStep();
|
|
s.setDeclarationId(declarationId);
|
|
s.setDeclarationName(declarationName);
|
|
s.setStepName(names[i]);
|
|
s.setStepOrder(i + 1);
|
|
s.setStatus(statuses[i]);
|
|
s.setOwner(owner);
|
|
s.setDueDate("2026-0" + (i < 3 ? 3 + i : 6) + "-15");
|
|
s.setCreatedAt(Instant.now());
|
|
declarationStepRepo.save(s);
|
|
}
|
|
}
|
|
|
|
// ----- declaration expert pool (申报专家库) -----
|
|
|
|
private void seedExperts() {
|
|
// field covers 给排水 / 环境工程 / 市政 / 财务 / 法律 / 水利; expertType
|
|
// covers 评审专家 / 咨询专家 / 行业专家; status covers 在库 / 暂停.
|
|
expert("陈国华", "给排水", "湖南大学土木工程学院", "教授", "评审专家",
|
|
"13900000001", "在库");
|
|
expert("林志远", "环境工程", "湖南省环境科学研究院", "研究员", "评审专家",
|
|
"13900000002", "在库");
|
|
expert("王海涛", "市政", "中南市政设计研究院", "教授级高工", "咨询专家",
|
|
"13900000003", "在库");
|
|
expert("赵敏华", "财务", "天职国际会计师事务所", "高级会计师", "咨询专家",
|
|
"13900000004", "在库");
|
|
expert("孙立军", "法律", "湖南金州律师事务所", "高级律师", "咨询专家",
|
|
"13900000005", "在库");
|
|
expert("周建波", "水利", "湖南省水利水电勘测设计院", "教授级高工", "行业专家",
|
|
"13900000006", "在库");
|
|
expert("吴秀英", "环境工程", "怀化学院化学与材料工程学院", "副教授", "评审专家",
|
|
"13900000007", "在库");
|
|
expert("郑文斌", "给排水", "湖南省建筑设计院", "高级工程师", "行业专家",
|
|
"13900000008", "暂停");
|
|
}
|
|
|
|
private void expert(String name, String field, String org, String title,
|
|
String expertType, String phone, String status) {
|
|
Expert e = new Expert();
|
|
e.setName(name);
|
|
e.setField(field);
|
|
e.setOrg(org);
|
|
e.setTitle(title);
|
|
e.setExpertType(expertType);
|
|
e.setPhone(phone);
|
|
e.setStatus(status);
|
|
e.setCreatedAt(Instant.now());
|
|
expertRepo.save(e);
|
|
}
|
|
|
|
// ----- 存货计价方法配置种子 -----
|
|
|
|
private void seedInventoryValuationConfigs() {
|
|
if (inventoryValuationConfigRepo.count() > 0) return;
|
|
inventoryValuationConfig("全局", "原材料", "移动平均", "2025-01", null,
|
|
"已生效", "初始建立全局计价方法", "张会计", "总会计师");
|
|
inventoryValuationConfig("生物质肥料制造中心", "成品/半成品", "先进先出", "2025-01", null,
|
|
"已生效", "制造中心成品按先进先出管理", "李主管", "成本控制部长");
|
|
inventoryValuationConfig("水处理药剂制造中心", "化学品", "个别计价", "2025-03", null,
|
|
"已生效", "化学品价格差异大,采用个别计价", "王会计", "总会计师");
|
|
inventoryValuationConfig("全局", "设备/零部件", "移动平均", "2026-01", null,
|
|
"草稿", "2026年度更新计价方法草案", "赵分析师", null);
|
|
}
|
|
|
|
private void inventoryValuationConfig(String costCenter, String materialCategory,
|
|
String method, String from, String to,
|
|
String status, String reason,
|
|
String applicant, String approver) {
|
|
InventoryValuationConfig c = new InventoryValuationConfig();
|
|
c.setCostCenter(costCenter);
|
|
c.setMaterialCategory(materialCategory);
|
|
c.setMethod(method);
|
|
c.setEffectivePeriodFrom(from);
|
|
c.setEffectivePeriodTo(to);
|
|
c.setStatus(status);
|
|
c.setReason(reason);
|
|
c.setApplicant(applicant);
|
|
c.setApprover(approver);
|
|
c.setCreatedAt(Instant.now().minus(Duration.ofDays(60)));
|
|
if (approver != null) {
|
|
c.setApprovedAt(Instant.now().minus(Duration.ofDays(55)));
|
|
}
|
|
inventoryValuationConfigRepo.save(c);
|
|
}
|
|
|
|
// ----- 成本调整操作日志种子 -----
|
|
|
|
private void seedCostAdjustLogs() {
|
|
if (costAdjustLogRepo.count() > 0) return;
|
|
costAdjustLog("标准成本修订", "StandardCost", null, "原材料钢材 2025-06标准成本",
|
|
new java.math.BigDecimal("5800.00"), new java.math.BigDecimal("6100.00"),
|
|
null, null, "供应商提价导致原材料采购成本上升", "张会计", "2025-06", "总会计师", 90);
|
|
costAdjustLog("差异手工分摊", "BomVarianceDetail", null, "2025-06材料价格差异分摊",
|
|
new java.math.BigDecimal("12000.00"), new java.math.BigDecimal("0.00"),
|
|
null, null, "月末将材料价格差异按比例分摊至库存和销售成本", "李主管", "2025-06", "成本控制部长", 85);
|
|
costAdjustLog("预算修改", "ProjectBudgetLine", null, "凯迪环保项目材料费预算调增",
|
|
new java.math.BigDecimal("500000.00"), new java.math.BigDecimal("560000.00"),
|
|
null, null, "因设计变更导致材料用量增加,申请预算调增", "王分析师", "2025-05", "项目总监", 100);
|
|
costAdjustLog("计价方法变更", "InventoryValuationConfig", null, "水处理药剂由移动平均改为个别计价",
|
|
null, null, "移动平均", "个别计价",
|
|
"化学品价格波动较大,个别计价更准确反映实际成本", "赵会计", "2025-03", "总会计师", 75);
|
|
costAdjustLog("标准成本修订", "StandardCost", null, "人工费率2025年度调整",
|
|
new java.math.BigDecimal("85.00"), new java.math.BigDecimal("92.00"),
|
|
null, null, "根据人力资源部工时费率调整方案更新标准人工费率", "张会计", "2025-01", "总会计师", 180);
|
|
}
|
|
|
|
private void costAdjustLog(String adjustType, String entityType, Long entityId,
|
|
String entityDesc, java.math.BigDecimal amountBefore,
|
|
java.math.BigDecimal amountAfter,
|
|
String valueBefore, String valueAfter,
|
|
String reason, String operator, String period,
|
|
String approver, int daysAgoOffset) {
|
|
CostAdjustLog log = new CostAdjustLog();
|
|
log.setAdjustType(adjustType);
|
|
log.setEntityType(entityType);
|
|
log.setEntityId(entityId);
|
|
log.setEntityDesc(entityDesc);
|
|
log.setAmountBefore(amountBefore != null ? amountBefore : java.math.BigDecimal.ZERO);
|
|
log.setAmountAfter(amountAfter != null ? amountAfter : java.math.BigDecimal.ZERO);
|
|
log.setValueBefore(valueBefore);
|
|
log.setValueAfter(valueAfter);
|
|
log.setReason(reason);
|
|
log.setOperator(operator);
|
|
log.setPeriod(period);
|
|
log.setApprover(approver);
|
|
log.setOperatedAt(Instant.now().minus(Duration.ofDays(daysAgoOffset)));
|
|
costAdjustLogRepo.save(log);
|
|
}
|
|
|
|
// ----- helpers -----
|
|
|
|
private Instant daysAgo(int offset, int hour, int minute) {
|
|
return Instant.now()
|
|
.minus(Duration.ofDays(offset))
|
|
.truncatedTo(ChronoUnit.DAYS)
|
|
.plus(Duration.ofHours(hour))
|
|
.plus(Duration.ofMinutes(minute));
|
|
}
|
|
}
|