You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
6.0 KiB
JavaScript
108 lines
6.0 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const base = 'D:/opencode/haoliang/frontend/src/views';
|
|
|
|
function w(dir, file, content) {
|
|
const p = path.join(base, dir, file);
|
|
fs.writeFileSync(p, content, 'utf8');
|
|
console.log('Created: ' + p);
|
|
}
|
|
|
|
// ===== MachineDetailPage =====
|
|
w('machine', 'MachineDetailPage.vue', `<template>
|
|
<div class="machine-detail-page">
|
|
<div class="page-header">
|
|
<el-button @click="$router.back()"><el-icon><ArrowLeft /></el-icon> 返回</el-button>
|
|
<span class="page-title">机床详情:{{ detail.name }}</span>
|
|
</div>
|
|
<el-row :gutter="20">
|
|
<el-col :span="12">
|
|
<el-card shadow="hover"><template #header><span>基本信息</span></template>
|
|
<el-descriptions :column="2" border size="small">
|
|
<el-descriptions-item label="机床名称">{{ detail.name }}</el-descriptions-item>
|
|
<el-descriptions-item label="device_code">{{ detail.deviceCode }}</el-descriptions-item>
|
|
<el-descriptions-item label="车间">{{ detail.workshopName }}</el-descriptions-item>
|
|
<el-descriptions-item label="品牌">{{ detail.brandName }}</el-descriptions-item>
|
|
<el-descriptions-item label="IP地址">{{ detail.ipAddress }}</el-descriptions-item>
|
|
<el-descriptions-item label="绑定工人">{{ detail.workerName || '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="在线状态"><el-tag :type="detail.isOnline ? 'success' : 'danger'" size="small">{{ detail.isOnline ? '在线' : '离线' }}</el-tag></el-descriptions-item>
|
|
<el-descriptions-item label="启用状态"><el-tag :type="detail.isEnabled ? 'success' : 'danger'" size="small">{{ detail.isEnabled ? '启用' : '停用' }}</el-tag></el-descriptions-item>
|
|
</el-descriptions>
|
|
</el-card>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-card shadow="hover"><template #header><span>实时状态</span></template>
|
|
<el-descriptions :column="2" border size="small">
|
|
<el-descriptions-item label="NC程序名">{{ status.programName || '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="零件数">{{ status.partCount ?? '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="运行状态">{{ status.runStatus || '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="操作模式">{{ status.operateMode || '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="主轴设定速度">{{ status.spindleSpeedSet ?? '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="进给设定速度">{{ status.feedSpeedSet ?? '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="主轴实际速度">{{ status.spindleSpeedActual ?? '-' }}</el-descriptions-item>
|
|
<el-descriptions-item label="主轴负载">{{ status.spindleLoad ?? '-' }}%</el-descriptions-item>
|
|
</el-descriptions>
|
|
</el-card>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row :gutter="20" style="margin-top:20px">
|
|
<el-col :span="12">
|
|
<el-card shadow="hover"><template #header><span>今日产量</span></template>
|
|
<el-table :data="todayProduction" border stripe size="small">
|
|
<el-table-column prop="programName" label="程序名" /><el-table-column prop="quantity" label="产量" align="center" /><el-table-column prop="runTime" label="运行时间" align="center" /><el-table-column prop="cuttingTime" label="切削时间" align="center" />
|
|
</el-table>
|
|
</el-card>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-card shadow="hover"><template #header><span>7天产量趋势</span></template>
|
|
<div ref="trendChartRef" style="height:250px"></div>
|
|
</el-card>
|
|
</el-col>
|
|
</el-row>
|
|
<el-card shadow="hover" style="margin-top:20px"><template #header><span>最近采集记录</span></template>
|
|
<el-table :data="collectRecords" border stripe size="small">
|
|
<el-table-column prop="collectTime" label="采集时间" /><el-table-column prop="programName" label="程序名" /><el-table-column prop="partCount" label="零件数" align="center" /><el-table-column prop="runStatus" label="运行状态" />
|
|
</el-table>
|
|
</el-card>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted, nextTick, onBeforeUnmount } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import request from '@/utils/request'
|
|
import * as echarts from 'echarts'
|
|
|
|
const route = useRoute()
|
|
const detail = ref<any>({})
|
|
const status = ref<any>({})
|
|
const todayProduction = ref<any[]>([])
|
|
const collectRecords = ref<any[]>([])
|
|
const trendChartRef = ref<HTMLElement>()
|
|
let chartInstance: echarts.ECharts | null = null
|
|
|
|
async function loadData() {
|
|
const id = route.params.id
|
|
const [d, s, t, r]: any[] = await Promise.all([
|
|
request.get('/admin/machine/detail', { params: { id } }),
|
|
request.get('/admin/machine/status', { params: { id } }),
|
|
request.get('/admin/machine/production/today', { params: { id } }),
|
|
request.get('/admin/machine/collect-records', { params: { id } }),
|
|
])
|
|
detail.value = d.data || {}; status.value = s.data || {}; todayProduction.value = t.data?.items || []; collectRecords.value = r.data?.items || []
|
|
const trend: any = await request.get('/admin/machine/production/trend', { params: { id } })
|
|
await nextTick()
|
|
if (trendChartRef.value) {
|
|
chartInstance = echarts.init(trendChartRef.value)
|
|
chartInstance.setOption({ xAxis: { type: 'category', data: (trend.data?.items || []).map((i: any) => i.date.slice(5)) }, yAxis: { type: 'value' }, series: [{ type: 'line', data: (trend.data?.items || []).map((i: any) => i.quantity), smooth: true, areaStyle: { opacity: 0.1 } }], tooltip: { trigger: 'axis' }, grid: { left: 40, right: 20, top: 10, bottom: 30 } })
|
|
}
|
|
}
|
|
onMounted(loadData)
|
|
onBeforeUnmount(() => { chartInstance?.dispose() })
|
|
</script>
|
|
<style scoped lang="scss">
|
|
.page-header { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; .page-title { font-size: 16px; font-weight: bold; } }
|
|
</style>`);
|
|
|
|
console.log('All detail pages created');
|