unicloud-db.vue 13.0 KB
Newer Older
d-u-a's avatar
d-u-a 已提交
1 2
<template>
  <view>
d-u-a's avatar
d-u-a 已提交
3 4 5 6 7
    <slot
      :options="options"
      :data="dataList"
      :pagination="paginationInternal"
      :loading="loading"
d-u-a's avatar
d-u-a 已提交
8
      :hasMore="hasMore"
d-u-a's avatar
d-u-a 已提交
9 10
      :error="errorMessage"
    />
d-u-a's avatar
d-u-a 已提交
11 12 13 14
  </view>
</template>

<script>
fxy060608's avatar
fxy060608 已提交
15 16 17 18
import { initVueI18n } from '@dcloudio/uni-i18n'
import messages from './i18n/index'

const { t } = initVueI18n(messages)
fxy060608's avatar
fxy060608 已提交
19

d-u-a's avatar
d-u-a 已提交
20 21 22 23 24 25 26 27
const events = {
  load: 'load',
  error: 'error'
}
const pageMode = {
  add: 'add',
  replace: 'replace'
}
28 29 30 31 32
const loadMode = {
  auto: 'auto',
  onready: 'onready',
  manual: 'manual'
}
d-u-a's avatar
d-u-a 已提交
33

d-u-a's avatar
d-u-a 已提交
34 35 36 37 38 39 40 41
const attrs = [
  'pageCurrent',
  'pageSize',
  'collection',
  'action',
  'field',
  'getcount',
  'orderby',
42 43 44 45
  'where',
  'groupby',
  'groupField',
  'distinct'
d-u-a's avatar
d-u-a 已提交
46
]
d-u-a's avatar
d-u-a 已提交
47

d-u-a's avatar
d-u-a 已提交
48 49 50 51 52 53 54
export default {
  name: 'UniClouddb',
  props: {
    options: {
      type: [Object, Array],
      default () {
        return {}
d-u-a's avatar
d-u-a 已提交
55 56
      }
    },
d-u-a's avatar
d-u-a 已提交
57 58 59
    collection: {
      type: String,
      default: ''
d-u-a's avatar
d-u-a 已提交
60
    },
d-u-a's avatar
d-u-a 已提交
61 62 63 64 65 66 67 68
    action: {
      type: String,
      default: ''
    },
    field: {
      type: String,
      default: ''
    },
69 70 71 72 73 74 75 76
    orderby: {
      type: String,
      default: ''
    },
    where: {
      type: [String, Object],
      default: ''
    },
d-u-a's avatar
d-u-a 已提交
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    pageData: {
      type: String,
      default: 'add'
    },
    pageCurrent: {
      type: Number,
      default: 1
    },
    pageSize: {
      type: Number,
      default: 20
    },
    getcount: {
      type: [Boolean, String],
      default: false
    },
93 94 95 96 97
    getone: {
      type: [Boolean, String],
      default: false
    },
    gettree: {
98
      type: [Boolean, String, Object],
99 100
      default: false
    },
101 102 103 104
    gettreepath: {
      type: [Boolean, String],
      default: false
    },
105
    startwith: {
d-u-a's avatar
d-u-a 已提交
106 107 108
      type: String,
      default: ''
    },
109 110 111
    limitlevel: {
      type: Number,
      default: 10
d-u-a's avatar
d-u-a 已提交
112
    },
113 114 115 116 117 118 119 120 121 122 123
    groupby: {
      type: String,
      default: ''
    },
    groupField: {
      type: String,
      default: ''
    },
    distinct: {
      type: [Boolean, String],
      default: false
124
    },
125 126 127 128
    pageIndistinct: {
      type: [Boolean, String],
      default: false
    },
129 130 131 132
    exceptForeignKey: {
      type: String,
      default: ''
    },
133 134 135 136
    loadtime: {
      type: String,
      default: 'auto'
    },
137 138 139
    manual: {
      type: Boolean,
      default: false
d-u-a's avatar
d-u-a 已提交
140 141 142 143 144
    }
  },
  data () {
    return {
      loading: false,
d-u-a's avatar
d-u-a 已提交
145
      hasMore: false,
146
      dataList: this.getone ? undefined : [],
147
      paginationInternal: {},
d-u-a's avatar
d-u-a 已提交
148 149 150 151 152
      errorMessage: ''
    }
  },
  created () {
    this._isEnded = false
153 154 155 156 157
    this.paginationInternal = {
      current: this.pageCurrent,
      size: this.pageSize,
      count: 0
    }
d-u-a's avatar
d-u-a 已提交
158

d-u-a's avatar
d-u-a 已提交
159 160 161 162 163 164 165
    this.$watch(() => {
      var al = []
      attrs.forEach(key => {
        al.push(this[key])
      })
      return al
    }, (newValue, oldValue) => {
166 167 168 169
      if (this.loadtime === loadMode.manual) {
        return
      }

170
      this.paginationInternal.size = this.pageSize
d-u-a's avatar
d-u-a 已提交
171

d-u-a's avatar
d-u-a 已提交
172 173 174 175 176
      let needReset = false
      for (let i = 2; i < newValue.length; i++) {
        if (newValue[i] !== oldValue[i]) {
          needReset = true
          break
d-u-a's avatar
d-u-a 已提交
177
        }
d-u-a's avatar
d-u-a 已提交
178 179 180 181 182 183 184 185
      }
      if (needReset) {
        this.clear()
        this.reset()
      }
      if (newValue[0] !== oldValue[0]) {
        this.paginationInternal.current = this.pageCurrent
      }
d-u-a's avatar
d-u-a 已提交
186

d-u-a's avatar
d-u-a 已提交
187 188
      this._execLoadData()
    })
d-u-a's avatar
d-u-a 已提交
189

d-u-a's avatar
d-u-a 已提交
190 191 192 193 194 195 196
    // #ifdef H5
    if (process.env.NODE_ENV === 'development') {
      this._debugDataList = []
      if (!window.unidev) {
        window.unidev = {
          clientDB: {
            data: []
d-u-a's avatar
d-u-a 已提交
197 198 199
          }
        }
      }
d-u-a's avatar
d-u-a 已提交
200 201 202
      window.unidev.clientDB.data.push(this._debugDataList)
    }
    // #endif
d-u-a's avatar
d-u-a 已提交
203

d-u-a's avatar
d-u-a 已提交
204 205 206 207 208 209 210
    // #ifdef MP-TOUTIAO
    let changeName
    const events = this.$scope.dataset.eventOpts
    for (var i = 0; i < events.length; i++) {
      const event = events[i]
      if (event[0].includes('^load')) {
        changeName = event[1][0][0]
d-u-a's avatar
d-u-a 已提交
211
      }
d-u-a's avatar
d-u-a 已提交
212 213 214 215 216 217 218 219 220 221 222
    }
    if (changeName) {
      let parent = this.$parent
      let maxDepth = 16
      this._changeDataFunction = null
      while (parent && maxDepth > 0) {
        const fun = parent[changeName]
        if (fun && typeof fun === 'function') {
          this._changeDataFunction = fun
          maxDepth = 0
          break
d-u-a's avatar
d-u-a 已提交
223
        }
d-u-a's avatar
d-u-a 已提交
224 225
        parent = parent.$parent
        maxDepth--
d-u-a's avatar
d-u-a 已提交
226
      }
d-u-a's avatar
d-u-a 已提交
227 228
    }
    // #endif
d-u-a's avatar
d-u-a 已提交
229

230
    if (!this.manual && this.loadtime === loadMode.auto) {
d-u-a's avatar
d-u-a 已提交
231 232 233 234 235 236 237 238 239 240 241 242
      this.loadData()
    }
  },
  // #ifdef H5
  beforeDestroy () {
    if (process.env.NODE_ENV === 'development' && window.unidev) {
      var cd = this._debugDataList
      var dl = window.unidev.clientDB.data
      for (var i = dl.length - 1; i >= 0; i--) {
        if (dl[i] === cd) {
          dl.splice(i, 1)
          break
d-u-a's avatar
d-u-a 已提交
243 244
        }
      }
d-u-a's avatar
d-u-a 已提交
245 246 247 248 249 250
    }
  },
  // #endif
  methods: {
    loadData (args1, args2) {
      let callback = null
251
      let clear = false
d-u-a's avatar
d-u-a 已提交
252 253
      if (typeof args1 === 'object') {
        if (args1.clear) {
254 255 256 257 258
          if (this.pageData === pageMode.replace) {
            this.clear()
          } else {
            clear = args1.clear
          }
d-u-a's avatar
d-u-a 已提交
259
          this.reset()
d-u-a's avatar
d-u-a 已提交
260
        }
d-u-a's avatar
d-u-a 已提交
261 262
        if (args1.current !== undefined) {
          this.paginationInternal.current = args1.current
d-u-a's avatar
d-u-a 已提交
263
        }
d-u-a's avatar
d-u-a 已提交
264 265
        if (typeof args2 === 'function') {
          callback = args2
d-u-a's avatar
d-u-a 已提交
266
        }
d-u-a's avatar
d-u-a 已提交
267 268 269 270
      } else if (typeof args1 === 'function') {
        callback = args1
      }

271
      this._execLoadData(callback, clear)
d-u-a's avatar
d-u-a 已提交
272 273
    },
    loadMore () {
274
      if (this._isEnded || this.loading) {
d-u-a's avatar
d-u-a 已提交
275 276
        return
      }
277 278 279 280 281

      if (this.pageData === pageMode.add) {
        this.paginationInternal.current++
      }

d-u-a's avatar
d-u-a 已提交
282 283 284 285 286 287 288 289 290 291 292 293 294 295
      this._execLoadData()
    },
    refresh () {
      this.clear()
      this._execLoadData()
    },
    clear () {
      this._isEnded = false
      this.dataList = []
    },
    reset () {
      this.paginationInternal.current = 1
    },
    add (value, {
296 297
      action,
      showToast = true,
d-u-a's avatar
d-u-a 已提交
298 299 300
      toastTitle,
      success,
      fail,
301 302 303 304
      complete,
      needConfirm = true,
      needLoading = true,
      loadingTitle = ''
d-u-a's avatar
d-u-a 已提交
305
    } = {}) {
306 307 308 309 310
      if (needLoading) {
        uni.showLoading({
          title: loadingTitle
        })
      }
d-u-a's avatar
d-u-a 已提交
311
      /* eslint-disable no-undef */
312 313 314 315 316
      let db = uniCloud.database()
      if (action) {
        db = db.action(action)
      }

d-u-a's avatar
d-u-a 已提交
317 318
      db.collection(this.collection).add(value).then((res) => {
        success && success(res)
319 320
        if (showToast) {
          uni.showToast({
fxy060608's avatar
fxy060608 已提交
321
            title: toastTitle || t('uniCloud.component.add.success')
322 323
          })
        }
d-u-a's avatar
d-u-a 已提交
324 325
      }).catch((err) => {
        fail && fail(err)
326 327 328 329 330 331
        if (needConfirm) {
          uni.showModal({
            content: err.message,
            showCancel: false
          })
        }
d-u-a's avatar
d-u-a 已提交
332
      }).finally(() => {
333 334 335
        if (needLoading) {
          uni.hideLoading()
        }
d-u-a's avatar
d-u-a 已提交
336 337 338 339 340 341 342 343 344
        complete && complete()
      })
    },
    remove (id, {
      action,
      success,
      fail,
      complete,
      confirmTitle,
345 346 347 348
      confirmContent,
      needConfirm = true,
      needLoading = true,
      loadingTitle = ''
d-u-a's avatar
d-u-a 已提交
349 350 351 352
    } = {}) {
      if (!id || !id.length) {
        return
      }
353 354 355 356
      if (!needConfirm) {
        this._execRemove(id, action, success, fail, complete, needConfirm, needLoading, loadingTitle)
        return
      }
d-u-a's avatar
d-u-a 已提交
357
      uni.showModal({
fxy060608's avatar
fxy060608 已提交
358 359
        title: confirmTitle || t('uniCloud.component.remove.showModal.title'),
        content: confirmContent || t('uniCloud.component.remove.showModal.content'),
d-u-a's avatar
d-u-a 已提交
360 361 362 363
        showCancel: true,
        success: (res) => {
          if (!res.confirm) {
            return
d-u-a's avatar
d-u-a 已提交
364
          }
365
          this._execRemove(id, action, success, fail, complete, needConfirm, needLoading, loadingTitle)
d-u-a's avatar
d-u-a 已提交
366 367 368 369
        }
      })
    },
    update (id, value, {
370 371
      action,
      showToast = true,
d-u-a's avatar
d-u-a 已提交
372 373 374
      toastTitle,
      success,
      fail,
375 376 377 378
      complete,
      needConfirm = true,
      needLoading = true,
      loadingTitle = ''
d-u-a's avatar
d-u-a 已提交
379
    } = {}) {
380 381 382 383 384
      if (needLoading) {
        uni.showLoading({
          title: loadingTitle
        })
      }
d-u-a's avatar
d-u-a 已提交
385
      /* eslint-disable no-undef */
386 387 388 389 390
      let db = uniCloud.database()
      if (action) {
        db = db.action(action)
      }

d-u-a's avatar
d-u-a 已提交
391 392
      return db.collection(this.collection).doc(id).update(value).then((res) => {
        success && success(res)
393 394
        if (showToast) {
          uni.showToast({
fxy060608's avatar
fxy060608 已提交
395
            title: toastTitle || t('uniCloud.component.update.success')
396 397
          })
        }
d-u-a's avatar
d-u-a 已提交
398 399
      }).catch((err) => {
        fail && fail(err)
400 401 402 403 404 405
        if (needConfirm) {
          uni.showModal({
            content: err.message,
            showCancel: false
          })
        }
d-u-a's avatar
d-u-a 已提交
406
      }).finally(() => {
407 408 409
        if (needLoading) {
          uni.hideLoading()
        }
d-u-a's avatar
d-u-a 已提交
410 411 412
        complete && complete()
      })
    },
413
    _execLoadData (callback, clear) {
d-u-a's avatar
d-u-a 已提交
414 415 416 417 418
      if (this.loading) {
        return
      }
      this.loading = true
      this.errorMessage = ''
d-u-a's avatar
d-u-a 已提交
419

d-u-a's avatar
d-u-a 已提交
420 421 422 423 424 425 426
      this._getExec().then((res) => {
        this.loading = false
        const {
          data,
          count
        } = res.result
        this._isEnded = data.length < this.pageSize
d-u-a's avatar
d-u-a 已提交
427
        this.hasMore = !this._isEnded
d-u-a's avatar
d-u-a 已提交
428

d-u-a's avatar
d-u-a 已提交
429
        const data2 = this.getone ? (data.length ? data[0] : undefined) : data
430

431 432 433 434 435
        if (this.getcount) {
          this.paginationInternal.count = count
        }

        callback && callback(data2, this._isEnded, this.paginationInternal)
d-u-a's avatar
d-u-a 已提交
436
        this._dispatchEvent(events.load, data2)
d-u-a's avatar
d-u-a 已提交
437

438 439 440
        if (this.getone || this.pageData === pageMode.replace) {
          this.dataList = data2
        } else {
441 442 443 444 445
          if (clear) {
            this.dataList = data2
          } else {
            this.dataList.push(...data2)
          }
d-u-a's avatar
d-u-a 已提交
446
        }
d-u-a's avatar
d-u-a 已提交
447 448 449 450

        // #ifdef H5
        if (process.env.NODE_ENV === 'development') {
          this._debugDataList.length = 0
451
          const formatData = JSON.parse(JSON.stringify(this.dataList))
452 453 454 455 456
          if (Array.isArray(this.dataList)) {
            this._debugDataList.push(...formatData)
          } else {
            this._debugDataList.push(formatData)
          }
d-u-a's avatar
d-u-a 已提交
457
        }
d-u-a's avatar
d-u-a 已提交
458 459 460 461 462 463 464 465
        // #endif
      }).catch((err) => {
        this.loading = false
        this.errorMessage = err
        callback && callback()
        this.$emit(events.error, err)
        if (process.env.NODE_ENV === 'development') {
          console.error(err)
d-u-a's avatar
d-u-a 已提交
466
        }
d-u-a's avatar
d-u-a 已提交
467 468 469 470 471
      })
    },
    _getExec () {
      /* eslint-disable no-undef */
      let db = uniCloud.database()
d-u-a's avatar
d-u-a 已提交
472

d-u-a's avatar
d-u-a 已提交
473 474 475
      if (this.action) {
        db = db.action(this.action)
      }
d-u-a's avatar
d-u-a 已提交
476

d-u-a's avatar
d-u-a 已提交
477
      db = db.collection(this.collection)
d-u-a's avatar
d-u-a 已提交
478

d-u-a's avatar
d-u-a 已提交
479 480 481 482 483 484
      if (!(!this.where || !Object.keys(this.where).length)) {
        db = db.where(this.where)
      }
      if (this.field) {
        db = db.field(this.field)
      }
485 486 487
      if (this.exceptForeignKey) {
        db = db.exceptForeignKey(this.exceptForeignKey)
      }
488
      if (this.groupby) {
489
        db = db.groupBy(this.groupby)
490 491 492 493 494 495 496
      }
      if (this.groupField) {
        db = db.groupField(this.groupField)
      }
      if (this.distinct === true) {
        db = db.distinct()
      }
d-u-a's avatar
d-u-a 已提交
497 498 499
      if (this.orderby) {
        db = db.orderBy(this.orderby)
      }
d-u-a's avatar
d-u-a 已提交
500

d-u-a's avatar
d-u-a 已提交
501 502 503 504
      const {
        current,
        size
      } = this.paginationInternal
505 506 507 508
      const getOptions = {}
      if (this.getcount) {
        getOptions.getCount = this.getcount
      }
509 510 511 512
      const treeOptions = {
        limitLevel: this.limitlevel,
        startWith: this.startwith
      }
513
      if (this.gettree) {
514 515 516 517
        getOptions.getTree = treeOptions
      }
      if (this.gettreepath) {
        getOptions.getTreePath = treeOptions
518 519
      }
      db = db.skip(size * (current - 1)).limit(size).get(getOptions)
d-u-a's avatar
d-u-a 已提交
520

d-u-a's avatar
d-u-a 已提交
521 522
      return db
    },
523
    _execRemove (id, action, success, fail, complete, needConfirm, needLoading, loadingTitle) {
d-u-a's avatar
d-u-a 已提交
524 525 526
      if (!this.collection || !id) {
        return
      }
d-u-a's avatar
d-u-a 已提交
527

d-u-a's avatar
d-u-a 已提交
528 529 530 531
      const ids = Array.isArray(id) ? id : [id]
      if (!ids.length) {
        return
      }
d-u-a's avatar
d-u-a 已提交
532

533 534 535 536 537 538
      if (needLoading) {
        uni.showLoading({
          mask: true,
          title: loadingTitle
        })
      }
d-u-a's avatar
d-u-a 已提交
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554

      /* eslint-disable no-undef */
      const db = uniCloud.database()
      const dbCmd = db.command

      let exec = db
      if (action) {
        exec = exec.action(action)
      }

      exec.collection(this.collection).where({
        _id: dbCmd.in(ids)
      }).remove().then((res) => {
        success && success(res.result)
        if (this.pageData === pageMode.replace) {
          this.refresh()
d-u-a's avatar
d-u-a 已提交
555
        } else {
d-u-a's avatar
d-u-a 已提交
556 557 558 559
          this.removeData(ids)
        }
      }).catch((err) => {
        fail && fail(err)
560 561 562 563 564 565
        if (needConfirm) {
          uni.showModal({
            content: err.message,
            showCancel: false
          })
        }
d-u-a's avatar
d-u-a 已提交
566
      }).finally(() => {
567 568 569
        if (needLoading) {
          uni.hideLoading()
        }
d-u-a's avatar
d-u-a 已提交
570 571 572 573 574 575 576 577 578 579 580
        complete && complete()
      })
    },
    removeData (ids) {
      const il = ids.slice(0)
      const dl = this.dataList
      for (let i = dl.length - 1; i >= 0; i--) {
        const index = il.indexOf(dl[i]._id)
        if (index >= 0) {
          dl.splice(i, 1)
          il.splice(index, 1)
d-u-a's avatar
d-u-a 已提交
581 582
        }
      }
d-u-a's avatar
d-u-a 已提交
583 584 585
    },
    _dispatchEvent (type, data) {
      if (this._changeDataFunction) {
586
        this._changeDataFunction(data, this._isEnded, this.paginationInternal)
d-u-a's avatar
d-u-a 已提交
587
      } else {
588
        this.$emit(type, data, this._isEnded, this.paginationInternal)
d-u-a's avatar
d-u-a 已提交
589
      }
d-u-a's avatar
d-u-a 已提交
590 591
    }
  }
d-u-a's avatar
d-u-a 已提交
592
}
d-u-a's avatar
d-u-a 已提交
593
</script>