Commit 1ae7fe7b authored by 刘松's avatar 刘松

cronjob & fix

parent 6c14d914
......@@ -51,4 +51,4 @@ app.use(routes);
app.listen(config.port);
console.log('server started on port ' + config.port);
/*cron.start();*/
cron.start();
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -72,16 +72,16 @@ class Schedule extends React.Component{
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;
const columns = [
{
title: '推广名称',
dataIndex: 'name',
key: 'name',
title: '分发ID',
dataIndex: 'id',
key: 'id',
width: 100,
render: text => <span href="#">{text}</span>,
},
{
title: '推广链接',
dataIndex: 'target',
key: 'target',
title: '推广页名称',
dataIndex: 'names',
key: 'names',
width: 100,
render: text => <span href="#">{text}</span>,
},
......@@ -92,6 +92,13 @@ class Schedule extends React.Component{
width: 100,
render: text => <span href="#">{text}</span>,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: text => <span href="#">{text}</span>,
},
{
title: '推广次数',
dataIndex: 'times',
......@@ -110,10 +117,16 @@ class Schedule extends React.Component{
let data = [];
let schedules = this.state.schedules;
for(let i = 0;i<schedules.length;i++){
let links = schedules[i].links;
var names = "";
links.forEach(function(link) {
names += (" " + link['name']);
});
data.push({
key:i,
name:schedules[i].taolink && schedules[i].taolink['name'] || '--',
target:schedules[i].taolink && schedules[i].taolink['target'] || '--',
id:schedules[i]._id,
names:names || '--',
status:schedules[i].status == 'use' ? '进行中' : '已暂停',
qd:schedules[i].qd && schedules[i].qd['user'] || '--',
times:schedules[i].times,
create:schedules[i].createdAt
......@@ -136,10 +149,10 @@ class Schedule extends React.Component{
>
<Form onSubmit={this.handleSubmit.bind(this)} className="login-form">
<FormItem>
{getFieldDecorator('name', {
rules: [{ required: true, message: '推广名称不能为空' }],
{getFieldDecorator('names', {
rules: [{ required: true, message: '推广名称不能为空' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>推广名称</span>} placeholder="例如:推广1" />
<Input prefix={<span style={{ fontSize: 13 }}>推广名称</span>} placeholder="例如:商品1@商品2@商品3" />
)}
</FormItem>
<FormItem>
......
......@@ -71,7 +71,7 @@ class Agent extends React.Component{
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;
const columns = [
{
title: '推广名称',
title: '推广名称',
dataIndex: 'name',
key: 'name',
width: 100,
......@@ -167,7 +167,7 @@ class Agent extends React.Component{
<Form onSubmit={this.handleSubmit.bind(this)} className="login-form">
<FormItem>
{getFieldDecorator('name', {
rules: [{ required: true, message: '推广名称不能为空' }],
rules: [{ required: true, message: '推广名称不能为空' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>推广名称</span>} placeholder="例如:推广1" />
)}
......
const React = require('react');
const moment = require('moment');
const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx';
import {Card, Form, Icon, Input, Button, Checkbox} from 'antd';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button} from 'antd';
const { RangePicker } = DatePicker;
const FormItem = Form.Item;
class Tbkls extends React.Component{
class Tbkl extends React.Component{
constructor(props){
super(props);
console.dir(this.props);
this.state= { tbkls :[],status:'pending',pagination:{current:1,pageSize:10,total:100},modalVisible:false,username:'channel'};
}
componentDidMount(){
let pagination = this.state.pagination;
if(document.cookie.match('username=[a-zA-Z0-9]+')[0] && document.cookie.match('username=[a-zA-Z0-9]+')[0].split('=')[1] == 'admin'){
this.setState({username:'admin'});
}
//let data = { start:moment().add(-6,'days').format('YYYYMMDD'),end:moment().format('YYYYMMDD')};
api('GET', 'tbkls?'+'skip=0&limit=' + pagination.pageSize).then((res) => {
this.setState({tbkls:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total},info:{quan:'',good:''}})
console.dir(res.result);
});
}
gettbkls(pagination){
console.dir(pagination);
this.setState({status:'pending'})
api('GET', 'tbkls?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize).then((res) => {
this.setState({tbkls:res.result,status:'ready'})
console.dir(res.result);
});
}
onChange(pagination) {
this.gettbkls(pagination);
}
componentWillMount(){
if(this.props.login && this.props.login.status == 'login')
location.href = '/manage'
const { dispatch } = this.props;
}
exportData(){
//json2xlsx(data,{sheetName:"基础数据", filename : '基础数据'+moment().format('YYYYMMDD')+'.xlsx'});
}
render(){
const columns = [
{
title: '淘口令',
dataIndex: 'info',
key: 'info',
width: 60,
render: text => <span href="#">{text}</span>,
},
{
title: '商品信息',
dataIndex: 'good',
key: 'good',
width: 100,
render: text => <span href="#">{text}</span>,
},
{
title: '推广连接',
dataIndex: 'target',
key: 'target',
width: 100,
render: text => <span href="#">{text}</span>,
},
{
title: '所属计划',
dataIndex: 'schedule',
key: 'schedule',
width: 100,
render: text => <span href="#">{text}</span>,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 40,
render: text => <span href="#">{text}</span>,
},
{
title: '创建日期',
dataIndex: 'create',
key: 'create',
width: 50,
render: text => <span href="#">{text}</span>,
}
];
let data = [];
let tbkls = this.state.tbkls;
for(let i = 0;i<tbkls.length;i++){
data.push({
key:i,
info:tbkls[i].info ,
good:(tbkls[i].link && tbkls[i].link['title']) || '--',
schedule:tbkls[i].schedule,
target:(tbkls[i].link && tbkls[i].link['target']) || '--',
status:tbkls[i].status == 'use' ? '进行中' : '已失效',
create:tbkls[i].createdAt
});
}
return (
<div>tbkl</div>
)
<div>
<Alert
message="提示"
description="淘口令油后台任务自动生成"
type="info"
/>
<Spin spinning= { this.state.status == 'pending' }>
<Table columns={columns} dataSource = { data } size="middle" pagination={ this.state.pagination } onChange = { this.onChange.bind(this)} bordered/>
</Spin>
</div>
)
}
}
module.exports = Tbkls;
module.exports = Tbkl;
\ No newline at end of file
......@@ -57,11 +57,18 @@ class DashBoard extends React.Component{
render: text => <a href="#">{text}</a>,
},
{
title: '渠道',
title: '推广计划',
dataIndex: 'qd',
key: 'qd',
width: 100,
render: text => <a href="#">{text}</a>,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: text => <a href="#">{text}</a>,
},{
title: '最近更新',
dataIndex: 'update',
......@@ -86,7 +93,8 @@ class DashBoard extends React.Component{
date:logs[i].date,
info:logs[i].key,
times:logs[i].times,
qd:(logs[i].qd && logs[i].qd['user']) || '--',
status:logs[i].status == 'disable' ? '已归档' :'--',
qd:(logs[i].schedule) || '--',
update:logs[i].updatedAt
});
}
......
......@@ -8,16 +8,21 @@ const schema = mongoose.Schema({
},
creater:{
type:ObjectId,
required: true,
required: false,
ref:'tao-agent'
},
schedule:{
type:ObjectId,
required: true,
ref:'tao-schedule'
},
status:{
type: String,
required: true
},
good:{
link:{
type:ObjectId,
required: false,
required: true,
ref:'tao-link'
}
}, {
......
......@@ -6,15 +6,24 @@ const schema = mongoose.Schema({
type: String,
required: true
},
qd:{
schedule:{
type:ObjectId,
required: true,
ref:'tao-agent'
ref:'tao-schedule'
},
link: {
type:ObjectId,
required: true,
ref:'tao-link'
},
times:{
type:Number,
required: true
},
status:{
type:String,
required: false
},
date:{
type:String,
required: true
......
......@@ -2,11 +2,7 @@ const mongoose = require('mongoose');
const {ObjectId} = mongoose.SchemaTypes;
const schema = mongoose.Schema({
taolink:{
type:ObjectId,
required: true,
ref:'tao-link'
},
links:[{type: ObjectId, ref: 'tao-link'}],
qd:{
type:ObjectId,
required: true,
......
......@@ -72,9 +72,9 @@ exports.logs = async (req, res, next) => {
}
exports.getTbkls = async (req, res, next) => {
let {limit = 1000,skip = 0,sort = {'updatedAt': -1}} = req.query;
let {limit = 100,skip = 0,sort = {'updatedAt': -1}} = req.query;
let options = {limit:parseInt(limit),skip:parseInt(skip),sort};
let tbkls = await Kouling.find({},null,options).populate('creater','user role').populate('good','title quan pid good');
let tbkls = await Kouling.find({},null,options).populate('link','title target');
let total = await Kouling.count({},null);
res.send({ status:'ok',result:tbkls,pagination:{total:total,skip:skip,limit:limit}});
}
......@@ -121,56 +121,58 @@ exports.createLink = async (req, res, next) => {
exports.getSchedules = async (req, res, next) => {
let {limit = 100,skip = 0,sort = {'updatedAt': -1}} = req.query;
let options = {limit:parseInt(limit),skip:parseInt(skip),sort};
let schedules = await Schedule.find({},null,options).populate('qd','user role').populate('taolink','name title target');
let schedules = await Schedule.find({},null,options).populate('links','name title target');
let total = await Schedule.count({},null);
res.send({ status:'ok',result:schedules,pagination:{total:total,skip:skip,limit:limit}});
}
exports.createSchedule = async (req, res, next) => {
let {user,times,status='use',name} = req.body;
let {user,times,status='use',names} = req.body;
var links = [];
try{
if(!user || !times || !name)
if(!user || !times || !names)
res.status(400).send(not_full);
else{
var agent = await Agent.findOne({user:user});
var link = await Link.findOne({name:name});
if(agent && link){
names = names.split("@");
names.forEach(async item => {
links.push(Link.findOne({name:item}));
});
Promise.all(links).then(function(arr){
let ids = arr.map(x => x.toJSON()._id);
if(agent && ids.length){
let qd = agent.toJSON()['_id'];
let taolink = link.toJSON()['_id'];
tao.saveSchedule({qd,taolink,status,times},function(e,result){
let links = ids;
tao.saveSchedule({qd,links,status,times},function(e,result){
if(e) throw e;
res.send({status:'ok',result:result});
});
}
else{
res.status(400).send(not_right);
}
}
else{
res.status(400).send(not_right);
}
});
}
}catch(e){
console.dir(e);
res.status(400).send(not_right);
}
}
exports.createTbkl = async (req, res, next) => {
/*let {quan,pid,good,title,qd} = req.body;
let quanQuery = urlArgs(url.parse(quan).query);
let goodQuery = urlArgs(url.parse(good).query);
//console.dir(quanQuery);
try {
if(!pid || !quanQuery['activityId'] || !goodQuery['id'])
res.status(400).send(not_full);
else{
let urlTarget = 'https://uland.taobao.com/coupon/edetail?activityId='+ quanQuery['activityId']+'&itemId='+goodQuery['id']+'&pid='+pid;
let goodInfo = await tao.getGood(goodQuery['id']);
let tbklInfo = await tao.createTbkl(goodInfo['title'],urlTarget);
let model = tbklInfo.model;
//console.dir(title);
console.dir(tbkl);
}
}catch(e){
res.status(400).send(e);
}*/
//res.send({ status:'ok',result:{} });
exports.createTbkl = async (data) => {
let {title,target,pic} = data;
return new Promise(async (r,d) => {
try {
let tbklInfo = await tao.createTbkl(title,target,pic);
let model = tbklInfo.model;
let _data = { info:model,schedule:data.schedule,link:data.link,status:'use' };
tao.saveKouling(_data,function(e,result){
if(e) d(e);
else r(result);
});
}catch(e){
d(e);
}
});
}
// const cron = require('cron');
// const UserAuth = require('../db/mongo/user-auto-auth');
// const UserAuthLog = require('../db/mongo/user-auto-used-log');
// const nodemailer = require('nodemailer');
// const _ = require('lodash');
// const moment = require('moment');
const cron = require('cron');
const nodemailer = require('nodemailer');
const Schedule = require('../db/mongo/tao-schedule');
const Kouling = require('../db/mongo/tao-kouling');
const Log = require('../db/mongo/tao-log');
const tao = require('./tao');
const _ = require('lodash');
const moment = require('moment');
const controller = require('./controller');
const max = 20000;
var CronJob = cron.CronJob;
var job = new CronJob({
cronTime: '* */1 * * *',
onTick: function() {
tbklTask();
},
start: false,
});
// var CronJob = cron.CronJob;
// var job = new CronJob({
// cronTime: '00 00 00 * * 0-6',
// onTick: function() {
// clearUserAuths();
// },
// start: false,
// });
async function sendMail(email,body) {
var smtpTransport = nodemailer.createTransport({
auth: {
user: "liusong@goyoo.com",
pass: "323609zhang"
},
host: 'smtp.exmail.qq.com',
port: 465
});
var mailOptions = {
from: "liusong@goyoo.com",
to: email, //发给谁
subject: '淘口令后台定时任务错误', //主题
text: body
};
smtpTransport.sendMail(mailOptions, function (err, response) {
if (!err) {
console.log('发送邮件成功');
} else {
console.log('发送邮件失败,请重试');
}
});
}
async function tbklTask () {
console.log('定时更新开始 =====> ');
try {
console.log('=====> ');
//let tkls = await Kouling.find({status:'use'}).populate('link','title target').limit(1000);
// 查询进行中计划
let schedules = await Schedule.find({status:'use'}).limit(500);
schedules.forEach( async item => {
let schedule = item.toJSON()._id;
// console.dir(schedule);
// 查询计划内 超过20000 请求 淘口令
//console.dir({times:{$gte:10},status:'use',schedule:schedule});
let logs = await Log.find({times:{$gte:max},schedule:schedule,status:{$ne:'disable'}}).populate('link','title target pic').limit(1000);
//console.dir(logs.length);
var tasks_new = [];
var tasks_old = [];
var tasks_log = [];
logs.forEach( item => {
item = item.toJSON();
//console.dir(item);
if(item.link && item.link.title && item.link.target && item.times >= max){
var data = {
title:item.link.title,
target:item.link.target,
schedule:item.schedule,
link:item.link,
status:'use',
pic:item.link.pic
}
tasks_new.push(controller.createTbkl(data));
tasks_old.push(Kouling.update({info:item.key},{$set:{status:'disable'}}));
tasks_log.push(Log.update({key:item.key},{$set:{status:'disable'}}));
}
});
if(tasks_new.length&&tasks_old.length&&tasks_log.length){
Promise.all(tasks_new).then(function(arr){
console.log('增加老口令 结束 影响' + arr.length + '条数据');
});
Promise.all(tasks_old).then(function(arr){
console.log('删除老口令 结束 影响' + arr.length + '条数据');
});
Promise.all(tasks_log).then(function(arr){
console.log('更新log数据 影响' + arr.length + '条数据');
});
}
else{
console.log('没有任务 影响0条数据');
}
});
} catch (err) {
console.dir(err);
console.dir('更新异常 =====>');
let mailList = 'liusong@goyoo.com';
sendMail(mailList, err.toString());
}
console.log(' 更新结束 ');
}
// async function sendMail(email,body) {
// var smtpTransport = nodemailer.createTransport({
// auth: {
// user: "liusong@goyoo.com",
// pass: "323609zhang"
// },
// host: 'smtp.exmail.qq.com',
// port: 465
// });
// var mailOptions = {
// from: "liusong@goyoo.com",
// to: email, //发给谁
// subject: '小云蜂巢定时任务错误', //主题
// text: body
// };
// smtpTransport.sendMail(mailOptions, function (err, response) {
// if (!err) {
// console.log('发送邮件成功');
// } else {
// console.log('发送邮件失败,请重试');
// }
// });
// }
// async function clearUserAuths () {
// console.log('定时更新开始 =====> ');
// try {
// let userAuths = await UserAuth.find({}).limit(500);
// userAuths.forEach( async item => {
// let log = item.toJSON();
// if(moment(log['updatedAt']).format('YYYYMMDD') !== moment().format('YYYYMMDD')){
// let auth = new UserAuthLog(_.omit(log, ['_id', 'createdAt', 'updatedAt']));
// await auth.save();
// }else{
// console.log('skip job');
// }
// });
// let data = {
// '$set':{
// used: 0
// }
// };
// await UserAuth.update({}, data, {multi:true});
// } catch (err) {
// console.dir(err);
// console.dir('更新异常 =====>');
// let mailList = 'liusong@goyoo.com';
// sendMail(mailList, err.toString());
// }
// console.log(' 更新结束 ');
// }
// module.exports.start = function ()
// {
// job.start();
// };
module.exports.start = function ()
{
job.start();
};
......@@ -82,11 +82,15 @@ exports.getGood = (id) => {
});
}
exports.createTbkl = (title,url) => {
exports.createTbkl = (title,url,pic) => {
console.dir(title);
console.dir(url)
console.dir(pic)
return new Promise((r,d) => {
client.execute('taobao.tbk.tpwd.create', {
'text':title,
'url':'https://uland.taobao.com/coupon/edetail?activityId=32fd90b87b9a418bb92d7c8cab52423a&itemId=527016966632&pid=mm_33320967_40070156_150834845&src=czhk_cztkl&ut_sk=1.utdid_null_1511245305902.TaoPassword-Outside.taoketop'
'url':url,
'logo':pic
}, function(error, response) {
if (response && response.data && !error) r(response.data);
else d(error);
......
const mongoose = require('mongoose');
const {ObjectId} = mongoose.SchemaTypes;
const schema = mongoose.Schema({
page:{
type:ObjectId,
required: true,
ref:'tao-link'
},
qd:{
type:ObjectId,
required: true,
ref:'tao-agent'
},
status:{
type: String,
required: true
},
times:{
type:Number,
required: true
}
}, {
timestamps: true
});
schema.index({info: 1});
module.exports = mongoose.model('tao-schedule', schema);
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