diff --git a/Entity/DbModel/Station/BatteryOpModel.cs b/Entity/DbModel/Station/BatteryOpModel.cs new file mode 100644 index 0000000..fece6bf --- /dev/null +++ b/Entity/DbModel/Station/BatteryOpModel.cs @@ -0,0 +1,67 @@ +using System; +using System.Linq; +using System.Text; +using SqlSugar; + +namespace Entity.DbModel.Station +{ + /// + ///电池运营模型 + /// + [SugarTable("battery_op_model")] + public partial class BatteryOpModel + { + public BatteryOpModel(){ + + + } + /// + /// Desc:id + /// Default: + /// Nullable:False + /// + [SugarColumn(IsPrimaryKey=true,IsIdentity=true,ColumnName="id")] + public int Id {get;set;} + + /// + /// Desc:模型id + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="model_id")] + public int? ModelId {get;set;} + + /// + /// Desc:创建人 + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="created_by")] + public string CreatedBy {get;set;} + + /// + /// Desc:创建时间 + /// Default:CURRENT_TIMESTAMP + /// Nullable:True + /// + [SugarColumn(ColumnName="created_time")] + public DateTime? CreatedTime {get;set;} + + /// + /// Desc:更新人 + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="updated_by")] + public string UpdatedBy {get;set;} + + /// + /// Desc:更新时间 + /// Default:CURRENT_TIMESTAMP + /// Nullable:True + /// + [SugarColumn(ColumnName="updated_time")] + public DateTime? UpdatedTime {get;set;} + + } +} diff --git a/Entity/DbModel/Station/BatteryOpModelDetail.cs b/Entity/DbModel/Station/BatteryOpModelDetail.cs new file mode 100644 index 0000000..c3213b6 --- /dev/null +++ b/Entity/DbModel/Station/BatteryOpModelDetail.cs @@ -0,0 +1,99 @@ +using System; +using System.Linq; +using System.Text; +using SqlSugar; + +namespace Entity.DbModel.Station +{ + /// + ///电池运营模型详情 + /// + [SugarTable("battery_op_model_detail")] + public partial class BatteryOpModelDetail + { + public BatteryOpModelDetail(){ + + + } + /// + /// Desc:id + /// Default: + /// Nullable:False + /// + [SugarColumn(IsPrimaryKey=true,ColumnName="id")] + public int Id {get;set;} + + /// + /// Desc:模型Id + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="model_id")] + public int? ModelId {get;set;} + + /// + /// Desc:开始时间:06:00:00 + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="start_time")] + public string StartTime {get;set;} + + /// + /// Desc:结束时间:06:00:01 + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="end_time")] + public string EndTime {get;set;} + + /// + /// Desc:需要电池数量 + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="battery_count")] + public int? BatteryCount {get;set;} + + /// + /// Desc:需要电池类型 + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="battery_type")] + public string BatteryType {get;set;} + + /// + /// Desc:创建人 + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="created_by")] + public string CreatedBy {get;set;} + + /// + /// Desc:创建时间 + /// Default:CURRENT_TIMESTAMP + /// Nullable:True + /// + [SugarColumn(ColumnName="created_time")] + public DateTime? CreatedTime {get;set;} + + /// + /// Desc:更新人 + /// Default: + /// Nullable:True + /// + [SugarColumn(ColumnName="updated_by")] + public string UpdatedBy {get;set;} + + /// + /// Desc:更新时间 + /// Default:CURRENT_TIMESTAMP + /// Nullable:True + /// + [SugarColumn(ColumnName="updated_time")] + public DateTime? UpdatedTime {get;set;} + + } +} diff --git a/Entity/DbModel/Station/ElecPriceModelVersion.cs b/Entity/DbModel/Station/ElecPriceModelVersion.cs index 6e1ad57..49639fa 100644 --- a/Entity/DbModel/Station/ElecPriceModelVersion.cs +++ b/Entity/DbModel/Station/ElecPriceModelVersion.cs @@ -29,7 +29,7 @@ namespace Entity.DbModel.Station /// Nullable:True /// [SugarColumn(ColumnName="version")] - public string Version {get;set;} + public int Version {get;set;} /// /// Desc:生效时间;生效时间(左开右闭) diff --git a/Entity/DbModel/Station/ElecPriceModelVersionDetail.cs b/Entity/DbModel/Station/ElecPriceModelVersionDetail.cs index 06d64f0..a25bd21 100644 --- a/Entity/DbModel/Station/ElecPriceModelVersionDetail.cs +++ b/Entity/DbModel/Station/ElecPriceModelVersionDetail.cs @@ -26,7 +26,7 @@ namespace Entity.DbModel.Station /// Nullable:True /// [SugarColumn(ColumnName = "version")] - public string Version { get; set; } + public int Version { get; set; } /// /// Desc:开始时间 diff --git a/HybirdFrameworkCore/Autofac/Attribute/ScopeAttribute.cs b/HybirdFrameworkCore/Autofac/Attribute/ScopeAttribute.cs index 5e34d5a..232b64f 100644 --- a/HybirdFrameworkCore/Autofac/Attribute/ScopeAttribute.cs +++ b/HybirdFrameworkCore/Autofac/Attribute/ScopeAttribute.cs @@ -4,7 +4,7 @@ public class ScopeAttribute : System.Attribute { public readonly string Scope; - public ScopeAttribute(string scope) + public ScopeAttribute(string scope = "SingleInstance") { Scope = scope; } diff --git a/Repository/BaseRepository.cs b/Repository/BaseRepository.cs index b321142..bd65d30 100644 --- a/Repository/BaseRepository.cs +++ b/Repository/BaseRepository.cs @@ -7,8 +7,6 @@ namespace Repository; public abstract class BaseRepository where T : class, new() { - private readonly ISqlSugarClient DbBaseClient; - //private readonly IUnitOfWork _unitOfWork; protected BaseRepository(ISqlSugarClient sqlSugar) { @@ -16,6 +14,8 @@ public abstract class BaseRepository where T : class, new() DbBaseClient = sqlSugar; } + public ISqlSugarClient DbBaseClient; + /// /// 根据主值查询单条数据 /// @@ -33,7 +33,7 @@ public abstract class BaseRepository where T : class, new() /// /// 根据主值查询单条数据 /// - /// id(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),如果是联合主键,请使用Where条件 + /// Id(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),如果是联合主键,请使用Where条件 /// 是否使用WITH(NOLOCK) /// 数据实体 public async Task QueryByIdAsync(object objId, bool blUseNoLock = false) @@ -59,44 +59,6 @@ public abstract class BaseRepository where T : class, new() .WithNoLockOrNot(blUseNoLock) .ToList(); } - public async Task> QueryPageAsync( - bool isWhere1, Expression> expression1, - bool isWhere2, Expression> expression2, - bool isWhere3, Expression> expression3, - int pageNumber, int pageSize, RefAsync totalNumber, - PageConfigReq input, bool blUseNoLock = false) - { - var page = await DbBaseClient - .Queryable() - .WhereIF(isWhere1, expression1) - .WhereIF(isWhere2, expression2) - .WhereIF(isWhere3, expression3) - .OrderBuilder(input) - .WithNoLockOrNot(blUseNoLock) - .ToPageListAsync(pageNumber, pageSize, totalNumber); - return page; - } - - public async Task UpdateAsync(T updateObj, bool ignoreAllNullColumns) - { - return await DbBaseClient - .Updateable(updateObj) - .IgnoreColumns(ignoreAllNullColumns) - .ExecuteCommandAsync(); - } - - public async Task> QueryByGroupByAsync( - Expression> expression, - Expression> expression2 - ) - { - return await DbBaseClient - .Queryable() - .GroupBy(expression) - .Select(expression2) - .ToListAsync(); - } - /// /// 根据主值列表查询单条数据 @@ -128,6 +90,98 @@ public abstract class BaseRepository where T : class, new() .ToList(); } + /// + /// 根据条件查询表单数据(分页) + /// + /// 页数 + /// 每页几条数据 + /// 是否使用WITH(NOLOCK) + /// + public IPage QueryIPageByCause(QueryPageModel page, Expression> predicate) + { + if (null == predicate) + { + return this.QueryIPage(page); + } + int totalCount = 0; + + + List pageList = DbBaseClient + .Queryable() + .Where(predicate) + .WithNoLockOrNot(false) + .ToPageList(page.Page, page.PageSize, ref totalCount); + + + + return new IPage(totalCount, page, pageList); + } + + /// + /// 根据条件查询表单数据(分页) 异步 + /// + /// + /// + /// + public async Task> QueryIPageByCauseAsync(QueryPageModel page, Expression> predicate) + { + if (null == predicate) + { + return await this.QueryIPageAsync(page); + } + RefAsync totalCount = 0; + + + List pageList = await DbBaseClient + .Queryable() + .Where(predicate) + .WithNoLockOrNot(false) + .ToPageListAsync(page.Page, page.PageSize, totalCount); + + + + return new IPage(totalCount, page, pageList); + } + + + /// + /// 查询表单所有数据(分页) + /// + /// 页数 + /// 每页几条数据 + /// 是否使用WITH(NOLOCK) + /// + public IPage QueryIPage(QueryPageModel page) + { + int totalCount = 0; + //page.Page = page.Page == 0 ? 1 : page.Page;//默认第一页 10条数据 + //page.PageSize = page.PageSize == 0 ? 10 : page.PageSize; + + List pageList = DbBaseClient + .Queryable() + .WithNoLockOrNot(false) + .ToPageList(page.Page, page.PageSize, ref totalCount); + + return new IPage(totalCount, page, pageList); + } + + /// + /// 查询表单所有数据(分页) 异步 + /// + /// + /// + public async Task> QueryIPageAsync(QueryPageModel page) + { + RefAsync totalCount = 0; + + List pageList = await DbBaseClient + .Queryable() + .WithNoLockOrNot(false) + .ToPageListAsync(page.Page, page.PageSize, totalCount); + + return new IPage(totalCount, page, pageList); + } + /// /// 根据主值列表查询单条数据 /// @@ -186,6 +240,7 @@ public abstract class BaseRepository where T : class, new() .ToList(); } + /// /// 根据条件查询数据 /// @@ -203,6 +258,66 @@ public abstract class BaseRepository where T : class, new() .WithNoLockOrNot(blUseNoLock) .ToListAsync(); } + public async Task> QueryListByClauseAsync( + bool isWhere, Expression> expression, + Expression> orderBy, + bool blUseNoLock = false) + { + return await DbBaseClient + .Queryable() + .OrderBy(orderBy, OrderByType.Asc) + .WhereIF(isWhere, expression) + .WithNoLockOrNot(blUseNoLock) + .Select() + .ToListAsync(); + } + + public async Task> QueryListByClauseAsync( + Expression> expression, Expression> expression1 + ) + { + return await DbBaseClient + .Queryable() + .Where(expression) + .ToListAsync(expression1); + } + + public async Task> QueryListBySelectClauseAsync(Expression> selectExpression) + { + return await DbBaseClient + .Queryable() + .Select(selectExpression) + .ToListAsync(); + } + + public async Task> QueryListByOrderClauseAsync(Expression> expression) + { + return await DbBaseClient + .Queryable() + .OrderBy(expression, OrderByType.Asc) + .ToListAsync(); + } + public async Task> QueryListByClauseAsync( + Expression>> include1, + Expression> expression) + { + return await DbBaseClient + .Queryable() + .Includes(include1) + .OrderBy(expression, OrderByType.Asc) + .ToListAsync(); + } + public async Task> QueryListByInludeClauseAsync( + Expression> include1, Expression> expression, Expression> expression2 + ) + { + return await DbBaseClient + .Queryable() + .Includes(include1) + .Where(expression) + .OrderBy(expression2, OrderByType.Asc) + .ToListAsync(); + } /// /// 根据条件查询数据 @@ -239,6 +354,89 @@ public abstract class BaseRepository where T : class, new() .WithNoLockOrNot(blUseNoLock) .ToListAsync(); } + public async Task> QueryListByClauseAsync( + bool isWhere, Expression> expression, + bool isWhere1, Expression> expression1, + bool isWhere2, Expression> expression2, + Expression> expression3, + bool blUseNoLock = false) + { + return await DbBaseClient + .Queryable() + .OrderBy(expression3, OrderByType.Asc) + .WhereIF(isWhere, expression) + .WhereIF(isWhere1, expression1) + .WhereIF(isWhere2, expression2) + .WithNoLockOrNot(blUseNoLock) + .ToListAsync(); + } + public async Task> QueryListByClauseAsync( + Expression> expression, + bool isWhere1, Expression> expression1, + bool isWhere2, Expression> expression2, + Expression> expression3, + int pageNumber, int pageSize, RefAsync totalNumber, + bool blUseNoLock = false) + { + return await DbBaseClient + .Queryable() + .OrderBy(expression3, OrderByType.Asc) + .Where(expression) + .WhereIF(isWhere1, expression1) + .WhereIF(isWhere2, expression2) + .WithNoLockOrNot(blUseNoLock) + .ToPageListAsync(pageNumber, pageSize, totalNumber); + } + public async Task> QueryTreeByClauseAsync( + Expression> expression, + Expression>> childListExpression, Expression> parentIdExpression, object rootValue) + { + return await DbBaseClient + .Queryable() + .OrderBy(expression, OrderByType.Asc) + .ToTreeAsync(childListExpression, parentIdExpression, rootValue); + } + public async Task> QueryTreeByClauseAsync( + Expression> expression, + Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds) + { + return await DbBaseClient + .Queryable() + .OrderBy(expression, OrderByType.Asc) + .ToTreeAsync(childListExpression, parentIdExpression, rootValue, childIds); + } + public async Task> QueryTreeByClauseAsync( + Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true) + { + return await DbBaseClient + .Queryable() + .ToChildListAsync(parentIdExpression, primaryKeyValue, isContainOneself); + } + public async Task> QueryTreeByClauseAsync( + Expression> expression, + Expression> expression1, + Expression>> childListExpression, Expression> parentIdExpression, object rootValue + ) + { + return await DbBaseClient + .Queryable() + .Where(expression) + .OrderBy(expression1, OrderByType.Asc) + .ToTreeAsync(childListExpression, parentIdExpression, rootValue); + } + public async Task> QueryTreeByClauseAsync( + Expression> expression, + Expression> expression1, + Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds + ) + { + return await DbBaseClient + .Queryable() + .Where(expression) + .OrderBy(expression1, OrderByType.Asc) + .ToTreeAsync(childListExpression, parentIdExpression, rootValue, childIds); + } + /// /// 根据条件查询数据 @@ -277,6 +475,19 @@ public abstract class BaseRepository where T : class, new() .WithNoLockOrNot(blUseNoLock) .ToListAsync(); } + public async Task> QueryListByClauseAsync( + Expression> expression, + bool isWhere, Expression> whereIfExpression, + Expression> selectExpression + ) + { + return await DbBaseClient + .Queryable() + .Where(expression) + .WhereIF(isWhere, whereIfExpression) + .Select(selectExpression) + .ToListAsync(); + } /// /// 根据条件查询一定数量数据 @@ -387,6 +598,47 @@ public abstract class BaseRepository where T : class, new() .WithNoLockOrNot(blUseNoLock) .FirstAsync(predicate); } + public async Task> QueryByGroupByAsync( + Expression> expression, + Expression> expression2 + ) + { + return await DbBaseClient + .Queryable() + .GroupBy(expression) + .Select(expression2) + .ToListAsync(); + } + public async Task> QueryByClauseAsync(Expression> predicate, Expression> selectExpression, bool blUseNoLock = false) + { + return await DbBaseClient + .Queryable() + .Where(predicate) + .Select(selectExpression) + .WithNoLockOrNot(blUseNoLock) + .ToListAsync(); + } + + public async Task UpdateColumnsAsync( + T updateObj, + Expression> columns + ) + { + return await DbBaseClient + .Updateable(updateObj) + .UpdateColumns(columns) + .ExecuteCommandAsync(); + } + + + public async Task> QueryListByClauseAsync( + Expression> expression) + { + return await DbBaseClient + .Queryable() + .Where(expression) + .ToListAsync(); + } /// /// 根据条件查询数据 @@ -423,6 +675,99 @@ public abstract class BaseRepository where T : class, new() .WithNoLockOrNot(blUseNoLock) .FirstAsync(predicate); } + public async Task> QueryByOrderByClauseAsync + ( + Expression> expression, + Expression> expression1, + bool blUseNoLock = false) + { + return await DbBaseClient + .Queryable() + .Where(expression) + .OrderBy(expression1, OrderByType.Asc) + .WithNoLockOrNot(blUseNoLock) + .ToListAsync(); + } + public List QueryByClauseToList( + Expression> expression, Expression> expression2, + Expression> expression1, bool blUseNoLock = false) + { + return DbBaseClient + .Queryable() + .Where(expression) + .Where(expression2) + .OrderBy(expression1, OrderByType.Asc) + .WithNoLockOrNot(blUseNoLock) + .ToList(); + } + public List QueryByClauseToList(Expression> expression, Expression> expression2, bool blUseNoLock = false) + { + return DbBaseClient + .Queryable() + .Where(expression) + .Where(expression2) + .WithNoLockOrNot(blUseNoLock) + .ToList(); + } + public List QueryByClauseToList(Expression> expression, Expression> expression1, bool blUseNoLock = false) + { + return DbBaseClient + .Queryable() + .Where(expression) + .OrderBy(expression1, OrderByType.Asc) + .WithNoLockOrNot(blUseNoLock) + .ToList(); + } + public List QueryByClauseToList(Expression> expression) + { + return DbBaseClient + .Queryable() + .Where(expression) + .ToList(); + } + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public async Task> QueryByClauseAsync( + Expression> joinExpression, + Expression> whereExpression, + Expression> orderExpression, + Expression> selectExpression + ) + { + return await DbBaseClient + .Queryable() + .LeftJoin(joinExpression) + .Where(whereExpression) + .OrderBy(orderExpression, OrderByType.Asc) + .Select(selectExpression) + .ToListAsync(); + } + public async Task> QueryByClauseAsync( + Expression> joinExpression, + Expression> whereExpression, + bool isWhere, Expression> whereifExpression, + Expression> orderExpression, + Expression> selectExpression + ) + { + return await DbBaseClient + .Queryable() + .LeftJoin(joinExpression) + .Where(whereExpression) + .WhereIF(isWhere, whereifExpression) + .OrderBy(orderExpression, OrderByType.Asc) + .Select(selectExpression) + .ToListAsync(); + } /// /// 写入实体数据 @@ -435,6 +780,16 @@ public abstract class BaseRepository where T : class, new() .Insertable(entity) .ExecuteReturnIdentity(); } + + /// + /// 写入或者更新实体数据 + /// + /// 实体数据 + /// + public int InsertOrUpdate(T entity) + { + return DbBaseClient.Storageable(entity).ExecuteCommand(); + } /// /// 写入实体数据 @@ -447,7 +802,12 @@ public abstract class BaseRepository where T : class, new() .Insertable(entity) .ExecuteReturnIdentityAsync(); } - + public async Task InsertReturnEntityAsync(T entity) + { + return await DbBaseClient + .Insertable(entity) + .ExecuteReturnEntityAsync(); + } /// /// 写入实体数据 /// @@ -554,6 +914,64 @@ public abstract class BaseRepository where T : class, new() return await DbBaseClient.Updateable(entity).ExecuteCommandHasChangeAsync(); } + public async Task UpdateAsync( + Expression> expression + ) + { + return await DbBaseClient + .Queryable() + .ClearFilter() + .AnyAsync(expression); + } + + public int Update(Expression> columns, + Expression> expression) + { + return DbBaseClient.Updateable().SetColumns(columns).Where(expression).ExecuteCommand(); + } + + + public async Task UpdateAsync( + Expression> columns, + Expression> expression + ) + { + return await DbBaseClient + .Updateable() + .SetColumns(columns) + .Where(expression) + .ExecuteCommandAsync(); + } + + public async Task UpdateAsync( + Expression> columns + ) + { + return await DbBaseClient + .Updateable() + .IgnoreColumns(columns) + .ExecuteCommandAsync(); + } + public async Task UpdateAsync( + T updateObj, + bool ignoreAllNullColumns + ) + { + return await DbBaseClient + .Updateable(updateObj) + .IgnoreColumns(ignoreAllNullColumns) + .ExecuteCommandAsync(); + } + public async Task UpdateAsync( + T updateObj, bool ignoreAllNullColumns, Expression> columns + ) + { + return await DbBaseClient + .Updateable(updateObj) + .IgnoreColumns(ignoreAllNullColumns) + .IgnoreColumns(columns) + .ExecuteCommandAsync(); + } /// /// 更新实体数据 /// @@ -574,6 +992,7 @@ public abstract class BaseRepository where T : class, new() return await DbBaseClient.Updateable(entity).ExecuteCommandHasChangeAsync(); } + /// /// 根据手写条件更新 /// @@ -718,7 +1137,23 @@ public abstract class BaseRepository where T : class, new() { return await DbBaseClient.Deleteable(entity).ExecuteCommandHasChangeAsync(); } - + /// + /// 新增方法 + /// 该方法用于:根据角色Id删除用户角色 + /// + /// + /// + /// + /// + public async Task DeleteUserRoleByRoleId( + Expression> predicate, + Expression> selectExpression, Action action) + { + await DbBaseClient.Queryable() + .Where(predicate) + .Select(selectExpression) + .ForEachAsync(action); + } /// /// 删除数据 /// @@ -1043,99 +1478,100 @@ public abstract class BaseRepository where T : class, new() { return await DbBaseClient.Queryable().Where(predicate).WithNoLockOrNot(blUseNoLock).SumAsync(field); } - /// - /// 根据条件查询表单数据(分页) - /// - /// 页数 - /// 每页几条数据 - /// 是否使用WITH(NOLOCK) - /// - public IPage QueryIPageByCause(QueryPageModel page, Expression> predicate) - { - if (null == predicate) - { - return this.QueryIPage(page); - } - int totalCount = 0; - - - List pageList = DbBaseClient - .Queryable() - .Where(predicate) - .WithNoLockOrNot(false) - .ToPageList(page.Page, page.PageSize, ref totalCount); - return new IPage(totalCount, page, pageList); - } - - /// - /// 根据条件查询表单数据(分页) 异步 - /// - /// - /// - /// - public async Task> QueryIPageByCauseAsync(QueryPageModel page, Expression> predicate) + public async Task> QueryPageByIncludeAsync(Expression> include1, + Expression> whereExpression, bool isWhere, Expression> expression, + bool isWhere1, Expression> expression1, + Expression> orderExpression, + //TODO:: + int pageIndex = 1, int pageSize = 20, RefAsync totalNumber = null, bool blUseNoLock = false) { - if (null == predicate) - { - return await this.QueryIPageAsync(page); - } - RefAsync totalCount = 0; - + var page = await DbBaseClient + .Queryable() + .Includes(include1) + .Where(whereExpression) + .WhereIF(isWhere, expression) + .WhereIF(isWhere1, expression1) + .OrderBy(orderExpression, OrderByType.Asc) + .WithNoLockOrNot(blUseNoLock) + .ToPageListAsync(pageIndex, pageSize, totalNumber); + return page; + } - List pageList = await DbBaseClient - .Queryable() - .Where(predicate) - .WithNoLockOrNot(false) - .ToPageListAsync(page.Page, page.PageSize, totalCount); - return new IPage(totalCount, page, pageList); + public async Task> QueryPageAsync( + bool isWhere1, Expression> expression1, + bool isWhere2, Expression> expression2, + Expression> orderBy, + int pageNumber, int pageSize, RefAsync totalNumber, + bool blUseNoLock = false) + { + var page = await DbBaseClient + .Queryable() + .OrderBy(orderBy, OrderByType.Asc) + .WhereIF(isWhere1, expression1) + .WhereIF(isWhere2, expression2) + .WithNoLockOrNot(blUseNoLock) + .ToPageListAsync(pageNumber, pageSize, totalNumber); + return page; } - - /// - /// 查询表单所有数据(分页) - /// - /// 页数 - /// 每页几条数据 - /// 是否使用WITH(NOLOCK) - /// - public IPage QueryIPage(QueryPageModel page) + public async Task> QueryPageAsync( + bool isWhere1, Expression> expression1, + bool isWhere2, Expression> expression2, + int pageNumber, int pageSize, RefAsync totalNumber, + bool blUseNoLock = false) { - int totalCount = 0; - //page.Page = page.Page == 0 ? 1 : page.Page;//默认第一页 10条数据 - //page.PageSize = page.PageSize == 0 ? 10 : page.PageSize; + var page = await DbBaseClient + .Queryable() + .WhereIF(isWhere1, expression1) + .WhereIF(isWhere2, expression2) + .WithNoLockOrNot(blUseNoLock) + .ToPageListAsync(pageNumber, pageSize, totalNumber); + return page; + } - List pageList = DbBaseClient - .Queryable() - .WithNoLockOrNot(false) - .ToPageList(page.Page, page.PageSize, ref totalCount); - return new IPage(totalCount, page, pageList); + public async Task> QueryPageAsync( + bool isWhere1, Expression> expression1, + bool isWhere2, Expression> expression2, + bool isWhere3, Expression> expression3, + Expression> orderBy, + int pageNumber, int pageSize, RefAsync totalNumber, + bool blUseNoLock = false) + { + var page = await DbBaseClient + .Queryable() + .OrderBy(orderBy, OrderByType.Asc) + .WhereIF(isWhere1, expression1) + .WhereIF(isWhere2, expression2) + .WhereIF(isWhere3, expression3) + .WithNoLockOrNot(blUseNoLock) + .ToPageListAsync(pageNumber, pageSize, totalNumber); + return page; } - - /// - /// 查询表单所有数据(分页) 异步 - /// - /// - /// - public async Task> QueryIPageAsync(QueryPageModel page) + public async Task> QueryPageAsync( + bool isWhere1, Expression> expression1, + bool isWhere2, Expression> expression2, + bool isWhere3, Expression> expression3, + int pageNumber, int pageSize, RefAsync totalNumber, + PageConfigReq input, bool blUseNoLock = false) { - RefAsync totalCount = 0; - - List pageList = await DbBaseClient + var page = await DbBaseClient .Queryable() - .WithNoLockOrNot(false) - .ToPageListAsync(page.Page, page.PageSize, totalCount); - - return new IPage(totalCount, page, pageList); + .WhereIF(isWhere1, expression1) + .WhereIF(isWhere2, expression2) + .WhereIF(isWhere3, expression3) + .OrderBuilder(input) + .WithNoLockOrNot(blUseNoLock) + .ToPageListAsync(pageNumber, pageSize, totalNumber); + return page; } - /// /// 查询-2表查询 /// @@ -1337,4 +1773,7 @@ public abstract class BaseRepository where T : class, new() var list = await DbBaseClient.SqlQueryable(sql).ToListAsync(); return list; } + + + } \ No newline at end of file diff --git a/Repository/Station/BatteryOpModelDetailRepository.cs b/Repository/Station/BatteryOpModelDetailRepository.cs new file mode 100644 index 0000000..3242768 --- /dev/null +++ b/Repository/Station/BatteryOpModelDetailRepository.cs @@ -0,0 +1,13 @@ +using Entity.DbModel.Station; +using HybirdFrameworkCore.Autofac.Attribute; +using SqlSugar; + +namespace Repository.Station; + +[Scope("SingleInstance")] +public class BatteryOpModelDetailRepository : BaseRepository +{ + public BatteryOpModelDetailRepository(ISqlSugarClient sqlSugar) : base(sqlSugar) + { + } +} \ No newline at end of file diff --git a/Repository/Station/BatteryOpModelRepository.cs b/Repository/Station/BatteryOpModelRepository.cs new file mode 100644 index 0000000..842b8bf --- /dev/null +++ b/Repository/Station/BatteryOpModelRepository.cs @@ -0,0 +1,13 @@ +using Entity.DbModel.Station; +using HybirdFrameworkCore.Autofac.Attribute; +using SqlSugar; + +namespace Repository.Station; + +[Scope("SingleInstance")] +public class BatteryOpModelRepository : BaseRepository +{ + public BatteryOpModelRepository(ISqlSugarClient sqlSugar) : base(sqlSugar) + { + } +} \ No newline at end of file diff --git a/Repository/Station/BinInfoRepository.cs b/Repository/Station/BinInfoRepository.cs index 9518b26..214f21a 100644 --- a/Repository/Station/BinInfoRepository.cs +++ b/Repository/Station/BinInfoRepository.cs @@ -3,10 +3,21 @@ using HybirdFrameworkCore.Autofac.Attribute; using SqlSugar; namespace Repository.Station; + [Scope("SingleInstance")] -public class BinInfoRepository:BaseRepository +public class BinInfoRepository : BaseRepository { public BinInfoRepository(ISqlSugarClient sqlSugar) : base(sqlSugar) { } + + /// + /// + /// + /// + /// + public BinInfo? QueryByBinNo(string binNo) + { + return this.QueryByClause(it => it.No == binNo); + } } \ No newline at end of file diff --git a/Service/Charger/ChargerService.cs b/Service/Charger/ChargerService.cs new file mode 100644 index 0000000..570e755 --- /dev/null +++ b/Service/Charger/ChargerService.cs @@ -0,0 +1,72 @@ +using Entity.DbModel.Station; +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkCore.Entity; +using Repository.Station; +using Service.Charger.Client; + +namespace Service.Charger; + +/// +/// 充电机服务 +/// +[Scope] +public class ChargerService +{ + public BinInfoRepository BinInfoRepository { get; set; } + + /// + /// 启动充电 + /// + /// + /// + public Result StartChargeByBinNo(string binNo) + { + BinInfo? binInfo = BinInfoRepository.QueryByBinNo(binNo); + if (binInfo == null) + { + return Result.Fail(@"充电仓不存在"); + } + + if (string.IsNullOrWhiteSpace(binInfo.ChargerNo)) + { + return Result.Fail(@"充电仓未配置充电机编号"); + } + + ChargerClient? chargerClient = ClientMgr.GetBySn(binInfo.ChargerNo); + if (chargerClient == null || !chargerClient.Connected) + { + return Result.Fail(@"充电机未连接"); + } + + return chargerClient.StartCharge(); + } + + /// + /// 停止充电 + /// + /// + /// + public Result StopChargeByBinNo(string binNo) + { + BinInfo? binInfo = BinInfoRepository.QueryByBinNo(binNo); + if (binInfo == null) + { + return Result.Fail(@"充电仓不存在"); + } + + if (string.IsNullOrWhiteSpace(binInfo.ChargerNo)) + { + return Result.Fail(@"充电仓未配置充电机编号"); + } + + ChargerClient? chargerClient = ClientMgr.GetBySn(binInfo.ChargerNo); + if (chargerClient == null || !chargerClient.Connected) + { + return Result.Fail(@"充电机未连接"); + } + + chargerClient.SendRemoteStopCharging(); + + return Result.Success("发送停止命令成功"); + } +} \ No newline at end of file diff --git a/Service/Charger/Client/ChargerClient.cs b/Service/Charger/Client/ChargerClient.cs index a8cd15d..d351fbf 100644 --- a/Service/Charger/Client/ChargerClient.cs +++ b/Service/Charger/Client/ChargerClient.cs @@ -27,7 +27,6 @@ namespace Service.Charger.Client; [Scope("InstancePerDependency")] public class ChargerClient : TcpClient { - #region 属性 public ushort AuthTimes { get; set; } = 0; @@ -37,10 +36,12 @@ public class ChargerClient : TcpClient /// 参考 Service.Charger.Common.ChargingStatus /// public UInt16 ChargingStatus { get; set; } + /// /// 是否已经开始充电 /// public bool IsCharged { get; set; } = false; + public bool IsStopped { get; set; } = false; public bool IsCanSendStopCmd { get; set; } = true; @@ -51,44 +52,53 @@ public class ChargerClient : TcpClient /// /// 电池包实时数据 /// - public BatteryPackData? BatteryPackData { get; set; } + public BatteryPackData? BatteryPackData { get; set; } + /// /// 电池包实时单体温度&单体电压数据 /// - public BatteryPackDataVoltage? BatteryPackDataVoltage { get; set; } + public BatteryPackDataVoltage? BatteryPackDataVoltage { get; set; } + /// /// 电池包上报累计充放电电量 /// - public BatteryPackTotalElectricity? BatteryPackTotalElectricity { get; set; } + public BatteryPackTotalElectricity? BatteryPackTotalElectricity { get; set; } + /// /// 电池包上报充放电口温度 /// - public BatteryPackPortTemperature? BatteryPackPortTemperature { get; set; } + public BatteryPackPortTemperature? BatteryPackPortTemperature { get; set; } + /// /// 电池包内部接触器状态和故障上报 /// - public BatteryPackStateAndFault? BatteryPackStateAndFault { get; set; } + public BatteryPackStateAndFault? BatteryPackStateAndFault { get; set; } /// /// 充放电设备应答站功率调节指令 /// public PowerRegulationRes PowerRegulationRes { get; set; } + /// /// 电池包实时遥信上报(站内充电模式有电池包时周期性上传) /// public RemoteSignaling RemoteSignaling { get; set; } + /// /// 充电机上报车辆 VIN /// public VehicleVIN VehicleVIN { get; set; } + /// /// 充放电机应答辅助控制 /// public AuxiliaryPowerRes AuxiliaryPowerRes { get; set; } + /// /// 充放电上报交流电表数据(交流电表接到充电机上的情况) /// public AcMeter AcMeter { get; set; } + /// ///充电机遥信数据 /// @@ -98,14 +108,17 @@ public class ChargerClient : TcpClient /// 充电机工作状态-从遥信数据包中得到。00H:待机 01H:工作 02H:工作完成 03H:充/放电暂停 /// public byte Workstate { get; set; } + /// /// 充电机故障-遥信数据包总故障 00H正常、01H故障 /// public bool TotalError { get; set; } + /// /// 充电机告警-遥信数据包总告警 00H正常、01H告警 /// public bool TotalWarning { get; set; } + /// /// 充电机遥测数据 /// @@ -115,35 +128,47 @@ public class ChargerClient : TcpClient ///充电机实时充电功率 /// public float RealTimeChargePower { get; set; } = 0; + /// /// 心跳-桩状态 /// public byte PileState { get; set; } + /// /// 电池编码 /// - public string? BatterNo { get; set; } + public string? BatteryNo { get; set; } + + /// + /// 电池厂家 + /// + public byte? BatteryFactory { get; set; } + /// /// 电池仓编号 /// public string? BinNo { get; set; } + /// /// 远程升级-监控网关上送升级完成确认帧 /// public UplinkUpgrade UplinkUpgrade { get; set; } + /// /// 充电订单号 /// - public string? ChargeOrderNo { get; set; } + public string? ChargeOrderNo { get; set; } + /// /// 当前指令 /// public string? CurrentCmd { get; set; } + /// /// 当前接收报文 /// public string? CurrentMsg { get; set; } - + #endregion #region db @@ -158,14 +183,15 @@ public class ChargerClient : TcpClient _chargeOrderRepository = chargeOrderRepository; _binInfoRepository = binInfoRepository; } - + /// /// /// /// public void ReceiveMsgHandle(ASDU asdu) { - this.CurrentMsg = CurrentCmd = JsonConvert.SerializeObject(asdu, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(asdu.ToBytes()); + this.CurrentMsg = CurrentCmd = JsonConvert.SerializeObject(asdu, Formatting.Indented) + "\r\n" + + BitUtls.BytesToHexStr(asdu.ToBytes()); } #region 发送指令 @@ -183,7 +209,7 @@ public class ChargerClient : TcpClient return AuthTimes; } - + /// /// 发送鉴权 @@ -193,7 +219,8 @@ public class ChargerClient : TcpClient byte authCodeKey = ChargerUtils.GetByteRandomNum(); //鉴码KEY[随机数] byte[] authCodes = ChargerUtils.GetAuthCodesResult(ChargerConst.AuthCode, authCodeKey); //鉴权码 Auth auth = new Auth(IncreAuthTimes(), authCodes, authCodeKey); - CurrentCmd = JsonConvert.SerializeObject(auth, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(auth.ToBytes()); + CurrentCmd = JsonConvert.SerializeObject(auth, Formatting.Indented) + "\r\n" + + BitUtls.BytesToHexStr(auth.ToBytes()); this.Channel.WriteAndFlushAsync(auth); } @@ -204,15 +231,17 @@ public class ChargerClient : TcpClient /// 功率调节指令类型.默认1 绝对功率值 /// 0.1kw/位,默认3600 /// 充电流水号 - public string SendRemoteStartCharging(byte socLimit, float changePower=3600, byte changePowerCmdType=1, + public string SendRemoteStartCharging(byte socLimit, float changePower = 3600, byte changePowerCmdType = 1, string? chargeOrderNo = null) { if (string.IsNullOrWhiteSpace(chargeOrderNo)) { chargeOrderNo = ChargerUtils.GenChargeOrderSn(); } + var remoteStartCharging = new RemoteStartCharging(socLimit, changePowerCmdType, changePower, chargeOrderNo); - CurrentCmd = JsonConvert.SerializeObject(remoteStartCharging, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(remoteStartCharging.ToBytes()); + CurrentCmd = JsonConvert.SerializeObject(remoteStartCharging, Formatting.Indented) + "\r\n" + + BitUtls.BytesToHexStr(remoteStartCharging.ToBytes()); this.Channel.WriteAndFlushAsync(remoteStartCharging); return chargeOrderNo; @@ -222,10 +251,11 @@ public class ChargerClient : TcpClient /// 监控平台发送远程停止充电指令 /// /// 0 正常停机 1 服务器发现桩异常,强制停机 - public void SendRemoteStopCharging(byte reason) + public void SendRemoteStopCharging(byte reason = 0) { RemoteStopCharging remoteStopCharging = new RemoteStopCharging(reason); - CurrentCmd = JsonConvert.SerializeObject(remoteStopCharging, Formatting.Indented) + "\r\n" + BitUtls.BytesToHexStr(remoteStopCharging.ToBytes()); + CurrentCmd = JsonConvert.SerializeObject(remoteStopCharging, Formatting.Indented) + "\r\n" + + BitUtls.BytesToHexStr(remoteStopCharging.ToBytes()); this.Channel.WriteAndFlushAsync(remoteStopCharging); } @@ -256,7 +286,8 @@ public class ChargerClient : TcpClient public void SendAuxiliaryPower(byte openFlag) { AuxiliaryPower auxiliaryPower = new AuxiliaryPower(openFlag); - CurrentCmd = JsonConvert.SerializeObject(auxiliaryPower, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(auxiliaryPower.ToBytes()); + CurrentCmd = JsonConvert.SerializeObject(auxiliaryPower, Formatting.Indented) + "\r\n" + + BitUtls.BytesToHexStr(auxiliaryPower.ToBytes()); this.Channel.WriteAndFlushAsync(auxiliaryPower); } @@ -269,12 +300,12 @@ public class ChargerClient : TcpClient public void SendBatteryHolderStatus(byte battery, byte connectionState, byte waterCondition) { BatteryHolderStatus batteryHolderStatus = new BatteryHolderStatus(battery, connectionState, waterCondition); - CurrentCmd = JsonConvert.SerializeObject(batteryHolderStatus, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(batteryHolderStatus.ToBytes()); + CurrentCmd = JsonConvert.SerializeObject(batteryHolderStatus, Formatting.Indented) + "\r\n" + + BitUtls.BytesToHexStr(batteryHolderStatus.ToBytes()); this.Channel.WriteAndFlushAsync(batteryHolderStatus); } - /// /// 站控下发 VIN 鉴权的结果 /// @@ -284,6 +315,7 @@ public class ChargerClient : TcpClient AuthenticationVIN authenticationVIN = new AuthenticationVIN(vinresult); this.Channel.WriteAndFlushAsync(authenticationVIN); } + /// /// 远程升级-站级监控升级请求下发 /// @@ -295,9 +327,10 @@ public class ChargerClient : TcpClient /// MD5校验值 /// URL(文件路径) public void SendUpgradeRequest(byte executionControl, byte downloadTimeout, string versionNumber, - string fileName, uint fileSize, string mD5Verification, string url) + string fileName, uint fileSize, string mD5Verification, string url) { - UpgradeRequest upgradeRequest=new UpgradeRequest(executionControl, downloadTimeout, versionNumber, fileName, fileSize, mD5Verification, url); + UpgradeRequest upgradeRequest = new UpgradeRequest(executionControl, downloadTimeout, versionNumber, fileName, + fileSize, mD5Verification, url); this.Channel.WriteAndFlushAsync(upgradeRequest); } @@ -307,7 +340,8 @@ public class ChargerClient : TcpClient /// public void SendSetPeakValleyTime(SetPeakValleyTime setPeakValleyTime) { - CurrentCmd = JsonConvert.SerializeObject(setPeakValleyTime, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(setPeakValleyTime.ToBytes()); + CurrentCmd = JsonConvert.SerializeObject(setPeakValleyTime, Formatting.Indented) + "\r\n" + + BitUtls.BytesToHexStr(setPeakValleyTime.ToBytes()); this.Channel.WriteAndFlushAsync(setPeakValleyTime); } @@ -318,7 +352,8 @@ public class ChargerClient : TcpClient public void SendOfflineStopCharging(byte enabled) { OfflineStopCharging offlineStopCharging = new OfflineStopCharging(enabled); - CurrentCmd = JsonConvert.SerializeObject(offlineStopCharging, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(offlineStopCharging.ToBytes()); + CurrentCmd = JsonConvert.SerializeObject(offlineStopCharging, Formatting.Indented) + "\r\n" + + BitUtls.BytesToHexStr(offlineStopCharging.ToBytes()); this.Channel.WriteAndFlushAsync(offlineStopCharging); } @@ -338,7 +373,8 @@ public class ChargerClient : TcpClient public void SendQueryBattery() { QueryBattery queryBattery = new QueryBattery(ChargerConst.BatteryNo); - CurrentCmd = JsonConvert.SerializeObject(queryBattery, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(queryBattery.ToBytes()); + CurrentCmd = JsonConvert.SerializeObject(queryBattery, Formatting.Indented) + "\r\n" + + BitUtls.BytesToHexStr(queryBattery.ToBytes()); this.Channel.WriteAndFlushAsync(queryBattery); } @@ -356,6 +392,7 @@ public class ChargerClient : TcpClient { return Result.Fail("charger init error with no BinNo"); } + if (!Connected) { return Result.Fail($"charger-{BinNo} disconnect"); @@ -366,12 +403,18 @@ public class ChargerClient : TcpClient { return Result.Fail($"charger-{BinNo} not exist"); } - BatterNo = binInfo.BatteryNo; - if (string.IsNullOrWhiteSpace(BatterNo)) + + BatteryNo = binInfo.BatteryNo; + if (string.IsNullOrWhiteSpace(BatteryNo)) { return Result.Fail($"charger-{BinNo} battery not exist"); } + if (binInfo.Status == 0) + { + return Result.Fail($"仓-{BinNo} 被禁用"); + } + RedisHelper redisHelper = AppInfo.Container.Resolve(); string? lockKey = redisHelper.GetStrValue($"chargeNo{BinNo}Start"); @@ -388,18 +431,18 @@ public class ChargerClient : TcpClient _chargeOrderRepository.Insert(new ChargeOrder() { Sn = chargeOrderNo, - BatteryNo = BatterNo, + BatteryNo = BatteryNo, CmdStatus = 0, ChargerNo = BinNo, ChargeMode = 1, StartMode = 1 }); - return Result.Success(true); + return Result.Success(true, "发送成功"); } #endregion - + /// /// /// diff --git a/Service/Charger/Client/ClientMgr.cs b/Service/Charger/Client/ClientMgr.cs index 7bc7243..b01e218 100644 --- a/Service/Charger/Client/ClientMgr.cs +++ b/Service/Charger/Client/ClientMgr.cs @@ -9,6 +9,7 @@ using log4net; using Repository.Station; using Service.Charger.Common; using Service.Equipment; +using Service.Init; namespace Service.Charger.Client; @@ -82,19 +83,49 @@ public static class ClientMgr } StartAutoChargeThread(); + StartQueryBatteryInfoThread(); + } + } + + private static void StartQueryBatteryInfoThread() + { + Thread thread = new Thread(QueryBatteryInfo) + { + Name = @"QueryBatteryInfoThread" + }; + thread.Start(); + } + + private static void QueryBatteryInfo() + { + while (true) + { + try + { + Thread.Sleep(1000); + foreach (var (key, client) in Dictionary) + { + client.SendQueryBattery(); + } + } + catch (Exception e) + { + Log.Error("QueryBatteryInfo error", e); + } + } } /// /// /// - public static void StartAutoChargeThread() + private static void StartAutoChargeThread() { if (!AutoChargeWorking) { Thread thread = new Thread(AutoChargeThread) { - Name = @"auto-charge" + Name = @"AutoChargeThread" }; thread.Start(); AutoChargeWorking = true; @@ -111,16 +142,42 @@ public static class ClientMgr ElecPriceModelVersionDetailRepository elecPriceModelVersionDetailRepository = AppInfo.Container.Resolve(); + BatteryOpModelRepository batteryOpModelRepository = AppInfo.Container.Resolve(); + BatteryOpModelDetailRepository batteryOpModelDetailRepository = + AppInfo.Container.Resolve(); + + BinInfoRepository binInfoRepository = AppInfo.Container.Resolve(); + while (true) { - Thread.Sleep(1000 * 30); try { + Thread.Sleep(1000 * 30); DateTime now = DateTime.Now; - ElecPriceModelVersion elecPriceModelVersion = elecPriceModelVersionRepository.QueryByClause(i => i.StartTime >= now && i.EndTime < now); + + List binInfos = binInfoRepository.Query(); + if (binInfos.Count < 0) + { + Log.Info("lack of binInfos"); + continue; + } + + var chargeSoc = StaticStationInfo.ChargeSoc; + List socNeedChargeList = binInfos.Where(t => t.Soc < chargeSoc).ToList(); + if (socNeedChargeList.Count < 0) + { + Log.Info($"lack of binInfos.soc < {chargeSoc}"); + continue; + } + + + #region 电价模型 + + int ceid = StaticStationInfo.Ceid; + ElecPriceModelVersion elecPriceModelVersion = elecPriceModelVersionRepository.QueryByClause(i => i.Version == ceid); if (elecPriceModelVersion == null) { - Log.Info("lack of effective elec price model"); + Log.Info("lack of effective elecPriceModelVersion"); continue; } @@ -130,17 +187,57 @@ public static class ClientMgr i.EndMinute > now.Minute).FirstOrDefault(); if (elecPriceModelVersionDetail == null) { - Log.Info("lack of effective elec price model detail"); + Log.Info("lack of effective elecPriceModelVersionDetail"); continue; } - //int batteryCount = elecPriceModelVersionDetail.BatteryCount; + #endregion + + #region 运营模型 + + int oid = int.Parse(StaticStationInfo.Oid); + BatteryOpModel batteryOpModel = batteryOpModelRepository.QueryByClause(d => d.ModelId == oid); + if (batteryOpModel == null) + { + Log.Info("lack of effective batteryOpModel"); + continue; + } + + List batteryOpModelDetails = batteryOpModelDetailRepository.QueryListByClause(d => d.ModelId == oid); + List opModelDetails = batteryOpModelDetails.Where(t => + { + List start = t.StartTime.Split(":").Select(int.Parse).ToList(); + List end = t.EndTime.Split(":").Select(int.Parse).ToList(); + return now.Hour >= start[0] && now.Hour < end[0] && now.Minute >= start[1] && now.Minute < end[1] && now.Second >= start[2] && now.Second < end[2] ; + }).ToList(); + + if (opModelDetails.Count == 0) + { + Log.Info("lack of effective batteryOpModelDetails"); + continue; + } + + int needBatteryCount = opModelDetails[0].BatteryCount ?? 8; + if ((binInfos.Count - socNeedChargeList.Count) >= needBatteryCount) + { + Log.Info($"lack of needBatteryCount {needBatteryCount}"); + continue; + } + #endregion - foreach (KeyValuePair pair in Dictionary) + + foreach (BinInfo binInfo in socNeedChargeList) { - Result result = pair.Value.StartCharge(); - Log.Info($"start {pair.Key} charge {result.IsSuccess}:{result.Msg}"); + if (Dictionary.TryGetValue(binInfo.ChargerNo, out var client)) + { + Result result = client.StartCharge(); + Log.Info($"start {binInfo.ChargerNo} charge {result.IsSuccess}:{result.Msg}"); + } + else + { + Log.Info($"can not find {binInfo.ChargerNo} in dict"); + } } } catch (Exception e) diff --git a/Service/Charger/Handler/QueryBatteryBasicInfo2ResHandler.cs b/Service/Charger/Handler/QueryBatterySnResHandler.cs similarity index 52% rename from Service/Charger/Handler/QueryBatteryBasicInfo2ResHandler.cs rename to Service/Charger/Handler/QueryBatterySnResHandler.cs index 8d93e2d..9e1b86e 100644 --- a/Service/Charger/Handler/QueryBatteryBasicInfo2ResHandler.cs +++ b/Service/Charger/Handler/QueryBatterySnResHandler.cs @@ -2,9 +2,9 @@ using DotNetty.Transport.Channels; using HybirdFrameworkCore.Autofac.Attribute; using log4net; +using Repository.Station; using Service.Charger.Client; using Service.Charger.Msg.Charger.Req; -using Service.Charger.Msg.Charger.Resp; namespace Service.Charger.Handler { @@ -16,9 +16,16 @@ namespace Service.Charger.Handler /// [Order(8)] [Scope("InstancePerDependency")] - public class QueryBatteryBasicInfo2ResHandler : SimpleChannelInboundHandler, IBaseHandler + public class QueryBatterySnResHandler : SimpleChannelInboundHandler, IBaseHandler { - private static readonly ILog Log = LogManager.GetLogger(typeof(QueryBatteryBasicInfo2ResHandler)); + private static readonly ILog Log = LogManager.GetLogger(typeof(QueryBatterySnResHandler)); + + private BinInfoRepository _binInfoRepository; + + public QueryBatterySnResHandler(BinInfoRepository binInfoRepository) + { + _binInfoRepository = binInfoRepository; + } protected override void ChannelRead0(IChannelHandlerContext ctx, QueryBatterySnRes msg) { @@ -30,7 +37,17 @@ namespace Service.Charger.Handler sb.Append(Convert.ToChar(b)); } - client.BatterNo = sb.ToString(); + client.BatteryNo = sb.ToString(); + client.BatteryFactory = msg.BatterFactory; + + if (_binInfoRepository.Update(t => t.BatteryNo == client.BatteryNo, t => t.No == client.BinNo) > 0) + { + Log.Info($"succeed update battery no {client.BatteryNo} for {client.BinNo}"); + } + else + { + Log.Info($"fail update battery no {client.BatteryNo} for {client.BinNo}"); + } Log.Info($"receive {msg} from {sn}"); } diff --git a/Service/Charger/Handler/RecordChargeHandler.cs b/Service/Charger/Handler/RecordChargeHandler.cs index ddf4387..c13daf2 100644 --- a/Service/Charger/Handler/RecordChargeHandler.cs +++ b/Service/Charger/Handler/RecordChargeHandler.cs @@ -73,7 +73,7 @@ namespace Service.Charger.Handler ChargeOrder chargeOrder = new ChargeOrder() { Sn = client.ChargeOrderNo, - BatteryNo = client.BatterNo, + BatteryNo = client.BatteryNo, StartTime = new DateTime((msg.StartYear+1900) , msg.StartMonth ,msg.StartDay ,msg.StartHour, msg.StartMinute, msg.StartSecond), EndTime = new DateTime(msg.EndYear + 1900, msg.EndMonth, msg.EndDay, msg.EndHour, msg.EndMinute, msg.EndSecond), StartSoc = msg.SocBefore, diff --git a/Service/Charger/Msg/Charger/Resp/QueryBatterySnRes.cs b/Service/Charger/Msg/Charger/Resp/QueryBatterySnRes.cs index 19a8b24..18f84d9 100644 --- a/Service/Charger/Msg/Charger/Resp/QueryBatterySnRes.cs +++ b/Service/Charger/Msg/Charger/Resp/QueryBatterySnRes.cs @@ -3,7 +3,7 @@ namespace Service.Charger.Msg.Charger.Req; /// -/// 3.6.2.3 充放电机回复电池基本参数 2(PGN:0x00F802) +/// 3.6.2.3 充放电机上传电池包编码(PGN:0x00F881) /// public class QueryBatterySnRes : ASDU { diff --git a/Service/Init/StaticStationInfo.cs b/Service/Init/StaticStationInfo.cs index a91f3e4..ddfa8f0 100644 --- a/Service/Init/StaticStationInfo.cs +++ b/Service/Init/StaticStationInfo.cs @@ -10,43 +10,59 @@ namespace Service.Init; /// public class StaticStationInfo { - public static string StationStatus + + + public static int StationStatus { - get => Resolve(StationParamConst.StationStatus); + get => int.Parse(Resolve(StationParamConst.StationStatus)); set => Set(StationParamConst.StationStatus, value); } - + public static string OperationStartTime + { + get => Resolve(StationParamConst.OperationStartTime); + set => Set(StationParamConst.OperationStartTime, value); + } + public static string OperationEndTime + { + get => Resolve(StationParamConst.OperationEndTime); + set => Set(StationParamConst.OperationEndTime, value); + } public static string StationWay { get => Resolve(StationParamConst.StationWay); set => Set(StationParamConst.StationWay, value); } - public static string StationModel { get => Resolve(StationParamConst.StationModel); set => Set(StationParamConst.StationModel, value); } - + public static string StationName { get => Resolve(StationParamConst.StationName); set => Set(StationParamConst.StationName, value); } + public static string StationNo { get => Resolve(StationParamConst.StationNo); set => Set(StationParamConst.StationNo, value); } - + public static string StationSn + { + get => Resolve(StationParamConst.StationSn); + set => Set(StationParamConst.StationSn, value); + } + public static string SwapFinishChargeTime { get => Resolve(StationParamConst.SwapFinishChargeTime); set => Set(StationParamConst.SwapFinishChargeTime, value); } - + public static string SwapSoc { get => Resolve(StationParamConst.SwapSoc); @@ -55,6 +71,24 @@ public class StaticStationInfo #region 充电相关 + public static int Eid + { + get => int.Parse(Resolve(StationParamConst.Eid)); + set => Set(StationParamConst.Eid, value); + } + + public static string Oid + { + get => Resolve(StationParamConst.Oid); + set => Set(StationParamConst.Oid, value); + } + + public static int Ceid + { + get => int.Parse(Resolve(StationParamConst.Ceid)); + set => Set(StationParamConst.Ceid, value); + } + public static byte ChargeSoc { get => byte.Parse(Resolve(StationParamConst.ChargeSoc)); @@ -70,14 +104,6 @@ public class StaticStationInfo set => Set(StationParamConst.AutoChargeEnabled, value); } - /// - /// 最低满电电池数量 - /// - public static int BatteryNeedCount - { - get => int.Parse(Resolve(StationParamConst.BatteryNeedCount)); - set => Set(StationParamConst.BatteryNeedCount, value); - } #endregion @@ -100,7 +126,6 @@ public class StaticStationInfo { return 33000; } - return int.Parse(port); } set => Set(StationParamConst.CloudServerPort, value); diff --git a/Service/Station/StationParamConst.cs b/Service/Station/StationParamConst.cs index d5d7b23..c4434e6 100644 --- a/Service/Station/StationParamConst.cs +++ b/Service/Station/StationParamConst.cs @@ -2,9 +2,185 @@ public class StationParamConst { + #region 换电站基础信息 + + /// + /// 换电站编码 + /// public static readonly string StationNo = "Station.StationNo"; + + /// + /// 换电站名称 + /// public static readonly string StationName = "Station.StationName"; + /// + /// 站类型 + /// + public static readonly string StationType = "Station.StationType"; + + /// + /// 换电站识别号 + /// + public static readonly string StationSn = "Station.StationSn"; + + /// + /// 地理位置 + /// + public static readonly string StationLocation = "Station.StationLocation"; + + /// + /// 经度 + /// + public static readonly string Longitude = "Station.Longitude"; + + /// + /// 纬度 + /// + public static readonly string Latitude = "Station.Latitude"; + + /// + /// 区域编号 + /// + public static readonly string AreaCode = "Station.AreaCode"; + + /// + /// 区域名称 + /// + public static readonly string AreaName = "Station.AreaName"; + + /// + /// 营运开始时间 + /// + public static readonly string OperationStartTime = "Station.OperationStartTime"; + + /// + /// 营运结束时间 + /// + public static readonly string OperationEndTime = "Station.OperationEndTime"; + + /// + /// 服务状态 + /// + public static readonly string Sevstatus = "Station.Sevstatus"; + + /// + /// 换电站状态: 1:营运中 2:歇业中 3:设备维护状态 4:暂停营业 + /// + public static readonly string Status = "Station.Status"; + + /// + /// 投放时间 + /// + public static readonly string? LaunchTime = "Station.LaunchTime"; + + /// + /// 联系方式 + /// + public static readonly string ContactWay = "Station.ContactWay"; + + /// + /// 负责人 + /// + public static readonly string Principal = "Station.Principal"; + + /// + /// 所属运营企业 + /// + public static readonly string StationCompany = "Station.StationCompany"; + + /// + /// 所属运营企业统一社会信用代码 + /// + public static readonly string SocialCreditCode = "Station.SocialCreditCode"; + + /// + /// 站控主机软件版本号 + /// + public static readonly string StationSftVer = "Station.StationSftVer"; + + /// + /// 供应商代码 + /// + public static readonly string SupplierCode = "Station.SupplierCode"; + + /// + /// 换电站基础信息版本号 + /// + public static readonly string StationVersion = "Station.StationVersion"; + + /// + /// 换电站硬件版本 + /// + public static readonly string? HardwareVersion = "Station.HardwareVersion"; + + /// + /// 封面图片文件 + /// + public static readonly string Cover = "Station.Cover"; + + /// + /// 总体故障等级 + /// + public static readonly string? Faultlevel = "Station.Faultlevel"; + + /// + /// 加解锁方式 + /// + public static readonly string? LockType = "Station.LockType"; + + /// + /// 进入方式 + /// + public static readonly string? AccessType = "Station.AccessType"; + + /// + /// 举升方式 + /// + public static readonly string? RiseType = "Station.RiseType"; + + /// + /// 创建时间 + /// + public static readonly string CreateTime = "Station.CreateTime"; + + /// + /// 修改时间 + /// + public static readonly string? ModifyTime = "Station.ModifyTime"; + + /// + /// 配电容量(kVA) + /// + public static readonly string? DistributionCapacity = "Station.DistributionCapacity"; + + /// + /// 总功率(kW) + /// + public static readonly string? TotalPower = "Station.TotalPower"; + + /// + /// 省份 + /// + public static readonly string StationProvince = "Station.StationProvince"; + + /// + /// 城市 + /// + public static readonly string StationCity = "Station.StationCity"; + + /// + /// 组织机构ID + /// + public static readonly string? OrganizationId = "Station.OrganizationId"; + + /// + /// 站控电脑MAC地址 + /// + public static readonly string StationMac = "Station.StationMac"; + + #endregion 换电站基础信息 + //选包策略中最后结束充电时间需要>此值 public static readonly string SwapFinishChargeTime = "Station.SwapFinishChargeTime"; @@ -14,8 +190,9 @@ public class StationParamConst //充电soc public static readonly string ChargeSoc = "Station.ChargeSoc"; public static readonly string AutoChargeEnabled = "Station.AutoChargeEnabled"; - public static readonly string BatteryNeedCount = "Station.BatteryNeedCount"; - + public static readonly string Eid = "Station.Eid"; + public static readonly string Oid = "Station.Oid"; + public static readonly string Ceid = "Station.Ceid"; public static readonly string StationStatus = "Station.StationStatus"; public static readonly string StationWay = "Station.StationWay"; diff --git a/WebStarter/Controllers/ChargeController.cs b/WebStarter/Controllers/ChargeController.cs new file mode 100644 index 0000000..feffa61 --- /dev/null +++ b/WebStarter/Controllers/ChargeController.cs @@ -0,0 +1,45 @@ +using HybirdFrameworkCore.Entity; +using Microsoft.AspNetCore.Mvc; +using Service.Charger; + +namespace WebStarter.Controllers; + +/// +/// 充电机管理 +/// +[Produces("application/json")] +[ApiController] +[Route("/api[controller]")] +public class ChargeController : ControllerBase +{ + private ChargerService _chargerService; + + public ChargeController(ChargerService chargerService) + { + _chargerService = chargerService; + } + + /// + /// 通过仓号启动充电 + /// + /// 仓号 + /// + [HttpGet] + [Route("/StartChargeByBinNo/{binNo}")] + public Result StartChargeByBinNo(string binNo) + { + return _chargerService.StartChargeByBinNo(binNo); + } + + /// + /// 通过仓号停止充电 + /// + /// 仓号 + /// + [HttpGet] + [Route("/StopChargeByBinNo/{binNo}")] + public Result StopChargeByBinNo(string binNo) + { + return _chargerService.StartChargeByBinNo(binNo); + } +} \ No newline at end of file diff --git a/WinFormStarter/Form2.cs b/WinFormStarter/Form2.cs index 6a15c0c..2443763 100644 --- a/WinFormStarter/Form2.cs +++ b/WinFormStarter/Form2.cs @@ -105,7 +105,7 @@ public partial class Form2 : Form private void DisplayData() { this.SetText(this.rTxtData, JsonConvert.SerializeObject(_chargerClient, Formatting.Indented)); - this.lblBatterNo.Text = _chargerClient?.BatterNo; + this.lblBatterNo.Text = _chargerClient?.BatteryNo; } private void btnConn_Click(object sender, EventArgs e)