diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json index a97fd25..59d78d5 100644 --- a/.hbuilderx/launch.json +++ b/.hbuilderx/launch.json @@ -4,7 +4,7 @@ "configurations": [{ "app-plus" : { - "launchtype" : "local" + "launchtype" : "remote" }, "default" : { diff --git a/App.vue b/App.vue index 8a45324..b59f73f 100644 --- a/App.vue +++ b/App.vue @@ -1,12 +1,12 @@ - diff --git a/pages/im/private/index.vue b/pages/im/private/index.vue index 6cb5d5b..988a19a 100644 --- a/pages/im/private/index.vue +++ b/pages/im/private/index.vue @@ -1,41 +1,33 @@ - @@ -64,5 +64,6 @@ } - diff --git a/store/modules/im.js b/store/modules/im.js index 4c4f80f..607eb51 100644 --- a/store/modules/im.js +++ b/store/modules/im.js @@ -1,11 +1,9 @@ -import { - getUserInfo -} from "@/apis/interfaces/im.js" +import im from "@/utils/im/index.js" export default { state: { newMsg: {}, - friends: [], + friends: {}, sender: {} }, getters: { @@ -16,12 +14,22 @@ export default { return state.friends }, userInfo: (state) => (targetId) => { - if (state.friends.filter((item) => item.userId == targetId)[0]) { - return state.friends.filter((item) => String(item.userId) == targetId)[0] + if (state.friends[targetId]) { + return state.friends[targetId] } else { - return getUserInfo(targetId) + console.log('没找到', targetId); + im.syncUserInfo(targetId) + return { + name: '', + address: '', + hash: '', + portraitUrl: '' + } } }, + hasUser: (state) => (targetId) => { + return Boolean(state.friends[targetId]) + }, sender(state) { return state.sender } @@ -30,8 +38,8 @@ export default { newMessage(state, msg) { Vue.set(state, 'newMsg', msg) }, - updateFriends(state, list) { - state.friends = list + updateFriends(state, userInfo) { + Vue.set(state.friends, userInfo.userId, userInfo) }, SET_state_sender(state, userInfo) { state.sender = userInfo @@ -43,15 +51,77 @@ export default { }, msg) { commit('newMessage', msg) }, - updateFriends({ - commit - }, list) { - commit('updateFriends', list) - }, setSenderInfo({ commit }, userInfo) { commit('SET_state_sender', userInfo) + }, + updateFriends({ + commit + }, userInfo) { + commit('updateFriends', userInfo) + const model = uni.model.friendModel + model.find('userId=' + userInfo.userId, (err, user) => { + if (!err && user.length == 0) { + console.log('哪里更新的 ', 1); + saveAvatar(userInfo, (savedFilePath) => { + model.insert({ + userId: userInfo.userId, + name: userInfo.name, + hash: userInfo.hash, + address: userInfo.address, + portraitUrl: savedFilePath, + }, (err, result) => {}) + userInfo.portraitUrl = savedFilePath + commit('updateFriends', userInfo) + }) + } else if (!err && user[0].hash != userInfo.hash) { + console.log('哪里更新的 ', 2); + saveAvatar(userInfo, (savedFilePath) => { + model.update('userId=' + userInfo.userId, { + name: userInfo.name, + hash: userInfo.hash, + portraitUrl: savedFilePath, + }, (err, result) => {}) + userInfo.portraitUrl = savedFilePath + commit('updateFriends', userInfo) + }) + } else if (!err && user[0].portraitUrl.length > 50) { + saveAvatar(userInfo, (savedFilePath) => { + model.update('userId=' + userInfo.userId, { + name: userInfo.name, + hash: userInfo.hash, + portraitUrl: savedFilePath, + }, (err, result) => {}) + + userInfo.portraitUrl = savedFilePath + commit('updateFriends', userInfo) + }) + } else { + console.log('不需要有动作', user[0]); + } + }) } } +} + +const saveAvatar = (userInfo, callback) => { + uni.downloadFile({ + url: userInfo.portraitUrl, + success: ({ + tempFilePath + }) => { + uni.saveFile({ + tempFilePath: tempFilePath, + success: ({ + savedFilePath + }) => { + callback(savedFilePath) + } + }) + }, + fail: (err) => { + console.log('头像保存失败', err); + } + }) } diff --git a/uni_modules/onemue-USQLite/changelog.md b/uni_modules/onemue-USQLite/changelog.md new file mode 100644 index 0000000..1764a1f --- /dev/null +++ b/uni_modules/onemue-USQLite/changelog.md @@ -0,0 +1,28 @@ +## 2.1.0(2022-01-14) +1. 新增了添加多个数据的事件选项(options, index)(感谢`@风扬`) +## 2.1.2(2022-01-14) +1. 新增了添加多个数据的事件选项(options, index)(感谢`@风扬`) +## 2.1.0(2022-01-14) +1. 新增了添加多个数据的事件选项(options, index)(感谢`@风扬`) +## 2.0.2(2022-01-05) +1. 新增了联合主键,详见文档 +## 2.0.1(2021-12-30) +1. 关闭了sql 输出信息 +## 2.0.0(2021-12-30) +1. 重构了代码 +2. 优化了调用模式 +3. 提供了相对完善示例项目 +## 1.2.0(2021-12-22) +1. 移除了不设置主键自动增加主键,已经有的无需处理,原有组件自增 无需操作 +2. 增加了表的重命名 +3. 增加了列表的新建列 +## 1.1.0(2021-12-20) +1. 增加了约束相关内容 +## 1.0.1(2021-12-17) +1. 修复了特殊表名无法使用的问题例如`[object Object]` +## 1.0.0(2021-12-16) +基于 html5-Plus的 sqlite 数据库方法封装 +1. 封装了简单的增删改查方法 +2. 使用ORM方式操作数据 +3. 可以使用链式调用 +4. 支持原生语法 diff --git a/uni_modules/onemue-USQLite/js_sdk/usqlite.js b/uni_modules/onemue-USQLite/js_sdk/usqlite.js new file mode 100644 index 0000000..1c6877d --- /dev/null +++ b/uni_modules/onemue-USQLite/js_sdk/usqlite.js @@ -0,0 +1,612 @@ +/** + * 对 SQLite 的 ORM 的封装处理 + * @time 2021-12-30 11:00:00 + * @version 2.0.0 + * + * @by onemue + */ + +let config = { + deBug: true, + isConnect: false +} +class Response { + constructor(code, msg, data) { + this.code = code; + this.msg = msg; + this.data = data; + } + toString() { + return JSON.stringify(this); + } +} + +class Utils { + static modelSql(name, options) { + let sql; + let sqlArr = []; + let primaryKeyArr = []; + Utils.log('options:' + options); + for (const key in options) { + if (Object.hasOwnProperty.call(options, key)) { + const option = options[key]; + sqlArr.push(Utils.restrain(key, option)); + if (option.primaryKey == true) { + primaryKeyArr.push(key.toString()); + Utils.log(`${key} is primary key${primaryKeyArr.length}`); + } + } + } + Utils.log(primaryKeyArr.length); + if (primaryKeyArr.length >= 1) { + sql = `CREATE TABLE '${name}' (${sqlArr.join(', ')}, PRIMARY KEY (${primaryKeyArr.join()}))`; + } else { + sql = `CREATE TABLE '${name}' (${sqlArr.join(', ')})`; + } + Utils.log(`modelSql :${sql}`); + return sql; + } + + static restrain(key, options) { + + let restrainArray = []; + restrainArray.push(`'${key}'`); + + // 如果是 String 拦截处理 + if (options.constructor != Object) { + restrainArray.push(Utils.toType(options)); + return restrainArray.join(' '); + } + + restrainArray.push(Utils.toType(options.type)); + // 非空 + if (options.notNull == true) { + restrainArray.push('NOT NULL'); + } + + // 默认值 + if (options.default) { + restrainArray.push(`DEFAULT ${options.default}`); + } + + // 是否是不同的值 + if (options.unique == true) { + restrainArray.push('UNIQUE'); + } + + // 主键 + // if (options.primaryKey === true) { + // restrainArray.push('PRIMARY KEY'); + // } + + // 检查 + if (options.check) { + restrainArray.push(`CHECK(${THIS_VALUE.check})`); + } + + return restrainArray.join(' '); + } + + // 联合主键 + static getUnionPrimaryKey() { + + } + + static toType(jsType) { + let sqliteType = ''; + if (jsType == Number) { + sqliteType = 'numeric'; + } else if (jsType == Date) { + sqliteType = 'timestamp'; + } else { + sqliteType = 'varchar'; + } + return sqliteType; + } + static log() { + if (config.deBug) { + console.log.apply(null, arguments); + } + } +} + + +/** + * Model 对象内部public方法全部 return this; + */ +class Model { + /** + * @constructor + * @param {String} name 数据库表名 + * @param {Object} options 数据表列对象 + * @returns + */ + constructor(name, options) { + let self = this; + self.name = name; + self.options = options; + + if (config.isConnect) { + self.repair(); + } else { + console.error('no connect'); + } + } + + /** + * @description 查询表数据 + * @param {String|Array} options + * - String WHERE 内容 + * - Array 需要查询的列 + * @param {*} callback + * @returns + */ + find(options, callback) { + let sql = ''; + let self = this; + self.repair(); + if (!callback) { + sql = `SELECT * FROM '${this.name}'`; // 查找全部 + callback = options; + } else if (options.constructor == Array) { + sql = `SELECT ${options.join()} FROM '${this.name}'`; // 查找制定列 + } else if (options.constructor == String) { + sql = `SELECT * FROM '${this.name}' WHERE ${options}`; // 制定条件查询 + }; + + Utils.log(`find: ${sql}`); + + plus.sqlite.selectSql({ + name: config.name, + sql: sql, + success(e) { + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + + return self; + } + + /** + * @description 分页查询 + * @param {Object} options : { where:查询条件, number: 当前页数 , count : 每页数量 } + * @param {Function} callback :(err,results)=>{} + * @return + */ + limit(options, callback) { + let sql = ''; + let self = this; + self.repair(); + + if (!options.where) { + // 不存在 where + sql = + `SELECT * FROM '${this.name}' LIMIT ${options.count} OFFSET ${(options.number - 1) * options.count}` + } else { + // 存在 where + sql = + `SELECT * FROM '${this.name}' WHERE ${options.where} LIMIT ${options.count} OFFSET ${(options.number - 1) * options.count}`; + }; + + Utils.log(`limit: ${sql}`); + + plus.sqlite.selectSql({ + name: config.name, + sql: sql, + success(e) { + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + return this; + } + + /** + * @description 插入数据 + * @param {Object|Array} options: 需要插入的单个或者多个数据 + * @param {Function} callback :(err,results)=>{} + */ + insert(options, callback) { + let self = this; + self.repair(); + + if (config.isConnect) { + if (options.constructor == Array) { + for (var i = 0; i < options.length; i++) { + this.insert(options[i], callback, i); + } + } else if (options.constructor == Object) { + let keys = []; + let values = []; + let index = arguments[3] ?? null; + for (var key in options) { + keys.push(key); + values.push(`'${options[key]}'`); + } + + let sql = `INSERT INTO '${this.name}' (${keys.join()}) VALUES (${values.join()})`; + + Utils.log(`insert: ${sql}`); + plus.sqlite.executeSql({ + name: config.name, + sql: sql, + success(e) { + if (index) { + callback(null, e, options, index); + } + callback(null, e, options); + }, + fail(e) { + if (index) { + callback(e, null, options, index); + } + callback(e, null, options); + } + }) + } + } + return this; + } + + /** + * @description 更新数据 + * @param {Object} options:可选参数 更新条件 + * @param {Object} obj: 修改后的数据 + * @param {Function} callback :(err,results)=>{} + */ + update(options, obj, callback) { + let sql = ''; + let self = this; + let items = []; + self.repair(); + + if (!callback) { + // 不存在options + callback = obj; + obj = options; + + for (var key in obj) { + items.push(`${key}='${obj[key]}'`); + }; + sql = `UPDATE '${this.name}' SET ${items.join()}`; + } else { + // 存在options + for (var key in obj) { + items.push(`${key}='${obj[key]}'`); + }; + sql = `UPDATE ${this.name} SET ${items.join()} WHERE ${options}`; + }; + Utils.log(`update: ${sql}`); + plus.sqlite.executeSql({ + name: config.name, + sql: sql, + success(e) { + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + + return this; + } + + /** + * @description 删除数据 + * @param {Object} options :可选参数 删除条件 + * @param {Function} callback :(err,results)=>{} + */ + delete(options, callback) { + var sql = ''; + let self = this; + self.repair(); + + if (!callback) { + sql = `DELETE FROM '${this.name}'`; + callback = options; + } else { + sql = `DELETE FROM '${this.name}' WHERE ${options}`; + }; + Utils.log(`delete: ${sql}`); + plus.sqlite.executeSql({ + name: config.name, + sql: sql, + success(e) { + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + + return this; + } + + + /** + * @description 重命名或者新增列 + * @param {Object} options 参数 数组为新增多列 对象为新增单列{aa} 字符串重命名 + * @param {Function} callback :(err,results)=>{} + * @return: + */ + alter(options, callback) { + let self = this; + let sql = ''; + self.repair(); + + if (options.constructor == Array) { // 新增多列 + for (let i = 0; i < options.length; i++) { + self.alter(options[i], callback); + } + } else if (options.constructor == Object) { // 新增单列 + let column = Utils.restrain(options.name, options.option); + sql = `ALTER TABLE '${this.name}' ADD COLUMN ${column}` + } else if (options.constructor == String) { // 重命名 + sql = `ALTER TABLE '${self.name}' RENAME TO '${options}'` + } + Utils.log(`alter: ${sql}`); + plus.sqlite.selectSql({ + name: config.name, + sql: sql, + success(e) { + if (options.constructor == String) { // 重命名 + self.name = options; + } + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + return this; + } + /** + * @description + * @param {Model} model 右 Model + * @param {Object} options + * @param {Function} callback + * @returns + */ + join(model, options, callback) { + if (!model) { + console.error('"model" cannot be empty.'); + } + if (options.constructor != Object) { + console.error('The type of "options" is wrong, it should be "Object".'); + } + if (!options.type || !options.predicate) { + console.error('Missing required parameters'); + } + + let leftName = this.name; + let rightName = model.name; + let leftValue = options.predicate.left; + let rightValue = options.predicate.right; + let cols = ['*']; + self.repair(); + + const SQL_MAP = { + cross: `SELECT ${cols.join()} FROM ${leftName} CROSS JOIN ${rightName};`, + inner: [`SELECT ${cols.join()} FROM ${leftName} NATURAL JOIN ${rightName}`, + `SELECT ${cols.join()} FROM ${leftName} INNER JOIN ${rightName} ON ${leftName}.${leftValue} = ${rightName}.${rightValue}` + ], + outer: `SELECT ${cols.join()} FROM ${leftName} OUTER JOIN ${rightName} ON ${leftName}.${leftValue} = ${rightName}.${rightValue}` + } + + let sql = ''; + if (options.type == inner && !options.predicate) { + sql = SQL_MAP[options.type][0]; + } else if (options.type == inner && !options.predicate) { + sql = SQL_MAP[options.type][1]; + } else { + sql = SQL_MAP[options.type]; + } + + Utils.log(`join: ${sql}`); + plus.sqlite.selectSql({ + name: config.name, + sql: sql, + success(e) { + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + return this; + } + + /** + * @description 执行sql语句 + * @param {String} sql : sql语句 + * @param {Function} callback :(err,results)=>{} + */ + sql(sql, callback) { + let self = this; + self.repair(); + + Utils.log(`sql: ${sql}`); + plus.sqlite.selectSql({ + name: config.name, + sql: sql, + success(e) { + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + return this; + } + + /** + * @description 判断是否存在 + * @param {Function} callback + */ + isExist(callback) { + let sql = `SELECT count(*) AS isExist FROM sqlite_master WHERE type='table' AND name='${this.name}'`; + let self = this; + Utils.log(`isExist: ${sql}`); + Utils.log(`isExist: ${config.name}`); + plus.sqlite.selectSql({ + name: config.name, + sql: sql, + success(e) { + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + return this; + } + /** + * @description 删除数据表 **不推荐** + * @param {Function} callback + */ + drop(callback) { + var sql = `DROP TABLE '${this.name}'`; + let self = this; + self.repair(); + + Utils.log(`drop: ${sql}`); + plus.sqlite.selectSql({ + name: config.name, + sql: sql, + success(e) { + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + return this; + } + + /** + * @description 创建数据表 **不推荐** + * @param {Function} callback + */ + create(callback) { + let self = this; + let sql = Utils.modelSql(self.name, self.options); + Utils.log(`create: ${sql}`); + plus.sqlite.executeSql({ + name: config.name, + sql: sql, + success(e) { + callback(null, e); + }, + fail(e) { + callback(e) + } + }); + return this; + } + + toString() { + return `[${this.name} Model]`; + } + + repair() { + let self = this; + self.isExist(function (e, r) { + if (e) { + console.error(e); + } + + if (!r[0].isExist) { + self.create(function (e, r) { + Utils.log(e, r); + }); + } + }); + } + // TODO 更新表结构 + // TODO 数据表备份?? + // TODO 多表联查 + // TODO 下班了其他的想不起来 回头再说 +} + + +// 单例模式 +export class usqlite { + /** + * 构造函数 + * @param {Object} options 数据库配置信息 * + * {name: 'demo', path: '_doc/demo.db'} + * - name 数据库名称* + * - path 数据库路径 + * @param {Function} callback + */ + constructor(options, callback) { + console.warn('No instantiation'); + } + /** + * @description 链接数据库 + * @param {Object} options 数据库配置信息 * + * {name: 'demo', path: '_doc/demo.db'} + * - name 数据库名称* + * - path 数据库路径 + * @param {Function} callback + */ + static connect(options, callback) { + config.name = options.name; // 数据库名称* + config.path = options.path; // 数据库名称* + + plus.sqlite.openDatabase({ + name: config.name, //数据库名称 + path: config.path, //数据库地址 + success(e) { + config.isConnect = true; + callback(null, e); + }, + fail(e) { + if (e.code == -1402) { + config.isConnect = true; + } + callback(e); + } + }); + } + /** + * @description 断开数据库 + * @param {*} callback + */ + static close(callback) { + plus.sqlite.closeDatabase({ + name: config.name, //数据库名称 + path: config.path, //数据库地址 + success(e) { + config.isConnect = false; + callback(null, e); + }, + fail(e) { + callback(e); + } + }); + } + /** + * @description 创建 Model 对象 + * @example + * usqlite.model('demo', + * { + * id: { + * type:Number + * }, + * content: String + * }) + * @param {String} name 数据表名称 * + * @param {String} options 参数配置 * + * @returns 返回 Model 对象 + */ + static model(name, options) { + Utils.log(config); + return new Model(name, options); + } +} diff --git a/uni_modules/onemue-USQLite/package.json b/uni_modules/onemue-USQLite/package.json new file mode 100644 index 0000000..5965fcd --- /dev/null +++ b/uni_modules/onemue-USQLite/package.json @@ -0,0 +1,80 @@ +{ + "id": "onemue-USQLite", + "displayName": "u-SQLite V2", + "version": "2.1.0", + "description": "基于ORM技术,使用对象的方式来操作sqlite数据库,而无需编写任何sql语句.", + "keywords": [ + "USQLite,数据库操作,缓存,大数据缓存,sqlite,sql,orm" +], + "repository": "https://github.com/onemue/u-sqlite", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "JS SDK", + "通用 SDK" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "sqlite" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "u" + }, + "App": { + "app-vue": "y", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "n", + "Android Browser": "n", + "微信浏览器(Android)": "n", + "QQ浏览器(Android)": "n" + }, + "H5-pc": { + "Chrome": "n", + "IE": "n", + "Edge": "n", + "Firefox": "n", + "Safari": "n" + }, + "小程序": { + "微信": "n", + "阿里": "n", + "百度": "n", + "字节跳动": "n", + "QQ": "n" + }, + "快应用": { + "华为": "n", + "联盟": "n" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/onemue-USQLite/readme.md b/uni_modules/onemue-USQLite/readme.md new file mode 100644 index 0000000..7e67594 --- /dev/null +++ b/uni_modules/onemue-USQLite/readme.md @@ -0,0 +1,287 @@ +

onemue-USQLite

+ +> u-SQLite 交流群:643867519 +> 如果觉的当前插件对你有帮助可以前往 [github](https://github.com/onemue/u-sqlite) 点 star! + +### 技术亮点 +1. 基于ORM技术,使用对象的方式来操作sqlite数据库,而无需编写任何sql语句 +2. 支持数据库的常规操作增删改查,API极为简洁,且高效智能。 +3. 支持条件查询 与 分页查询 +4. 支持原生sql语句,如果我们的框架无法满足您的需求,我们也提供了特殊的API可以直接使用sql语句来操作 +5. 支持链式语法 +### 使用方法 + +#### 挂载方法 +```js +// main.js +import { usqlite } from '@/uni_modules/onemue-USQLite/js_sdk/usqlite.js' +uni.$sql = usqlite; +``` +#### 链接数据库 +```js +//如果数据库存在则连接,不存在则会自动创建数据库 +uni.$sql.connect({ + name: 'local',// 数据库名称 + path:'_doc/local.db', // 路径 +}); +``` +#### 创建Model模型 +```js +//3.创建Model(表格模型:负责增删改查) +//如果table表格存在则连接,不存在则自动创建 +let studentModel = uni.$sql.model('student',{ + name:String, + age:{ + type: Number, + default: 18 + } +}); +``` +**约束** + +> 使用对象时,以约束模式处理,此时对象`type`为类型。 +> 使用一下内容,为约束。 +> `default`需要设置默认值,如:`{default: 0}`。 +> `check`需要设置条件,如:`{check:'age>18'}`。 + +- check CHECK 检查 +- primaryKey PRIMARY KEY 主键 +- unique UNIQUE 不重复 +- default DEFAULT 默认值 +- notNull NOT NULL 非空 + +**联合主键** + +> 在两列的约束同时设置`primaryKey`值为`true`时,可以创建联合主键。 + +> ~~如果没有主键,会自动添加主键`usql_id`。~~(已经移除) + +#### 调用 API 执行操作 +```js +//4.调用API:添加数据 +studentModel.insert({name:'张三10',age:30},(err,results)=>{ + console.log(err); + console.log(results); + if(!err) console.log('增加成功'); +}); +``` +### API 文档 + +#### 1.1 增加操作 +```js +studentModel.insert({name:'张三10',age:30},(err,results)=>{ + console.log(err); + console.log(results); + if(!err) console.log('增加成功'); +}); +``` +**批量增加** +```js +var arr = []; +for (var i = 1; i <= 10; i++) { + arr.push({ name: '张三', age: 30 }) +} + +studentModel.insert(arr, (err, results) => { + console.log(err); + console.log(results); + if (!err) console.log('增加成功'); +}); +``` +> v2.1.0 +> 感谢 `@风扬` +> 新增了事件选项(options, index),因为批量增加是遍历数组依次执行,所以callback回执行多次,可以使用第三,第四个(options, index)参数,判断是哪一个添加的数组出现了问题 +> 例如: +> ```js +> studentModel.insert(arr, (err, results, option, index) => { +> console.log(err); +> console.log(results); +> if (!err) console.log('增加成功'); +> console.log(`第${index}条数据出现问题,姓名是:${option.name}`) // index 从0开始 +> }); + +#### 1.2-查询操作 +**1-查询所有数据** +```js +//2.1 查询所有数据 +studentModel.find((err,results)=>{ + console.log(results); +}); +``` + +**2-查询数据库指定字段数据** +```js +//2.2 根据数据库字段查询部分数据 +// ['name'] : 将要查询的字段放入数组中 +studentModel.find(['name'],(err,results)=>{ + console.log(results); +}); +``` + +**3-条件查询** +```js +//2.3 根据条件查询数据 +// 'id=1' : 查询id为1的数据 (查询条件可以参考sql语句) +//例如 'age>10' : 查询age超过10的数据 +//例如 'name>"张三"' : 查询名字为张三的数据,注意字符串添加引号 +studentModel.find('id>21',(err,results)=>{ + console.log(results); +}); +``` + +**4-分页查询** +```js +//2.4 分页查询 +// 第一个参数options对象有三个属性 {where:分页查询条件(可选), number:页数 , count:每页数量} +studentModel.limit({where:'age>28',number:1,count:10},(err,results)=>{ + console.log(results); +}); +``` +#### 1.3-多表查询 +> Join 用于结合两个或多个数据库中表的记录。 +> 有三种链接形式: +> 交叉连接 - CROSS JOIN 连接的两个表所有数据行的笛卡尔积 +> 内连接 - INNER JOIN 只返回 左表在右表中有有匹配的行。 +> 外连接 - OUTER JOIN 返回左表所有的行,即使在右表中没有匹配的行 + +```js +studentModel.join( // 左表 + resultModel, // 右表 + { + where: 'grade<60', // 筛选条件 + type: 'inner', // 链接模式 + predicate: { // 谓语匹配词语 + left: 'id', // 左表 + right: 'id' // 右表 + } + }, + function(e, r){ + + }) +``` +#### 1.4-修改操作 +**1-修改所有数据** +```js +//3.1 将数据库中所有的name字段值:修改为李四 +studentModel.update({name:'李四'},(err,results)=>{ + console.log(results); +}); +``` + +**2-条件修改** +```js +//3.2 将数据库中 id = 1 的数据,age修改为30 +studentModel.update('id=1',{age:30},(err,results)=>{ + console.log(results); +}); + +//3.3 将数据库中所有 age < 20 的数据,name修改为王五 +studentModel.update('age<20',{name:'王五'},(err,results)=>{ + console.log(results); +}); +``` + +#### 1.5-删除操作 +```js +//4.1 删除所有 age>30 的数据 +studentModel.delete('age>20',(err,results)=>{ + console.log(results); +}); + +//4.2 清空表中所有数据 +studentModel.delete((err,results)=>{ + console.log(results); +}); +``` + +#### 1.6-执行自定义SQL语句 +```js +studentModel.sql('insert into student(name,age) values("andy",20)',(err,results)=>{ + console.log(results); +}); +``` + +#### 1.7-删除表格(慎用) +```js +studentModel.drop((err,results)=>{ + console.log(results); +}); +``` + +#### 1.8-创建表格(慎用) +```js +studentModel.create((err,results)=>{ + console.log(results); +}); +``` + +#### 1.9-数据库是否存在Model对应的数据表(慎用) +```js +studentModel.isExist((err,results)=>{ + console.log(results); +}); +``` + +#### 1.10-链式语法支持 +```js +studentModel.insert({name:'张三22',age:22},(err,results)=>{ + console.log(err); + console.log(results); +}) +.find('name="张三22"',(err,results)=>{ + console.log(err); + console.log(results); +}); +``` + +#### 1.11-表的相关操作 (慎用) +```js +// 8.1 重命名 +studentModel.alter('student_bak',(err,results)=>{ + console.log(err); + console.log(results); +}) +// 8.2 新增单列 +studentModel.alter({name:'id', option:Number},(err,results)=>{ + console.log(err); + console.log(results); +}) +// 8.3 新增多列 +studentModel.alter([ + {name:'id', option:Number}, // option 可以使用约束模式 + {name:'xx', option:Number}, + {name:'xxx', option:Number} +],(err,results)=>{ + console.log(err); + console.log(results); +}) + +``` +### JS类型转存SQLite时如何处理 +> 参考: +> [sqliet数据类型](https://www.runoob.com/sqlite/sqlite-data-types.html) +总结来说就是大部分都转化成了TEXT格式进行存储。 +```js +if (option[key] == Number) { + str += `'${key}' numeric,`; +} else if (option[key] == Date) { + str += `'${key}' timestamp,`; +} else { + str += `'${key}' varchar,`; +} +``` +**Number** +usqlite 会将`Number`数据类型转换`numeric`,但是sqlite会根据数据是否可逆,转化为`INTEGER`(带符号的整数)或者`REAL`(8 字节的 IEEE 浮点数). +**其他内容** +usqlite 会将其他数据类型转化`varchar`,sqlite会将其转化为`TEXT`。 +### Q&A +1. db 文件存放在什么位置? +> 答: 如果是`_doc`的话存放存放位置参考[H5+ Api - PRIVATE_DOC](https://www.html5plus.org/doc/zh_cn/io.html#plus.io.PRIVATE_DOC)。 +> 如果是其他路径,请参考[H5+ Api - SQLite](https://www.html5plus.org/doc/zh_cn/sqlite.html#openDatabase)。 + +2. 后续更新其他api会不会不兼容当然版本? +> 答: 在后续版本中,始终会兼容当前版本。 + +3. 为什么兼容性这么差,只兼容APP版本吗?后续会不会兼容其他版本? +> 答: 由于**H5+ plus API**限制,当前版本只支持APP,后续版本会兼容其他内容,但是兼容其他版本就不能使用Sqlite,而是使用其他`Storage`或者其他内容进行兼容处理部分api将不支持,特别是自定sql的api。 +> 并且这个这些功能会在后期在开发,可能要到年后或者什么时候,我近期开发Sqlite的App可视化插件。 diff --git a/utils/im/index.js b/utils/im/index.js index 2920eed..a1f1534 100644 --- a/utils/im/index.js +++ b/utils/im/index.js @@ -1,7 +1,8 @@ import * as RongIMLib from '@rongcloud/imlib-uni' import store from '@/store/index.js' import { - getFriends + getFriends, + getUserInfo } from '@/apis/interfaces/im.js' const initIm = (KEY) => { @@ -18,12 +19,12 @@ const setNotifyBadge = (count) => { if (code === 0) { if (count > 0) { uni.setTabBarBadge({ - index: 2, + index: 3, text: String(count > 99 ? '99+' : count) }) } else { uni.removeTabBarBadge({ - index: 2 + index: 3 }) } } @@ -43,10 +44,18 @@ const connect = (token, userInfo) => { store.dispatch('setSenderInfo', userInfo) setNotifyBadge() -} - -const disconnect = () => { - RongIMLib.disconnect() + + const model = uni.model.friendModel + + model.find((err, results) => { + results.map(item => { + store.dispatch('updateFriends', item) + }) + }) +} + +const disconnect = () => { + RongIMLib.disconnect() } const addListeners = () => { @@ -76,9 +85,19 @@ const newMessage = (msg) => { setNotifyBadge() + if (!store.getters.hasUser(msg.targetId)) { + syncUserInfo(msg.targetId) + } + store.dispatch('newMessage', msg) } +function syncUserInfo(targetId) { + getUserInfo(targetId).then(res => { + store.dispatch('updateFriends', res) + }) +} + // 播放状态 let tipState = false @@ -133,7 +152,10 @@ const sendMsg = (conversationType, targetId, content, callback) => { */ const syncFriends = () => { getFriends().then(res => { - store.dispatch('updateFriends', res) + res.map(item => { + console.log('item', item); + store.dispatch('updateFriends', item) + }) }) } @@ -142,5 +164,6 @@ export default { connect, sendMsg, setNotifyBadge, - syncFriends + syncFriends, + syncUserInfo } diff --git a/utils/im/models.js b/utils/im/models.js new file mode 100644 index 0000000..a36e1bd --- /dev/null +++ b/utils/im/models.js @@ -0,0 +1,22 @@ +import { + usqlite +} from '@/uni_modules/onemue-USQLite/js_sdk/usqlite.js' + +const friendModel = usqlite.model('friends', { + userId: { + type: String, + primaryKey: true, + unique: true + }, + name: String, + address: String, + hash: { + type: String, + unique: true + }, + portraitUrl: String +}) + +export default { + friendModel +} diff --git a/utils/im/sqlite.js b/utils/im/sqlite.js new file mode 100644 index 0000000..100cda2 --- /dev/null +++ b/utils/im/sqlite.js @@ -0,0 +1,44 @@ +const openSqlite = (callback) => { + plus.sqlite.openDatabase({ + name: 'friends', + path: '_doc/friends.db', + success: (res) => { + callback(res) + }, + fail: (err) => { + callback(err) + } + }) +} + +const executeSQL = (callback) => { + plus.sqlite.selectSql({ + name: 'friends', + sql: sql, + success: (res) => { + callback(res) + }, + fail: (err) => { + callback(err) + } + }) +} + +const closeSqlite = (callback) => { + plus.sqlite.closeDatabase({ + name: 'friends', + path: '_doc/friends.db', + success: (res) => { + callback(res) + }, + fail: (err) => { + callback(err) + } + }) +} + +export { + openSqlite, + executeSQL, + closeSqlite +} \ No newline at end of file