|
...
|
...
|
@@ -135,6 +135,29 @@ |
|
135
|
135
|
title="科办"
|
|
136
|
136
|
@confirm="onOfficeConfirm"
|
|
137
|
137
|
/>
|
|
|
138
|
+ <!-- 批量:统一弹框(通过/驳回) -->
|
|
|
139
|
+ <uni-popup ref="approvePopup" type="center" :mask-click="false">
|
|
|
140
|
+ <view class="action-modal">
|
|
|
141
|
+ <view class="header">{{ approveType === 'PASS' ? '通过' : '驳回' }}</view>
|
|
|
142
|
+ <view class="body">
|
|
|
143
|
+ <text class="tip">
|
|
|
144
|
+ {{ approveType === 'PASS' ? '您将通过该信息的审核' : '您将驳回该信息的审核' }}
|
|
|
145
|
+ </text>
|
|
|
146
|
+ <uni-easyinput
|
|
|
147
|
+ v-model="approveComment"
|
|
|
148
|
+ :placeholder="approveType === 'PASS' ? '请输入通过原因' : '请输入驳回原因'"
|
|
|
149
|
+ />
|
|
|
150
|
+ </view>
|
|
|
151
|
+ <view class="footer">
|
|
|
152
|
+ <button class="btn cancel" @click="cancelApprove">取消</button>
|
|
|
153
|
+ <button
|
|
|
154
|
+ class="btn confirm"
|
|
|
155
|
+ type="primary"
|
|
|
156
|
+ @click="confirmApprove"
|
|
|
157
|
+ >{{ approveType === 'PASS' ? '通过' : '驳回' }}</button>
|
|
|
158
|
+ </view>
|
|
|
159
|
+ </view>
|
|
|
160
|
+ </uni-popup>
|
|
138
|
161
|
</view>
|
|
139
|
162
|
</template>
|
|
140
|
163
|
|
|
...
|
...
|
@@ -142,7 +165,7 @@ |
|
142
|
165
|
import CardList from '@/components/card/index.vue'
|
|
143
|
166
|
import FilterModal from '@/components/filter/index.vue'
|
|
144
|
167
|
import SingleSelectSheet from '@/components/single-select/index.vue'
|
|
145
|
|
-import { queryApi, officeQueryApi, statusOptions, getTodoTypeStatisticsApi } from '@/api/devManage.js'
|
|
|
168
|
+import { queryApi, officeQueryApi, statusOptions, getTodoTypeStatisticsApi, batchApproveApi } from '@/api/devManage.js'
|
|
146
|
169
|
import {getDicByCodes, getDicName} from '@/utils/dic';
|
|
147
|
170
|
|
|
148
|
171
|
export default {
|
|
...
|
...
|
@@ -150,6 +173,7 @@ export default { |
|
150
|
173
|
data() {
|
|
151
|
174
|
return {
|
|
152
|
175
|
searchKeyword: '',
|
|
|
176
|
+ searchKeywordDebounced: '',
|
|
153
|
177
|
officeList: [], // 科办列表下拉选
|
|
154
|
178
|
tabs: [],
|
|
155
|
179
|
todoType: '',
|
|
...
|
...
|
@@ -180,7 +204,9 @@ export default { |
|
180
|
204
|
// 批量选择
|
|
181
|
205
|
batchMode: false,
|
|
182
|
206
|
selectedKeys: [],
|
|
183
|
|
- rowKey: 'customerId',
|
|
|
207
|
+ rowKey: 'id',
|
|
|
208
|
+ selectedRows: [],
|
|
|
209
|
+ currentItems: [],
|
|
184
|
210
|
|
|
185
|
211
|
// 筛选弹框
|
|
186
|
212
|
filterVisible: false,
|
|
...
|
...
|
@@ -188,12 +214,15 @@ export default { |
|
188
|
214
|
officeSelectVisible: false,
|
|
189
|
215
|
// 审核状态枚举(来自 api/devManage.js)
|
|
190
|
216
|
statusOptions,
|
|
|
217
|
+ // 批量操作弹框数据
|
|
|
218
|
+ approveType: 'PASS', // PASS:通过;REFUSE:驳回
|
|
|
219
|
+ approveComment: ''
|
|
191
|
220
|
}
|
|
192
|
221
|
},
|
|
193
|
222
|
computed: {
|
|
194
|
223
|
extraCombined() {
|
|
195
|
224
|
return {
|
|
196
|
|
- keyword: this.searchKeyword,
|
|
|
225
|
+ customerName: this.searchKeywordDebounced || undefined,
|
|
197
|
226
|
todoType: this.todoType || undefined,
|
|
198
|
227
|
workshopType: this.workshopType || undefined
|
|
199
|
228
|
}
|
|
...
|
...
|
@@ -206,6 +235,13 @@ export default { |
|
206
|
235
|
this.extraParams = v
|
|
207
|
236
|
},
|
|
208
|
237
|
immediate: true
|
|
|
238
|
+ },
|
|
|
239
|
+ // 勾选变化时同步 selectedRows
|
|
|
240
|
+ selectedKeys: {
|
|
|
241
|
+ deep: true,
|
|
|
242
|
+ handler() {
|
|
|
243
|
+ this.updateSelectedRows()
|
|
|
244
|
+ }
|
|
209
|
245
|
}
|
|
210
|
246
|
},
|
|
211
|
247
|
created() {
|
|
...
|
...
|
@@ -229,42 +265,36 @@ export default { |
|
229
|
265
|
methods: {
|
|
230
|
266
|
onCardLoaded({ items }) {
|
|
231
|
267
|
this.currentItems = items
|
|
|
268
|
+ this.updateSelectedRows()
|
|
232
|
269
|
},
|
|
233
|
270
|
onCardError() {
|
|
234
|
271
|
uni.showToast({ title: '列表加载失败', icon: 'none' })
|
|
235
|
272
|
},
|
|
236
|
|
- onSearch() {
|
|
237
|
|
- this.extraParams = { ...this.extraParams, keyword: this.searchKeyword }
|
|
238
|
|
- },
|
|
239
|
|
- // 输入实时搜索:300ms 防抖更新关键字并触发 CardList 刷新
|
|
|
273
|
+ // 输入实时搜索:1200ms 防抖,仅在停止输入超过阈值后刷新
|
|
240
|
274
|
onSearchInput(val) {
|
|
241
|
|
- this.searchKeyword = typeof val === 'string' ? val : (val && val.value) ? val.value : this.searchKeyword
|
|
242
|
275
|
if (this.searchDebounceTimer) clearTimeout(this.searchDebounceTimer)
|
|
243
|
276
|
this.searchDebounceTimer = setTimeout(() => {
|
|
244
|
|
- this.extraParams = { ...this.extraParams, keyword: this.searchKeyword }
|
|
|
277
|
+ this.searchKeywordDebounced = this.searchKeyword
|
|
245
|
278
|
this.searchDebounceTimer = null
|
|
246
|
|
- }, 300)
|
|
|
279
|
+ }, 1200)
|
|
247
|
280
|
},
|
|
248
|
281
|
// uni-search-bar 确认搜索:更新关键字并触发 CardList 刷新
|
|
249
|
282
|
search(e) {
|
|
250
|
283
|
const val = e && e.value != null ? e.value : this.searchKeyword
|
|
251
|
284
|
this.searchKeyword = val
|
|
252
|
|
- this.extraParams = { ...this.extraParams, keyword: val }
|
|
|
285
|
+ this.searchKeywordDebounced = val
|
|
253
|
286
|
},
|
|
254
|
287
|
switchTab(item) {
|
|
255
|
288
|
this.todoType = item.value;
|
|
256
|
|
- this.extraParams = { ...this.extraParams, todoType: item.value }
|
|
257
|
289
|
},
|
|
258
|
290
|
switchWorkshopType(item, i) {
|
|
259
|
291
|
this.workshopType = item.value;
|
|
260
|
292
|
this.currentWorkshopTypeIndex = i;
|
|
261
|
|
- this.extraParams = { ...this.extraParams, workshopType: item.value }
|
|
262
|
293
|
},
|
|
263
|
294
|
openFilter() {
|
|
264
|
295
|
this.filterVisible = true
|
|
265
|
296
|
},
|
|
266
|
297
|
onFilterReset(payload) {
|
|
267
|
|
- console.log('onFilterReset',payload)
|
|
268
|
298
|
// 保持弹框不关闭,仅同步表单
|
|
269
|
299
|
this.filterForm = payload
|
|
270
|
300
|
},
|
|
...
|
...
|
@@ -297,13 +327,45 @@ export default { |
|
297
|
327
|
this.batchMode = !this.batchMode
|
|
298
|
328
|
if (!this.batchMode) this.selectedKeys = []
|
|
299
|
329
|
},
|
|
|
330
|
+ // 根据 selectedKeys 与当前页 items 计算选中行对象
|
|
|
331
|
+ updateSelectedRows() {
|
|
|
332
|
+ const key = this.rowKey || 'id'
|
|
|
333
|
+ const keys = Array.isArray(this.selectedKeys) ? this.selectedKeys : []
|
|
|
334
|
+ const items = Array.isArray(this.currentItems) ? this.currentItems : []
|
|
|
335
|
+ this.selectedRows = items.filter(it => keys.includes(it && it[key]))
|
|
|
336
|
+ },
|
|
300
|
337
|
batchReject() {
|
|
301
|
338
|
if (this.selectedKeys.length === 0) return uni.showToast({ title: '请选择记录', icon: 'none' })
|
|
302
|
|
- uni.showToast({ title: '已发起驳回', icon: 'none' })
|
|
|
339
|
+ this.approveType = 'REFUSE'
|
|
|
340
|
+ this.approveComment = ''
|
|
|
341
|
+ this.$refs.approvePopup && this.$refs.approvePopup.open()
|
|
303
|
342
|
},
|
|
304
|
343
|
batchPass() {
|
|
305
|
344
|
if (this.selectedKeys.length === 0) return uni.showToast({ title: '请选择记录', icon: 'none' })
|
|
306
|
|
- uni.showToast({ title: '已发起通过', icon: 'none' })
|
|
|
345
|
+ this.approveType = 'PASS'
|
|
|
346
|
+ this.approveComment = ''
|
|
|
347
|
+ this.$refs.approvePopup && this.$refs.approvePopup.open()
|
|
|
348
|
+ },
|
|
|
349
|
+ cancelApprove() {
|
|
|
350
|
+ this.$refs.approvePopup && this.$refs.approvePopup.close()
|
|
|
351
|
+ this.approveComment = ''
|
|
|
352
|
+ },
|
|
|
353
|
+ async confirmApprove() {
|
|
|
354
|
+ this.flowTaskIds = this.selectedRows.map((item) => item.flowTaskId || '' + "");
|
|
|
355
|
+ batchApproveApi({ taskIds: this.flowTaskIds, approveType: this.approveType, message: this.approveComment }).then((res) => {
|
|
|
356
|
+ console.log('batchApproveApi_res', res)
|
|
|
357
|
+ uni.showToast({ title: this.approveType === 'PASS' ? '已通过' : '已驳回', icon: 'none' })
|
|
|
358
|
+ this.$refs.approvePopup && this.$refs.approvePopup.close()
|
|
|
359
|
+ this.approveComment = '';
|
|
|
360
|
+ this.selectedKeys = [];
|
|
|
361
|
+ this.selectedRows = [];
|
|
|
362
|
+ this.batchMode = false;
|
|
|
363
|
+ this.$refs.cardRef && this.$refs.cardRef.reload && this.$refs.cardRef.reload();
|
|
|
364
|
+ this.getTodoTypeStatisticsFun()
|
|
|
365
|
+ }).catch(() => {
|
|
|
366
|
+ console.error('confirmApprove error', e)
|
|
|
367
|
+ uni.showToast({ title: '操作失败', icon: 'none' })
|
|
|
368
|
+ })
|
|
307
|
369
|
},
|
|
308
|
370
|
onAdd() {
|
|
309
|
371
|
uni.showToast({ title: '点击新增', icon: 'none' })
|
|
...
|
...
|
@@ -317,9 +379,9 @@ export default { |
|
317
|
379
|
params.createEndTime = params.dateRange[1] + ' 23:59:59'
|
|
318
|
380
|
delete params.dateRange
|
|
319
|
381
|
}
|
|
320
|
|
- // 关键字
|
|
321
|
|
- if (this.searchKeyword) {
|
|
322
|
|
- params.keyword = this.searchKeyword
|
|
|
382
|
+ // 关键字(使用去抖后的值避免频繁触发)
|
|
|
383
|
+ if (this.searchKeywordDebounced) {
|
|
|
384
|
+ params.customerName = this.searchKeywordDebounced
|
|
323
|
385
|
}
|
|
324
|
386
|
return queryApi(params)
|
|
325
|
387
|
.then(res => {
|
|
...
|
...
|
@@ -633,4 +695,55 @@ export default { |
|
633
|
695
|
|
|
634
|
696
|
}
|
|
635
|
697
|
|
|
|
698
|
+.action-modal {
|
|
|
699
|
+ width: 560rpx;
|
|
|
700
|
+ padding: 32rpx 28rpx 20rpx;
|
|
|
701
|
+ background: #fff;
|
|
|
702
|
+ border-radius: 20rpx;
|
|
|
703
|
+ .header {
|
|
|
704
|
+ text-align: center;
|
|
|
705
|
+ font-size: 34rpx;
|
|
|
706
|
+ font-weight: 600;
|
|
|
707
|
+ margin-bottom: 12rpx;
|
|
|
708
|
+ color: rgba(0,0,0,0.9);
|
|
|
709
|
+ }
|
|
|
710
|
+ .body {
|
|
|
711
|
+ padding: 12rpx 4rpx 24rpx;
|
|
|
712
|
+ .tip {
|
|
|
713
|
+ display: block;
|
|
|
714
|
+ text-align: center;
|
|
|
715
|
+ font-size: 32rpx;
|
|
|
716
|
+ color: rgba(0,0,0,0.6);
|
|
|
717
|
+ margin-bottom: 32rpx;
|
|
|
718
|
+ }
|
|
|
719
|
+ ::v-deep .uni-easyinput {
|
|
|
720
|
+ width: 100%;
|
|
|
721
|
+ }
|
|
|
722
|
+ }
|
|
|
723
|
+ .footer {
|
|
|
724
|
+ display: flex;
|
|
|
725
|
+ justify-content: space-between;
|
|
|
726
|
+ gap: 16rpx;
|
|
|
727
|
+ .btn {
|
|
|
728
|
+ flex: 1;
|
|
|
729
|
+ height: 80rpx;
|
|
|
730
|
+ line-height: 80rpx;
|
|
|
731
|
+ border-radius: 12rpx;
|
|
|
732
|
+ font-size: 30rpx;
|
|
|
733
|
+ font-size: 32rpx;
|
|
|
734
|
+ &::after {
|
|
|
735
|
+ border: none;
|
|
|
736
|
+ }
|
|
|
737
|
+ }
|
|
|
738
|
+ .cancel {
|
|
|
739
|
+ background: #fff;
|
|
|
740
|
+ color: rgba(0,0,0,0.9);
|
|
|
741
|
+ }
|
|
|
742
|
+ .confirm {
|
|
|
743
|
+ background: #fff !important;
|
|
|
744
|
+ color: $theme-primary !important;
|
|
|
745
|
+ }
|
|
|
746
|
+ }
|
|
|
747
|
+}
|
|
|
748
|
+
|
|
636
|
749
|
</style> |
|
|
\ No newline at end of file |
...
|
...
|
|