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.
haoliang-net/frontend/gen2.cjs

189 lines
13 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const b = 'D:/opencode/haoliang/frontend/src/views';
function w(d, f, c) { fs.writeFileSync(path.join(b, d, f), c, 'utf8'); console.log('OK: ' + d + '/' + f); }
// MachineDetailPage
w('machine', 'MachineDetailPage.vue', `<template>
<div>
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px">
<el-button @click="$router.back()"><el-icon><ArrowLeft /></el-icon> 返回</el-button>
<span style="font-size:16px;font-weight:bold">机床详情:{{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="todayProd" 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="chartRef" 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="records" 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 todayProd = ref<any[]>([]); const records = ref<any[]>([])
const chartRef = ref<HTMLElement>()
let chart: 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 || {}
todayProd.value = t.data?.items || []; records.value = r.data?.items || []
const trend: any = await request.get('/admin/machine/production/trend', { params: { id } })
await nextTick()
if (chartRef.value) {
chart = echarts.init(chartRef.value)
const items = trend.data?.items || []
chart.setOption({ xAxis: { type: 'category', data: items.map((i: any) => i.date.slice(5)) }, yAxis: { type: 'value' }, series: [{ type: 'line', 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(() => { chart?.dispose() })
</script>`);
// CollectAddressListPage
w('collect-address', 'CollectAddressListPage.vue', `<template>
<div>
<div style="margin-bottom:16px"><el-button type="primary" @click="handleAdd">+ 新增地址</el-button></div>
<el-form :inline="true" style="margin-bottom:16px">
<el-form-item label="品牌"><el-select v-model="query.brandId" clearable><el-option v-for="b in brandList" :key="b.id" :label="b.brandName" :value="b.id"/></el-select></el-form-item>
<el-form-item><el-button type="primary" @click="loadData">查询</el-button><el-button @click="query={};loadData()">重置</el-button></el-form-item>
</el-form>
<el-table :data="tableData" border stripe v-loading="loading">
<el-table-column prop="name" label="名称" width="150"><template #default="{row}"><el-link type="primary" @click="goDetail(row.id)">{{row.name}}</el-link></template></el-table-column>
<el-table-column prop="url" label="URL" show-overflow-tooltip/>
<el-table-column prop="brandName" label="品牌" width="100" align="center"/>
<el-table-column prop="collectInterval" label="采集间隔" width="100" align="center"/>
<el-table-column label="状态" width="80" align="center"><template #default="{row}"><el-tag :type="row.isEnabled?'success':'danger'" size="small">{{row.isEnabled?'启用':'停用'}}</el-tag></template></el-table-column>
<el-table-column prop="lastCollectTime" label="最后采集" width="170"/>
<el-table-column prop="machineCount" label="机床数" width="80" align="center"/>
<el-table-column label="操作" width="160" align="center"><template #default="{row}">
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
</template></el-table-column>
</el-table>
<el-dialog v-model="dialogVisible" :title="editingId?'编辑地址':'新增地址'" width="600px" destroy-on-close>
<el-form :model="form" label-width="100px">
<el-form-item label="名称" required><el-input v-model="form.name"/></el-form-item>
<el-form-item label="URL" required><el-input v-model="form.url"/></el-form-item>
<el-form-item label="品牌" required><el-select v-model="form.brandId"><el-option v-for="b in brandList" :key="b.id" :label="b.brandName" :value="b.id"/></el-select></el-form-item>
<el-form-item label="采集间隔" required><el-input-number v-model="form.collectInterval" :min="5"/></el-form-item>
</el-form>
<template #footer><el-button @click="dialogVisible=false">取消</el-button><el-button type="primary" :loading="submitting" @click="handleSubmit">保存</el-button></template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import {ref,reactive,onMounted} from 'vue'
import {useRouter} from 'vue-router'
import {ElMessage,ElMessageBox} from 'element-plus'
import request from '@/utils/request'
import {useMockMode} from '@/composables/useMockMode'
const router=useRouter();const{isMock}=useMockMode()
const loading=ref(false);const tableData=ref<any[]>([]);const brandList=ref<any[]>([])
const dialogVisible=ref(false);const submitting=ref(false);const editingId=ref<number|null>(null)
const query=reactive({brandId:undefined as any})
const form=reactive({name:'',url:'',brandId:undefined as any,collectInterval:30})
function goDetail(id:number){router.push((isMock.value?'/mock/collect-address/':'/collect-address/')+id)}
async function loadData(){loading.value=true;try{const r:any=await request.get('/admin/collect-address');tableData.value=r.data?.items||[]}finally{loading.value=false}}
function handleAdd(){editingId.value=null;Object.assign(form,{name:'',url:'',brandId:undefined,collectInterval:30});dialogVisible.value=true}
function handleEdit(row:any){editingId.value=row.id;Object.assign(form,row);dialogVisible.value=true}
async function handleSubmit(){submitting.value=true;try{await request.post(editingId.value?'/admin/collect-address/update':'/admin/collect-address',{...form,id:editingId.value});ElMessage.success('保存成功');dialogVisible.value=false;loadData()}finally{submitting.value=false}}
async function handleDelete(row:any){await ElMessageBox.confirm('确定删除【'+row.name+'】?此操作不可恢复。','提示',{type:'warning'});await request.post('/admin/collect-address/delete',{id:row.id});ElMessage.success('已删除');loadData()}
async function loadDrops(){const r:any=await request.get('/admin/brand/list');brandList.value=r.data?.items||[]}
onMounted(()=>{loadData();loadDrops()})
</script>`);
// CollectAddressDetailPage
w('collect-address', 'CollectAddressDetailPage.vue', `<template>
<div>
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px">
<el-button @click="$router.back()"><el-icon><ArrowLeft /></el-icon> 返回</el-button>
<span style="font-size:16px;font-weight:bold">采集地址详情:{{detail.name}}</span>
</div>
<el-card shadow="hover" style="margin-bottom:20px"><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="URL">{{detail.url}}</el-descriptions-item>
<el-descriptions-item label="品牌">{{detail.brandName}}</el-descriptions-item>
<el-descriptions-item label="采集间隔">{{detail.collectInterval}}秒</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-item label="最后采集">{{detail.lastCollectTime||'-'}}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card shadow="hover" style="margin-bottom:20px"><template #header><span>关联机床</span></template>
<el-table :data="machines" border stripe size="small">
<el-table-column prop="machineName" label="机床名称"/><el-table-column prop="deviceCode" label="device_code"/><el-table-column prop="workshopName" label="车间"/>
<el-table-column label="在线" align="center"><template #default="{row}"><el-tag :type="row.isOnline?'success':'danger'" size="small">{{row.isOnline?'在线':'离线'}}</el-tag></template></el-table-column>
<el-table-column prop="programName" label="当前程序"/>
</el-table>
</el-card>
<el-card shadow="hover"><template #header><span>最近采集记录</span></template>
<el-table :data="records" border stripe size="small">
<el-table-column prop="requestTime" label="请求时间"/><el-table-column prop="duration" label="耗时(ms)" align="center"/>
<el-table-column label="状态" align="center"><template #default="{row}"><el-tag :type="row.isSuccess?'success':'danger'" size="small">{{row.isSuccess?'成功':'失败'}}</el-tag></template></el-table-column>
<el-table-column prop="machineCount" label="机床数" align="center"/>
</el-table>
</el-card>
</div>
</template>
<script setup lang="ts">
import {ref,onMounted} from 'vue'
import {useRoute} from 'vue-router'
import request from '@/utils/request'
const route=useRoute()
const detail=ref<any>({});const machines=ref<any[]>([]);const records=ref<any[]>([])
async function loadData(){
const id=route.params.id
const[d,m,r]:any[]=await Promise.all([request.get('/admin/collect-address/detail',{params:{id}}),request.get('/admin/collect-address/machines',{params:{id}}),request.get('/admin/collect-address/collect-records',{params:{id}})])
detail.value=d.data||{};machines.value=m.data?.items||[];records.value=r.data?.items||[]
}
onMounted(loadData)
</script>`);
console.log('gen2 done: machine detail, collect-address list+detail');