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 @@
-
-
-
-
-
-
-
-
-
- {{ item.content.content }}
-
-
- 未读
-
-
-
-
-
-
-
- {{ item.sentTime|timeCustomCN }}
-
-
-
-
-
+
+
+
+
+
+
+ {{ item.sentTime|timeCustomCN }}
+
+
+
+ {{ item.content.content }}
+
+
+ {{ item.sentStatus == 50 ? '已读': '未读'}}
+
+
+
+
+
+
+
+
+
diff --git a/pages/im/private/setting.vue b/pages/im/private/setting.vue
index 89d97db..4082d1d 100644
--- a/pages/im/private/setting.vue
+++ b/pages/im/private/setting.vue
@@ -3,7 +3,7 @@
会话设置 {{ targetId}}
免打扰开关 {{status}}
置顶会话 {{isTop}}
-
+
会首页
@@ -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