Commit 2c7f3f8f authored by 刘松's avatar 刘松

v2

parent b0cb1a7a
...@@ -15,7 +15,13 @@ RUN npm i --only=production --registry https://registry.npm.taobao.org ...@@ -15,7 +15,13 @@ RUN npm i --only=production --registry https://registry.npm.taobao.org
ENV SERVICE_PORT=6662 ENV SERVICE_PORT=6662
ENV PROJECT_LEVEL=production ENV PROJECT_LEVEL=production
ENV MONGO='mongodb://mongo-adpro-ssp-v2-rs-1.localhost:1301/remarketing?replicaSet=adpro_ssp_v2_rs' ENV MONGO='mongodb://mongo-adpro-ssp-v2-rs-2.localhost:1301/remarketing?replicaSet=adpro_ssp_v2_rs'
ENV MONGO_OEM='mongodb://bjwjh:OhzFH7t7Qn0T@mongo-bjwjh-rs-1.localhost:1302,mongo-bjwjh-rs-2.localhost:1302,mongo-bjwjh-rs-3.localhost:1302/'
ENV MONGO_DB_MTTY='oem_mtty_remarketing'
ENV MONGO_DB_XIBAO='oem_xibao_remarketing'
ENV NODE_ENV='production' ENV NODE_ENV='production'
EXPOSE 6662 EXPOSE 6662
CMD node server.js CMD node server.js
const mongodb = require("mongodb");
const MongoClient = mongodb.MongoClient;
let db = {};
let oem_db = { mtty:{}, xibao:{} };
const dbpath = process.env.MONGO || "mongodb://127.0.0.1:27017/remarketing";
const oem_dbpath = ( process.env.MONGO_OEM + process.env.MONGO_DB_MTTY || "mongodb://127.0.0.1:27017/remarketing" ) + (process.env.MONGO_OEM ? "?replicaSet=bjwjh-rs&authSource=admin" : '');
//const xibao_dbpath = process.env.MONGO_OEM +process.env.MONGO_DB_XIBAO + "?replicaSet=bjwjh-rs&authSource=admin";
const salt = ",tom";
const EXPIRATION = 60 * 30;
// TODO ! put into init
/*console.dir(dbpath);
console.dir(oem_dbpath);*/
/*MongoClient.connect(dbpath, (err, conn) => {
if (err) return console.log(err);
console.log("#### DB CONNECTED");
db = conn.db("remarketing");
db
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
});*/
/*MongoClient.connect(oem_dbpath, (err, conn) => {
if (err) return console.log(err);
console.log("#### OEM DB CONNECTED");
oem_db.mtty = conn.db(process.env.MONGO_DB_MTTY);
oem_db.xibao = conn.db(process.env.MONGO_DB_XIBAO);
oem_db.mtty
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
oem_db.xibao
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
});*/
module.exports = {
getDb: async () => {
const conn = await MongoClient.connect(dbpath);
db = conn.db("remarketing");
console.log("#### DB CONNECTED");
db
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
return db;
},
getOemDb: async () => {
const conn = await MongoClient.connect(oem_dbpath);
oem_db.mtty = conn.db(process.env.MONGO_DB_MTTY);
oem_db.xibao = conn.db(process.env.MONGO_DB_XIBAO);
return oem_db;
}
};
const router = require("express").Router();
const mongodb = require("mongodb");
const MongoClient = mongodb.MongoClient;
const crypto = require("crypto");
const axios = require("axios");
const _ = require("lodash");
const moment = require('moment');
const adminID = process.env.NODE_ENV === 'production' ? '5a9f9e6b46da1176a40e1082' : '5ab083b1f6134d82b40d95f2';
let db = {};
let oem_db = { mtty:{}, xibao:{} };
const dbpath = process.env.MONGO || "mongodb://127.0.0.1:27017/remarketing";
const oem_dbpath = process.env.MONGO_OEM + process.env.MONGO_DB_MTTY + "?replicaSet=bjwjh-rs&authSource=admin";
//const xibao_dbpath = process.env.MONGO_OEM +process.env.MONGO_DB_XIBAO + "?replicaSet=bjwjh-rs&authSource=admin";
const salt = ",tom";
const EXPIRATION = 60 * 30;
// TODO ! put into init
MongoClient.connect(dbpath, (err, conn) => {
if (err) return console.log(err);
console.log("#### DB CONNECTED");
db = conn.db("remarketing");
db
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
});
MongoClient.connect(oem_dbpath, (err, conn) => {
if (err) return console.log(err);
console.log("#### OEM DB CONNECTED");
oem_db.mtty = conn.db(process.env.MONGO_DB_MTTY);
oem_db.xibao = conn.db(process.env.MONGO_DB_XIBAO);
oem_db.mtty
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
oem_db.xibao
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
});
router.post('/remark',function (req,res) {
const { recog, remark, unikey, sessionID } = req.body;
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
let doc = { recog, remark, unikey };
if(doc.recog) delete doc.unikey;
if(doc.unikey) delete doc.recog;
const host = getHost(rep) + "/remark";
axios(host, {
method: "POST",
headers: { "Content-Type": "application/json" },
data: doc,
timeout: 300000
})
.then(async rep => {
res.send({ status:'ok', data: rep.data });
})
.catch(err => {
console.dir(err);
if (err) return res.status(500).json({ error: '服务出错'});
});
}});
});
router.post('/job/call',function (req,res) {
const { pubID, slotID, phone, expiration = EXPIRATION, unikey, sessionID } = req.body;
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
console.dir(err);
console.dir(rep);
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
let _host = getHost(rep);
getCallConsumeByUnikey(unikey, db, (err, data) => {
if(err) return res.status(500).json({ error: err});
if(data && data.number) {
checkBill({ accountID: pubID, number: data.number }, db, async (_err) => {
if(_err) {
return res.status(500).json({ error: _err});
} else {
if(!notEmpty(req.body)) res.status(500).json({ error: "参数错误"});
else {
const fromID = await getFromID(pubID,db);
const host = _host + "/bind/" + (pubID + "_" + fromID) + '/' + slotID + '?caller=' + phone + '&unikey=' + unikey + '&expiration=' + expiration;
axios(host, {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(async rep => {
if(rep.data && rep.data.called && rep.data._id && rep.data.bindID){
//const fromID = await getFromID(pubID);
updateBill({pre: true, number: data.number, accountID: pubID, fromID, type: 'call', taskID: rep.data._id}, db, (err,_rep) => {
if(err) {
// log 代码;
}
res.send({ status: 'ok', called: rep.data.called, bindID: rep.data.bindID });
});
}
else{
res.status(500).json({ error: '取号失败'});
}
})
.catch(err => {
console.dir(err)
if (err) return res.status(500).json({ error: '运营商拒绝服务'});
});
}
}
});
} else {
res.status(500);
}
});
}});
});
router.post('/job/dspcall',function (req,res) {
const { pubID, groupID, phone, expiration = EXPIRATION, unikey } = req.body;
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
let _host = getHost(rep);
getCallConsumeByUnikey(unikey, db, (err, data) => {
if(err) return res.status(500).json({ error: err});
if(data && data.number) {
checkBill({ accountID: pubID, number: data.number },db, async (_err) => {
if(_err) {
return res.status(500).json({ error: _err});
} else {
if(!notEmpty(req.body)) res.status(500).json({ error: "参数错误"});
else {
const fromID = await getFromID(pubID,db);
const host = _host + "/dspBind/" + (pubID + "_" + fromID) + '/' + groupID + '?caller=' + phone + '&unikey=' + unikey + '&expiration=' + expiration;
axios(host, {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(async rep => {
if(rep.data && rep.data.called && rep.data._id && rep.data.bindID){
//const fromID = await getFromID(pubID);
updateBill({pre: true, number: data.number, accountID: pubID, fromID, type: 'dspcall', groupID,taskID: rep.data._id }, db, (err,_rep) => {
if(err) {
// log 代码;
}
res.send({ status: 'ok', called: rep.data.called, bindID: rep.data.bindID });
});
}
else{
res.status(500).json({ error: '取号失败'});
}
})
.catch(err => {
console.dir(err)
if (err) return res.status(500).json({ error: '运营商拒绝服务'});
});
}
}
});
} else {
res.status(500);
}
});
}
});
});
router.get('/unbind',function (req,res) {
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let _host = getHost(rep);
const { bindID } = req.query;
const host = _host + "/unbind?bindID=" + bindID;
axios(host, {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(rep => {
res.send({status:'ok'});
})
.catch(err => {
console.dir(err);
if (err) return res.status(500).json({ error: '解绑错误'});
});
}
})
});
router.get('/dspUnbind',function (req,res) {
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let _host = getHost(rep);
const { bindID } = req.query;
const host = _host + "/dspUnbind?bindID=" + bindID;
axios(host, {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(rep => {
res.send({status:'ok'});
})
.catch(err => {
if (err) return res.status(500).json({ error: '解绑错误'});
});
}
});
});
router.post('/login',async function (req,res) {
//token phone sessionID
checkSession(req.body, (err, rep) => {
if (err) return res.status(500).json({ error: "查询失败" });
if (!rep) {
//没有符合的session
return authorize(req.body, (err, rep) => {
console.dir(err);
if (err) return res.status(500).json({ error: "查询账户失败" });
if (!rep) return res.status(403).json({ error: "账户不存在" });
//验证通过
const token = _.merge(rep, { sessionID: genSessionID(rep._id, rep.db) });
delete token.token;
res.send({ status: "ok", token });
});
} else {
let db = getDB(rep);
db
.collection("tokens")
.findOne({ _id: OID(rep.tokenID) }, (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "查询账户失败"});
const token = _.merge(rep, { sessionID: req.body.sessionID });
delete token.token;
delete token.passwd;
res.send({ status: "ok", token });
});
}
});
});
router.post("/logout",function(req,res) {
let { sessionID } = req.body;
db
.collection('tokenSession')
.remove({ _id: OID(sessionID) }, (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "更新session新失败"});
res.send({ status: "ok", rep });
});
});
router.get("/recognitions",function(req,res) {
let { sessionID, limit = 10, skip = 0, date = null, start, end, called = 'false' } = req.query;
checkSession(req.query, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
const tokenID = rep.tokenID;
if(date) {
start = (end = date);
}
let sort = {};
let qs = getTimeRange({start, end, key:'updateTimestamp', type: 'millisecond'});
//let qs = { updateTimestamp: { '$gt': parseInt(moment(date, 'YYYYMMDD').startOf('day').format('x')), '$lte': parseInt(moment(date, 'YYYYMMDD').endOf('day').format('x')) }, 'tokenInfo.tokenID': OID(tokenID) };
_.merge(qs, { calledInfo: { $exists: called == 'true' } , 'tokenInfo.tokenID': OID(tokenID) , auditStatus: 2 } );
if(called == 'true') sort.calledTimestamp = -1;
else sort.updateTimestamp = -1;
console.dir(qs);
const count = await db.collection('recognition').count(qs);
db
.collection('recognition')
.find(qs)
.sort(sort)
.skip(parseInt(skip * limit))
.limit(parseInt(limit))
.toArray(async (err, rep) => {
if (err) return res.status(500).json({ error: "数据查询失败" });
//const arrs = await getStars(rep);
let _arrs = await getSlots(rep,db);
_arrs = _arrs.map( x => {
x.score = { score: x.score || 0 };
return x;
});
if(called == 'true') _arrs = await getTasks(_arrs,db);
res.send({ status: "ok", recognitions: _arrs, page: { skip: skip, total: count } })
});
}
});
});
router.get("/dsprecognitions",function(req,res) {
let { sessionID, limit = 10, skip = 0, date = null, start, end, called = 'false' } = req.query;
checkSession(req.query, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
const tokenID = rep.tokenID;
if(date) {
start = (end = date);
}
let sort = {};
let qs = getTimeRange({start, end, key:'createdAt', type: 'millisecond'});
//let qs = { updateTimestamp: { '$gt': parseInt(moment(date, 'YYYYMMDD').startOf('day').format('x')), '$lte': parseInt(moment(date, 'YYYYMMDD').endOf('day').format('x')) }, 'tokenInfo.tokenID': OID(tokenID) };
_.merge(qs, { calledInfo: { $exists: called == 'true' } , 'tokenInfo.tokenID': OID(tokenID) } );
if(called == 'true') sort.calledTimestamp = -1;
else sort.createdAt = -1;
const count = await db.collection('dspRecognition').count(qs);
db
.collection('dspRecognition')
.find(qs,{ tags:0 })
.sort(sort)
.skip(parseInt(skip * limit))
.limit(parseInt(limit))
.toArray(async (err, rep) => {
if (err) return res.status(500).json({ error: "数据查询失败" });
let _arrs = await getCallGroupInfo(rep, db);
res.send({ status: "ok", recognitions: _arrs, page: { skip: skip, total: count } })
});
}
});
});
async function getCallGroupInfo(arrays,_db) {
let tasks = [];
arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => {
const GroupInfo = (x.groupID && exists(x.groupID)) ? await _db
.collection("dspCallGroups")
.findOne({ _id: OID(x.groupID) },{dspgroup: 1}) : { dspgroup: '' };
r(_.merge(x, { dspgroup: (GroupInfo ? GroupInfo.dspgroup : '') } ));
}));
});
const arrs = await Promise.all(tasks);
return arrs;
}
async function getStars(arrays) {
let tasks = [];
arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => {
const score = x.slotID && x.pubID && x.unikey ? await db
.collection("score")
.findOne({ slotID: x.slotID , pubID: x.pubID, unikey: x.unikey },{ score: 1 }) : { score: -1 };
r(_.merge(x,{ score: (score ? score : { score: -1 }) }));
}));
});
const arrs = await Promise.all(tasks);
return arrs;
}
async function getSlots(arrays,_db) {
let tasks = [];
arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => {
const slot = x['slotID'] ? await _db
.collection("slotTemps")
.findOne({ _id: OID(x.slotID), accountID: OID(x.pubID) },{ slotName: 1 }) : { slotName: '未知' };
r(_.merge(x,{ slot: (slot ? slot : { slotName: '未知' }) }));
}));
});
const arrs = await Promise.all(tasks);
return arrs;
}
function md5token(str) {
const salt = ",tom";
const hash = crypto
.createHash("md5")
.update(str + salt)
.digest()
.toString("hex");
return hash;
}
function checkSession(data, callback) {
if (!data.sessionID || !/^[0-9a-z]{24}$/.test(data.sessionID)) return callback(null);
db
.collection("tokenSession")
.findOne({ sessionID: OID(data.sessionID) }, (err, rep) => {
if (err || !rep) return callback(err, null);
callback(null, rep);
});
}
function exsists(ID) {
return ID !== undefined && ID !== null && ID !== 'all' && ID !== 'undefined';
}
function notEmpty(data) {
let temp = true;
Object.keys(data).forEach((key) => {
temp = temp && data[key] && exsists(data[key]);
})
return temp;
}
async function authorize(data, callback) {
let token = md5token(data.token);
try {
let self_user = await db.collection("tokens").findOne({ phone: data.phone });
let mtty_user = await oem_db.mtty.collection("tokens").findOne({ phone: data.phone });
let xibao_user = await oem_db.xibao.collection("tokens").findOne({ phone: data.phone });
if (self_user && self_user.passwd == token) {
return callback(null, _.merge(self_user, {db: 'self'}));
}
if ( mtty_user && mtty_user.passwd == token) {
return callback(null, _.merge(mtty_user, {db: 'mtty'}));
}
if ( xibao_user && xibao_user.passwd == token) {
return callback(null, _.merge(xibao_user, {db: 'xibao'}));
} else {
return callback(null, null);
}
} catch (err) {
return callback(err, null);
}
/* db.collection("tokens").findOne({ phone: data.phone }, (err, rep) => {
if (err || !rep) return callback(err, null);
if (md5token(data.token) !== rep.passwd)
return callback("password wrong", null);
callback(null, rep);
});*/
}
function genSessionID(tokenID,_db) {
const sessionID = mongodb.ObjectID();
db.collection("tokenSession").insert(
{
createdAt: new Date(),
sessionID,
tokenID,
db:_db || 'self'
},
(err, rep) => {
if (err) console.log(err);
}
);
return sessionID;
}
async function checkBill(data, _db, callback) {
if(!notEmpty(data)) return callback('参数错误');
let { number, accountID } = data;
if(!/^[0-9a-z]{24}$/.test(accountID) ) return callback('参数错误');
let recharge = await getRechargeByAccount( accountID, _db );
if( recharge <= 0 ) { return callback('余额不足') }
let consume = await getBillByAccount( accountID , _db);
if( consume + number > recharge ) { return callback('余额不足') }
callback && callback();
}
/*async function updateBill(data, callback) {
if(!notEmpty(data)) return callback('params wrong');
let { pre, number, accountID, type, taskID } = data;
if(!/^[0-9a-z]{24}$/.test(accountID) ) return callback('参数错误');
db
.collection('bills')
.insert(wrapTime({ pre, number, accountID: OID(accountID), type, taskID: OID(taskID) },true), (err, rep) => {
if (err) return callback(err);
callback && callback(null, rep);
});
}*/
async function updateBill(data, _db, callback) {
if(!notEmpty(data)) return callback('params wrong');
let { pre, number, accountID, type, taskID, fromID = 'self', groupID, preNum = 30 } = data;
if(!/^[0-9a-z]{24}$/.test(accountID) ) return callback('params wrong');
let _data = { pre, number, accountID: OID(accountID), fromID, type };
if(groupID) {
_data.groupID = OID(groupID);
}
_data.taskID = OID(taskID);
_db
.collection('bills')
.insert(wrapTime(_data,true), (err, rep) => {
if (err) return callback(err);
callback && callback(null, rep);
});
}
async function getBillByAccount( accountID, _db ) {
let consumes = await _db
.collection('bills')
.aggregate([
{
$match:{
"accountID": OID(accountID),
"removed": { $ne: true }
/* "createdAt": { '$gt': start, '$lte': end }*/
}
},
{
$group:{
_id: null,
sum: {$sum:"$number"}
}
}]).toArray();
return ( (consumes && consumes.length) ? consumes[0].sum : 0 );
}
async function getRechargeByAccount(accountID, _db) {
let recharges = await _db
.collection('recharge')
.aggregate([
{
$match:{
"accountID": OID(accountID),
"removed": { $ne: true }
}
},
{
$group:{
_id:null,
sum:{$sum:"$number"}
}
}]).toArray();
return ( (recharges && recharges.length) ? recharges[0].sum : 0 );
}
async function getCallConsumeByUnikey(unikey,_db,callback) {
const price = _db.collection('price').findOne({type: 'call'});
let number = (price && price.number) ? price.number : 1;
//const task = db.collection('callTask').findOne({ unikey });
callback(null, { number: Math.ceil((EXPIRATION / 60) ) * number });
}
async function getTasks(arrays,_db) {
let _tasks = [];
arrays.forEach((x) => {
_tasks.push(new Promise(async (r,e) => {
if(x.calledInfo && x.calledInfo.length) {
let tasks = [];
x.calledInfo.forEach((y) => {
tasks.push(new Promise(async (r,e) => {
const TaskInfo = (y.taskID && exsists(y.taskID)) ? await _db
.collection("callTask")
.findOne({ _id: OID(y.taskID) },{ startTime : 1 }) : { startTime: -1 };
r(_.merge( y, { TaskInfo } ));
}));
});
const arrs = await Promise.all(tasks);
x.calledInfo = arrs;
}
r(x);
}));
});
const _arr = await Promise.all(_tasks);
return _arr;
}
function OID(str) {
return typeof str === 'string' ? mongodb.ObjectID(str) : str;
}
function wrapTime(obj, date) {
let d = { createdAt: new Date() };
if(date) {
d.date = moment().format('YYYYMMDD');
}
return _.merge(obj,d )
}
function getDB(session) {
if(session.db == 'mtty') return oem_db.mtty;
if(session.db == 'xibao') return oem_db.xibao;
else return db;
}
function getHost(session) {
if(session.db == 'mtty') return 'http://remarkering-mtty-yh.yoo.yunpro.cn';
if(session.db == 'xibao') return 'http://remarketing-xibao-yh.yoo.yunpro.cn';
else return 'http://remarketing-job-yh.yoo.yunpro.cn';
}
async function getFromID(accountID,_db) {
const account = await _db.collection('account').findOne({ _id: OID(accountID) });
return (account && account.fromID ? account.fromID : 'self');
}
function getTimeRange({ start, end, type, key}) {
if(/^[0-9]{8}$/.test(start) && /^[0-9]{8}$/.test(end) ) {
if(type === 'millisecond') {
return { [ key ]: { '$gt': parseInt(moment(start,'YYYYMMDD').startOf('day').format('x')), '$lte': parseInt(moment(end,'YYYYMMDD').endOf('day').format('x')) } };
} else {
return { [ key ]: { '$gt': moment(start,'YYYYMMDD').startOf('day').toDate(), '$lte': moment(end,'YYYYMMDD').endOf('day').toDate() } };
}
} else {
if(type === 'millisecond') {
return { [ key ]: { '$gt': parseInt(moment().add(-7,'days').startOf('day').format('x')), '$lte': parseInt(moment().endOf('day').format('x')) } };
} else {
return { [ key ]: { '$gt': moment().add(-7,'days').startOf('day').toDate(), '$lte': moment().endOf('day').toDate() } };
}
}
}
function exists(ID) {
return ID !== undefined && ID !== null && ID !== 'null' && ID !== '' && ID !== 'all' && ID !== 'undefined';
}
module.exports = router;
...@@ -8,7 +8,13 @@ const moment = require('moment'); ...@@ -8,7 +8,13 @@ const moment = require('moment');
const adminID = process.env.NODE_ENV === 'production' ? '5a9f9e6b46da1176a40e1082' : '5ab083b1f6134d82b40d95f2'; const adminID = process.env.NODE_ENV === 'production' ? '5a9f9e6b46da1176a40e1082' : '5ab083b1f6134d82b40d95f2';
let db = {}; let db = {};
let oem_db = { mtty:{}, xibao:{} };
const dbpath = process.env.MONGO || "mongodb://127.0.0.1:27017/remarketing"; const dbpath = process.env.MONGO || "mongodb://127.0.0.1:27017/remarketing";
const oem_dbpath = ( process.env.MONGO_OEM + process.env.MONGO_DB_MTTY || "mongodb://127.0.0.1:27017/remarketing" ) + (process.env.MONGO_OEM ? "?replicaSet=bjwjh-rs&authSource=admin" : '');
//const xibao_dbpath = process.env.MONGO_OEM +process.env.MONGO_DB_XIBAO + "?replicaSet=bjwjh-rs&authSource=admin";
const salt = ",tom"; const salt = ",tom";
const EXPIRATION = 60 * 30; const EXPIRATION = 60 * 30;
// TODO ! put into init // TODO ! put into init
...@@ -21,170 +27,230 @@ MongoClient.connect(dbpath, (err, conn) => { ...@@ -21,170 +27,230 @@ MongoClient.connect(dbpath, (err, conn) => {
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 }); .createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
}); });
MongoClient.connect(oem_dbpath, (err, conn) => {
if (err) return console.log(err);
console.log("#### OEM DB CONNECTED");
oem_db.mtty = conn.db(process.env.MONGO_DB_MTTY);
oem_db.xibao = conn.db(process.env.MONGO_DB_XIBAO);
oem_db.mtty
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
oem_db.xibao
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
});
router.post('/remark',function (req,res) { router.post('/remark',function (req,res) {
const { recog, remark, unikey } = req.body; const { recog, remark, unikey, sessionID } = req.body;
let doc = { recog, remark, unikey }; let data = _.merge(req.query,req.body);
if(doc.recog) delete doc.unikey; checkSession(data, async (err, rep) => {
if(doc.unikey) delete doc.recog; if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
const host = "http://remarketing-job-yh.yoo.yunpro.cn/remark"; else {
axios(host, { let db = getDB(rep);
method: "POST", let doc = { recog, remark, unikey };
headers: { "Content-Type": "application/json" }, if(doc.recog) delete doc.unikey;
data: doc, if(doc.unikey) delete doc.recog;
timeout: 300000 const host = getHost(rep) + "/remark";
}) axios(host, {
.then(async rep => { method: "POST",
res.send({ status:'ok', data: rep.data }); headers: { "Content-Type": "application/json" },
}) data: doc,
.catch(err => { timeout: 300000
console.dir(err); })
if (err) return res.status(500).json({ error: '服务出错'}); .then(async rep => {
}); res.send({ status:'ok', data: rep.data });
})
.catch(err => {
console.dir(err);
if (err) return res.status(500).json({ error: '服务出错'});
});
}});
}); });
router.post('/job/call',function (req,res) { router.post('/job/call',function (req,res) {
const { pubID, slotID, phone, expiration = EXPIRATION, unikey } = req.body; const { pubID, slotID, phone, expiration = EXPIRATION, unikey, sessionID } = req.body;
getCallConsumeByUnikey(unikey, (err, data) => { let data = _.merge(req.query,req.body);
if(err) return res.status(500).json({ error: err}); checkSession(data, async (err, rep) => {
if(data && data.number) { console.dir(err);
checkBill({ accountID: pubID, number: data.number },async (_err) => { console.dir(rep);
if(_err) { if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
return res.status(500).json({ error: _err}); else {
} else { let db = getDB(rep);
if(!notEmpty(req.body)) res.status(500).json({ error: "参数错误"}); let _host = getHost(rep);
else { getCallConsumeByUnikey(unikey, db, (err, data) => {
const fromID = await getFromID(pubID); if(err) return res.status(500).json({ error: err});
const host = "http://remarketing-job-yh.yoo.yunpro.cn/bind/" + (pubID + "_" + fromID) + '/' + slotID + '?caller=' + phone + '&unikey=' + unikey + '&expiration=' + expiration; if(data && data.number) {
axios(host, { checkBill({ accountID: pubID, number: data.number }, db, async (_err) => {
method: "GET", if(_err) {
headers: { "Content-Type": "application/json" }, return res.status(500).json({ error: _err});
timeout: 300000 } else {
}) console.dir('req.body ===');
.then(async rep => { console.dir(req.body);
if(rep.data && rep.data.called && rep.data._id && rep.data.bindID){ if(!notEmpty(req.body)) res.status(500).json({ error: "参数错误"});
//const fromID = await getFromID(pubID); else {
console.dir(fromID + '====>'); const fromID = await getFromID(pubID,db);
updateBill({pre: true, number: data.number, accountID: pubID, fromID, type: 'call', taskID: rep.data._id}, (err,_rep) => { const host = _host + "/bind/" + (pubID + "_" + fromID) + '/' + slotID + '?caller=' + phone + '&unikey=' + unikey + '&expiration=' + expiration;
if(err) { axios(host, {
// log 代码; method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(async rep => {
if(rep.data && rep.data.called && rep.data._id && rep.data.bindID){
//const fromID = await getFromID(pubID);
updateBill({pre: true, number: data.number, accountID: pubID, fromID, type: 'call', taskID: rep.data._id}, db, (err,_rep) => {
if(err) {
// log 代码;
}
res.send({ status: 'ok', called: rep.data.called, bindID: rep.data.bindID });
});
}
else{
res.status(500).json({ error: '取号失败'});
}
})
.catch(err => {
console.dir(err)
if (err) return res.status(500).json({ error: '运营商拒绝服务'});
});
} }
res.send({ status: 'ok', called: rep.data.called, bindID: rep.data.bindID }); }
}); });
} } else {
else{ res.status(500);
res.status(500).json({ error: '取号失败'}); }
} });
}) }});
.catch(err => {
console.dir(err)
if (err) return res.status(500).json({ error: '运营商拒绝服务'});
});
}
}
});
} else {
res.status(500);
}
});
}); });
router.post('/job/dspcall',function (req,res) { router.post('/job/dspcall',function (req,res) {
const { pubID, groupID, phone, expiration = EXPIRATION, unikey } = req.body; const { pubID, groupID, phone, expiration = EXPIRATION, unikey } = req.body;
getCallConsumeByUnikey(unikey, (err, data) => { let data = _.merge(req.query,req.body);
if(err) return res.status(500).json({ error: err}); checkSession(data, async (err, rep) => {
if(data && data.number) { if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
checkBill({ accountID: pubID, number: data.number },async (_err) => { else {
if(_err) { let db = getDB(rep);
return res.status(500).json({ error: _err}); let _host = getHost(rep);
} else { getCallConsumeByUnikey(unikey, db, (err, data) => {
if(!notEmpty(req.body)) res.status(500).json({ error: "参数错误"}); if(err) return res.status(500).json({ error: err});
else { if(data && data.number) {
const fromID = await getFromID(pubID); checkBill({ accountID: pubID, number: data.number },db, async (_err) => {
const host = "http://remarketing-job-yh.yoo.yunpro.cn/dspBind/" + (pubID + "_" + fromID) + '/' + groupID + '?caller=' + phone + '&unikey=' + unikey + '&expiration=' + expiration; if(_err) {
axios(host, { return res.status(500).json({ error: _err});
method: "GET", } else {
headers: { "Content-Type": "application/json" }, console.dir('req.body === dsp');
timeout: 300000 console.dir(req.body);
}) if(!notEmpty(req.body)) res.status(500).json({ error: "参数错误"});
.then(async rep => { else {
if(rep.data && rep.data.called && rep.data._id && rep.data.bindID){ const fromID = await getFromID(pubID,db);
//const fromID = await getFromID(pubID); const host = _host + "/dspBind/" + (pubID + "_" + fromID) + '/' + groupID + '?caller=' + phone + '&unikey=' + unikey + '&expiration=' + expiration;
updateBill({pre: true, number: data.number, accountID: pubID, fromID, type: 'dspcall', groupID,taskID: rep.data._id }, (err,_rep) => { axios(host, {
if(err) { method: "GET",
// log 代码; headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(async rep => {
if(rep.data && rep.data.called && rep.data._id && rep.data.bindID){
//const fromID = await getFromID(pubID);
updateBill({pre: true, number: data.number, accountID: pubID, fromID, type: 'dspcall', groupID,taskID: rep.data._id }, db, (err,_rep) => {
if(err) {
// log 代码;
}
res.send({ status: 'ok', called: rep.data.called, bindID: rep.data.bindID });
});
}
else{
res.status(500).json({ error: '取号失败'});
} }
res.send({ status: 'ok', called: rep.data.called, bindID: rep.data.bindID }); })
.catch(err => {
console.dir(err)
if (err) return res.status(500).json({ error: '运营商拒绝服务'});
}); });
} }
else{ }
res.status(500).json({ error: '取号失败'}); });
} } else {
}) res.status(500);
.catch(err => {
console.dir(err)
if (err) return res.status(500).json({ error: '运营商拒绝服务'});
});
}
} }
}); });
} else { }
res.status(500);
}
}); });
}); });
router.get('/unbind',function (req,res) { router.get('/unbind',function (req,res) {
const { bindID } = req.query; let data = _.merge(req.query,req.body);
const host = "http://remarketing-job-yh.yoo.yunpro.cn/unbind?bindID=" + bindID; checkSession(data, async (err, rep) => {
axios(host, { if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
method: "GET", else {
headers: { "Content-Type": "application/json" }, let _host = getHost(rep);
timeout: 300000 const { bindID } = req.query;
}) const host = _host + "/unbind?bindID=" + bindID;
.then(rep => { axios(host, {
res.send({status:'ok'}); method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(rep => {
res.send({status:'ok'});
})
.catch(err => {
console.dir(err);
if (err) return res.status(500).json({ error: '解绑错误'});
});
}
}) })
.catch(err => {
console.dir(err);
if (err) return res.status(500).json({ error: '解绑错误'});
});
}); });
router.get('/dspUnbind',function (req,res) { router.get('/dspUnbind',function (req,res) {
const { bindID } = req.query; let data = _.merge(req.query,req.body);
const host = "http://remarketing-job-yh.yoo.yunpro.cn/dspUnbind?bindID=" + bindID; checkSession(data, async (err, rep) => {
axios(host, { if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
method: "GET", else {
headers: { "Content-Type": "application/json" }, let _host = getHost(rep);
timeout: 300000 const { bindID } = req.query;
}) const host = _host + "/dspUnbind?bindID=" + bindID;
.then(rep => { axios(host, {
res.send({status:'ok'}); method: "GET",
}) headers: { "Content-Type": "application/json" },
.catch(err => { timeout: 300000
console.dir(err); })
if (err) return res.status(500).json({ error: '解绑错误'}); .then(rep => {
res.send({status:'ok'});
})
.catch(err => {
if (err) return res.status(500).json({ error: '解绑错误'});
});
}
}); });
}); });
router.post('/login',async function (req,res) { router.post('/login',async function (req,res) {
//token phone sessionID //token phone sessionID
console.dir('in login');
console.dir(req.body);
checkSession(req.body, (err, rep) => { checkSession(req.body, (err, rep) => {
if (err) return res.status(500).json({ error: "查询失败" }); if (err) return res.status(500).json({ error: "查询失败" });
if (!rep) { if (!rep) {
//没有符合的session //没有符合的session
return authorize(req.body, (err, rep) => { return authorize(req.body, (err, rep) => {
console.dir(err);
if (err) return res.status(500).json({ error: "查询账户失败" }); if (err) return res.status(500).json({ error: "查询账户失败" });
if (!rep) return res.status(403).json({ error: "账户不存在" }); if (!rep) return res.status(403).json({ error: "账户不存在" });
//验证通过 //验证通过
const token = _.merge(rep, { sessionID: genSessionID(rep._id) }); const token = _.merge(rep, { sessionID: genSessionID(rep._id, rep.db) });
delete token.token; delete token.token;
res.send({ status: "ok", token }); res.send({ status: "ok", token });
}); });
} else { } else {
let db = getDB(rep);
db db
.collection("tokens") .collection("tokens")
.findOne({ _id: OID(rep.tokenID) }, (err, rep) => { .findOne({ _id: OID(rep.tokenID) }, (err, rep) => {
...@@ -213,6 +279,7 @@ router.get("/recognitions",function(req,res) { ...@@ -213,6 +279,7 @@ router.get("/recognitions",function(req,res) {
checkSession(req.query, async (err, rep) => { checkSession(req.query, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 }); if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else { else {
let db = getDB(rep);
const tokenID = rep.tokenID; const tokenID = rep.tokenID;
if(date) { if(date) {
start = (end = date); start = (end = date);
...@@ -223,7 +290,6 @@ router.get("/recognitions",function(req,res) { ...@@ -223,7 +290,6 @@ router.get("/recognitions",function(req,res) {
_.merge(qs, { calledInfo: { $exists: called == 'true' } , 'tokenInfo.tokenID': OID(tokenID) , auditStatus: 2 } ); _.merge(qs, { calledInfo: { $exists: called == 'true' } , 'tokenInfo.tokenID': OID(tokenID) , auditStatus: 2 } );
if(called == 'true') sort.calledTimestamp = -1; if(called == 'true') sort.calledTimestamp = -1;
else sort.updateTimestamp = -1; else sort.updateTimestamp = -1;
console.dir(qs);
const count = await db.collection('recognition').count(qs); const count = await db.collection('recognition').count(qs);
db db
.collection('recognition') .collection('recognition')
...@@ -234,12 +300,12 @@ router.get("/recognitions",function(req,res) { ...@@ -234,12 +300,12 @@ router.get("/recognitions",function(req,res) {
.toArray(async (err, rep) => { .toArray(async (err, rep) => {
if (err) return res.status(500).json({ error: "数据查询失败" }); if (err) return res.status(500).json({ error: "数据查询失败" });
//const arrs = await getStars(rep); //const arrs = await getStars(rep);
let _arrs = await getSlots(rep); let _arrs = await getSlots(rep,db);
_arrs = _arrs.map( x => { _arrs = _arrs.map( x => {
x.score = { score: x.score || 0 }; x.score = { score: x.score || 0 };
return x; return x;
}); });
if(called == 'true') _arrs = await getTasks(_arrs); if(called == 'true') _arrs = await getTasks(_arrs,db);
res.send({ status: "ok", recognitions: _arrs, page: { skip: skip, total: count } }) res.send({ status: "ok", recognitions: _arrs, page: { skip: skip, total: count } })
}); });
} }
...@@ -251,6 +317,7 @@ router.get("/dsprecognitions",function(req,res) { ...@@ -251,6 +317,7 @@ router.get("/dsprecognitions",function(req,res) {
checkSession(req.query, async (err, rep) => { checkSession(req.query, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 }); if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else { else {
let db = getDB(rep);
const tokenID = rep.tokenID; const tokenID = rep.tokenID;
if(date) { if(date) {
start = (end = date); start = (end = date);
...@@ -259,7 +326,6 @@ router.get("/dsprecognitions",function(req,res) { ...@@ -259,7 +326,6 @@ router.get("/dsprecognitions",function(req,res) {
let qs = getTimeRange({start, end, key:'createdAt', type: 'millisecond'}); let qs = getTimeRange({start, end, key:'createdAt', type: 'millisecond'});
//let qs = { updateTimestamp: { '$gt': parseInt(moment(date, 'YYYYMMDD').startOf('day').format('x')), '$lte': parseInt(moment(date, 'YYYYMMDD').endOf('day').format('x')) }, 'tokenInfo.tokenID': OID(tokenID) }; //let qs = { updateTimestamp: { '$gt': parseInt(moment(date, 'YYYYMMDD').startOf('day').format('x')), '$lte': parseInt(moment(date, 'YYYYMMDD').endOf('day').format('x')) }, 'tokenInfo.tokenID': OID(tokenID) };
_.merge(qs, { calledInfo: { $exists: called == 'true' } , 'tokenInfo.tokenID': OID(tokenID) } ); _.merge(qs, { calledInfo: { $exists: called == 'true' } , 'tokenInfo.tokenID': OID(tokenID) } );
console.dir(qs);
if(called == 'true') sort.calledTimestamp = -1; if(called == 'true') sort.calledTimestamp = -1;
else sort.createdAt = -1; else sort.createdAt = -1;
const count = await db.collection('dspRecognition').count(qs); const count = await db.collection('dspRecognition').count(qs);
...@@ -271,7 +337,7 @@ router.get("/dsprecognitions",function(req,res) { ...@@ -271,7 +337,7 @@ router.get("/dsprecognitions",function(req,res) {
.limit(parseInt(limit)) .limit(parseInt(limit))
.toArray(async (err, rep) => { .toArray(async (err, rep) => {
if (err) return res.status(500).json({ error: "数据查询失败" }); if (err) return res.status(500).json({ error: "数据查询失败" });
let _arrs = await getCallGroupInfo(rep); let _arrs = await getCallGroupInfo(rep, db);
res.send({ status: "ok", recognitions: _arrs, page: { skip: skip, total: count } }) res.send({ status: "ok", recognitions: _arrs, page: { skip: skip, total: count } })
}); });
} }
...@@ -279,11 +345,11 @@ router.get("/dsprecognitions",function(req,res) { ...@@ -279,11 +345,11 @@ router.get("/dsprecognitions",function(req,res) {
}); });
async function getCallGroupInfo(arrays) { async function getCallGroupInfo(arrays,_db) {
let tasks = []; let tasks = [];
arrays.forEach((x) => { arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => { tasks.push(new Promise(async (r,e) => {
const GroupInfo = (x.groupID && exists(x.groupID)) ? await db const GroupInfo = (x.groupID && exists(x.groupID)) ? await _db
.collection("dspCallGroups") .collection("dspCallGroups")
.findOne({ _id: OID(x.groupID) },{dspgroup: 1}) : { dspgroup: '' }; .findOne({ _id: OID(x.groupID) },{dspgroup: 1}) : { dspgroup: '' };
r(_.merge(x, { dspgroup: (GroupInfo ? GroupInfo.dspgroup : '') } )); r(_.merge(x, { dspgroup: (GroupInfo ? GroupInfo.dspgroup : '') } ));
...@@ -307,11 +373,11 @@ async function getStars(arrays) { ...@@ -307,11 +373,11 @@ async function getStars(arrays) {
return arrs; return arrs;
} }
async function getSlots(arrays) { async function getSlots(arrays,_db) {
let tasks = []; let tasks = [];
arrays.forEach((x) => { arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => { tasks.push(new Promise(async (r,e) => {
const slot = x['slotID'] ? await db const slot = x['slotID'] ? await _db
.collection("slotTemps") .collection("slotTemps")
.findOne({ _id: OID(x.slotID), accountID: OID(x.pubID) },{ slotName: 1 }) : { slotName: '未知' }; .findOne({ _id: OID(x.slotID), accountID: OID(x.pubID) },{ slotName: 1 }) : { slotName: '未知' };
r(_.merge(x,{ slot: (slot ? slot : { slotName: '未知' }) })); r(_.merge(x,{ slot: (slot ? slot : { slotName: '未知' }) }));
...@@ -356,22 +422,36 @@ function notEmpty(data) { ...@@ -356,22 +422,36 @@ function notEmpty(data) {
function authorize(data, callback) { async function authorize(data, callback) {
db.collection("tokens").findOne({ phone: data.phone }, (err, rep) => { let token = md5token(data.token);
if (err || !rep) return callback(err, null); try {
if (md5token(data.token) !== rep.passwd) let self_user = await db.collection("tokens").findOne({ phone: data.phone });
return callback("password wrong", null); let mtty_user = await oem_db.mtty.collection("tokens").findOne({ phone: data.phone });
callback(null, rep); let xibao_user = await oem_db.xibao.collection("tokens").findOne({ phone: data.phone });
}); if (self_user && self_user.passwd == token) {
return callback(null, _.merge(self_user, {db: 'self'}));
}
if ( mtty_user && mtty_user.passwd == token) {
return callback(null, _.merge(mtty_user, {db: 'mtty'}));
}
if ( xibao_user && xibao_user.passwd == token) {
return callback(null, _.merge(xibao_user, {db: 'xibao'}));
} else {
return callback(null, null);
}
} catch (err) {
return callback(err, null);
}
} }
function genSessionID(tokenID) { function genSessionID(tokenID,_db) {
const sessionID = mongodb.ObjectID(); const sessionID = mongodb.ObjectID();
db.collection("tokenSession").insert( db.collection("tokenSession").insert(
{ {
createdAt: new Date(), createdAt: new Date(),
sessionID, sessionID,
tokenID tokenID,
db:_db || 'self'
}, },
(err, rep) => { (err, rep) => {
if (err) console.log(err); if (err) console.log(err);
...@@ -381,13 +461,13 @@ function genSessionID(tokenID) { ...@@ -381,13 +461,13 @@ function genSessionID(tokenID) {
} }
async function checkBill(data, callback) { async function checkBill(data, _db, callback) {
if(!notEmpty(data)) return callback('参数错误'); if(!notEmpty(data)) return callback('参数错误');
let { number, accountID } = data; let { number, accountID } = data;
if(!/^[0-9a-z]{24}$/.test(accountID) ) return callback('参数错误'); if(!/^[0-9a-z]{24}$/.test(accountID) ) return callback('参数错误');
let recharge = await getRechargeByAccount( accountID ); let recharge = await getRechargeByAccount( accountID, _db );
if( recharge <= 0 ) { return callback('余额不足') } if( recharge <= 0 ) { return callback('余额不足') }
let consume = await getBillByAccount( accountID ); let consume = await getBillByAccount( accountID , _db);
if( consume + number > recharge ) { return callback('余额不足') } if( consume + number > recharge ) { return callback('余额不足') }
callback && callback(); callback && callback();
} }
...@@ -404,7 +484,7 @@ async function checkBill(data, callback) { ...@@ -404,7 +484,7 @@ async function checkBill(data, callback) {
}); });
}*/ }*/
async function updateBill(data, callback) { async function updateBill(data, _db, callback) {
if(!notEmpty(data)) return callback('params wrong'); if(!notEmpty(data)) return callback('params wrong');
let { pre, number, accountID, type, taskID, fromID = 'self', groupID, preNum = 30 } = data; let { pre, number, accountID, type, taskID, fromID = 'self', groupID, preNum = 30 } = data;
if(!/^[0-9a-z]{24}$/.test(accountID) ) return callback('params wrong'); if(!/^[0-9a-z]{24}$/.test(accountID) ) return callback('params wrong');
...@@ -413,7 +493,7 @@ async function updateBill(data, callback) { ...@@ -413,7 +493,7 @@ async function updateBill(data, callback) {
_data.groupID = OID(groupID); _data.groupID = OID(groupID);
} }
_data.taskID = OID(taskID); _data.taskID = OID(taskID);
db _db
.collection('bills') .collection('bills')
.insert(wrapTime(_data,true), (err, rep) => { .insert(wrapTime(_data,true), (err, rep) => {
if (err) return callback(err); if (err) return callback(err);
...@@ -421,8 +501,8 @@ async function updateBill(data, callback) { ...@@ -421,8 +501,8 @@ async function updateBill(data, callback) {
}); });
} }
async function getBillByAccount( accountID ) { async function getBillByAccount( accountID, _db ) {
let consumes = await db let consumes = await _db
.collection('bills') .collection('bills')
.aggregate([ .aggregate([
{ {
...@@ -441,8 +521,8 @@ async function getBillByAccount( accountID ) { ...@@ -441,8 +521,8 @@ async function getBillByAccount( accountID ) {
return ( (consumes && consumes.length) ? consumes[0].sum : 0 ); return ( (consumes && consumes.length) ? consumes[0].sum : 0 );
} }
async function getRechargeByAccount(accountID) { async function getRechargeByAccount(accountID, _db) {
let recharges = await db let recharges = await _db
.collection('recharge') .collection('recharge')
.aggregate([ .aggregate([
{ {
...@@ -460,14 +540,14 @@ async function getRechargeByAccount(accountID) { ...@@ -460,14 +540,14 @@ async function getRechargeByAccount(accountID) {
return ( (recharges && recharges.length) ? recharges[0].sum : 0 ); return ( (recharges && recharges.length) ? recharges[0].sum : 0 );
} }
async function getCallConsumeByUnikey(unikey,callback) { async function getCallConsumeByUnikey(unikey,_db,callback) {
const price = db.collection('price').findOne({type: 'call'}); const price = _db.collection('price').findOne({type: 'call'});
let number = (price && price.number) ? price.number : 1; let number = (price && price.number) ? price.number : 1;
//const task = db.collection('callTask').findOne({ unikey }); //const task = db.collection('callTask').findOne({ unikey });
callback(null, { number: Math.ceil((EXPIRATION / 60) ) * number }); callback(null, { number: Math.ceil((EXPIRATION / 60) ) * number });
} }
async function getTasks(arrays) { async function getTasks(arrays,_db) {
let _tasks = []; let _tasks = [];
arrays.forEach((x) => { arrays.forEach((x) => {
_tasks.push(new Promise(async (r,e) => { _tasks.push(new Promise(async (r,e) => {
...@@ -475,7 +555,7 @@ async function getTasks(arrays) { ...@@ -475,7 +555,7 @@ async function getTasks(arrays) {
let tasks = []; let tasks = [];
x.calledInfo.forEach((y) => { x.calledInfo.forEach((y) => {
tasks.push(new Promise(async (r,e) => { tasks.push(new Promise(async (r,e) => {
const TaskInfo = (y.taskID && exsists(y.taskID)) ? await db const TaskInfo = (y.taskID && exsists(y.taskID)) ? await _db
.collection("callTask") .collection("callTask")
.findOne({ _id: OID(y.taskID) },{ startTime : 1 }) : { startTime: -1 }; .findOne({ _id: OID(y.taskID) },{ startTime : 1 }) : { startTime: -1 };
r(_.merge( y, { TaskInfo } )); r(_.merge( y, { TaskInfo } ));
...@@ -504,8 +584,20 @@ function wrapTime(obj, date) { ...@@ -504,8 +584,20 @@ function wrapTime(obj, date) {
return _.merge(obj,d ) return _.merge(obj,d )
} }
async function getFromID(accountID) { function getDB(session) {
const account = await db.collection('account').findOne({ _id: OID(accountID) }); if(session.db == 'mtty') return oem_db.mtty;
if(session.db == 'xibao') return oem_db.xibao;
else return db;
}
function getHost(session) {
if(session.db == 'mtty') return 'http://remarkering-mtty-yh.yoo.yunpro.cn';
if(session.db == 'xibao') return 'http://remarketing-xibao-yh.yoo.yunpro.cn';
else return 'http://remarketing-job-yh.yoo.yunpro.cn';
}
async function getFromID(accountID,_db) {
const account = await _db.collection('account').findOne({ _id: OID(accountID) });
return (account && account.fromID ? account.fromID : 'self'); return (account && account.fromID ? account.fromID : 'self');
} }
......
const router = require("express").Router();
const mongodb = require("mongodb");
const MongoClient = mongodb.MongoClient;
const crypto = require("crypto");
const axios = require("axios");
const _ = require("lodash");
const moment = require('moment');
const adminID = process.env.NODE_ENV === 'production' ? '5a9f9e6b46da1176a40e1082' : '5ab083b1f6134d82b40d95f2';
let db = {};
let oem_db = { mtty:{}, xibao:{} };
const dbpath = process.env.MONGO || "mongodb://10.11.3.127:1301/remarketing";
const oem_dbpath = ( process.env.MONGO_OEM + process.env.MONGO_DB_MTTY || "mongodb://10.11.3.127:1301/remarketing" ) + (process.env.MONGO_OEM ? "?replicaSet=bjwjh-rs&authSource=admin" : '');
//const xibao_dbpath = process.env.MONGO_OEM +process.env.MONGO_DB_XIBAO + "?replicaSet=bjwjh-rs&authSource=admin";
const salt = ",tom";
const EXPIRATION = 60 * 30;
// TODO ! put into init
MongoClient.connect(dbpath, (err, conn) => {
if (err) return console.log(err);
console.log("#### DB CONNECTED");
db = conn.db("remarketing");
db
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
});
MongoClient.connect(oem_dbpath, (err, conn) => {
if (err) return console.log(err);
console.log("#### OEM DB CONNECTED");
oem_db.mtty = conn.db(process.env.MONGO_DB_MTTY);
oem_db.xibao = conn.db(process.env.MONGO_DB_XIBAO);
oem_db.mtty
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
oem_db.xibao
.collection("tokenSession")
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 * 24 });
});
/*router.post('/remark',function (req,res) {
const { recog, remark, unikey, sessionID } = req.body;
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
let doc = { recog, remark, unikey };
if(doc.recog) delete doc.unikey;
if(doc.unikey) delete doc.recog;
const host = getHost(rep) + "/remark";
axios(host, {
method: "POST",
headers: { "Content-Type": "application/json" },
data: doc,
timeout: 300000
})
.then(async rep => {
res.send({ status:'ok', data: rep.data });
})
.catch(err => {
console.dir(err);
if (err) return res.status(500).json({ error: '服务出错'});
});
}});
});*/
router.post('/remark',function (req,res) {
const { recog, tags, remark, sessionID } = req.body;
const type = req.query.type;
checkSession(req.body, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
let collectionName = ((type === 'dsp') ? 'dspRecognition' : 'recognition');
let _tags = Array.isArray(tags) ? tags : [tags];
db.collection(collectionName).update({ _id: OID(recog) },{ $addToSet: { systemTags: { $each: _tags } }, $push: { remark: remark } }, (err, rep) => {
if(err) res.status(500).json({ error: '服务出错'});
else res.send({ status: 'ok',rep });
});
}});
});
router.get('/tags',function (req,res) {
checkSession(req.query, async (err, rep) => {
if (err || !rep || !rep.tokenID) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
let dspGroupIds = await db.collection('dspRecognition').distinct('groupID',{'tokenInfo.tokenID': OID(rep.tokenID) });
let slotIds = await db.collection('recognition').distinct('slotID',{'tokenInfo.tokenID': OID(rep.tokenID) });
let dspGroups = dspGroupIds.length ? await db.collection('dspCallGroups').find({ _id: { $in: dspGroupIds} }, { dspgroup : 1 }).toArray() : [];
dspGroups = dspGroups.map( x => { return { _id: x._id, name: x.dspgroup } });
slotIds = slotIds.map( x => OID(x));
let slots = slotIds.length ? await db.collection('slotTemps').find({ _id: { $in: slotIds } },{ slotName: 1 }).toArray() : [];
slots = slots.map( x => { return { _id: x._id, name: x.slotName } });
res.send({ status:'ok',callstatus: ['已拨打','未拨打'], tags: ['有意向','已经加微信','需回拨','未接通','无意向'], dspGroups, slots });
}
})
})
router.post('/job/call',function (req,res) {
const { pubID, slotID, phone, expiration = EXPIRATION, unikey, sessionID } = req.body;
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
let _host = getHost(rep);
getCallConsumeByUnikey(unikey, db, (err, data) => {
if(err) return res.status(500).json({ error: err});
if(data && data.number) {
checkBill({ accountID: pubID, number: data.number }, db, async (_err) => {
if(_err) {
return res.status(500).json({ error: _err});
} else {
if(!notEmpty(req.body)) res.status(500).json({ error: "参数错误"});
else {
const fromID = await getFromID(pubID,db);
const host = _host + "/bind/" + (pubID + "_" + fromID) + '/' + slotID + '?caller=' + phone + '&unikey=' + unikey + '&expiration=' + expiration;
axios(host, {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(async rep => {
if(rep.data && rep.data.called && rep.data._id && rep.data.bindID){
//const fromID = await getFromID(pubID);
updateBill({pre: true, number: data.number, accountID: pubID, fromID, type: 'call', taskID: rep.data._id}, db, (err,_rep) => {
if(err) {
// log 代码;
}
res.send({ status: 'ok', called: rep.data.called, bindID: rep.data.bindID });
});
}
else{
res.status(500).json({ error: '取号失败'});
}
})
.catch(err => {
console.dir(err)
if (err) return res.status(500).json({ error: '运营商拒绝服务'});
});
}
}
});
} else {
res.status(500);
}
});
}});
});
router.post('/job/dspcall',function (req,res) {
const { pubID, groupID, phone, expiration = EXPIRATION, unikey } = req.body;
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
let _host = getHost(rep);
getCallConsumeByUnikey(unikey, db, (err, data) => {
if(err) return res.status(500).json({ error: err});
if(data && data.number) {
checkBill({ accountID: pubID, number: data.number },db, async (_err) => {
if(_err) {
return res.status(500).json({ error: _err});
} else {
if(!notEmpty(req.body)) res.status(500).json({ error: "参数错误"});
else {
const fromID = await getFromID(pubID,db);
const host = _host + "/dspBind/" + (pubID + "_" + fromID) + '/' + groupID + '?caller=' + phone + '&unikey=' + unikey + '&expiration=' + expiration;
axios(host, {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(async rep => {
if(rep.data && rep.data.called && rep.data._id && rep.data.bindID){
//const fromID = await getFromID(pubID);
updateBill({pre: true, number: data.number, accountID: pubID, fromID, type: 'dspcall', groupID,taskID: rep.data._id }, db, (err,_rep) => {
if(err) {
// log 代码;
}
res.send({ status: 'ok', called: rep.data.called, bindID: rep.data.bindID });
});
}
else{
res.status(500).json({ error: '取号失败'});
}
})
.catch(err => {
console.dir(err)
if (err) return res.status(500).json({ error: '运营商拒绝服务'});
});
}
}
});
} else {
res.status(500);
}
});
}
});
});
router.get('/unbind',function (req,res) {
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let _host = getHost(rep);
const { bindID } = req.query;
const host = _host + "/unbind?bindID=" + bindID;
axios(host, {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(rep => {
res.send({status:'ok'});
})
.catch(err => {
console.dir(err);
if (err) return res.status(500).json({ error: '解绑错误'});
});
}
})
});
router.get('/dspUnbind',function (req,res) {
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let _host = getHost(rep);
const { bindID } = req.query;
const host = _host + "/dspUnbind?bindID=" + bindID;
axios(host, {
method: "GET",
headers: { "Content-Type": "application/json" },
timeout: 300000
})
.then(rep => {
res.send({status:'ok'});
})
.catch(err => {
if (err) return res.status(500).json({ error: '解绑错误'});
});
}
});
});
router.get('/stats',function (req,res) {
let data = _.merge(req.query,req.body);
checkSession(data, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
let { phone } = await db
.collection("tokens")
.findOne({ _id: OID(rep.tokenID) })
if(!phone) return res.status(500).json({ error: "账号错误,重新登录", code: 302 });
let date = new Date();
let weekday = date.getDay() || 7;
date.setDate(date.getDate()-weekday+1);
let start = moment(date).format('YYYYMMDD');
let end = moment().format('YYYYMMDD');
let statistics = {};
let stats = await db
.collection('callTask')
.aggregate([
{
$match:{
"caller" : phone,
"date": { $gte: start, $lte: end },
}
},
{
$group:{
_id: {
date: "$date",
result: "$result"
},
duration: { $sum:"$duration" },
count: { $sum: 1 }
}
}]).toArray();
let dspstats = await db
.collection('dspCallTask')
.aggregate([
{
$match:{
"caller" : phone,
"date": { $gte: start, $lte: end },
}
},
{
$group:{
_id: {
date: "$date",
result: "$result"
},
duration: {$sum:"$duration"},
count: { $sum: 1 }
}
}]).toArray();
let _stats = stats.concat(dspstats);
_stats.forEach( x => {
let date = x._id.date || 'unknown';
if(statistics[date]) {
statistics[date].count += x.count;
statistics[date].duration += x.duration;
statistics[date].pinged += (x._id.result ? x.count : 0);
} else {
statistics[date] = {
count: x.count,
duration: x.duration,
pinged: x._id.result ? x.count : 0,
}
}
});
res.send({ status:'ok',totalstats: statistics ,stats,dspstats });
}
});
});
router.post('/login',async function (req,res) {
//token phone sessionID
checkSession(req.body, (err, rep) => {
if (err) return res.status(500).json({ error: "查询失败" });
if (!rep) {
//没有符合的session
return authorize(req.body, (err, rep) => {
console.dir(err);
if (err) return res.status(500).json({ error: "查询账户失败" });
if (!rep) return res.status(403).json({ error: "账户不存在" });
//验证通过
const token = _.merge(rep, { sessionID: genSessionID(rep._id, rep.db) });
delete token.token;
res.send({ status: "ok", token });
});
} else {
let db = getDB(rep);
db
.collection("tokens")
.findOne({ _id: OID(rep.tokenID) }, (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "查询账户失败"});
const token = _.merge(rep, { sessionID: req.body.sessionID });
delete token.token;
delete token.passwd;
res.send({ status: "ok", token });
});
}
});
});
router.post("/logout",function(req,res) {
let { sessionID } = req.body;
db
.collection('tokenSession')
.remove({ _id: OID(sessionID) }, (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "更新session新失败"});
res.send({ status: "ok", rep });
});
});
router.post("/recognitions",function(req,res) {
let { sessionID, limit = 10, skip = 0, called , tags , slots, carrier } = req.body;
checkSession(req.body, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
const tokenID = rep.tokenID;
let sort = {};
let qs = {};
if( tags && tags.length) {
let _tags = Array.isArray(tags) ? tags : [ tags ];
qs.systemTags = { $in: _tags };
}
if( slots && slots.length ) {
let _slots = Array.isArray(slots) ? slots : [ slots ];
qs.slotID = { $in: slots };
}
if( called ) {
qs.calledInfo = { $exists: called == 'true' }
}
if(carrier === 'ctcc' || carrier === 'cmcc') {
qs.carrier = carrier
} else {
qs.carrier = { $nin: ['ctcc','cmcc'] }
}
_.merge(qs, { 'tokenInfo.tokenID': OID(tokenID) , auditStatus: 2 } );
if(called === 'true' || called === true ) sort.calledTimestamp = -1;
else sort.updateTimestamp = -1;
const count = await db.collection('recognition').count(qs);
db
.collection('recognition')
.find(qs)
.sort(sort)
.skip(parseInt(skip * limit))
.limit(parseInt(limit))
.toArray(async (err, rep) => {
if (err) return res.status(500).json({ error: "数据查询失败" });
//const arrs = await getStars(rep);
let _arrs = await getSlots(rep,db);
if(called == 'true') _arrs = await getTasks(_arrs,db);
res.send({ status: "ok", recognitions: _arrs, page: { skip: skip, total: count } })
});
}
});
});
router.post("/dsprecognitions",function(req,res) {
let { sessionID, limit = 10, skip = 0, called, tags, groups, carrier } = req.body;
checkSession(req.body, async (err, rep) => {
if (err || !rep) return res.status(500).json({ error: "session错误,重新登录", code: 302 });
else {
let db = getDB(rep);
const tokenID = rep.tokenID;
let sort = {};
let qs = {}
if( tags && tags.length) {
let _tags = Array.isArray(tags) ? tags : [ tags ];
qs.systemTags = { $in: _tags };
}
if( groups && groups.length ) {
let _groups = Array.isArray(groups) ? groups : [ groups ];
_groups = _groups.map( x => OID(x) );
qs.groupID = { $in: _groups };
}
if( called ) {
qs.calledInfo = { $exists: called == 'true' }
}
_.merge(qs, { 'tokenInfo.tokenID': OID(tokenID) } );
if(called === 'true' || called === true) sort.calledTimestamp = -1;
else sort.createdAt = -1;
if(carrier === 'ctcc' || carrier === 'cmcc') {
qs.carrier = carrier
} else {
qs.carrier = { $nin: ['ctcc','cmcc'] }
}
const count = await db.collection('dspRecognition').count(qs);
db
.collection('dspRecognition')
.find(qs,{ tags:0 })
.sort(sort)
.skip(parseInt(skip * limit))
.limit(parseInt(limit))
.toArray(async (err, rep) => {
if (err) return res.status(500).json({ error: "数据查询失败" });
let _arrs = await getCallGroupInfo(rep, db);
_arrs.map( x => {
let body = {};
if(x.tags && x.tags.length)
x.tags.forEach( (x,i) => {
if(i === 1) body.city = x;
if(x.indexOf("岁") >= 0) body.age = x;
if(x.indexOf("男") >= 0) body.sex = '男';
if(x.indexOf("女") >= 0) body.sex = '女';
});
return _.merge(x,body);
});
res.send({ status: "ok", recognitions: _arrs, page: { skip: skip, total: count } })
});
}
});
});
async function getCallGroupInfo(arrays,_db) {
let tasks = [];
arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => {
const GroupInfo = (x.groupID && exists(x.groupID)) ? await _db
.collection("dspCallGroups")
.findOne({ _id: OID(x.groupID) },{dspgroup: 1}) : { dspgroup: '' };
r(_.merge(x, { dspgroup: (GroupInfo ? GroupInfo.dspgroup : '') } ));
}));
});
const arrs = await Promise.all(tasks);
return arrs;
}
async function getStars(arrays) {
let tasks = [];
arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => {
const score = x.slotID && x.pubID && x.unikey ? await db
.collection("score")
.findOne({ slotID: x.slotID , pubID: x.pubID, unikey: x.unikey },{ score: 1 }) : { score: -1 };
r(_.merge(x,{ score: (score ? score : { score: -1 }) }));
}));
});
const arrs = await Promise.all(tasks);
return arrs;
}
async function getSlots(arrays,_db) {
let tasks = [];
arrays.forEach((x) => {
tasks.push(new Promise(async (r,e) => {
const slot = x['slotID'] ? await _db
.collection("slotTemps")
.findOne({ _id: OID(x.slotID), accountID: OID(x.pubID) },{ slotName: 1 }) : { slotName: '未知' };
r(_.merge(x,{ slot: (slot ? slot : { slotName: '未知' }) }));
}));
});
const arrs = await Promise.all(tasks);
return arrs;
}
function md5token(str) {
const salt = ",tom";
const hash = crypto
.createHash("md5")
.update(str + salt)
.digest()
.toString("hex");
return hash;
}
function checkSession(data, callback) {
if (!data.sessionID || !/^[0-9a-z]{24}$/.test(data.sessionID)) return callback(null);
console.dir(data);
db
.collection("tokenSession")
.findOne({ sessionID: OID(data.sessionID) }, (err, rep) => {
console.dir(err)
console.dir(rep)
if (err || !rep) return callback(err, null);
callback(null, rep);
});
}
function exsists(ID) {
return ID !== undefined && ID !== null && ID !== 'all' && ID !== 'undefined';
}
function notEmpty(data) {
let temp = true;
Object.keys(data).forEach((key) => {
temp = temp && data[key] && exsists(data[key]);
})
return temp;
}
async function authorize(data, callback) {
let token = md5token(data.token);
try {
let self_user = await db.collection("tokens").findOne({ phone: data.phone });
let mtty_user = await oem_db.mtty.collection("tokens").findOne({ phone: data.phone });
let xibao_user = await oem_db.xibao.collection("tokens").findOne({ phone: data.phone });
if (self_user && self_user.passwd == token) {
return callback(null, _.merge(self_user, {db: 'self'}));
}
if ( mtty_user && mtty_user.passwd == token) {
return callback(null, _.merge(mtty_user, {db: 'mtty'}));
}
if ( xibao_user && xibao_user.passwd == token) {
return callback(null, _.merge(xibao_user, {db: 'xibao'}));
} else {
return callback(null, null);
}
} catch (err) {
return callback(err, null);
}
}
function genSessionID(tokenID,_db) {
const sessionID = mongodb.ObjectID();
db.collection("tokenSession").insert(
{
createdAt: new Date(),
sessionID,
tokenID,
db:_db || 'self'
},
(err, rep) => {
if (err) console.log(err);
}
);
return sessionID;
}
async function checkBill(data, _db, callback) {
if(!notEmpty(data)) return callback('参数错误');
let { number, accountID } = data;
if(!/^[0-9a-z]{24}$/.test(accountID) ) return callback('参数错误');
let recharge = await getRechargeByAccount( accountID, _db );
if( recharge <= 0 ) { return callback('余额不足') }
let consume = await getBillByAccount( accountID , _db);
if( consume + number > recharge ) { return callback('余额不足') }
callback && callback();
}
async function updateBill(data, _db, callback) {
if(!notEmpty(data)) return callback('params wrong');
let { pre, number, accountID, type, taskID, fromID = 'self', groupID, preNum = 30 } = data;
if(!/^[0-9a-z]{24}$/.test(accountID) ) return callback('params wrong');
let _data = { pre, number, accountID: OID(accountID), fromID, type };
if(groupID) {
_data.groupID = OID(groupID);
}
_data.taskID = OID(taskID);
_db
.collection('bills')
.insert(wrapTime(_data,true), (err, rep) => {
if (err) return callback(err);
callback && callback(null, rep);
});
}
async function getBillByAccount( accountID, _db ) {
let consumes = await _db
.collection('bills')
.aggregate([
{
$match:{
"accountID": OID(accountID),
"removed": { $ne: true }
/* "createdAt": { '$gt': start, '$lte': end }*/
}
},
{
$group:{
_id: null,
sum: {$sum:"$number"}
}
}]).toArray();
return ( (consumes && consumes.length) ? consumes[0].sum : 0 );
}
async function getRechargeByAccount(accountID, _db) {
let recharges = await _db
.collection('recharge')
.aggregate([
{
$match:{
"accountID": OID(accountID),
"removed": { $ne: true }
}
},
{
$group:{
_id:null,
sum:{$sum:"$number"}
}
}]).toArray();
return ( (recharges && recharges.length) ? recharges[0].sum : 0 );
}
async function getCallConsumeByUnikey(unikey,_db,callback) {
const price = _db.collection('price').findOne({type: 'call'});
let number = (price && price.number) ? price.number : 1;
//const task = db.collection('callTask').findOne({ unikey });
callback(null, { number: Math.ceil((EXPIRATION / 60) ) * number });
}
async function getTasks(arrays,_db) {
let _tasks = [];
arrays.forEach((x) => {
_tasks.push(new Promise(async (r,e) => {
if(x.calledInfo && x.calledInfo.length) {
let tasks = [];
x.calledInfo.forEach((y) => {
tasks.push(new Promise(async (r,e) => {
const TaskInfo = (y.taskID && exsists(y.taskID)) ? await _db
.collection("callTask")
.findOne({ _id: OID(y.taskID) },{ startTime : 1 }) : { startTime: -1 };
r(_.merge( y, { TaskInfo } ));
}));
});
const arrs = await Promise.all(tasks);
x.calledInfo = arrs;
}
r(x);
}));
});
const _arr = await Promise.all(_tasks);
return _arr;
}
function OID(str) {
return typeof str === 'string' ? mongodb.ObjectID(str) : str;
}
function wrapTime(obj, date) {
let d = { createdAt: new Date() };
if(date) {
d.date = moment().format('YYYYMMDD');
}
return _.merge(obj,d )
}
function getDB(session) {
if(session.db == 'mtty') return oem_db.mtty;
if(session.db == 'xibao') return oem_db.xibao;
else return db;
}
function getHost(session) {
if(session.db == 'mtty') return 'http://remarkering-mtty-yh.yoo.yunpro.cn';
if(session.db == 'xibao') return 'http://remarketing-xibao-yh.yoo.yunpro.cn';
else return 'http://remarketing-job-yh.yoo.yunpro.cn';
}
async function getFromID(accountID,_db) {
const account = await _db.collection('account').findOne({ _id: OID(accountID) });
return (account && account.fromID ? account.fromID : 'self');
}
function getTimeRange({ start, end, type, key}) {
if(/^[0-9]{8}$/.test(start) && /^[0-9]{8}$/.test(end) ) {
if(type === 'millisecond') {
return { [ key ]: { '$gt': parseInt(moment(start,'YYYYMMDD').startOf('day').format('x')), '$lte': parseInt(moment(end,'YYYYMMDD').endOf('day').format('x')) } };
} else {
return { [ key ]: { '$gt': moment(start,'YYYYMMDD').startOf('day').toDate(), '$lte': moment(end,'YYYYMMDD').endOf('day').toDate() } };
}
} else {
if(type === 'millisecond') {
return { [ key ]: { '$gt': parseInt(moment().add(-7,'days').startOf('day').format('x')), '$lte': parseInt(moment().endOf('day').format('x')) } };
} else {
return { [ key ]: { '$gt': moment().add(-7,'days').startOf('day').toDate(), '$lte': moment().endOf('day').toDate() } };
}
}
}
function exists(ID) {
return ID !== undefined && ID !== null && ID !== 'null' && ID !== '' && ID !== 'all' && ID !== 'undefined';
}
module.exports = router;
...@@ -5,6 +5,7 @@ var fs = require('fs'); ...@@ -5,6 +5,7 @@ var fs = require('fs');
var http = require('http'); var http = require('http');
var app = express(); var app = express();
const api = require('./api'); const api = require('./api');
const apiV2 = require('./api/v2');
var server = http.Server(app); var server = http.Server(app);
...@@ -16,6 +17,7 @@ app.use(cookieParser()); ...@@ -16,6 +17,7 @@ app.use(cookieParser());
app.use(express.static(__dirname + '/dist')); app.use(express.static(__dirname + '/dist'));
app.use('/api', api); app.use('/api', api);
app.use('/v2/api', apiV2);
server.listen(6662, function() { server.listen(6662, function() {
console.log('server started'); console.log('server started');
......
...@@ -23,7 +23,7 @@ const getters = { ...@@ -23,7 +23,7 @@ const getters = {
const actions = { const actions = {
[types.SEND_JOB]({ commit }, { templateId, unikeyArray, sendTime, accountID, callback }) { [types.SEND_JOB]({ commit }, { templateId, unikeyArray, sendTime, accountID, callback }) {
fetch('/api/job/msg', { //短信任务 fetch('/v2/api/job/msg', { //短信任务
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json;charset=UTF-8', 'Content-Type': 'application/json;charset=UTF-8',
...@@ -43,7 +43,7 @@ const actions = { ...@@ -43,7 +43,7 @@ const actions = {
}, },
[types.GET_JOBS]({ commit }, { accountID, skip = 0, limit = 50, callback, page }) { [types.GET_JOBS]({ commit }, { accountID, skip = 0, limit = 50, callback, page }) {
commit(types.JOB_LOADING, true); commit(types.JOB_LOADING, true);
fetch(`/api/jobs?accountID=${accountID}&skip=${skip}&limit=${limit}`).then((res) => { //短信任务获取 fetch(`/v2/api/jobs?accountID=${accountID}&skip=${skip}&limit=${limit}`).then((res) => { //短信任务获取
if (res.ok) { if (res.ok) {
return res.json(); return res.json();
} }
......
...@@ -66,7 +66,7 @@ const getters = { ...@@ -66,7 +66,7 @@ const getters = {
const actions = { const actions = {
[types.GET_RECOGNITIONS]({ commit }, { sessionID, skip = 0, limit = 50, date, refresh = false, called =false, callback }) { [types.GET_RECOGNITIONS]({ commit }, { sessionID, skip = 0, limit = 50, date, refresh = false, called =false, callback }) {
commit(types.NUMBERS_LOADING, true); commit(types.NUMBERS_LOADING, true);
fetch(`/api/recognitions?sessionID=${sessionID}&skip=${skip}&limit=${limit}&date=${date}&called=${called}`, { fetch(`/v2/api/recognitions?sessionID=${sessionID}&skip=${skip}&limit=${limit}&date=${date}&called=${called}`, {
}).then((res) => { }).then((res) => {
if (res.ok) { if (res.ok) {
return res.json(); return res.json();
...@@ -82,7 +82,7 @@ const actions = { ...@@ -82,7 +82,7 @@ const actions = {
}); });
}, },
[types.CALL_BEGIN]({ commit }, { slotID, pubID, unikey, phone, expiration= 30*60, callback }) { [types.CALL_BEGIN]({ commit }, { slotID, pubID, unikey, phone, expiration= 30*60, callback }) {
fetch('/api/job/call', { fetch('/v2/api/job/call', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json;charset=UTF-8', 'Content-Type': 'application/json;charset=UTF-8',
......
...@@ -33,7 +33,7 @@ const getters = { ...@@ -33,7 +33,7 @@ const getters = {
const actions = { const actions = {
login({ commit }, { phone, token, sessionID, callback }) { login({ commit }, { phone, token, sessionID, callback }) {
fetch('/api/login', { fetch('/v2/api/login', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json;charset=UTF-8', 'Content-Type': 'application/json;charset=UTF-8',
...@@ -54,7 +54,7 @@ const actions = { ...@@ -54,7 +54,7 @@ const actions = {
}, },
// check session when fresh // check session when fresh
session({ commit }, callback) { session({ commit }, callback) {
fetch('/api/session', { fetch('/v2/api/session', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json;charset=UTF-8', 'Content-Type': 'application/json;charset=UTF-8',
...@@ -74,7 +74,7 @@ const actions = { ...@@ -74,7 +74,7 @@ const actions = {
}); });
}, },
delSession({ commit }, callback) { delSession({ commit }, callback) {
fetch('/api/logout', { fetch('/v2/api/logout', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json;charset=UTF-8', 'Content-Type': 'application/json;charset=UTF-8',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment