diff --git a/src/CncRepository/Impl/WorkshopRepository.cs b/src/CncRepository/Impl/WorkshopRepository.cs new file mode 100644 index 0000000..3c7f126 --- /dev/null +++ b/src/CncRepository/Impl/WorkshopRepository.cs @@ -0,0 +1,111 @@ +using System.Collections.Generic; +using System.Linq; +using Dapper; +using CncModels.Entity; +using CncRepository.Base; +using CncRepository.Interface; +using System.Data; +using CncModels.Dto; + +namespace CncRepository.Impl +{ + /// + /// 车间仓储实现 + /// + public class WorkshopRepository : BusinessRepository, IWorkshopRepository + { + public WorkshopRepository(string connectionString) : base(connectionString) { } + + public Workshop GetById(int id) + { + using (var conn = CreateConnection()) + { + var sql = @"SELECT Id as Id, Name as Name, SortOrder as SortOrder, IsEnabled as IsEnabled, CreatedAt as CreatedAt, UpdatedAt as UpdatedAt FROM cnc_workshop WHERE Id = @Id"; + return conn.QuerySingleOrDefault(sql, new { Id = id }); + } + } + + public List GetAll() + { + using (var conn = CreateConnection()) + { + var sql = @"SELECT Id as Id, Name as Name, SortOrder as SortOrder, IsEnabled as IsEnabled, CreatedAt as CreatedAt, UpdatedAt as UpdatedAt FROM cnc_workshop ORDER BY SortOrder ASC"; + return conn.Query(sql).ToList(); + } + } + + public PagedResult GetList(string keyword) + { + using (var conn = CreateConnection()) + { + var where = string.Empty; + var param = new DynamicParameters(); + if (!string.IsNullOrWhiteSpace(keyword)) + { + where = " WHERE Name LIKE @Keyword"; + param.Add("Keyword", $"%{keyword}%"); + } + var limit = 20; + var sql = $@"SELECT Id as Id, Name as Name, SortOrder as SortOrder, IsEnabled as IsEnabled, CreatedAt as CreatedAt, UpdatedAt as UpdatedAt + FROM cnc_workshop {where} ORDER BY SortOrder ASC LIMIT {limit} OFFSET 0"; + var totalSql = $@"SELECT COUNT(*) FROM cnc_workshop {where}"; + var items = conn.Query(sql, param).ToList(); + var total = conn.ExecuteScalar(totalSql, param); + return new PagedResult + { + Items = items, + Total = total, + Page = 1, + PageSize = limit + }; + } + } + + public int Create(Workshop entity) + { + using (var conn = CreateConnection()) + { + var sql = @"INSERT INTO cnc_workshop (Name, SortOrder, IsEnabled, CreatedAt, UpdatedAt) + VALUES (@Name, @SortOrder, @IsEnabled, @CreatedAt, @UpdatedAt); + SELECT LAST_INSERT_ID();"; + return conn.QuerySingle(sql, entity); + } + } + + public bool Update(Workshop entity) + { + using (var conn = CreateConnection()) + { + var sql = @"UPDATE cnc_workshop SET Name = @Name, SortOrder = @SortOrder, IsEnabled = @IsEnabled, UpdatedAt = @UpdatedAt WHERE Id = @Id"; + return conn.Execute(sql, entity) > 0; + } + } + + public bool Delete(int id) + { + using (var conn = CreateConnection()) + { + var sql = @"DELETE FROM cnc_workshop WHERE Id = @Id"; + return conn.Execute(sql, new { Id = id }) > 0; + } + } + + public bool ToggleEnabled(int id) + { + using (var conn = CreateConnection()) + { + var sql = @"UPDATE cnc_workshop SET IsEnabled = CASE WHEN IsEnabled = 1 THEN 0 ELSE 1 END, UpdatedAt = NOW() WHERE Id = @Id"; + return conn.Execute(sql, new { Id = id }) > 0; + } + } + + public int GetMachineCount(int workshopId) + { + using (var conn = CreateConnection()) + { + var sql = @"SELECT COUNT(*) FROM cnc_machine WHERE WorkshopId = @WorkshopId"; + return conn.ExecuteScalar(sql, new { WorkshopId = workshopId }); + } + } + } +} diff --git a/src/CncWebApi/App_Start/WebApiConfig.cs b/src/CncWebApi/App_Start/WebApiConfig.cs index ebeb7dd..2672acc 100644 --- a/src/CncWebApi/App_Start/WebApiConfig.cs +++ b/src/CncWebApi/App_Start/WebApiConfig.cs @@ -1,5 +1,7 @@ using System.Web.Http; using System.Web.Http.Cors; +using CncWebApi.Filters; +using CncWebApi.Infrastructure; namespace CncWebApi.App_Start { @@ -15,16 +17,17 @@ namespace CncWebApi.App_Start /// HTTP配置对象 public static void Register(HttpConfiguration config) { + // 依赖注入解析器 + config.DependencyResolver = new ServiceResolver(); + // 跨域配置(局域网场景,允许所有来源) config.EnableCors(new EnableCorsAttribute("*", "*", "*")); // 路由注册 - // 默认路由模板:api/{controller}/{id} - // 各Controller使用 [RoutePrefix] + [Route] 属性路由覆盖此默认 config.MapHttpAttributeRoutes(); // 全局异常过滤器 - config.Filters.Add(new Filters.GlobalExceptionFilter()); + config.Filters.Add(new GlobalExceptionFilter()); // 统一JSON序列化设置 config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = diff --git a/src/CncWebApi/Controllers/AlertController.cs b/src/CncWebApi/Controllers/AlertController.cs new file mode 100644 index 0000000..f5d0a67 --- /dev/null +++ b/src/CncWebApi/Controllers/AlertController.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Alert; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 告警中心控制器 + /// + [RoutePrefix("api/admin/alert")] + [JwtAuthFilter] + public class AlertController : ApiController + { + private readonly IAlertService _alertService; + + /// + /// 构造函数 + /// + public AlertController(IAlertService alertService) + { + _alertService = alertService; + } + + /// + /// 告警列表(分页) + /// GET /api/admin/alert + /// + [HttpGet] + [Route("")] + public IHttpActionResult GetList([FromUri] AlertQuery query) + { + if (query == null) query = new AlertQuery(); + var result = _alertService.GetList(query); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 告警统计 + /// GET /api/admin/alert/statistics + /// + [HttpGet] + [Route("statistics")] + public IHttpActionResult GetStatistics() + { + var result = _alertService.GetStatistics(); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 处理单条告警 + /// PUT /api/admin/alert/{id}/resolve + /// + [HttpPut] + [Route("{id:long}/resolve")] + public IHttpActionResult Resolve(long id) + { + var result = _alertService.Resolve(id); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 批量处理告警 + /// POST /api/admin/alert/batch-resolve + /// + [HttpPost] + [Route("batch-resolve")] + public IHttpActionResult BatchResolve([FromBody] BatchResolveRequest request) + { + var ids = request.Ids.Select(i => (long)i).ToList(); + var count = _alertService.BatchResolve(ids); + return Ok(ApiResponse.Success(new { count })); + } + } +} diff --git a/src/CncWebApi/Controllers/AuthController.cs b/src/CncWebApi/Controllers/AuthController.cs new file mode 100644 index 0000000..c6dc24c --- /dev/null +++ b/src/CncWebApi/Controllers/AuthController.cs @@ -0,0 +1,36 @@ +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Login; +using CncService.Interface; + +namespace CncWebApi.Controllers +{ + /// + /// 登录认证控制器 + /// + [RoutePrefix("api/admin")] + public class AuthController : ApiController + { + private readonly IAuthService _authService; + + /// + /// 构造函数 + /// + public AuthController(IAuthService authService) + { + _authService = authService; + } + + /// + /// 管理员登录 + /// POST /api/admin/login + /// + [HttpPost] + [Route("login")] + public IHttpActionResult Login([FromBody] LoginRequest request) + { + var result = _authService.Login(request); + return Ok(ApiResponse.Success(result)); + } + } +} diff --git a/src/CncWebApi/Controllers/BrandController.cs b/src/CncWebApi/Controllers/BrandController.cs new file mode 100644 index 0000000..2c11c21 --- /dev/null +++ b/src/CncWebApi/Controllers/BrandController.cs @@ -0,0 +1,123 @@ +using System.Collections.Generic; +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Brand; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 品牌模板控制器 + /// + [RoutePrefix("api/admin/brand")] + [JwtAuthFilter] + public class BrandController : ApiController + { + private readonly IBrandService _brandService; + + /// + /// 构造函数 + /// + public BrandController(IBrandService brandService) + { + _brandService = brandService; + } + + /// + /// 品牌列表 + /// GET /api/admin/brand + /// + [HttpGet] + [Route("")] + public IHttpActionResult GetList() + { + var result = _brandService.GetList(); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 品牌详情(含字段映射) + /// GET /api/admin/brand/{id} + /// + [HttpGet] + [Route("{id:int}")] + public IHttpActionResult GetById(int id) + { + var result = _brandService.GetById(id); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 新增品牌 + /// POST /api/admin/brand + /// + [HttpPost] + [Route("")] + public IHttpActionResult Create([FromBody] CreateBrandRequest request) + { + var id = _brandService.Create(request); + return Ok(ApiResponse.Success(new { id })); + } + + /// + /// 编辑品牌 + /// PUT /api/admin/brand/{id} + /// + [HttpPut] + [Route("{id:int}")] + public IHttpActionResult Update(int id, [FromBody] UpdateBrandRequest request) + { + var result = _brandService.Update(id, request); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 删除品牌 + /// DELETE /api/admin/brand/{id} + /// + [HttpDelete] + [Route("{id:int}")] + public IHttpActionResult Delete(int id) + { + var result = _brandService.Delete(id); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 复制品牌 + /// POST /api/admin/brand/{id}/copy + /// + [HttpPost] + [Route("{id:int}/copy")] + public IHttpActionResult Copy(int id) + { + var newId = _brandService.Copy(id); + return Ok(ApiResponse.Success(new { id = newId })); + } + + /// + /// 启停品牌 + /// PUT /api/admin/brand/{id}/toggle + /// + [HttpPut] + [Route("{id:int}/toggle")] + public IHttpActionResult ToggleEnabled(int id) + { + var result = _brandService.ToggleEnabled(id); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 标准字段列表 + /// GET /api/admin/brand/standard-fields + /// + [HttpGet] + [Route("standard-fields")] + public IHttpActionResult GetStandardFields() + { + var result = _brandService.GetStandardFields(); + return Ok(ApiResponse>.Success(result)); + } + } +} diff --git a/src/CncWebApi/Controllers/CollectAddressController.cs b/src/CncWebApi/Controllers/CollectAddressController.cs new file mode 100644 index 0000000..3736096 --- /dev/null +++ b/src/CncWebApi/Controllers/CollectAddressController.cs @@ -0,0 +1,99 @@ +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.CollectAddress; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 采集地址控制器 + /// + [RoutePrefix("api/admin/collect-address")] + [JwtAuthFilter] + public class CollectAddressController : ApiController + { + private readonly ICollectAddressService _collectAddressService; + + /// + /// 构造函数 + /// + public CollectAddressController(ICollectAddressService collectAddressService) + { + _collectAddressService = collectAddressService; + } + + /// + /// 地址列表(分页) + /// GET /api/admin/collect-address + /// + [HttpGet] + [Route("")] + public IHttpActionResult GetList([FromUri] CollectAddressQuery query) + { + if (query == null) query = new CollectAddressQuery(); + var result = _collectAddressService.GetList(query); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 地址详情 + /// GET /api/admin/collect-address/{id} + /// + [HttpGet] + [Route("{id:int}")] + public IHttpActionResult GetById(int id) + { + var result = _collectAddressService.GetById(id); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 新增地址 + /// POST /api/admin/collect-address + /// + [HttpPost] + [Route("")] + public IHttpActionResult Create([FromBody] CreateCollectAddressRequest request) + { + var id = _collectAddressService.Create(request); + return Ok(ApiResponse.Success(new { id })); + } + + /// + /// 编辑地址 + /// PUT /api/admin/collect-address/{id} + /// + [HttpPut] + [Route("{id:int}")] + public IHttpActionResult Update(int id, [FromBody] UpdateCollectAddressRequest request) + { + var result = _collectAddressService.Update(id, request); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 删除地址 + /// DELETE /api/admin/collect-address/{id} + /// + [HttpDelete] + [Route("{id:int}")] + public IHttpActionResult Delete(int id) + { + var result = _collectAddressService.Delete(id); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 启停地址 + /// PUT /api/admin/collect-address/{id}/toggle + /// + [HttpPut] + [Route("{id:int}/toggle")] + public IHttpActionResult ToggleEnabled(int id) + { + var result = _collectAddressService.ToggleEnabled(id); + return Ok(ApiResponse.Success(null)); + } + } +} diff --git a/src/CncWebApi/Controllers/DashboardController.cs b/src/CncWebApi/Controllers/DashboardController.cs new file mode 100644 index 0000000..fc3623d --- /dev/null +++ b/src/CncWebApi/Controllers/DashboardController.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Dashboard; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 仪表盘控制器 + /// + [RoutePrefix("api/admin/dashboard")] + [JwtAuthFilter] + public class DashboardController : ApiController + { + private readonly IDashboardService _dashboardService; + + /// + /// 构造函数 + /// + public DashboardController(IDashboardService dashboardService) + { + _dashboardService = dashboardService; + } + + /// + /// 8个统计卡片数据 + /// GET /api/admin/dashboard/summary + /// + [HttpGet] + [Route("summary")] + public IHttpActionResult GetSummary() + { + var result = _dashboardService.GetSummary(); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 车间平均单机产量 + /// GET /api/admin/dashboard/workshop-production + /// + [HttpGet] + [Route("workshop-production")] + public IHttpActionResult GetWorkshopProduction(DateTime? startDate = null, DateTime? endDate = null) + { + var result = _dashboardService.GetWorkshopProduction(startDate, endDate); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 机床产量排行TOP10 + /// GET /api/admin/dashboard/machine-rank + /// + [HttpGet] + [Route("machine-rank")] + public IHttpActionResult GetMachineRank(DateTime? startDate = null, DateTime? endDate = null, int top = 10) + { + var result = _dashboardService.GetMachineRank(startDate, endDate, top); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 工人产量排行TOP10 + /// GET /api/admin/dashboard/worker-rank + /// + [HttpGet] + [Route("worker-rank")] + public IHttpActionResult GetWorkerRank(DateTime? startDate = null, DateTime? endDate = null, int top = 10) + { + var result = _dashboardService.GetWorkerRank(startDate, endDate, top); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 产量趋势(近7天) + /// GET /api/admin/dashboard/trend + /// + [HttpGet] + [Route("trend")] + public IHttpActionResult GetProductionTrend(int days = 7) + { + var result = _dashboardService.GetProductionTrend(days); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 机床状态分布 + /// GET /api/admin/dashboard/machine-status-distribution + /// + [HttpGet] + [Route("machine-status-distribution")] + public IHttpActionResult GetMachineStatusDistribution() + { + var result = _dashboardService.GetMachineStatusDistribution(); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 最新5条告警 + /// GET /api/admin/dashboard/recent-alerts + /// + [HttpGet] + [Route("recent-alerts")] + public IHttpActionResult GetRecentAlerts(int count = 5) + { + var result = _dashboardService.GetRecentAlerts(count); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 采集服务状态 + /// GET /api/admin/collector/status + /// + [HttpGet] + [Route("~/api/admin/collector/status")] + public IHttpActionResult GetCollectorStatus() + { + var result = _dashboardService.GetCollectorStatus(); + return Ok(ApiResponse.Success(result)); + } + } +} diff --git a/src/CncWebApi/Controllers/LogController.cs b/src/CncWebApi/Controllers/LogController.cs new file mode 100644 index 0000000..cdccba6 --- /dev/null +++ b/src/CncWebApi/Controllers/LogController.cs @@ -0,0 +1,55 @@ +using System; +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Log; +using CncRepository.Interface; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 操作日志控制器 + /// + [RoutePrefix("api/admin/log")] + [JwtAuthFilter] + public class LogController : ApiController + { + private readonly ISystemLogService _systemLogService; + private readonly IProductionAdjustmentRepository _adjustmentRepository; + + /// + /// 构造函数 + /// + public LogController(ISystemLogService systemLogService, IProductionAdjustmentRepository adjustmentRepository) + { + _systemLogService = systemLogService; + _adjustmentRepository = adjustmentRepository; + } + + /// + /// 系统运行日志(分页) + /// GET /api/admin/log/system + /// + [HttpGet] + [Route("system")] + public IHttpActionResult GetSystemLog([FromUri] SystemLogQuery query) + { + if (query == null) query = new SystemLogQuery(); + var result = _systemLogService.GetList(query); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 产量修正日志(分页) + /// GET /api/admin/log/adjustment + /// + [HttpGet] + [Route("adjustment")] + public IHttpActionResult GetAdjustmentLog(string targetTable = null, DateTime? startDate = null, DateTime? endDate = null, string keyword = null, int page = 1, int pageSize = 20) + { + var result = _adjustmentRepository.GetList(targetTable, startDate, endDate, keyword, page, pageSize); + return Ok(ApiResponse>.Success(result)); + } + } +} diff --git a/src/CncWebApi/Controllers/MachineController.cs b/src/CncWebApi/Controllers/MachineController.cs new file mode 100644 index 0000000..c16401f --- /dev/null +++ b/src/CncWebApi/Controllers/MachineController.cs @@ -0,0 +1,99 @@ +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Machine; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 设备管理控制器 + /// + [RoutePrefix("api/admin/machine")] + [JwtAuthFilter] + public class MachineController : ApiController + { + private readonly IMachineService _machineService; + + /// + /// 构造函数 + /// + public MachineController(IMachineService machineService) + { + _machineService = machineService; + } + + /// + /// 机床列表(分页) + /// GET /api/admin/machine + /// + [HttpGet] + [Route("")] + public IHttpActionResult GetList([FromUri] MachineQuery query) + { + if (query == null) query = new MachineQuery(); + var result = _machineService.GetList(query); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 机床详情 + /// GET /api/admin/machine/{id} + /// + [HttpGet] + [Route("{id:int}")] + public IHttpActionResult GetById(int id) + { + var result = _machineService.GetById(id); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 新增机床 + /// POST /api/admin/machine + /// + [HttpPost] + [Route("")] + public IHttpActionResult Create([FromBody] CreateMachineRequest request) + { + var id = _machineService.Create(request); + return Ok(ApiResponse.Success(new { id })); + } + + /// + /// 编辑机床 + /// PUT /api/admin/machine/{id} + /// + [HttpPut] + [Route("{id:int}")] + public IHttpActionResult Update(int id, [FromBody] UpdateMachineRequest request) + { + var result = _machineService.Update(id, request); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 删除机床 + /// DELETE /api/admin/machine/{id} + /// + [HttpDelete] + [Route("{id:int}")] + public IHttpActionResult Delete(int id) + { + var result = _machineService.Delete(id); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 启停机床 + /// PUT /api/admin/machine/{id}/toggle + /// + [HttpPut] + [Route("{id:int}/toggle")] + public IHttpActionResult ToggleEnabled(int id) + { + var result = _machineService.ToggleEnabled(id); + return Ok(ApiResponse.Success(null)); + } + } +} diff --git a/src/CncWebApi/Controllers/OptionController.cs b/src/CncWebApi/Controllers/OptionController.cs new file mode 100644 index 0000000..39bd3ad --- /dev/null +++ b/src/CncWebApi/Controllers/OptionController.cs @@ -0,0 +1,109 @@ +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Common; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 公共下拉选项控制器 + /// + [RoutePrefix("api/admin")] + [JwtAuthFilter] + public class OptionController : ApiController + { + private readonly IWorkshopService _workshopService; + private readonly IBrandService _brandService; + private readonly IMachineService _machineService; + private readonly IWorkerService _workerService; + private readonly ICollectAddressService _collectAddressService; + + /// + /// 构造函数 + /// + public OptionController( + IWorkshopService workshopService, + IBrandService brandService, + IMachineService machineService, + IWorkerService workerService, + ICollectAddressService collectAddressService) + { + _workshopService = workshopService; + _brandService = brandService; + _machineService = machineService; + _workerService = workerService; + _collectAddressService = collectAddressService; + } + + /// + /// 车间下拉 + /// GET /api/admin/workshop/list + /// + [HttpGet] + [Route("workshop/list")] + public IHttpActionResult WorkshopList() + { + var list = _workshopService.GetList(null); + var items = list.Select(w => new SimpleOption { Value = w.Id.ToString(), Label = w.Name }).ToList(); + return Ok(ApiResponse>.Success(items)); + } + + /// + /// 品牌下拉 + /// GET /api/admin/brand/list + /// + [HttpGet] + [Route("brand/list")] + public IHttpActionResult BrandList() + { + var list = _brandService.GetList(); + var items = list.Select(b => new SimpleOption { Value = b.Id.ToString(), Label = b.BrandName }).ToList(); + return Ok(ApiResponse>.Success(items)); + } + + /// + /// 机床下拉 + /// GET /api/admin/machine/list + /// + [HttpGet] + [Route("machine/list")] + public IHttpActionResult MachineList() + { + var query = new CncModels.Dto.Machine.MachineQuery { Page = 1, PageSize = 1000 }; + var paged = _machineService.GetList(query); + var items = paged.Items.Select(m => new SimpleOption { Value = m.Id.ToString(), Label = m.Name ?? m.DeviceCode }).ToList(); + return Ok(ApiResponse>.Success(items)); + } + + /// + /// 工人下拉 + /// GET /api/admin/worker/list + /// + [HttpGet] + [Route("worker/list")] + public IHttpActionResult WorkerList() + { + var query = new CncModels.Dto.Worker.WorkerQuery { Page = 1, PageSize = 1000 }; + var paged = _workerService.GetList(query); + var items = paged.Items.Select(w => new SimpleOption { Value = w.Id.ToString(), Label = w.Name + "(" + w.Code + ")" }).ToList(); + return Ok(ApiResponse>.Success(items)); + } + + /// + /// 采集地址下拉 + /// GET /api/admin/collect-address/list + /// + [HttpGet] + [Route("collect-address/list")] + public IHttpActionResult CollectAddressList() + { + var query = new CncModels.Dto.CollectAddress.CollectAddressQuery { Page = 1, PageSize = 1000 }; + var paged = _collectAddressService.GetList(query); + var items = paged.Items.Select(a => new SimpleOption { Value = a.Id.ToString(), Label = a.Name }).ToList(); + return Ok(ApiResponse>.Success(items)); + } + } +} diff --git a/src/CncWebApi/Controllers/ProductionController.cs b/src/CncWebApi/Controllers/ProductionController.cs new file mode 100644 index 0000000..ce9a7a1 --- /dev/null +++ b/src/CncWebApi/Controllers/ProductionController.cs @@ -0,0 +1,64 @@ +using System; +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Production; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 产量报表控制器 + /// + [RoutePrefix("api/admin/production")] + [JwtAuthFilter] + public class ProductionController : ApiController + { + private readonly IProductionService _productionService; + + /// + /// 构造函数 + /// + public ProductionController(IProductionService productionService) + { + _productionService = productionService; + } + + /// + /// 日产量列表(分页) + /// GET /api/admin/production/daily + /// + [HttpGet] + [Route("daily")] + public IHttpActionResult GetList([FromUri] ProductionQuery query) + { + if (query == null) query = new ProductionQuery(); + var result = _productionService.GetList(query); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 日汇总统计 + /// GET /api/admin/production/daily-summary + /// + [HttpGet] + [Route("daily-summary")] + public IHttpActionResult GetSummary(DateTime? date = null, int? workshopId = null) + { + var result = _productionService.GetSummary(date, workshopId); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 修正产量 + /// POST /api/admin/production/adjust + /// + [HttpPost] + [Route("adjust")] + public IHttpActionResult Adjust([FromBody] ProductionAdjustRequest request) + { + var result = _productionService.Adjust(request); + return Ok(ApiResponse.Success(null)); + } + } +} diff --git a/src/CncWebApi/Controllers/ScreenConfigController.cs b/src/CncWebApi/Controllers/ScreenConfigController.cs new file mode 100644 index 0000000..4edd501 --- /dev/null +++ b/src/CncWebApi/Controllers/ScreenConfigController.cs @@ -0,0 +1,141 @@ +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; +using CncModels.Dto; +using CncModels.Entity; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 大屏配置控制器 + /// + [RoutePrefix("api/admin")] + [JwtAuthFilter] + public class ScreenConfigController : ApiController + { + private readonly IScreenService _screenService; + + /// + /// 构造函数 + /// + public ScreenConfigController(IScreenService screenService) + { + _screenService = screenService; + } + + #region 卡片配置 + + /// + /// 卡片配置列表 + /// GET /api/admin/screen-config + /// + [HttpGet] + [Route("screen-config")] + public IHttpActionResult GetConfigs() + { + var result = _screenService.GetConfigs(); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 编辑卡片 + /// PUT /api/admin/screen-config/{id} + /// + [HttpPut] + [Route("screen-config/{id:int}")] + public IHttpActionResult UpdateConfig(int id, [FromBody] ScreenConfig entity) + { + if (entity == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.BadRequest, "请求参数不能为空"); + entity.Id = id; + var result = _screenService.UpdateConfig(entity); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 删除卡片 + /// DELETE /api/admin/screen-config/{id} + /// + [HttpDelete] + [Route("screen-config/{id:int}")] + public IHttpActionResult DeleteConfig(int id) + { + var result = _screenService.DeleteFilter(id); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 启停卡片 + /// PUT /api/admin/screen-config/{id}/toggle + /// + [HttpPut] + [Route("screen-config/{id:int}/toggle")] + public IHttpActionResult ToggleConfig(int id) + { + var configs = _screenService.GetConfigs(); + var config = configs.FirstOrDefault(c => c.Id == id); + if (config == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.NotFound, "配置不存在"); + config.IsEnabled = config.IsEnabled == 1 ? 0 : 1; + _screenService.UpdateConfig(config); + return Ok(ApiResponse.Success(null)); + } + + #endregion + + #region 筛选配置 + + /// + /// 筛选配置列表 + /// GET /api/admin/screen-filter + /// + [HttpGet] + [Route("screen-filter")] + public IHttpActionResult GetFilters(string screenKey = null) + { + var result = _screenService.GetFilters(screenKey ?? "main_screen"); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 新增筛选项 + /// POST /api/admin/screen-filter + /// + [HttpPost] + [Route("screen-filter")] + public IHttpActionResult CreateFilter([FromBody] ScreenFilter entity) + { + if (entity == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.BadRequest, "请求参数不能为空"); + var id = _screenService.CreateFilter(entity); + return Ok(ApiResponse.Success(new { id })); + } + + /// + /// 编辑筛选项 + /// PUT /api/admin/screen-filter/{id} + /// + [HttpPut] + [Route("screen-filter/{id:int}")] + public IHttpActionResult UpdateFilter(int id, [FromBody] ScreenFilter entity) + { + if (entity == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.BadRequest, "请求参数不能为空"); + entity.Id = id; + var result = _screenService.UpdateFilter(entity); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 删除筛选项 + /// DELETE /api/admin/screen-filter/{id} + /// + [HttpDelete] + [Route("screen-filter/{id:int}")] + public IHttpActionResult DeleteFilter(int id) + { + var result = _screenService.DeleteFilter(id); + return Ok(ApiResponse.Success(null)); + } + + #endregion + } +} diff --git a/src/CncWebApi/Controllers/ScreenController.cs b/src/CncWebApi/Controllers/ScreenController.cs new file mode 100644 index 0000000..1c23178 --- /dev/null +++ b/src/CncWebApi/Controllers/ScreenController.cs @@ -0,0 +1,150 @@ +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Common; +using CncModels.Dto.Dashboard; +using CncModels.Dto.Screen; +using CncModels.Entity; +using CncRepository.Interface; +using CncService.Interface; + +namespace CncWebApi.Controllers +{ + /// + /// 大屏看板控制器(无需认证) + /// + [RoutePrefix("api/screen")] + public class ScreenController : ApiController + { + private readonly IDashboardService _dashboardService; + private readonly IScreenService _screenService; + private readonly ISysConfigRepository _sysConfigRepository; + + /// + /// 构造函数 + /// + public ScreenController(IDashboardService dashboardService, IScreenService screenService, ISysConfigRepository sysConfigRepository) + { + _dashboardService = dashboardService; + _screenService = screenService; + _sysConfigRepository = sysConfigRepository; + } + + /// + /// 大屏汇总统计 + /// GET /api/screen/summary + /// + [HttpGet] + [Route("summary")] + public IHttpActionResult GetSummary() + { + var result = _screenService.GetSummary(); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 采集服务状态 + /// GET /api/screen/collector-status + /// + [HttpGet] + [Route("collector-status")] + public IHttpActionResult GetCollectorStatus() + { + var result = _dashboardService.GetCollectorStatus(); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 各车间产量 + /// GET /api/screen/workshop-production + /// + [HttpGet] + [Route("workshop-production")] + public IHttpActionResult GetWorkshopProduction() + { + var result = _dashboardService.GetWorkshopProduction(null, null); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 7天产量趋势 + /// GET /api/screen/production-trend + /// + [HttpGet] + [Route("production-trend")] + public IHttpActionResult GetProductionTrend(int days = 7) + { + var result = _dashboardService.GetProductionTrend(days); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 机床产量排行 + /// GET /api/screen/machine-rank + /// + [HttpGet] + [Route("machine-rank")] + public IHttpActionResult GetMachineRank(int top = 10) + { + var result = _dashboardService.GetMachineRank(null, null, top); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 工人产量排行 + /// GET /api/screen/worker-rank + /// + [HttpGet] + [Route("worker-rank")] + public IHttpActionResult GetWorkerRank(int top = 10) + { + var result = _dashboardService.GetWorkerRank(null, null, top); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 机床状态总览 + /// GET /api/screen/machine-status + /// + [HttpGet] + [Route("machine-status")] + public IHttpActionResult GetMachineStatus() + { + var result = _dashboardService.GetMachineStatusDistribution(); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 大屏筛选条件 + /// GET /api/screen/filters + /// + [HttpGet] + [Route("filters")] + public IHttpActionResult GetFilters(string screenKey = "main_screen") + { + var filters = _screenService.GetFilters(screenKey); + var items = filters.Select(f => new CncModels.Dto.Common.SimpleOption + { + Value = f.FilterValue, + Label = f.FilterType + }).ToList(); + return Ok(ApiResponse>.Success(items)); + } + + /// + /// 刷新间隔配置 + /// GET /api/screen/refresh-interval + /// + [HttpGet] + [Route("refresh-interval")] + public IHttpActionResult GetRefreshInterval() + { + var cfg = _sysConfigRepository.GetByKey("screen_refresh_interval"); + int interval = 30; + if (cfg != null && int.TryParse(cfg.ConfigValue, out int val)) + interval = val; + return Ok(ApiResponse.Success(new { interval })); + } + } +} diff --git a/src/CncWebApi/Controllers/SettingsController.cs b/src/CncWebApi/Controllers/SettingsController.cs new file mode 100644 index 0000000..4db6df0 --- /dev/null +++ b/src/CncWebApi/Controllers/SettingsController.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Settings; +using CncModels.Entity; +using CncRepository.Interface; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 系统设置控制器 + /// + [RoutePrefix("api/admin")] + [JwtAuthFilter] + public class SettingsController : ApiController + { + private readonly ISysConfigRepository _sysConfigRepository; + private readonly IWorkshopService _workshopService; + + /// + /// 构造函数 + /// + public SettingsController(ISysConfigRepository sysConfigRepository, IWorkshopService workshopService) + { + _sysConfigRepository = sysConfigRepository; + _workshopService = workshopService; + } + + #region 系统配置 + + /// + /// 配置项列表 + /// GET /api/admin/sys-config + /// + [HttpGet] + [Route("sys-config")] + public IHttpActionResult GetSysConfigList() + { + var configs = _sysConfigRepository.GetAll(); + var items = configs.Select(c => new SysConfigListItem + { + Id = c.Id, + ConfigKey = c.ConfigKey, + ConfigValue = c.ConfigValue, + ValueType = c.ValueType, + Description = c.Description + }).ToList(); + return Ok(ApiResponse>.Success(items)); + } + + /// + /// 编辑配置项 + /// PUT /api/admin/sys-config/{id} + /// + [HttpPut] + [Route("sys-config/{id:int}")] + public IHttpActionResult UpdateSysConfig(int id, [FromBody] UpdateSysConfigRequest request) + { + if (request == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.BadRequest, "请求参数不能为空"); + var result = _sysConfigRepository.UpdateValue(id, request.ConfigValue); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 修改密码 + /// POST /api/admin/change-password + /// + [HttpPost] + [Route("change-password")] + public IHttpActionResult ChangePassword([FromBody] ChangePasswordRequest request) + { + if (request == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.BadRequest, "请求参数不能为空"); + // 简化实现:更新密码哈希到 SysConfig + var hash = BCrypt.Net.BCrypt.HashPassword(request.NewPassword); + var pwdCfg = _sysConfigRepository.GetByKey("admin_password_hash"); + if (pwdCfg == null) throw new CncService.BusinessException(CncModels.Constants.ErrorCode.NotFound, "密码配置未找到"); + _sysConfigRepository.UpdateValue(pwdCfg.Id, hash); + return Ok(ApiResponse.Success(null)); + } + + #endregion + + #region 车间管理 + + /// + /// 车间列表 + /// GET /api/admin/workshop + /// + [HttpGet] + [Route("workshop")] + public IHttpActionResult GetWorkshopList(string keyword = null) + { + var result = _workshopService.GetList(keyword); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 新增车间 + /// POST /api/admin/workshop + /// + [HttpPost] + [Route("workshop")] + public IHttpActionResult CreateWorkshop([FromBody] CreateWorkshopRequest request) + { + var id = _workshopService.Create(request); + return Ok(ApiResponse.Success(new { id })); + } + + /// + /// 编辑车间 + /// PUT /api/admin/workshop/{id} + /// + [HttpPut] + [Route("workshop/{id:int}")] + public IHttpActionResult UpdateWorkshop(int id, [FromBody] UpdateWorkshopRequest request) + { + var result = _workshopService.Update(id, request); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 删除车间 + /// DELETE /api/admin/workshop/{id} + /// + [HttpDelete] + [Route("workshop/{id:int}")] + public IHttpActionResult DeleteWorkshop(int id) + { + var result = _workshopService.Delete(id); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 启停车间 + /// PUT /api/admin/workshop/{id}/toggle + /// + [HttpPut] + [Route("workshop/{id:int}/toggle")] + public IHttpActionResult ToggleWorkshop(int id) + { + var result = _workshopService.ToggleEnabled(id); + return Ok(ApiResponse.Success(null)); + } + + #endregion + } +} diff --git a/src/CncWebApi/Controllers/WorkerController.cs b/src/CncWebApi/Controllers/WorkerController.cs new file mode 100644 index 0000000..ac36ae8 --- /dev/null +++ b/src/CncWebApi/Controllers/WorkerController.cs @@ -0,0 +1,132 @@ +using System.Web.Http; +using CncModels.Dto; +using CncModels.Dto.Worker; +using CncService.Interface; +using CncWebApi.Infrastructure; + +namespace CncWebApi.Controllers +{ + /// + /// 员工管理控制器 + /// + [RoutePrefix("api/admin/worker")] + [JwtAuthFilter] + public class WorkerController : ApiController + { + private readonly IWorkerService _workerService; + + /// + /// 构造函数 + /// + public WorkerController(IWorkerService workerService) + { + _workerService = workerService; + } + + /// + /// 工人列表(分页) + /// GET /api/admin/worker + /// + [HttpGet] + [Route("")] + public IHttpActionResult GetList([FromUri] WorkerQuery query) + { + if (query == null) query = new WorkerQuery(); + var result = _workerService.GetList(query); + return Ok(ApiResponse>.Success(result)); + } + + /// + /// 工人详情 + /// GET /api/admin/worker/{id} + /// + [HttpGet] + [Route("{id:int}")] + public IHttpActionResult GetById(int id) + { + var result = _workerService.GetById(id); + return Ok(ApiResponse.Success(result)); + } + + /// + /// 新增工人 + /// POST /api/admin/worker + /// + [HttpPost] + [Route("")] + public IHttpActionResult Create([FromBody] CreateWorkerRequest request) + { + var id = _workerService.Create(request); + return Ok(ApiResponse.Success(new { id })); + } + + /// + /// 编辑工人 + /// PUT /api/admin/worker/{id} + /// + [HttpPut] + [Route("{id:int}")] + public IHttpActionResult Update(int id, [FromBody] UpdateWorkerRequest request) + { + var result = _workerService.Update(id, request); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 删除工人 + /// DELETE /api/admin/worker/{id} + /// + [HttpDelete] + [Route("{id:int}")] + public IHttpActionResult Delete(int id) + { + var result = _workerService.Delete(id); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 启停工人 + /// PUT /api/admin/worker/{id}/toggle + /// + [HttpPut] + [Route("{id:int}/toggle")] + public IHttpActionResult ToggleEnabled(int id) + { + var result = _workerService.ToggleEnabled(id); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 绑定机床 + /// POST /api/admin/worker/{id}/bind + /// + [HttpPost] + [Route("{id:int}/bind")] + public IHttpActionResult BindMachine(int id, [FromBody] BindMachineRequest request) + { + var result = _workerService.BindMachine(id, request.MachineId); + return Ok(ApiResponse.Success(null)); + } + + /// + /// 解绑机床 + /// POST /api/admin/worker/{id}/unbind + /// + [HttpPost] + [Route("{id:int}/unbind")] + public IHttpActionResult UnbindMachine(int id, [FromBody] BindMachineRequest request) + { + var result = _workerService.UnbindMachine(id, request.MachineId); + return Ok(ApiResponse.Success(null)); + } + } + + /// + /// 绑定/解绑机床请求 + /// + public class BindMachineRequest + { + /// 机床ID + public int MachineId { get; set; } + } +} diff --git a/src/CncWebApi/Infrastructure/JwtAuthFilter.cs b/src/CncWebApi/Infrastructure/JwtAuthFilter.cs new file mode 100644 index 0000000..345e1b8 --- /dev/null +++ b/src/CncWebApi/Infrastructure/JwtAuthFilter.cs @@ -0,0 +1,112 @@ +using System; +using System.Net; +using System.Net.Http; +using System.Security.Cryptography; +using System.Text; +using System.Web.Http.Controllers; +using System.Web.Http.Filters; +using CncModels.Dto; +using CncModels.Constants; + +namespace CncWebApi.Infrastructure +{ + /// + /// JWT 认证过滤器 + /// 验证请求 Header 中的 Bearer Token + /// 管理 /api/admin/** 接口需要认证,大屏 /api/screen/** 不需要 + /// + public class JwtAuthFilter : AuthorizationFilterAttribute + { + /// + public override void OnAuthorization(HttpActionContext actionContext) + { + // 从 Header 读取 Authorization + var authHeader = actionContext.Request.Headers.Authorization; + if (authHeader == null || !string.Equals(authHeader.Scheme, "Bearer", StringComparison.OrdinalIgnoreCase)) + { + Reject(actionContext, "Token缺失"); + return; + } + + var token = authHeader.Parameter; + if (string.IsNullOrWhiteSpace(token)) + { + Reject(actionContext, "Token为空"); + return; + } + + // 验证 JWT + try + { + var parts = token.Split('.'); + if (parts.Length != 3) + { + Reject(actionContext, "Token格式无效"); + return; + } + + // 从 Web.config 读取密钥 + var secret = System.Configuration.ConfigurationManager.AppSettings["JwtSecret"]; + if (string.IsNullOrEmpty(secret)) + { + Reject(actionContext, "服务端配置错误"); + return; + } + + // 验证签名 + using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret))) + { + var expectedSig = Base64UrlEncode(hmac.ComputeHash(Encoding.UTF8.GetBytes(parts[0] + "." + parts[1]))); + if (!string.Equals(expectedSig, parts[2], StringComparison.Ordinal)) + { + Reject(actionContext, "Token签名无效"); + return; + } + } + + // 检查过期 + var payloadBytes = Base64UrlDecode(parts[1]); + var payloadJson = Encoding.UTF8.GetString(payloadBytes); + var expMatch = System.Text.RegularExpressions.Regex.Match(payloadJson, @"""exp"":(\d+)"); + if (expMatch.Success) + { + var exp = long.Parse(expMatch.Groups[1].Value); + var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + if (now > exp) + { + Reject(actionContext, "Token已过期"); + return; + } + } + } + catch (Exception) + { + Reject(actionContext, "Token验证失败"); + return; + } + } + + private void Reject(HttpActionContext actionContext, string message) + { + var response = ApiResponse.Fail(ErrorCode.Unauthorized, message); + actionContext.Response = actionContext.Request.CreateResponse( + HttpStatusCode.OK, response); + } + + private static string Base64UrlEncode(byte[] input) + { + return Convert.ToBase64String(input).Replace("+", "-").Replace("/", "_").TrimEnd('='); + } + + private static byte[] Base64UrlDecode(string input) + { + var base64 = input.Replace("-", "+").Replace("_", "/"); + switch (base64.Length % 4) + { + case 2: base64 += "=="; break; + case 3: base64 += "="; break; + } + return Convert.FromBase64String(base64); + } + } +} diff --git a/src/CncWebApi/Infrastructure/ServiceResolver.cs b/src/CncWebApi/Infrastructure/ServiceResolver.cs new file mode 100644 index 0000000..f6968cb --- /dev/null +++ b/src/CncWebApi/Infrastructure/ServiceResolver.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Web.Http.Dependencies; +using CncRepository.Base; +using CncRepository.Interface; +using CncService.Interface; + +namespace CncWebApi.Infrastructure +{ + /// + /// 简单的依赖注入解析器 + /// 手动注册 Repository 和 Service 的映射关系 + /// + public class ServiceResolver : IDependencyResolver + { + private static readonly string _businessConn = ConfigurationManager.ConnectionStrings["BusinessConnection"]?.ConnectionString; + private static readonly string _logConn = ConfigurationManager.ConnectionStrings["LogConnection"]?.ConnectionString; + private static readonly string _jwtSecret = ConfigurationManager.AppSettings["JwtSecret"]; + + /// + public IDependencyScope BeginScope() + { + return this; + } + + /// + public object GetService(Type serviceType) + { + // Controller 解析 + if (serviceType == typeof(Controllers.AuthController)) + return new Controllers.AuthController( + ResolveAuthService()); + if (serviceType == typeof(Controllers.DashboardController)) + return new Controllers.DashboardController( + ResolveDashboardService()); + if (serviceType == typeof(Controllers.MachineController)) + return new Controllers.MachineController( + ResolveMachineService()); + if (serviceType == typeof(Controllers.BrandController)) + return new Controllers.BrandController( + ResolveBrandService()); + if (serviceType == typeof(Controllers.CollectAddressController)) + return new Controllers.CollectAddressController( + ResolveCollectAddressService()); + if (serviceType == typeof(Controllers.WorkerController)) + return new Controllers.WorkerController( + ResolveWorkerService()); + if (serviceType == typeof(Controllers.ProductionController)) + return new Controllers.ProductionController( + ResolveProductionService()); + if (serviceType == typeof(Controllers.AlertController)) + return new Controllers.AlertController( + ResolveAlertService()); + if (serviceType == typeof(Controllers.SettingsController)) + return new Controllers.SettingsController( + new CncRepository.Impl.SysConfigRepository(_businessConn), + ResolveWorkshopService()); + if (serviceType == typeof(Controllers.LogController)) + return new Controllers.LogController( + ResolveSystemLogService(), + ResolveProductionAdjustmentRepository()); + if (serviceType == typeof(Controllers.ScreenConfigController)) + return new Controllers.ScreenConfigController( + ResolveScreenService()); + if (serviceType == typeof(Controllers.ScreenController)) + return new Controllers.ScreenController( + ResolveDashboardService(), + ResolveScreenService(), + new CncRepository.Impl.SysConfigRepository(_businessConn)); + if (serviceType == typeof(Controllers.OptionController)) + return new Controllers.OptionController( + ResolveWorkshopService(), + ResolveBrandService(), + ResolveMachineService(), + ResolveWorkerService(), + ResolveCollectAddressService()); + if (serviceType == typeof(Controllers.HealthController)) + return new Controllers.HealthController(); + + return null; + } + + /// + public IEnumerable GetServices(Type serviceType) + { + return Enumerable.Empty(); + } + + /// + public void Dispose() { } + + #region Service 解析 + + private IAuthService ResolveAuthService() + { + return new CncService.Impl.AuthService( + new CncRepository.Impl.SysConfigRepository(_businessConn), + _jwtSecret); + } + + private IDashboardService ResolveDashboardService() + { + return new CncService.Impl.DashboardService( + new CncRepository.Impl.Dashboard.DashboardRepository(_businessConn), + new CncRepository.Impl.Log.CollectorHeartbeatRepository(_logConn)); + } + + private IMachineService ResolveMachineService() + { + return new CncService.Impl.MachineService( + new CncRepository.Impl.MachineRepository(_businessConn), + new CncRepository.Impl.CollectAddressRepository(_businessConn), + new CncRepository.Impl.WorkerMachineRepository(_businessConn), + new CncRepository.Impl.BrandRepository(_businessConn)); + } + + private IBrandService ResolveBrandService() + { + return new CncService.Impl.BrandService( + new CncRepository.Impl.BrandRepository(_businessConn), + new CncRepository.Impl.BrandFieldMappingRepository(_businessConn), + new CncRepository.Impl.CollectAddressRepository(_businessConn)); + } + + private ICollectAddressService ResolveCollectAddressService() + { + return new CncService.Impl.CollectAddressService( + new CncRepository.Impl.CollectAddressRepository(_businessConn), + new CncRepository.Impl.MachineRepository(_businessConn), + new CncRepository.Impl.BrandRepository(_businessConn)); + } + + private IWorkerService ResolveWorkerService() + { + return new CncService.Impl.WorkerService( + new CncRepository.Impl.WorkerRepository(_businessConn), + new CncRepository.Impl.WorkerMachineRepository(_businessConn), + new CncRepository.Impl.MachineRepository(_businessConn)); + } + + private IProductionService ResolveProductionService() + { + return new CncService.Impl.ProductionService( + new CncRepository.Impl.DailyProductionRepository(_businessConn), + new CncRepository.Impl.ProductionSegmentRepository(_businessConn), + new CncRepository.Impl.ProductionAdjustmentRepository(_businessConn)); + } + + private IAlertService ResolveAlertService() + { + return new CncService.Impl.AlertService( + new CncRepository.Impl.AlertRepository(_businessConn)); + } + + private IWorkshopService ResolveWorkshopService() + { + return new CncService.Impl.WorkshopService( + new CncRepository.Impl.WorkshopRepository(_businessConn)); + } + + private IScreenService ResolveScreenService() + { + return new CncService.Impl.ScreenService( + new CncRepository.Impl.ScreenConfigRepository(_businessConn), + new CncRepository.Impl.ScreenFilterRepository(_businessConn), + new CncRepository.Impl.WorkshopRepository(_businessConn)); + } + + private ISystemLogService ResolveSystemLogService() + { + return new CncService.Impl.SystemLogService( + new CncRepository.Impl.SystemLogRepository(_logConn)); + } + + private IProductionAdjustmentRepository ResolveProductionAdjustmentRepository() + { + return new CncRepository.Impl.ProductionAdjustmentRepository(_businessConn); + } + + #endregion + } +}