Compare commits
2
Commits
d77feb67f7
...
9e78aa7769
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e78aa7769 | ||
|
|
6bd8ef4a7c |
+2
-1
@@ -364,4 +364,5 @@ MigrationBackup/
|
|||||||
.ionide/
|
.ionide/
|
||||||
|
|
||||||
# Fody - auto-generated XML schema
|
# Fody - auto-generated XML schema
|
||||||
FodyWeavers.xsd
|
FodyWeavers.xsd
|
||||||
|
/IOT_API/appsettings.json
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Model;
|
using Model;
|
||||||
using Model.Entity.Asset;
|
using Model.Entity.Asset;
|
||||||
using ORM;
|
|
||||||
using Service.Implement;
|
|
||||||
using Service.Interface;
|
using Service.Interface;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -20,12 +18,9 @@ namespace IOT_API.Controllers.Asset
|
|||||||
{
|
{
|
||||||
private readonly IEquipmentService _equipmentService;
|
private readonly IEquipmentService _equipmentService;
|
||||||
|
|
||||||
public EquipmentController()
|
public EquipmentController(IEquipmentService equipmentService)
|
||||||
{
|
{
|
||||||
// 项目未注册 DI 容器,SqlSugarContext.DbContext 为静态单例,直接实例化服务
|
_equipmentService = equipmentService;
|
||||||
_equipmentService = new EquipmentService(
|
|
||||||
new SqlSugarRepository<EquipmentEntity>(),
|
|
||||||
new SqlSugarRepository<EquipmentStatusRecordEntity>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
using ORM;
|
||||||
using Service.Implement;
|
using Service.Implement;
|
||||||
|
using SqlSugar;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace WebAPI
|
namespace WebAPI
|
||||||
@@ -15,6 +17,12 @@ namespace WebAPI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static IServiceCollection AddBusinessServices(this IServiceCollection services)
|
public static IServiceCollection AddBusinessServices(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
// SqlSugar 客户端:静态单例(SqlSugarScope 线程安全),供仓储及其他需要注入 ISqlSugarClient 的地方使用
|
||||||
|
services.AddSingleton<ISqlSugarClient>(SqlSugarContext.DbContext);
|
||||||
|
|
||||||
|
// 泛型仓储:所有 SqlSugarRepository<TEntity> 统一注册(内部使用 SqlSugarContext.DbContext 静态单例)
|
||||||
|
services.AddScoped(typeof(SqlSugarRepository<>));
|
||||||
|
|
||||||
// Service 项目程序集(接口与实现都在同一个程序集里)
|
// Service 项目程序集(接口与实现都在同一个程序集里)
|
||||||
Assembly assembly = typeof(BaseService<>).Assembly;
|
Assembly assembly = typeof(BaseService<>).Assembly;
|
||||||
|
|
||||||
|
|||||||
@@ -48,27 +48,6 @@ namespace WebAPI
|
|||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen();
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
// ======= Database init start =======
|
|
||||||
// Npgsql 时间兼容开关:允许向 PostgreSQL 写入本地时间 DateTime(DateTime.Now)
|
|
||||||
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
|
||||||
|
|
||||||
// 从 appsettings.json 读取数据库配置(PostgreSQL)
|
|
||||||
var dbConfig = builder.Configuration.GetSection("Database");
|
|
||||||
DatabaseConfig.InitPostgreSql(
|
|
||||||
dbConfig["Server"] ?? "localhost",
|
|
||||||
int.TryParse(dbConfig["Port"], out var port) ? port : 5432,
|
|
||||||
dbConfig["Database"] ?? "iot",
|
|
||||||
dbConfig["Uid"] ?? "postgres",
|
|
||||||
dbConfig["Pwd"] ?? "");
|
|
||||||
|
|
||||||
// 数据库不存在则创建,并检查连接(租户雪花机器码可按需设置)
|
|
||||||
DatabaseConfig.SetTenant(10001);
|
|
||||||
DatabaseConfig.CreateDatabaseAndCheckConnection(createDatabase: true, checkConnection: true);
|
|
||||||
|
|
||||||
// CodeFirst 自动建表:扫描 Model.dll 中所有以 Entity 结尾的类建表/补列
|
|
||||||
SqlSugarContext.InitDatabase();
|
|
||||||
// ======= Database init end =======
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowedHosts": "*",
|
|
||||||
"Database": {
|
|
||||||
"Type": "PostgreSQL",
|
|
||||||
"Server": "127.0.0.1",
|
|
||||||
"Port": 5432,
|
|
||||||
"Database": "IOT_WEB",
|
|
||||||
"User": "postgres",
|
|
||||||
"Password": "kylt123",
|
|
||||||
"TenantId": 10001
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,266 @@
|
|||||||
|
using Model;
|
||||||
|
using Model.Entity.Asset;
|
||||||
|
using ORM;
|
||||||
using Service.Interface;
|
using Service.Interface;
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Service.Implement
|
namespace Service.Implement
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备台账 服务实现
|
/// 设备台账服务实现(资产管理)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EquipmentService : IEquipmentService
|
public class EquipmentService : BaseService<EquipmentEntity>, IEquipmentService
|
||||||
{
|
{
|
||||||
// TODO: 实现 设备台账 相关方法
|
private readonly SqlSugarRepository<EquipmentStatusRecordEntity> _statusRecordRepository;
|
||||||
|
|
||||||
|
public EquipmentService(SqlSugarRepository<EquipmentEntity> repository,
|
||||||
|
SqlSugarRepository<EquipmentStatusRecordEntity> statusRecordRepository)
|
||||||
|
: base(repository)
|
||||||
|
{
|
||||||
|
_statusRecordRepository = statusRecordRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询全部设备(过滤已删除数据)
|
||||||
|
/// </summary>
|
||||||
|
public override async Task<Result<List<EquipmentEntity>>> GetAllAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var list = await _repository.Entities
|
||||||
|
.Where(x => x.IsDel == 0)
|
||||||
|
.OrderBy(x => x.CreateTime, OrderByType.Desc)
|
||||||
|
.ToListAsync();
|
||||||
|
return Result<List<EquipmentEntity>>.Success(list);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result<List<EquipmentEntity>>.Error("查询设备台账失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分页查询设备台账(支持关键字、分类、状态筛选)
|
||||||
|
/// </summary>
|
||||||
|
public async Task<Result<List<EquipmentEntity>>> GetPagedAsync(int pageIndex, int pageSize, RefAsync<int> total,
|
||||||
|
string? keyword, long categoryId = 0, EquipmentStatusEnum? status = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var list = await _repository.Entities
|
||||||
|
.Where(x => x.IsDel == 0)
|
||||||
|
.WhereIF(!string.IsNullOrWhiteSpace(keyword),
|
||||||
|
x => x.Code!.Contains(keyword!) || x.Name!.Contains(keyword!))
|
||||||
|
.WhereIF(categoryId > 0, x => x.CategoryId == categoryId)
|
||||||
|
.WhereIF(status.HasValue, x => x.Status == status!.Value)
|
||||||
|
.OrderBy(x => x.CreateTime, OrderByType.Desc)
|
||||||
|
.ToPageListAsync(pageIndex, pageSize, total);
|
||||||
|
total.Value = (int)Math.Ceiling((double)total.Value / pageSize);
|
||||||
|
return Result<List<EquipmentEntity>>.Success(list);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result<List<EquipmentEntity>>.Error("分页查询设备台账失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据 Id 获取设备台账详情
|
||||||
|
/// </summary>
|
||||||
|
public async Task<Result<EquipmentEntity>> GetByIdAsync(long id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var entity = await _repository.Entities
|
||||||
|
.Where(x => x.Id == id && x.IsDel == 0)
|
||||||
|
.FirstAsync();
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
return Result<EquipmentEntity>.Error("设备不存在或已被删除");
|
||||||
|
}
|
||||||
|
return Result<EquipmentEntity>.Success(entity);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result<EquipmentEntity>.Error("查询设备详情失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增设备台账(校验编号唯一性,补充创建时间)
|
||||||
|
/// </summary>
|
||||||
|
public override async Task<Result<bool>> InsertAsync(EquipmentEntity entity)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(entity.Code))
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("设备编号不能为空");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 设备编号唯一性校验(未删除范围内)
|
||||||
|
bool exists = await _repository.Entities
|
||||||
|
.AnyAsync(x => x.Code == entity.Code && x.IsDel == 0);
|
||||||
|
if (exists)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error($"设备编号【{entity.Code}】已存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.CreateTime = DateTime.Now;
|
||||||
|
var result = await _repository.Context.Insertable(entity).ExecuteCommandAsync();
|
||||||
|
return Result<bool>.Success(result > 0);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("新增设备失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新设备台账
|
||||||
|
/// </summary>
|
||||||
|
public async Task<Result<bool>> UpdateAsync(EquipmentEntity entity)
|
||||||
|
{
|
||||||
|
if (entity.Id <= 0)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("设备 Id 无效");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var old = await _repository.Entities
|
||||||
|
.Where(x => x.Id == entity.Id && x.IsDel == 0)
|
||||||
|
.FirstAsync();
|
||||||
|
if (old == null)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("设备不存在或已被删除");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备编号变更时校验唯一性
|
||||||
|
if (!string.IsNullOrWhiteSpace(entity.Code) && entity.Code != old.Code)
|
||||||
|
{
|
||||||
|
bool exists = await _repository.Entities
|
||||||
|
.AnyAsync(x => x.Code == entity.Code && x.IsDel == 0 && x.Id != entity.Id);
|
||||||
|
if (exists)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error($"设备编号【{entity.Code}】已存在");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.IsDel = old.IsDel;
|
||||||
|
entity.CreateTime = old.CreateTime;
|
||||||
|
entity.UpdateTime = DateTime.Now;
|
||||||
|
var result = await _repository.Context.Updateable(entity).ExecuteCommandAsync();
|
||||||
|
return Result<bool>.Success(result > 0);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("更新设备失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 软删除设备台账(置 IsDel = 1)
|
||||||
|
/// </summary>
|
||||||
|
public async Task<Result<bool>> DeleteEquipmentAsync(long id)
|
||||||
|
{
|
||||||
|
if (id <= 0)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("设备 Id 无效");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await _repository.Context.Updateable<EquipmentEntity>()
|
||||||
|
.SetColumns(x => x.IsDel == 1)
|
||||||
|
.Where(x => x.Id == id)
|
||||||
|
.ExecuteCommandAsync();
|
||||||
|
return Result<bool>.Success(result > 0);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("删除设备失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 变更设备状态,并记录状态变更历史(事务保证一致性)
|
||||||
|
/// </summary>
|
||||||
|
public async Task<Result<bool>> ChangeStatusAsync(long equipmentId, EquipmentStatusEnum toStatus, string? operatorName, string? remark)
|
||||||
|
{
|
||||||
|
if (equipmentId <= 0)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("设备 Id 无效");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var equipment = await _repository.Entities
|
||||||
|
.Where(x => x.Id == equipmentId && x.IsDel == 0)
|
||||||
|
.FirstAsync();
|
||||||
|
if (equipment == null)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("设备不存在或已被删除");
|
||||||
|
}
|
||||||
|
if (equipment.Status == toStatus)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("目标状态与当前状态一致,无需变更");
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = DateTime.Now;
|
||||||
|
var record = new EquipmentStatusRecordEntity
|
||||||
|
{
|
||||||
|
EquipmentId = equipmentId,
|
||||||
|
FromStatus = equipment.Status,
|
||||||
|
ToStatus = toStatus,
|
||||||
|
ChangeTime = now,
|
||||||
|
Operator = operatorName,
|
||||||
|
Remark = remark,
|
||||||
|
CreateTime = now
|
||||||
|
};
|
||||||
|
|
||||||
|
// 事务:更新设备状态 + 插入状态变更记录
|
||||||
|
_repository.BeginTran();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
equipment.Status = toStatus;
|
||||||
|
equipment.UpdateTime = now;
|
||||||
|
await _repository.Context.Updateable(equipment)
|
||||||
|
.UpdateColumns(x => new { x.Status, x.UpdateTime })
|
||||||
|
.ExecuteCommandAsync();
|
||||||
|
await _statusRecordRepository.Context.Insertable(record).ExecuteCommandAsync();
|
||||||
|
_repository.CommitTran();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
_repository.RollbackTran();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result<bool>.Success(true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result<bool>.Error("变更设备状态失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询指定设备的状态变更历史记录(按变更时间倒序)
|
||||||
|
/// </summary>
|
||||||
|
public async Task<Result<List<EquipmentStatusRecordEntity>>> GetStatusRecordsAsync(long equipmentId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var list = await _statusRecordRepository.Entities
|
||||||
|
.Where(x => x.EquipmentId == equipmentId && x.IsDel == 0)
|
||||||
|
.OrderBy(x => x.ChangeTime, OrderByType.Desc)
|
||||||
|
.ToListAsync();
|
||||||
|
return Result<List<EquipmentStatusRecordEntity>>.Success(list);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result<List<EquipmentStatusRecordEntity>>.Error("查询状态变更记录失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,266 +0,0 @@
|
|||||||
using Model;
|
|
||||||
using Model.Entity.Asset;
|
|
||||||
using ORM;
|
|
||||||
using Service.Interface;
|
|
||||||
using SqlSugar;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Service.Implement
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 设备台账服务实现(资产管理)
|
|
||||||
/// </summary>
|
|
||||||
public class EquipmentService : BaseService<EquipmentEntity>, IEquipmentService
|
|
||||||
{
|
|
||||||
private readonly SqlSugarRepository<EquipmentStatusRecordEntity> _statusRecordRepository;
|
|
||||||
|
|
||||||
public EquipmentService(SqlSugarRepository<EquipmentEntity> repository,
|
|
||||||
SqlSugarRepository<EquipmentStatusRecordEntity> statusRecordRepository)
|
|
||||||
: base(repository)
|
|
||||||
{
|
|
||||||
_statusRecordRepository = statusRecordRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查询全部设备(过滤已删除数据)
|
|
||||||
/// </summary>
|
|
||||||
public override async Task<Result<List<EquipmentEntity>>> GetAllAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var list = await _repository.Entities
|
|
||||||
.Where(x => x.IsDel == 0)
|
|
||||||
.OrderBy(x => x.CreateTime, OrderByType.Desc)
|
|
||||||
.ToListAsync();
|
|
||||||
return Result<List<EquipmentEntity>>.Success(list);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return Result<List<EquipmentEntity>>.Error("查询设备台账失败", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 分页查询设备台账(支持关键字、分类、状态筛选)
|
|
||||||
/// </summary>
|
|
||||||
public async Task<Result<List<EquipmentEntity>>> GetPagedAsync(int pageIndex, int pageSize, RefAsync<int> total,
|
|
||||||
string? keyword, long categoryId = 0, EquipmentStatusEnum? status = null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var list = await _repository.Entities
|
|
||||||
.Where(x => x.IsDel == 0)
|
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(keyword),
|
|
||||||
x => x.Code!.Contains(keyword!) || x.Name!.Contains(keyword!))
|
|
||||||
.WhereIF(categoryId > 0, x => x.CategoryId == categoryId)
|
|
||||||
.WhereIF(status.HasValue, x => x.Status == status!.Value)
|
|
||||||
.OrderBy(x => x.CreateTime, OrderByType.Desc)
|
|
||||||
.ToPageListAsync(pageIndex, pageSize, total);
|
|
||||||
total.Value = (int)Math.Ceiling((double)total.Value / pageSize);
|
|
||||||
return Result<List<EquipmentEntity>>.Success(list);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return Result<List<EquipmentEntity>>.Error("分页查询设备台账失败", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据 Id 获取设备台账详情
|
|
||||||
/// </summary>
|
|
||||||
public async Task<Result<EquipmentEntity>> GetByIdAsync(long id)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var entity = await _repository.Entities
|
|
||||||
.Where(x => x.Id == id && x.IsDel == 0)
|
|
||||||
.FirstAsync();
|
|
||||||
if (entity == null)
|
|
||||||
{
|
|
||||||
return Result<EquipmentEntity>.Error("设备不存在或已被删除");
|
|
||||||
}
|
|
||||||
return Result<EquipmentEntity>.Success(entity);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return Result<EquipmentEntity>.Error("查询设备详情失败", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 新增设备台账(校验编号唯一性,补充创建时间)
|
|
||||||
/// </summary>
|
|
||||||
public override async Task<Result<bool>> InsertAsync(EquipmentEntity entity)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(entity.Code))
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("设备编号不能为空");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 设备编号唯一性校验(未删除范围内)
|
|
||||||
bool exists = await _repository.Entities
|
|
||||||
.AnyAsync(x => x.Code == entity.Code && x.IsDel == 0);
|
|
||||||
if (exists)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error($"设备编号【{entity.Code}】已存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.CreateTime = DateTime.Now;
|
|
||||||
var result = await _repository.Context.Insertable(entity).ExecuteCommandAsync();
|
|
||||||
return Result<bool>.Success(result > 0);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("新增设备失败", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新设备台账
|
|
||||||
/// </summary>
|
|
||||||
public async Task<Result<bool>> UpdateAsync(EquipmentEntity entity)
|
|
||||||
{
|
|
||||||
if (entity.Id <= 0)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("设备 Id 无效");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var old = await _repository.Entities
|
|
||||||
.Where(x => x.Id == entity.Id && x.IsDel == 0)
|
|
||||||
.FirstAsync();
|
|
||||||
if (old == null)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("设备不存在或已被删除");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设备编号变更时校验唯一性
|
|
||||||
if (!string.IsNullOrWhiteSpace(entity.Code) && entity.Code != old.Code)
|
|
||||||
{
|
|
||||||
bool exists = await _repository.Entities
|
|
||||||
.AnyAsync(x => x.Code == entity.Code && x.IsDel == 0 && x.Id != entity.Id);
|
|
||||||
if (exists)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error($"设备编号【{entity.Code}】已存在");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.IsDel = old.IsDel;
|
|
||||||
entity.CreateTime = old.CreateTime;
|
|
||||||
entity.UpdateTime = DateTime.Now;
|
|
||||||
var result = await _repository.Context.Updateable(entity).ExecuteCommandAsync();
|
|
||||||
return Result<bool>.Success(result > 0);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("更新设备失败", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 软删除设备台账(置 IsDel = 1)
|
|
||||||
/// </summary>
|
|
||||||
public async Task<Result<bool>> DeleteEquipmentAsync(long id)
|
|
||||||
{
|
|
||||||
if (id <= 0)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("设备 Id 无效");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var result = await _repository.Context.Updateable<EquipmentEntity>()
|
|
||||||
.SetColumns(x => x.IsDel == 1)
|
|
||||||
.Where(x => x.Id == id)
|
|
||||||
.ExecuteCommandAsync();
|
|
||||||
return Result<bool>.Success(result > 0);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("删除设备失败", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 变更设备状态,并记录状态变更历史(事务保证一致性)
|
|
||||||
/// </summary>
|
|
||||||
public async Task<Result<bool>> ChangeStatusAsync(long equipmentId, EquipmentStatusEnum toStatus, string? operatorName, string? remark)
|
|
||||||
{
|
|
||||||
if (equipmentId <= 0)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("设备 Id 无效");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var equipment = await _repository.Entities
|
|
||||||
.Where(x => x.Id == equipmentId && x.IsDel == 0)
|
|
||||||
.FirstAsync();
|
|
||||||
if (equipment == null)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("设备不存在或已被删除");
|
|
||||||
}
|
|
||||||
if (equipment.Status == toStatus)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("目标状态与当前状态一致,无需变更");
|
|
||||||
}
|
|
||||||
|
|
||||||
var now = DateTime.Now;
|
|
||||||
var record = new EquipmentStatusRecordEntity
|
|
||||||
{
|
|
||||||
EquipmentId = equipmentId,
|
|
||||||
FromStatus = equipment.Status,
|
|
||||||
ToStatus = toStatus,
|
|
||||||
ChangeTime = now,
|
|
||||||
Operator = operatorName,
|
|
||||||
Remark = remark,
|
|
||||||
CreateTime = now
|
|
||||||
};
|
|
||||||
|
|
||||||
// 事务:更新设备状态 + 插入状态变更记录
|
|
||||||
_repository.BeginTran();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
equipment.Status = toStatus;
|
|
||||||
equipment.UpdateTime = now;
|
|
||||||
await _repository.Context.Updateable(equipment)
|
|
||||||
.UpdateColumns(x => new { x.Status, x.UpdateTime })
|
|
||||||
.ExecuteCommandAsync();
|
|
||||||
await _statusRecordRepository.Context.Insertable(record).ExecuteCommandAsync();
|
|
||||||
_repository.CommitTran();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
_repository.RollbackTran();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result<bool>.Success(true);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return Result<bool>.Error("变更设备状态失败", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查询指定设备的状态变更历史记录(按变更时间倒序)
|
|
||||||
/// </summary>
|
|
||||||
public async Task<Result<List<EquipmentStatusRecordEntity>>> GetStatusRecordsAsync(long equipmentId)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var list = await _statusRecordRepository.Entities
|
|
||||||
.Where(x => x.EquipmentId == equipmentId && x.IsDel == 0)
|
|
||||||
.OrderBy(x => x.ChangeTime, OrderByType.Desc)
|
|
||||||
.ToListAsync();
|
|
||||||
return Result<List<EquipmentStatusRecordEntity>>.Success(list);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return Result<List<EquipmentStatusRecordEntity>>.Error("查询状态变更记录失败", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,65 @@
|
|||||||
|
using Model;
|
||||||
|
using Model.Entity.Asset;
|
||||||
|
using SqlSugar;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Service.Interface
|
namespace Service.Interface
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备台账 服务接口
|
/// 设备台账服务接口(资产管理)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IEquipmentService
|
public interface IEquipmentService : IBaseService<EquipmentEntity>
|
||||||
{
|
{
|
||||||
// TODO: 定义 设备台账 相关方法
|
/// <summary>
|
||||||
|
/// 分页查询设备台账(支持按关键字、分类、状态筛选)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pageIndex">页码(从1开始)</param>
|
||||||
|
/// <param name="pageSize">每页数量</param>
|
||||||
|
/// <param name="total">总页数(输出参数)</param>
|
||||||
|
/// <param name="keyword">关键字(模糊匹配设备编号/名称)</param>
|
||||||
|
/// <param name="categoryId">设备分类Id(0表示不过滤)</param>
|
||||||
|
/// <param name="status">设备状态(null表示不过滤)</param>
|
||||||
|
/// <returns>返回包含分页数据的 Result</returns>
|
||||||
|
Task<Result<List<EquipmentEntity>>> GetPagedAsync(int pageIndex, int pageSize, RefAsync<int> total,
|
||||||
|
string? keyword, long categoryId = 0, EquipmentStatusEnum? status = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据 Id 获取设备台账详情
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">主键 Id</param>
|
||||||
|
/// <returns>返回包含设备详情的 Result</returns>
|
||||||
|
Task<Result<EquipmentEntity>> GetByIdAsync(long id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新设备台账
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">设备实体(必须包含 Id)</param>
|
||||||
|
/// <returns>返回操作是否成功的 Result</returns>
|
||||||
|
Task<Result<bool>> UpdateAsync(EquipmentEntity entity);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 软删除设备台账(置 IsDel = 1)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">主键 Id</param>
|
||||||
|
/// <returns>返回操作是否成功的 Result</returns>
|
||||||
|
Task<Result<bool>> DeleteEquipmentAsync(long id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 变更设备状态,并记录状态变更历史(事务保证一致性)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="equipmentId">设备 Id</param>
|
||||||
|
/// <param name="toStatus">目标状态</param>
|
||||||
|
/// <param name="operatorName">操作人</param>
|
||||||
|
/// <param name="remark">变更原因/备注</param>
|
||||||
|
/// <returns>返回操作是否成功的 Result</returns>
|
||||||
|
Task<Result<bool>> ChangeStatusAsync(long equipmentId, EquipmentStatusEnum toStatus, string? operatorName, string? remark);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询指定设备的状态变更历史记录(按变更时间倒序)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="equipmentId">设备 Id</param>
|
||||||
|
/// <returns>返回包含状态记录列表的 Result</returns>
|
||||||
|
Task<Result<List<EquipmentStatusRecordEntity>>> GetStatusRecordsAsync(long equipmentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
using Model;
|
|
||||||
using Model.Entity.Asset;
|
|
||||||
using SqlSugar;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Service.Interface
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 设备台账服务接口(资产管理)
|
|
||||||
/// </summary>
|
|
||||||
public interface IEquipmentService : IBaseService<EquipmentEntity>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 分页查询设备台账(支持按关键字、分类、状态筛选)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pageIndex">页码(从1开始)</param>
|
|
||||||
/// <param name="pageSize">每页数量</param>
|
|
||||||
/// <param name="total">总页数(输出参数)</param>
|
|
||||||
/// <param name="keyword">关键字(模糊匹配设备编号/名称)</param>
|
|
||||||
/// <param name="categoryId">设备分类Id(0表示不过滤)</param>
|
|
||||||
/// <param name="status">设备状态(null表示不过滤)</param>
|
|
||||||
/// <returns>返回包含分页数据的 Result</returns>
|
|
||||||
Task<Result<List<EquipmentEntity>>> GetPagedAsync(int pageIndex, int pageSize, RefAsync<int> total,
|
|
||||||
string? keyword, long categoryId = 0, EquipmentStatusEnum? status = null);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据 Id 获取设备台账详情
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">主键 Id</param>
|
|
||||||
/// <returns>返回包含设备详情的 Result</returns>
|
|
||||||
Task<Result<EquipmentEntity>> GetByIdAsync(long id);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新设备台账
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">设备实体(必须包含 Id)</param>
|
|
||||||
/// <returns>返回操作是否成功的 Result</returns>
|
|
||||||
Task<Result<bool>> UpdateAsync(EquipmentEntity entity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 软删除设备台账(置 IsDel = 1)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">主键 Id</param>
|
|
||||||
/// <returns>返回操作是否成功的 Result</returns>
|
|
||||||
Task<Result<bool>> DeleteEquipmentAsync(long id);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 变更设备状态,并记录状态变更历史(事务保证一致性)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="equipmentId">设备 Id</param>
|
|
||||||
/// <param name="toStatus">目标状态</param>
|
|
||||||
/// <param name="operatorName">操作人</param>
|
|
||||||
/// <param name="remark">变更原因/备注</param>
|
|
||||||
/// <returns>返回操作是否成功的 Result</returns>
|
|
||||||
Task<Result<bool>> ChangeStatusAsync(long equipmentId, EquipmentStatusEnum toStatus, string? operatorName, string? remark);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查询指定设备的状态变更历史记录(按变更时间倒序)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="equipmentId">设备 Id</param>
|
|
||||||
/// <returns>返回包含状态记录列表的 Result</returns>
|
|
||||||
Task<Result<List<EquipmentStatusRecordEntity>>> GetStatusRecordsAsync(long equipmentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user