< Summary

Information
Class: CounterDrone.Core.Services.ScenarioService
Assembly: CounterDrone.Core
File(s): C:\Users\Tellme\apps\CounterDroneBackend\src\CounterDrone.Core\Services\ScenarioService.cs
Line coverage
96%
Covered lines: 148
Uncovered lines: 6
Coverable lines: 154
Total lines: 224
Line coverage: 96.1%
Branch coverage
82%
Covered branches: 38
Total branches: 46
Branch coverage: 82.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
CreateTask(...)100%66100%
DeleteTask(...)100%11100%
SearchTasks(...)50%44100%
GetTaskDetail(...)100%88100%
SaveScene(...)100%22100%
SaveControlZones(...)100%22100%
SaveTarget(...)50%4480%
SaveDeployment(...)75%4490.9%
SaveCloudDispersal(...)50%2287.5%
SaveRoute(...)66.66%6688.23%
UpdateStep(...)100%66100%
TouchTask(...)100%22100%
GenerateTaskNumber()100%11100%

File(s)

C:\Users\Tellme\apps\CounterDroneBackend\src\CounterDrone.Core\Services\ScenarioService.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Threading;
 4using CounterDrone.Core.Models;
 5using CounterDrone.Core.Repository;
 6
 7namespace CounterDrone.Core.Services
 8{
 9    public class ScenarioService : IScenarioService
 10    {
 11        private readonly SimTaskRepository _taskRepo;
 12        private readonly CombatSceneRepository _sceneRepo;
 13        private readonly ControlZoneRepository _zoneRepo;
 14        private readonly TargetConfigRepository _targetRepo;
 15        private readonly EquipmentDeploymentRepository _equipRepo;
 16        private readonly CloudDispersalRepository _cloudRepo;
 17        private readonly RoutePlanRepository _routeRepo;
 18        private readonly WaypointRepository _waypointRepo;
 19
 3220        public ScenarioService(
 3221            SimTaskRepository taskRepo,
 3222            CombatSceneRepository sceneRepo,
 3223            ControlZoneRepository zoneRepo,
 3224            TargetConfigRepository targetRepo,
 3225            EquipmentDeploymentRepository equipRepo,
 3226            CloudDispersalRepository cloudRepo,
 3227            RoutePlanRepository routeRepo,
 3228            WaypointRepository waypointRepo)
 3229        {
 3230            _taskRepo = taskRepo;
 3231            _sceneRepo = sceneRepo;
 3232            _zoneRepo = zoneRepo;
 3233            _targetRepo = targetRepo;
 3234            _equipRepo = equipRepo;
 3235            _cloudRepo = cloudRepo;
 3236            _routeRepo = routeRepo;
 3237            _waypointRepo = waypointRepo;
 3238        }
 39
 40        // ========== Task CRUD ==========
 41
 42        public SimTask CreateTask(string name, string taskNumber)
 4943        {
 4944            if (string.IsNullOrWhiteSpace(name))
 145                throw new ArgumentException("任务名称不能为空");
 46
 4847            if (string.IsNullOrWhiteSpace(taskNumber))
 4548                taskNumber = GenerateTaskNumber();
 49
 4850            var existing = _taskRepo.GetByTaskNumber(taskNumber);
 4851            if (existing != null)
 152                throw new ArgumentException($"任务编号 {taskNumber} 已存在");
 53
 4754            var task = new SimTask
 4755            {
 4756                Name = name,
 4757                TaskNumber = taskNumber,
 4758                Status = (int)TaskStatus.Configuring,
 4759                CurrentStep = 1,
 4760            };
 61
 4762            _taskRepo.Insert(task);
 4763            return task;
 4764        }
 65
 66        public void DeleteTask(string id)
 167        {
 168            _taskRepo.Delete(id);
 169        }
 70
 71        public PagedResult<SimTask> SearchTasks(string keyword, string? dateFrom, string? dateTo, int page, int pageSize
 772        {
 773            if (page < 1) page = 1;
 774            if (pageSize < 1) pageSize = 10;
 775            var offset = (page - 1) * pageSize;
 76
 777            var items = _taskRepo.Search(keyword, dateFrom, dateTo, offset, pageSize, out var total);
 78
 779            return new PagedResult<SimTask>
 780            {
 781                Items = items,
 782                TotalCount = total,
 783                Page = page,
 784                PageSize = pageSize,
 785            };
 786        }
 87
 88        public TaskFullConfig? GetTaskDetail(string id)
 3689        {
 3690            var task = _taskRepo.GetById(id);
 3791            if (task == null) return null;
 92
 3593            return new TaskFullConfig
 3594            {
 3595                Task = task,
 3596                Scene = _sceneRepo.GetById(id) ?? new CombatScene { TaskId = id },
 3597                ControlZones = _zoneRepo.GetByTaskId(id),
 3598                Targets = _targetRepo.GetByTaskId(id),
 3599                Equipment = _equipRepo.GetByTaskId(id),
 35100                Cloud = _cloudRepo.GetById(id) ?? new CloudDispersal { TaskId = id },
 35101                Route = _routeRepo.GetById(id) ?? new RoutePlan { TaskId = id },
 35102                Waypoints = _waypointRepo.GetByTaskId(id),
 35103            };
 36104        }
 105
 106        // ========== Step Save ==========
 107
 108        public void SaveScene(string taskId, CombatScene scene)
 17109        {
 17110            scene.TaskId = taskId;
 17111            var existing = _sceneRepo.GetById(taskId);
 17112            if (existing != null)
 1113                _sceneRepo.Update(scene);
 114            else
 16115                _sceneRepo.Insert(scene);
 17116            TouchTask(taskId);
 17117        }
 118
 119        public void SaveControlZones(string taskId, List<ControlZone> zones)
 5120        {
 5121            _zoneRepo.DeleteByTaskId(taskId);
 24122            for (int i = 0; i < zones.Count; i++)
 7123            {
 7124                zones[i].TaskId = taskId;
 7125                zones[i].OrderIndex = i;
 7126            }
 5127            _zoneRepo.InsertAll(zones);
 5128            TouchTask(taskId);
 5129        }
 130
 131        public void SaveTarget(string taskId, TargetConfig target)
 15132        {
 15133            target.TaskId = taskId;
 15134            if (string.IsNullOrEmpty(target.Id))
 0135                target.Id = Guid.NewGuid().ToString();
 136
 15137            var existing = _targetRepo.GetById(target.Id);
 15138            if (existing != null)
 0139                _targetRepo.Update(target);
 140            else
 15141                _targetRepo.Insert(target);
 15142            TouchTask(taskId);
 15143        }
 144
 145        public void SaveDeployment(string taskId, List<EquipmentDeployment> equips)
 14146        {
 14147            _equipRepo.DeleteByTaskId(taskId);
 86148            foreach (var e in equips)
 22149            {
 22150                e.TaskId = taskId;
 22151                if (string.IsNullOrEmpty(e.Id))
 0152                    e.Id = Guid.NewGuid().ToString();
 22153            }
 14154            _equipRepo.InsertAll(equips);
 14155            TouchTask(taskId);
 14156        }
 157
 158        public void SaveCloudDispersal(string taskId, CloudDispersal cloud)
 14159        {
 14160            cloud.TaskId = taskId;
 14161            var existing = _cloudRepo.GetById(taskId);
 14162            if (existing != null)
 0163                _cloudRepo.Update(cloud);
 164            else
 14165                _cloudRepo.Insert(cloud);
 14166            TouchTask(taskId);
 14167        }
 168
 169        public void SaveRoute(string taskId, RoutePlan route, List<Waypoint> waypoints)
 14170        {
 14171            route.TaskId = taskId;
 14172            var existingRoute = _routeRepo.GetById(taskId);
 14173            if (existingRoute != null)
 0174                _routeRepo.Update(route);
 175            else
 14176                _routeRepo.Insert(route);
 177
 14178            _waypointRepo.DeleteByTaskId(taskId);
 86179            for (int i = 0; i < waypoints.Count; i++)
 29180            {
 29181                waypoints[i].TaskId = taskId;
 29182                waypoints[i].OrderIndex = i;
 29183                if (string.IsNullOrEmpty(waypoints[i].Id))
 0184                    waypoints[i].Id = Guid.NewGuid().ToString();
 29185            }
 14186            _waypointRepo.InsertAll(waypoints);
 14187            TouchTask(taskId);
 14188        }
 189
 190        public void UpdateStep(string taskId, int step)
 10191        {
 10192            var task = _taskRepo.GetById(taskId);
 10193            if (task == null) return;
 194
 11195            if (step < 1) step = 1;
 11196            if (step > 5) step = 5;
 197
 10198            task.CurrentStep = step;
 10199            _taskRepo.Update(task);
 10200        }
 201
 202        // ========== Helpers ==========
 203
 204        private void TouchTask(string taskId)
 79205        {
 79206            var task = _taskRepo.GetById(taskId);
 79207            if (task != null)
 79208            {
 79209                task.UpdatedAt = DateTime.UtcNow.ToString("o");
 79210                _taskRepo.Update(task);
 79211            }
 79212        }
 213
 214        private static int _counter;
 215
 216        public static string GenerateTaskNumber()
 45217        {
 45218            var now = DateTime.Now;
 45219            var datePart = now.ToString("yyyyMMdd");
 45220            var seq = Interlocked.Increment(ref _counter);
 45221            return $"SIM-{datePart}-{seq:D3}";
 45222        }
 223    }
 224}