Browse Source

add batch create ab from peer
add batch update ab tags

lejianwen 1 year ago
parent
commit
f70764f4c6

+ 16 - 0
src/api/address_book.js

@@ -52,3 +52,19 @@ export function shareByWebClient (data) {
52 52
     data,
53 53
   })
54 54
 }
55
+
56
+export function batchCreateFromPeers (data) {
57
+  return request({
58
+    url: '/address_book/batchCreateFromPeers',
59
+    method: 'post',
60
+    data,
61
+  })
62
+}
63
+
64
+export function batchUpdateTags (data) {
65
+  return request({
66
+    url: '/address_book/batchUpdateTags',
67
+    method: 'post',
68
+    data,
69
+  })
70
+}

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

@@ -450,5 +450,11 @@
450 450
   },
451 451
   "UserToken": {
452 452
     "One": "User Token"
453
+  },
454
+  "BatchAddToAB": {
455
+    "One": "Batch Add To Address Book"
456
+  },
457
+  "BatchEditTags": {
458
+    "One": "Batch Edit Tags"
453 459
   }
454 460
 }

+ 6 - 0
src/utils/i18n/es.json

@@ -453,5 +453,11 @@
453 453
   },
454 454
   "MyPeer": {
455 455
     "One": "Mis pares"
456
+  },
457
+  "BatchAddToAB": {
458
+    "One": "Agregar en bloque a la libreta de direcciones"
459
+  },
460
+  "BatchEditTags": {
461
+    "One": "Editar etiquetas en bloque"
456 462
   }
457 463
 }

+ 6 - 0
src/utils/i18n/ko.json

@@ -439,5 +439,11 @@
439 439
   },
440 440
   "MyPeer": {
441 441
     "One": "내 피어"
442
+  },
443
+  "BatchAddToAB": {
444
+    "One": "주소록에 일괄 추가"
445
+  },
446
+  "BatchEditTags": {
447
+    "One": "태그 일괄 편집"
442 448
   }
443 449
 }

+ 6 - 0
src/utils/i18n/ru.json

@@ -453,6 +453,12 @@
453 453
   },
454 454
   "MyPeer": {
455 455
     "One": "Мои партнеры"
456
+  },
457
+  "BatchAddToAB": {
458
+    "One": "Пакетное добавление в адресную книгу"
459
+  },
460
+  "BatchEditTags": {
461
+    "One": "Пакетное редактирование тегов"
456 462
   }
457 463
 }
458 464
 

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

@@ -469,5 +469,11 @@
469 469
   },
470 470
   "Information": {
471 471
     "One": "信息"
472
+  },
473
+  "BatchAddToAB": {
474
+    "One": "批量添加到地址簿"
475
+  },
476
+  "BatchEditTags": {
477
+    "One": "批量编辑标签"
472 478
   }
473 479
 }

+ 52 - 2
src/views/address_book/index.js

@@ -1,5 +1,5 @@
1
-import { reactive, ref, watch } from 'vue'
2
-import { create, list, remove, update } from '@/api/address_book'
1
+import { reactive, ref } from 'vue'
2
+import { batchUpdateTags, create, list, remove, update } from '@/api/address_book'
3 3
 import { ElMessage, ElMessageBox } from 'element-plus'
4 4
 import { T } from '@/utils/i18n'
5 5
 import { useRepositories as useCollectionRepositories } from '@/views/address_book/collection'
@@ -246,3 +246,53 @@ export function useRepositories (is_my = 0) {
246 246
     fromPeer,
247 247
   }
248 248
 }
249
+
250
+export function useBatchUpdateTagsRepositories (is_my = 0) {
251
+  const {
252
+    listRes: tagListRes,
253
+    listQuery: tagListQuery,
254
+    getList: getTagList,
255
+  } = useTagRepositories(is_my)
256
+  tagListQuery.page_size = 9999
257
+
258
+  const visible = ref(false)
259
+  const show = () => {
260
+    if (formData.value.row_ids.length === 0) {
261
+      ElMessage.warning(T('PleaseSelectData'))
262
+      return
263
+    }
264
+    visible.value = true
265
+  }
266
+  const formData = ref({
267
+    tags: [],
268
+    row_ids: [],
269
+  })
270
+  const submit = async () => {
271
+    if (formData.value.row_ids.length === 0) {
272
+      ElMessage.warning(T('PleaseSelectData'))
273
+      return false
274
+    }
275
+    if (formData.value.tags.length === 0) {
276
+      ElMessage.warning(T('PleaseSelectData'))
277
+      return false
278
+    }
279
+    const res = await batchUpdateTags(formData.value).catch(_ => false)
280
+    if (res) {
281
+      ElMessage.success(T('Success'))
282
+      visible.value = false
283
+      return true
284
+    }
285
+    return false
286
+  }
287
+
288
+  return {
289
+    tagListQuery,
290
+    getTagList,
291
+    tagListRes,
292
+
293
+    visible,
294
+    formData,
295
+    show,
296
+    submit,
297
+  }
298
+}

+ 50 - 3
src/views/my/address_book/index.vue

@@ -20,12 +20,13 @@
20 20
         <el-form-item>
21 21
           <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
22 22
           <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
23
+          <el-button type="primary" @click="showBatchEditTags">{{ T('BatchEditTags') }}</el-button>
23 24
         </el-form-item>
24 25
       </el-form>
25 26
     </el-card>
26 27
     <el-card class="list-body" shadow="hover">
27
-      <!--      <el-tag type="danger" style="margin-bottom: 10px">不建议在此操作地址簿,可能会造成数据不同步</el-tag>-->
28
-      <el-table :data="listRes.list" v-loading="listRes.loading" border>
28
+      <el-table :data="listRes.list" v-loading="listRes.loading" border @selection-change="handleSelectionChange">
29
+        <el-table-column type="selection" width="50" align="center"></el-table-column>
29 30
         <el-table-column prop="id" label="ID" align="center" width="200">
30 31
           <template #default="{row}">
31 32
             <div>
@@ -151,13 +152,31 @@
151 152
                         @cancel="shareToWebClientVisible=false"
152 153
                         @success=""/>
153 154
     </el-dialog>
155
+    <el-dialog v-model="batchEditTagVisible" width="800">
156
+      <el-form :model="batchEditTagsFormData" label-width="120px" class="dialog-form">
157
+        <el-form-item :label="T('Tags')" prop="tags">
158
+          <el-select v-model="batchEditTagsFormData.tags" multiple>
159
+            <el-option
160
+                v-for="item in tagListResForBatchEdit.list"
161
+                :key="item.name"
162
+                :label="item.name"
163
+                :value="item.name"
164
+            ></el-option>
165
+          </el-select>
166
+        </el-form-item>
167
+        <el-form-item>
168
+          <el-button @click="batchEditTagVisible = false">{{ T('Cancel') }}</el-button>
169
+          <el-button @click="submitBatchEditTags" type="primary">{{ T('Submit') }}</el-button>
170
+        </el-form-item>
171
+      </el-form>
172
+    </el-dialog>
154 173
   </div>
155 174
 </template>
156 175
 
157 176
 <script setup>
158 177
   import { onActivated, onMounted, ref, watch } from 'vue'
159 178
   import { list as fetchTagList } from '@/api/tag'
160
-  import { useRepositories } from '@/views/address_book'
179
+  import { useBatchUpdateTagsRepositories, useRepositories } from '@/views/address_book'
161 180
   import { toWebClientLink } from '@/utils/webclient'
162 181
   import { T } from '@/utils/i18n'
163 182
   import shareByWebClient from '@/views/address_book/components/shareByWebClient.vue'
@@ -166,6 +185,9 @@
166 185
   import { handleClipboard } from '@/utils/clipboard'
167 186
   import { CopyDocument } from '@element-plus/icons'
168 187
   import PlatformIcons from '@/components/icons/platform.vue'
188
+  import { batchUpdateTags } from '@/api/address_book'
189
+  import { ElMessage } from 'element-plus'
190
+  import { useRepositories as useTagRepositories } from '@/views/tag'
169 191
 
170 192
   const is_my = 1
171 193
   const appStore = useAppStore()
@@ -199,6 +221,31 @@
199 221
   watch(() => listQuery.page, getList)
200 222
 
201 223
   watch(() => listQuery.page_size, handlerQuery)
224
+
225
+  const {
226
+    tagListRes: tagListResForBatchEdit,
227
+    getTagList: getTagListForBatchEdit,
228
+    visible: batchEditTagVisible,
229
+    show: showBatchEditTags,
230
+    formData: batchEditTagsFormData,
231
+    submit: _submitBatchEditTags,
232
+  } = useBatchUpdateTagsRepositories(is_my)
233
+  onMounted(getTagListForBatchEdit)
234
+  const submitBatchEditTags = async () => {
235
+    const res = await _submitBatchEditTags().catch(_ => false)
236
+    if (res) {
237
+      getList()
238
+    }
239
+  }
240
+
241
+  const multipleSelection = ref([])
242
+  const handleSelectionChange = (val) => {
243
+    multipleSelection.value = val
244
+
245
+    batchEditTagsFormData.value.row_ids = val.map(v => v.row_id)
246
+  }
247
+
248
+
202 249
 </script>
203 250
 
204 251
 <style scoped lang="scss">

+ 60 - 2
src/views/my/peer/index.vue

@@ -23,6 +23,8 @@
23 23
           <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
24 24
           <el-button type="success" @click="toExport">{{ T('Export') }}</el-button>
25 25
           <el-button type="danger" @click="toBatchDelete">{{ T('BatchDelete') }}</el-button>
26
+          <el-button type="primary" @click="toBatchAddToAB">{{ T('BatchAddToAB') }}</el-button>
27
+
26 28
         </el-form-item>
27 29
       </el-form>
28 30
     </el-card>
@@ -147,6 +149,31 @@
147 149
         </el-form-item>
148 150
       </el-form>
149 151
     </el-dialog>
152
+
153
+    <el-dialog v-model="batchABFormVisible" width="800" :title="T('Create')">
154
+      <el-form class="dialog-form" ref="form" :model="batchABFormData" label-width="120px">
155
+        <el-form-item :label="T('AddressBookName')" required prop="collection_id">
156
+          <el-select v-model="batchABFormData.collection_id" clearable @change="changeCollection">
157
+            <el-option :value="0" :label="T('MyAddressBook')"></el-option>
158
+            <el-option v-for="c in collectionListRes.list" :key="c.id" :label="c.name" :value="c.id"></el-option>
159
+          </el-select>
160
+        </el-form-item>
161
+        <el-form-item :label="T('Tags')" prop="tags">
162
+          <el-select v-model="batchABFormData.tags" multiple>
163
+            <el-option
164
+                v-for="item in tagListRes.list"
165
+                :key="item.name"
166
+                :label="item.name"
167
+                :value="item.name"
168
+            ></el-option>
169
+          </el-select>
170
+        </el-form-item>
171
+        <el-form-item>
172
+          <el-button @click="batchABFormVisible = false">{{ T('Cancel') }}</el-button>
173
+          <el-button @click="submitBatchAddToAB" type="primary">{{ T('Submit') }}</el-button>
174
+        </el-form-item>
175
+      </el-form>
176
+    </el-dialog>
150 177
   </div>
151 178
 </template>
152 179
 
@@ -164,6 +191,7 @@
164 191
   import { connectByClient } from '@/utils/peer'
165 192
   import { CopyDocument } from '@element-plus/icons'
166 193
   import { handleClipboard } from '@/utils/clipboard'
194
+  import { batchCreateFromPeers } from '@/api/address_book'
167 195
 
168 196
   const appStore = useAppStore()
169 197
   const listRes = reactive({
@@ -282,8 +310,8 @@
282 310
     tagListRes,
283 311
     changeCollection,
284 312
     submit: ABSubmit,
285
-    fromPeer
286
-  } = useABRepositories()
313
+    fromPeer,
314
+  } = useABRepositories(1)
287 315
   onMounted(getCollectionList)
288 316
   const toAddressBook = (peer) => {
289 317
     fromPeer(peer)
@@ -314,6 +342,36 @@
314 342
       getList()
315 343
     }
316 344
   }
345
+
346
+  const batchABFormVisible = ref(false)
347
+  const toBatchAddToAB = () => {
348
+    batchABFormVisible.value = true
349
+  }
350
+  const batchABFormData = ref({
351
+    collection_id: 0,
352
+    tags: [],
353
+    peer_ids: [],
354
+  })
355
+  const submitBatchAddToAB = async () => {
356
+    if (multipleSelection.value.length === 0) {
357
+      ElMessage.warning(T('PleaseSelectData'))
358
+      return false
359
+    }
360
+    batchABFormData.value.peer_ids = multipleSelection.value.map(i => i.row_id)
361
+    if (!batchABFormData.value.peer_ids.length) {
362
+      ElMessage.warning(T('PleaseSelectData'))
363
+      return false
364
+    }
365
+
366
+    const res = await batchCreateFromPeers(batchABFormData.value).catch(_ => false)
367
+    if (res) {
368
+      ElMessage.success(T('OperationSuccess'))
369
+      batchABFormVisible.value = false
370
+      getList()
371
+    }
372
+  }
373
+
374
+
317 375
 </script>
318 376
 
319 377
 <style scoped lang="scss">

+ 0 - 6
src/views/tag/index.js

@@ -106,12 +106,6 @@ export function useRepositories (is_my = 0) {
106 106
       getList()
107 107
     }
108 108
   }
109
-  onMounted(getList)
110
-  onActivated(getList)
111
-
112
-  watch(() => listQuery.page, getList)
113
-
114
-  watch(() => listQuery.page_size, handlerQuery)
115 109
 
116 110
   const formVisible = ref(false)
117 111
   const formData = reactive({