Commit 6383932d authored by 刘松's avatar 刘松

fix

parent 8e13891a
FROM node:latest
FROM hub.c.163.com/library/node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN \
rm /etc/localtime && \
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN npm install --production --registry=https://registry.npm.taobao.org
# RUN npm install yarn --registry=https://registry.npm.taobao.org
# RUN yarn config set registry https://registry.npm.taobao.org
......
......@@ -58,7 +58,6 @@ app.use(async function(req,res,next){
else res.redirect('/');
});
app.get('/', function (req, res){
console.dir('login');
res.sendFile(path.resolve(__dirname, 'app', 'index.html'))
});
app.get('/manage', function (req, res){
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -103,7 +103,7 @@ div.ant-row .ant-col-6:nth-of-type(4) .box h3{
text-align: center;
}
.detail-body{
.detail-body,.detail-b-body{
margin-bottom: 3px;
}
.detail-body-list{
......@@ -112,6 +112,11 @@ div.ant-row .ant-col-6:nth-of-type(4) .box h3{
.detail-body span{
width: 33.3%;
display: inline-block;
overflow: hidden;
}
.detail-body span:nth-of-type(1){
text-overflow: ellipsis;
overflow: hidden;
}
.detail-body-list{
margin-bottom: 3px;
......
......@@ -4,7 +4,7 @@ const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, Alert, Row, Col, Spin, Button,Modal,Form,Input,Switch,message,Select,DatePicker} from 'antd';
import { Table, Icon, Alert, Row, Col, Spin, Button,Modal,Form,Input,Switch,message,Select,DatePicker,Radio} from 'antd';
const { RangePicker } = DatePicker;
const Option = Select.Option;
const FormItem = Form.Item;
......@@ -13,7 +13,7 @@ class Schedule extends React.Component{
constructor(props){
super(props);
this.state= { currentQd:'all',qds:[],schedules :[],status:'pending',pagination:{current:1,pageSize:10,total:1},modalVisible:false,username:'channel'};
this.state= { currentQd:'all',qds:[],schedules :[],status:'pending',pagination:{current:1,pageSize:10,total:1},modalVisible:false,username:'channel', sort:'createdAt'};
}
componentDidMount(){
let pagination = this.state.pagination;
......@@ -29,26 +29,43 @@ class Schedule extends React.Component{
});
}
getschedules(pagination,qd){
getschedules(pagination,qd,sort){
console.dir(pagination);
this.setState({status:'pending'});
var url = 'schedules?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize;
if(qd && qd !== 'all')
url += ('&qd='+ qd);
if(sort)
url += ('&sort='+ sort);
api('GET', url).then((res) => {
this.setState({schedules:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}})
console.dir(res.result);
});
}
handleSort(e){
this.setState({sort:e.target.value});
this.getschedules({current:1,pageSize:this.state.pagination.pageSize},this.state.currentQd,e.target.value);
}
onChange(pagination) {
this.getschedules(pagination,this.state.currentQd);
this.getschedules(pagination,this.state.currentQd,this.state.sort);
}
createSchedule(){
this.setModalVisible(true);
}
tendFinal(schedule,data) {
var scheduleID = schedule.id;
var final = data.valueOf();
api('GET', 'schedule/final?final='+ final + '&scheduleID='+scheduleID).then((res) => {
message.success('修改成功,刷新查看');
}).catch((data) =>{
message.error(data.responseText);
});
}
setModalVisible(b){
this.setState({modalVisible:b});
}
......@@ -129,21 +146,21 @@ class Schedule extends React.Component{
title: '计划ID',
dataIndex: 'id',
key: 'id',
width: 100,
width: 50,
render: text => <span href="#">{text}</span>,
},
{
title: '分发ID/渠道',
dataIndex: 'qd',
key: 'qd',
width: 100,
width: 70,
render: text => <span href="#">{text}</span>,
},
{
title: '推广页名称',
dataIndex: 'names',
key: 'names',
width: 100,
width: 50,
render: text => <span href="#">{text}</span>,
},
{
......@@ -167,12 +184,13 @@ class Schedule extends React.Component{
width: 75,
render: text => <span href="#">{text}</span>,
},{
title: '投放状态 / 手动替换 / 定时更新 ',
title: '投放状态 / 手动替换 / 定时更新 / 延长投放 ',
dataIndex: 'status',
key: 'status',
width: 130,
width: 230,
render: (data,schedule) => <div><Switch checked={ data.status == 'use' ? true : false } onChange={this.checkUpdate.bind(this,schedule)} style = {{'marginRight': '10px'}}/><Button onClick = {this.tklUpdate.bind(this,schedule)} style = {{'marginRight': '10px'}}>生成淘口令</Button>
<Switch checked={ data.auto == 'use' ? true : false } onChange={this.autoUpdate.bind(this,schedule)} style = {{'marginRight': '17px'}}/></div>,
<Switch checked={ data.auto == 'use' ? true : false } onChange={this.autoUpdate.bind(this,schedule)} style = {{'marginRight': '17px'}}/>
<DatePicker showTime onOk={ this.tendFinal.bind(this,schedule) } format="YYYY-MM-DD HH:mm:ss" /></div>,
}
];
let children = [<Option key='all'>全部</Option>];
......@@ -213,6 +231,10 @@ class Schedule extends React.Component{
>
{children}
</Select>
<Radio.Group value = { this.state.sort } onChange={this.handleSort.bind(this)} style={{ float:'right', "margin":'10px' }}>
<Radio.Button value="createdAt">按时间</Radio.Button>
<Radio.Button value="status">按状态</Radio.Button>
</Radio.Group>
<Spin spinning= { this.state.status == 'pending' }>
<Table columns={columns} dataSource = { data } size="middle" pagination={ this.state.pagination } onChange = { this.onChange.bind(this)} bordered/>
</Spin>
......
......@@ -4,8 +4,9 @@ const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Modal,Form,Input,Radio} from 'antd';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Modal,Form,Input,Radio,message} from 'antd';
const RadioGroup = Radio.Group;
const Search = Input.Search;
const { RangePicker } = DatePicker;
const FormItem = Form.Item;
......@@ -14,7 +15,7 @@ class Agent extends React.Component{
constructor(props){
super(props);
console.dir(this.props);
this.state= { links :[],status:'pending',pagination:{current:1,pageSize:500,total:1},modalVisible:false,username:'channel',target:'target'};
this.state= { links :[],status:'pending',pagination:{current:1,pageSize:200,total:0},modalVisible:false,username:'channel',target:'target',keyword:''};
}
componentDidMount(){
let pagination = this.state.pagination;
......@@ -28,27 +29,40 @@ class Agent extends React.Component{
});
}
getLinks(pagination){
console.dir(pagination);
getLinks(pagination,keyword){
this.setState({status:'pending'})
api('GET', 'links?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize).then((res) => {
keyword = keyword || '';
api('GET', 'links?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize + '&keyword=' + keyword).then((res) => {
this.setState({links:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}})
console.dir(res.result);
});
}
onChange(pagination) {
this.getLinks(pagination);
this.getLinks(pagination,this.state.keyword);
}
createLink(){
this.setModalVisible(true);
}
delete(data) {
api('GET', 'link/del/'+ data.key).then((res) => {
message.success('删除成功');
}).catch((data) => {
message.error(data.responseText);
});
}
setModalVisible(b){
this.setState({modalVisible:b});
}
search(value) {
this.setState({ keyword:value });
this.getLinks({ current:1,pageSize:this.state.pagination.pageSize }, value);
}
handleSubmit(e){
e.preventDefault();
var self = this;
......@@ -58,10 +72,11 @@ class Agent extends React.Component{
if(values[k]) values[k] = values[k].trim();
}
values['select'] = this.state.target;
console.dir(values);
api('POST', 'link',values).then((res) => {
if(res && res.result){
self.setModalVisible(false);
self.getLinks({limit:this.state.pagination.pageSize,skip:0});
self.getLinks({limit:this.state.pagination.pageSize,skip:0},this.state.keyword);
}
});
}
......@@ -141,13 +156,24 @@ class Agent extends React.Component{
key: 'create',
width: 100,
render: text => <span href="#">{text}</span>,
},
{
title: '操作',
dataIndex: 'delete',
key: 'delete',
width: 10,
render: (text,data) =><div>
<Button type="primary" onClick={ this.delete.bind(this,data) } style = {{ marginLeft:'10px' }}>
删除
</Button>
</div>
}
];
let data = [];
let links = this.state.links;
for(let i = 0;i<links.length;i++){
data.push({
key:i,
key:links[i]._id,
name:links[i].name,
quan:links[i].quan,
slogan:links[i].title,
......@@ -164,6 +190,12 @@ class Agent extends React.Component{
<Button type="primary" icon="plus" onClick={ this.createLink.bind(this) } style={{ margin:'10px 0px'}}>
创建推广页
</Button>
<Search
placeholder="搜索推广页"
onSearch={ this.search.bind(this) }
style={{ width: 200, float:'right' }}
/>
<Spin spinning= { this.state.status == 'pending' }>
<Table columns={columns} dataSource = { data } size="middle" pagination={ this.state.pagination } onChange = { this.onChange.bind(this)} bordered/>
</Spin>
......@@ -182,6 +214,7 @@ class Agent extends React.Component{
<Radio.Button value="target">二合一链接</Radio.Button>
<Radio.Button value="quan">优惠券链接</Radio.Button>
<Radio.Button value="good">商品链接</Radio.Button>
<Radio.Button value="notbk">推广链接(非淘宝客)</Radio.Button>
</Radio.Group>
</FormItem>
<FormItem>
......@@ -192,7 +225,7 @@ class Agent extends React.Component{
)}
</FormItem>
{
this.state.target == 'good' ? <div></div> : <FormItem>
this.state.target == 'good' || this.state.target == 'notbk' ? <div></div> : <FormItem>
{getFieldDecorator('quan', {
rules: [{ required: true, message: '优惠券链接不能为空' }],
})(
......@@ -200,6 +233,24 @@ class Agent extends React.Component{
)}
</FormItem>
}
{
this.state.target == 'good' ? <FormItem>
{getFieldDecorator('good_id', {
rules: [{ required: true, message: 'id不能为空' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>商品ID</span>} placeholder="例如:2194810505" />
)}
</FormItem> : <div></div>
}
{
this.state.target == 'notbk' ? <FormItem>
{getFieldDecorator('pic', {
rules: [{ required: true, message: '图片链接不能为空' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>图片链接</span>} placeholder="例如:..." />
)}
</FormItem> : <div></div>
}
<FormItem>
{getFieldDecorator('good', {
rules: [{ required: true, message: '商品连接不能为空' }],
......@@ -208,7 +259,7 @@ class Agent extends React.Component{
)}
</FormItem>
{
this.state.target == 'good' ? <div></div> : <FormItem>
this.state.target == 'good' || this.state.target == 'notbk' ? <div></div> : <FormItem>
{getFieldDecorator('pid', {
rules: [{ required: true, message: 'pid不能为空' }],
})(
......
This diff is collapsed.
......@@ -4,8 +4,8 @@ module.exports = {
mongo:'mongodb://user:password@mongo-gp-content-distribution-1.localhost:1302,mongo-gp-content-distribution-2.localhost:1302,mongo-gp-content-distribution-3.localhost:1302/taoarticle?replicaSet=gp-content-aiweibang',
taobao: {
host:"http://gw.api.taobao.com/router/rest",
appKey:"23390725",
appSecret:'0575587ba36b29fa5680ad571c5e51f4'
appKey:"24594025",
appSecret:'def2396c763580d49e4a0aa15c4c18bd'
//appKey:"24594025",//"23580470",//"23390725",
//appSecret:'def2396c763580d49e4a0aa15c4c18bd'//"e5f350cbdbd6db2a8727f0b65dac1f7c",//"0575587ba36b29fa5680ad571c5e51f4"
}
......
......@@ -24,6 +24,10 @@ const schema = mongoose.Schema({
type:Number,
required: true
},
click_times:{
type:Number,
required: false
},
dc_times:{
type:Number,
required: false
......
......@@ -19,6 +19,10 @@ const schema = mongoose.Schema({
type: String,
required: false
},
id:{
type: String,
required: false
},
title:{
type: String,
required: true
......@@ -39,6 +43,10 @@ const schema = mongoose.Schema({
status:{
type:String,
required:false
},
removed:{
type:String,
required:false
}
}, {
timestamps: true
......
This diff is collapsed.
......@@ -55,13 +55,14 @@ async function tbklTask () {
var tasks_schedule_koulings = [];
if(item.final && item.final < moment().format('x')){
console.dir(schedule + '过期')
tasks_schedules.push(Kouling.update({status:'use',schedule:schedule},{$set:{status:'disable'}},{multi:true}));
tasks_schedule_koulings.push(Schedule.update({_id:schedule},{$set:{status:"disable"}},{multi:true}));
}
// 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);
let logs = await Log.find({times:{$gte:max},schedule:schedule,status:{$ne:'disable'}}).populate('link','title target pic id pid').limit(1000);
var tasks_new = [];
var tasks_old = [];
var tasks_log = [];
......@@ -76,7 +77,9 @@ async function tbklTask () {
link:item.link,
status:'use',
qd:qd,
pic:item.link.pic
id:item.link.id,
pic:item.link.pic,
pid:item.link.pid,
}
tasks_new.push(controller.createTbkl(data));
tasks_old.push(Kouling.update({info:item.key,status:{$ne:'disable'}},{$set:{status:'disable'}},{multi:true}));
......
......@@ -57,7 +57,7 @@ async function tbklTask () {
// 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);
let logs = await Log.find({times:{$gte:max},schedule:schedule,status:{$ne:'disable'}}).populate('link','title target pic id').limit(1000);
var tasks_new = [];
var tasks_old = [];
if(auto == 'use'){
......@@ -69,6 +69,7 @@ async function tbklTask () {
link:_item._id,
status:'use',
qd:qd,
id:_item.id,
pic:_item.pic
}
for(var i = 0;i<10; i++){
......
......@@ -3,6 +3,7 @@ const nodemailer = require('nodemailer');
const Schedule = require('../db/mongo/tao-schedule');
const Data = require('../db/mongo/tao-data');
const Log = require('../db/mongo/tao-log');
const Click = require('../db/mongo/tao-log-click');
const _ = require('lodash');
const moment = require('moment');
const controller = require('./controller');
......@@ -56,6 +57,26 @@ async function tbklTask () {
}
}
]);
var clicks = await Click.aggregate([
{
$match:{
"date": date
}
},
{
$group:{
_id: "$qd",
sum:{ $sum:"$times" }
}
}
]);
var qd2clicks = {};
clicks.forEach( async item => {
//schedule = schedule.toJSON();
//var schedule = _tasks.push(Schedule.findById(item._id));
qd2clicks[item._id] = item.sum;
console.dir(item);
});
var qd2schedule = {};
var sum2schedule = {};
......@@ -90,7 +111,7 @@ async function tbklTask () {
}
//var total = qd2schedule[k].reduce(function(a,b){ return a.times + b.times},{times:0});
//console.dir({qd:qd,schedules:qd2schedule[k],date:logDate,times:total});
var data = new Data({qd:qd,schedules:qd2schedule[k],date:logDate,times:total});
var data = new Data({qd:qd,schedules:qd2schedule[k],date:logDate,times:total,click_times:qd2clicks[qd]});
tasks.push(data.save());
}
Promise.all(tasks).then(function(arr){
......
......@@ -19,6 +19,7 @@ router.post('/qd',controller.createQd);
router.post('/newtkl',controller.newTbkl);
router.post('/link',controller.createLink);
router.get('/link/del/:link',controller.removeLink);
router.post('/put_data',controller.putGatherData);
......@@ -32,6 +33,7 @@ router.post('/tool2_tbkls',controller.admin2Tbkl);
router.get('/schedules',controller.getSchedules);
router.post('/schedule',controller.createSchedule);
router.get('/schedule/final',controller.updateScheduleFinal)
router.post('/schedule_update',controller.updateSchedule);
router.post('/schedule_auto_update',controller.updateAutoSchedule);
router.get('/gathers/qd',controller.getQdGatherData);
......
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