address-client 3.0.41-aodeToV4 → 3.0.43-aodeToV4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <div class="flex" @keyup.enter="search">
3
+ <work-busy :is-busy="batchSubmitBusy"></work-busy>
3
4
  <criteria-paged :model="model" v-ref:paged>
4
5
  <criteria partial='criteria' @condition-changed='$parent.selfSearch' v-ref:cri>
5
6
  <div novalidate class="form-horizontal select-overspread container-fluid auto" partial>
@@ -53,6 +54,8 @@
53
54
  <button v-if="!$parent.$parent.f_special" class="button_new button_spacing" style="width: max-content;" @click="$parent.$parent.add('小区')">添加小区</button>
54
55
  <button v-if="$parent.$parent.f_special"class="button_new button_spacing" style="width: max-content;" @click="$parent.$parent.add('单位')">添加单位</button>
55
56
  <button v-if="$parent.$parent.checkitem.length>=1" class="button_clear button_spacing" @click="$parent.$parent.deleteall()">批量删除</button>
57
+ <button class="button_clear button_spacing" @click="$parent.$parent.batchModify()">批量修改</button>
58
+
56
59
  <button class="button_clear button_spacing" @click="$parent.$parent.clear()">清空</button>
57
60
  <export-excel :data="$parent.$parent.getCondition" :defaultselect="$parent.$parent.getfield"
58
61
  :field="$parent.$parent.getfield"
@@ -86,8 +89,115 @@
86
89
  condition="f_residential_area like '%{}%'" placeholder="小区"
87
90
  :size="model.f_residential_area ? model.f_residential_area.length*2 : 6"/>
88
91
  </div>
89
-
90
- </div>
92
+ </div>
93
+ <div class="row" v-if="$parent.$parent.criteriaShow">
94
+ <div :class="$parent.$parent.style">
95
+ <label class="font_normal_body">安检网格员</label>
96
+ <v-select
97
+ :value.sync="model.f_check_gridman"
98
+ v-model="model.f_check_gridman"
99
+ :options='$parent.$parent.gridmans'
100
+ :value-single="true"
101
+ placeholder='请选择'
102
+ close-on-select
103
+ condition="f_check_gridman = '{}'"
104
+ :search='true'>
105
+ </v-select>
106
+ </div>
107
+ <div :class="$parent.$parent.style">
108
+ <label class="font_normal_body">上次安检网格员</label>
109
+ <v-select
110
+ :value.sync="model.f_old_check_gridman"
111
+ v-model="model.f_old_check_gridman"
112
+ :options='$parent.$parent.gridmans'
113
+ :value-single="true"
114
+ placeholder='请选择'
115
+ close-on-select
116
+ condition="f_old_check_gridman = '{}'"
117
+ :search='true'>
118
+ </v-select>
119
+ </div>
120
+ <div :class="$parent.$parent.style">
121
+ <label class="font_normal_body">置换网格员</label>
122
+ <v-select
123
+ :value.sync="model.f_replace_gridman"
124
+ v-model="model.f_replace_gridman"
125
+ :options='$parent.$parent.gridmans1'
126
+ :value-single="true"
127
+ placeholder='请选择'
128
+ close-on-select
129
+ condition="f_replace_gridman = '{}'"
130
+ :search='true'>
131
+ </v-select>
132
+ </div>
133
+ <div :class="$parent.$parent.style">
134
+ <label class="font_normal_body">上次置换网格员</label>
135
+ <v-select
136
+ :value.sync="model.f_old_replace_gridman"
137
+ v-model="model.f_old_replace_gridman"
138
+ :options='$parent.$parent.gridmans1'
139
+ :value-single="true"
140
+ placeholder='请选择'
141
+ close-on-select
142
+ condition="f_old_replace_gridman = '{}'"
143
+ :search='true'>
144
+ </v-select>
145
+ </div>
146
+ </div>
147
+ <div class="row" v-if="$parent.$parent.criteriaShow">
148
+ <div :class="$parent.$parent.style">
149
+ <label class="font_normal_body">维修网格员</label>
150
+ <v-select
151
+ :value.sync="model.f_repair_gridman"
152
+ v-model="model.f_repair_gridman"
153
+ :options='$parent.$parent.gridmans2'
154
+ :value-single="true"
155
+ placeholder='请选择'
156
+ close-on-select
157
+ condition="f_repair_gridman = '{}'"
158
+ :search='true'>
159
+ </v-select>
160
+ </div>
161
+ <div :class="$parent.$parent.style">
162
+ <label class="font_normal_body">上次维修网格员</label>
163
+ <v-select
164
+ :value.sync="model.f_old_repair_gridman"
165
+ v-model="model.f_old_repair_gridman"
166
+ :options='$parent.$parent.gridmans2'
167
+ :value-single="true"
168
+ placeholder='请选择'
169
+ close-on-select
170
+ condition="f_old_repair_gridman = '{}'"
171
+ :search='true'>
172
+ </v-select>
173
+ </div>
174
+ <div :class="$parent.$parent.style">
175
+ <label class="font_normal_body">工商业网格员</label>
176
+ <v-select
177
+ :value.sync="model.f_industry_gridman"
178
+ v-model="model.f_industry_gridman"
179
+ :options='$parent.$parent.gridmans3'
180
+ :value-single="true"
181
+ placeholder='请选择'
182
+ close-on-select
183
+ condition="f_industry_gridman = '{}'"
184
+ :search='true'>
185
+ </v-select>
186
+ </div>
187
+ <div :class="$parent.$parent.style">
188
+ <label class="font_normal_body">上次工商业网格员</label>
189
+ <v-select
190
+ :value.sync="model.f_old_industry_gridman"
191
+ v-model="model.f_old_industry_gridman"
192
+ :options='$parent.$parent.gridmans3'
193
+ :value-single="true"
194
+ placeholder='请选择'
195
+ close-on-select
196
+ condition="f_old_industry_gridman = '{}'"
197
+ :search='true'>
198
+ </v-select>
199
+ </div>
200
+ </div>
91
201
  </div>
92
202
 
93
203
 
@@ -96,11 +206,24 @@
96
206
  <template partial='head'>
97
207
  <tr>
98
208
  <th>
99
- <input
100
- type="checkbox"
101
- v-model="$parent.$parent.$parent.checkall"
102
- @change="$parent.$parent.$parent.chooseAll"
103
- />
209
+ <div style="display:flex;align-items:center;gap:5px;">
210
+ <span>删除</span>
211
+ <input
212
+ type="checkbox"
213
+ v-model="$parent.$parent.$parent.checkall"
214
+ @change="$parent.$parent.$parent.chooseAll"
215
+ />
216
+ </div>
217
+ </th>
218
+ <th>
219
+ <div style="display:flex;align-items:center;gap:5px;">
220
+ <span>修改</span>
221
+ <input
222
+ type="checkbox"
223
+ v-model="$parent.$parent.$parent.batchCheckall"
224
+ @change="$parent.$parent.$parent.batchChooseAll"
225
+ />
226
+ </div>
104
227
  </th>
105
228
  <th><nobr>序号</nobr></th>
106
229
  <th v-if="false"><nobr>省份</nobr></th>
@@ -125,6 +248,18 @@
125
248
  <th><nobr>关联地址 </nobr></th>
126
249
  <th><nobr>操作人</nobr></th>
127
250
  <th><nobr>操作日期</nobr></th>
251
+ <th><nobr>安检网格员</nobr></th>
252
+ <th><nobr>上次安检网格员</nobr></th>
253
+ <th><nobr>安检网格员电话</nobr></th>
254
+ <th><nobr>置换网格员</nobr></th>
255
+ <th><nobr>上次置换网格员</nobr></th>
256
+ <th><nobr>置换网格员电话</nobr></th>
257
+ <th><nobr>维修网格员</nobr></th>
258
+ <th><nobr>上次维修网格员</nobr></th>
259
+ <th><nobr>维修网格员电话</nobr></th>
260
+ <th><nobr>工商业网格员</nobr></th>
261
+ <th><nobr>上次工商业网格员</nobr></th>
262
+ <th><nobr>工商业网格员电话</nobr></th>
128
263
  <th><nobr>操作</nobr></th>
129
264
 
130
265
  </tr>
@@ -140,6 +275,13 @@
140
275
  :checked="$parent.$parent.$parent.ischecked(row.id)"
141
276
  />
142
277
  </td>
278
+ <td style="text-align: center">
279
+ <input
280
+ type="checkbox"
281
+ @change="$parent.$parent.$parent.batchChooseOne($event, row, model.rows)"
282
+ :checked="$parent.$parent.$parent.isBatchChecked(row.id)"
283
+ />
284
+ </td>
143
285
  <td style="text-align:center"><nobr>{{$index + 1}}</nobr></td>
144
286
  <td style="text-align:center" v-if="false"><nobr>{{row.f_province}}</nobr></td>
145
287
  <td style="text-align:center" v-if="false"><nobr>{{row.f_city}}</nobr></td>
@@ -159,6 +301,18 @@
159
301
  <td style="text-align:center"><nobr>{{row.addresscount}}</nobr></td>
160
302
  <td style="text-align:center"><nobr>{{row.f_operator}}</nobr></td>
161
303
  <td style="text-align:center"><nobr>{{row.f_operate_date}}</nobr></td>
304
+ <td style="text-align:center"><nobr>{{row.f_check_gridman}}</nobr></td>
305
+ <td style="text-align:center"><nobr>{{row.f_old_check_gridman}}</nobr></td>
306
+ <td style="text-align:center"><nobr>{{row.f_check_phone}}</nobr></td>
307
+ <td style="text-align:center"><nobr>{{row.f_replace_gridman}}</nobr></td>
308
+ <td style="text-align:center"><nobr>{{row.f_old_replace_gridman}}</nobr></td>
309
+ <td style="text-align:center"><nobr>{{row.f_replace_phone}}</nobr></td>
310
+ <td style="text-align:center"><nobr>{{row.f_repair_gridman}}</nobr></td>
311
+ <td style="text-align:center"><nobr>{{row.f_old_repair_gridman}}</nobr></td>
312
+ <td style="text-align:center"><nobr>{{row.f_repair_phone}}</nobr></td>
313
+ <td style="text-align:center"><nobr>{{row.f_industry_gridman}}</nobr></td>
314
+ <td style="text-align:center"><nobr>{{row.f_old_industry_gridman}}</nobr></td>
315
+ <td style="text-align:center"><nobr>{{row.f_industry_phone}}</nobr></td>
162
316
  <td><nobr>
163
317
  <!--<button type="button" name="button" class="btn btn-link"
164
318
  @click.stop="$parent.$parent.$parent.modify(row)">修改</button>-->
@@ -170,11 +324,78 @@
170
324
  <template partial='foot'></template>
171
325
  </data-grid>
172
326
  </criteria-paged>
327
+ <!-- 批量修改:仅网格员下拉;未选择的项不提交、后端不更新 -->
328
+ <modal :show.sync="batchModifyShow" width="520px" backdrop="false">
329
+ <header slot="modal-header" class="modal-header">
330
+ <h4 class="modal-title" style="text-align: center;">
331
+ 批量修改网格员
332
+ <span v-if="batchDisplayCount > 0" class="batch-select-tip">(已选 {{ batchDisplayCount }} 个小区)</span>
333
+ </h4>
334
+ </header>
335
+ <article slot="modal-body" class="modal-body area-batch-gridman-body">
336
+ <p class="area-batch-hint">只填写需要修改的项,未选择的列保持原数据不变。选错后可点第一项「不修改」恢复为不提交该列。</p>
337
+ <table class="area-batch-gridman-table">
338
+ <colgroup>
339
+ <col class="area-batch-col-label-l">
340
+ <col class="area-batch-col-select">
341
+ </colgroup>
342
+ <tr>
343
+ <th class="area-batch-th">安检网格员</th>
344
+ <td class="area-batch-td-ctrl area-batch-td-select">
345
+ <span v-if="batchGridmanLoading" class="area-batch-loading">加载中…</span>
346
+ <v-select v-else
347
+ :value.sync="batchData.f_check_gridman" :value-single="true"
348
+ :options='batchGridmanOptions' placeholder='不修改请留空'
349
+ close-on-select @change="onBatchCheckChange">
350
+ </v-select>
351
+ </td>
352
+ </tr>
353
+ <tr>
354
+ <th class="area-batch-th">置换网格员</th>
355
+ <td class="area-batch-td-ctrl area-batch-td-select">
356
+ <span v-if="batchGridmanLoading" class="area-batch-loading">加载中…</span>
357
+ <v-select v-else
358
+ :value.sync="batchData.f_replace_gridman" :value-single="true"
359
+ :options='batchGridmanOptions1' placeholder='不修改请留空'
360
+ close-on-select @change="onBatchReplaceChange">
361
+ </v-select>
362
+ </td>
363
+ </tr>
364
+ <tr>
365
+ <th class="area-batch-th">维修网格员</th>
366
+ <td class="area-batch-td-ctrl area-batch-td-select">
367
+ <span v-if="batchGridmanLoading" class="area-batch-loading">加载中…</span>
368
+ <v-select v-else
369
+ :value.sync="batchData.f_repair_gridman" :value-single="true"
370
+ :options='batchGridmanOptions2' placeholder='不修改请留空'
371
+ close-on-select @change="onBatchRepairChange">
372
+ </v-select>
373
+ </td>
374
+ </tr>
375
+ <tr>
376
+ <th class="area-batch-th">工商业网格员</th>
377
+ <td class="area-batch-td-ctrl area-batch-td-select">
378
+ <span v-if="batchGridmanLoading" class="area-batch-loading">加载中…</span>
379
+ <v-select v-else
380
+ :value.sync="batchData.f_industry_gridman" :value-single="true"
381
+ :options='batchGridmanOptions3' placeholder='不修改请留空'
382
+ close-on-select @change="onBatchIndustryChange">
383
+ </v-select>
384
+ </td>
385
+ </tr>
386
+ </table>
387
+ </article>
388
+ <footer slot="modal-footer" class="modal-footer">
389
+ <button class="button_search" @click="confirmBatchModify()">保存</button>
390
+ <button class="button_clear" @click="batchModifyShow = false">取消</button>
391
+ </footer>
392
+ </modal>
173
393
  </div>
174
394
  </template>
175
395
 
176
396
  <script>
177
397
  import { PagedList } from 'vue-client'
398
+ import { HttpResetClass } from 'vue-client'
178
399
 
179
400
  export default {
180
401
 
@@ -182,6 +403,10 @@
182
403
  return {
183
404
  checkall:false,
184
405
  checkitem:[],
406
+ batchCheckall:false,
407
+ batchCheckitem:[],
408
+ batchSelectAll: false,
409
+ batchTotalCount: 0,
185
410
  criteriaShow: false,
186
411
  model: new PagedList('api/af-revenue/sql/address_getarealist',50),
187
412
  addflag: false,
@@ -189,11 +414,64 @@
189
414
  condition:'',
190
415
  // 公司下拉
191
416
  curorgid: [this.$login.f.orgid],
192
- f_orgid: ''
417
+ f_orgid: '',
418
+ // 批量修改
419
+ batchModifyShow: false,
420
+ batchData: {
421
+ f_check_gridman: '',
422
+ f_replace_gridman: '',
423
+ f_repair_gridman: '',
424
+ f_industry_gridman: '',
425
+ f_check_phone: '',
426
+ f_replace_phone: '',
427
+ f_repair_phone: '',
428
+ f_industry_phone: ''
429
+ },
430
+ gridmans: [],
431
+ gridmans1: [],
432
+ gridmans2: [],
433
+ gridmans3: [],
434
+ // 批量修改弹窗的 name → phone 映射
435
+ batchGridmanPhoneMap: {},
436
+ batchGridmanPhoneMap1: {},
437
+ batchGridmanPhoneMap2: {},
438
+ batchGridmanPhoneMap3: {},
439
+ batchSubmitBusy: false,
440
+ batchGridmanLoading: false
193
441
  }
194
442
  },
195
443
  title: '小区管理',
196
444
  computed:{
445
+ /** 全选时用查询总条数;单选时用已勾选的条数(避免只显示当前页 50 条) */
446
+ batchDisplayCount () {
447
+ if (this.batchSelectAll) {
448
+ const n = this.batchTotalCount || (this.model && this.model.count) || 0
449
+ return n
450
+ }
451
+ return this.batchCheckitem.length
452
+ },
453
+ /** 批量弹窗专用:首项 value 为空,选后等同「本列不参与修改」,不影响表格行内编辑的 gridmans */
454
+ // 批量弹窗:去掉 gridmans 里的「全部」首项,只保留「不修改」选项
455
+ batchGridmanOptions () {
456
+ const none = { label: '— 不修改(保持原数据)—', value: '' }
457
+ const src = this.gridmans[0] && this.gridmans[0].value === '' ? this.gridmans.slice(1) : this.gridmans
458
+ return [none, ...src]
459
+ },
460
+ batchGridmanOptions1 () {
461
+ const none = { label: '— 不修改(保持原数据)—', value: '' }
462
+ const src = this.gridmans1[0] && this.gridmans1[0].value === '' ? this.gridmans1.slice(1) : this.gridmans1
463
+ return [none, ...src]
464
+ },
465
+ batchGridmanOptions2 () {
466
+ const none = { label: '— 不修改(保持原数据)—', value: '' }
467
+ const src = this.gridmans2[0] && this.gridmans2[0].value === '' ? this.gridmans2.slice(1) : this.gridmans2
468
+ return [none, ...src]
469
+ },
470
+ batchGridmanOptions3 () {
471
+ const none = { label: '— 不修改(保持原数据)—', value: '' }
472
+ const src = this.gridmans3[0] && this.gridmans3[0].value === '' ? this.gridmans3.slice(1) : this.gridmans3
473
+ return [none, ...src]
474
+ },
197
475
  getCondition() {
198
476
  return {condition: this.condition}
199
477
  },
@@ -239,6 +517,7 @@
239
517
  },
240
518
  ready(){
241
519
  this.search()
520
+ this.initGridmans()
242
521
  },
243
522
  methods: {
244
523
  chooseAll(){
@@ -267,6 +546,33 @@
267
546
  ischecked(row){
268
547
  return this.checkitem.indexOf(row)>-1
269
548
  },
549
+ batchChooseAll(){
550
+ if(this.batchCheckall){
551
+ this.batchSelectAll = true
552
+ // 立刻把当前页所有 id 勾上,不发请求
553
+ if (this.model && this.model.rows && this.model.rows.length > 0) {
554
+ this.batchCheckitem = this.model.rows.map(r => r.id).filter(id => id != null && id !== '')
555
+ }
556
+ this.batchTotalCount = this.model ? this.model.count : 0
557
+ } else {
558
+ this.batchSelectAll = false
559
+ this.batchTotalCount = 0
560
+ this.batchCheckitem = []
561
+ }
562
+ },
563
+ batchChooseOne(e, row, rows) {
564
+ this.batchCheckall = false
565
+ this.batchSelectAll = false
566
+ let checked = e.target.checked;
567
+ if(checked===false){
568
+ this.batchCheckitem.splice(this.batchCheckitem.indexOf(row.id), 1)
569
+ } else {
570
+ this.batchCheckitem.push(row.id)
571
+ }
572
+ },
573
+ isBatchChecked(row){
574
+ return this.batchCheckitem.indexOf(row)>-1
575
+ },
270
576
  operate (f_residential_area_id,f_residential_area) {
271
577
  this.$parent.areaShow = false;
272
578
  this.$parent.usershow=true
@@ -311,6 +617,365 @@
311
617
  })
312
618
 
313
619
 
620
+ },
621
+ // 批量修改网格员
622
+ async batchModify() {
623
+ if (this.batchCheckitem.length < 1) {
624
+ this.$showAlert('请先选择要修改的小区', 'warning', 2000)
625
+ return
626
+ }
627
+ if (this.batchSelectAll && this.model && this.model.count) {
628
+ this.batchTotalCount = this.model.count
629
+ }
630
+ this.batchData = {
631
+ f_check_gridman: '',
632
+ f_replace_gridman: '',
633
+ f_repair_gridman: '',
634
+ f_industry_gridman: '',
635
+ f_check_phone: '',
636
+ f_replace_phone: '',
637
+ f_repair_phone: '',
638
+ f_industry_phone: ''
639
+ }
640
+ this.batchModifyShow = true
641
+ this.batchGridmanLoading = true
642
+ await this.initGridmans()
643
+ this.batchGridmanLoading = false
644
+ },
645
+ // 获取网格员列表
646
+ async initGridmans() {
647
+ try {
648
+ let http = new HttpResetClass()
649
+ let param = {
650
+ tablename: 'AFV4_System.dbo.system_users',
651
+ condition: `roles like '%安检网格员%' and org_id = '${this.$login.f.orgid}'`
652
+ }
653
+ let param1 = {
654
+ tablename: 'AFV4_System.dbo.system_users',
655
+ condition: `roles like '%置换网格员%' and org_id = '${this.$login.f.orgid}'`
656
+ }
657
+ let param2 = {
658
+ tablename: 'AFV4_System.dbo.system_users',
659
+ condition: `roles like '%维修网格员%' and org_id = '${this.$login.f.orgid}'`
660
+ }
661
+ let param3 = {
662
+ tablename: 'AFV4_System.dbo.system_users',
663
+ condition: `roles like '%工商业网格员%' and org_id = '${this.$login.f.orgid}'`
664
+ }
665
+ let res = await http.load('POST', 'api/af-revenue/sql/saleSingleTable', {
666
+ data: param
667
+ }, {
668
+ resolveMsg: null,
669
+ rejectMsg: '获取安检网格员失败!'
670
+ })
671
+ let res1 = await http.load('POST', 'api/af-revenue/sql/saleSingleTable', {
672
+ data: param1
673
+ }, {
674
+ resolveMsg: null,
675
+ rejectMsg: '获取置换网格员失败!'
676
+ })
677
+ let res2 = await http.load('POST', 'api/af-revenue/sql/saleSingleTable', {
678
+ data: param2
679
+ }, {
680
+ resolveMsg: null,
681
+ rejectMsg: '获取维修网格员失败!'
682
+ })
683
+ let res3 = await http.load('POST', 'api/af-revenue/sql/saleSingleTable', {
684
+ data: param3
685
+ }, {
686
+ resolveMsg: null,
687
+ rejectMsg: '获取工商业网格员失败!'
688
+ })
689
+ let arr = []
690
+ let arr1 = []
691
+ let arr2 = []
692
+ let arr3 = []
693
+ this.batchGridmanPhoneMap = {}
694
+ this.batchGridmanPhoneMap1 = {}
695
+ this.batchGridmanPhoneMap2 = {}
696
+ this.batchGridmanPhoneMap3 = {}
697
+ const pickPhone = (row) => {
698
+ if (!row) return ''
699
+ const p = row.phone != null && row.phone !== '' ? row.phone
700
+ : (row.f_phone != null && row.f_phone !== '' ? row.f_phone
701
+ : (row.mobile != null && row.mobile !== '' ? row.mobile : (row.tel || '')))
702
+ return String(p).trim()
703
+ }
704
+ const rowsFromRes = (res) => {
705
+ if (!res || !res.data) return []
706
+ const d = res.data
707
+ if (Array.isArray(d)) return d
708
+ if (d.rows && Array.isArray(d.rows)) return d.rows
709
+ return []
710
+ }
711
+ const list0 = rowsFromRes(res)
712
+ const list1 = rowsFromRes(res1)
713
+ const list2 = rowsFromRes(res2)
714
+ const list3 = rowsFromRes(res3)
715
+ list0.forEach(row => {
716
+ if (row && row.name != null && String(row.name).trim() !== '') {
717
+ const nm = String(row.name).trim()
718
+ arr.push({label: nm, value: nm})
719
+ const ph = pickPhone(row)
720
+ if (ph) this.batchGridmanPhoneMap[nm] = ph
721
+ }
722
+ })
723
+ list1.forEach(row => {
724
+ if (row && row.name != null && String(row.name).trim() !== '') {
725
+ const nm = String(row.name).trim()
726
+ arr1.push({label: nm, value: nm})
727
+ const ph = pickPhone(row)
728
+ if (ph) this.batchGridmanPhoneMap1[nm] = ph
729
+ }
730
+ })
731
+ list2.forEach(row => {
732
+ if (row && row.name != null && String(row.name).trim() !== '') {
733
+ const nm = String(row.name).trim()
734
+ arr2.push({label: nm, value: nm})
735
+ const ph = pickPhone(row)
736
+ if (ph) this.batchGridmanPhoneMap2[nm] = ph
737
+ }
738
+ })
739
+ list3.forEach(row => {
740
+ if (row && row.name != null && String(row.name).trim() !== '') {
741
+ const nm = String(row.name).trim()
742
+ arr3.push({label: nm, value: nm})
743
+ const ph = pickPhone(row)
744
+ if (ph) this.batchGridmanPhoneMap3[nm] = ph
745
+ }
746
+ })
747
+ this.gridmans = [{ label: '全部', value: '' }, ...arr]
748
+ this.gridmans1 = [{ label: '全部', value: '' }, ...arr1]
749
+ this.gridmans2 = [{ label: '全部', value: '' }, ...arr2]
750
+ this.gridmans3 = [{ label: '全部', value: '' }, ...arr3]
751
+ } catch (e) {
752
+ this.gridmans = [{ label: '全部', value: '' }]
753
+ this.gridmans1 = [{ label: '全部', value: '' }]
754
+ this.gridmans2 = [{ label: '全部', value: '' }]
755
+ this.gridmans3 = [{ label: '全部', value: '' }]
756
+ this.batchGridmanPhoneMap = {}
757
+ this.batchGridmanPhoneMap1 = {}
758
+ this.batchGridmanPhoneMap2 = {}
759
+ this.batchGridmanPhoneMap3 = {}
760
+ }
761
+ },
762
+ // 规范化网格员名称(change 可能返回字符串/对象/数组)
763
+ normalizeBatchGridmanName (val) {
764
+ if (val == null || val === '') return ''
765
+ if (typeof val === 'object') {
766
+ const v = val.value != null ? val.value : (val.label != null ? val.label : val.name)
767
+ return v != null ? String(v).trim() : ''
768
+ }
769
+ return String(val).trim()
770
+ },
771
+ // 批量弹窗选中网格员后自动填入电话
772
+ onBatchGridmanChange (type, val) {
773
+ const map = { check: 'batchGridmanPhoneMap', replace: 'batchGridmanPhoneMap1', repair: 'batchGridmanPhoneMap2', industry: 'batchGridmanPhoneMap3' }
774
+ const phoneField = { check: 'f_check_phone', replace: 'f_replace_phone', repair: 'f_repair_phone', industry: 'f_industry_phone' }
775
+ const mapKey = map[type]
776
+ const phoneKey = phoneField[type]
777
+ const name = this.normalizeBatchGridmanName(val)
778
+ if (mapKey && this[mapKey] && name) {
779
+ this.batchData[phoneKey] = this[mapKey][name] || ''
780
+ } else {
781
+ this.batchData[phoneKey] = ''
782
+ }
783
+ },
784
+ onBatchCheckChange (val) { this.onBatchGridmanChange('check', val) },
785
+ onBatchReplaceChange (val) { this.onBatchGridmanChange('replace', val) },
786
+ onBatchRepairChange (val) { this.onBatchGridmanChange('repair', val) },
787
+ onBatchIndustryChange (val) { this.onBatchGridmanChange('industry', val) },
788
+ // 判断 rowId 是否在 ids 里(统一字符串比较,防止 11434 vs "11434" 不匹配)
789
+ idInList (ids, rowId) {
790
+ return ids.some(id => String(id) === String(rowId))
791
+ },
792
+ // 按 ids 顺序从行列表中取出对应行(id 可能为数字或字符串)
793
+ pickRowsByIds (rows, ids) {
794
+ if (!rows || !ids || ids.length === 0) return []
795
+ const m = {}
796
+ rows.forEach(r => {
797
+ if (r && r.id != null) m[String(r.id)] = r
798
+ })
799
+ return ids.map(id => m[String(id)]).filter(Boolean)
800
+ },
801
+ // 批量修改前:拉取选中行的原始行(含 f_check_gridman 等)。列表接口分页,不能只用 pageSize=ids.length(会拿到前 N 条而非选中 id)
802
+ async collectOldGridmanRows (ids) {
803
+ if (!ids || ids.length === 0) return []
804
+ let got = this.model && this.model.rows ? this.pickRowsByIds(this.model.rows, ids) : []
805
+ if (got.length === ids.length) return got
806
+ try {
807
+ let http = new HttpResetClass()
808
+ const opt = { resolveMsg: null, rejectMsg: null, aoteEncrypt: this.model.aoteEncrypt, encryKey: this.model.encryKey }
809
+ const n = Math.max((this.model && this.model.count) || 0, ids.length, 50)
810
+ const url = `${this.model.url}?pageNo=1&pageSize=${n}`
811
+ const res = await http.load('POST', url, { data: this.model.params }, opt)
812
+ let list = res && res.data
813
+ if (list && !Array.isArray(list) && list.rows) list = list.rows
814
+ if (!Array.isArray(list)) return got
815
+ const full = this.pickRowsByIds(list, ids)
816
+ return full.length >= got.length ? full : got
817
+ } catch (e) {
818
+ return got
819
+ }
820
+ },
821
+ // 把「改前网格员」写入 setClause(只写 changedTypes 里的列)
822
+ appendBatchOldGridmanParts (setClause, rows, changedTypes) {
823
+ if (!changedTypes || changedTypes.length === 0) return
824
+ const typeToPair = {
825
+ check: ['f_old_check_gridman', 'f_check_gridman'],
826
+ replace: ['f_old_replace_gridman', 'f_replace_gridman'],
827
+ repair: ['f_old_repair_gridman', 'f_repair_gridman'],
828
+ industry:['f_old_industry_gridman', 'f_industry_gridman']
829
+ }
830
+ const valOf = (row, src) => (row[src] != null && row[src] !== '' ? String(row[src]) : '')
831
+ if (!rows || rows.length === 0) return
832
+ changedTypes.forEach(type => {
833
+ const pair = typeToPair[type]
834
+ if (!pair) return
835
+ const [oldCol, srcCol] = pair
836
+ if (rows.length === 1) {
837
+ setClause.push(oldCol + " = '" + this.escapeSql(valOf(rows[0], srcCol)) + "'")
838
+ } else {
839
+ const first = valOf(rows[0], srcCol)
840
+ if (rows.every(r => valOf(r, srcCol) === first)) {
841
+ setClause.push(oldCol + " = '" + this.escapeSql(first) + "'")
842
+ }
843
+ }
844
+ })
845
+ },
846
+ // 从 v-select 取值(可能为字符串、数组、对象)
847
+ normBatchGridmanVal (v) {
848
+ if (v === null || v === undefined) return null
849
+ if (Array.isArray(v)) {
850
+ if (v.length === 0) return null
851
+ const x = v[0]
852
+ if (x == null) return null
853
+ if (typeof x === 'object') {
854
+ const s = x.value != null ? x.value : x.label
855
+ if (s == null || String(s).trim() === '') return null
856
+ return String(s).trim()
857
+ }
858
+ const t = String(x).trim()
859
+ return t === '' ? null : t
860
+ }
861
+ if (typeof v === 'string') {
862
+ const t = v.trim()
863
+ return t === '' ? null : t
864
+ }
865
+ const t = String(v).trim()
866
+ return t === '' ? null : t
867
+ },
868
+ // 确认批量修改:只提交已选择的网格员字段及对应电话(前端拼接 setClause)
869
+ async confirmBatchModify() {
870
+ const c = this.normBatchGridmanVal(this.batchData.f_check_gridman)
871
+ const r = this.normBatchGridmanVal(this.batchData.f_replace_gridman)
872
+ const rp = this.normBatchGridmanVal(this.batchData.f_repair_gridman)
873
+ const ind = this.normBatchGridmanVal(this.batchData.f_industry_gridman)
874
+ const parts = []
875
+ const labels = []
876
+ // changedTypes 标记实际修改了哪几列,只对这些列写入 f_old_*
877
+ const changedTypes = []
878
+ if (c != null) {
879
+ parts.push("f_check_gridman = '" + this.escapeSql(c) + "'")
880
+ parts.push("f_check_phone = '" + this.escapeSql(this.batchData.f_check_phone || '') + "'")
881
+ labels.push('安检网格员')
882
+ changedTypes.push('check')
883
+ }
884
+ if (r != null) {
885
+ parts.push("f_replace_gridman = '" + this.escapeSql(r) + "'")
886
+ parts.push("f_replace_phone = '" + this.escapeSql(this.batchData.f_replace_phone || '') + "'")
887
+ labels.push('置换网格员')
888
+ changedTypes.push('replace')
889
+ }
890
+ if (rp != null) {
891
+ parts.push("f_repair_gridman = '" + this.escapeSql(rp) + "'")
892
+ parts.push("f_repair_phone = '" + this.escapeSql(this.batchData.f_repair_phone || '') + "'")
893
+ labels.push('维修网格员')
894
+ changedTypes.push('repair')
895
+ }
896
+ if (ind != null) {
897
+ parts.push("f_industry_gridman = '" + this.escapeSql(ind) + "'")
898
+ parts.push("f_industry_phone = '" + this.escapeSql(this.batchData.f_industry_phone || '') + "'")
899
+ labels.push('工商业网格员')
900
+ changedTypes.push('industry')
901
+ }
902
+ if (parts.length === 0) {
903
+ this.$showAlert('请至少选择一项要修改的网格员', 'warning', 2000)
904
+ return
905
+ }
906
+ const setClause = parts
907
+
908
+ // 全选模式:先请求全量 id,再弹确认
909
+ if (this.batchSelectAll) {
910
+ if (!this.model || this.model.state !== '正确' || !this.model.count) {
911
+ this.$showAlert('查询数据已失效,请重新查询后再试', 'warning', 2000)
912
+ return
913
+ }
914
+ this._doBatchSubmit(setClause, labels, this.model.count, true, changedTypes)
915
+ } else {
916
+ if (this.batchCheckitem.length === 0) {
917
+ this.$showAlert('请先选择要修改的小区', 'warning', 2000)
918
+ return
919
+ }
920
+ this._doBatchSubmit(setClause, labels, this.batchCheckitem.length, false, changedTypes)
921
+ }
922
+ },
923
+ // SQL 字符串转义,防止注入
924
+ escapeSql(val) {
925
+ if (val == null) return ''
926
+ return String(val).replace(/'/g, "''")
927
+ },
928
+ // 统一提交逻辑
929
+ // setClause: string[] 待更新的字段 parts,函数内部追加 f_old_* 字段后再 join
930
+ // fromAllSelect: bool 是否全选模式(需要自行拉 id + 旧数据)
931
+ // changedTypes: string[] 实际修改了哪些列(如 ['check']),只对这些列写入 f_old_*
932
+ async _doBatchSubmit(setClause, labels, count, fromAllSelect, changedTypes) {
933
+ const payload = { ids: null, setClause: '' }
934
+ const msg = `共计修改${count}个小区,将更新:${labels.join('、')},请确认`
935
+ const confirmed = await this.$showMessage(msg, ['confirm', 'cancel'])
936
+ if (confirmed !== 'confirm') return
937
+ this.batchSubmitBusy = true
938
+ try {
939
+ if (fromAllSelect) {
940
+ if (!this.model || this.model.state !== '正确' || !this.model.count) {
941
+ this.$showAlert('查询数据已失效,请重新查询后再试', 'warning', 2000)
942
+ return
943
+ }
944
+ try {
945
+ let http = new HttpResetClass()
946
+ const opt = { resolveMsg: null, rejectMsg: null, aoteEncrypt: this.model.aoteEncrypt, encryKey: this.model.encryKey }
947
+ const url = `${this.model.url}?pageNo=1&pageSize=${this.model.count}`
948
+ const res2 = await http.load('POST', url, { data: this.model.params }, opt)
949
+ let list = res2 && res2.data
950
+ if (list && !Array.isArray(list) && list.rows) list = list.rows
951
+ if (Array.isArray(list) && list.length > 0) {
952
+ payload.ids = list.map(r => r.id).filter(id => id != null && id !== '')
953
+ const targetRows = list.filter(r => this.idInList(payload.ids, r.id))
954
+ this.appendBatchOldGridmanParts(setClause, targetRows, changedTypes)
955
+ }
956
+ } catch (e) { /* ignore */ }
957
+ if (!payload.ids || payload.ids.length === 0) {
958
+ this.$showAlert('全选数据获取失败,无法提交', 'warning', 2000)
959
+ return
960
+ }
961
+ } else {
962
+ payload.ids = this.batchCheckitem
963
+ const targetRows = await this.collectOldGridmanRows(this.batchCheckitem)
964
+ this.appendBatchOldGridmanParts(setClause, targetRows, changedTypes)
965
+ }
966
+ payload.setClause = setClause.join(',')
967
+ await this.$resetpost('api/af-revenue/logic/batchUpdateGridman', payload, {
968
+ resolveMsg: '批量修改成功',
969
+ rejectMsg: '批量修改失败'
970
+ })
971
+ this.batchModifyShow = false
972
+ this.batchCheckitem = []
973
+ this.batchCheckall = false
974
+ this.batchSelectAll = false
975
+ this.search()
976
+ } finally {
977
+ this.batchSubmitBusy = false
978
+ }
314
979
  },
315
980
  add(val){
316
981
  if (this.f_filialeids) {
@@ -326,6 +991,10 @@
326
991
  },
327
992
  selfSearch (args) {
328
993
  this.checkall = false;
994
+ this.batchCheckall = false;
995
+ this.batchCheckitem = [];
996
+ this.batchSelectAll = false;
997
+ this.batchTotalCount = 0;
329
998
  this.$parent.usershow = false;
330
999
  this.$parent.areaShow = false;
331
1000
  if (!this.f_orgid) {
@@ -355,3 +1024,58 @@
355
1024
 
356
1025
  }
357
1026
  </script>
1027
+
1028
+ <style>
1029
+ .area-batch-gridman-body {
1030
+ padding: 12px 20px 18px;
1031
+ box-sizing: border-box;
1032
+ }
1033
+ .area-batch-hint {
1034
+ margin: 0 0 12px;
1035
+ color: #666;
1036
+ font-size: 13px;
1037
+ }
1038
+ .batch-select-tip {
1039
+ font-size: 13px;
1040
+ font-weight: normal;
1041
+ color: #e6a23c;
1042
+ margin-left: 8px;
1043
+ }
1044
+ .area-batch-gridman-table {
1045
+ width: 100%;
1046
+ margin: 0;
1047
+ table-layout: fixed;
1048
+ border-collapse: separate;
1049
+ border-spacing: 0 12px;
1050
+ }
1051
+ .area-batch-gridman-table .area-batch-col-label-l {
1052
+ width: 9em;
1053
+ }
1054
+ .area-batch-gridman-table .area-batch-col-select {
1055
+ width: auto;
1056
+ }
1057
+ .area-batch-loading {
1058
+ color: #999;
1059
+ font-size: 13px;
1060
+ padding: 6px 0;
1061
+ display: inline-block;
1062
+ }
1063
+ .area-batch-gridman-table .area-batch-th {
1064
+ font-weight: normal;
1065
+ text-align: right;
1066
+ vertical-align: middle;
1067
+ white-space: nowrap;
1068
+ padding: 0 12px 0 0;
1069
+ border: none;
1070
+ overflow: visible;
1071
+ }
1072
+ .area-batch-gridman-table .area-batch-td-ctrl {
1073
+ vertical-align: middle;
1074
+ padding: 0;
1075
+ border: none;
1076
+ overflow: visible;
1077
+ }
1078
+ .area-batch-gridman-table .area-batch-td-select {
1079
+ padding-right: 0;
1080
+ }
1081
+ </style>