From 1eca9390106c92c242b652e3065fc57861beeeab Mon Sep 17 00:00:00 2001 From: LOG1997 <2694233102@qq.com> Date: Mon, 13 Oct 2025 22:31:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20indexdb=E5=AD=98=E5=82=A8=E4=BA=BA?= =?UTF-8?q?=E5=91=98=E5=90=8D=E5=8D=95=EF=BC=8C=E4=BD=BF=E7=94=A8dexie?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 8 + src/store/personConfig.ts | 302 +++++++++++++++++++++----------------- src/utils/dexie/index.ts | 108 ++++++++++++++ src/utils/dexie/type.ts | 3 + 5 files changed, 284 insertions(+), 138 deletions(-) create mode 100644 src/utils/dexie/index.ts create mode 100644 src/utils/dexie/type.ts diff --git a/package.json b/package.json index 5d5a7b7..9de49ae 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "axios": "^1.7.8", "canvas-confetti": "^1.9.3", "dayjs": "^1.11.13", + "dexie": "^4.2.1", "github-markdown-css": "^5.8.0", "localforage": "^1.10.0", "markdown-it": "^14.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c9cda78..3584108 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: dayjs: specifier: ^1.11.13 version: 1.11.13 + dexie: + specifier: ^4.2.1 + version: 4.2.1 github-markdown-css: specifier: ^5.8.0 version: 5.8.0 @@ -2701,6 +2704,9 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dexie@4.2.1: + resolution: {integrity: sha512-Ckej0NS6jxQ4Po3OrSQBFddayRhTCic2DoCAG5zacOfOVB9P2Q5Xc5uL/nVa7ZVs+HdMnvUPzLFCB/JwpB6Csg==} + dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -8238,6 +8244,8 @@ snapshots: dependencies: dequal: 2.0.3 + dexie@4.2.1: {} + dom-accessibility-api@0.5.16: {} dom-serializer@0.2.2: diff --git a/src/store/personConfig.ts b/src/store/personConfig.ts index 06df7d1..b142649 100644 --- a/src/store/personConfig.ts +++ b/src/store/personConfig.ts @@ -1,159 +1,185 @@ import type { IPersonConfig, IPrizeConfig } from '@/types/storeType' - import dayjs from 'dayjs' import { defineStore } from 'pinia' +import { computed, ref, toRaw, watch } from 'vue' +import { IndexDb } from '@/utils/dexie' import { defaultPersonList } from './data' import { usePrizeConfig } from './prizeConfig' -export const usePersonConfig = defineStore('person', { - state() { - return { - personConfig: { +// 获取IPersonConfig的key组成数组 +export const personListKey = Object.keys(defaultPersonList[0]) +export const usePersonConfig = defineStore('person', () => { + const personDb = new IndexDb('person', ['allPersonList', 'alreadyPersonList'], 1, personListKey) + // NOTE: state + const personConfig = ref({ allPersonList: [] as IPersonConfig[], alreadyPersonList: [] as IPersonConfig[], - }, - } - }, - getters: { + }) + personDb.getAllData('allPersonList').then((data) => { + personConfig.value.allPersonList = data + }) + personDb.getAllData('alreadyPersonList').then((data) => { + console.log(data) + personConfig.value.alreadyPersonList = data + }) + + // NOTE: getter // 获取全部配置 - getPersonConfig(state) { - return state.personConfig - }, + const getPersonConfig = computed(() => personConfig.value) // 获取全部人员名单 - getAllPersonList(state) { - return state.personConfig.allPersonList.filter((item: IPersonConfig) => { - return item - }) - }, + const getAllPersonList = computed(() => personConfig.value.allPersonList) // 获取未获此奖的人员名单 - getNotThisPrizePersonList(state: any) { - const currentPrize = usePrizeConfig().prizeConfig.currentPrize - const data = state.personConfig.allPersonList.filter((item: IPersonConfig) => { - return !item.prizeId.includes(currentPrize.id as string) - }) - - return data - }, - // 获取已中奖人员名单 - getAlreadyPersonList(state) { - return state.personConfig.allPersonList.filter((item: IPersonConfig) => { - return item.isWin === true - }) - }, - // 获取中奖人员详情 - getAlreadyPersonDetail(state) { - return state.personConfig.alreadyPersonList - }, - // 获取未中奖人员名单 - getNotPersonList(state) { - return state.personConfig.allPersonList.filter((item: IPersonConfig) => { - return item.isWin === false - }) - }, - }, - actions: { - // 添加未中奖人员 - addNotPersonList(personList: IPersonConfig[]) { - if (personList.length <= 0) { - return - } - personList.forEach((item: IPersonConfig) => { - this.personConfig.allPersonList.push(item) - }) - }, - // 添加已中奖人员 - addAlreadyPersonList(personList: IPersonConfig[], prize: IPrizeConfig | null) { - if (personList.length <= 0) { - return - } - personList.forEach((person: IPersonConfig) => { - this.personConfig.allPersonList.map((item: IPersonConfig) => { - if (item.id === person.id && prize != null) { - item.isWin = true - // person.isWin = true - item.prizeName.push(prize.name) - // person.prizeName += prize.name - item.prizeTime.push(dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')) - // person.prizeTime = new Date().toString() - item.prizeId.push(prize.id as string) - } - - return item + const getNotThisPrizePersonList = computed(() => { + const currentPrize = usePrizeConfig().prizeConfig.currentPrize + const data = personConfig.value.allPersonList.filter((item: IPersonConfig) => { + return !item.prizeId.includes(currentPrize.id as string) }) - this.personConfig.alreadyPersonList.push(person) - }) - }, - // 从已中奖移动到未中奖 - moveAlreadyToNot(person: IPersonConfig) { - if (person.id === undefined || person.id == null) { - return - } - const alreadyPersonListLength = this.personConfig.alreadyPersonList.length - for (let i = 0; i < this.personConfig.allPersonList.length; i++) { - if (person.id === this.personConfig.allPersonList[i].id) { - this.personConfig.allPersonList[i].isWin = false - this.personConfig.allPersonList[i].prizeName = [] - this.personConfig.allPersonList[i].prizeTime = [] - this.personConfig.allPersonList[i].prizeId = [] - break + return data + }) + + // 获取已中奖人员名单 + const getAlreadyPersonList = computed(() => { + return personConfig.value.allPersonList.filter((item: IPersonConfig) => { + return item.isWin === true + }) + }) + // 获取中奖人员详情 + const getAlreadyPersonDetail = computed(() => personConfig.value.alreadyPersonList) + // 获取未中奖人员名单 + const getNotPersonList = computed(() => personConfig.value.allPersonList.filter((item: IPersonConfig) => { + return item.isWin === false + })) + // NOTE: action + // 添加未中奖人员 + function addNotPersonList(personList: IPersonConfig[]) { + if (personList.length <= 0) { + return } - } - for (let i = 0; i < alreadyPersonListLength; i++) { - this.personConfig.alreadyPersonList = this.personConfig.alreadyPersonList.filter((item: IPersonConfig) => - item.id !== person.id, - ) - } - }, + personList.forEach((item: IPersonConfig) => { + personConfig.value.allPersonList.push(item) + }) + personDb.setAllData('allPersonList', personList) + } + // 添加已中奖人员 + function addAlreadyPersonList(personList: IPersonConfig[], prize: IPrizeConfig | null) { + if (personList.length <= 0) { + return + } + personList.forEach((person: IPersonConfig) => { + personConfig.value.allPersonList.map((item: IPersonConfig) => { + if (item.id === person.id && prize != null) { + item.isWin = true + // person.isWin = true + item.prizeName.push(prize.name) + // person.prizeName += prize.name + item.prizeTime.push(dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')) + // person.prizeTime = new Date().toString() + item.prizeId.push(prize.id as string) + } + return item + }) + personConfig.value.alreadyPersonList.push(person) + personDb.updateData('allPersonList', toRaw(person)) + personDb.setData('alreadyPersonList', toRaw(person)) + }) + } + // 从已中奖移动到未中奖 + function moveAlreadyToNot(person: IPersonConfig) { + if (person.id === undefined || person.id == null) { + return + } + const alreadyPersonListLength = personConfig.value.alreadyPersonList.length + for (let i = 0; i < personConfig.value.allPersonList.length; i++) { + if (person.id === personConfig.value.allPersonList[i].id) { + personConfig.value.allPersonList[i].isWin = false + personConfig.value.allPersonList[i].prizeName = [] + personConfig.value.allPersonList[i].prizeTime = [] + personConfig.value.allPersonList[i].prizeId = [] + personDb.updateData('allPersonList', toRaw(personConfig.value.allPersonList[i])) + break + } + } + const alreadyPersonListRaw = toRaw(personConfig.value.alreadyPersonList) + for (let i = 0; i < alreadyPersonListLength; i++) { + personConfig.value.alreadyPersonList = alreadyPersonListRaw.filter((item: IPersonConfig) => + item.id !== person.id, + ) + } + personDb.deleteData('alreadyPersonList', person) + } // 删除指定人员 - deletePerson(person: IPersonConfig) { - if (person.id !== undefined || person.id != null) { - this.personConfig.allPersonList = this.personConfig.allPersonList.filter((item: IPersonConfig) => item.id !== person.id) - this.personConfig.alreadyPersonList = this.personConfig.alreadyPersonList.filter((item: IPersonConfig) => item.id !== person.id) - } - }, + function deletePerson(person: IPersonConfig) { + if (person.id !== undefined || person.id != null) { + const allPersonListRaw = toRaw(personConfig.value.allPersonList) + const alreadyPersonListRaw = toRaw(personConfig.value.alreadyPersonList) + personConfig.value.allPersonList = allPersonListRaw.filter((item: IPersonConfig) => item.id !== person.id) + personConfig.value.alreadyPersonList = alreadyPersonListRaw.filter((item: IPersonConfig) => item.id !== person.id) + personDb.deleteData('allPersonList', person) + personDb.deleteData('alreadyPersonList', person) + } + } // 删除所有人员 - deleteAllPerson() { - this.personConfig.allPersonList = [] - this.personConfig.alreadyPersonList = [] - }, + function deleteAllPerson() { + personConfig.value.allPersonList = [] + personConfig.value.alreadyPersonList = [] + personDb.deleteAll('allPersonList') + personDb.deleteAll('alreadyPersonList') + } // 删除所有人员 - resetPerson() { - this.personConfig.allPersonList = [] - this.personConfig.alreadyPersonList = [] - }, + function resetPerson() { + personConfig.value.allPersonList = [] + personConfig.value.alreadyPersonList = [] + personDb.deleteAll('allPersonList') + personDb.deleteAll('alreadyPersonList') + } // 重置已中奖人员 - resetAlreadyPerson() { - // 把已中奖人员合并到未中奖人员,要验证是否已存在 - this.personConfig.allPersonList.forEach((item: IPersonConfig) => { - item.isWin = false - item.prizeName = [] - item.prizeTime = [] - item.prizeId = [] - }) - this.personConfig.alreadyPersonList = [] - }, - setDefaultPersonList() { - this.personConfig.allPersonList = defaultPersonList - this.personConfig.alreadyPersonList = [] - }, + function resetAlreadyPerson() { + // 把已中奖人员合并到未中奖人员,要验证是否已存在 + personConfig.value.allPersonList.forEach((item: IPersonConfig) => { + item.isWin = false + item.prizeName = [] + item.prizeTime = [] + item.prizeId = [] + }) + personConfig.value.alreadyPersonList = [] + const allPersonListRaw = toRaw(personConfig.value.allPersonList) + personDb.deleteAll('allPersonList') + personDb.setAllData('allPersonList', allPersonListRaw) + personDb.deleteAll('alreadyPersonList') + } + function setDefaultPersonList() { + personConfig.value.allPersonList = defaultPersonList + personConfig.value.alreadyPersonList = [] + personDb.setAllData('allPersonList', defaultPersonList) + personDb.deleteAll('alreadyPersonList') + } // 重置所有配置 - reset() { - this.personConfig = { - allPersonList: [] as IPersonConfig[], - alreadyPersonList: [] as IPersonConfig[], - } - }, - }, - persist: { - enabled: true, - strategies: [ - { - // 如果要存储在localStorage中 - storage: localStorage, - key: 'personConfig', - }, - ], - }, + function reset() { + personConfig.value = { + allPersonList: [] as IPersonConfig[], + alreadyPersonList: [] as IPersonConfig[], + } + personDb.deleteAll('allPersonList') + personDb.deleteAll('alreadyPersonList') + } + return { + personConfig, + getPersonConfig, + getAllPersonList, + getNotThisPrizePersonList, + getAlreadyPersonList, + getAlreadyPersonDetail, + getNotPersonList, + addNotPersonList, + addAlreadyPersonList, + moveAlreadyToNot, + deletePerson, + deleteAllPerson, + resetPerson, + resetAlreadyPerson, + setDefaultPersonList, + reset, + } }) diff --git a/src/utils/dexie/index.ts b/src/utils/dexie/index.ts new file mode 100644 index 0000000..704073b --- /dev/null +++ b/src/utils/dexie/index.ts @@ -0,0 +1,108 @@ +import type { EntityTable } from 'dexie' +import type { DbData } from './type' +import dayjs from 'dayjs' +import Dexie from 'dexie' + +class IndexDb { + name: string + dbStore: any + version: number + dbKeys: string[] + tableNames: string[] + constructor(name: string, tableNames: string[], version = 1, dbKeys: string[] = []) { + this.name = name // 数据库名称 + this.version = version // 数据库版本号 + this.dbKeys = dbKeys // 数据库key + this.tableNames = tableNames + this.dbStore = new Dexie(name) as Dexie & { [key: string]: EntityTable } + // 获取存在的key + const stores: Record = {} + for (const tableName of tableNames) { + stores[tableName] = 'id,dateTime,type,uid' // 根据需要调整字段 + } + this.dbStore.version(this.version).stores(stores) + } + + setAllData(tableName: string, data: DbData[]) { + this.dbStore[tableName].bulkAdd(data) + } + + /** + * @param data + * @description 添加单条数据,并为数据添加dataTime和type属性 + */ + setData(tableName: string, data: Partial) { + if (!data.dateTime) { + data.dateTime = dayjs().format('YYYY-MM-DD HH:mm:ss:SSS') + } + if (!data.type) { + data.type = 'info' + } + this.dbStore[tableName].add(data) + } + + // 更新单条数据 + updateData(tableName: string, data: Partial) { + this.dbStore[tableName].update(data.id, data) + } + + /** + * @returns 所有数据Array + * @description 删除所有数据并返回被删除的数据 + */ + deleteAll(tableName: string) { + return this.dbStore[tableName].clear() + } + + /** + * @param data + * @description 删除单条数据 + */ + deleteData(tableName: string, data: Partial) { + this.dbStore[tableName].delete(data.id) + } + + /** + * @returns 所有数据Array + * @description 获取所有数据 + */ + async getAllData(tableName: string, isAsc: boolean = true) { + const allData = await this.dbStore[tableName].toArray() + // return allData + return isAsc ? allData : allData.reverse() + } + + // 分页获取数据 + async getPageData(tableName: string, pageNum: number, pageSize: number, isAsc: boolean = true) { + const allData = await this.dbStore[tableName].toArray() + const start = (pageNum - 1) * pageSize + const end = pageNum * pageSize + return isAsc ? allData.slice(start, end) : allData.slice(end, start).reverse() + } + + /** + * @returns 数据库总长度 + * @description 获取所有数据的列表长度 + */ + getAllLength(tableName: string) { + return this.dbStore[tableName].count() + } + + /** + * + * @param filter 根据筛选条件返回数据 + * @returns + */ + getFilterData(tableName: string, filter: string) { + return this.dbStore[tableName].filter((item: any) => { + return item.content.includes(filter) + }).toArray() + } + + getKeys(tableName: string, key: string) { + // keys 方法获取所有主键 + return this.dbStore[tableName].orderBy(key).keys() + } +} + +export { IndexDb } diff --git a/src/utils/dexie/type.ts b/src/utils/dexie/type.ts new file mode 100644 index 0000000..e2e8ecc --- /dev/null +++ b/src/utils/dexie/type.ts @@ -0,0 +1,3 @@ +export interface DbData { + [key: string]: any +}