|
|
|
|
@ -76,7 +76,12 @@
|
|
|
|
|
alt="封面图"
|
|
|
|
|
/>
|
|
|
|
|
<div class="dashboard-card-state">
|
|
|
|
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="item.state" />
|
|
|
|
|
<el-tag v-if="item.state === 1" type="success" size="small">
|
|
|
|
|
启用
|
|
|
|
|
</el-tag>
|
|
|
|
|
<el-tag v-else type="info" size="small">
|
|
|
|
|
禁用
|
|
|
|
|
</el-tag>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="dashboard-card-body">
|
|
|
|
|
@ -123,29 +128,53 @@
|
|
|
|
|
v-model="createDialogVisible"
|
|
|
|
|
:title="dialogMode === 'create' ? '新增数据大屏' : '编辑数据大屏'"
|
|
|
|
|
width="600px"
|
|
|
|
|
draggable
|
|
|
|
|
>
|
|
|
|
|
<el-form :model="createForm" ref="createFormRef" label-width="80px">
|
|
|
|
|
<el-form-item label="名称">
|
|
|
|
|
<el-form :model="createForm" ref="createFormRef" label-width="80px" :rules="createFormRules">
|
|
|
|
|
<el-form-item label="名称" prop="name">
|
|
|
|
|
<el-input v-model="createForm.name" placeholder="请输入名称" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="备注">
|
|
|
|
|
<el-input v-model="createForm.remark" placeholder="请输入备注" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="启用状态">
|
|
|
|
|
<el-select v-model="createForm.state" placeholder="请选择启用状态" class="!w-240px">
|
|
|
|
|
<el-form-item label="大屏类型" prop="type">
|
|
|
|
|
<el-select v-model="createForm.type" placeholder="请选择大屏类型" class="!w-240px">
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="dict in getStrDictOptions(DICT_TYPE.COMMON_STATUS)"
|
|
|
|
|
v-for="dict in getStrDictOptions('mes_goview_type')"
|
|
|
|
|
:key="dict.value"
|
|
|
|
|
:label="dict.label"
|
|
|
|
|
:value="dict.value"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="图片路径">
|
|
|
|
|
<el-input v-model="createForm.indexImage" placeholder="请输入图片路径" />
|
|
|
|
|
<el-form-item label="产线" prop="orgId">
|
|
|
|
|
<el-tree-select
|
|
|
|
|
v-model="createForm.orgId"
|
|
|
|
|
:data="organizationTree"
|
|
|
|
|
:props="lineTreeProps"
|
|
|
|
|
filterable
|
|
|
|
|
clearable
|
|
|
|
|
class="!w-240px"
|
|
|
|
|
placeholder="请选择产线"
|
|
|
|
|
@change="handleOrgChange"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="路由路径">
|
|
|
|
|
<el-input v-model="createForm.route" placeholder="请输入路由路径" />
|
|
|
|
|
<el-form-item label="设备" v-if="createForm.type === '1'">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="selectedDeviceIds"
|
|
|
|
|
multiple
|
|
|
|
|
:multiple-limit="8"
|
|
|
|
|
collapse-tags
|
|
|
|
|
collapse-tags-tooltip
|
|
|
|
|
placeholder="请选择设备(必须选择8个)"
|
|
|
|
|
clearable
|
|
|
|
|
filterable
|
|
|
|
|
class="!w-240px"
|
|
|
|
|
>
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in deviceList"
|
|
|
|
|
:key="item.id"
|
|
|
|
|
:label="item.deviceName"
|
|
|
|
|
:value="String(item.id)"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="内容">
|
|
|
|
|
<el-input
|
|
|
|
|
@ -155,6 +184,16 @@
|
|
|
|
|
placeholder="请输入内容"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="备注">
|
|
|
|
|
<el-input v-model="createForm.remark" placeholder="请输入备注" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="启用状态">
|
|
|
|
|
<el-switch
|
|
|
|
|
v-model="createForm.state"
|
|
|
|
|
:active-value="1"
|
|
|
|
|
:inactive-value="0"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<template #footer>
|
|
|
|
|
<el-button @click="createDialogVisible = false">取 消</el-button>
|
|
|
|
|
@ -169,20 +208,27 @@
|
|
|
|
|
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
|
|
|
|
import request from '@/config/axios'
|
|
|
|
|
import defaultImage from '@/assets/imgs/logo.png'
|
|
|
|
|
import { OrganizationApi } from '@/api/mes/organization'
|
|
|
|
|
import { handleTree } from '@/utils/tree'
|
|
|
|
|
import { DeviceApi } from '@/api/iot/device'
|
|
|
|
|
|
|
|
|
|
defineOptions({ name: 'DashboardList' })
|
|
|
|
|
|
|
|
|
|
const { push } = useRouter()
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
const message = useMessage()
|
|
|
|
|
|
|
|
|
|
interface DashboardItem {
|
|
|
|
|
id: number
|
|
|
|
|
name: string
|
|
|
|
|
remark: string
|
|
|
|
|
state: string
|
|
|
|
|
state: number
|
|
|
|
|
indexImage?: string
|
|
|
|
|
route?: string
|
|
|
|
|
content?: string
|
|
|
|
|
type?: string
|
|
|
|
|
orgId?: number | string
|
|
|
|
|
orgName?: string
|
|
|
|
|
deviceIds?: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
@ -207,12 +253,32 @@ const editingId = ref<number | null>(null)
|
|
|
|
|
const createForm = reactive({
|
|
|
|
|
name: '',
|
|
|
|
|
remark: '',
|
|
|
|
|
state: '',
|
|
|
|
|
state: 1,
|
|
|
|
|
type: '',
|
|
|
|
|
orgId: undefined as number | string | undefined,
|
|
|
|
|
orgName: '',
|
|
|
|
|
deviceIds: '',
|
|
|
|
|
indexImage: '',
|
|
|
|
|
route: '',
|
|
|
|
|
content: ''
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const createFormRules = reactive({
|
|
|
|
|
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
|
|
|
|
|
type: [{ required: true, message: '大屏类型不能为空', trigger: 'change' }],
|
|
|
|
|
orgId: [{ required: true, message: '产线不能为空', trigger: 'change' }]
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const organizationTree = ref<any[]>([])
|
|
|
|
|
const lineTreeProps = {
|
|
|
|
|
label: 'name',
|
|
|
|
|
children: 'children',
|
|
|
|
|
value: 'id'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const deviceList = ref<any[]>([])
|
|
|
|
|
const selectedDeviceIds = ref<string[]>([])
|
|
|
|
|
|
|
|
|
|
const getList = async () => {
|
|
|
|
|
loading.value = true
|
|
|
|
|
try {
|
|
|
|
|
@ -238,21 +304,33 @@ const resetQuery = () => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handlePreview = (item: DashboardItem) => {
|
|
|
|
|
if (!item.route) {
|
|
|
|
|
const typeRoute = getRouteByType(item.type)
|
|
|
|
|
const route = typeRoute || item.route || ''
|
|
|
|
|
if (!route) {
|
|
|
|
|
message.error('未配置预览路由')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const path = item.route.startsWith('/') ? item.route : `/${item.route}`
|
|
|
|
|
push(path)
|
|
|
|
|
const path = route.startsWith('/') ? route : `/${route}`
|
|
|
|
|
const queryParams = new URLSearchParams()
|
|
|
|
|
if (item.orgId) queryParams.append('orgId', String(item.orgId))
|
|
|
|
|
if (item.type === '1' && item.deviceIds) queryParams.append('deviceIds', item.deviceIds)
|
|
|
|
|
const queryString = queryParams.toString()
|
|
|
|
|
const url = router.resolve(path + (queryString ? `?${queryString}` : '')).href
|
|
|
|
|
window.open(url, '_blank')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const resetCreateForm = () => {
|
|
|
|
|
createForm.name = ''
|
|
|
|
|
createForm.remark = ''
|
|
|
|
|
createForm.state = ''
|
|
|
|
|
createForm.state = 1
|
|
|
|
|
createForm.type = ''
|
|
|
|
|
createForm.orgId = undefined
|
|
|
|
|
createForm.orgName = ''
|
|
|
|
|
createForm.deviceIds = ''
|
|
|
|
|
createForm.indexImage = ''
|
|
|
|
|
createForm.route = ''
|
|
|
|
|
createForm.content = ''
|
|
|
|
|
selectedDeviceIds.value = []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const openCreateDialog = () => {
|
|
|
|
|
@ -267,18 +345,55 @@ const openEditDialog = (item: DashboardItem) => {
|
|
|
|
|
editingId.value = item.id
|
|
|
|
|
createForm.name = item.name || ''
|
|
|
|
|
createForm.remark = item.remark || ''
|
|
|
|
|
createForm.state = item.state || ''
|
|
|
|
|
createForm.state = item.state
|
|
|
|
|
createForm.type = item.type || ''
|
|
|
|
|
createForm.orgId = item.orgId || undefined
|
|
|
|
|
createForm.orgName = item.orgName || ''
|
|
|
|
|
createForm.deviceIds = item.deviceIds || ''
|
|
|
|
|
createForm.indexImage = item.indexImage || ''
|
|
|
|
|
createForm.route = item.route || ''
|
|
|
|
|
createForm.content = item.content || ''
|
|
|
|
|
selectedDeviceIds.value = createForm.deviceIds
|
|
|
|
|
? createForm.deviceIds.split(',').filter((v) => v)
|
|
|
|
|
: []
|
|
|
|
|
createDialogVisible.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getRouteByType = (type?: string) => {
|
|
|
|
|
if (type === '1') return 'iot/report/dashboardPage/Dashboard1'
|
|
|
|
|
if (type === '2') return 'iot/report/dashboardPage/Dashboard8'
|
|
|
|
|
return ''
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const submitDialog = async () => {
|
|
|
|
|
if (!createForm.name) {
|
|
|
|
|
message.error('名称不能为空')
|
|
|
|
|
try {
|
|
|
|
|
await createFormRef.value?.validate()
|
|
|
|
|
} catch {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (createForm.type === '1') {
|
|
|
|
|
if (!selectedDeviceIds.value.length) {
|
|
|
|
|
message.error('设备不能为空')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (selectedDeviceIds.value.length !== 8) {
|
|
|
|
|
message.error('设备必须选择8个')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
createForm.deviceIds = selectedDeviceIds.value.join(',')
|
|
|
|
|
} else {
|
|
|
|
|
createForm.deviceIds = ''
|
|
|
|
|
}
|
|
|
|
|
if (createForm.orgId) {
|
|
|
|
|
const org = findOrgNode(organizationTree.value || [], createForm.orgId)
|
|
|
|
|
createForm.orgName = org?.name || ''
|
|
|
|
|
} else {
|
|
|
|
|
createForm.orgName = ''
|
|
|
|
|
}
|
|
|
|
|
const route = getRouteByType(createForm.type)
|
|
|
|
|
if (route) {
|
|
|
|
|
createForm.route = route
|
|
|
|
|
}
|
|
|
|
|
if (dialogMode.value === 'edit' && !editingId.value) {
|
|
|
|
|
message.error('缺少数据编号,无法编辑')
|
|
|
|
|
return
|
|
|
|
|
@ -320,8 +435,38 @@ const handleDelete = async (item: DashboardItem) => {
|
|
|
|
|
} catch {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const loadOrganizationTree = async () => {
|
|
|
|
|
const data = await OrganizationApi.getOrganizationList()
|
|
|
|
|
organizationTree.value = handleTree(data, 'id', 'parentId')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const findOrgNode = (nodes: any[], id: any): any | undefined => {
|
|
|
|
|
for (const node of nodes) {
|
|
|
|
|
if (String(node.id) === String(id)) return node
|
|
|
|
|
const children = Array.isArray(node.children) ? node.children : []
|
|
|
|
|
const found = findOrgNode(children, id)
|
|
|
|
|
if (found) return found
|
|
|
|
|
}
|
|
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleOrgChange = () => {
|
|
|
|
|
if (!createForm.orgId) {
|
|
|
|
|
createForm.orgName = ''
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const org = findOrgNode(organizationTree.value || [], createForm.orgId)
|
|
|
|
|
createForm.orgName = org?.name || ''
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const loadDeviceList = async () => {
|
|
|
|
|
deviceList.value = await DeviceApi.getDeviceList()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getList()
|
|
|
|
|
loadOrganizationTree()
|
|
|
|
|
loadDeviceList()
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|