uniapp使用本地数据库sqlite,以及文件下载并保存到设备本地

一、建立SQL.js,内容如下:

class SQL {

constructor(plus) {
// 数据库名称一个软件只需要一个库这里写死
this.name = 'sqlite_mine_sql';
this.prefix = 'im_'; //数据表前缀
this.plus = plus;
// 存储路径
this.path = `_doc/sqlite_mine.db`;
this.totalNum = 100000;//每张数据表可以保存数据上限,超过则自动清理
}

initDatabase() {
return new Promise((resolve, reject) => {
const that = this;
console.log('数据表初始化');

// **第一步:打开数据库**
plus.sqlite.openDatabase({
name: that.name,
path: this.path,
success() {
console.log("数据库打开成功,开始检查表");

// **定义要创建的表**
//1.媒体表,存储视频,音频,图片本地路径
const tables = [{
name: "im_media",
createSql: `
CREATE TABLE IF NOT EXISTS im_media (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT,
url TEXT UNIQUE,
localUrl TEXT,
mid TEXT
)`
},
//2.聊天表-私聊
{
name: "im_chat_user",
createSql: `
CREATE TABLE IF NOT EXISTS im_chat_user (
id INTEGER DEFAULT 0,
userid TEXT,
type TEXT,
touid INTEGER,
tip_uid INTEGER DEFAULT 0,
groupid INTEGER DEFAULT 0,
content TEXT,
content1 TEXT,
addtime INTEGER,
self INTEGER DEFAULT 0,
isread INTEGER DEFAULT 0,
ishow INTEGER DEFAULT 1,
isback INTEGER DEFAULT 0,
del_uids TEXT DEFAULT '@',
sender TEXT,
chat_id TEXT
)`
},
//3.聊天表-群聊 chat_id标识聊天ID
{
name: "im_chat_group",
createSql: `
CREATE TABLE IF NOT EXISTS im_chat_group (
id INTEGER DEFAULT 0,
userid TEXT,
type TEXT,
touid INTEGER,
tip_uid INTEGER DEFAULT 0,
groupid INTEGER DEFAULT 0,
content TEXT,
content1 TEXT,
addtime INTEGER,
self INTEGER DEFAULT 0,
isread INTEGER DEFAULT 0,
ishow INTEGER DEFAULT 1,
isback INTEGER DEFAULT 0,
del_uids TEXT DEFAULT '@',
sender TEXT,
chat_id TEXT
)`
},
/*4.定期清理数据表
status 0为不清理,1为已清理
table_name清理的表名
num_clean清理的数量
addtime 本次清理时间
nexttime 下次清理时间
content 本次操作描述
*/
{
name: "im_clean",
createSql: `
CREATE TABLE IF NOT EXISTS im_clean (
id INTEGER PRIMARY KEY AUTOINCREMENT,
status INTEGER DEFAULT 0,
table_name TEXT,
num_clean INTEGER DEFAULT 0,
addtime INTEGER,
nexttime INTEGER,
content TEXT
)`
}
];

// **创建表的 Promise 数组**
let tablePromises = tables.map(table => {
return new Promise((resolveTable, rejectTable) => {
let checkTableSql =
`SELECT name FROM sqlite_master WHERE type='table' AND name='${table.name}'`;

plus.sqlite.selectSql({
name: that.name,
sql: checkTableSql,
success(data) {
if (data.length === 0) {
console.log(
`${table.name} 表不存在,开始创建`);
plus.sqlite.executeSql({
name: that.name,
sql: table.createSql,
success() {
console.log(
`${table.name} 表创建成功`
);
resolveTable(
`${table.name} 表创建成功`
);
},
fail(e) {
console.error(
`创建 ${table.name} 失败:`,
JSON
.stringify(
e));
rejectTable(
`创建 ${table.name} 失败`
);
}
});
} else {
console.log(`${table.name} 表已存在`);
resolveTable(`${table.name} 表已存在`);
}
},
fail(e) {
console.error(`查询 ${table.name} 失败:`,
JSON.stringify(e));
rejectTable(`查询 ${table.name} 失败`);
}
});
});
});

// **等待所有表创建完成**
Promise.all(tablePromises)
.then(results => {
console.log("所有表初始化完成", results);
resolve({
message: "所有表初始化完成",
results
});
})
.catch(error => {
console.error("表初始化失败:", error);
reject({
message: "表初始化失败",
error
});
});
},
fail(e) {
console.error("数据库打开失败:", JSON.stringify(e));
reject({
message: "数据库打开失败",
error: e
});
}
});
});
}

// 连接数据库
openDB() {
return new Promise((resolve, reject) => {
if (this.isOpen()) {
return resolve();
}
this.initDatabase();
});
}

// 判断数据库是否打开
isOpen() {
return this.plus.sqlite.isOpenDatabase({
name: this.name,
path: this.path
});
}

// 关闭数据库
closeDB() {
this.plus.sqlite.closeDatabase({
name: this.name,
success(e) {
console.log('closeDatabase success!');
},
fail(e) {
console.warn('closeDatabase failed: ' + JSON.stringify(e));
}
});
}

/* 执行sql语句
options示例:{addtime:{'>=',1234567890,'<=',1234567980},isgroup:1,or:[{ userid: 1, touid: 2 },{ userid: 2, touid: 1 }]}
表示查询addtime >= 1234567890 && addtime <=xxx && isgroup = 1 && (userid= 1 && touid= 2 || userid= 2 && touid= 1)
handleType类型 dbname数据表 options条件 data修改时操作的数据 sort查询时排序 page查询时分页数据*/
async handleSQL(handleType, dbname, options, data = {}, sort = 'id asc', page = {
pageNum: 1, //多少页
pageSize: 30 //每页多少条
}, isClose = false) {
await this.openDB();
// await this.initDatabase();
if (!dbname.includes('im_')) {
// console.log('表不包含前缀 im_');
dbname = this.prefix + dbname;
}
switch (handleType) {
case 'insert':
//插入单条数据
return this.insertSQL(dbname, options, isClose);
case 'insertAll':
//批量插入数据
return this.insertAllSQL(dbname, options, isClose);
case 'delete':
//删除数据
return this.deleteSQL(dbname, options, isClose);
case 'select':
//查询多条数据
return this.selectSQL(dbname, options, sort, page, isClose);
case 'update':
//编辑修改数据
return this.updateSQL(dbname, data, options, isClose);
case 'find':
//查询单条数据
return this.findSQL(dbname, options, sort = "id DESC", 0, isClose);
case 'findIn':
//查询指定数据是否在数据库如 {id:[1,2,3]}为查询这3条数据在数据库的条数
return this.findInSQL(dbname, options, isClose);
default:
throw new Error('没有这个操作!!!');
}
}

// 插入sql语句
insertSQL(dbname, options, isClose) {
const that = this;
return new Promise((resolve, reject) => {
if (!options || Object.keys(options).length === 0) {
// console.error("insertSQL 失败:options 不能为空");
return reject("插入数据不能为空");
}

const keys = Object.keys(options).join(', '); // "type, url, localUrl"
const valuesStr = Object.values(options).map(val => `'${val}'`).join(
', '); // "'image', 'http://...', '_doc/...'"

const sql = `INSERT OR IGNORE INTO ${dbname} (${keys}) VALUES (${valuesStr});`; //忽略唯一索引已存在的

// console.log('执行插入 SQL:', sql);
that.plus.sqlite.executeSql({
name: that.name,
sql: sql,
success() {
// console.log('insertSQL success');

// 查询刚插入的数据
that.plus.sqlite.selectSql({
name: that.name,
sql: "SELECT last_insert_rowid() AS id;",
success(data) {
// console.log('最后插入的 ID:', data[0].id);
isClose && that.closeDB();
resolve(data);
},
fail(e) {
console.warn('查询 last_insert_rowid 失败:', JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});
},
fail(e) {
console.warn('insertSQL failed:', JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});
});
}

//插入多条数据
insertAllSQL(dbname, options, isClose) {
const that = this;
return new Promise((resolve, reject) => {
if (!options || (Array.isArray(options) && options.length === 0)) {
// console.error("insertSQL 失败:options 不能为空");
return reject("插入数据不能为空");
}

let keys, valuesStr;


if (Array.isArray(options)) {
// 处理多条数据
keys = Object.keys(options[0]).join(', '); // 获取字段名
valuesStr = options.map(row =>
`(${Object.values(row).map(val => `'${val}'`).join(', ')})`
).join(', '); // 生成多行插入语句
} else {
// 处理单条数据
keys = Object.keys(options).join(', ');
valuesStr = `(${Object.values(options).map(val => `'${val}'`).join(', ')})`;
}

const sql = `INSERT INTO ${dbname} (${keys}) VALUES ${valuesStr};`;

// console.log('执行插入 SQL:', sql);
that.plus.sqlite.executeSql({
name: that.name,
sql: sql,
success() {
// console.log('insertSQL success');

// 查询最后插入的 ID
that.plus.sqlite.selectSql({
name: that.name,
sql: "SELECT last_insert_rowid() AS id;",
success(data) {
// console.log('最后插入的 ID:', data[0]?.id);
isClose && that.closeDB();
resolve(data[0]?.id || null);
},
fail(e) {
console.warn('查询 last_insert_rowid 失败:', JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});
},
fail(e) {
console.warn('insertSQL failed:', JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});
});
}


// 删除sql语句
deleteSQL(dbname, options, isClose) {
return new Promise((resolve, reject) => {
const that = this;
if (!options || Object.keys(options).length === 0) {
// console.log("deleteSQL 失败:options 不能为空");
return reject("删除条件不能为空");
}

// 生成 WHERE 条件
let whereClauseParts = [];

// 处理非 or 的条件
Object.keys(options).forEach(key => {
if (key !== "or") {
let value = options[key];
if (typeof value === "object" && value !== null) {
// 处理多个运算符
Object.entries(value).forEach(([operator, val]) => {
whereClauseParts.push(`${key} ${operator} '${val}'`);
});
} else {
whereClauseParts.push(`${key} = '${value}'`);
}
}
});

// 处理 or 逻辑
if (options.or) {
let orClause = options.or.map(group =>
"(" + Object.entries(group)
.map(([key, value]) => `${key} = '${value}'`)
.join(" AND ") + ")"
).join(" OR ");

whereClauseParts.push(`(${orClause})`);
}

// 组合 WHERE 条件
let whereClause = whereClauseParts.length ? " WHERE " + whereClauseParts.join(" AND ") : "";

// 生成完整的 SQL 语句
const sql = `DELETE FROM ${dbname} ${whereClause};`;

// console.log("执行 deleteSQL:", sql); // 调试 SQL 语句

that.plus.sqlite.executeSql({
name: that.name,
sql: sql,
success(data) {
// console.log('deleteSQL success: ' + JSON.stringify(data));
isClose && that.closeDB();
resolve(data);
},
fail(e) {
console.warn('deleteSQL failed: ' + JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});
});
}

// 查询sql语句 options参数为查询条件
selectSQL(dbname, options, sort, page, isClose) {
return new Promise((resolve, reject) => {
const that = this;

if (!options || Object.keys(options).length === 0) {
// console.error("selectSQL 失败:options 不能为空");
return reject("查询条件不能为空");
}

let whereClauseParts = []; // 用于存储各个条件的 SQL 片段

// 处理非 or 的条件
Object.keys(options).forEach(key => {
if (key !== "or") {
let value = options[key];
if (typeof value === "object" && value !== null) {
// 处理多个运算符
Object.entries(value).forEach(([operator, val]) => {
whereClauseParts.push(`${key} ${operator} '${val}'`);
});
} else {
whereClauseParts.push(`${key} = '${value}'`);
}
}
});

// 处理 or 逻辑
if (options.or) {
let orClause = options.or.map(group =>
"(" + Object.entries(group)
.map(([key, value]) => `${key} = '${value}'`)
.join(" AND ") + ")"
).join(" OR ");

whereClauseParts.push(`(${orClause})`);
}

// 组合 WHERE 条件
let whereClause = whereClauseParts.length ? " WHERE " + whereClauseParts.join(" AND ") : "";

// 解析分页参数
let pageNum = page?.pageNum || 1; // 默认为第1页
let pageSize = page?.pageSize || 30; // 默认为30条
let offset = (pageNum - 1) * pageSize; // 计算OFFSET

// 生成完整的 SQL 语句
const selectSQL =
`SELECT * FROM ${dbname} ${whereClause} ORDER BY ${sort} LIMIT ${pageSize} OFFSET ${offset};`;
// **查询总条数**
const countSQL = `SELECT COUNT(*) as total FROM ${dbname} ${whereClause};`;

// console.log('select语句:', selectSQL)

// 先执行统计查询
that.plus.sqlite.selectSql({
name: that.name,
sql: countSQL,
success(countData) {
let total = countData[0]?.total || 0; // 获取总条数
// console.log('条数', total)

// 再执行分页查询
that.plus.sqlite.selectSql({
name: that.name,
sql: selectSQL,
success(data) {

if (dbname == that.prefix+'chat_user' || dbname == that.prefix+'chat_group') {
// 重新排序
// console.log('重新排序',data)
data.sort((a, b) => {
if (a.addtime !== b.addtime) {
return a.addtime - b
.addtime; // addtime 从小到大
}
if (a.id === 0 && b.id !== 0) {
return -1; // id=0 的排前面
}
if (a.id !== 0 && b.id === 0) {
return 1; // id≠0 的排后面
}
return a.id - b.id; // id 从小到大
});
// **排序后直接还原数据**
data = data.map(i => ({
...i, // 直接扩展原对象,保持不变的字段
id: i.id === 0 && i.type === 'time' ? i
.addtime : i.id,
content: i.content.replace(/''/g, "'")
.replace(/\\"/g, '"'), // 还原单引号和双引号
content1: that.tryParseJSON(i
.content1), // 解析 JSON
sender: that.tryParseJSON(i
.sender) // 解析 JSON
}));
}

// console.log('selectSQL success:', JSON.stringify(data));
let totalPages = Math.ceil(total / pageSize); // 计算总页数

resolve({
pageNum,
pageSize,
total,
totalPages,
list: data // **直接返回分页后的数据**
});

isClose && that.closeDB();
},
fail(e) {
console.log('selectSQL failed:', JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});
},
fail(e) {
console.log('countSQL failed:', JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});

});
}

//修改sql语句
updateSQL(dbname, data, options, isClose) {
const that = this;
return new Promise((resolve, reject) => {

if (!data || Object.keys(data).length === 0) {
// console.error("updateSQL 失败:更新数据不能为空");
return reject("更新数据不能为空");
}
if (!options || Object.keys(options).length === 0) {
// console.error("updateSQL 失败:条件不能为空");
return reject("更新条件不能为空");
}

// 构造 SET 语句
let setClause = Object.keys(data)
.map(key => `${key} = '${data[key]}'`)
.join(", ");

let whereClauseParts = []; // 用于存储各个条件的 SQL 片段

// 处理非 or 的条件
Object.keys(options).forEach(key => {
if (key !== "or") {
let value = options[key];
if (typeof value === "object" && value !== null) {
// 处理多个运算符
Object.entries(value).forEach(([operator, val]) => {
whereClauseParts.push(`${key} ${operator} '${val}'`);
});
} else {
whereClauseParts.push(`${key} = '${value}'`);
}
}
});

// 处理 or 逻辑
if (options.or) {
let orClause = options.or.map(group =>
"(" + Object.entries(group)
.map(([key, value]) => `${key} = '${value}'`)
.join(" AND ") + ")"
).join(" OR ");

whereClauseParts.push(`(${orClause})`);
}

// 组合 WHERE 条件
let whereClause = whereClauseParts.length ? " WHERE " + whereClauseParts.join(" AND ") : "";

// 生成完整的 SQL 语句
const sql = `UPDATE ${dbname} SET ${setClause} ${whereClause};`;

// console.log("执行 SQL:", sql); // 调试 SQL 语句

that.plus.sqlite.executeSql({
name: that.name,
sql: sql,
success(data) {
// console.log('updateSQL success: ' + JSON.stringify(data));
isClose && that.closeDB();
resolve(data);
},
fail(e) {
console.warn('updateSQL failed: ' + JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});
});
}

// 查询单条数据的 SQL 语句
findSQL(dbname, options, sort = 'id DESC', offset= 0, isClose) {
return new Promise((resolve, reject) => {
const that = this;

//查询条件为空则返回id最大的数据
// if (!options || Object.keys(options).length === 0) {
// // console.error("queryOneSQL 失败:options 不能为空");
// return reject("查询条件不能为空");
// }

let whereClauseParts = []; // 用于存储各个条件的 SQL 片段

// 处理非 or 的条件
Object.keys(options).forEach(key => {
if (key !== "or") {
let value = options[key];
if (typeof value === "object" && value !== null) {
// 处理多个运算符
Object.entries(value).forEach(([operator, val]) => {
whereClauseParts.push(`${key} ${operator} '${val}'`);
});
} else {
whereClauseParts.push(`${key} = '${value}'`);
}
}
});

// 处理 or 逻辑
if (options.or) {
let orClause = options.or.map(group =>
"(" + Object.entries(group)
.map(([key, value]) => `${key} = '${value}'`)
.join(" AND ") + ")"
).join(" OR ");

whereClauseParts.push(`(${orClause})`);
}

// 组合 WHERE 条件
let whereClause = whereClauseParts.length ? " WHERE " + whereClauseParts.join(" AND ") : "";
let whereOffset = offset > 0 ? " OFFSET " + offset : "";

// 生成完整的 SQL 语句
const sql = `SELECT * FROM ${dbname} ${whereClause} ORDER BY ${sort} LIMIT 1 ${whereOffset};`;

// console.log("执行 SQL:", sql); // 调试 SQL 语句

that.plus.sqlite.selectSql({
name: that.name,
sql: sql,
success(data) {
// console.log('findSQL success: ' + JSON.stringify(data));
isClose && that.closeDB();
// 只返回第一条数据
resolve(data.length > 0 ? data[0] : null);
},
fail(e) {
console.warn('findSQL failed: ' + JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});
});
}

// in查询数据是否在数据库
findInSQL(dbname, options, isClose) {
return new Promise((resolve, reject) => {
const that = this;

if (!options || Object.keys(options).length === 0) {
return reject("查询条件不能为空");
}

let whereClauseParts = []; // 存储 WHERE 条件

Object.keys(options).forEach(key => {
let values = options[key];

if (Array.isArray(values) && values.length > 0) {
// 生成 IN 查询部分
let inValues = values.map(val => `'${val}'`).join(", ");
whereClauseParts.push(`${key} IN (${inValues})`);
} else {
whereClauseParts.push(`${key} = '${values}'`);
}
});

// 组合 WHERE 条件
let whereClause = whereClauseParts.length ? " WHERE " + whereClauseParts.join(" AND ") : "";

// 构造 SQL 语句
let sql = `SELECT COUNT(*) AS count FROM ${dbname} ${whereClause}`;

// 执行查询
that.plus.sqlite.selectSql({
name: that.name,
sql: sql,
success(data) {
isClose && that.closeDB();
// 返回查询到的数量
resolve(data.length > 0 ? data[0].count : 0);
},
fail(e) {
console.log('findInSQL failed: ' + JSON.stringify(e));
isClose && that.closeDB();
reject(e);
}
});

})
}
// 自动清理超量数据专用函数
deleteExcessData(isClose) {
return new Promise((resolve, reject) => {
let that = this;
//全部表清理,获取全部表名
const sql = `SELECT name FROM sqlite_master WHERE type='table'`;
// 获取所有表名
that.plus.sqlite.selectSql({
name: that.name,
sql: sql,
success(tablesData) {
// console.log('全部表名:', tablesData)
let totime = Math.floor(Date.now() / 1000); //当前时间戳
let totime_7day = totime + 7*24*3600; //7天后时间戳
let totalNum = that.totalNum;//超过此数量需要清理
let data_clean = {};//需要更新的clean表数据

// 遍历每个表,获取表的记录条数
tablesData.forEach(table => {
const tableName = table.name;
if (!tableName.includes('im_')) {
return;// 如果表名不包含 'im_',则跳过当前循环
}
const checkTableCountSql = `SELECT COUNT(*) AS table_count FROM ${tableName}`;

that.plus.sqlite.selectSql({
name: that.name, // 数据库名称
sql: checkTableCountSql,
success(res) {
// console.log("数据表数量:", res[0].table_count);
if (res[0].table_count <= totalNum) {
// console.log('总数量为:' + res[0].table_count + ',没有超过:' + totalNum)
data_clean = {
status: 0,
table_name: tableName,
num_clean: 0,
addtime: totime,
nexttime: totime_7day,
content: '总数量为:' + res[0].table_count + ',没有超过:' + totalNum
}
// resolve(res[0].table_count)
} else {
//需要进行删除操作
let changeNum = res[0].table_count - totalNum;
data_clean = {
status: 1,
table_name: tableName,
num_clean: changeNum,
addtime: totime,
nexttime: totime_7day,
content: '超过:' + totalNum+',本次清理数量为:'+ changeNum
}
//删除多于的数据
let sort = "id ASC";
let field = "id";
if(tableName == that.prefix+'chat_user' || tableName == that.prefix+'chat_group'){
sort = "addtime ASC"
field = "addtime"
}
that.findSQL(tableName,{},sort,changeNum).then((val)=>{
// console.log('看看查出来的数据',val)
if(val && val[field]){
//执行删除
// console.log('执行删除',val[field])
that.deleteSQL(tableName,{[field]:{'<=':val[field]}}).then((del)=>{
console.log('删除多于数据成功',del)
})
}
})
// resolve(res[0].table_count);
}
that.handleSQL('insert','clean',data_clean);
},
fail(e) {
console.warn("查询表数量失败:", JSON.stringify(e));
reject(e);
}
});
})

}
})


});
}

// **还原插入时转成json的**
tryParseJSON(value) {
if (!value) {
return value;
}
let jsonStr = value.replace(/\\\"/g, '"'); // 先去掉多余的转义
try {
return JSON.parse(jsonStr);
} catch (e) {
// console.warn("JSON 解析失败,直接返回:", value);
return jsonStr;
}
}

}

export default new SQL(plus);

二、引入方式:在main.js引入

// #ifdef APP-PLUS
import SQL from './library/SQL.js'; // 引入 SQL 类
Vue.prototype.$sql = SQL; // 挂载到 Vue 全局
// #endif

 

//文件缓存
Vue.prototype.file_cache = async function(image_url,type='image',mid='') {

// #ifndef APP-PLUS
if (image_url == undefined) return false;

if (image_url.indexOf('http') <= -1) image_url = store.getters.get_weburl.imgUri + image_url;

return image_url;
// #endif


// #ifdef APP-PLUS
if (image_url == undefined) return false;

if (image_url.indexOf('http') <= -1) image_url = store.getters.get_weburl.imgUri + image_url;
// return '_doc/uniapp_save/17404810011980.jpg';
try {
let res = await this.$sql.handleSQL('find', 'media', {
type: type,
url: image_url
});
if (res) {
image_url = res.localUrl; // ✅ 查询到本地缓存,返回本地路径
} else {
// 没查询到,需要下载并缓存
try {
// 先返回原始 URL,不等待下载完成
(async () => {
try {
let localPath = await action.localSaveFileHttp(type, mid, image_url);

// 下载完成后,更新数据库
let insertId = await this.$sql.handleSQL('insert', 'media', {
type: type,
url: image_url,
mid: mid,
localUrl: localPath
});
// console.log("文件下载并插入数据库成功 ID:", insertId);
} catch (error) {
// console.error("后台文件下载失败:", error);
}
})();
// console.log('立即返回',image_url)
return image_url; // 立即返回原始 URL
} catch (error) {
return image_url; // 发生异常,依然返回原始 URL
}

}
return image_url;
} catch (error) {
return image_url; // ❌ 查询数据库失败,返回原始 URL
}
// #endif

}

 

二、(2)action的方法:

// 服务器下载到本地
async localSaveFileHttp(type, mid, url) {
return new Promise((resolve, reject) => {
uni.downloadFile({
url: url, // 你的音频文件或其他文件的 HTTPS 链接
success: (downloadRes) => {
if (downloadRes.statusCode === 200) {
// 下载成功,保存文件
let localPath = this.localSaveFile(type, mid, downloadRes.tempFilePath, url);
resolve(localPath); // ✅ 返回最终的本地路径
} else {
// console.error('文件下载失败:', downloadRes);
reject(new Error('下载失败,状态码:' + downloadRes.statusCode));
}
},
fail: (error) => {
// console.error('下载文件失败:', error);
reject(url);
}
});
});
}

// 文件保存本地类型type 唯一标识mid,url远程路径
async localSaveFile(type, mid, tempFilePath, url = '') {
return new Promise((resolve, reject) => {
uni.saveFile({
tempFilePath: tempFilePath,
success: (saveRes) => {
let savedFilePath = saveRes.savedFilePath; // 获取本地存储路径
// console.log('文件保存成功:', savedFilePath);
resolve(savedFilePath); // ✅ 正确返回保存后的本地路径
},
fail: (error) => {
console.error('保存失败:', error);
reject(error);
}
});
});
}

 

三、使用方式:

(1)先在App.vue的onLaunch初始化数据库:

//监听数据库状态
this.$sql.openDB().then(() => {

}).then(() => {
console.log("数据库初始化完成");
}).catch(err => {
console.error("数据库初始化失败:", err);
});

(2)在退出app时关闭数据库:

//应用完全退出,关闭数据库
onUnload() {
// #ifdef APP-PLUS
console.log('应用彻底退出,关闭数据库');
this.$sql.closeDB();
// #endif
},

 

(3)使用案例:

 //替换视频缩略图为本地图片
this.vedioImgSrc = await this.file_cache(url,'vedio');
posted @ 2025-02-26 20:10  幽暗天琴  阅读(1349)  评论(0)    收藏  举报