Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
229594b1
authored
Feb 05, 2025
by
安浩浩
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【代码重构】IoT:重构插件配置管理,替换 PluginInfo 为 PluginConfig
parent
5d32cc38
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
84 additions
and
90 deletions
+84
-90
src/api/iot/plugin/index.ts
+20
-30
src/views/iot/plugin/PluginConfigForm.vue
+7
-7
src/views/iot/plugin/detail/PluginImportForm.vue
+1
-1
src/views/iot/plugin/detail/index.vue
+25
-28
src/views/iot/plugin/index.vue
+31
-24
No files found.
src/api/iot/plugin
info
/index.ts
→
src/api/iot/plugin/index.ts
View file @
229594b1
import
request
from
'@/config/axios'
// IoT 插件
信息
VO
export
interface
Plugin
Info
VO
{
// IoT 插件
配置
VO
export
interface
Plugin
Config
VO
{
id
:
number
// 主键ID
pluginKey
:
string
// 插件标识
name
:
string
// 插件名称
...
...
@@ -17,45 +17,35 @@ export interface PluginInfoVO {
script
:
string
// 插件脚本
}
// IoT 插件
信息
API
export
const
Plugin
Info
Api
=
{
// 查询IoT 插件
信息
分页
getPlugin
Info
Page
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/iot/plugin-
info
/page`
,
params
})
// IoT 插件
配置
API
export
const
Plugin
Config
Api
=
{
// 查询IoT 插件
配置
分页
getPlugin
Config
Page
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/iot/plugin-
config
/page`
,
params
})
},
// 查询IoT 插件
信息
详情
getPlugin
Info
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/iot/plugin-
info
/get?id=`
+
id
})
// 查询IoT 插件
配置
详情
getPlugin
Config
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/iot/plugin-
config
/get?id=`
+
id
})
},
// 新增IoT 插件
信息
createPlugin
Info
:
async
(
data
:
PluginInfo
VO
)
=>
{
return
await
request
.
post
({
url
:
`/iot/plugin-
info
/create`
,
data
})
// 新增IoT 插件
配置
createPlugin
Config
:
async
(
data
:
PluginConfig
VO
)
=>
{
return
await
request
.
post
({
url
:
`/iot/plugin-
config
/create`
,
data
})
},
// 修改IoT 插件
信息
updatePlugin
Info
:
async
(
data
:
PluginInfo
VO
)
=>
{
return
await
request
.
put
({
url
:
`/iot/plugin-
info
/update`
,
data
})
// 修改IoT 插件
配置
updatePlugin
Config
:
async
(
data
:
PluginConfig
VO
)
=>
{
return
await
request
.
put
({
url
:
`/iot/plugin-
config
/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 插件配置
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-info/update-status`
,
data
})
},
// 上传Jar包
uploadPluginFile
:
async
(
data
:
any
)
=>
{
return
await
request
.
post
({
url
:
`/iot/plugin-info/upload-file`
,
data
})
return
await
request
.
put
({
url
:
`/iot/plugin-config/update-status`
,
data
})
}
}
src/views/iot/plugin/Plugin
Info
Form.vue
→
src/views/iot/plugin/Plugin
Config
Form.vue
View file @
229594b1
...
...
@@ -29,10 +29,10 @@
</template>
<
script
setup
lang=
"ts"
>
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
Plugin
InfoApi
,
PluginInfoVO
}
from
'@/api/iot/plugininfo
'
import
{
Plugin
ConfigApi
,
PluginConfigVO
}
from
'@/api/iot/plugin
'
/** IoT 插件
信息
表单 */
defineOptions
({
name
:
'Plugin
Info
Form'
})
/** IoT 插件
配置
表单 */
defineOptions
({
name
:
'Plugin
Config
Form'
})
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
...
...
@@ -62,7 +62,7 @@ const open = async (type: string, id?: number) => {
if
(
id
)
{
formLoading
.
value
=
true
try
{
formData
.
value
=
await
Plugin
InfoApi
.
getPluginInfo
(
id
)
formData
.
value
=
await
Plugin
ConfigApi
.
getPluginConfig
(
id
)
}
finally
{
formLoading
.
value
=
false
}
...
...
@@ -78,12 +78,12 @@ const submitForm = async () => {
// 提交请求
formLoading
.
value
=
true
try
{
const
data
=
formData
.
value
as
unknown
as
Plugin
Info
VO
const
data
=
formData
.
value
as
unknown
as
Plugin
Config
VO
if
(
formType
.
value
===
'create'
)
{
await
Plugin
InfoApi
.
createPluginInfo
(
data
)
await
Plugin
ConfigApi
.
createPluginConfig
(
data
)
message
.
success
(
t
(
'common.createSuccess'
))
}
else
{
await
Plugin
InfoApi
.
updatePluginInfo
(
data
)
await
Plugin
ConfigApi
.
updatePluginConfig
(
data
)
message
.
success
(
t
(
'common.updateSuccess'
))
}
dialogVisible
.
value
=
false
...
...
src/views/iot/plugin/detail/PluginImportForm.vue
View file @
229594b1
...
...
@@ -36,7 +36,7 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const
formLoading
=
ref
(
false
)
// 表单的加载中
const
uploadRef
=
ref
()
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
fileList
=
ref
([])
// 文件列表
...
...
src/views/iot/plugin/detail/index.vue
View file @
229594b1
...
...
@@ -12,24 +12,25 @@
<ContentWrap
class=
"mt-10px"
>
<el-descriptions
:column=
"2"
direction=
"horizontal"
>
<el-descriptions-item
label=
"插件名称"
>
{{
plugin
Info
.
name
}}
{{
plugin
Config
.
name
}}
</el-descriptions-item>
<el-descriptions-item
label=
"插件标识"
>
{{
plugin
Info
.
pluginKey
}}
{{
plugin
Config
.
pluginKey
}}
</el-descriptions-item>
<el-descriptions-item
label=
"版本号"
>
{{
plugin
Info
.
version
}}
{{
plugin
Config
.
version
}}
</el-descriptions-item>
<el-descriptions-item
label=
"状态"
>
<el-switch
v-model=
"plugin
Info
.status"
v-model=
"plugin
Config
.status"
:active-value=
"1"
:inactive-value=
"0"
:disabled=
"pluginConfig.id
<
=
0
"
@
change=
"handleStatusChange"
/>
</el-descriptions-item>
<el-descriptions-item
label=
"插件描述"
>
{{
plugin
Info
.
description
}}
{{
plugin
Config
.
description
}}
</el-descriptions-item>
</el-descriptions>
</ContentWrap>
...
...
@@ -45,23 +46,22 @@
<!-- TODO @haohao:插件实例的前端展示:底部要不要加个分页,展示运行中的实力?默认勾选,只展示 state 为在线的 -->
<!-- 插件导入对话框 -->
<!-- TODO @haohao:Number 尽量不用。因为有用户会使用 snowflake、或者 string 的时候,会有问题 -->
<PluginImportForm
ref=
"importFormRef"
:id=
"
Number(pluginInfo.id)
"
@
success=
"getPlugin
Info(Number(pluginInfo.id)
)"
:id=
"
pluginConfig.id
"
@
success=
"getPlugin
Config(pluginConfig.id
)"
/>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
Plugin
InfoApi
,
PluginInfoVO
}
from
'@/api/iot/plugininfo
'
import
{
Plugin
ConfigApi
,
PluginConfigVO
}
from
'@/api/iot/plugin
'
import
{
useRoute
}
from
'vue-router'
import
{
onMounted
,
ref
}
from
'vue'
import
PluginImportForm
from
'./PluginImportForm.vue'
const
message
=
useMessage
()
const
route
=
useRoute
()
const
plugin
Info
=
ref
<
PluginInfo
VO
>
({
const
plugin
Config
=
ref
<
PluginConfig
VO
>
({
id
:
0
,
pluginKey
:
''
,
name
:
''
,
...
...
@@ -76,41 +76,30 @@ const pluginInfo = ref<PluginInfoVO>({
config
:
''
,
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
getPlugin
Info
=
async
(
id
:
number
)
=>
{
plugin
Info
.
value
=
await
PluginInfoApi
.
getPluginInfo
(
id
)
const
getPlugin
Config
=
async
(
id
:
number
)
=>
{
plugin
Config
.
value
=
await
PluginConfigApi
.
getPluginConfig
(
id
)
}
/** 处理状态变更 */
const
handleStatusChange
=
async
(
status
:
number
)
=>
{
if
(
isInitialLoad
.
value
)
{
if
(
pluginConfig
.
value
.
id
<=
0
)
{
return
}
try
{
// 修改状态的二次确认
const
text
=
status
===
1
?
'启用'
:
'停用'
await
message
.
confirm
(
'确认要"'
+
text
+
'"插件吗?'
)
await
Plugin
Info
Api
.
updatePluginStatus
({
id
:
plugin
Info
.
value
.
id
,
await
Plugin
Config
Api
.
updatePluginStatus
({
id
:
plugin
Config
.
value
.
id
,
status
})
message
.
success
(
'更新状态成功'
)
// 获取详情
await
getPlugin
Info
(
pluginInfo
.
value
.
id
)
await
getPlugin
Config
(
pluginConfig
.
value
.
id
)
}
catch
(
error
)
{
plugin
Info
.
value
.
status
=
status
===
1
?
0
:
1
plugin
Config
.
value
.
status
=
status
===
1
?
0
:
1
message
.
error
(
'更新状态失败'
)
}
}
...
...
@@ -120,4 +109,12 @@ const importFormRef = ref()
const
handleImport
=
()
=>
{
importFormRef
.
value
.
open
()
}
/** 初始化插件详情 */
onMounted
(()
=>
{
const
id
=
Number
(
route
.
params
.
id
)
if
(
id
)
{
getPluginConfig
(
id
)
}
})
</
script
>
src/views/iot/plugin/index.vue
View file @
229594b1
<!-- TODO @芋艿:增加一个【运维管理】,然后把插件放过去? -->
<
template
>
<ContentWrap>
<!-- 搜索工作栏 -->
...
...
@@ -51,7 +50,7 @@
type=
"primary"
plain
@
click=
"openForm('create')"
v-hasPermi=
"['iot:plugin-
info
:create']"
v-hasPermi=
"['iot:plugin-
config
:create']"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
新增
</el-button>
...
...
@@ -65,7 +64,7 @@
<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=
"pluginKey"
/>
<el-table-column
label=
"jar 包"
align=
"center"
prop=
"file"
/>
<el-table-column
label=
"jar 包"
align=
"center"
prop=
"file
Name
"
/>
<el-table-column
label=
"版本号"
align=
"center"
prop=
"version"
/>
<el-table-column
label=
"部署方式"
align=
"center"
prop=
"deployType"
>
<template
#
default=
"scope"
>
...
...
@@ -103,7 +102,7 @@
link
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['iot:plugin-
info
:update']"
v-hasPermi=
"['iot:plugin-
config
:update']"
>
编辑
</el-button>
...
...
@@ -111,7 +110,7 @@
link
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['iot:plugin-
info
:delete']"
v-hasPermi=
"['iot:plugin-
config
:delete']"
>
删除
</el-button>
...
...
@@ -133,6 +132,24 @@
<el-image
:src=
"defaultIconUrl"
class=
"w-[18px] h-[18px]"
/>
</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>
<!-- 信息区域 -->
...
...
@@ -156,16 +173,6 @@
<span
class=
"text-[#717c8e] mr-2.5"
>
部署方式
</span>
<dict-tag
:type=
"DICT_TYPE.IOT_PLUGIN_DEPLOY_TYPE"
:value=
"item.deployType"
/>
</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>
...
...
@@ -179,7 +186,7 @@
type=
"primary"
plain
@
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"
/>
编辑
...
...
@@ -220,23 +227,23 @@
</ContentWrap>
<!-- 表单弹窗:添加/修改 -->
<Plugin
Info
Form
ref=
"formRef"
@
success=
"getList"
/>
<Plugin
Config
Form
ref=
"formRef"
@
success=
"getList"
/>
</template>
<
script
setup
lang=
"ts"
>
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
{
Plugin
InfoApi
,
PluginInfoVO
}
from
'@/api/iot/plugininfo
'
import
Plugin
InfoForm
from
'./PluginInfo
Form.vue'
import
{
Plugin
ConfigApi
,
PluginConfigVO
}
from
'@/api/iot/plugin
'
import
Plugin
ConfigForm
from
'./PluginConfig
Form.vue'
/** IoT 插件
信息
列表 */
/** IoT 插件
配置
列表 */
defineOptions
({
name
:
'IoTPlugin'
})
const
message
=
useMessage
()
// 消息弹窗
const
{
t
}
=
useI18n
()
// 国际化
const
loading
=
ref
(
true
)
// 列表的加载中
const
list
=
ref
<
Plugin
Info
VO
[]
>
([])
// 列表的数据
const
list
=
ref
<
Plugin
Config
VO
[]
>
([])
// 列表的数据
const
total
=
ref
(
0
)
// 列表的总页数
const
queryParams
=
reactive
({
pageNo
:
1
,
...
...
@@ -252,7 +259,7 @@ const viewMode = ref<'card' | 'list'>('card') // 视图模式状态
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
Plugin
InfoApi
.
getPluginInfo
Page
(
queryParams
)
const
data
=
await
Plugin
ConfigApi
.
getPluginConfig
Page
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
...
...
@@ -290,7 +297,7 @@ const handleDelete = async (id: number) => {
// 删除的二次确认
await
message
.
delConfirm
()
// 发起删除
await
Plugin
InfoApi
.
deletePluginInfo
(
id
)
await
Plugin
ConfigApi
.
deletePluginConfig
(
id
)
message
.
success
(
t
(
'common.delSuccess'
))
// 刷新列表
await
getList
()
...
...
@@ -303,7 +310,7 @@ const handleStatusChange = async (id: number, status: number) => {
// 修改状态的二次确认
const
text
=
status
===
1
?
'启用'
:
'停用'
await
message
.
confirm
(
'确认要"'
+
text
+
'"插件吗?'
)
await
Plugin
Info
Api
.
updatePluginStatus
({
await
Plugin
Config
Api
.
updatePluginStatus
({
id
:
id
,
status
})
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment