328 lines
8.2 KiB
TypeScript
328 lines
8.2 KiB
TypeScript
/**
|
||
* 模仿thinkingdata-node直接写一个log的写入,而日志直接用pinus-logger实现
|
||
*/
|
||
import { taLogger } from "../../util/logger";
|
||
|
||
const KEY_NAME_MATCH_REGEX = /^[a-zA-Z#][a-zA-Z0-9_]+$/;
|
||
|
||
let util: any = {};
|
||
util.version = '1.2.2';
|
||
util.log = function(message: string) {
|
||
console.log(message);
|
||
}
|
||
util.each = function (obj, iterator, context) {
|
||
if (obj === null) {
|
||
return;
|
||
}
|
||
if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) {
|
||
obj.forEach(iterator, context);
|
||
} else if (obj.length === +obj.length) {
|
||
for (let i = 0, l = obj.length; i < l; i++) {
|
||
// @ts-ignore
|
||
if (i in obj && iterator.call(context, obj[i], i, obj)) {
|
||
return;
|
||
}
|
||
}
|
||
} else {
|
||
for (let key in obj) {
|
||
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||
// @ts-ignore
|
||
if (iterator.call(context, obj[key], key, obj)) {
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
util.formatDate = function (d) {
|
||
function pad(n) {
|
||
return n < 10 ? '0' + n : n;
|
||
}
|
||
|
||
function padMilliseconds(n) {
|
||
if (n < 10) {
|
||
return '00' + n;
|
||
} else if (n < 100) {
|
||
return '0' + n;
|
||
} else {
|
||
return n;
|
||
}
|
||
}
|
||
return d.getFullYear() + '-' +
|
||
pad(d.getMonth() + 1) + '-' +
|
||
pad(d.getDate()) + ' ' +
|
||
pad(d.getHours()) + ':' +
|
||
pad(d.getMinutes()) + ':' +
|
||
pad(d.getSeconds()) + '.' +
|
||
padMilliseconds(d.getMilliseconds());
|
||
};
|
||
|
||
util.formatString = function (format) {
|
||
const args = Array.prototype.slice.call(arguments, 1);
|
||
return format.replace(/{(\d+)}/g, function (match, number) {
|
||
return typeof args[number] !== 'undefined'
|
||
? args[number]
|
||
: match
|
||
;
|
||
});
|
||
};
|
||
util.isArray = Array.isArray;
|
||
util.isObject = function (obj) {
|
||
return obj === Object(obj) && !util.isArray(obj) && typeof obj === 'object';
|
||
};
|
||
util.encodeURIComponent = function (str) {
|
||
return encodeURIComponent(str);
|
||
}
|
||
util.trim = function (str) {
|
||
return str.replace(/^\s+|\s+$/g, '');
|
||
}
|
||
util.toArray = function (iterable) {
|
||
if (!iterable) {
|
||
return [];
|
||
}
|
||
if (iterable.toArray) {
|
||
return iterable.toArray();
|
||
}
|
||
return [].slice.call(iterable);
|
||
}
|
||
util.each(['Function', 'String', 'Object', 'Number', 'Boolean', 'Date', 'RegExp', 'Error'], function (name) {
|
||
util['is' + name] = function (obj) {
|
||
return Object.prototype.toString.call(obj) === '[object ' + name + ']';
|
||
};
|
||
});
|
||
util.getProperty = function (obj, key) {
|
||
return obj == null ? undefined : obj[key];
|
||
};
|
||
util.setProperty = function (obj, key, value) {
|
||
obj[key] = value;
|
||
};
|
||
util.hasProperty = function (obj, key) {
|
||
return obj != null && typeof obj === 'object' && key in obj;
|
||
};
|
||
util.createLog = function (category) {
|
||
const log = function () {
|
||
};
|
||
log.debug = function () {
|
||
};
|
||
log.info = function () {
|
||
};
|
||
log.warn = function () {
|
||
};
|
||
log.error = function () {
|
||
};
|
||
return log;
|
||
};
|
||
const TABLE_NAME = "app_gold_record";
|
||
|
||
const EXTRA_CODE = {
|
||
"#": "_j_",
|
||
"ing": "_deng_",
|
||
"&": "_he_",
|
||
};
|
||
|
||
function encodeKey(key) {
|
||
let result = "";
|
||
for (let i = 0; i < key.length; i++) {
|
||
const c = key.charAt(i);
|
||
result += EXTRA_CODE[c] || c;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
function decodeKey(key) {
|
||
let result = "";
|
||
let i = 0;
|
||
while (i < key.length) {
|
||
const c = key.charAt(i);
|
||
if (c === '_' && i + 2 < key.length) {
|
||
const nextTwo = key.substring(i + 1, i + 3);
|
||
let found = false;
|
||
for (const [encoded, decoded] of Object.entries(EXTRA_CODE)) {
|
||
if (nextTwo === encoded.substring(1)) {
|
||
result += decoded;
|
||
i += 3;
|
||
found = true;
|
||
break;
|
||
}
|
||
}
|
||
if (!found) {
|
||
result += c;
|
||
i++;
|
||
}
|
||
} else {
|
||
result += c;
|
||
i++;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
function encode(data) {
|
||
const str = JSON.stringify(data);
|
||
return new Buffer(str).toString("base64");
|
||
}
|
||
|
||
function decode(str) {
|
||
return JSON.parse(new Buffer(str, "base64").toString());
|
||
}
|
||
|
||
function encodeId(id) {
|
||
return encodeKey(encode({
|
||
"appid": 1,
|
||
"id": id,
|
||
}));
|
||
}
|
||
|
||
function decodeId(id) {
|
||
const decoded = decode(decodeKey(id));
|
||
return decoded["id"];
|
||
}
|
||
|
||
function encodeData(data) {
|
||
return encode({
|
||
"data": data,
|
||
"time": Date.now(),
|
||
});
|
||
}
|
||
|
||
function decodeData(data) {
|
||
const decoded = decode(data);
|
||
return decoded["data"];
|
||
}
|
||
|
||
let instance = null;
|
||
|
||
export class TA {
|
||
private appId: string;
|
||
private worker: any;
|
||
private receiver: any;
|
||
|
||
constructor(appId: string, token: string) {
|
||
this.appId = appId;
|
||
this.worker = null;
|
||
this.receiver = null;
|
||
}
|
||
|
||
userSet(userId: string, properties: any) {
|
||
const data = {
|
||
"#type": "user_set",
|
||
"#time": util.formatDate(new Date()),
|
||
"#account_id": userId,
|
||
};
|
||
util.each(properties, function (val, key) {
|
||
data[key] = val;
|
||
});
|
||
this.upload(data);
|
||
}
|
||
|
||
userSetOnce(userId: string, properties: any) {
|
||
const data = {
|
||
"#type": "user_setOnce",
|
||
"#time": util.formatDate(new Date()),
|
||
"#account_id": userId,
|
||
};
|
||
util.each(properties, function (val, key) {
|
||
data[key] = val;
|
||
});
|
||
this.upload(data);
|
||
}
|
||
|
||
userAdd(userId: string, properties: any) {
|
||
const data = {
|
||
"#type": "user_add",
|
||
"#time": util.formatDate(new Date()),
|
||
"#account_id": userId,
|
||
};
|
||
util.each(properties, function (val, key) {
|
||
data[key] = val;
|
||
});
|
||
this.upload(data);
|
||
}
|
||
|
||
userUnset(userId: string, keys: string[]) {
|
||
const data: any = {
|
||
"#type": "user_unset",
|
||
"#time": util.formatDate(new Date()),
|
||
"#account_id": userId,
|
||
};
|
||
for (let i = 0; i < keys.length; i++) {
|
||
data[keys[i]] = 0;
|
||
}
|
||
this.upload(data);
|
||
}
|
||
|
||
userDelete(userId: string) {
|
||
const data = {
|
||
"#type": "user_del",
|
||
"#time": util.formatDate(new Date()),
|
||
"#account_id": userId,
|
||
};
|
||
this.upload(data);
|
||
}
|
||
|
||
track(userId: string, eventName: string, properties: any) {
|
||
const data = {
|
||
"#type": "track",
|
||
"#time": util.formatDate(new Date()),
|
||
"#account_id": userId,
|
||
"#event_name": eventName,
|
||
};
|
||
util.each(properties, function (val, key) {
|
||
if (!KEY_NAME_MATCH_REGEX.test(key)) {
|
||
return;
|
||
}
|
||
data[key] = val;
|
||
});
|
||
this.upload(data);
|
||
}
|
||
|
||
upload(data) {
|
||
if (!instance) {
|
||
taLogger.info("ta data:", JSON.stringify(data));
|
||
} else {
|
||
taLogger.info("ta data:", JSON.stringify(data));
|
||
}
|
||
}
|
||
}
|
||
|
||
let ta: TA = null;
|
||
let initCount = 0;
|
||
|
||
export function initTa(appId: string, token: string) {
|
||
initCount++;
|
||
if (ta == null || initCount <= 1) {
|
||
ta = new TA(appId, token);
|
||
}
|
||
return ta;
|
||
}
|
||
|
||
export function getTa() {
|
||
if (!ta) {
|
||
console.error("ta未初始化");
|
||
return null;
|
||
}
|
||
return ta;
|
||
}
|
||
|
||
export function reportTAEvent(uid: string, event: string, data: any) {
|
||
const ta = getTa();
|
||
if (ta) {
|
||
ta.track(uid, event, data);
|
||
}
|
||
}
|
||
|
||
export function reportTAUserSet(uid: string, data: any) {
|
||
const ta = getTa();
|
||
if (ta) {
|
||
ta.userSet(uid, data);
|
||
}
|
||
}
|
||
|
||
export function initTaLoggingMode(isInit: boolean) {
|
||
if (isInit) {
|
||
if (!instance) {
|
||
instance = new TA("AABBCC", "");
|
||
}
|
||
}
|
||
}
|