Просмотр исходного кода

add batch create ab from peer
add batch update ab tags

lejianwen 1 год назад
Родитель
Сommit
f70764f4c6

+ 16 - 0
src/api/address_book.js

@@ -52,3 +52,19 @@ export function shareByWebClient (data) {
52
     data,
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
   "UserToken": {
451
   "UserToken": {
452
     "One": "User Token"
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
   "MyPeer": {
454
   "MyPeer": {
455
     "One": "Mis pares"
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
   "MyPeer": {
440
   "MyPeer": {
441
     "One": "내 피어"
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
   "MyPeer": {
454
   "MyPeer": {
455
     "One": "Мои партнеры"
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
   "Information": {
470
   "Information": {
471
     "One": "信息"
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
 import { ElMessage, ElMessageBox } from 'element-plus'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
4
 import { T } from '@/utils/i18n'
4
 import { T } from '@/utils/i18n'
5
 import { useRepositories as useCollectionRepositories } from '@/views/address_book/collection'
5
 import { useRepositories as useCollectionRepositories } from '@/views/address_book/collection'
@@ -246,3 +246,53 @@ export function useRepositories (is_my = 0) {
246
     fromPeer,
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
         <el-form-item>
20
         <el-form-item>
21
           <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
21
           <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
22
           <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
22
           <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
23
+          <el-button type="primary" @click="showBatchEditTags">{{ T('BatchEditTags') }}</el-button>
23
         </el-form-item>
24
         </el-form-item>
24
       </el-form>
25
       </el-form>
25
     </el-card>
26
     </el-card>
26
     <el-card class="list-body" shadow="hover">
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
         <el-table-column prop="id" label="ID" align="center" width="200">
30
         <el-table-column prop="id" label="ID" align="center" width="200">
30
           <template #default="{row}">
31
           <template #default="{row}">
31
             <div>
32
             <div>
@@ -151,13 +152,31 @@
151
                         @cancel="shareToWebClientVisible=false"
152
                         @cancel="shareToWebClientVisible=false"
152
                         @success=""/>
153
                         @success=""/>
153
     </el-dialog>
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
   </div>
173
   </div>
155
 </template>
174
 </template>
156
 
175
 
157
 <script setup>
176
 <script setup>
158
   import { onActivated, onMounted, ref, watch } from 'vue'
177
   import { onActivated, onMounted, ref, watch } from 'vue'
159
   import { list as fetchTagList } from '@/api/tag'
178
   import { list as fetchTagList } from '@/api/tag'
160
-  import { useRepositories } from '@/views/address_book'
179
+  import { useBatchUpdateTagsRepositories, useRepositories } from '@/views/address_book'
161
   import { toWebClientLink } from '@/utils/webclient'
180
   import { toWebClientLink } from '@/utils/webclient'
162
   import { T } from '@/utils/i18n'
181
   import { T } from '@/utils/i18n'
163
   import shareByWebClient from '@/views/address_book/components/shareByWebClient.vue'
182
   import shareByWebClient from '@/views/address_book/components/shareByWebClient.vue'
@@ -166,6 +185,9 @@
166
   import { handleClipboard } from '@/utils/clipboard'
185
   import { handleClipboard } from '@/utils/clipboard'
167
   import { CopyDocument } from '@element-plus/icons'
186
   import { CopyDocument } from '@element-plus/icons'
168
   import PlatformIcons from '@/components/icons/platform.vue'
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
   const is_my = 1
192
   const is_my = 1
171
   const appStore = useAppStore()
193
   const appStore = useAppStore()
@@ -199,6 +221,31 @@
199
   watch(() => listQuery.page, getList)
221
   watch(() => listQuery.page, getList)
200
 
222
 
201
   watch(() => listQuery.page_size, handlerQuery)
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
 </script>
249
 </script>
203
 
250
 
204
 <style scoped lang="scss">
251
 <style scoped lang="scss">

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

@@ -23,6 +23,8 @@
23
           <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
23
           <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
24
           <el-button type="success" @click="toExport">{{ T('Export') }}</el-button>
24
           <el-button type="success" @click="toExport">{{ T('Export') }}</el-button>
25
           <el-button type="danger" @click="toBatchDelete">{{ T('BatchDelete') }}</el-button>
25
           <el-button type="danger" @click="toBatchDelete">{{ T('BatchDelete') }}</el-button>
26
+          <el-button type="primary" @click="toBatchAddToAB">{{ T('BatchAddToAB') }}</el-button>
27
+
26
         </el-form-item>
28
         </el-form-item>
27
       </el-form>
29
       </el-form>
28
     </el-card>
30
     </el-card>
@@ -147,6 +149,31 @@
147
         </el-form-item>
149
         </el-form-item>
148
       </el-form>
150
       </el-form>
149
     </el-dialog>
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
   </div>
177
   </div>
151
 </template>
178
 </template>
152
 
179
 
@@ -164,6 +191,7 @@
164
   import { connectByClient } from '@/utils/peer'
191
   import { connectByClient } from '@/utils/peer'
165
   import { CopyDocument } from '@element-plus/icons'
192
   import { CopyDocument } from '@element-plus/icons'
166
   import { handleClipboard } from '@/utils/clipboard'
193
   import { handleClipboard } from '@/utils/clipboard'
194
+  import { batchCreateFromPeers } from '@/api/address_book'
167
 
195
 
168
   const appStore = useAppStore()
196
   const appStore = useAppStore()
169
   const listRes = reactive({
197
   const listRes = reactive({
@@ -282,8 +310,8 @@
282
     tagListRes,
310
     tagListRes,
283
     changeCollection,
311
     changeCollection,
284
     submit: ABSubmit,
312
     submit: ABSubmit,
285
-    fromPeer
286
-  } = useABRepositories()
313
+    fromPeer,
314
+  } = useABRepositories(1)
287
   onMounted(getCollectionList)
315
   onMounted(getCollectionList)
288
   const toAddressBook = (peer) => {
316
   const toAddressBook = (peer) => {
289
     fromPeer(peer)
317
     fromPeer(peer)
@@ -314,6 +342,36 @@
314
       getList()
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
 </script>
375
 </script>
318
 
376
 
319
 <style scoped lang="scss">
377
 <style scoped lang="scss">

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

@@ -106,12 +106,6 @@ export function useRepositories (is_my = 0) {
106
       getList()
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
   const formVisible = ref(false)
110
   const formVisible = ref(false)
117
   const formData = reactive({
111
   const formData = reactive({