miao-plugin/components/models/UserModel.js
2022-03-26 16:21:44 +08:00

274 lines
6.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* UserModel Class
* 提供用户实例相关的操作方法
*
* * TODO将与具体用户操作相关的方法逐步迁移到UserModel中外部尽量只调用实例方法
* 以确保逻辑收敛且维护性更强
* */
import BaseModel from "./BaseModel.js"
import lodash from "lodash";
import md5 from "md5";
import { MysApi, Data } from "../index.js";
const _path = process.cwd();
const redisPrefix = "cache";
const userInstanceReclaimTime = 60;
let userMap = {};
// Redis相关操作方法
const Cache = {
prefix: "genshin",
async get(type, key) {
return await redis.get(`${Cache.prefix}:${type}:${key}`);
},
async set(type, key, val, exp = 2592000) {
return await redis.set(`${Cache.prefix}:${type}:${key}`, val, { EX: exp });
},
async del(type, key) {
return await redis.del(`${Cache.prefix}:${type}:${key}`);
}
};
const saveCookieFile = function () {
Data.writeJson("./data/NoteCookie/", "NoteCookie", NoteCookie);
};
// UserModel class
class UserModel extends BaseModel {
// 初始化用户
constructor(id) {
super();
// 一个id对应一个用户根据id检索用户信息
this.id = id;
// 检索是否存在NoteCookie信息
let data = NoteCookie[id];
if (data) {
this._data = data;
this.isPush = data.isPush;
this.isSignAuto = data.isSignAuto;
this.uid = data.uid;
} else {
this._data = {};
}
}
// 是绑定的cookie用户
// 需要存在NoteCookie记录且存在 cookie 与 uid 才认为是正确记录
get isBind() {
let dbData = NoteCookie[this.id];
return !!(dbData && dbData.cookie && dbData.uid);
}
// 是否是管理员
// TODO
get isMaster() {
return !this.isBot && BotConfig.masterQQ && BotConfig.masterQQ.includes(Number(this.id));
}
get isBot() {
// todo
return false;
}
// 获取当前用户cookie
get cookie() {
return this._data.cookie;
}
// 获取当前用户uid
get uid() {
return this._uid || this._data.uid || this._reg_uid;
}
set uid(uid) {
this._uid = uid;
this._reg_uid = uid;
}
// 保存用户信息
/*
async _save() {
// todo
return
let data = NoteCookie[this.id] || this._data || {};
// 将信息更新至 NoteCookie
data.id = this.id;
data.uid = this._uid || this._data.uid;
data.cookie = this._cookie || this._data.cookie;
data.isPush = this.isPush;
data.isAutoSign = !!this.isAutoSign;
// 保存信息
NoteCookie[this.id] = data;
this._data = data;
saveCookieFile();
// 建立当前用户相关缓存
await this.refreshCache();
return this;
}
*/
// 设置&更新用户缓存
async refreshCache() {
// 设置缓存
await Cache.set("id-uid", this.qq, this.uid);
await Cache.set("uid-id", this.uid, this.id);
Bot.logger.mark(`绑定用户QQ${this.id},UID${this.uid}`);
}
// 删除用户缓存
async delCache() {
await Cache.del("id-uid", this.id);
await Cache.del("uid-id", this.uid);
}
// 获取曾经查询过当前用户的人
async getSourceUser() {
let lastQuery = await Cache.get("id-source", this.id);
if (lastQuery) {
return UserModel.get(lastQuery);
}
return false;
}
// 设置曾经查询过当前用户的人缓存23小时
async setSourceUser(user) {
await Cache.set("id-source", this.id, user.id, 3600 * 23);
}
// 删除曾经查询过当前用户的人
async delSourceUser() {
await Cache.del("id-source", this.id);
}
/* 获取当前用户注册的uid
*
* 1. 如果是绑定用户优先返回当前绑定的uidcookie 对应uid
* 2. 返回redis中存储的uid
*
* 注redis uid需要主动调用一次 getRegUid 才能被this.uid访问到
*
* */
async getRegUid() {
if (this.isBind) {
return this.uid;
}
if (!this._reg_uid) {
let uid = await Cache.get('id-regUid', this.id);
if (uid) {
this._reg_uid = uid;
}
}
return this._reg_uid;
}
async setRegUid(uid) {
// 只有非绑定用户才设置 注册uid
if (!this.isBind) {
this._reg_uid = uid;
Cache.set('id-regUid', this.id, uid);
Cache.set('regUid-id', this.uid, this.id);
}
}
}
/* UserModel static function */
/*
* 获取用户实例
* query为获取条件默认为 id
*
* */
UserModel.get = async function (query, getDraftWhenNotFound = false) {
let user = await getUser(query, getDraftWhenNotFound);
user._reclaimFn && clearTimeout(user._reclaimFn);
user._reclaimFn = setTimeout(() => {
delete userMap[user.id];
}, userInstanceReclaimTime);
userMap[user.id] = user;
return user;
};
// 格式化查询
const formatQuery = function (query) {
if (typeof (query) === "string") {
return { id: query };
}
return query;
};
let getUser = async function (query, getDraftWhenNotFound = false) {
query = formatQuery(query);
let id = "";
// 根据id获取用户
if (query.id) {
id = query.id;
} else if (query.uid) {
// 根据uid检索id
id = await Cache.get("uid-id", query.uid);
if (!id) {
// 如未查找到则从注册uid中检索
id = await Cache.get("regUid-id", query.uid)
}
} else if (query.token) {
// 根据token检索id
// 不常用,仅用在机器人绑定环节
id = await Cache.get("token-id", query.token);
}
// 已有实例优先使用已有的
if (userMap[id]) {
return userMap[id];
}
// 如果是注册用户则返回新instance
if (NoteCookie[id]) {
return new UserModel(id);
}
// 如果允许返回Draft则生成并返回
if (getDraftWhenNotFound) {
return getDraft(query);
}
// 未查询到用户则返回false
return false;
}
let getDraft = function (query) {
let id = '';
if (query.id) {
id = query.id;
} else if (query.uid) {
id = '_UID_' + query.uid;
} else if (query.token) {
id = "_CK_" + md5(query.token);
}
let user = new UserModel(id);
user.id = query.id;
user.uid = query.uid;
user.cookie = query.cookie;
return user;
}
export default UserModel;