Browse Source

feat: Add device group

lejianwen 11 months ago
parent
commit
b1ebedefc6

+ 38 - 0
src/api/device_group.js

@@ -0,0 +1,38 @@
1
+import request from '@/utils/request'
2
+
3
+export function list (params) {
4
+  return request({
5
+    url: '/device_group/list',
6
+    params,
7
+  })
8
+}
9
+
10
+export function detail (id) {
11
+  return request({
12
+    url: `/device_group/detail/${id}`,
13
+  })
14
+}
15
+
16
+export function create (data) {
17
+  return request({
18
+    url: '/device_group/create',
19
+    method: 'post',
20
+    data,
21
+  })
22
+}
23
+
24
+export function update (data) {
25
+  return request({
26
+    url: '/device_group/update',
27
+    method: 'post',
28
+    data,
29
+  })
30
+}
31
+
32
+export function remove (data) {
33
+  return request({
34
+    url: '/device_group/delete',
35
+    method: 'post',
36
+    data,
37
+  })
38
+}

+ 6 - 0
src/router/index.js

@@ -118,6 +118,12 @@ export const asyncRoutes = [
118 118
         meta: { title: 'GroupManage', icon: 'ChatRound' /*keepAlive: true*/ },
119 119
         component: () => import('@/views/group/index.vue'),
120 120
       },
121
+      {
122
+        path: 'deviceGroup',
123
+        name: 'DeviceGroup',
124
+        meta: { title: 'DeviceGroupManage', icon: 'ChatRound' /*keepAlive: true*/ },
125
+        component: () => import('@/views/group/deviceGroupList.vue'),
126
+      },
121 127
       {
122 128
         path: 'index',
123 129
         name: 'UserList',

+ 3 - 0
src/utils/i18n/en.json

@@ -504,5 +504,8 @@
504 504
   },
505 505
   "Result": {
506 506
     "One": "Result"
507
+  },
508
+  "DeviceGroupManage": {
509
+    "One": "Device Group Manage"
507 510
   }
508 511
 }

+ 3 - 0
src/utils/i18n/zh_CN.json

@@ -523,5 +523,8 @@
523 523
   },
524 524
   "Result": {
525 525
     "One": "结果"
526
+  },
527
+  "DeviceGroupManage": {
528
+    "One": "设备组管理"
526 529
   }
527 530
 }

+ 138 - 0
src/views/group/deviceGroupList.vue

@@ -0,0 +1,138 @@
1
+<template>
2
+  <div>
3
+    <el-card class="list-query" shadow="hover">
4
+      <el-form inline label-width="80px">
5
+        <!--        <el-form-item label="名称">
6
+                  <el-input v-model="listQuery.name"></el-input>
7
+                </el-form-item>-->
8
+        <el-form-item>
9
+          <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
10
+          <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
11
+        </el-form-item>
12
+      </el-form>
13
+    </el-card>
14
+    <el-card class="list-body" shadow="hover">
15
+      <el-table :data="listRes.list" v-loading="listRes.loading" border>
16
+        <el-table-column prop="id" label="ID" align="center"></el-table-column>
17
+        <el-table-column prop="name" :label="T('Name')" align="center"/>
18
+        <el-table-column prop="created_at" :label="T('CreatedAt')" align="center"/>
19
+        <el-table-column prop="updated_at" :label="T('UpdatedAt')" align="center"/>
20
+        <el-table-column :label="T('Actions')" align="center">
21
+          <template #default="{row}">
22
+            <el-button @click="toEdit(row)">{{ T('Edit') }}</el-button>
23
+            <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
24
+          </template>
25
+        </el-table-column>
26
+      </el-table>
27
+    </el-card>
28
+    <el-card class="list-page" shadow="hover">
29
+      <el-pagination background
30
+                     layout="prev, pager, next, sizes, jumper"
31
+                     :page-sizes="[10,20,50,100]"
32
+                     v-model:page-size="listQuery.page_size"
33
+                     v-model:current-page="listQuery.page"
34
+                     :total="listRes.total">
35
+      </el-pagination>
36
+    </el-card>
37
+    <el-dialog v-model="formVisible" :title="!formData.id?T('Create'):T('Update')" width="800">
38
+      <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
39
+        <el-form-item :label="T('Name')" prop="name" required>
40
+          <el-input v-model="formData.name"></el-input>
41
+        </el-form-item>
42
+        <el-form-item>
43
+          <el-button @click="formVisible = false">{{ T('Cancel') }}</el-button>
44
+          <el-button @click="submit" type="primary">{{ T('Submit') }}</el-button>
45
+        </el-form-item>
46
+      </el-form>
47
+    </el-dialog>
48
+  </div>
49
+</template>
50
+
51
+<script setup>
52
+  import { onMounted, reactive, watch, ref, onActivated } from 'vue'
53
+  import { list, create, update, detail, remove } from '@/api/device_group'
54
+  import { ElMessage, ElMessageBox } from 'element-plus'
55
+  import { T } from '@/utils/i18n'
56
+
57
+  const listRes = reactive({
58
+    list: [], total: 0, loading: false,
59
+  })
60
+  const listQuery = reactive({
61
+    page: 1,
62
+    page_size: 10,
63
+  })
64
+
65
+  const getList = async () => {
66
+    listRes.loading = true
67
+    const res = await list(listQuery).catch(_ => false)
68
+    listRes.loading = false
69
+    if (res) {
70
+      listRes.list = res.data.list
71
+      listRes.total = res.data.total
72
+    }
73
+  }
74
+  const handlerQuery = () => {
75
+    if (listQuery.page === 1) {
76
+      getList()
77
+    } else {
78
+      listQuery.page = 1
79
+    }
80
+  }
81
+
82
+  const del = async (row) => {
83
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
84
+      confirmButtonText: T('Confirm'),
85
+      cancelButtonText: T('Cancel'),
86
+      type: 'warning',
87
+    }).catch(_ => false)
88
+    if (!cf) {
89
+      return false
90
+    }
91
+
92
+    const res = await remove({ id: row.id }).catch(_ => false)
93
+    if (res) {
94
+      ElMessage.success(T('OperationSuccess'))
95
+      getList()
96
+    }
97
+  }
98
+  onMounted(getList)
99
+  onActivated(getList)
100
+
101
+  watch(() => listQuery.page, getList)
102
+
103
+  watch(() => listQuery.page_size, handlerQuery)
104
+
105
+  const formVisible = ref(false)
106
+  const formData = reactive({
107
+    id: 0,
108
+    name: '',
109
+    type: 1,
110
+  })
111
+
112
+  const toEdit = (row) => {
113
+    formVisible.value = true
114
+    formData.id = row.id
115
+    formData.name = row.name
116
+    formData.type = row.type
117
+  }
118
+  const toAdd = () => {
119
+    formVisible.value = true
120
+    formData.id = 0
121
+    formData.name = ''
122
+    formData.type = 1
123
+  }
124
+  const submit = async () => {
125
+    const api = formData.id ? update : create
126
+    const res = await api(formData).catch(_ => false)
127
+    if (res) {
128
+      ElMessage.success(T('OperationSuccess'))
129
+      formVisible.value = false
130
+      getList()
131
+    }
132
+  }
133
+
134
+</script>
135
+
136
+<style scoped lang="scss">
137
+
138
+</style>

+ 41 - 0
src/views/peer/index.vue

@@ -49,6 +49,12 @@
49 49
         </el-table-column>
50 50
         <el-table-column prop="last_online_ip" :label="T('LastOnlineIp')" align="center" min-width="120"/>
51 51
         <el-table-column prop="username" :label="T('Username')" align="center" width="120"/>
52
+        <el-table-column prop="group_id" :label="T('Group')" align="center" width="120">
53
+          <template #default="{row}">
54
+            <span v-if="row.group_id"> <el-tag>{{ groupListRes.list?.find(g => g.id === row.group_id)?.name }} </el-tag> </span>
55
+            <span v-else> - </span>
56
+          </template>
57
+        </el-table-column>
52 58
         <el-table-column prop="uuid" :label="T('Uuid')" align="center" width="120" show-overflow-tooltip/>
53 59
         <el-table-column prop="version" :label="T('Version')" align="center" width="80"/>
54 60
         <el-table-column prop="created_at" :label="T('CreatedAt')" align="center" width="150"/>
@@ -78,6 +84,16 @@
78 84
         <el-form-item label="ID" prop="id" required>
79 85
           <el-input v-model="formData.id"></el-input>
80 86
         </el-form-item>
87
+        <el-form-item :label="T('Group')" prop="group_id">
88
+          <el-select v-model="formData.group_id">
89
+            <el-option
90
+                v-for="item in groupListRes.list"
91
+                :key="item.id"
92
+                :label="item.name"
93
+                :value="item.id"
94
+            ></el-option>
95
+          </el-select>
96
+        </el-form-item>
81 97
         <el-form-item :label="T('Username')" prop="username">
82 98
           <el-input v-model="formData.username"></el-input>
83 99
         </el-form-item>
@@ -151,6 +167,7 @@
151 167
 <script setup>
152 168
   import { computed, onActivated, onMounted, reactive, ref, watch } from 'vue'
153 169
   import { batchRemove, create, list, remove, update } from '@/api/peer'
170
+  import { list as groupList } from '@/api/device_group'
154 171
   import { ElMessage, ElMessageBox } from 'element-plus'
155 172
   import { toWebClientLink } from '@/utils/webclient'
156 173
   import { T } from '@/utils/i18n'
@@ -166,6 +183,29 @@
166 183
   import createABForm from '@/views/peer/createABForm.vue'
167 184
 
168 185
   const appStore = useAppStore()
186
+
187
+  //group
188
+  const groupListRes = reactive({
189
+    list: [], total: 0, loading: false,
190
+  })
191
+  const groupListQuery = reactive({
192
+    page: 1,
193
+    page_size: 999,
194
+  })
195
+  const getGroupList = async () => {
196
+    groupListRes.loading = true
197
+    const res = await groupList(groupListQuery).catch(_ => false)
198
+    groupListRes.loading = false
199
+    if (res) {
200
+      groupListRes.list = res.data.list
201
+      groupListRes.total = res.data.total
202
+    }
203
+  }
204
+  onMounted(getGroupList)
205
+  //
206
+
207
+
208
+
169 209
   const listRes = reactive({
170 210
     list: [], total: 0, loading: false,
171 211
   })
@@ -220,6 +260,7 @@
220 260
   const formVisible = ref(false)
221 261
   const formData = reactive({
222 262
     row_id: 0,
263
+    group_id: null,
223 264
     cpu: '',
224 265
     hostname: '',
225 266
     id: '',