123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- import { defineStore } from 'pinia'
- interface IndexedDBStoreConfig {
- name: string;
- keyPath: string;
- indexes?: Array<{
- name: string
- keyPath: string | string[]
- options?: IDBIndexParameters
- }>;
- }
- interface IndexedDBConfig {
- dbName: string;
- version?: number;
- }
- export const useIndexedDBStore = defineStore('indexedDB', {
- state: () => ({
- storeRegistry: new Map<string, IndexedDBStoreConfig>(),
- dbName: <string>'',
- db: <IDBDatabase | null>null,
- currentVersion: <number>0,
- isInitialized: <boolean>false
- }),
- actions: {
- registerStore(storeConfig: IndexedDBStoreConfig) {
- if (!this.storeRegistry.has(storeConfig.name)) {
- this.storeRegistry.set(storeConfig.name, storeConfig)
- }
- },
- deleteDB() {
- return new Promise<boolean>((resolve, reject) => {
- const request = indexedDB.deleteDatabase(this.dbName)
- request.onsuccess = () => {
- resolve(true)
- window.location.reload()
- }
- request.onerror = () => {
- reject(request.error)
- }
- })
- },
- openDB(config: IndexedDBConfig) {
- if (config) {
- this.dbName = config.dbName
- this.currentVersion = config.version || 1
- }
- return new Promise((resolve, reject) => {
- const request = indexedDB.open(this.dbName, this.currentVersion)
- request.onupgradeneeded = (event: IDBVersionChangeEvent) => {
- const db = (event.target as IDBOpenDBRequest).result
- // 从注册中心获取所有Store配置
- const stores = Array.from(this.storeRegistry.values())
- stores.forEach((storeConfig: any) => {
- if (!db.objectStoreNames.contains(storeConfig.name)) {
- const objectStore = db.createObjectStore(
- storeConfig.name,
- { keyPath: storeConfig.keyPath }
- )
- storeConfig.indexes?.forEach((index: any) => {
- objectStore.createIndex(
- index.name,
- index.keyPath,
- index.options
- )
- })
- }
- })
- }
- request.onsuccess = (event: Event) => {
- this.db = (event.target as IDBOpenDBRequest).result
- this.isInitialized = true
- Array.from(this.db.objectStoreNames).forEach((storeName: any) => {
- this.registerStore({
- name: storeName,
- keyPath: 'id'
- })
- })
- resolve(this.db)
- }
- request.onerror = (event: Event) => {
- reject((event.target as IDBOpenDBRequest).error)
- }
- })
- },
- // 动态升级数据库版本
- async upgradeVersion() {
- this.currentVersion += 1
- localStorage.setItem('dbVersion', this.currentVersion.toString())
- this.db?.close()
- return this.openDB({ dbName: this.dbName, version: this.currentVersion })
- },
- useStore(storeName: string) {
- const verifyStore = async () => {
- if (!this.storeRegistry.has(storeName)) {
- throw new Error(`Store ${storeName} not registered`)
- }
- if (this.db && !this.db.objectStoreNames.contains(storeName)) {
- await this.upgradeVersion()
- }
- }
- const executeWithTransaction = async (mode: IDBTransactionMode, operation: any) => {
- await verifyStore()
- if (!this.db) await this.openDB({ dbName: this.dbName, version: this.currentVersion })
- return new Promise((resolve, reject) => {
- // this.db;
- const transaction = this.db!.transaction(storeName, mode)
- const objectStore = transaction.objectStore(storeName)
- // 事务成功完成时的回调
- // transaction.oncomplete = () => {
- // resolve(); // 事务成功完成,返回结果
- // };
- // 事务失败时的回调
- transaction.onerror = (event) => {
- reject((event.target as IDBRequest).error)
- }
- // 执行操作
- operation(objectStore).then((result: any) => {
- // 操作成功,返回结果
- resolve(result)
- }).catch((error: any) => {
- // 操作失败,拒绝 Promise
- reject(error)
- })
- })
- }
- return {
- add: (data: any) => executeWithTransaction(
- 'readwrite',
- (store: any) => new Promise((resolve, reject) => {
- const request = store.add(data)
- request.onsuccess = () => resolve(request.result as IDBValidKey)
- request.onerror = () => reject(request.error)
- })
- ),
- get: (key: IDBValidKey) => executeWithTransaction(
- 'readonly',
- (store: any) => new Promise((resolve, reject) => {
- const request = store.get(key)
- request.onsuccess = () => resolve(request.result as any)
- request.onerror = () => reject(request.error)
- })
- ),
- update: (data: any) => executeWithTransaction(
- 'readwrite',
- (store: any) => new Promise((resolve, reject) => {
- const request = store.put(data)
- request.onsuccess = () => resolve(request.result as IDBValidKey)
- request.onerror = () => reject(request.error)
- })
- ),
- delete: (key: IDBValidKey) => executeWithTransaction(
- 'readwrite',
- (store: any) => new Promise((resolve, reject) => {
- const request = store.delete(key)
- request.onsuccess = () => resolve(undefined)
- request.onerror = () => reject(request.error)
- })
- ),
- getAll: () => executeWithTransaction(
- 'readonly',
- (store: any) => new Promise((resolve, reject) => {
- const request = store.getAll()
- request.onsuccess = () => resolve(request.result as any[])
- request.onerror = () => reject(request.error)
- })
- ),
- clearAll: () => executeWithTransaction(
- 'readwrite',
- (store: any) => new Promise((resolve, reject) => {
- const request = store.clear()
- request.onsuccess = () => resolve(true)
- request.onerror = () => reject(request.error)
- })
- )
- }
- }
- }
- })
|