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 RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY package.json /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 --production --registry=https://registry.npm.taobao.org
# RUN npm install yarn --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 # RUN yarn config set registry https://registry.npm.taobao.org
......
...@@ -58,7 +58,6 @@ app.use(async function(req,res,next){ ...@@ -58,7 +58,6 @@ app.use(async function(req,res,next){
else res.redirect('/'); else res.redirect('/');
}); });
app.get('/', function (req, res){ app.get('/', function (req, res){
console.dir('login');
res.sendFile(path.resolve(__dirname, 'app', 'index.html')) res.sendFile(path.resolve(__dirname, 'app', 'index.html'))
}); });
app.get('/manage', function (req, res){ app.get('/manage', function (req, res){
......
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.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -103,7 +103,7 @@ div.ant-row .ant-col-6:nth-of-type(4) .box h3{ ...@@ -103,7 +103,7 @@ div.ant-row .ant-col-6:nth-of-type(4) .box h3{
text-align: center; text-align: center;
} }
.detail-body{ .detail-body,.detail-b-body{
margin-bottom: 3px; margin-bottom: 3px;
} }
.detail-body-list{ .detail-body-list{
...@@ -112,6 +112,11 @@ div.ant-row .ant-col-6:nth-of-type(4) .box h3{ ...@@ -112,6 +112,11 @@ div.ant-row .ant-col-6:nth-of-type(4) .box h3{
.detail-body span{ .detail-body span{
width: 33.3%; width: 33.3%;
display: inline-block; display: inline-block;
overflow: hidden;
}
.detail-body span:nth-of-type(1){
text-overflow: ellipsis;
overflow: hidden;
} }
.detail-body-list{ .detail-body-list{
margin-bottom: 3px; margin-bottom: 3px;
......
...@@ -4,7 +4,7 @@ const api = require('../../js/api'); ...@@ -4,7 +4,7 @@ const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx'; 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 { RangePicker } = DatePicker;
const Option = Select.Option; const Option = Select.Option;
const FormItem = Form.Item; const FormItem = Form.Item;
...@@ -13,7 +13,7 @@ class Schedule extends React.Component{ ...@@ -13,7 +13,7 @@ class Schedule extends React.Component{
constructor(props){ constructor(props){
super(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(){ componentDidMount(){
let pagination = this.state.pagination; let pagination = this.state.pagination;
...@@ -29,26 +29,43 @@ class Schedule extends React.Component{ ...@@ -29,26 +29,43 @@ class Schedule extends React.Component{
}); });
} }
getschedules(pagination,qd){ getschedules(pagination,qd,sort){
console.dir(pagination); console.dir(pagination);
this.setState({status:'pending'}); this.setState({status:'pending'});
var url = 'schedules?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize; var url = 'schedules?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize;
if(qd && qd !== 'all') if(qd && qd !== 'all')
url += ('&qd='+ qd); url += ('&qd='+ qd);
if(sort)
url += ('&sort='+ sort);
api('GET', url).then((res) => { 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}}) this.setState({schedules:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}})
console.dir(res.result); 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) { onChange(pagination) {
this.getschedules(pagination,this.state.currentQd); this.getschedules(pagination,this.state.currentQd,this.state.sort);
} }
createSchedule(){ createSchedule(){
this.setModalVisible(true); 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){ setModalVisible(b){
this.setState({modalVisible:b}); this.setState({modalVisible:b});
} }
...@@ -129,21 +146,21 @@ class Schedule extends React.Component{ ...@@ -129,21 +146,21 @@ class Schedule extends React.Component{
title: '计划ID', title: '计划ID',
dataIndex: 'id', dataIndex: 'id',
key: 'id', key: 'id',
width: 100, width: 50,
render: text => <span href="#">{text}</span>, render: text => <span href="#">{text}</span>,
}, },
{ {
title: '分发ID/渠道', title: '分发ID/渠道',
dataIndex: 'qd', dataIndex: 'qd',
key: 'qd', key: 'qd',
width: 100, width: 70,
render: text => <span href="#">{text}</span>, render: text => <span href="#">{text}</span>,
}, },
{ {
title: '推广页名称', title: '推广页名称',
dataIndex: 'names', dataIndex: 'names',
key: 'names', key: 'names',
width: 100, width: 50,
render: text => <span href="#">{text}</span>, render: text => <span href="#">{text}</span>,
}, },
{ {
...@@ -167,12 +184,13 @@ class Schedule extends React.Component{ ...@@ -167,12 +184,13 @@ class Schedule extends React.Component{
width: 75, width: 75,
render: text => <span href="#">{text}</span>, render: text => <span href="#">{text}</span>,
},{ },{
title: '投放状态 / 手动替换 / 定时更新 ', title: '投放状态 / 手动替换 / 定时更新 / 延长投放 ',
dataIndex: 'status', dataIndex: 'status',
key: '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> 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>]; let children = [<Option key='all'>全部</Option>];
...@@ -213,6 +231,10 @@ class Schedule extends React.Component{ ...@@ -213,6 +231,10 @@ class Schedule extends React.Component{
> >
{children} {children}
</Select> </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' }> <Spin spinning= { this.state.status == 'pending' }>
<Table columns={columns} dataSource = { data } size="middle" pagination={ this.state.pagination } onChange = { this.onChange.bind(this)} bordered/> <Table columns={columns} dataSource = { data } size="middle" pagination={ this.state.pagination } onChange = { this.onChange.bind(this)} bordered/>
</Spin> </Spin>
......
...@@ -4,8 +4,9 @@ const api = require('../../js/api'); ...@@ -4,8 +4,9 @@ const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx'; 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 RadioGroup = Radio.Group;
const Search = Input.Search;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const FormItem = Form.Item; const FormItem = Form.Item;
...@@ -14,7 +15,7 @@ class Agent extends React.Component{ ...@@ -14,7 +15,7 @@ class Agent extends React.Component{
constructor(props){ constructor(props){
super(props); super(props);
console.dir(this.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(){ componentDidMount(){
let pagination = this.state.pagination; let pagination = this.state.pagination;
...@@ -28,27 +29,40 @@ class Agent extends React.Component{ ...@@ -28,27 +29,40 @@ class Agent extends React.Component{
}); });
} }
getLinks(pagination){ getLinks(pagination,keyword){
console.dir(pagination);
this.setState({status:'pending'}) 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}}) this.setState({links:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}})
console.dir(res.result); console.dir(res.result);
}); });
} }
onChange(pagination) { onChange(pagination) {
this.getLinks(pagination); this.getLinks(pagination,this.state.keyword);
} }
createLink(){ createLink(){
this.setModalVisible(true); this.setModalVisible(true);
} }
delete(data) {
api('GET', 'link/del/'+ data.key).then((res) => {
message.success('删除成功');
}).catch((data) => {
message.error(data.responseText);
});
}
setModalVisible(b){ setModalVisible(b){
this.setState({modalVisible:b}); this.setState({modalVisible:b});
} }
search(value) {
this.setState({ keyword:value });
this.getLinks({ current:1,pageSize:this.state.pagination.pageSize }, value);
}
handleSubmit(e){ handleSubmit(e){
e.preventDefault(); e.preventDefault();
var self = this; var self = this;
...@@ -58,10 +72,11 @@ class Agent extends React.Component{ ...@@ -58,10 +72,11 @@ class Agent extends React.Component{
if(values[k]) values[k] = values[k].trim(); if(values[k]) values[k] = values[k].trim();
} }
values['select'] = this.state.target; values['select'] = this.state.target;
console.dir(values);
api('POST', 'link',values).then((res) => { api('POST', 'link',values).then((res) => {
if(res && res.result){ if(res && res.result){
self.setModalVisible(false); 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{ ...@@ -141,13 +156,24 @@ class Agent extends React.Component{
key: 'create', key: 'create',
width: 100, width: 100,
render: text => <span href="#">{text}</span>, 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 data = [];
let links = this.state.links; let links = this.state.links;
for(let i = 0;i<links.length;i++){ for(let i = 0;i<links.length;i++){
data.push({ data.push({
key:i, key:links[i]._id,
name:links[i].name, name:links[i].name,
quan:links[i].quan, quan:links[i].quan,
slogan:links[i].title, slogan:links[i].title,
...@@ -164,6 +190,12 @@ class Agent extends React.Component{ ...@@ -164,6 +190,12 @@ class Agent extends React.Component{
<Button type="primary" icon="plus" onClick={ this.createLink.bind(this) } style={{ margin:'10px 0px'}}> <Button type="primary" icon="plus" onClick={ this.createLink.bind(this) } style={{ margin:'10px 0px'}}>
创建推广页 创建推广页
</Button> </Button>
<Search
placeholder="搜索推广页"
onSearch={ this.search.bind(this) }
style={{ width: 200, float:'right' }}
/>
<Spin spinning= { this.state.status == 'pending' }> <Spin spinning= { this.state.status == 'pending' }>
<Table columns={columns} dataSource = { data } size="middle" pagination={ this.state.pagination } onChange = { this.onChange.bind(this)} bordered/> <Table columns={columns} dataSource = { data } size="middle" pagination={ this.state.pagination } onChange = { this.onChange.bind(this)} bordered/>
</Spin> </Spin>
...@@ -182,6 +214,7 @@ class Agent extends React.Component{ ...@@ -182,6 +214,7 @@ class Agent extends React.Component{
<Radio.Button value="target">二合一链接</Radio.Button> <Radio.Button value="target">二合一链接</Radio.Button>
<Radio.Button value="quan">优惠券链接</Radio.Button> <Radio.Button value="quan">优惠券链接</Radio.Button>
<Radio.Button value="good">商品链接</Radio.Button> <Radio.Button value="good">商品链接</Radio.Button>
<Radio.Button value="notbk">推广链接(非淘宝客)</Radio.Button>
</Radio.Group> </Radio.Group>
</FormItem> </FormItem>
<FormItem> <FormItem>
...@@ -192,7 +225,7 @@ class Agent extends React.Component{ ...@@ -192,7 +225,7 @@ class Agent extends React.Component{
)} )}
</FormItem> </FormItem>
{ {
this.state.target == 'good' ? <div></div> : <FormItem> this.state.target == 'good' || this.state.target == 'notbk' ? <div></div> : <FormItem>
{getFieldDecorator('quan', { {getFieldDecorator('quan', {
rules: [{ required: true, message: '优惠券链接不能为空' }], rules: [{ required: true, message: '优惠券链接不能为空' }],
})( })(
...@@ -200,6 +233,24 @@ class Agent extends React.Component{ ...@@ -200,6 +233,24 @@ class Agent extends React.Component{
)} )}
</FormItem> </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> <FormItem>
{getFieldDecorator('good', { {getFieldDecorator('good', {
rules: [{ required: true, message: '商品连接不能为空' }], rules: [{ required: true, message: '商品连接不能为空' }],
...@@ -208,7 +259,7 @@ class Agent extends React.Component{ ...@@ -208,7 +259,7 @@ class Agent extends React.Component{
)} )}
</FormItem> </FormItem>
{ {
this.state.target == 'good' ? <div></div> : <FormItem> this.state.target == 'good' || this.state.target == 'notbk' ? <div></div> : <FormItem>
{getFieldDecorator('pid', { {getFieldDecorator('pid', {
rules: [{ required: true, message: 'pid不能为空' }], rules: [{ required: true, message: 'pid不能为空' }],
})( })(
......
...@@ -5,7 +5,7 @@ import ReactEcharts from "echarts-for-react"; ...@@ -5,7 +5,7 @@ import ReactEcharts from "echarts-for-react";
import json2xlsx from '../../js/json2xlsx'; import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Popover,Form,Input,Modal,InputNumber,message,Select,Tabs} from 'antd'; import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Popover,Form,Input,Modal,InputNumber,message,Select,Tabs,Tag} from 'antd';
const FormItem = Form.Item; const FormItem = Form.Item;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const TabPane = Tabs.TabPane; const TabPane = Tabs.TabPane;
...@@ -19,18 +19,16 @@ class Gather extends React.Component{ ...@@ -19,18 +19,16 @@ class Gather extends React.Component{
this.count = 51; this.count = 51;
this.dynamic = { sum:0,click:0 }; this.dynamic = { sum:0,click:0 };
this.range = [moment().subtract(14,'days').format('YYYYMMDD'), moment().format('YYYYMMDD')]; this.range = [moment().subtract(14,'days').format('YYYYMMDD'), moment().format('YYYYMMDD')];
this.state= { range:this.range,currentQd:'all',qds:[],qdgathers :[],status:'pending',pagination:{current:1,pageSize:20,total:100},username:'channel',tody:{ click_count:0,tkl_count:0,count:0,schedule_count:0} ,none_tkls:[],list:[],modalVisible:false,xAxis:[],series:[],loading:true,dynamicOption:this.getDynamicOption(),websocket:(("WebSocket" in window) || ('MozWebSocket' in window))}; this.state= { info:{request:0,dc:0,click:0},range:this.range,currentQdforcharts:'all',currentQd:'all',qds:[],qdgathers :[],status:'pending',pagination:{current:1,pageSize:20,total:100},username:'channel',tody:{ click_count:0,tkl_count:0,count:0,schedule_count:0} ,none_tkls:[],list:[],modalVisible:false,modaltodyVisible:false,xAxis:[],series:[],loading:true,dynamicOption:this.getDynamicOption(),websocket:(("WebSocket" in window) || ('MozWebSocket' in window))};
} }
fetchNewDate(date,_data0,_data1){ fetchNewDate(date,_data0,_data1){
let axisData = (date).toLocaleTimeString().replace(/^\D*/,''); let axisData = (date).toLocaleTimeString().replace(/^\D*/,'');
let option = this.state.dynamicOption; let option = this.state.dynamicOption;
//option.title.text = 'Hello Echarts-for-react.' + new Date().getSeconds();
let data0 = option.series[0].data; let data0 = option.series[0].data;
let data1 = option.series[1].data; let data1 = option.series[1].data;
var sum = this.dynamic['sum'] != 0 ? _data0 - this.dynamic['sum'] : 0; var sum = this.dynamic['sum'] != 0 ? _data0 - this.dynamic['sum'] : 0;
var click = this.dynamic['click'] != 0 ? _data1 - this.dynamic['click'] : 0; var click = this.dynamic['click'] != 0 ? _data1 - this.dynamic['click'] : 0;
// console.dir(this.dynamic);
this.dynamic['sum'] = _data0; this.dynamic['sum'] = _data0;
this.dynamic['click'] = _data1; this.dynamic['click'] = _data1;
data0.shift(); data0.shift();
...@@ -45,9 +43,7 @@ class Gather extends React.Component{ ...@@ -45,9 +43,7 @@ class Gather extends React.Component{
var self = this; var self = this;
if (this.timeTicket) { if (this.timeTicket) {
clearInterval(this.timeTicket); clearInterval(this.timeTicket);
} }
//this.timeTicket = setInterval(this.fetchNewDate.bind(this), 1000);
//let data = { start:moment().add(-6,'days').format('YYYYMMDD'),end:moment().format('YYYYMMDD')};
if(document.cookie.match('username=[a-zA-Z0-9]+')[0] && document.cookie.match('username=[a-zA-Z0-9]+')[0].split('=')[1]){ if(document.cookie.match('username=[a-zA-Z0-9]+')[0] && document.cookie.match('username=[a-zA-Z0-9]+')[0].split('=')[1]){
this.setState({username:document.cookie.match('username=[a-zA-Z0-9]+')[0].split('=')[1]}); this.setState({username:document.cookie.match('username=[a-zA-Z0-9]+')[0].split('=')[1]});
if(document.cookie.match('username=[a-zA-Z0-9]+')[0].split('=')[1] == 'admin') if(document.cookie.match('username=[a-zA-Z0-9]+')[0].split('=')[1] == 'admin')
...@@ -58,6 +54,7 @@ class Gather extends React.Component{ ...@@ -58,6 +54,7 @@ class Gather extends React.Component{
} }
api('GET', 'gathers/qd?skip=0&limit=20').then((res) => { api('GET', 'gathers/qd?skip=0&limit=20').then((res) => {
this.setState({qdgathers:res.result,status:'ready',none_tkls:res.none_tkls,list:res.list,pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}}); this.setState({qdgathers:res.result,status:'ready',none_tkls:res.none_tkls,list:res.list,pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}});
this.setState({clickData:res.clickData});
this.handle(res.list,res.tkl_count,res.clickData); this.handle(res.list,res.tkl_count,res.clickData);
}); });
if("WebSocket" in window || 'MozWebSocket' in window){ if("WebSocket" in window || 'MozWebSocket' in window){
...@@ -117,19 +114,26 @@ class Gather extends React.Component{ ...@@ -117,19 +114,26 @@ class Gather extends React.Component{
}, 3000);*/ }, 3000);*/
} }
getCharts(start,end){ getCharts(start,end,qd){
var self = this; var self = this;
this.setState({loading:true}); this.setState({loading:true,info:{request:0,dc:0}});
api('GET','gatherall?start=' +start+ '&end=' + end).then((res) => { var url = 'gatherall?start=' +start+ '&end=' + end;
if(res.status == 'ok' && res.list && res.list.length){ if(qd)
url += ('&qd='+qd)
api('GET',url).then((res) => {
if(res.status == 'ok' && res.list){
if(res.list.length == 0)
return message.warn('无数据');
var times = []; var times = [];
var dc_times = []; var dc_times = [];
var click_times = [];
var xAxis = []; var xAxis = [];
res.list.sort(function(a,b){ return parseInt(a._id) - parseInt(b._id) }); res.list.sort(function(a,b){ return parseInt(a._id) - parseInt(b._id) });
for(var k in res.list){ for(var k in res.list){
var item = res.list[k]; var item = res.list[k];
times.push(item.times); times.push(item.times);
dc_times.push(item.dc_times); dc_times.push(item.dc_times);
click_times.push(item.click_times);
xAxis.push(item.date); xAxis.push(item.date);
} }
self.setState({series:[ { self.setState({series:[ {
...@@ -140,12 +144,18 @@ class Gather extends React.Component{ ...@@ -140,12 +144,18 @@ class Gather extends React.Component{
data:times data:times
}, },
{ {
name:'点击数',
type:'line',
stack: '总量',
areaStyle: {normal: {}},
data:click_times
}, {
name:'导出数', name:'导出数',
type:'line', type:'line',
stack: '总量', stack: '总量',
areaStyle: {normal: {}}, areaStyle: {normal: {}},
data:dc_times data:dc_times
}],xAxis:xAxis,loading:false}); }],xAxis:xAxis,loading:false,info:{request:times.reduce(function(a,b){ return a+b}),click:click_times.reduce(function(a,b){ return a+b}),dc:dc_times.reduce(function(a,b){ return a+b})} });
} }
else else
message.warn('取数错误'); message.warn('取数错误');
...@@ -175,7 +185,7 @@ class Gather extends React.Component{ ...@@ -175,7 +185,7 @@ class Gather extends React.Component{
trigger: 'axis' trigger: 'axis'
}, },
legend: { legend: {
data:['请求数','导出数'] data:['请求数','点击数','导出数']
}, },
toolbox: { toolbox: {
feature: { feature: {
...@@ -371,25 +381,36 @@ class Gather extends React.Component{ ...@@ -371,25 +381,36 @@ class Gather extends React.Component{
//let data = { start:dateString[0],end:dateString[1]}; //let data = { start:dateString[0],end:dateString[1]};
//this.range = ; //this.range = ;
this.setState({range:[dateString[0],dateString[1]]}); this.setState({range:[dateString[0],dateString[1]]});
this.getCharts(dateString[0],dateString[1]) this.getCharts(dateString[0],dateString[1],this.state.currentQdforcharts)
//console.dir(data); //console.dir(data);
} }
exportData(){ exportData(data){
var datas = [['日期','渠道','推广页面','请求数']];
//json2xlsx(data,{sheetName:"基础数据", filename : '基础数据'+moment().format('YYYYMMDD')+'.xlsx'}); for(var i =0; i < data.length; i++){
var item = [data[i].date, data[i].user, data[i].page, data[i].times];
datas.push(item);
}
json2xlsx(datas,{sheetName:"基础数据", filename : '基础数据'+moment().format('YYYYMMDDHH')+'.xlsx'});
} }
setModalVisible(b){ setModalVisible(b){
this.setState({modalVisible:b}); this.setState({modalVisible:b});
} }
settodyModalVisible(b){
this.setState({modaltodyVisible:b});
}
detaiShow(){ detaiShow(){
this.setModalVisible(true); this.setModalVisible(true);
} }
todydetaiShow(){
this.settodyModalVisible(true);
}
putexData(data){ putexData(data){
console.dir(data);
api('POST','put_data',{dc_times:data['dc_times'],id:data['id']}).then( res => { api('POST','put_data',{dc_times:data['dc_times'],id:data['id']}).then( res => {
message.success('执行成功, 影响'+ (res.result ? res.result.nModified : 0 )+" 条数据"); message.success('执行成功, 影响'+ (res.result ? res.result.nModified : 0 )+" 条数据");
}); });
...@@ -405,6 +426,11 @@ class Gather extends React.Component{ ...@@ -405,6 +426,11 @@ class Gather extends React.Component{
//console.log(`selected ${value}`); //console.log(`selected ${value}`);
} }
handleChangeforCharts(value){
this.setState({currentQdforcharts:value});
this.getCharts(this.state.range[0],this.state.range[1],value)
}
detailData(data){ detailData(data){
console.dir(data); console.dir(data);
var date = data.date; var date = data.date;
...@@ -493,7 +519,6 @@ class Gather extends React.Component{ ...@@ -493,7 +519,6 @@ class Gather extends React.Component{
</Button> </Button>
</Popover> </Popover>
}); });
columns.push({ columns.push({
title: '操作', title: '操作',
dataIndex: 'put', dataIndex: 'put',
...@@ -521,6 +546,7 @@ class Gather extends React.Component{ ...@@ -521,6 +546,7 @@ class Gather extends React.Component{
ranges.push(moment(end,'YYYYMMDD')); ranges.push(moment(end,'YYYYMMDD'));
let data = []; let data = [];
let modal_data = []; let modal_data = [];
let tody_modal_data = [];
let count = 0; let count = 0;
let qdgathers = this.state.qdgathers; let qdgathers = this.state.qdgathers;
...@@ -539,6 +565,13 @@ class Gather extends React.Component{ ...@@ -539,6 +565,13 @@ class Gather extends React.Component{
rate:item.dc_times / item.times ? ((item.dc_times / item.times).toFixed(6) * 100).toFixed(3) : 0 rate:item.dc_times / item.times ? ((item.dc_times / item.times).toFixed(6) * 100).toFixed(3) : 0
} }
if(this.state.username == 'admin'){ if(this.state.username == 'admin'){
modal_data.push({
key:i + '-total' ,
date:item.date,
user:(item.qd && item.qd.user),
page:'全部推广汇总',
times:item.times,
});
if(item.schedules && item.schedules.length) if(item.schedules && item.schedules.length)
item.schedules.sort((a,b) => { return b.times - a.times }); item.schedules.sort((a,b) => { return b.times - a.times });
for(var j = 0;j < item.schedules.length; j++){ for(var j = 0;j < item.schedules.length; j++){
...@@ -568,9 +601,11 @@ class Gather extends React.Component{ ...@@ -568,9 +601,11 @@ class Gather extends React.Component{
} }
var none_tkls = this.state.none_tkls; var none_tkls = this.state.none_tkls;
var list = this.state.list; var list = this.state.list;
var clickData = this.state.clickData;
var sum = 0; var sum = 0;
var list_show = []; var list_show = [];
var sum_list_show = []; var sum_list_show = [];
var click_sum_list_show = [];
for(var i in none_tkls){ for(var i in none_tkls){
sum += none_tkls[i]['times']; sum += none_tkls[i]['times'];
let qd = none_tkls[i]["qd"]; let qd = none_tkls[i]["qd"];
...@@ -581,9 +616,20 @@ class Gather extends React.Component{ ...@@ -581,9 +616,20 @@ class Gather extends React.Component{
for(var k in list){ for(var k in list){
if(list[k] && list[k].qd && list[k]['qd']['user']) if(list[k] && list[k].qd && list[k]['qd']['user'])
map2qd[list[k]['qd']['user']] = (map2qd[list[k]['qd']['user']] ? (map2qd[list[k]['qd']['user']]+list[k]['sum']) : list[k]['sum']); map2qd[list[k]['qd']['user']] = (map2qd[list[k]['qd']['user']] ? (map2qd[list[k]['qd']['user']]+list[k]['sum']) : list[k]['sum']);
tody_modal_data.push({
key: list[k]._id,
date:moment().format('YYYYMMDD'),
user:list[k] && list[k].qd && list[k]['qd']['user'] ? list[k]['qd']['user'] : '--' ,
page:list[k] && list[k].links ? list[k].links.map( x => x.name ).join(',') : '--',
times:list[k].sum
})
}
for(var m in clickData){
click_sum_list_show.push(<div className="detail-body" key={ m }><span style={{ width:"50%"}}>{clickData[m]['_id']}</span><span style={{ width:"50%"}}>{ clickData[m]['sum'] }</span></div>);
} }
for(var j in map2qd){ for(var j in map2qd){
sum_list_show.push(<div className="detail-body" key={ j }><span>{j}</span><span>{ map2qd[j] }</span></div>); sum_list_show.push(<div className="detail-body" key={ j }><span style={{ width:"50%"}}>{j}</span><span style={{ width:"50%"}}>{ map2qd[j] }</span></div>);
} }
const content = ( const content = (
...@@ -595,6 +641,9 @@ class Gather extends React.Component{ ...@@ -595,6 +641,9 @@ class Gather extends React.Component{
<div> <div>
{ sum_list_show } { sum_list_show }
</div>); </div>);
const click_sum_content = (<div>
{ click_sum_list_show }
</div>);
return ( return (
<div> <div>
<div> <div>
...@@ -607,13 +656,16 @@ class Gather extends React.Component{ ...@@ -607,13 +656,16 @@ class Gather extends React.Component{
<span>{ this.state.tody.count }</span> <span>{ this.state.tody.count }</span>
</Popover> </Popover>
} }
</div> </div>
</Col> </Col>
<Col span="6"> <Col span="6">
<div className = "box"> <div className = "box">
<h3>点击数</h3> <h3>点击数</h3>{
<span>{ this.state.tody.click_count }</span> this.state.username !== 'admin' ? <span>{ this.state.tody.click_count }</span> :
<Popover placement="bottom" content={click_sum_content} title="详情">
<span>{ this.state.tody.click_count }</span>
</Popover>
}
</div> </div>
</Col> </Col>
{ {
...@@ -642,11 +694,24 @@ class Gather extends React.Component{ ...@@ -642,11 +694,24 @@ class Gather extends React.Component{
{this.state.username == 'admin' ? <Tabs {this.state.username == 'admin' ? <Tabs
defaultActiveKey="1" defaultActiveKey="1"
tabPosition={'left'} tabPosition={'left'}
style={{height: '406px', width: '100%',margin:'15px 0px'}} style={{height: '436px', width: '100%',margin:'15px 0px'}}
> >
<TabPane tab="每日走势" key="1" > <TabPane tab="每日走势" key="1" >
<RangePicker onChange={ this.onChangeDate.bind(this) } value={ ranges } format={'YYYYMMDD'} style={{margin:'10px 0px'}}/> <RangePicker onChange={ this.onChangeDate.bind(this) } value={ ranges } format={'YYYYMMDD'} style={{margin:'10px'}}/>
<ReactEcharts <Select
style={{ float:'left',width:200,margin:'10px 0px 10px 0px'}}
placeholder="输入渠道名称"
defaultValue="all"
onChange={this.handleChangeforCharts.bind(this)}
>
{children}
</Select>
<div style={{ float:'right',margin:'10px 0px 10px 0px'}}>
<Tag color="#f50" style={{ height:'28px',lineHeight:'28px'}}>{"请求数: "+this.state.info.request}</Tag>
<Tag color="#87d068" style={{ height:'28px',lineHeight:'28px'}}>{"点击数: "+this.state.info.click}</Tag>
<Tag color="#108ee9" style={{ height:'28px',lineHeight:'28px'}}>{"导出数: "+this.state.info.dc}</Tag>
</div>
<ReactEcharts
option={this.getOption()} option={this.getOption()}
style={{height: '350px', width: '100%',margin:'15px 0px'}} style={{height: '350px', width: '100%',margin:'15px 0px'}}
onChartReady={this.onChartReady.bind(this)} onChartReady={this.onChartReady.bind(this)}
...@@ -662,7 +727,7 @@ class Gather extends React.Component{ ...@@ -662,7 +727,7 @@ class Gather extends React.Component{
</Tabs> : <div></div>} </Tabs> : <div></div>}
<div style={{ overflow:"hidden"}}> <div style={{ overflow:"hidden"}}>
<Button type="primary" icon="export" onClick={ this.exportData.bind(this) } style={{ float:'right',margin:'10px 0px'}}> <Button type="primary" icon="export" onClick={ this.exportData.bind(this, modal_data) } style={{ float:'right',margin:'10px 0px'}}>
导出数据 导出数据
</Button> </Button>
{ {
...@@ -671,6 +736,12 @@ class Gather extends React.Component{ ...@@ -671,6 +736,12 @@ class Gather extends React.Component{
本页详情 本页详情
</Button> : <div></div> </Button> : <div></div>
} }
{
this.state.username == 'admin' ?
<Button type="primary" onClick={ this.todydetaiShow.bind(this) } style={{ float:'right',margin:'10px'}}>
今日详情
</Button> : <div></div>
}
{ {
this.state.username == 'admin' ? <Modal this.state.username == 'admin' ? <Modal
...@@ -684,6 +755,19 @@ class Gather extends React.Component{ ...@@ -684,6 +755,19 @@ class Gather extends React.Component{
</Modal> : <div></div> </Modal> : <div></div>
} }
{
this.state.username == 'admin' ? <Modal
title="今日数据详情"
style={{ top: 30 }}
visible={this.state.modaltodyVisible}
footer = { null }
onCancel = { this.settodyModalVisible.bind(this,false) }
>
<Table columns={ modal_columns } dataSource = { tody_modal_data } size="middle" bordered/>
</Modal> : <div></div>
}
{ {
this.state.username == 'admin' ? <Select this.state.username == 'admin' ? <Select
style={{ float:'left',width:200,margin:'10px 0px'}} style={{ float:'left',width:200,margin:'10px 0px'}}
......
...@@ -4,8 +4,8 @@ module.exports = { ...@@ -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', 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: { taobao: {
host:"http://gw.api.taobao.com/router/rest", host:"http://gw.api.taobao.com/router/rest",
appKey:"23390725", appKey:"24594025",
appSecret:'0575587ba36b29fa5680ad571c5e51f4' appSecret:'def2396c763580d49e4a0aa15c4c18bd'
//appKey:"24594025",//"23580470",//"23390725", //appKey:"24594025",//"23580470",//"23390725",
//appSecret:'def2396c763580d49e4a0aa15c4c18bd'//"e5f350cbdbd6db2a8727f0b65dac1f7c",//"0575587ba36b29fa5680ad571c5e51f4" //appSecret:'def2396c763580d49e4a0aa15c4c18bd'//"e5f350cbdbd6db2a8727f0b65dac1f7c",//"0575587ba36b29fa5680ad571c5e51f4"
} }
......
...@@ -24,6 +24,10 @@ const schema = mongoose.Schema({ ...@@ -24,6 +24,10 @@ const schema = mongoose.Schema({
type:Number, type:Number,
required: true required: true
}, },
click_times:{
type:Number,
required: false
},
dc_times:{ dc_times:{
type:Number, type:Number,
required: false required: false
......
...@@ -19,6 +19,10 @@ const schema = mongoose.Schema({ ...@@ -19,6 +19,10 @@ const schema = mongoose.Schema({
type: String, type: String,
required: false required: false
}, },
id:{
type: String,
required: false
},
title:{ title:{
type: String, type: String,
required: true required: true
...@@ -39,6 +43,10 @@ const schema = mongoose.Schema({ ...@@ -39,6 +43,10 @@ const schema = mongoose.Schema({
status:{ status:{
type:String, type:String,
required:false required:false
},
removed:{
type:String,
required:false
} }
}, { }, {
timestamps: true timestamps: true
......
...@@ -15,12 +15,12 @@ const Nonetkl = require('../db/mongo/tao-nonetkl-log'); ...@@ -15,12 +15,12 @@ const Nonetkl = require('../db/mongo/tao-nonetkl-log');
const url = require('url'); const url = require('url');
const not_full = 'params not full error'; const not_full = 'params not full error';
const not_right = 'params not right error'; const not_right = 'params not right error';
const not_login = 'please login first'; const not_login = 'please login first'
const not_auth = 'auth error'; const not_auth = 'auth error';
const {ObjectId} = mongoose.SchemaTypes; const {ObjectId} = mongoose.SchemaTypes;
function dateFormat(target,format) { function dateFormat(target,format) {
return moment(new Date(target.getTime()),'x').format(format || 'YYYYMMDD HH:mm:ss'); return moment(new Date(target.getTime()),'x').add(0,'hours').format(format || 'YYYYMMDD HH:mm:ss');
}; };
function urlArgs(query) { function urlArgs(query) {
...@@ -106,7 +106,7 @@ exports.logs = async (req, res, next) => { ...@@ -106,7 +106,7 @@ exports.logs = async (req, res, next) => {
} }
exports.getIps = async(req,res,next) => { exports.getIps = async(req,res,next) => {
let now = moment().add(8,'hours').format('YYYYMMDD'); let now = moment().add(0,'hours').format('YYYYMMDD');
let { qd = 'all', date = now,limit = 100,skip = 0} = req.query; let { qd = 'all', date = now,limit = 100,skip = 0} = req.query;
if(!qd ) return res.status(400).send(not_full); if(!qd ) return res.status(400).send(not_full);
let sess = req.cookies['sess']; let sess = req.cookies['sess'];
...@@ -116,7 +116,7 @@ exports.getIps = async(req,res,next) => { ...@@ -116,7 +116,7 @@ exports.getIps = async(req,res,next) => {
if(session_body){ if(session_body){
var user = session_body.toJSON().user; var user = session_body.toJSON().user;
if(user != '5a1e81f8c86fa7aa4b51b18b'){ if(user != '5a1e81f8c86fa7aa4b51b18b'){
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else{ else{
var qs = {date:date}; var qs = {date:date};
...@@ -130,7 +130,7 @@ exports.getIps = async(req,res,next) => { ...@@ -130,7 +130,7 @@ exports.getIps = async(req,res,next) => {
} }
} }
else else
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else else
res.status(400).send(not_login); res.status(400).send(not_login);
...@@ -143,7 +143,7 @@ exports.getQdGatherData = async (req, res, next) => { ...@@ -143,7 +143,7 @@ exports.getQdGatherData = async (req, res, next) => {
let sess = req.cookies['sess']; let sess = req.cookies['sess'];
var qs = {}; var qs = {};
var clickData = {}; var clickData = {};
var date = moment().add(8,'hours').format('YYYYMMDD'); var date = moment().add(0,'hours').format('YYYYMMDD');
if(sess){ if(sess){
if(qd) if(qd)
qs['qd'] = qd; qs['qd'] = qd;
...@@ -191,8 +191,9 @@ exports.getQdGatherData = async (req, res, next) => { ...@@ -191,8 +191,9 @@ exports.getQdGatherData = async (req, res, next) => {
]); ]);
var tasks = []; var tasks = [];
list.forEach( async (item,i) => { list.forEach( async (item,i) => {
var schedule = await Schedule.findById(item._id).populate('qd','user'); var schedule = await Schedule.findById(item._id).populate('qd','user').populate('links','name');
list[i]['qd'] = schedule.toJSON().qd; list[i]['qd'] = schedule.toJSON().qd;
list[i]['links'] = schedule.toJSON().links;
}); });
clickData = await Click.aggregate([ clickData = await Click.aggregate([
{ {
...@@ -265,7 +266,7 @@ exports.putGatherData = async(req,res,next) => { ...@@ -265,7 +266,7 @@ exports.putGatherData = async(req,res,next) => {
if(session_body){ if(session_body){
var user = session_body.toJSON().user; var user = session_body.toJSON().user;
if(user != '5a1e81f8c86fa7aa4b51b18b'){ if(user != '5a1e81f8c86fa7aa4b51b18b'){
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else{ else{
console.dir(dc_times); console.dir(dc_times);
...@@ -275,7 +276,7 @@ exports.putGatherData = async(req,res,next) => { ...@@ -275,7 +276,7 @@ exports.putGatherData = async(req,res,next) => {
} }
} }
else else
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else else
res.status(400).send(not_login); res.status(400).send(not_login);
...@@ -291,7 +292,7 @@ exports.putIp = async(req,res,next) => { ...@@ -291,7 +292,7 @@ exports.putIp = async(req,res,next) => {
if(session_body){ if(session_body){
var user = session_body.toJSON().user; var user = session_body.toJSON().user;
if(user != '5a1e81f8c86fa7aa4b51b18b'){ if(user != '5a1e81f8c86fa7aa4b51b18b'){
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else{ else{
console.dir(iplimit); console.dir(iplimit);
...@@ -301,7 +302,7 @@ exports.putIp = async(req,res,next) => { ...@@ -301,7 +302,7 @@ exports.putIp = async(req,res,next) => {
} }
} }
else else
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else else
res.status(400).send(not_login); res.status(400).send(not_login);
...@@ -317,7 +318,7 @@ exports.putQdUpdate = async(req,res,next) => { ...@@ -317,7 +318,7 @@ exports.putQdUpdate = async(req,res,next) => {
if(session_body){ if(session_body){
var user = session_body.toJSON().user; var user = session_body.toJSON().user;
if(user != '5a1e81f8c86fa7aa4b51b18b'){ if(user != '5a1e81f8c86fa7aa4b51b18b'){
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else{ else{
var result = await Agent.update({_id:id},{$set:{ipstatus:ipstatus}}); var result = await Agent.update({_id:id},{$set:{ipstatus:ipstatus}});
...@@ -325,7 +326,7 @@ exports.putQdUpdate = async(req,res,next) => { ...@@ -325,7 +326,7 @@ exports.putQdUpdate = async(req,res,next) => {
} }
} }
else else
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else else
res.status(400).send(not_login); res.status(400).send(not_login);
...@@ -341,11 +342,15 @@ exports.getTbkls = async (req, res, next) => { ...@@ -341,11 +342,15 @@ exports.getTbkls = async (req, res, next) => {
} }
exports.getLinks = async (req, res, next) => { exports.getLinks = async (req, res, next) => {
let {limit = 100,skip = 0,sort = {'updatedAt': -1}} = req.query; let {limit = 100,skip = 0,sort = {'updatedAt': -1}, keyword='' } = req.query;
let options = {limit:parseInt(limit),skip:parseInt(skip)*limit,sort}; let options = {limit:parseInt(limit),skip:parseInt(skip)*limit,sort};
let links = await Link.find({},null,options); let qs = { removed: { $ne:true } };
if(keyword.length) {
qs.name = new RegExp(`${keyword}`)
}
let links = await Link.find(qs,null,options);
links = links.map(x => { var d = x.toJSON();d['createdAt'] = dateFormat(d['createdAt']);return d;}) links = links.map(x => { var d = x.toJSON();d['createdAt'] = dateFormat(d['createdAt']);return d;})
let total = await Link.count({},null); let total = await Link.count(qs,null);
var tasks = []; var tasks = [];
links.forEach(item => { links.forEach(item => {
tasks.push(Schedule.find({status:'use',links:{ '$in':[ item._id ]}}).populate('qd','user').limit(1000)); tasks.push(Schedule.find({status:'use',links:{ '$in':[ item._id ]}}).populate('qd','user').limit(1000));
...@@ -366,35 +371,43 @@ exports.getLinks = async (req, res, next) => { ...@@ -366,35 +371,43 @@ exports.getLinks = async (req, res, next) => {
} }
exports.createLink = async (req, res, next) => { exports.createLink = async (req, res, next) => {
var {quan,pid,good,name,select = 'target'} = req.body; var {quan,pid,good,name,select = 'target',good_id,pic,title} = req.body;
console.dir((select == 'good' && !good) || (select == 'good' && (!pid || !good || !quan || !name))); //console.dir((select == 'good' && !good) || (select == 'good' && (!pid || !good || !quan || !name)));
if((select == 'good' && !good) || (select != 'good' && (!pid || !good || !quan || !name))) if((select == 'good' && !good) || (select == 'notbk' && !pic && !name && !good && !title) || ((select != 'good' && select != 'notbk') && (!pid || !good || !quan || !name)))
res.status(400).send(not_full); return res.status(400).send(not_full);
else{ else{
try { try {
let quanQuery = ''; if(select === 'notbk') {
if(select !== 'good' && quan) quanQuery = urlArgs(url.parse(quan).query); tao.saveLink({name,good,title,pic,target: good},function(e,result){
let goodQuery = urlArgs(url.parse(good).query);
console.dir(goodQuery);
if(!goodQuery['id'])
res.status(400).send(not_full);
else{
let goodInfo = await tao.getGood(goodQuery['id']);
let title = (req.body.title && req.body.title.length) ? req.body.title : goodInfo['title'];
let pic = goodInfo['pict_url'] || '';
let target = '';
console.dir(select);
if(select == 'target')
target = 'https://uland.taobao.com/coupon/edetail?activityId='+ quanQuery['activityId']+'&itemId='+goodQuery['id']+'&pid='+pid+'&dx=1&src=tkm_tkmwz';
if(select == 'good')
target = good;
if(select == 'quan')
target = quan;
console.dir(target);
tao.saveLink({name,quan,pid,good,title,pic,target},function(e,result){
if(e) throw e; if(e) throw e;
res.send({result:'ok',result:result}) res.send({result:'ok',result:result})
}); });
} else {
let quanQuery = '';
if(select !== 'good' && select !== 'notbk' && quan) quanQuery = urlArgs(url.parse(quan).query);
let goodQuery = urlArgs(url.parse(good).query);
console.dir(goodQuery);
if(!goodQuery['id'] && !good_id)
res.status(400).send(not_full);
else{
let goodInfo = await tao.getGood(goodQuery['id'] || good_id);
let title = (req.body.title && req.body.title.length) ? req.body.title : goodInfo['title'];
let pic = goodInfo['pict_url'] || '';
let target = '';
let id = good_id;
console.dir(select);
if(select == 'target')
target = 'https://uland.taobao.com/coupon/edetail?activityId='+ quanQuery['activityId']+'&itemId='+goodQuery['id']+'&pid='+pid+'&src=tkdg_tkdggj';
if(select == 'good')
target = good;
if(select == 'quan')
target = quan;
console.dir(target);
tao.saveLink({name,quan,pid,good,title,pic,target,id},function(e,result){
if(e) throw e;
res.send({result:'ok',result:result})
});
}
} }
}catch(e){ }catch(e){
console.dir(e); console.dir(e);
...@@ -403,13 +416,48 @@ exports.createLink = async (req, res, next) => { ...@@ -403,13 +416,48 @@ exports.createLink = async (req, res, next) => {
} }
} }
exports.removeLink = async (req,res,next) => {
let sess = req.cookies['sess'];
let link = req.params.link;
if(!/^[0-9a-z]{24}$/.test(link)) return res.status(500).send('格式错误');
if(sess){
var none_tkls = [];
var session_body = await Session.findById(sess);
if(session_body){
var user = session_body.toJSON().user;
if(user != '5a1e81f8c86fa7aa4b51b18b'){
res.status(403).send(not_auth);
}
else{
let count = await Schedule.count({links: { $in: [ mongoose.Types.ObjectId(link) ] }});
if(!count) {
let result = await Link.update({ _id: mongoose.Types.ObjectId(link) },{$set:{ removed:true }});
res.send({ result:'ok',result });
} else {
return res.status(500).send('有绑定计划不能删除');
}
}
}
else
res.status(403).send(not_auth);
}else{
res.status(403).send(not_auth);
}
};
exports.getSchedules = async (req, res, next) => { exports.getSchedules = async (req, res, next) => {
let {limit = 100,skip = 0,sort = {'createdAt': -1},qd = 'all'} = req.query; let {limit = 100,skip = 0,sort,qd = 'all'} = req.query;
let options = {limit:parseInt(limit),skip:parseInt(skip)*limit,sort};
var qs = {}; var qs = {};
if(qd != 'all') if(qd != 'all')
qs = {qd:qd} qs = {qd:qd}
console.dir(qs); console.dir(qs);
var sort_body = {}
if(sort) sort_body[ sort ] = -1;
else sort_body['createdAt'] = -1;
let options = {limit:parseInt(limit),skip:parseInt(skip)*limit,sort:sort_body};
console.dir(options)
let schedules = await Schedule.find(qs,null,options).populate('links','name title target').populate('qd','user'); let schedules = await Schedule.find(qs,null,options).populate('links','name title target').populate('qd','user');
var tasks = []; var tasks = [];
schedules.forEach( (item) => { schedules.forEach( (item) => {
...@@ -424,6 +472,18 @@ exports.getSchedules = async (req, res, next) => { ...@@ -424,6 +472,18 @@ exports.getSchedules = async (req, res, next) => {
}); });
} }
exports.updateScheduleFinal = async (req, res, next) => {
let { final, scheduleID } = req.query
let now = Date.now();
if(final <= now) return res.status(403).send('日期不能小于当前');
try {
const result = await Schedule.update({_id:mongoose.Types.ObjectId(scheduleID)},{$set:{final: parseInt(final)}});
res.send({status:'ok',result});
} catch(error) {
res.status(500).send('修改失败');
}
}
exports.getQds = async (req, res, next) => { exports.getQds = async (req, res, next) => {
let {limit = 100,skip = 0,sort = {'createdAt': -1}} = req.query; let {limit = 100,skip = 0,sort = {'createdAt': -1}} = req.query;
let options = {limit:parseInt(limit),skip:parseInt(skip)*limit,sort}; let options = {limit:parseInt(limit),skip:parseInt(skip)*limit,sort};
...@@ -484,9 +544,11 @@ exports.updateSchedule = async (req, res, next) => { ...@@ -484,9 +544,11 @@ exports.updateSchedule = async (req, res, next) => {
pic:item.pic, pic:item.pic,
qd:qd, qd:qd,
link:item._id, link:item._id,
schedule:schedule._id schedule:schedule._id,
id:item.id,
pid: item.pid
} }
for(var i=0;i<5;i++){ for(var i=0;i<10;i++){
tasks.push(createTbkl(data)); tasks.push(createTbkl(data));
} }
}); });
...@@ -520,6 +582,7 @@ exports.createSchedule = async (req, res, next) => { ...@@ -520,6 +582,7 @@ exports.createSchedule = async (req, res, next) => {
Promise.all(links).then(function(arr){ Promise.all(links).then(function(arr){
arr = arr.map(x => x.toJSON()); //获取所有推广页id arr = arr.map(x => x.toJSON()); //获取所有推广页id
ids = arr.map(x => x._id); ids = arr.map(x => x._id);
console.dir(arr);
if(agent && ids.length){ if(agent && ids.length){
var qd = agent.toJSON()['_id']; var qd = agent.toJSON()['_id'];
var links = ids; var links = ids;
...@@ -532,7 +595,9 @@ exports.createSchedule = async (req, res, next) => { ...@@ -532,7 +595,9 @@ exports.createSchedule = async (req, res, next) => {
item['link'] = item._id; item['link'] = item._id;
item['schedule'] = schedule; item['schedule'] = schedule;
item['qd'] = qd; item['qd'] = qd;
for(let i = 0;i<5;i++){ item['id'] = item.id;
item['pid'] = item.pid;
for(let i = 0;i<10;i++){
tkl_Tasks.push(createTbkl(item)); tkl_Tasks.push(createTbkl(item));
} }
}); });
...@@ -567,9 +632,11 @@ exports.newTbkl = async (req, res, next) => { ...@@ -567,9 +632,11 @@ exports.newTbkl = async (req, res, next) => {
pic:item.pic, pic:item.pic,
qd:qd, qd:qd,
link:item._id, link:item._id,
schedule:schedule._id schedule:schedule._id,
id:item.id,
pid: item.pid,
} }
for(var i=0;i<5;i++){ for(var i=0;i<10;i++){
tasks.push(createTbkl(data)); tasks.push(createTbkl(data));
} }
}); });
...@@ -599,7 +666,7 @@ exports.adminTbkl = async(req,res,next) => { ...@@ -599,7 +666,7 @@ exports.adminTbkl = async(req,res,next) => {
if(session_body){ if(session_body){
var user = session_body.toJSON().user; var user = session_body.toJSON().user;
if(user != '5a1e81f8c86fa7aa4b51b18b'){ if(user != '5a1e81f8c86fa7aa4b51b18b'){
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else{ else{
var quanQuery = urlArgs(url.parse(quan).query); var quanQuery = urlArgs(url.parse(quan).query);
...@@ -623,15 +690,15 @@ exports.adminTbkl = async(req,res,next) => { ...@@ -623,15 +690,15 @@ exports.adminTbkl = async(req,res,next) => {
} }
} }
else else
res.status(400).send(not_auth); res.status(403).send(not_auth);
}else{ }else{
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
} }
exports.getAllGatherData = async(req,res,next) => { exports.getAllGatherData = async(req,res,next) => {
var {start,end} = req.query; var {start,end,qd='all'} = req.query;
if(!start || !end) return res.status(400).send(not_full); if(!start || !end) return res.status(400).send(not_full);
let sess = req.cookies['sess']; let sess = req.cookies['sess'];
if(sess){ if(sess){
...@@ -640,12 +707,13 @@ exports.getAllGatherData = async(req,res,next) => { ...@@ -640,12 +707,13 @@ exports.getAllGatherData = async(req,res,next) => {
if(session_body){ if(session_body){
var user = session_body.toJSON().user; var user = session_body.toJSON().user;
if(user != '5a1e81f8c86fa7aa4b51b18b'){ if(user != '5a1e81f8c86fa7aa4b51b18b'){
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else{ else{
console.dir(start); var condition = {'date': {'$gte': moment(start, 'YYYYMMDD').startOf('day').toDate(),'$lt': moment(end, 'YYYYMMDD').endOf('day').toDate()}};
console.dir(end); if(qd != 'all')
const condition = {'date': {'$gte': moment(start, 'YYYYMMDD').startOf('day').toDate(),'$lt': moment(end, 'YYYYMMDD').endOf('day').toDate()}}; condition['qd'] = mongoose.Types.ObjectId(qd);
console.dir(condition);
var list = await GatherData.aggregate([ var list = await GatherData.aggregate([
{ {
$match:condition $match:condition
...@@ -654,7 +722,8 @@ exports.getAllGatherData = async(req,res,next) => { ...@@ -654,7 +722,8 @@ exports.getAllGatherData = async(req,res,next) => {
$group:{ $group:{
_id: "$date", _id: "$date",
times:{ $sum:"$times" }, times:{ $sum:"$times" },
dc_times:{ $sum:"$dc_times" } dc_times:{ $sum:"$dc_times" },
click_times:{ $sum:"$click_times" }
} }
} }
]); ]);
...@@ -663,9 +732,9 @@ exports.getAllGatherData = async(req,res,next) => { ...@@ -663,9 +732,9 @@ exports.getAllGatherData = async(req,res,next) => {
} }
} }
else else
res.status(400).send(not_auth); res.status(403).send(not_auth);
}else{ }else{
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
} }
...@@ -685,7 +754,7 @@ exports.admin2Tbkl = async(req,res,next) => { ...@@ -685,7 +754,7 @@ exports.admin2Tbkl = async(req,res,next) => {
/*exports.getDetails = async (req,res,next) => { /*exports.getDetails = async (req,res,next) => {
var {date,qd} = req.query; var {date,qd} = req.query;
let now = moment().add(8,'hours').format('YYYYMMDD'); let now = moment().add(0,'hours').format('YYYYMMDD');
if(!date || !qd || parseInt(now) - parseInt(date) < 0){ if(!date || !qd || parseInt(now) - parseInt(date) < 0){
res.status(400).send(not_right); res.status(400).send(not_right);
} }
...@@ -695,7 +764,7 @@ exports.admin2Tbkl = async(req,res,next) => { ...@@ -695,7 +764,7 @@ exports.admin2Tbkl = async(req,res,next) => {
if(session_body){ if(session_body){
var user = session_body.toJSON().user; var user = session_body.toJSON().user;
if(user != '5a1e81f8c86fa7aa4b51b18b' && user != qd){ if(user != '5a1e81f8c86fa7aa4b51b18b' && user != qd){
res.status(400).send(not_auth); res.status(403).send(not_auth);
} }
else{ else{
...@@ -739,14 +808,17 @@ exports.admin2Tbkl = async(req,res,next) => { ...@@ -739,14 +808,17 @@ exports.admin2Tbkl = async(req,res,next) => {
} }
}*/ }*/
var createTbkl = async (data) => { var createTbkl = async (data) => {
let {title,target,pic,qd} = data; console.dir('data ========================');
console.dir(data);
let {title,target,pic,qd,id,pid} = data;
return new Promise(async (r,d) => { return new Promise(async (r,d) => {
try { try {
let targetQuery = urlArgs(url.parse(target).query); let targetQuery = urlArgs(url.parse(target).query);
var tbklInfo = null; var tbklInfo = null;
console.dir(targetQuery); console.dir(targetQuery);
if(targetQuery['pid']) if(targetQuery['pid'] || id || pid)
tbklInfo = await tao.createTbkl(title,target,pic); tbklInfo = await tao.createTbkl(title,target,pic);
else else
tbklInfo = await tao.createnormalTbkl(title,target,pic); tbklInfo = await tao.createnormalTbkl(title,target,pic);
......
...@@ -55,13 +55,14 @@ async function tbklTask () { ...@@ -55,13 +55,14 @@ async function tbklTask () {
var tasks_schedule_koulings = []; var tasks_schedule_koulings = [];
if(item.final && item.final < moment().format('x')){ 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_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})); tasks_schedule_koulings.push(Schedule.update({_id:schedule},{$set:{status:"disable"}},{multi:true}));
} }
// console.dir(schedule); // console.dir(schedule);
// 查询计划内 超过20000 请求 淘口令 // 查询计划内 超过20000 请求 淘口令
//console.dir({times:{$gte:10},status:'use',schedule:schedule}); //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_new = [];
var tasks_old = []; var tasks_old = [];
var tasks_log = []; var tasks_log = [];
...@@ -76,7 +77,9 @@ async function tbklTask () { ...@@ -76,7 +77,9 @@ async function tbklTask () {
link:item.link, link:item.link,
status:'use', status:'use',
qd:qd, 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_new.push(controller.createTbkl(data));
tasks_old.push(Kouling.update({info:item.key,status:{$ne:'disable'}},{$set:{status:'disable'}},{multi:true})); tasks_old.push(Kouling.update({info:item.key,status:{$ne:'disable'}},{$set:{status:'disable'}},{multi:true}));
......
...@@ -57,7 +57,7 @@ async function tbklTask () { ...@@ -57,7 +57,7 @@ async function tbklTask () {
// console.dir(schedule); // console.dir(schedule);
// 查询计划内 超过20000 请求 淘口令 // 查询计划内 超过20000 请求 淘口令
//console.dir({times:{$gte:10},status:'use',schedule:schedule}); //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_new = [];
var tasks_old = []; var tasks_old = [];
if(auto == 'use'){ if(auto == 'use'){
...@@ -69,6 +69,7 @@ async function tbklTask () { ...@@ -69,6 +69,7 @@ async function tbklTask () {
link:_item._id, link:_item._id,
status:'use', status:'use',
qd:qd, qd:qd,
id:_item.id,
pic:_item.pic pic:_item.pic
} }
for(var i = 0;i<10; i++){ for(var i = 0;i<10; i++){
......
...@@ -3,6 +3,7 @@ const nodemailer = require('nodemailer'); ...@@ -3,6 +3,7 @@ const nodemailer = require('nodemailer');
const Schedule = require('../db/mongo/tao-schedule'); const Schedule = require('../db/mongo/tao-schedule');
const Data = require('../db/mongo/tao-data'); const Data = require('../db/mongo/tao-data');
const Log = require('../db/mongo/tao-log'); const Log = require('../db/mongo/tao-log');
const Click = require('../db/mongo/tao-log-click');
const _ = require('lodash'); const _ = require('lodash');
const moment = require('moment'); const moment = require('moment');
const controller = require('./controller'); const controller = require('./controller');
...@@ -56,6 +57,26 @@ async function tbklTask () { ...@@ -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 qd2schedule = {};
var sum2schedule = {}; var sum2schedule = {};
...@@ -90,7 +111,7 @@ async function tbklTask () { ...@@ -90,7 +111,7 @@ async function tbklTask () {
} }
//var total = qd2schedule[k].reduce(function(a,b){ return a.times + b.times},{times:0}); //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}); //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()); tasks.push(data.save());
} }
Promise.all(tasks).then(function(arr){ Promise.all(tasks).then(function(arr){
......
...@@ -19,6 +19,7 @@ router.post('/qd',controller.createQd); ...@@ -19,6 +19,7 @@ router.post('/qd',controller.createQd);
router.post('/newtkl',controller.newTbkl); router.post('/newtkl',controller.newTbkl);
router.post('/link',controller.createLink); router.post('/link',controller.createLink);
router.get('/link/del/:link',controller.removeLink);
router.post('/put_data',controller.putGatherData); router.post('/put_data',controller.putGatherData);
...@@ -32,6 +33,7 @@ router.post('/tool2_tbkls',controller.admin2Tbkl); ...@@ -32,6 +33,7 @@ router.post('/tool2_tbkls',controller.admin2Tbkl);
router.get('/schedules',controller.getSchedules); router.get('/schedules',controller.getSchedules);
router.post('/schedule',controller.createSchedule); router.post('/schedule',controller.createSchedule);
router.get('/schedule/final',controller.updateScheduleFinal)
router.post('/schedule_update',controller.updateSchedule); router.post('/schedule_update',controller.updateSchedule);
router.post('/schedule_auto_update',controller.updateAutoSchedule); router.post('/schedule_auto_update',controller.updateAutoSchedule);
router.get('/gathers/qd',controller.getQdGatherData); 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