feat 数据库问题修复
This commit is contained in:
2
src/auto-imports.d.ts
vendored
2
src/auto-imports.d.ts
vendored
@@ -122,6 +122,7 @@ declare global {
|
|||||||
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
|
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
|
||||||
const saveDeviceInfo: typeof import('./utils/device')['saveDeviceInfo']
|
const saveDeviceInfo: typeof import('./utils/device')['saveDeviceInfo']
|
||||||
const selectSql: typeof import('./utils/sqlite')['selectSql']
|
const selectSql: typeof import('./utils/sqlite')['selectSql']
|
||||||
|
const setDbInitPromise: typeof import('./utils/sqlite')['setDbInitPromise']
|
||||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||||
const shallowRef: typeof import('vue')['shallowRef']
|
const shallowRef: typeof import('vue')['shallowRef']
|
||||||
@@ -468,6 +469,7 @@ declare module 'vue' {
|
|||||||
readonly resolveUnref: UnwrapRef<typeof import('@vueuse/core')['resolveUnref']>
|
readonly resolveUnref: UnwrapRef<typeof import('@vueuse/core')['resolveUnref']>
|
||||||
readonly saveDeviceInfo: UnwrapRef<typeof import('./utils/device')['saveDeviceInfo']>
|
readonly saveDeviceInfo: UnwrapRef<typeof import('./utils/device')['saveDeviceInfo']>
|
||||||
readonly selectSql: UnwrapRef<typeof import('./utils/sqlite')['selectSql']>
|
readonly selectSql: UnwrapRef<typeof import('./utils/sqlite')['selectSql']>
|
||||||
|
readonly setDbInitPromise: UnwrapRef<typeof import('./utils/sqlite')['setDbInitPromise']>
|
||||||
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||||
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||||
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ function onIconClick(name: string) {
|
|||||||
<image class="nav-logo" src="/static/logo.png" mode="aspectFit" @tap="onIconClick('logo')" />
|
<image class="nav-logo" src="/static/logo.png" mode="aspectFit" @tap="onIconClick('logo')" />
|
||||||
<view class="nav-info">
|
<view class="nav-info">
|
||||||
<text class="nav-title">
|
<text class="nav-title">
|
||||||
{{ project?.project_name || '未设置项目' }}
|
{{ project?.project_name || '-----' }}
|
||||||
</text>
|
</text>
|
||||||
<text class="nav-subtitle">
|
<text class="nav-subtitle">
|
||||||
{{ project?.stake_range || '--' }}
|
{{ project?.stake_range || '-----' }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"navigationBarTitleText": "Road-Roller"
|
"navigationBarTitleText": "Road-Roller"
|
||||||
},
|
},
|
||||||
"pages": [
|
"pages": [
|
||||||
|
// GENERATED BY UNI-PAGES, PLATFORM: APP
|
||||||
{
|
{
|
||||||
"path": "pages/Ahome/index",
|
"path": "pages/Ahome/index",
|
||||||
"type": "home",
|
"type": "home",
|
||||||
@@ -120,6 +121,7 @@
|
|||||||
"color": "@tabFontColor",
|
"color": "@tabFontColor",
|
||||||
"selectedColor": "@tabSelectedColor",
|
"selectedColor": "@tabSelectedColor",
|
||||||
"list": [
|
"list": [
|
||||||
|
// GENERATED BY UNI-PAGES, PLATFORM: APP
|
||||||
{
|
{
|
||||||
"pagePath": "pages/Ahome/index",
|
"pagePath": "pages/Ahome/index",
|
||||||
"text": "首页",
|
"text": "首页",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import DB from '@/utils/sqlite'
|
import DB, { setDbInitPromise } from '@/utils/sqlite'
|
||||||
import { historyReportTableSql } from './historyReport'
|
import { historyReportTableSql } from './historyReport'
|
||||||
import { projectTableSql } from './project'
|
import { projectTableSql } from './project'
|
||||||
import { rtkTrackTableSql } from './rtkTrack'
|
import { rtkTrackTableSql } from './rtkTrack'
|
||||||
@@ -77,20 +77,29 @@ async function resetDatabase() {
|
|||||||
* 初始化数据库(建表 → 结构校验/重建 → 空表灌假数据)
|
* 初始化数据库(建表 → 结构校验/重建 → 空表灌假数据)
|
||||||
*/
|
*/
|
||||||
export async function initTables() {
|
export async function initTables() {
|
||||||
try {
|
// 先打开数据库,确保后续 DB.open() 走 isOpen 快速路径,不等 initPromise(避免死锁)
|
||||||
console.log('开始初始化数据库表...')
|
await DB.open()
|
||||||
await DB.transaction(tableSqls)
|
|
||||||
|
|
||||||
if (await isSchemaOutdated()) {
|
// 立即设置 initPromise,让其他并发的 DB 操作等待
|
||||||
await resetDatabase()
|
const promise = (async () => {
|
||||||
return
|
try {
|
||||||
|
console.log('开始初始化数据库表...')
|
||||||
|
await DB.transaction(tableSqls)
|
||||||
|
|
||||||
|
if (await isSchemaOutdated()) {
|
||||||
|
await resetDatabase()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('数据库表初始化成功')
|
||||||
|
await seedIfNeeded()
|
||||||
}
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.error('数据库表初始化失败:', err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
console.log('数据库表初始化成功')
|
setDbInitPromise(promise)
|
||||||
await seedIfNeeded()
|
return promise
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.error('数据库表初始化失败:', err)
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,26 @@ const DB_PATH = '_doc/road_roller.db'
|
|||||||
|
|
||||||
let isOpen = false
|
let isOpen = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库初始化 Promise,确保在表创建完成前不执行查询
|
||||||
|
* initTables() 设置此 Promise,DB.open() 会等待它完成
|
||||||
|
*/
|
||||||
|
let initPromise: Promise<void> | null = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册数据库初始化 Promise(由 initTables 调用)
|
||||||
|
*/
|
||||||
|
export function setDbInitPromise(promise: Promise<void>) {
|
||||||
|
initPromise = promise
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 等待数据库初始化完成
|
||||||
|
*/
|
||||||
|
function waitForInit(): Promise<void> {
|
||||||
|
return initPromise ?? Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转义 SQL 字符串值,防止单引号注入
|
* 转义 SQL 字符串值,防止单引号注入
|
||||||
*/
|
*/
|
||||||
@@ -57,32 +77,39 @@ class DB {
|
|||||||
* 打开数据库
|
* 打开数据库
|
||||||
*/
|
*/
|
||||||
static open(): Promise<void> {
|
static open(): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
// 已打开则直接返回,避免与 initPromise 产生死锁
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
resolve()
|
return Promise.resolve()
|
||||||
return
|
}
|
||||||
}
|
|
||||||
|
|
||||||
plus.sqlite.openDatabase({
|
return waitForInit().then(() => {
|
||||||
name: DB_NAME,
|
return new Promise((resolve, reject) => {
|
||||||
path: DB_PATH,
|
if (isOpen) {
|
||||||
success() {
|
|
||||||
console.log('数据库打开成功')
|
|
||||||
isOpen = true
|
|
||||||
resolve()
|
resolve()
|
||||||
},
|
return
|
||||||
fail(err: any) {
|
}
|
||||||
// -1402: Same Name Already Open,数据库已打开则视为成功
|
|
||||||
if (err?.code === -1402) {
|
plus.sqlite.openDatabase({
|
||||||
console.log('数据库已打开,跳过')
|
name: DB_NAME,
|
||||||
|
path: DB_PATH,
|
||||||
|
success() {
|
||||||
|
console.log('数据库打开成功')
|
||||||
isOpen = true
|
isOpen = true
|
||||||
resolve()
|
resolve()
|
||||||
}
|
},
|
||||||
else {
|
fail(err: any) {
|
||||||
console.error('数据库打开失败:', err)
|
// -1402: Same Name Already Open,数据库已打开则视为成功
|
||||||
reject(err)
|
if (err?.code === -1402) {
|
||||||
}
|
console.log('数据库已打开,跳过')
|
||||||
},
|
isOpen = true
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.error('数据库打开失败:', err)
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -114,13 +141,14 @@ class DB {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行 SQL 语句(增、删、改)
|
* 执行 SQL 语句(增、删、改)
|
||||||
|
* sql 可以是单条语句(string)或多条语句(string[])
|
||||||
*/
|
*/
|
||||||
static executeSql(sql: string[]): Promise<any> {
|
static executeSql(sql: string | string[]): Promise<any> {
|
||||||
return DB.open().then(() => {
|
return DB.open().then(() => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
plus.sqlite.executeSql({
|
plus.sqlite.executeSql({
|
||||||
name: DB_NAME,
|
name: DB_NAME,
|
||||||
sql,
|
sql: sql as any, // plus.sqlite 实际支持 string | string[],TS 声明不完整
|
||||||
success(res: any) {
|
success(res: any) {
|
||||||
resolve(res)
|
resolve(res)
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user