设备管理联调:修复brandId缺失、batchToggle改逐个toggle、详情页添加4个子API端点

- 前端:新增/编辑机床时传递brandId字段
- 前端:启停切换改为逐个调用PUT /admin/machine/{id}/toggle
- 前端:详情页API调用从query参数改为RESTful路径参数
- 后端:新增4个详情页API(status/production-today/production-trend/collect-records)
- 后端:新增3个DTO(MachineTodayProdItem/MachineTrendItem/MachineCollectRecordItem)
- 后端:更新MachineStatusResponse字段以匹配前端展示需求
main
haoliang 1 week ago
parent 2e3199490c
commit dfc18fabb5

@ -39,6 +39,8 @@ export interface Machine {
isEnabled: boolean isEnabled: boolean
workerName?: string workerName?: string
collectAddressName?: string collectAddressName?: string
/** 编辑表单用品牌ID */
brandId?: number
/** 编辑表单用所属车间ID */ /** 编辑表单用所属车间ID */
workshopId?: number workshopId?: number
/** 编辑表单用采集地址ID */ /** 编辑表单用采集地址ID */
@ -91,6 +93,7 @@ export interface CollectAddress {
id: number id: number
name: string name: string
url: string url: string
brandId: number
brandName: string brandName: string
interval: number interval: number
/** 详情页显示用:采集间隔(秒) */ /** 详情页显示用:采集间隔(秒) */

@ -85,16 +85,16 @@ let chart: ECharts | null = null
async function loadData() { async function loadData() {
const id = route.params.id const id = route.params.id
const [d, s, t, r] = await Promise.all([ const [d, s, t, r] = await Promise.all([
request.get<Machine>('/admin/machine/detail', { params: { id } }), request.get<Machine>(`/admin/machine/${id}`),
request.get<MachineStatus>('/admin/machine/status', { params: { id } }), request.get<MachineStatus>(`/admin/machine/${id}/status`),
request.get<{ items: TodayProdRow[] }>('/admin/machine/production/today', { params: { id } }), request.get<{ items: TodayProdRow[] }>(`/admin/machine/${id}/production/today`),
request.get<{ items: CollectRecordRow[] }>('/admin/machine/collect-records', { params: { id } }), request.get<{ items: CollectRecordRow[] }>(`/admin/machine/${id}/collect-records`),
]) ])
detail.value = d.data || {} as Machine detail.value = d.data || {} as Machine
status.value = s.data || {} as MachineStatus status.value = s.data || {} as MachineStatus
todayProd.value = t.data?.items || [] todayProd.value = t.data?.items || []
records.value = r.data?.items || [] records.value = r.data?.items || []
const trend = await request.get<{ items: TrendItem[] }>('/admin/machine/production/trend', { params: { id } }) const trend = await request.get<{ items: TrendItem[] }>(`/admin/machine/${id}/production/trend`)
await nextTick() await nextTick()
if (chartRef.value) { if (chartRef.value) {
chart = echarts.init(chartRef.value) chart = echarts.init(chartRef.value)
@ -105,7 +105,7 @@ async function loadData() {
async function fetchStatus() { async function fetchStatus() {
const id = route.params.id const id = route.params.id
const r = await request.get<MachineStatus>('/admin/machine/status', { params: { id } }) const r = await request.get<MachineStatus>(`/admin/machine/${id}/status`)
status.value = r.data || {} as MachineStatus status.value = r.data || {} as MachineStatus
} }

@ -168,7 +168,7 @@ const editingId = ref<number | null>(null)
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const form = reactive({ const form = reactive({
name: '', deviceCode: '', workshopId: undefined as number | undefined, name: '', deviceCode: '', workshopId: undefined as number | undefined,
collectAddressId: undefined as number | undefined, brandName: '', collectAddressId: undefined as number | undefined, brandId: undefined as number | undefined, brandName: '',
ipAddress: '', workerId: undefined as number | undefined, ipAddress: '', workerId: undefined as number | undefined,
}) })
@ -215,7 +215,7 @@ function resetQuery() {
function handleAdd() { function handleAdd() {
editingId.value = null editingId.value = null
Object.assign(form, { name: '', deviceCode: '', workshopId: undefined, collectAddressId: undefined, brandName: '', ipAddress: '', workerId: undefined }) Object.assign(form, { name: '', deviceCode: '', workshopId: undefined, collectAddressId: undefined, brandId: undefined, brandName: '', ipAddress: '', workerId: undefined })
dialogVisible.value = true dialogVisible.value = true
} }
@ -223,7 +223,7 @@ function handleEdit(row: Machine) {
editingId.value = row.id editingId.value = row.id
Object.assign(form, { Object.assign(form, {
name: row.name, deviceCode: row.deviceCode, workshopId: row.workshopId, name: row.name, deviceCode: row.deviceCode, workshopId: row.workshopId,
collectAddressId: row.collectAddressId, brandName: row.brandName, collectAddressId: row.collectAddressId, brandId: row.brandId, brandName: row.brandName,
ipAddress: row.ipAddress, workerId: row.workerId, ipAddress: row.ipAddress, workerId: row.workerId,
}) })
dialogVisible.value = true dialogVisible.value = true
@ -231,6 +231,7 @@ function handleEdit(row: Machine) {
function onAddressChange(addressId: number) { function onAddressChange(addressId: number) {
const addr = addressList.value.find((a: CollectAddress) => a.id === addressId) const addr = addressList.value.find((a: CollectAddress) => a.id === addressId)
form.brandId = addr ? addr.brandId : undefined
form.brandName = addr ? addr.brandName : '' form.brandName = addr ? addr.brandName : ''
} }
@ -255,7 +256,12 @@ async function handleDelete(row: Machine) {
async function batchToggle(isEnabled: number) { async function batchToggle(isEnabled: number) {
await ElMessageBox.confirm(`确定对选中的${selectedRows.value.length}项操作?`, '提示', { type: 'warning' }) await ElMessageBox.confirm(`确定对选中的${selectedRows.value.length}项操作?`, '提示', { type: 'warning' })
await request.post('/admin/machine/batch-toggle', { ids: selectedRows.value.map((r: {id:number}) => r.id), isEnabled }) // toggletoggle
for (const row of selectedRows.value) {
if ((isEnabled === 1 && !row.isEnabled) || (isEnabled === 0 && row.isEnabled)) {
await request.put(`/admin/machine/${row.id}/toggle`)
}
}
ElMessage.success('操作成功') ElMessage.success('操作成功')
loadData() loadData()
} }

@ -0,0 +1,20 @@
namespace CncModels.Dto.Machine
{
/// <summary>
/// 机床采集记录项
/// </summary>
public class MachineCollectRecordItem
{
/// <summary>采集时间</summary>
public string CollectTime { get; set; }
/// <summary>NC程序名</summary>
public string ProgramName { get; set; }
/// <summary>零件计数</summary>
public decimal? PartCount { get; set; }
/// <summary>运行状态</summary>
public string RunStatus { get; set; }
}
}

@ -5,9 +5,28 @@ namespace CncModels.Dto.Machine
/// </summary> /// </summary>
public class MachineStatusResponse public class MachineStatusResponse
{ {
public int Status { get; set; } /// <summary>NC程序名</summary>
public System.DateTime? LastUpdate { get; set; } public string ProgramName { get; set; }
public string LastProgramName { get; set; }
public string Message { get; set; } /// <summary>零件计数</summary>
public decimal? PartCount { get; set; }
/// <summary>运行状态</summary>
public string RunStatus { get; set; }
/// <summary>操作模式</summary>
public string OperationMode { get; set; }
/// <summary>主轴设定转速</summary>
public decimal? SpindleSpeedSet { get; set; }
/// <summary>进给设定速度</summary>
public decimal? FeedSpeedSet { get; set; }
/// <summary>主轴实际转速</summary>
public decimal? SpindleSpeedActual { get; set; }
/// <summary>主轴负载(%</summary>
public decimal? SpindleLoad { get; set; }
} }
} }

@ -0,0 +1,20 @@
namespace CncModels.Dto.Machine
{
/// <summary>
/// 机床今日产量明细项
/// </summary>
public class MachineTodayProdItem
{
/// <summary>NC程序名</summary>
public string ProgramName { get; set; }
/// <summary>产量</summary>
public int Quantity { get; set; }
/// <summary>运行时间(分钟)</summary>
public decimal? RunTime { get; set; }
/// <summary>切削时间(分钟)</summary>
public decimal? CuttingTime { get; set; }
}
}

@ -0,0 +1,14 @@
namespace CncModels.Dto.Machine
{
/// <summary>
/// 机床产量趋势数据项
/// </summary>
public class MachineTrendItem
{
/// <summary>日期yyyy-MM-dd</summary>
public string Date { get; set; }
/// <summary>当日产量</summary>
public int Quantity { get; set; }
}
}

@ -127,5 +127,45 @@ namespace CncService.Impl
if (id <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的机床ID"); if (id <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的机床ID");
return _machineRepository.ToggleEnabled(id); return _machineRepository.ToggleEnabled(id);
} }
/// <inheritdoc/>
public MachineStatusResponse GetStatus(int id)
{
if (id <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的机床ID");
var machine = _machineRepository.GetById(id);
if (machine == null) throw new BusinessException(ErrorCode.NotFound, "机床未找到");
// 采集服务尚未运行,返回空状态
return new MachineStatusResponse();
}
/// <inheritdoc/>
public List<MachineTodayProdItem> GetTodayProduction(int id)
{
if (id <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的机床ID");
var machine = _machineRepository.GetById(id);
if (machine == null) throw new BusinessException(ErrorCode.NotFound, "机床未找到");
// 采集服务尚未运行,暂无产量数据
return new List<MachineTodayProdItem>();
}
/// <inheritdoc/>
public List<MachineTrendItem> GetProductionTrend(int id)
{
if (id <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的机床ID");
var machine = _machineRepository.GetById(id);
if (machine == null) throw new BusinessException(ErrorCode.NotFound, "机床未找到");
// 采集服务尚未运行,暂无趋势数据
return new List<MachineTrendItem>();
}
/// <inheritdoc/>
public List<MachineCollectRecordItem> GetCollectRecords(int id)
{
if (id <= 0) throw new BusinessException(ErrorCode.BadRequest, "无效的机床ID");
var machine = _machineRepository.GetById(id);
if (machine == null) throw new BusinessException(ErrorCode.NotFound, "机床未找到");
// 采集服务尚未运行,暂无采集记录
return new List<MachineCollectRecordItem>();
}
} }
} }

@ -52,5 +52,33 @@ namespace CncService.Interface
/// <param name="id">机床ID</param> /// <param name="id">机床ID</param>
/// <returns>是否切换成功</returns> /// <returns>是否切换成功</returns>
bool ToggleEnabled(int id); bool ToggleEnabled(int id);
/// <summary>
/// 获取机床实时采集状态
/// </summary>
/// <param name="id">机床ID</param>
/// <returns>实时状态信息</returns>
MachineStatusResponse GetStatus(int id);
/// <summary>
/// 获取机床今日产量明细
/// </summary>
/// <param name="id">机床ID</param>
/// <returns>今日产量列表</returns>
List<MachineTodayProdItem> GetTodayProduction(int id);
/// <summary>
/// 获取机床7天产量趋势
/// </summary>
/// <param name="id">机床ID</param>
/// <returns>趋势数据列表</returns>
List<MachineTrendItem> GetProductionTrend(int id);
/// <summary>
/// 获取机床近期采集记录
/// </summary>
/// <param name="id">机床ID</param>
/// <returns>采集记录列表</returns>
List<MachineCollectRecordItem> GetCollectRecords(int id);
} }
} }

@ -95,5 +95,53 @@ namespace CncWebApi.Controllers
var result = _machineService.ToggleEnabled(id); var result = _machineService.ToggleEnabled(id);
return Ok(ApiResponse<object>.Success(null)); return Ok(ApiResponse<object>.Success(null));
} }
/// <summary>
/// 机床实时采集状态
/// GET /api/admin/machine/{id}/status
/// </summary>
[HttpGet]
[Route("{id:int}/status")]
public IHttpActionResult GetStatus(int id)
{
var result = _machineService.GetStatus(id);
return Ok(ApiResponse<MachineStatusResponse>.Success(result));
}
/// <summary>
/// 机床今日产量明细
/// GET /api/admin/machine/{id}/production/today
/// </summary>
[HttpGet]
[Route("{id:int}/production/today")]
public IHttpActionResult GetTodayProduction(int id)
{
var result = _machineService.GetTodayProduction(id);
return Ok(ApiResponse<object>.Success(new { items = result }));
}
/// <summary>
/// 机床7天产量趋势
/// GET /api/admin/machine/{id}/production/trend
/// </summary>
[HttpGet]
[Route("{id:int}/production/trend")]
public IHttpActionResult GetProductionTrend(int id)
{
var result = _machineService.GetProductionTrend(id);
return Ok(ApiResponse<object>.Success(new { items = result }));
}
/// <summary>
/// 机床近期采集记录
/// GET /api/admin/machine/{id}/collect-records
/// </summary>
[HttpGet]
[Route("{id:int}/collect-records")]
public IHttpActionResult GetCollectRecords(int id)
{
var result = _machineService.GetCollectRecords(id);
return Ok(ApiResponse<object>.Success(new { items = result }));
}
} }
} }

Loading…
Cancel
Save