【代码重构】IoT:重构插件配置管理,替换 PluginInfo 为 PluginConfig

This commit is contained in:
安浩浩 2025-02-05 23:02:06 +08:00
parent 5d32cc3821
commit 229594b159
6 changed files with 116 additions and 122 deletions

View File

@ -0,0 +1,51 @@
import request from '@/config/axios'
// IoT 插件配置 VO
export interface PluginConfigVO {
id: number // 主键ID
pluginKey: string // 插件标识
name: string // 插件名称
description: string // 描述
deployType: number // 部署方式
fileName: string // 插件包文件名
version: string // 插件版本
type: number // 插件类型
protocol: string // 设备插件协议类型
status: number // 状态
configSchema: string // 插件配置项描述信息
config: string // 插件配置信息
script: string // 插件脚本
}
// IoT 插件配置 API
export const PluginConfigApi = {
// 查询IoT 插件配置分页
getPluginConfigPage: async (params: any) => {
return await request.get({ url: `/iot/plugin-config/page`, params })
},
// 查询IoT 插件配置详情
getPluginConfig: async (id: number) => {
return await request.get({ url: `/iot/plugin-config/get?id=` + id })
},
// 新增IoT 插件配置
createPluginConfig: async (data: PluginConfigVO) => {
return await request.post({ url: `/iot/plugin-config/create`, data })
},
// 修改IoT 插件配置
updatePluginConfig: async (data: PluginConfigVO) => {
return await request.put({ url: `/iot/plugin-config/update`, data })
},
// 删除IoT 插件配置
deletePluginConfig: async (id: number) => {
return await request.delete({ url: `/iot/plugin-config/delete?id=` + id })
},
// 修改IoT 插件状态
updatePluginStatus: async (data: any) => {
return await request.put({ url: `/iot/plugin-config/update-status`, data })
}
}

View File

@ -1,61 +0,0 @@
import request from '@/config/axios'
// IoT 插件信息 VO
export interface PluginInfoVO {
id: number // 主键ID
pluginKey: string // 插件标识
name: string // 插件名称
description: string // 描述
deployType: number // 部署方式
fileName: string // 插件包文件名
version: string // 插件版本
type: number // 插件类型
protocol: string // 设备插件协议类型
status: number // 状态
configSchema: string // 插件配置项描述信息
config: string // 插件配置信息
script: string // 插件脚本
}
// IoT 插件信息 API
export const PluginInfoApi = {
// 查询IoT 插件信息分页
getPluginInfoPage: async (params: any) => {
return await request.get({ url: `/iot/plugin-info/page`, params })
},
// 查询IoT 插件信息详情
getPluginInfo: async (id: number) => {
return await request.get({ url: `/iot/plugin-info/get?id=` + id })
},
// 新增IoT 插件信息
createPluginInfo: async (data: PluginInfoVO) => {
return await request.post({ url: `/iot/plugin-info/create`, data })
},
// 修改IoT 插件信息
updatePluginInfo: async (data: PluginInfoVO) => {
return await request.put({ url: `/iot/plugin-info/update`, data })
},
// 删除IoT 插件信息
deletePluginInfo: async (id: number) => {
return await request.delete({ url: `/iot/plugin-info/delete?id=` + id })
},
// 导出IoT 插件信息 Excel
exportPluginInfo: async (params) => {
return await request.download({ url: `/iot/plugin-info/export-excel`, params })
},
// 修改IoT 插件状态
updatePluginStatus: async (data: any) => {
return await request.put({ url: `/iot/plugin-info/update-status`, data })
},
// 上传Jar包
uploadPluginFile: async (data: any) => {
return await request.post({ url: `/iot/plugin-info/upload-file`, data })
}
}

View File

@ -29,10 +29,10 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { PluginInfoApi, PluginInfoVO } from '@/api/iot/plugininfo' import { PluginConfigApi, PluginConfigVO } from '@/api/iot/plugin'
/** IoT 插件信息 表单 */ /** IoT 插件配置 表单 */
defineOptions({ name: 'PluginInfoForm' }) defineOptions({ name: 'PluginConfigForm' })
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //
@ -62,7 +62,7 @@ const open = async (type: string, id?: number) => {
if (id) { if (id) {
formLoading.value = true formLoading.value = true
try { try {
formData.value = await PluginInfoApi.getPluginInfo(id) formData.value = await PluginConfigApi.getPluginConfig(id)
} finally { } finally {
formLoading.value = false formLoading.value = false
} }
@ -78,12 +78,12 @@ const submitForm = async () => {
// //
formLoading.value = true formLoading.value = true
try { try {
const data = formData.value as unknown as PluginInfoVO const data = formData.value as unknown as PluginConfigVO
if (formType.value === 'create') { if (formType.value === 'create') {
await PluginInfoApi.createPluginInfo(data) await PluginConfigApi.createPluginConfig(data)
message.success(t('common.createSuccess')) message.success(t('common.createSuccess'))
} else { } else {
await PluginInfoApi.updatePluginInfo(data) await PluginConfigApi.updatePluginConfig(data)
message.success(t('common.updateSuccess')) message.success(t('common.updateSuccess'))
} }
dialogVisible.value = false dialogVisible.value = false

View File

@ -36,7 +36,7 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const formLoading = ref(false) // const formLoading = ref(false) //
const uploadRef = ref() const uploadRef = ref()
const importUrl = const importUrl =
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/iot/plugin-info/upload-file' import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/iot/plugin-config/upload-file'
const uploadHeaders = ref() // Header const uploadHeaders = ref() // Header
const fileList = ref([]) // const fileList = ref([]) //

View File

@ -12,24 +12,25 @@
<ContentWrap class="mt-10px"> <ContentWrap class="mt-10px">
<el-descriptions :column="2" direction="horizontal"> <el-descriptions :column="2" direction="horizontal">
<el-descriptions-item label="插件名称"> <el-descriptions-item label="插件名称">
{{ pluginInfo.name }} {{ pluginConfig.name }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="插件标识"> <el-descriptions-item label="插件标识">
{{ pluginInfo.pluginKey }} {{ pluginConfig.pluginKey }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="版本号"> <el-descriptions-item label="版本号">
{{ pluginInfo.version }} {{ pluginConfig.version }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="状态"> <el-descriptions-item label="状态">
<el-switch <el-switch
v-model="pluginInfo.status" v-model="pluginConfig.status"
:active-value="1" :active-value="1"
:inactive-value="0" :inactive-value="0"
:disabled="pluginConfig.id <= 0"
@change="handleStatusChange" @change="handleStatusChange"
/> />
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="插件描述"> <el-descriptions-item label="插件描述">
{{ pluginInfo.description }} {{ pluginConfig.description }}
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
</ContentWrap> </ContentWrap>
@ -45,23 +46,22 @@
<!-- TODO @haohao插件实例的前端展示底部要不要加个分页展示运行中的实力默认勾选只展示 state 为在线的 --> <!-- TODO @haohao插件实例的前端展示底部要不要加个分页展示运行中的实力默认勾选只展示 state 为在线的 -->
<!-- 插件导入对话框 --> <!-- 插件导入对话框 -->
<!-- TODO @haohaoNumber 尽量不用因为有用户会使用 snowflake或者 string 的时候会有问题 -->
<PluginImportForm <PluginImportForm
ref="importFormRef" ref="importFormRef"
:id="Number(pluginInfo.id)" :id="pluginConfig.id"
@success="getPluginInfo(Number(pluginInfo.id))" @success="getPluginConfig(pluginConfig.id)"
/> />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { PluginInfoApi, PluginInfoVO } from '@/api/iot/plugininfo' import { PluginConfigApi, PluginConfigVO } from '@/api/iot/plugin'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import PluginImportForm from './PluginImportForm.vue' import PluginImportForm from './PluginImportForm.vue'
const message = useMessage() const message = useMessage()
const route = useRoute() const route = useRoute()
const pluginInfo = ref<PluginInfoVO>({ const pluginConfig = ref<PluginConfigVO>({
id: 0, id: 0,
pluginKey: '', pluginKey: '',
name: '', name: '',
@ -76,41 +76,30 @@ const pluginInfo = ref<PluginInfoVO>({
config: '', config: '',
script: '' script: ''
}) })
// TODO @haohao pluginInfo.id > 0 handleStatusChange disable
const isInitialLoad = ref(true) //
onMounted(() => {
const id = Number(route.params.id)
if (id) {
getPluginInfo(id).then(() => {
isInitialLoad.value = false // false
})
}
})
/** 获取插件详情 */ /** 获取插件详情 */
const getPluginInfo = async (id: number) => { const getPluginConfig = async (id: number) => {
pluginInfo.value = await PluginInfoApi.getPluginInfo(id) pluginConfig.value = await PluginConfigApi.getPluginConfig(id)
} }
/** 处理状态变更 */ /** 处理状态变更 */
const handleStatusChange = async (status: number) => { const handleStatusChange = async (status: number) => {
if (isInitialLoad.value) { if (pluginConfig.value.id <= 0) {
return return
} }
try { try {
// //
const text = status === 1 ? '启用' : '停用' const text = status === 1 ? '启用' : '停用'
await message.confirm('确认要"' + text + '"插件吗?') await message.confirm('确认要"' + text + '"插件吗?')
await PluginInfoApi.updatePluginStatus({ await PluginConfigApi.updatePluginStatus({
id: pluginInfo.value.id, id: pluginConfig.value.id,
status status
}) })
message.success('更新状态成功') message.success('更新状态成功')
// //
await getPluginInfo(pluginInfo.value.id) await getPluginConfig(pluginConfig.value.id)
} catch (error) { } catch (error) {
pluginInfo.value.status = status === 1 ? 0 : 1 pluginConfig.value.status = status === 1 ? 0 : 1
message.error('更新状态失败') message.error('更新状态失败')
} }
} }
@ -120,4 +109,12 @@ const importFormRef = ref()
const handleImport = () => { const handleImport = () => {
importFormRef.value.open() importFormRef.value.open()
} }
/** 初始化插件详情 */
onMounted(() => {
const id = Number(route.params.id)
if (id) {
getPluginConfig(id)
}
})
</script> </script>

View File

@ -1,4 +1,3 @@
<!-- TODO @芋艿增加一个运维管理然后把插件放过去 -->
<template> <template>
<ContentWrap> <ContentWrap>
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
@ -51,7 +50,7 @@
type="primary" type="primary"
plain plain
@click="openForm('create')" @click="openForm('create')"
v-hasPermi="['iot:plugin-info:create']" v-hasPermi="['iot:plugin-config:create']"
> >
<Icon icon="ep:plus" class="mr-5px" /> 新增 <Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button> </el-button>
@ -65,7 +64,7 @@
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="插件名称" align="center" prop="name" /> <el-table-column label="插件名称" align="center" prop="name" />
<el-table-column label="插件标识" align="center" prop="pluginKey" /> <el-table-column label="插件标识" align="center" prop="pluginKey" />
<el-table-column label="jar 包" align="center" prop="file" /> <el-table-column label="jar 包" align="center" prop="fileName" />
<el-table-column label="版本号" align="center" prop="version" /> <el-table-column label="版本号" align="center" prop="version" />
<el-table-column label="部署方式" align="center" prop="deployType"> <el-table-column label="部署方式" align="center" prop="deployType">
<template #default="scope"> <template #default="scope">
@ -103,7 +102,7 @@
link link
type="primary" type="primary"
@click="openForm('update', scope.row.id)" @click="openForm('update', scope.row.id)"
v-hasPermi="['iot:plugin-info:update']" v-hasPermi="['iot:plugin-config:update']"
> >
编辑 编辑
</el-button> </el-button>
@ -111,7 +110,7 @@
link link
type="danger" type="danger"
@click="handleDelete(scope.row.id)" @click="handleDelete(scope.row.id)"
v-hasPermi="['iot:plugin-info:delete']" v-hasPermi="['iot:plugin-config:delete']"
> >
删除 删除
</el-button> </el-button>
@ -133,6 +132,24 @@
<el-image :src="defaultIconUrl" class="w-[18px] h-[18px]" /> <el-image :src="defaultIconUrl" class="w-[18px] h-[18px]" />
</div> </div>
<div class="text-[16px] font-600 flex-1">{{ item.name }}</div> <div class="text-[16px] font-600 flex-1">{{ item.name }}</div>
<!-- 添加插件状态标签 -->
<div class="inline-flex items-center">
<div
class="w-1 h-1 rounded-full mr-1.5"
:class="
item.status === 1
? 'bg-[var(--el-color-success)]'
: 'bg-[var(--el-color-danger)]'
"
>
</div>
<el-text
class="!text-xs font-bold"
:type="item.status === 1 ? 'success' : 'danger'"
>
{{ item.status === 1 ? '开启' : '禁用' }}
</el-text>
</div>
</div> </div>
<!-- 信息区域 --> <!-- 信息区域 -->
@ -156,16 +173,6 @@
<span class="text-[#717c8e] mr-2.5">部署方式</span> <span class="text-[#717c8e] mr-2.5">部署方式</span>
<dict-tag :type="DICT_TYPE.IOT_PLUGIN_DEPLOY_TYPE" :value="item.deployType" /> <dict-tag :type="DICT_TYPE.IOT_PLUGIN_DEPLOY_TYPE" :value="item.deployType" />
</div> </div>
<!-- TODO @haohao这里状态要不去掉变成1通过颜色区分开启禁用类似 device 上线状态2开启禁用操作放到下面的按钮3 个一排好看电 -->
<div class="mb-2.5 last:mb-0">
<span class="text-[#717c8e] mr-2.5">状态</span>
<el-switch
v-model="item.status"
:active-value="1"
:inactive-value="0"
@change="handleStatusChange(item.id, Number($event))"
/>
</div>
</div> </div>
</div> </div>
@ -179,7 +186,7 @@
type="primary" type="primary"
plain plain
@click="openForm('update', item.id)" @click="openForm('update', item.id)"
v-hasPermi="['iot:plugin-info:update']" v-hasPermi="['iot:plugin-config:update']"
> >
<Icon icon="ep:edit-pen" class="mr-1" /> <Icon icon="ep:edit-pen" class="mr-1" />
编辑 编辑
@ -220,23 +227,23 @@
</ContentWrap> </ContentWrap>
<!-- 表单弹窗添加/修改 --> <!-- 表单弹窗添加/修改 -->
<PluginInfoForm ref="formRef" @success="getList" /> <PluginConfigForm ref="formRef" @success="getList" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime' import { dateFormatter } from '@/utils/formatTime'
import { PluginInfoApi, PluginInfoVO } from '@/api/iot/plugininfo' import { PluginConfigApi, PluginConfigVO } from '@/api/iot/plugin'
import PluginInfoForm from './PluginInfoForm.vue' import PluginConfigForm from './PluginConfigForm.vue'
/** IoT 插件信息 列表 */ /** IoT 插件配置 列表 */
defineOptions({ name: 'IoTPlugin' }) defineOptions({ name: 'IoTPlugin' })
const message = useMessage() // const message = useMessage() //
const { t } = useI18n() // const { t } = useI18n() //
const loading = ref(true) // const loading = ref(true) //
const list = ref<PluginInfoVO[]>([]) // const list = ref<PluginConfigVO[]>([]) //
const total = ref(0) // const total = ref(0) //
const queryParams = reactive({ const queryParams = reactive({
pageNo: 1, pageNo: 1,
@ -252,7 +259,7 @@ const viewMode = ref<'card' | 'list'>('card') // 视图模式状态
const getList = async () => { const getList = async () => {
loading.value = true loading.value = true
try { try {
const data = await PluginInfoApi.getPluginInfoPage(queryParams) const data = await PluginConfigApi.getPluginConfigPage(queryParams)
list.value = data.list list.value = data.list
total.value = data.total total.value = data.total
} finally { } finally {
@ -290,7 +297,7 @@ const handleDelete = async (id: number) => {
// //
await message.delConfirm() await message.delConfirm()
// //
await PluginInfoApi.deletePluginInfo(id) await PluginConfigApi.deletePluginConfig(id)
message.success(t('common.delSuccess')) message.success(t('common.delSuccess'))
// //
await getList() await getList()
@ -303,7 +310,7 @@ const handleStatusChange = async (id: number, status: number) => {
// //
const text = status === 1 ? '启用' : '停用' const text = status === 1 ? '启用' : '停用'
await message.confirm('确认要"' + text + '"插件吗?') await message.confirm('确认要"' + text + '"插件吗?')
await PluginInfoApi.updatePluginStatus({ await PluginConfigApi.updatePluginStatus({
id: id, id: id,
status status
}) })