houzhongjian
2024-11-27 9e876a11f6f0b384d4b1f0a60e066944dbcdeaa5
提交 | 用户 | 时间
24d32b 1 <template>
2   <el-drawer
3     v-model="drawer"
ebf2c1 4     size="60%"
24d32b 5     title="Opcua Tag"
6     :direction="direction"
7     :before-close="handleClose"
8   >
9     <!-- 搜索 -->
10     <ContentWrap>
11       <el-form
12         class="-mb-15px"
13         :model="queryParams"
14         ref="queryFormRef"
15         :inline="true"
16         label-width="68px"
17       >
18         <el-form-item label="Tag名称" prop="tagName">
19           <el-input
20             v-model="queryParams.tagName"
21             placeholder="请输入Tag名称"
22             clearable
23             @keyup.enter="handleQuery"
24             class="!w-240px"
25           />
26         </el-form-item>
27         <el-form-item label="地址" prop="address">
28           <el-input
29             v-model="queryParams.address"
30             placeholder="请输入地址"
31             clearable
32             @keyup.enter="handleQuery"
33             class="!w-240px"
34           />
35         </el-form-item>
36         <el-form-item>
37           <el-button @click="handleQuery">
38             <Icon icon="ep:search" class="mr-5px" />
39             搜索
40           </el-button>
41           <el-button @click="resetQuery">
42             <Icon icon="ep:refresh" class="mr-5px" />
43             重置
44           </el-button>
45           <el-button
46             type="primary"
47             plain
48             @click="openForm('create')"
49             v-hasPermi="['data:channel-opcua:create']"
50           >
51             <Icon icon="ep:plus" class="mr-5px" />
52             新增
53           </el-button>
6c2636 54           <el-button
J 55             type="warning"
56             plain
57             @click="handleImport"
58             v-hasPermi="['data:channel-opcua-tag:import']">
59             <Icon icon="ep:upload" /> 导入
60           </el-button>
61           <el-button
62             type="success"
63             plain
64             @click="handleExport"
65             :loading="exportLoading"
66             v-hasPermi="['data:channel-opcua-tag:export']">
67             <Icon icon="ep:download" />导出
68           </el-button>
24d32b 69         </el-form-item>
e1e013 70         <el-form-item label="更新当前值" label-width="100px">
D 71           <el-switch
72             v-model="queryParams.currentValue"
73             active-color="#13ce66"
74             inactive-color="#ff4949"/>
75         </el-form-item>
24d32b 76       </el-form>
77     </ContentWrap>
78     <!-- 列表 -->
79     <ContentWrap>
80       <el-table v-loading="loading" :data="list">
81         <el-table-column
82           prop="tagName"
83           label="Tag名称"
84           header-align="center"
85           align="left"
86           min-width="150"
87         />
88         <el-table-column
89           prop="dataType"
90           label="数据类型"
91           header-align="center"
92           align="center"
93         />
94         <el-table-column
95           prop="address"
96           label="地址"
97           header-align="center"
98           align="center"
99         />
100         <el-table-column
101           prop="samplingRate"
102           label="采集频率"
103           header-align="center"
104           align="center"
105         />
106         <el-table-column
107           prop="enabled"
108           label="是否启用"
109           header-align="center"
110           align="center"
111         >
112           <template #default="scope">
6c2636 113             <el-tag v-if="scope.row.enabled === 1" size="small">是</el-tag>
24d32b 114             <el-tag v-else size="small" type="danger">否</el-tag>
115           </template>
116         </el-table-column>
93ce03 117         <el-table-column
D 118           prop="dataValue"
119           label="数据值"
120           header-align="center"
121           align="center"
ebf2c1 122           min-width="100"
93ce03 123           :formatter="(row) => {if (row.dataValue === -2.0) {return '--';}return row.dataValue;}"
D 124         />
125         <el-table-column
ebf2c1 126           prop="dataTime"
127           label="数据时间"
128           header-align="center"
129           align="center"
130           min-width="150"
131         />
132         <el-table-column
133           prop="dataQuality"
93ce03 134           label="数据质量"
D 135           header-align="center"
136           align="center"
ebf2c1 137         />
24d32b 138         <el-table-column label="操作" align="center" min-width="110" fixed="right">
139           <template #default="scope">
140             <el-button
141               link
142               type="primary"
143               @click="openForm('update', scope.row.id)"
144               v-hasPermi="['data:channel-opcua:update']"
145             >
146               编辑
147             </el-button>
148             <el-button
149               link
150               type="danger"
151               @click="handleDelete(scope.row.id)"
152               v-hasPermi="['data:channel-opcua:delete']"
153             >
154               删除
155             </el-button>
156           </template>
157         </el-table-column>
158       </el-table>
159       <!-- 分页 -->
160       <Pagination
161         :total="total"
162         v-model:page="queryParams.pageNo"
163         v-model:limit="queryParams.pageSize"
164         @pagination="getList"
165       />
166     </ContentWrap>
167     <!-- 表单弹窗:添加/修改 -->
168     <TagForm ref="formRef" @success="getList" />
6c2636 169     <TagImportForm ref="importFormRef" @success="getList" />
24d32b 170   </el-drawer>
171 </template>
172 <script lang="ts" setup>
173   import type { DrawerProps } from 'element-plus'
6c2636 174   import * as OpcUaTagApi from "@/api/data/channel/opcua/tag";
24d32b 175   import TagForm from './TagForm.vue'
6c2636 176   import download from "@/utils/download";
050ddd 177   import {ref, reactive, onMounted, onBeforeUnmount} from "vue";
6c2636 178   import TagImportForm from '../../common/tag/TagImportForm.vue'
050ddd 179   import * as OpcdaTagApi from "@/api/data/channel/opcda/tag";
24d32b 180
181   defineOptions({name: 'OpcuaTag'})
182
183   const message = useMessage() // 消息弹窗
184   const {t} = useI18n() // 国际化
185
186   const drawer = ref(false)
187   const direction = ref<DrawerProps['direction']>('rtl')
188   const loading = ref(true) // 列表的加载中
189   const total = ref(0) // 列表的总页数
190   const list = ref([]) // 列表的数据
191   const queryParams = reactive({
192     pageNo: 1,
193     pageSize: 10,
194     device: undefined,
93ce03 195     deviceId: undefined,
24d32b 196     tagName: undefined,
050ddd 197     currentValue:false,
24d32b 198     address: undefined
199   })
200   const queryFormRef = ref() // 搜索的表单
201   const exportLoading = ref(false) // 导出的加载中
202
203   /** 查询列表 */
204   const getList = async () => {
205     loading.value = true
206     try {
6c2636 207       const page = await OpcUaTagApi.getOpcuaTagPage(queryParams)
24d32b 208       list.value = page.list
209       total.value = page.total
210     } finally {
211       loading.value = false
212     }
213   }
214
215   /** 搜索按钮操作 */
216   const handleQuery = () => {
217     queryParams.pageNo = 1
218     getList()
219   }
220
221   /** 重置按钮操作 */
222   const resetQuery = () => {
223     queryFormRef.value.resetFields()
224     handleQuery()
225   }
226
227   /** 添加/修改操作 */
228   const formRef = ref()
229   const openForm = (type: string, id?: number) => {
230     formRef.value.open(type, id, queryParams.device)
231   }
232
233   /** 删除按钮操作 */
234   const handleDelete = async (id: number) => {
235     try {
236       // 删除的二次确认
237       await message.delConfirm()
238       // 发起删除
6c2636 239       await OpcUaTagApi.deleteOpcuaTag(id)
24d32b 240       message.success(t('common.delSuccess'))
241       // 刷新列表
242       await getList()
243     } catch {
244     }
245   }
246
247   /** 打开弹窗 */
93ce03 248   const open = async (deviceId?: string,device?: string) => {
24d32b 249     resetForm()
250     drawer.value = true
251     queryParams.device = device
93ce03 252     queryParams.deviceId = deviceId
24d32b 253     if (device) {
254       getList()
255     }
256   }
257   defineExpose({open}) // 提供 open 方法,用于打开弹窗
258
259   /** 重置表单 */
260   const resetForm = () => {
261     queryParams.pageNo = 1
262     queryParams.pageSize = 10
263     queryParams.device = ''
264     queryParams.tagName = ''
265     queryParams.address = ''
266   }
267
268   const handleClose = (done: () => void) => {
269     drawer.value = false
270   }
6c2636 271
J 272   /** tag导入 */
273   const importFormRef = ref()
274   const handleImport = () => {
275     if(queryParams.device){
276       importFormRef.value.open(queryParams.device, '/data/channel/opcua/tag/import',OpcUaTagApi.importOpcUaTagTemplate(), 'OpcUa', queryParams.device)
277     }
278   }
279
280   /** 导出按钮操作 */
281   const handleExport = async () => {
282     try {
283       // 导出的二次确认
284       await message.exportConfirm()
285       // 发起导出
286       exportLoading.value = true
287       const data = await OpcUaTagApi.exportOpcUaTag(queryParams)
288       download.excel(data, 'OpcUa_' + queryParams.device + '_Tag列表.xlsx')
289     } catch {
290     } finally {
291       exportLoading.value = false
292     }
293   }
050ddd 294
D 295   let intervalId;
296
297   onMounted(async () => {
298     // 创建定时器
299     intervalId = setInterval(async () => {
300       if(queryParams.currentValue){
301         const page = await OpcUaTagApi.getOpcuaTagPage(queryParams)
302         list.value = page.list
303         total.value = page.total
304       }
305     }, 10000);
306   });
307
308   // 在组件卸载时清除定时器
309   onBeforeUnmount(() => {
310     if (intervalId) {
311       clearInterval(intervalId);
312     }
313   });
24d32b 314 </script>