<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      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  幽暗天琴  閱讀(1513)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 麻豆人妻| 亚洲国产成人资源在线| 四虎影视库国产精品一区| 国产av无码专区亚洲草草| 国产精品自偷一区在线观看| 国产综合视频一区二区三区| 亚洲国产午夜福利精品| 日本极品少妇videossexhd| 亚洲免费的福利片| 亚洲一区二区三区在线| 国产永久免费高清在线| 蜜桃一区二区三区免费看| 国产一区二区内射最近更新| 99国产精品白浆无码流出| 国语精品一区二区三区| 日韩福利片午夜免费观着| 亚洲欧美日韩愉拍自拍美利坚| 亚洲中文字幕在线二页| 男女激情一区二区三区| 成人网站国产在线视频内射视频| av综合亚洲一区二区| 一本色道婷婷久久欧美| 日韩亚av无码一区二区三区| 特黄特色的大片观看免费视频| 波多结野衣一区二区三区| 亚洲情A成黄在线观看动漫尤物| 又黄又无遮挡AAAAA毛片| 国产精品中文字幕第一区| 亚洲精品日韩中文字幕| 国产精品久久自在自线不卡| 永久免费av网站可以直接看的| 久久月本道色综合久久| 国产爆乳无码视频在线观看3| 日韩丝袜亚洲国产欧美一区| 被黑人巨大一区二区三区| 国产精品中文字幕av| 亚洲人成小说网站色在线| 国产亚洲精品合集久久久久| 伊人欧美在线| 国产免费午夜福利片在线| 亚洲国产精品成人无码区|