(ctx context.Context, eid, jobID int64)
| 611 | } |
| 612 | |
| 613 | func (s *SkillLibraryService) ForceImportSkill(ctx context.Context, eid, jobID int64) (*SkillImportResult, error) { |
| 614 | if jobID <= 0 { |
| 615 | return nil, ErrSkillImportRequestInvalid |
| 616 | } |
| 617 | |
| 618 | job, err := model.GetSkillScanJobByIDAndEID(eid, jobID) |
| 619 | if err != nil { |
| 620 | return nil, err |
| 621 | } |
| 622 | if job == nil { |
| 623 | return nil, gorm.ErrRecordNotFound |
| 624 | } |
| 625 | if job.Status != model.SkillScanJobStatusFailed { |
| 626 | return nil, fmt.Errorf("任务状态不是失败,无法强制导入") |
| 627 | } |
| 628 | if job.RiskLevel != model.SkillRiskLevelHigh { |
| 629 | return nil, fmt.Errorf("任务非高风险失败,无法强制导入") |
| 630 | } |
| 631 | if job.SkillLibraryID > 0 { |
| 632 | return nil, fmt.Errorf("任务已关联技能,无法强制导入") |
| 633 | } |
| 634 | |
| 635 | var payload SkillImportJobPayload |
| 636 | if err := json.Unmarshal([]byte(job.ScanPayload), &payload); err != nil { |
| 637 | return nil, fmt.Errorf("解析任务数据失败: %v", err) |
| 638 | } |
| 639 | if payload.OriginZipKey == "" { |
| 640 | return nil, fmt.Errorf("任务缺少原始文件数据,无法强制导入") |
| 641 | } |
| 642 | |
| 643 | zipContent, err := s.storage.Load(payload.OriginZipKey) |
| 644 | if err != nil { |
| 645 | return nil, fmt.Errorf("读取原始文件失败: %v", err) |
| 646 | } |
| 647 | |
| 648 | req := &SkillImportRequest{ |
| 649 | Eid: eid, |
| 650 | SourceType: strings.TrimSpace(payload.SourceType), |
| 651 | GithubURL: strings.TrimSpace(payload.GithubURL), |
| 652 | Ref: strings.TrimSpace(payload.Ref), |
| 653 | SkillPath: strings.TrimSpace(payload.SkillPath), |
| 654 | } |
| 655 | if err := normalizeSkillImportRequest(req); err != nil { |
| 656 | return nil, err |
| 657 | } |
| 658 | |
| 659 | archiveSkillPath := "" |
| 660 | if req.SourceType == model.SkillSourceTypeGithub { |
| 661 | archiveSkillPath = parseGithubSourceSkillPath(payload.Ref) |
| 662 | } |
| 663 | |
| 664 | stagingPath, err := createSkillExtractionStagingPath(s.buildSkillTenantRootPath(eid)) |
| 665 | if err != nil { |
| 666 | return nil, err |
| 667 | } |
| 668 | defer os.RemoveAll(stagingPath) |
| 669 | |
| 670 | inspection, err := extractSkillArchiveToPath(zipContent, archiveSkillPath, stagingPath) |
no test coverage detected