Compare commits

...

6 Commits

@ -1,4 +1,5 @@
import request from '@/config/axios' import request from '@/config/axios'
import qs from 'qs'
// 物联设备 VO // 物联设备 VO
export interface DeviceVO { export interface DeviceVO {
@ -65,6 +66,7 @@ export interface HistoryRecordParams {
deviceId: string | number deviceId: string | number
collectionStartTime?: string collectionStartTime?: string
collectionEndTime?: string collectionEndTime?: string
attributeCodes?: string[]
} }
export interface DeviceContactModelVO { export interface DeviceContactModelVO {
@ -143,7 +145,11 @@ export const DeviceApi = {
}, },
getHistoryRecord: async (params: HistoryRecordParams) => { getHistoryRecord: async (params: HistoryRecordParams) => {
return await request.get({ url: `/iot/device/historyRecord`, params }) return await request.get({
url: `/iot/device/historyRecord`,
params,
paramsSerializer: (p) => qs.stringify(p, { allowDots: true, arrayFormat: 'repeat' })
})
}, },
devicePointList: async () => { devicePointList: async () => {
@ -162,7 +168,7 @@ export const DeviceApi = {
return await request.get({ url: `/iot/device/device-attribute/page`, params }) return await request.get({ url: `/iot/device/device-attribute/page`, params })
}, },
// 获得设备属性列表 // 获得设备属性列表
getDeviceAttributeList: async (deviceId: number) => { getDeviceAttributeList: async (deviceId: number | string) => {
return await request.get({ url: `/iot/device/device-attribute/list?deviceId=` + deviceId }) return await request.get({ url: `/iot/device/device-attribute/list?deviceId=` + deviceId })
}, },

@ -37,6 +37,7 @@ export default {
toolDes: 'Used to set up custom systems', toolDes: 'Used to set up custom systems',
query: 'Query', query: 'Query',
reset: 'Reset', reset: 'Reset',
noData: 'No data',
shrink: 'Put away', shrink: 'Put away',
expand: 'Expand', expand: 'Expand',
confirmTitle: 'System Hint', confirmTitle: 'System Hint',
@ -59,6 +60,47 @@ export default {
copyError: 'Copy Error', copyError: 'Copy Error',
code:'Auto-generate on Save' code:'Auto-generate on Save'
}, },
ReportDashboard: {
DashboardList: {
searchNameLabel: 'Name',
searchNamePlaceholder: 'Please enter name',
searchRemarkLabel: 'Remark',
searchRemarkPlaceholder: 'Please enter remark',
searchStateLabel: 'Status',
searchStatePlaceholder: 'Please select status',
coverAlt: 'Cover image',
stateEnabled: 'Enabled',
stateDisabled: 'Disabled',
noRemark: 'No description',
dialogCreateTitle: 'Create Dashboard',
dialogEditTitle: 'Edit Dashboard',
dialogNameLabel: 'Name',
dialogNamePlaceholder: 'Please enter name',
dialogTypeLabel: 'Type',
dialogTypePlaceholder: 'Please select type',
dialogOrgLabel: 'Line',
dialogOrgPlaceholder: 'Please select line',
dialogDeviceLabel: 'Device',
dialogDevicePlaceholder: 'Please select device',
dialogPointPlaceholder: 'Please select points',
dialogAddDeviceButton: 'Add device',
dialogContentLabel: 'Content',
dialogContentPlaceholder: 'Please enter content',
dialogRemarkLabel: 'Remark',
dialogRemarkPlaceholder: 'Please enter remark',
dialogStateLabel: 'Status',
validatorNameRequired: 'Name is required',
validatorTypeRequired: 'Dashboard type is required',
validatorOrgRequired: 'Line is required',
messageRouteMissing: 'Preview route is not configured',
messageDevicePointRequired: 'Please configure at least one device and point group',
messageMissingId: 'Missing record ID, unable to edit'
}
},
ErpStock: { ErpStock: {
Warehouse: { Warehouse: {
name: 'Warehouse Name', name: 'Warehouse Name',
@ -3763,6 +3805,8 @@ export default {
dialogCollectionTimeLabel: 'Collection Time', dialogCollectionTimeLabel: 'Collection Time',
dialogCollectionTimeStartPlaceholder: 'Start Time', dialogCollectionTimeStartPlaceholder: 'Start Time',
dialogCollectionTimeEndPlaceholder: 'End Time', dialogCollectionTimeEndPlaceholder: 'End Time',
dialogPointFilterLabel: 'Point Filter',
dialogPointFilterPlaceholder: 'Please select points',
dialogSearchButtonText: 'Search', dialogSearchButtonText: 'Search',
dialogResetButtonText: 'Reset', dialogResetButtonText: 'Reset',
dialogRecordCollectionTimePrefix: 'Collection Time: ', dialogRecordCollectionTimePrefix: 'Collection Time: ',

@ -37,6 +37,7 @@ export default {
toolDes: '用于设置定制系统', toolDes: '用于设置定制系统',
query: '查询', query: '查询',
reset: '重置', reset: '重置',
noData: '暂无数据',
shrink: '收起', shrink: '收起',
expand: '展开', expand: '展开',
confirmTitle: '系统提示', confirmTitle: '系统提示',
@ -59,6 +60,47 @@ export default {
copyError: '复制失败', copyError: '复制失败',
code: '编码保存后自动生成' code: '编码保存后自动生成'
}, },
ReportDashboard: {
DashboardList: {
searchNameLabel: '名称',
searchNamePlaceholder: '请输入名称',
searchRemarkLabel: '备注',
searchRemarkPlaceholder: '请输入备注',
searchStateLabel: '启用状态',
searchStatePlaceholder: '请选择启用状态',
coverAlt: '封面图',
stateEnabled: '启用',
stateDisabled: '禁用',
noRemark: '暂无描述',
dialogCreateTitle: '新增数据大屏',
dialogEditTitle: '编辑数据大屏',
dialogNameLabel: '名称',
dialogNamePlaceholder: '请输入名称',
dialogTypeLabel: '大屏类型',
dialogTypePlaceholder: '请选择大屏类型',
dialogOrgLabel: '产线',
dialogOrgPlaceholder: '请选择产线',
dialogDeviceLabel: '设备',
dialogDevicePlaceholder: '请选择设备',
dialogPointPlaceholder: '请选择点位',
dialogAddDeviceButton: '添加设备',
dialogContentLabel: '内容',
dialogContentPlaceholder: '请输入内容',
dialogRemarkLabel: '备注',
dialogRemarkPlaceholder: '请输入备注',
dialogStateLabel: '启用状态',
validatorNameRequired: '名称不能为空',
validatorTypeRequired: '大屏类型不能为空',
validatorOrgRequired: '产线不能为空',
messageRouteMissing: '未配置预览路由',
messageDevicePointRequired: '请至少配置一组设备和点位',
messageMissingId: '缺少数据编号,无法编辑'
}
},
ErpStock: { ErpStock: {
Warehouse: { Warehouse: {
name: '仓库名称', name: '仓库名称',
@ -3607,6 +3649,8 @@ export default {
dialogCollectionTimeLabel: '采集时间', dialogCollectionTimeLabel: '采集时间',
dialogCollectionTimeStartPlaceholder: '开始时间', dialogCollectionTimeStartPlaceholder: '开始时间',
dialogCollectionTimeEndPlaceholder: '结束时间', dialogCollectionTimeEndPlaceholder: '结束时间',
dialogPointFilterLabel: '点位筛选',
dialogPointFilterPlaceholder: '请选择点位',
dialogSearchButtonText: '查询', dialogSearchButtonText: '查询',
dialogResetButtonText: '重置', dialogResetButtonText: '重置',
dialogRecordCollectionTimePrefix: '采集时间:', dialogRecordCollectionTimePrefix: '采集时间:',

@ -7,7 +7,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('SparePartsManagement.SpareIn.product')" prop="productId"> <el-form-item :label="t('SparePartsManagement.SpareIn.product')" prop="productId">
<el-select <el-select

@ -9,7 +9,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('SparePartsManagement.SpareInfo.name')" prop="name"> <el-form-item :label="t('SparePartsManagement.SpareInfo.name')" prop="name">
<el-input <el-input

@ -8,7 +8,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('SparePartsManagement.SpareStock.product')" prop="productId"> <el-form-item :label="t('SparePartsManagement.SpareStock.product')" prop="productId">
<el-select <el-select

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('MoldManagement.MoldBrand.code')" prop="code"> <el-form-item :label="t('MoldManagement.MoldBrand.code')" prop="code">
<el-input <el-input

@ -8,7 +8,7 @@ v-loading="typeTreeLoading" :data="brandTreeData" node-key="id" highlight-curren
<div class="device-ledger-right"> <div class="device-ledger-right">
<ContentWrap> <ContentWrap>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('MoldManagement.Mold.code')" prop="code"> <el-form-item :label="t('MoldManagement.Mold.code')" prop="code">
<el-input <el-input
v-model="queryParams.code" :placeholder="t('MoldManagement.Mold.code')" clearable @keyup.enter="handleQuery" v-model="queryParams.code" :placeholder="t('MoldManagement.Mold.code')" clearable @keyup.enter="handleQuery"

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('FactoryModeling.ProductCategory.searchNameLabel')" prop="name"> <el-form-item :label="t('FactoryModeling.ProductCategory.searchNameLabel')" prop="name">
<el-input <el-input

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('FactoryModeling.ProductUnit.searchNameLabel')" prop="name"> <el-form-item :label="t('FactoryModeling.ProductUnit.searchNameLabel')" prop="name">
<el-input <el-input

@ -1,7 +1,7 @@
<template> <template>
<ContentWrap> <ContentWrap>
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('DataCollection.Device.deviceCode')" prop="deviceCode"> <el-form-item :label="t('DataCollection.Device.deviceCode')" prop="deviceCode">
<el-input <el-input
v-model="queryParams.deviceCode" v-model="queryParams.deviceCode"

@ -5,7 +5,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="80px" min-label-width="80px"
> >
<el-form-item :label="t('DataCollection.DeviceAttributeType.code')" prop="code"> <el-form-item :label="t('DataCollection.DeviceAttributeType.code')" prop="code">
<el-input <el-input

@ -1,7 +1,7 @@
<template> <template>
<ContentWrap> <ContentWrap>
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('DataCollection.DeviceModel.code')" prop="code"> <el-form-item :label="t('DataCollection.DeviceModel.code')" prop="code">
<el-input <el-input
v-model="queryParams.code" v-model="queryParams.code"

@ -1,5 +1,5 @@
<template> <template>
<Dialog v-model="dialogVisible" :title="dialogTitle" width="900" :scroll="true" max-height="80vh" align-center> <Dialog v-model="dialogVisible" :title="dialogTitle" width="1100" :scroll="true" max-height="80vh" align-center>
<div class="single-device-dialog"> <div class="single-device-dialog">
<el-form class="-mb-15px history-single-device-form" :inline="true" label-width="auto"> <el-form class="-mb-15px history-single-device-form" :inline="true" label-width="auto">
<el-form-item :label="t('DataCollection.HistoryData.dialogCollectionTimeLabel')"> <el-form-item :label="t('DataCollection.HistoryData.dialogCollectionTimeLabel')">
@ -10,9 +10,30 @@
:start-placeholder="t('DataCollection.HistoryData.dialogCollectionTimeStartPlaceholder')" :start-placeholder="t('DataCollection.HistoryData.dialogCollectionTimeStartPlaceholder')"
:end-placeholder="t('DataCollection.HistoryData.dialogCollectionTimeEndPlaceholder')" :end-placeholder="t('DataCollection.HistoryData.dialogCollectionTimeEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-360px" class="!w-280px"
/> />
</el-form-item> </el-form-item>
<el-form-item :label="t('DataCollection.HistoryData.dialogPointFilterLabel')">
<el-select
v-model="attributeCodes"
class="!w-280px"
multiple
:max-collapse-tags="1"
collapse-tags
collapse-tags-tooltip
filterable
clearable
:loading="attributeLoading"
:placeholder="t('DataCollection.HistoryData.dialogPointFilterPlaceholder')"
>
<el-option
v-for="item in attributeOptions"
:key="item.attributeCode"
:label="item.label"
:value="item.attributeCode"
/>
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<el-button @click="handleQuery">{{ t('DataCollection.HistoryData.dialogSearchButtonText') }}</el-button> <el-button @click="handleQuery">{{ t('DataCollection.HistoryData.dialogSearchButtonText') }}</el-button>
<el-button @click="resetQuery">{{ t('DataCollection.HistoryData.dialogResetButtonText') }}</el-button> <el-button @click="resetQuery">{{ t('DataCollection.HistoryData.dialogResetButtonText') }}</el-button>
@ -125,6 +146,14 @@ const loading = ref(false)
const recordGroups = ref<RecordGroup[]>([]) const recordGroups = ref<RecordGroup[]>([])
const collectionTimeRange = ref<string[]>([]) const collectionTimeRange = ref<string[]>([])
const attributeCodes = ref<string[]>([])
const attributeLoading = ref(false)
type AttributeOption = {
attributeCode: string
label: string
}
const attributeOptions = ref<AttributeOption[]>([])
const formatDateTime = (date: Date) => { const formatDateTime = (date: Date) => {
const pad = (value: number) => String(value).padStart(2, '0') const pad = (value: number) => String(value).padStart(2, '0')
@ -204,6 +233,36 @@ const buildSectionsFromGroups = (groups: Record<string, any[]>): Section[] => {
return result return result
} }
const fetchDeviceAttributes = async () => {
if (props.deviceId === undefined || props.deviceId === null || props.deviceId === '') {
attributeOptions.value = []
return
}
attributeLoading.value = true
try {
const res: any = await DeviceApi.getDeviceAttributeList(props.deviceId)
const responseData = res?.data?.data ?? res?.data ?? res
const list: any[] = Array.isArray(responseData?.list)
? responseData.list
: Array.isArray(responseData)
? responseData
: []
attributeOptions.value = list
.map((item: any) => {
const code = String(item?.attributeCode ?? '').trim()
if (!code) return null
const name = String(item?.attributeName ?? '').trim()
return {
attributeCode: code,
label: name ? `${name}(${code})` : code
}
})
.filter(Boolean) as AttributeOption[]
} finally {
attributeLoading.value = false
}
}
const fetchHistory = async () => { const fetchHistory = async () => {
if (props.deviceId === undefined || props.deviceId === null || props.deviceId === '') { if (props.deviceId === undefined || props.deviceId === null || props.deviceId === '') {
recordGroups.value = [] recordGroups.value = []
@ -221,6 +280,9 @@ const fetchHistory = async () => {
params.collectionStartTime = collectionTimeRange.value[0] params.collectionStartTime = collectionTimeRange.value[0]
params.collectionEndTime = collectionTimeRange.value[1] params.collectionEndTime = collectionTimeRange.value[1]
} }
if (Array.isArray(attributeCodes.value) && attributeCodes.value.length) {
params.attributeCodes = attributeCodes.value
}
const res: any = await DeviceApi.getHistoryRecord(params) const res: any = await DeviceApi.getHistoryRecord(params)
const responseData = res?.data?.data ?? res?.data ?? res const responseData = res?.data?.data ?? res?.data ?? res
@ -256,6 +318,7 @@ const handleQuery = () => {
const resetQuery = () => { const resetQuery = () => {
collectionTimeRange.value = [] collectionTimeRange.value = []
attributeCodes.value = []
queryParams.pageNo = 1 queryParams.pageNo = 1
queryParams.pageSize = 10 queryParams.pageSize = 10
fetchHistory() fetchHistory()
@ -268,8 +331,10 @@ watch(
return return
} }
collectionTimeRange.value = buildLastHoursRange(4) collectionTimeRange.value = buildLastHoursRange(4)
attributeCodes.value = []
queryParams.pageNo = 1 queryParams.pageNo = 1
queryParams.pageSize = 10 queryParams.pageSize = 10
fetchDeviceAttributes()
fetchHistory() fetchHistory()
} }
) )

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="80px" min-label-width="80px"
> >
<el-form-item :label="t('FactoryModeling.ProductBOM.searchCodeLabel')" prop="code"> <el-form-item :label="t('FactoryModeling.ProductBOM.searchCodeLabel')" prop="code">
<el-input <el-input

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="120px" min-label-width="120px"
> >
<el-form-item :label="t('EnergyManagement.EnergyType.searchCodeLabel')" prop="code"> <el-form-item :label="t('EnergyManagement.EnergyType.searchCodeLabel')" prop="code">
<el-input <el-input

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<!-- <el-form-item label="操作类型" prop="operateType"> <!-- <el-form-item label="操作类型" prop="operateType">
<el-select <el-select

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('MoldManagement.MoldReturn.no')" prop="no"> <el-form-item :label="t('MoldManagement.MoldReturn.no')" prop="no">
<el-input <el-input

@ -1,6 +1,6 @@
<template> <template>
<ContentWrap> <ContentWrap>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('EquipmentManagement.PlanMaintenance.planName')" prop="planName"> <el-form-item :label="t('EquipmentManagement.PlanMaintenance.planName')" prop="planName">
<el-input <el-input
v-model="queryParams.planName" v-model="queryParams.planName"

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('ProductionPlan.Task.searchCodeLabel')" prop="code"> <el-form-item :label="t('ProductionPlan.Task.searchCodeLabel')" prop="code">
<el-input <el-input

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('FactoryModeling.WorkTeam.searchTeamNameLabel')" prop="teamName"> <el-form-item :label="t('FactoryModeling.WorkTeam.searchTeamNameLabel')" prop="teamName">
<el-input <el-input

@ -1,6 +1,6 @@
<template> <template>
<ContentWrap> <ContentWrap>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('QualityManagement.ZjTask.code')" prop="code"> <el-form-item :label="t('QualityManagement.ZjTask.code')" prop="code">
<el-input <el-input
v-model="queryParams.code" v-model="queryParams.code"

@ -1,7 +1,7 @@
<template> <template>
<ContentWrap> <ContentWrap>
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('QualityManagement.ZjSchema.name')" prop="name"> <el-form-item :label="t('QualityManagement.ZjSchema.name')" prop="name">
<el-input <el-input
v-model="queryParams.name" v-model="queryParams.name"

@ -6,7 +6,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('QualityManagement.ZjType.code')" prop="code"> <el-form-item :label="t('QualityManagement.ZjType.code')" prop="code">
<el-input <el-input

@ -1,6 +1,6 @@
<template> <template>
<ContentWrap> <ContentWrap>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('MoldManagement.MoldInspectionPlan.planName')" prop="planName"> <el-form-item :label="t('MoldManagement.MoldInspectionPlan.planName')" prop="planName">
<el-input <el-input
v-model="queryParams.planName" v-model="queryParams.planName"

@ -1,6 +1,6 @@
<template> <template>
<ContentWrap> <ContentWrap>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('MoldManagement.MoldRepair.repairCode')" prop="repairCode"> <el-form-item :label="t('MoldManagement.MoldRepair.repairCode')" prop="repairCode">
<el-input <el-input
v-model="queryParams.repairCode" v-model="queryParams.repairCode"

@ -1,6 +1,6 @@
<template> <template>
<ContentWrap> <ContentWrap>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('MoldManagement.MoldRepairItems.subjectCode')" prop="subjectCode"> <el-form-item :label="t('MoldManagement.MoldRepairItems.subjectCode')" prop="subjectCode">
<el-input <el-input
v-model="queryParams.subjectCode" v-model="queryParams.subjectCode"

@ -5,7 +5,7 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" min-label-width="68px"
> >
<el-form-item :label="t('EquipmentManagement.TaskManagement.name')" prop="name"> <el-form-item :label="t('EquipmentManagement.TaskManagement.name')" prop="name">
<el-input <el-input

@ -1,6 +1,6 @@
<template> <template>
<ContentWrap> <ContentWrap>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
<el-form-item :label="t('MoldManagement.MoldWorkOrderInquiry.planNo')" prop="planNo"> <el-form-item :label="t('MoldManagement.MoldWorkOrderInquiry.planNo')" prop="planNo">
<el-input <el-input
v-model="queryParams.planNo" v-model="queryParams.planNo"

@ -1,18 +1,18 @@
<template> <template>
<ContentWrap> <ContentWrap>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="80px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="80px">
<el-form-item label="名称" prop="name"> <el-form-item :label="t('ReportDashboard.DashboardList.searchNameLabel')" prop="name">
<el-input <el-input
v-model="queryParams.name" placeholder="请输入名称" clearable @keyup.enter="handleQuery" v-model="queryParams.name" :placeholder="t('ReportDashboard.DashboardList.searchNamePlaceholder')" clearable @keyup.enter="handleQuery"
class="!w-240px" /> class="!w-240px" />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ReportDashboard.DashboardList.searchRemarkLabel')" prop="remark">
<el-input <el-input
v-model="queryParams.remark" placeholder="请输入备注" clearable @keyup.enter="handleQuery" v-model="queryParams.remark" :placeholder="t('ReportDashboard.DashboardList.searchRemarkPlaceholder')" clearable @keyup.enter="handleQuery"
class="!w-240px" /> class="!w-240px" />
</el-form-item> </el-form-item>
<el-form-item label="启用状态" prop="state"> <el-form-item :label="t('ReportDashboard.DashboardList.searchStateLabel')" prop="state">
<el-select v-model="queryParams.state" placeholder="请选择启用状态" clearable class="!w-240px"> <el-select v-model="queryParams.state" :placeholder="t('ReportDashboard.DashboardList.searchStatePlaceholder')" clearable class="!w-240px">
<el-option <el-option
v-for="dict in getStrDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value" :label="dict.label" v-for="dict in getStrDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value" :label="dict.label"
:value="dict.value" /> :value="dict.value" />
@ -20,13 +20,13 @@ v-for="dict in getStrDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value" :la
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="openCreateDialog"> <el-button type="primary" @click="openCreateDialog">
<Icon icon="ep:plus" class="mr-5px" /> 新增 <Icon icon="ep:plus" class="mr-5px" /> {{ t('action.add') }}
</el-button> </el-button>
<el-button @click="handleQuery"> <el-button @click="handleQuery">
<Icon icon="ep:search" class="mr-5px" /> 搜索 <Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}
</el-button> </el-button>
<el-button @click="resetQuery"> <el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" /> 重置 <Icon icon="ep:refresh" class="mr-5px" /> {{ t('common.reset') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -34,18 +34,18 @@ v-for="dict in getStrDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value" :la
<ContentWrap> <ContentWrap>
<div class="dashboard-card-list"> <div class="dashboard-card-list">
<el-empty v-if="!loading && list.length === 0" description="暂无数据" /> <el-empty v-if="!loading && list.length === 0" :description="t('common.noData')" />
<el-row v-else :gutter="16"> <el-row v-else :gutter="16">
<el-col v-for="item in list" :key="item.id" :xl="6" :lg="8" :md="12" :sm="24" :xs="24" class="mb-16px"> <el-col v-for="item in list" :key="item.id" :xl="6" :lg="8" :md="12" :sm="24" :xs="24" class="mb-16px">
<el-card shadow="hover" class="dashboard-card" :body-style="{ padding: '0' }"> <el-card shadow="hover" class="dashboard-card" :body-style="{ padding: '0' }">
<div class="dashboard-card-image-wrapper" @click="handlePreview(item)"> <div class="dashboard-card-image-wrapper" @click="handlePreview(item)">
<img class="dashboard-card-image" :src="getDashboardImage(item)" alt="封面图" /> <img class="dashboard-card-image" :src="getDashboardImage(item)" :alt="t('ReportDashboard.DashboardList.coverAlt')" />
<div class="dashboard-card-state"> <div class="dashboard-card-state">
<el-tag v-if="item.state === 1" type="success" size="small"> <el-tag v-if="item.state === 1" type="success" size="small">
启用 {{ t('ReportDashboard.DashboardList.stateEnabled') }}
</el-tag> </el-tag>
<el-tag v-else type="info" size="small"> <el-tag v-else type="info" size="small">
禁用 {{ t('ReportDashboard.DashboardList.stateDisabled') }}
</el-tag> </el-tag>
</div> </div>
</div> </div>
@ -55,7 +55,7 @@ v-for="dict in getStrDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value" :la
{{ item.name || '-' }} {{ item.name || '-' }}
</div> </div>
<div class="dashboard-card-remark" :title="item.remark"> <div class="dashboard-card-remark" :title="item.remark">
{{ item.remark || '暂无描述' }} {{ item.remark || t('ReportDashboard.DashboardList.noRemark') }}
</div> </div>
</div> </div>
<div class="dashboard-card-actions"> <div class="dashboard-card-actions">
@ -65,8 +65,8 @@ v-for="dict in getStrDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value" :la
</el-button> </el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu class="dashboard-card-menu"> <el-dropdown-menu class="dashboard-card-menu">
<el-dropdown-item class="dashboard-card-menu-primary" @click="openEditDialog(item)"></el-dropdown-item> <el-dropdown-item class="dashboard-card-menu-primary" @click="openEditDialog(item)">{{ t('action.edit') }}</el-dropdown-item>
<el-dropdown-item divided class="dashboard-card-menu-danger" @click="handleDelete(item)"></el-dropdown-item> <el-dropdown-item divided class="dashboard-card-menu-danger" @click="handleDelete(item)">{{ t('action.delete') }}</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
@ -82,35 +82,35 @@ v-if="total > 0" :total="total" v-model:page="queryParams.pageNo" v-model:limit=
</ContentWrap> </ContentWrap>
<el-dialog <el-dialog
v-model="createDialogVisible" :title="dialogMode === 'create' ? '新增数据大屏' : '编辑数据大屏'" width="600px" v-model="createDialogVisible" :title="dialogMode === 'create' ? t('ReportDashboard.DashboardList.dialogCreateTitle') : t('ReportDashboard.DashboardList.dialogEditTitle')" width="600px"
draggable @closed="handleCreateDialogClosed"> draggable @closed="handleCreateDialogClosed">
<el-form :model="createForm" ref="createFormRef" label-width="80px" :rules="createFormRules"> <el-form :model="createForm" ref="createFormRef" label-width="80px" :rules="createFormRules">
<el-form-item label="名称" prop="name"> <el-form-item :label="t('ReportDashboard.DashboardList.dialogNameLabel')" prop="name">
<el-input v-model="createForm.name" placeholder="请输入名称" /> <el-input v-model="createForm.name" :placeholder="t('ReportDashboard.DashboardList.dialogNamePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="大屏类型" prop="type"> <el-form-item :label="t('ReportDashboard.DashboardList.dialogTypeLabel')" prop="type">
<el-select v-model="createForm.type" placeholder="请选择大屏类型" class="!w-240px"> <el-select v-model="createForm.type" :placeholder="t('ReportDashboard.DashboardList.dialogTypePlaceholder')" class="!w-240px">
<el-option <el-option
v-for="dict in getStrDictOptions('mes_goview_type')" :key="dict.value" :label="dict.label" v-for="dict in getStrDictOptions('mes_goview_type')" :key="dict.value" :label="dict.label"
:value="dict.value" /> :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="产线" prop="orgId"> <el-form-item :label="t('ReportDashboard.DashboardList.dialogOrgLabel')" prop="orgId">
<el-tree-select <el-tree-select
v-model="createForm.orgName" :data="organizationTree" :props="lineTreeProps" filterable clearable v-model="createForm.orgName" :data="organizationTree" :props="lineTreeProps" filterable clearable
class="!w-240px" placeholder="请选择产线" @change="handleOrgChange" /> class="!w-240px" :placeholder="t('ReportDashboard.DashboardList.dialogOrgPlaceholder')" @change="handleOrgChange" />
</el-form-item> </el-form-item>
<el-form-item label="设备" v-if="createForm.type === '1'"> <el-form-item :label="t('ReportDashboard.DashboardList.dialogDeviceLabel')" v-if="createForm.type === '1'">
<div class="dashboard-device-group-list"> <div class="dashboard-device-group-list">
<div v-for="(group, index) in deviceAttrSelections" :key="index" class="dashboard-device-group"> <div v-for="(group, index) in deviceAttrSelections" :key="index" class="dashboard-device-group">
<el-select <el-select
v-model="group.deviceId" placeholder="请选择设备" clearable filterable class="!w-160px mr-8px" v-model="group.deviceId" :placeholder="t('ReportDashboard.DashboardList.dialogDevicePlaceholder')" clearable filterable class="!w-160px mr-8px"
@change="(val) => handleDeviceChange(val, index)"> @change="(val) => handleDeviceChange(val, index)">
<el-option v-for="item in deviceList" :key="item.id" :label="item.deviceName" :value="item.id" /> <el-option v-for="item in deviceList" :key="item.id" :label="item.deviceName" :value="item.id" />
</el-select> </el-select>
<el-select <el-select
v-model="group.attributeIds" multiple collapse-tags collapse-tags-tooltip v-model="group.attributeIds" multiple collapse-tags collapse-tags-tooltip
:disabled="!group.deviceId" placeholder="请选择点位" clearable filterable class="!w-260px"> :disabled="!group.deviceId" :placeholder="t('ReportDashboard.DashboardList.dialogPointPlaceholder')" clearable filterable class="!w-260px">
<el-option <el-option
v-for="attr in (deviceAttributeOptionsMap[String(group.deviceId)] || [])" :key="attr.id" v-for="attr in (deviceAttributeOptionsMap[String(group.deviceId)] || [])" :key="attr.id"
:label="attr.attributeName" :value="attr.id" /> :label="attr.attributeName" :value="attr.id" />
@ -124,24 +124,24 @@ v-if="deviceAttrSelections.length > 1" type="danger" text class="dashboard-devic
<el-button <el-button
type="primary" text @click="addDeviceAttrGroup" :disabled="deviceAttrSelections.length >= 8" type="primary" text @click="addDeviceAttrGroup" :disabled="deviceAttrSelections.length >= 8"
class="mt-8px"> class="mt-8px">
<Icon icon="ep:plus" class="mr-5px" /> 添加设备 <Icon icon="ep:plus" class="mr-5px" /> {{ t('ReportDashboard.DashboardList.dialogAddDeviceButton') }}
</el-button> </el-button>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="内容"> <el-form-item :label="t('ReportDashboard.DashboardList.dialogContentLabel')">
<el-input v-model="createForm.content" type="textarea" :rows="4" placeholder="请输入内容" /> <el-input v-model="createForm.content" type="textarea" :rows="4" :placeholder="t('ReportDashboard.DashboardList.dialogContentPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="备注"> <el-form-item :label="t('ReportDashboard.DashboardList.dialogRemarkLabel')">
<el-input v-model="createForm.remark" placeholder="请输入备注" /> <el-input v-model="createForm.remark" :placeholder="t('ReportDashboard.DashboardList.dialogRemarkPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="启用状态"> <el-form-item :label="t('ReportDashboard.DashboardList.dialogStateLabel')">
<el-switch v-model="createForm.state" :active-value="1" :inactive-value="0" /> <el-switch v-model="createForm.state" :active-value="1" :inactive-value="0" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="createDialogVisible = false"> </el-button> <el-button @click="createDialogVisible = false">{{ t('common.cancel') }}</el-button>
<el-button type="primary" :loading="createLoading" @click="submitDialog"> <el-button type="primary" :loading="createLoading" @click="submitDialog">
{{ t('common.ok') }}
</el-button> </el-button>
</template> </template>
</el-dialog> </el-dialog>
@ -161,6 +161,7 @@ defineOptions({ name: 'DashboardList' })
const router = useRouter() const router = useRouter()
const message = useMessage() const message = useMessage()
const { t } = useI18n()
interface DashboardItem { interface DashboardItem {
id: number id: number
@ -182,12 +183,8 @@ const list = ref<DashboardItem[]>([])
const total = ref(0) const total = ref(0)
const getDashboardImage = (item: DashboardItem) => { const getDashboardImage = (item: DashboardItem) => {
if (item.name === '智能制造产线任务总览') { if (item.type === '2') return dashboardImage1
return dashboardImage1 if (item.type === '1') return dashboardImage2
}
if (item.name === '产线运行看板') {
return dashboardImage2
}
return item.indexImage || defaultImage return item.indexImage || defaultImage
} }
@ -220,9 +217,9 @@ const createForm = reactive({
}) })
const createFormRules = reactive({ const createFormRules = reactive({
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }], name: [{ required: true, message: t('ReportDashboard.DashboardList.validatorNameRequired'), trigger: 'blur' }],
type: [{ required: true, message: '大屏类型不能为空', trigger: 'change' }], type: [{ required: true, message: t('ReportDashboard.DashboardList.validatorTypeRequired'), trigger: 'change' }],
orgId: [{ required: true, message: '产线不能为空', trigger: 'change' }] orgId: [{ required: true, message: t('ReportDashboard.DashboardList.validatorOrgRequired'), trigger: 'change' }]
}) })
const organizationTree = ref<any[]>([]) const organizationTree = ref<any[]>([])
@ -266,7 +263,7 @@ const handlePreview = (item: DashboardItem) => {
const typeRoute = getRouteByType(item.type) const typeRoute = getRouteByType(item.type)
const route = typeRoute || item.route || '' const route = typeRoute || item.route || ''
if (!route) { if (!route) {
message.error('未配置预览路由') message.error(t('ReportDashboard.DashboardList.messageRouteMissing'))
return return
} }
const path = route.startsWith('/') ? route : `/${route}` const path = route.startsWith('/') ? route : `/${route}`
@ -392,7 +389,7 @@ const submitDialog = async () => {
})) }))
.filter((g) => g.deviceId && g.attributesIds.length) .filter((g) => g.deviceId && g.attributesIds.length)
if (!groups.length) { if (!groups.length) {
message.error('请至少配置一组设备和点位') message.error(t('ReportDashboard.DashboardList.messageDevicePointRequired'))
return return
} }
createForm.deviceIdsList = groups.map((g) => ({ createForm.deviceIdsList = groups.map((g) => ({
@ -416,7 +413,7 @@ const submitDialog = async () => {
createForm.route = route createForm.route = route
} }
if (dialogMode.value === 'edit' && !editingId.value) { if (dialogMode.value === 'edit' && !editingId.value) {
message.error('缺少数据编号,无法编辑') message.error(t('ReportDashboard.DashboardList.messageMissingId'))
return return
} }
createLoading.value = true createLoading.value = true
@ -426,7 +423,7 @@ const submitDialog = async () => {
url: '/mes/goview/create', url: '/mes/goview/create',
data: createForm data: createForm
}) })
message.success('新增成功') message.success(t('common.createSuccess'))
} else { } else {
await request.put({ await request.put({
url: '/mes/goview/update', url: '/mes/goview/update',
@ -435,7 +432,7 @@ const submitDialog = async () => {
...createForm ...createForm
} }
}) })
message.success('编辑成功') message.success(t('common.updateSuccess'))
} }
createDialogVisible.value = false createDialogVisible.value = false
handleQuery() handleQuery()
@ -451,7 +448,7 @@ const handleDelete = async (item: DashboardItem) => {
await request.delete({ await request.delete({
url: `/mes/goview/delete?id=${item.id}` url: `/mes/goview/delete?id=${item.id}`
}) })
message.success('删除成功') message.success(t('common.delSuccess'))
await getList() await getList()
} catch { } } catch { }
} }

@ -48,7 +48,7 @@
</el-tag> </el-tag>
</div> </div>
<div class="header-right"> <div class="header-right">
<span class="device-id">ID: {{ item.deviceId }}</span> <span class="device-id">{{ t('ReportDashboard.Dashboard1.deviceIdPrefix') }}{{ item.deviceId }}</span>
</div> </div>
</div> </div>
<div class="device-body"> <div class="device-body">
@ -80,7 +80,7 @@
</el-tag> </el-tag>
</div> </div>
<div class="header-right"> <div class="header-right">
<span class="device-id">ID: {{ item.deviceId }}</span> <span class="device-id">{{ t('ReportDashboard.Dashboard1.deviceIdPrefix') }}{{ item.deviceId }}</span>
</div> </div>
</div> </div>
<div class="device-body"> <div class="device-body">
@ -128,6 +128,7 @@ import ProductionTrend from './components/ProductionTrend.vue'
const route = useRoute() const route = useRoute()
const goviewId = route.query.goviewId as string const goviewId = route.query.goviewId as string
const orgId = route.query.orgId const orgId = route.query.orgId
const { t } = useI18n()
interface DeviceAttribute { interface DeviceAttribute {
attributeName: string attributeName: string
@ -164,7 +165,7 @@ const loadDeviceAttributes = async () => {
const cards: DeviceCardData[] = list.map((d: any) => { const cards: DeviceCardData[] = list.map((d: any) => {
return { return {
deviceName: d.deviceName || 'Device', deviceName: d.deviceName || t('ReportDashboard.Dashboard1.defaultDeviceName'),
deviceId: d.deviceId, deviceId: d.deviceId,
operatingStatus: d.operatingStatus, operatingStatus: d.operatingStatus,
attributes: (d.attributes || []).map((attr: any) => ({ attributes: (d.attributes || []).map((attr: any) => ({
@ -193,7 +194,7 @@ const getDeviceStatusType = (status?: string) => {
} }
const getDeviceStatusText = (status?: string) => { const getDeviceStatusText = (status?: string) => {
if (!status) return '离线' if (!status) return t('ReportDashboard.Dashboard1.statusOffline')
return status return status
} }

Loading…
Cancel
Save