unicloud-db.vue 14.1 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
    collection: {
58
      type: [String, Array],
d-u-a's avatar
d-u-a 已提交
59
      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
    foreignKey: {
130 131 132
      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
      errorMessage: ''
    }
  },
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
  computed: {
    collectionArgs () {
      return Array.isArray(this.collection) ? this.collection : [this.collection]
    },
    isLookup () {
      return (Array.isArray(this.collection) && this.collection.length > 1) || (typeof this.collection === 'string' && this.collection.indexOf(',') > -1)
    },
    mainCollection () {
      if (typeof this.collection === 'string') {
        return this.collection.split(',')[0]
      }
      const mainQuery = JSON.parse(JSON.stringify(this.collection[0]))
      return mainQuery.$db[0].$param[0]
    }
  },
d-u-a's avatar
d-u-a 已提交
166 167
  created () {
    this._isEnded = false
168 169 170 171 172
    this.paginationInternal = {
      current: this.pageCurrent,
      size: this.pageSize,
      count: 0
    }
d-u-a's avatar
d-u-a 已提交
173

d-u-a's avatar
d-u-a 已提交
174 175 176 177 178 179 180
    this.$watch(() => {
      var al = []
      attrs.forEach(key => {
        al.push(this[key])
      })
      return al
    }, (newValue, oldValue) => {
181 182 183 184
      this.paginationInternal.size = this.pageSize
      if (newValue[0] !== oldValue[0]) {
        this.paginationInternal.current = this.pageCurrent
      }
185 186 187 188
      if (this.loadtime === loadMode.manual) {
        return
      }

d-u-a's avatar
d-u-a 已提交
189 190 191 192 193
      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 已提交
194
        }
d-u-a's avatar
d-u-a 已提交
195 196 197 198 199
      }
      if (needReset) {
        this.clear()
        this.reset()
      }
d-u-a's avatar
d-u-a 已提交
200

d-u-a's avatar
d-u-a 已提交
201 202
      this._execLoadData()
    })
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 H5
    if (process.env.NODE_ENV === 'development') {
      this._debugDataList = []
      if (!window.unidev) {
        window.unidev = {
          clientDB: {
            data: []
d-u-a's avatar
d-u-a 已提交
211 212 213
          }
        }
      }
d-u-a's avatar
d-u-a 已提交
214 215 216
      window.unidev.clientDB.data.push(this._debugDataList)
    }
    // #endif
d-u-a's avatar
d-u-a 已提交
217

d-u-a's avatar
d-u-a 已提交
218 219
    // #ifdef MP-TOUTIAO
    let changeName
220
    const events = this.$scope.dataset.eventOpts || []
d-u-a's avatar
d-u-a 已提交
221 222 223 224
    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 已提交
225
      }
d-u-a's avatar
d-u-a 已提交
226 227 228 229 230 231 232 233 234 235 236
    }
    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 已提交
237
        }
d-u-a's avatar
d-u-a 已提交
238 239
        parent = parent.$parent
        maxDepth--
d-u-a's avatar
d-u-a 已提交
240
      }
d-u-a's avatar
d-u-a 已提交
241 242
    }
    // #endif
d-u-a's avatar
d-u-a 已提交
243

244
    if (!this.manual && this.loadtime === loadMode.auto) {
d-u-a's avatar
d-u-a 已提交
245 246 247 248 249 250 251 252 253 254 255 256
      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 已提交
257 258
        }
      }
d-u-a's avatar
d-u-a 已提交
259 260 261 262 263 264
    }
  },
  // #endif
  methods: {
    loadData (args1, args2) {
      let callback = null
265
      let clear = false
d-u-a's avatar
d-u-a 已提交
266 267
      if (typeof args1 === 'object') {
        if (args1.clear) {
268 269 270 271 272
          if (this.pageData === pageMode.replace) {
            this.clear()
          } else {
            clear = args1.clear
          }
d-u-a's avatar
d-u-a 已提交
273
          this.reset()
d-u-a's avatar
d-u-a 已提交
274
        }
d-u-a's avatar
d-u-a 已提交
275 276
        if (args1.current !== undefined) {
          this.paginationInternal.current = args1.current
d-u-a's avatar
d-u-a 已提交
277
        }
d-u-a's avatar
d-u-a 已提交
278 279
        if (typeof args2 === 'function') {
          callback = args2
d-u-a's avatar
d-u-a 已提交
280
        }
d-u-a's avatar
d-u-a 已提交
281 282 283 284
      } else if (typeof args1 === 'function') {
        callback = args1
      }

285
      this._execLoadData(callback, clear)
d-u-a's avatar
d-u-a 已提交
286 287
    },
    loadMore () {
288
      if (this._isEnded || this.loading) {
d-u-a's avatar
d-u-a 已提交
289 290
        return
      }
291 292 293 294 295

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

d-u-a's avatar
d-u-a 已提交
296 297 298 299 300 301 302 303 304 305 306 307 308 309
      this._execLoadData()
    },
    refresh () {
      this.clear()
      this._execLoadData()
    },
    clear () {
      this._isEnded = false
      this.dataList = []
    },
    reset () {
      this.paginationInternal.current = 1
    },
    add (value, {
310 311
      action,
      showToast = true,
d-u-a's avatar
d-u-a 已提交
312 313 314
      toastTitle,
      success,
      fail,
315 316 317 318
      complete,
      needConfirm = true,
      needLoading = true,
      loadingTitle = ''
d-u-a's avatar
d-u-a 已提交
319
    } = {}) {
320 321 322 323 324
      if (needLoading) {
        uni.showLoading({
          title: loadingTitle
        })
      }
d-u-a's avatar
d-u-a 已提交
325
      /* eslint-disable no-undef */
326 327 328 329 330
      let db = uniCloud.database()
      if (action) {
        db = db.action(action)
      }

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

405
      return db.collection(this.mainCollection).doc(id).update(value).then((res) => {
d-u-a's avatar
d-u-a 已提交
406
        success && success(res)
407 408
        if (showToast) {
          uni.showToast({
fxy060608's avatar
fxy060608 已提交
409
            title: toastTitle || t('uniCloud.component.update.success')
410 411
          })
        }
d-u-a's avatar
d-u-a 已提交
412 413
      }).catch((err) => {
        fail && fail(err)
414 415 416 417 418 419
        if (needConfirm) {
          uni.showModal({
            content: err.message,
            showCancel: false
          })
        }
d-u-a's avatar
d-u-a 已提交
420
      }).finally(() => {
421 422 423
        if (needLoading) {
          uni.hideLoading()
        }
d-u-a's avatar
d-u-a 已提交
424 425 426
        complete && complete()
      })
    },
Q
qiang 已提交
427
    getTemp (isTemp = true) {
d-u-a's avatar
d-u-a 已提交
428 429
      /* eslint-disable no-undef */
      let db = uniCloud.database()
d-u-a's avatar
d-u-a 已提交
430

d-u-a's avatar
d-u-a 已提交
431 432 433
      if (this.action) {
        db = db.action(this.action)
      }
d-u-a's avatar
d-u-a 已提交
434

435
      db = db.collection(...this.collectionArgs)
d-u-a's avatar
d-u-a 已提交
436

d-u-a's avatar
d-u-a 已提交
437 438 439 440 441 442
      if (!(!this.where || !Object.keys(this.where).length)) {
        db = db.where(this.where)
      }
      if (this.field) {
        db = db.field(this.field)
      }
443 444
      if (this.foreignKey) {
        db = db.foreignKey(this.foreignKey)
445
      }
446
      if (this.groupby) {
447
        db = db.groupBy(this.groupby)
448 449 450 451 452 453 454
      }
      if (this.groupField) {
        db = db.groupField(this.groupField)
      }
      if (this.distinct === true) {
        db = db.distinct()
      }
d-u-a's avatar
d-u-a 已提交
455 456 457
      if (this.orderby) {
        db = db.orderBy(this.orderby)
      }
d-u-a's avatar
d-u-a 已提交
458

d-u-a's avatar
d-u-a 已提交
459 460 461 462
      const {
        current,
        size
      } = this.paginationInternal
463 464 465 466
      const getOptions = {}
      if (this.getcount) {
        getOptions.getCount = this.getcount
      }
467 468 469 470
      const treeOptions = {
        limitLevel: this.limitlevel,
        startWith: this.startwith
      }
471
      if (this.gettree) {
472 473 474 475
        getOptions.getTree = treeOptions
      }
      if (this.gettreepath) {
        getOptions.getTreePath = treeOptions
476
      }
477 478 479 480 481 482 483 484
      db = db.skip(size * (current - 1)).limit(size)

      if (isTemp) {
        db = db.getTemp(getOptions)
        db.udb = this
      } else {
        db = db.get(getOptions)
      }
d-u-a's avatar
d-u-a 已提交
485

d-u-a's avatar
d-u-a 已提交
486 487
      return db
    },
Q
qiang 已提交
488
    setResult (result) {
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
      if (result.code === 0) {
        this._execLoadDataSuccess(result)
      } else {
        this._execLoadDataFail(new Error(result.message))
      }
    },
    _execLoadData (callback, clear) {
      if (this.loading) {
        return
      }
      this.loading = true
      this.errorMessage = ''

      this._getExec().then((res) => {
        this.loading = false
        this._execLoadDataSuccess(res.result, callback, clear)

        // #ifdef H5
        if (process.env.NODE_ENV === 'development') {
          this._debugDataList.length = 0
          const formatData = JSON.parse(JSON.stringify(this.dataList))
          if (Array.isArray(this.dataList)) {
            this._debugDataList.push(...formatData)
          } else {
            this._debugDataList.push(formatData)
          }
        }
        // #endif
      }).catch((err) => {
        this.loading = false
        this._execLoadDataFail(err, callback)
      })
    },
Q
qiang 已提交
522
    _execLoadDataSuccess (result, callback, clear) {
523 524 525 526
      const {
        data,
        count
      } = result
d-u-a's avatar
d-u-a 已提交
527
      this._isEnded = count !== undefined ? (this.paginationInternal.current * this.paginationInternal.size >= count) : (data.length < this.pageSize)
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
      this.hasMore = !this._isEnded

      const data2 = this.getone ? (data.length ? data[0] : undefined) : data

      if (this.getcount) {
        this.paginationInternal.count = count
      }

      callback && callback(data2, this._isEnded, this.paginationInternal)
      this._dispatchEvent(events.load, data2)

      if (this.getone || this.pageData === pageMode.replace) {
        this.dataList = data2
      } else {
        if (clear) {
          this.dataList = data2
        } else {
          this.dataList.push(...data2)
        }
      }
    },
Q
qiang 已提交
549
    _execLoadDataFail (err, callback) {
550 551 552 553 554 555 556 557 558 559
      this.errorMessage = err
      callback && callback()
      this.$emit(events.error, err)
      if (process.env.NODE_ENV === 'development') {
        console.error(err)
      }
    },
    _getExec () {
      return this.getTemp(false)
    },
560
    _execRemove (id, action, success, fail, complete, needConfirm, needLoading, loadingTitle) {
d-u-a's avatar
d-u-a 已提交
561 562 563
      if (!this.collection || !id) {
        return
      }
d-u-a's avatar
d-u-a 已提交
564

d-u-a's avatar
d-u-a 已提交
565 566 567 568
      const ids = Array.isArray(id) ? id : [id]
      if (!ids.length) {
        return
      }
d-u-a's avatar
d-u-a 已提交
569

570 571 572 573 574 575
      if (needLoading) {
        uni.showLoading({
          mask: true,
          title: loadingTitle
        })
      }
d-u-a's avatar
d-u-a 已提交
576 577 578 579 580 581 582 583 584 585

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

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

586
      exec.collection(this.mainCollection).where({
d-u-a's avatar
d-u-a 已提交
587 588 589 590 591
        _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 已提交
592
        } else {
d-u-a's avatar
d-u-a 已提交
593 594 595 596
          this.removeData(ids)
        }
      }).catch((err) => {
        fail && fail(err)
597 598 599 600 601 602
        if (needConfirm) {
          uni.showModal({
            content: err.message,
            showCancel: false
          })
        }
d-u-a's avatar
d-u-a 已提交
603
      }).finally(() => {
604 605 606
        if (needLoading) {
          uni.hideLoading()
        }
d-u-a's avatar
d-u-a 已提交
607 608 609 610 611 612 613 614 615 616 617
        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 已提交
618 619
        }
      }
d-u-a's avatar
d-u-a 已提交
620 621 622
    },
    _dispatchEvent (type, data) {
      if (this._changeDataFunction) {
623
        this._changeDataFunction(data, this._isEnded, this.paginationInternal)
d-u-a's avatar
d-u-a 已提交
624
      } else {
625
        this.$emit(type, data, this._isEnded, this.paginationInternal)
d-u-a's avatar
d-u-a 已提交
626
      }
d-u-a's avatar
d-u-a 已提交
627 628
    }
  }
d-u-a's avatar
d-u-a 已提交
629
}
d-u-a's avatar
d-u-a 已提交
630
</script>