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 diff is collapsed.
This diff is collapsed.
......@@ -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