Commit 0d27eb51 authored by 刘松's avatar 刘松

complex

parent 0b12a7e4
FROM node:7.6
FROM node:latest
RUN mkdir -p /usr/src/app
......
......@@ -14,6 +14,7 @@ const mongoose = require('mongoose');
const sessions = require('./db/mongo/session');
const cron = require('./lib/cron');
const cron_gather = require('./lib/cron_gather');
const cron_auto = require('./lib/cron_auto');
const options = {
useMongoClient: true
......@@ -54,5 +55,6 @@ console.log(process.env.NODE_ENV + 'server started on port ' + config.port);
if(process.env.NODE_ENV === 'production'){
cron.start();
cron_gather.start();
cron_auto.start();
}
This diff is collapsed.
This diff is collapsed.
body{
background: #ececec
background: #ececec;
font-size: 13px;
}
.wrapper,.login-wrapper{
background: #ececec;
......@@ -83,6 +84,18 @@ body{
text-align: center;
background: #5587b3;
}
div.ant-row .ant-col-6:nth-of-type(1) .box h3{
background: #5587b3;
}
div.ant-row .ant-col-6:nth-of-type(2) .box h3{
background: #ffb980;
}
div.ant-row .ant-col-6:nth-of-type(3) .box h3 {
background: #5ab1ef;
}
div.ant-row .ant-col-6:nth-of-type(4) .box h3{
background: #97b552;
}
.box span{
font-size: 20px;
width: 58%;
......@@ -97,7 +110,7 @@ body{
width: 500px;
}
.detail-body span{
width: 50%;
width: 33.3%;
display: inline-block;
}
.detail-body-list{
......@@ -122,3 +135,57 @@ body{
.detail-body-list span:nth-of-type(3){
width: 10%;
}
.tool-box{
display: flex;
display: -webkit-flex; /* Safari */
align-items: center;
flex-direction: row;
justify-content:flex-start;
}
.tool-box .none{
margin-left: 20px;
/* background: aquamarine; */
height: 100%;
width: 100%;
min-width: 200px;
text-align: center;
}
.label-info{
border-bottom: 1px solid #b1abab;
padding: 10px 0px;
}
.label-info label{
font-size: 13px;
font-weight: bold;
width: 200px;
float: left;
}
label.tkllabel{
font-size: 13px;
font-weight: bold;
width: 200px;
padding: 10px 0px;
display: block;
}
.label-info p{
display: block;
max-width: 100%;
overflow: hidden;
word-wrap: break-word;
}
.label-info div{
margin-left: 10px;
}
.label-info img{
width: 100px;
}
.model-box{
height: 150px;
overflow: auto;
}
.model{
float: left;
margin: 0px 9px 10px 0px;
}
......@@ -22,6 +22,18 @@ module.exports = {
{
path:'qd',
component:require('../../jsx/setting/qd.jsx')
},
{
path:'tools',
component:require('../../jsx/setting/tools.jsx')
},
{
path:'tools_num2',
component:require('../../jsx/setting/tool2s.jsx')
},
{
path:'ips',
component:require('../../jsx/setting/ips.jsx')
}
]
}
\ No newline at end of file
......@@ -9,14 +9,17 @@ const MenuItemGroup = Menu.ItemGroup;
const ButtonGroup = Button.Group;
const { Header, Footer, Sider, Content } = Layout;
const mapLocations = ['/manage/statistics','/manage','/manage/setting','/manage/tkl','/manage/schedule','/manage/qd']
const mapLocations = ['/manage/statistics','/manage','/manage/ips','/manage/setting','/manage/tkl','/manage/schedule','/manage/qd','/manage/tools','/manage/tools_num2']
class Main extends React.Component{
constructor(props){
super(props);
this.map = ['数据统计','数据统计','配置','淘口令','渠道管理']
this.map = ['口令数据','汇总数据','IP数据','推广页面管理','淘口令','推广计划','渠道管理','小工具','小工具2'];
console.dir(location.pathname);
var pathname = location.pathname;
console.dir(mapLocations.indexOf(pathname));
this.state = {
current: '1',
current: mapLocations.indexOf(pathname) >= 0 ? mapLocations.indexOf(pathname) : 0,
openKeys: [],
theme: 'dark',
username:null
......@@ -25,7 +28,8 @@ class Main extends React.Component{
handleClick(e){
//this.props.dispatch(actions.getMenu());
if(e.key == 6){
this.setState({current:e.key})
if(e.key == 9){
api('GET', 'logout').then(function(res){
if(res.result == 'ok') location.href = '/';
});
......@@ -48,7 +52,7 @@ class Main extends React.Component{
}
render(){
console.log(this.props.menu.currentPage);
console.log(this.state.current);
return (
<Layout className="layout">
<Header>
......@@ -58,25 +62,28 @@ class Main extends React.Component{
<Menu
theme="dark"
mode="horizontal"
defaultSelectedKeys = {[ this.props.menu.currentPage +'' ]}
defaultSelectedKeys = {[ this.state.current ]}
onClick={ this.handleClick.bind(this) }
style={{ lineHeight: '64px' }}
>
<SubMenu title={<span>数据统计</span>}>
<Menu.Item key="1">汇总数据</Menu.Item>
<Menu.Item key="0">口令数据</Menu.Item>
<Menu.Item key="2">IP数据</Menu.Item>
</SubMenu>
<Menu.Item key="2">推广页管理</Menu.Item>
<Menu.Item key="3">淘口令</Menu.Item>
<Menu.Item key="4">推广计划</Menu.Item>
<Menu.Item key="5">渠道管理</Menu.Item>
<Menu.Item key="6" style ={{ float:'right'}}><Icon type="logout" />{ this.state.username }</Menu.Item>
<Menu.Item key="3">推广页管理</Menu.Item>
<Menu.Item key="4">淘口令</Menu.Item>
<Menu.Item key="5">推广计划</Menu.Item>
<Menu.Item key="6">渠道管理</Menu.Item>
<Menu.Item key="7">小工具</Menu.Item>
<Menu.Item key="8">小工具2</Menu.Item>
<Menu.Item key="9" style ={{ float:'right'}}><Icon type="logout" />{ this.state.username }</Menu.Item>
</Menu>
</Header>
<Content style={{ padding: '0 50px' }}>
<Breadcrumb style={{ margin: '12px 0' }}>
<Breadcrumb.Item>{ this.map[ this.props.menu.currentPage ]}</Breadcrumb.Item>
<Breadcrumb.Item>{ this.props.menu.currentPage == '0' ? '数据统计' : (this.props.menu.currentPage == '0' ? '汇总数据' : "配置" )}</Breadcrumb.Item>
<Breadcrumb.Item>{ parseInt(this.state.current) < 3 ? '数据统计' : '配置与管理'}</Breadcrumb.Item>
<Breadcrumb.Item>{ this.map[ this.state.current ]}</Breadcrumb.Item>
</Breadcrumb>
<div style={{ background: '#fff', padding: 24, minHeight: 280 }}>{
this.props.children
......@@ -90,7 +97,7 @@ class Main extends React.Component{
}
}
function mapStateToProps (state) {
/*function mapStateToProps (state) {
return state;
}
module.exports = connect(mapStateToProps)(Main);
\ No newline at end of file
}*/
module.exports = Main;
\ No newline at end of file
const React = require('react');
/*const connect = require('react-redux').connect;
const actions = require('../../js/actions');*/
const moment = require('moment');
const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Badge} from 'antd';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Select,Radio} from 'antd';
const Option = Select.Option;
const { RangePicker } = DatePicker;
class Details extends React.Component{
class Ips extends React.Component{
constructor(props){
super(props);
console.dir(this.props);
this.state= { details :[],status:'pending',pagination:{current:1,pageSize:10,total:100},modalVisible:false,username:'channel',qd:null,date:null};
this.range = [moment().subtract(6,'days').format('YYYYMMDD'), moment().format('YYYYMMDD')];
this.state= { currentDate:null,qds:[],ips :[],status:'pending',pagination:{current:1,pageSize:100,total:1},sort:'updatedAt',currentQd:'all' };
}
getQueryString(name) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
var r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
componentDidMount(){
let pagination = this.state.pagination;
//alert(this.getQueryString('date') + this.getQueryString('qd'));
let qd = this.getQueryString('qd');
let date = this.getQueryString('date');
this.setState({qd:qd,date:date});
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]});
}
let pagination = this.state.pagination;
api('GET', 'qds?skip=0&limit=1000').then((res) => {
this.setState({qds:res.result});
});
//let data = { start:moment().add(-6,'days').format('YYYYMMDD'),end:moment().format('YYYYMMDD')};
api('GET', 'details?'+'skip=0&limit=' + pagination.pageSize+'&qd='+qd+'&date='+date).then((res) => {
this.setState({details:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total},info:{quan:'',good:''}})
console.dir(res.result);
api('GET', 'ips?'+'skip=0&limit=' + pagination.pageSize+'&qd=all').then((res) => {
this.setState({ips:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}})
});
}
getdetails(pagination){
console.dir(pagination);
getips(pagination,value,date){
api('GET', 'qds?skip=0&limit=1000').then((res) => {
this.setState({qds:res.result});
});
this.setState({status:'pending'});
api('GET', 'details?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize +'&qd=' + this.state.qd+'&date=' + this.state.date).then((res) => {
this.setState({details:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}})
console.dir(res.result);
var url = 'ips?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize;
if(value)
url += ('&qd='+ value);
if(date)
url += ('&date='+ date);
api('GET', url).then((res) => {
this.setState({ips:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}})
});
}
onChange(pagination) {
this.getdetails(pagination);
//let data = { start:dateString[0],end:dateString[1]};
this.getips(pagination,this.state.currentQd,this.state.currentDate);
//this.props.dispatch(actions.getMainData(data));
}
onChangeDate(date, dateString){
this.setState({currentDate:dateString});
this.getips({current:1,pageSize:this.state.pagination.pageSize},this.state.currentQd,dateString);
}
exportData(){
//json2xlsx(data,{sheetName:"基础数据", filename : '基础数据'+moment().format('YYYYMMDD')+'.xlsx'});
}
handleSort(e){
this.setState({sort:e.target.value});
this.getips({current:1,pageSize:this.state.pagination.pageSize},e.target.value);
}
handleChange(value) {
this.setState({currentQd:value});
this.getips({pageSize:this.state.pagination.pageSize,current:1},value,this.state.currentDate)
//console.log(`selected ${value}`);
}
render(){
console.dir(this.state.pagination);
let children = [<Option key='all'>全部</Option>];
for (var i = 0; i < this.state.qds.length; i++) {
let item = this.state.qds[i];
children.push(<Option key={item._id}>{ item.user }</Option>);
}
const columns = [
{
title: '渠道',
dataIndex: 'qd',
key: 'qd',
width: 60,
render: text => <span href="#">{text}</span>,
},
{
title: '计划ID',
dataIndex: 'schedule',
key: 'schedule',
title: '日期',
dataIndex: 'date',
key: 'date',
width: 100,
render: text => <span href="#">{text}</span>,
},
{
title: '商品页面',
dataIndex: 'link',
key: 'link',
title: 'ip',
dataIndex: 'ip',
key: 'ip',
width: 100,
render: text => <span href="#">{text}</span>,
},{
title: '次数',
dataIndex: 'times',
key: 'times',
width: 100,
render: text => <span href="#">{text}</span>,
},
{
title: '淘口令',
dataIndex: 'tkl',
key: 'tkl',
title: '渠道',
dataIndex: 'qd',
key: 'qd',
width: 100,
// sorter: (a, b) => { a.qd - b.qd},
render: text => <span href="#">{text}</span>,
},
{
title: '请求数',
dataIndex: 'times',
key: 'times',
width: 40,
render: text => <span href="#">{text}</span>
}
];
let data = [];
let details = this.state.details;
for(let i = 0;i<details.length;i++){
let count = 0;
let ips = this.state.ips;
for(let i = 0;i<ips.length;i++){
data.push({
key:i,
qd:details[i].info ,
schedule:details[i].schedule,
link:(details[i].link && details[i].link['target']) || '--',
tkl:details[i].status,
times:details[i].createdAt
ip:ips[i].ip,
date:ips[i].date,
times:ips[i].times,
qd:(ips[i]['qd'] && ips[i]['qd']['user']) || '--'
});
}
return (
<div>
<Alert
message="提示"
description="淘口令油后台任务自动生成"
type="info"
/>
<Spin spinning= { this.state.status == 'pending' }>
this.state.username == 'admin' ? <div>
<DatePicker onChange={ this.onChangeDate.bind(this) } format={'YYYYMMDD'} style={{ width:200,margin:'10px'}}/>
<Select
style={{ width:200,margin:'10px 0px'}}
placeholder="输入渠道名称"
defaultValue="all"
onChange={this.handleChange.bind(this)}
>
{children}
</Select>
<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>
</div>: <Alert
message="抱歉"
description="您没有权限"
type="warning"
/>
)
}
}
module.exports = Details;
/*
function mapStateToProps (state) {
return state;
}
module.exports = connect(mapStateToProps)(DashBoard);*/
module.exports = Ips;
......@@ -5,7 +5,7 @@ const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Modal,Form,Input,Switch} from 'antd';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Modal,Form,Input,Switch,InputNumber,message} from 'antd';
const { RangePicker } = DatePicker;
const FormItem = Form.Item;
......@@ -59,12 +59,48 @@ class Qd extends React.Component{
});
}
ipsChange(data,value){
console.dir(data);
console.dir(value);
var key = data['key'];
var qds = this.state.qds;
//console.dir(qds.length + '====');
qds[key]['iplimit'] = value;
console.dir(qds[key]['iplimit']);
this.setState({qds:qds});
}
putIpData(data){
console.dir(data);
api('POST','put_ip',{iplimit:data['ip'],id:data['id']}).then( res => {
message.success('执行成功, 影响'+ (res.result ? res.result.nModified : 0 )+" 条数据");
});
}
setModalVisible(b){
this.setState({modalVisible:b});
}
exportData(){
//json2xlsx(data,{sheetName:"基础数据", filename : '基础数据'+moment().format('YYYYMMDD')+'.xlsx'});
}
checkUpdate(qd){
var qds = this.state.qds;
var data = {
ipstatus:qd['ipstatus'] && qd['ipstatus'] == 'use' ? 'disable' : 'use',
id:qd['id']
}
var self = this;
api('POST', 'qd_update',data).then((res) => {
if(res.result && res.result.nModified){
message.success('执行成功, 影响'+ (res.result ? res.result.nModified : 0 )+" 条数据");
qds[qd['key']]['ipstatus'] = (qd['ipstatus'] && qd['ipstatus'] == 'use' ? 'disable' : 'use');
self.setState({qds:qds});
}
});
}
render(){
......@@ -104,6 +140,19 @@ class Qd extends React.Component{
key: 'tkl',
width: 40,
render: text => <span href="#">{text}</span>,
},
{
title: 'IP控制(状态 / 次数)',
dataIndex: 'ip',
key: 'ip',
width: 100,
render: (text,data) => <div>
<Switch checked={ data.ipstatus == 'use' ? true : false } onChange={this.checkUpdate.bind(this,data)} style = {{'marginRight': '10px'}}/>
<InputNumber min={0} max={1000000000000000} value = { text || 0 } onChange = { this.ipsChange.bind(this,data)}/>
<Button type="primary" onClick={ this.putIpData.bind(this,data) } style = {{ marginLeft:'10px' }}>
确定
</Button>
</div>
}
];
let data = [];
......@@ -111,10 +160,12 @@ class Qd extends React.Component{
for(let i = 0;i<qds.length;i++){
data.push({
key:i,
id:qds[i]._id ,
ipstatus:(qds[i].ipstatus) || 'disable',
id:qds[i]._id,
user:qds[i].user,
info:qds[i].info || '--',
schedule:(qds[i].schedule_count) || 0,
ip:(qds[i].iplimit) || 0,
tkl:(qds[i].tkl_count) || 0
});
}
......@@ -163,7 +214,7 @@ class Qd extends React.Component{
</Form>
</Modal>
</div>: <Alert
message="提示"
message="抱歉"
description="您没有权限"
type="warning"
/>
......
......@@ -4,40 +4,45 @@ const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Modal,Form,Input,Switch,message} from 'antd';
import { Table, Icon, Alert, Row, Col, Spin, Button,Modal,Form,Input,Switch,message,Select,DatePicker} from 'antd';
const { RangePicker } = DatePicker;
const Option = Select.Option;
const FormItem = Form.Item;
class Schedule extends React.Component{
constructor(props){
super(props);
console.dir(this.props);
this.state= { 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'};
}
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]){
this.setState({username:document.cookie.match('username=[a-zA-Z0-9]+')[0].split('=')[1]});
}
api('GET', 'qds?skip=0&limit=1000').then((res) => {
this.setState({qds:res.result});
});
//let data = { start:moment().add(-6,'days').format('YYYYMMDD'),end:moment().format('YYYYMMDD')};
api('GET', 'schedules?'+'skip=0&limit=' + pagination.pageSize).then((res) => {
this.setState({schedules:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total},info:{quan:'',good:''}})
console.dir(res.result);
});
}
getschedules(pagination){
getschedules(pagination,qd){
console.dir(pagination);
this.setState({status:'pending'})
api('GET', 'schedules?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize).then((res) => {
this.setState({status:'pending'});
var url = 'schedules?'+'skip='+ (pagination.current-1) + '&limit=' + pagination.pageSize;
if(qd && qd !== 'all')
url += ('&qd='+ qd);
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);
});
}
onChange(pagination) {
this.getschedules(pagination);
this.getschedules(pagination,this.state.currentQd);
}
createSchedule(){
......@@ -53,11 +58,12 @@ class Schedule extends React.Component{
var self = this;
this.props.form.validateFields((err, values) => {
if (!err) {
console.dir(values)
if(values['final'])
values['final'] = values.final.valueOf();
api('POST', 'schedule',values).then((res) => {
if(res && res.result){
self.setModalVisible(false);
self.getschedules({limit:this.state.pagination.pageSize,skip:0});
self.getschedules({pageSize:this.state.pagination.pageSize,current:1});
}
});
}
......@@ -66,7 +72,7 @@ class Schedule extends React.Component{
checkUpdate(schedule){
var schedules = this.state.schedules;
var data = {
status:schedule['status'] == 'use' ? 'disable' : 'use',
status:schedule['status'] && schedule['status']['status'] == 'use' ? 'disable' : 'use',
scheduleId:schedule['id']
}
var self = this;
......@@ -76,7 +82,7 @@ class Schedule extends React.Component{
message.success('执行成功, 生成'+ (res.new ? res.new.length : 0 )+" 条淘口令");
else
message.success('执行成功, 删除'+ (res.remove_result ? res.remove_result.nModified : 0 )+" 条淘口令");
schedules[schedule['key']]['status'] = (schedule['status'] == 'use' ? 'disable' : 'use');
schedules[schedule['key']]['status'] = (schedule['status'] && schedule['status']['status'] == 'use' ? 'disable' : 'use');
self.setState({schedules:schedules});
}
//message.success('执行成功, 生成 '+(res.new ? res.new.length : 0) +" 条,删除 "+ (res.remove_result ? res.remove_result.nModified : 0 )+" 条");
......@@ -84,17 +90,38 @@ class Schedule extends React.Component{
}
tklUpdate(schedule){
console.dir(schedule);
api('POST', 'newtkl',{id:schedule.id}).then((res) => {
if(res && res.result =='ok')
message.success('执行成功, 生成 '+(res.new ? res.new.length : 0) +" 条,删除 "+ (res.remove_result ? res.remove_result.nModified : 0 )+" 条");
});
}
autoUpdate(schedule){
var schedules = this.state.schedules;
var data = {
auto:schedule['status'] && schedule['status']['auto'] == 'use' ? 'disable' : 'use',
scheduleId:schedule['id']
}
var self = this;
api('POST', 'schedule_auto_update',data).then((res) => {
if(res && res.schedule){
schedules[schedule['key']]['auto'] = (schedule['status'] && schedule['status']['auto'] == 'use' ? 'disable' : 'use');
self.setState({schedules:schedules});
}
//message.success('执行成功, 生成 '+(res.new ? res.new.length : 0) +" 条,删除 "+ (res.remove_result ? res.remove_result.nModified : 0 )+" 条");
});
}
exportData(){
//json2xlsx(data,{sheetName:"基础数据", filename : '基础数据'+moment().format('YYYYMMDD')+'.xlsx'});
}
handleChange(value) {
this.setState({currentQd:value});
this.getschedules({pageSize:this.state.pagination.pageSize,current:1},value)
//console.log(`selected ${value}`);
}
render(){
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;
const columns = [
......@@ -123,30 +150,36 @@ class Schedule extends React.Component{
title: '可用淘口令',
dataIndex: 'tkls',
key: 'tkls',
width: 10,
render: text => <span href="#">{text}</span>,
},
{
title: '推广次数',
dataIndex: 'times',
key: 'times',
width: 50,
width: 5,
render: text => <span href="#">{text}</span>,
},
{
title: '创建日期',
dataIndex: 'create',
key: 'create',
width: 70,
width: 75,
render: text => <span href="#">{text}</span>,
},
{
title: '截止日期',
dataIndex: 'final',
key: 'final',
width: 75,
render: text => <span href="#">{text}</span>,
},{
title: '投放状态 / 操作',
title: '投放状态 / 手动替换 / 定时更新 ',
dataIndex: 'status',
key: 'status',
width: 30,
render: (text,schedule) => <div><Switch checked={ text == 'use' ? true : false } onChange={this.checkUpdate.bind(this,schedule)} style = {{'margin-right': '17px'}}/><Button onClick = {this.tklUpdate.bind(this,schedule)}>生成淘口令</Button></div>,
width: 130,
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>,
}
];
let children = [<Option key='all'>全部</Option>];
for (var i = 0; i < this.state.qds.length; i++) {
let item = this.state.qds[i];
children.push(<Option key={item._id}>{ item.user }</Option>);
}
let data = [];
let schedules = this.state.schedules;
for(let i = 0;i<schedules.length;i++){
......@@ -158,8 +191,9 @@ class Schedule extends React.Component{
data.push({
key:i,
id:(schedules[i]._id && schedules[i]._id) || '--',
final:schedules[i].final || '--',
names:names || '--',
status:schedules[i].status,
status:{ status:schedules[i].status,auto:schedules[i].auto},
qd:((schedules[i].qd && schedules[i].qd['user']) || '--') + ' /' + ((schedules[i].qd && schedules[i].qd['_id']) || '--'),
tkls:(schedules[i].count),
times:schedules[i].times,
......@@ -171,6 +205,14 @@ class Schedule extends React.Component{
<Button type="primary" icon="plus" onClick={ this.createSchedule.bind(this) } style={{ margin:'10px 0px'}}>
创建计划
</Button>
<Select
style={{ float:'right',width:200,margin:'10px 0px'}}
placeholder="输入渠道名称"
defaultValue="all"
onChange={this.handleChange.bind(this)}
>
{children}
</Select>
<Spin spinning= { this.state.status == 'pending' }>
<Table columns={columns} dataSource = { data } size="middle" pagination={ this.state.pagination } onChange = { this.onChange.bind(this)} bordered/>
</Spin>
......@@ -203,6 +245,15 @@ class Schedule extends React.Component{
<Input prefix={<span style={{ fontSize: 13 }}>推广次数</span>} placeholder="例如:1000000" />
)}
</FormItem>
<FormItem>
<span style={{ fontSize: 13,display:"block" }}>截止日期</span>
{getFieldDecorator('final',{ type: 'object', required: true, message: 'Please select time!' })(
<DatePicker
showTime
format="YYYY-MM-DD HH:mm:ss"
placeholder="选择"/>
)}
</FormItem>
<FormItem>
<Button type="primary" htmlType="submit" className="login-form-button">
一键生成
......@@ -211,7 +262,7 @@ class Schedule extends React.Component{
</Form>
</Modal>
</div>: <Alert
message="提示"
message="抱歉"
description="您没有权限"
type="warning"
/>
......
......@@ -4,7 +4,8 @@ const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Modal,Form,Input} from 'antd';
import { Table, Icon, DatePicker, Alert, Row, Col, Spin, Button,Modal,Form,Input,Radio} from 'antd';
const RadioGroup = Radio.Group;
const { RangePicker } = DatePicker;
const FormItem = Form.Item;
......@@ -13,7 +14,7 @@ class Agent extends React.Component{
constructor(props){
super(props);
console.dir(this.props);
this.state= { links :[],status:'pending',pagination:{current:1,pageSize:10,total:1},modalVisible:false,username:'channel'};
this.state= { links :[],status:'pending',pagination:{current:1,pageSize:500,total:1},modalVisible:false,username:'channel'};
}
componentDidMount(){
let pagination = this.state.pagination;
......@@ -53,6 +54,9 @@ class Agent extends React.Component{
var self = this;
this.props.form.validateFields((err, values) => {
if (!err) {
for(var k in values){
if(values[k]) values[k] = values[k].trim();
}
api('POST', 'link',values).then((res) => {
if(res && res.result){
self.setModalVisible(false);
......@@ -105,7 +109,7 @@ class Agent extends React.Component{
render: text => <span href="#">{text}</span>,
},
{
title: '二合一',
title: '目标链接',
dataIndex: 'target',
key: 'target',
width: 100,
......@@ -193,6 +197,16 @@ class Agent extends React.Component{
<Input prefix={<span style={{ fontSize: 13 }}>PID</span>} placeholder="例如:mm_33320967_40070156_153504280" />
)}
</FormItem>
<FormItem
label="推广使用"
>
{getFieldDecorator('select')(
<RadioGroup>
<Radio value="quan">优惠券链接</Radio>
<Radio value="target">二合一链接</Radio>
</RadioGroup>
)}
</FormItem>
<FormItem>
<Button type="primary" htmlType="submit" className="login-form-button">
一键生成
......@@ -201,7 +215,7 @@ class Agent extends React.Component{
</Form>
</Modal>
</div> : <Alert
message="提示"
message="抱歉"
description="您没有权限"
type="warning"
/>
......
......@@ -107,14 +107,14 @@ class Tbkls extends React.Component{
this.state.username == 'admin' ? <div>
<Alert
message="提示"
description="淘口令后台任务自动生成"
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>: <Alert
message="提示"
message="抱歉"
description="您没有权限"
type="warning"
/>
......
const React = require('react');
const moment = require('moment');
const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, DatePicker, Alert, Spin, Button,Badge,Form,Input,InputNumber,Row,Col,message,Card} from 'antd';
const FormItem = Form.Item;
class Tools extends React.Component{
constructor(props){
super(props);
console.dir(this.props);
this.state= { tkls:[],good:{title:'',pict_url:'',target:''} ,status:'pending'};
}
componentDidMount(){
}
handleSubmit(e){
e.preventDefault();
var self = this;
this.props.form.validateFields((err, values) => {
if (!err) {
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.getTkls(values);
}
});
}
getTkls(data){
//this.setState({status:'pending'});
api('POST', 'tool2_tbkls',data).then((res) => {
//this.setState({details:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}})
if(res.result && res.good) this.setState({tkls:res.result,good:res.good,status:'ready'});
else message.warn('请求错误');
});
}
render(){
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;
var list = [];
this.state.tkls.forEach(item => {
list.push(<span className ='model' >{ item.model }</span>)
});
return (
<div className ='tool-box'>
<Form onSubmit={this.handleSubmit.bind(this)} className="login-form" style ={{ width:'50%','max-width': '350px','min-width': '300px','background': '#ddd','padding': '10px'}}>
<FormItem
label="淘口令数量"
>
{getFieldDecorator('num', { initialValue: 10 })(
<InputNumber min={1} max={100} />
)}
<span className="ant-form-text"></span>
</FormItem>
<FormItem>
{getFieldDecorator('url', {
rules: [{ required: true, message: '链接不能为空' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>优惠券链接</span>} placeholder="例如:https://taoquan.taobao.com/coupon/unify_apply.htm?sellerId=2194810505&activityId=5c3186407cd441d48ecd2460815793e6" />
)}
</FormItem>
<FormItem>
{getFieldDecorator('logo', {
rules: [{ required: false, message: '图片链接不能为空' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>图片链接</span>} placeholder="例如:https://detail.tmall.com/item.htm?id=40663494639" />
)}
</FormItem>
<FormItem>
{getFieldDecorator('text', {
rules: [{ required: true, message: '推广语' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>推广语</span>} placeholder="例如:mm_33320967_40070156_153504280" />
)}
</FormItem>
<FormItem>
<Button type="primary" htmlType="submit" className="login-form-button">
一键生成
</Button>
</FormItem>
</Form>
{
this.state.status !== 'pending' ?
<div style ={{ padding:'50px 30px','min-width':'500px'}}>
<div className ='label-info'>
<label>LOGO大图</label>
<img src = { this.state.good.logo } />
</div>
<div className ='label-info'>
<label>推广语</label>
<div><p>{ this.state.good.text }</p></div>
</div>
<div className ='label-info'>
<label>目标连接</label>
<div><p>{ this.state.good.url }</p></div>
</div>
<label className='tkllabel'>淘口令</label>
<div className = 'model-box'>
{ list }
</div>
</div> : <div className ='none'>填写内容,尝试生成淘口令吧 ~ ~</div>
}
</div>
)
}
}
Tools = Form.create()(Tools);
module.exports = Tools;
const React = require('react');
const moment = require('moment');
const api = require('../../js/api');
import json2xlsx from '../../js/json2xlsx';
import { Table, Icon, DatePicker, Alert, Spin, Button,Badge,Form,Input,InputNumber,Row,Col,message,Card} from 'antd';
const FormItem = Form.Item;
class Tools extends React.Component{
constructor(props){
super(props);
console.dir(this.props);
this.state= { tkls:[],good:{title:'',pict_url:'',target:''} ,status:'pending'};
}
componentDidMount(){
}
handleSubmit(e){
e.preventDefault();
var self = this;
this.props.form.validateFields((err, values) => {
if (!err) {
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.getTkls(values);
}
});
}
getTkls(data){
//this.setState({status:'pending'});
api('POST', 'tool_tbkls',data).then((res) => {
//this.setState({details:res.result,status:'ready',pagination:{current:res.pagination.skip,pageSize:res.pagination.limit,total:res.pagination.total}})
if(res.result && res.good) this.setState({tkls:res.result,good:res.good,status:'ready'});
else message.warn('请求错误');
});
}
render(){
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;
var list = [];
this.state.tkls.forEach(item => {
list.push(<span className ='model' >{ item.model }</span>)
});
return (
<div className ='tool-box'>
<Form onSubmit={this.handleSubmit.bind(this)} className="login-form" style ={{ width:'50%','max-width': '350px','min-width': '300px','background': '#ddd','padding': '10px'}}>
<FormItem
label="淘口令数量"
>
{getFieldDecorator('num', { initialValue: 10 })(
<InputNumber min={1} max={100} />
)}
<span className="ant-form-text"></span>
</FormItem>
<FormItem>
{getFieldDecorator('quan', {
rules: [{ required: true, message: '优惠券链接不能为空' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>优惠券链接</span>} placeholder="例如:https://taoquan.taobao.com/coupon/unify_apply.htm?sellerId=2194810505&activityId=5c3186407cd441d48ecd2460815793e6" />
)}
</FormItem>
<FormItem>
{getFieldDecorator('good', {
rules: [{ required: true, message: '商品连接不能为空' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>商品连接</span>} placeholder="例如:https://detail.tmall.com/item.htm?id=40663494639" />
)}
</FormItem>
<FormItem>
{getFieldDecorator('pid', {
rules: [{ required: true, message: 'pid不能为空' }],
})(
<Input prefix={<span style={{ fontSize: 13 }}>PID</span>} placeholder="例如:mm_33320967_40070156_153504280" />
)}
</FormItem>
<FormItem>
<Button type="primary" htmlType="submit" className="login-form-button">
一键生成
</Button>
</FormItem>
</Form>
{
this.state.status !== 'pending' ?
<div style ={{ padding:'50px 30px','min-width':'500px'}}>
<div className ='label-info'>
<label>LOGO大图</label>
<img src = { this.state.good.pict_url } />
</div>
<div className ='label-info'>
<label>推广语</label>
<div><p>{ this.state.good.title }</p></div>
</div>
<div className ='label-info'>
<label>二合一连接</label>
<div><p>{ this.state.good.target }</p></div>
</div>
<label className='tkllabel'>淘口令</label>
<div className = 'model-box'>
{ list }
</div>
</div> : <div className ='none'>填写内容,尝试生成淘口令吧 ~ ~</div>
}
</div>
)
}
}
Tools = Form.create()(Tools);
module.exports = Tools;
......@@ -14,7 +14,7 @@ class DashBoard extends React.Component{
constructor(props){
super(props);
this.range = [moment().subtract(6,'days').format('YYYYMMDD'), moment().format('YYYYMMDD')];
this.range = [moment().subtract(14,'days').format('YYYYMMDD'), moment().format('YYYYMMDD')];
this.state= { logs :[],status:'pending',pagination:{current:1,pageSize:100,total:1},sort:'updatedAt' };
}
componentDidMount(){
......
This diff is collapsed.
......@@ -5,7 +5,9 @@ module.exports = {
//mongo:'mongodb://127.0.0.1:27017/taoarticle',
taobao: {
host:"http://gw.api.taobao.com/router/rest",
appKey:"24594025",//"23580470",//"23390725",
appSecret:'def2396c763580d49e4a0aa15c4c18bd'//"e5f350cbdbd6db2a8727f0b65dac1f7c",//"0575587ba36b29fa5680ad571c5e51f4"
appKey:"23390725",
appSecret:'0575587ba36b29fa5680ad571c5e51f4'
//appKey:"24594025",//"23580470",//"23390725",
// appSecret:'def2396c763580d49e4a0aa15c4c18bd'//"e5f350cbdbd6db2a8727f0b65dac1f7c",//"0575587ba36b29fa5680ad571c5e51f4"
}
};
\ No newline at end of file
......@@ -4,7 +4,9 @@ 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:"24594025",//"23580470",//"23390725",
appSecret:'def2396c763580d49e4a0aa15c4c18bd'//"e5f350cbdbd6db2a8727f0b65dac1f7c",//"0575587ba36b29fa5680ad571c5e51f4"
appKey:"23390725",
appSecret:'0575587ba36b29fa5680ad571c5e51f4'
//appKey:"24594025",//"23580470",//"23390725",
//appSecret:'def2396c763580d49e4a0aa15c4c18bd'//"e5f350cbdbd6db2a8727f0b65dac1f7c",//"0575587ba36b29fa5680ad571c5e51f4"
}
};
\ No newline at end of file
......@@ -13,6 +13,14 @@ const schema = mongoose.Schema({
required: true,
set: v => hash(v)
},
ipstatus:{
type:String,
required:false
},
iplimit:{
type:Number,
required:false
},
info:{
type: String,
unique: false
......
const mongoose = require('mongoose');
const {ObjectId} = mongoose.SchemaTypes;
const schema = mongoose.Schema({
ip: {
type: String,
required: true
},
date:{
type:String,
required:true
},
qd: {
type: ObjectId,
ref:'tao-agent',
required: true
},
times:{
type:Number,
required:true
}
}, {
timestamps: true
});
schema.index({ip: 1});
module.exports = mongoose.model('tao-ip', schema);
......@@ -15,6 +15,14 @@ const schema = mongoose.Schema({
times:{
type:Number,
required: true
},
auto:{
type:String,
required: false
},
final:{
type:Number,
required:false
}
}, {
timestamps: true
......
This diff is collapsed.
......@@ -51,6 +51,13 @@ async function tbklTask () {
schedules.forEach( async item => {
let schedule = item.toJSON()._id;
var qd = item.toJSON().qd;
var tasks_schedules = [];
var tasks_schedule_koulings = [];
if(item.final && item.final < moment().format('x')){
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});
......@@ -76,6 +83,12 @@ async function tbklTask () {
tasks_log.push(Log.update({_id:item._id},{$set:{status:'disable'}}));
}
});
if(tasks_schedule_koulings.length && tasks_schedules.length){
var tasks_schedule_koulings_arr = await Promise.all(tasks_schedule_koulings);
var tasks_schedules_arr = await Promise.all(tasks_schedules);
console.log('更新计划 结束 影响' + tasks_schedules_arr.length + '条数据');
console.log('更新计划相关口令 影响' + tasks_schedule_koulings_arr.length + '条数据');
}
if(tasks_new.length&&tasks_old.length&&tasks_log.length){
var oldArrs = await Promise.all(tasks_old)
var logArrs = await Promise.all(tasks_log);
......
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 = 10000;
var CronJob = cron.CronJob;
var job = new CronJob({
cronTime: '0 */30 * * * *',
onTick: function() {
tbklTask();
},
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 {
//let tkls = await Kouling.find({status:'use'}).populate('link','title target').limit(1000);
// 查询进行中计划
let schedules = await Schedule.find({status:'use'}).populate('links').limit(500);
if(schedules.length == 0) console.log(' auto 更新结束 无任务');
else
schedules.forEach( async item => {
item = item.toJSON();
var schedule = item._id;
var qd = item.qd;
var auto = item.auto;
var links = item.links;
// 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);
var tasks_new = [];
var tasks_old = [];
if(auto == 'use'){
links.forEach( _item => {
var data = {
title:_item.title,
target:_item.target,
schedule:schedule,
link:_item._id,
status:'use',
qd:qd,
pic:_item.pic
}
for(var i = 0;i<10; i++){
tasks_new.push(controller.createTbkl(data));
}
tasks_old.push(Kouling.update({schedule:schedule,status:{$ne:'disable'}},{$set:{status:'disable'}},{multi:true}));
//tasks_log.push(Log.update({_id:item._id},{$set:{status:'disable'}}));
});
}
if(tasks_old.length){
var oldArrs = await Promise.all(tasks_old);
console.dir(oldArrs);
console.log('auto 删除老口令 结束 影响' + oldArrs.length + '条数据');
}
if(tasks_new.length){
var newArrs = await Promise.all(tasks_new);
console.dir(newArrs);
console.log('auto 增加新口令 结束 影响' + newArrs.length + '条数据');
}
if(tasks_new.length || tasks_old.length){
console.log(' auto 更新计划'+ item._id +'结束 有任务');
}
else{
console.log(' auto 更新结束 '+ item._id +' 无任务');
}
});
} catch (err) {
console.dir(err);
console.dir('更新异常 =====>');
let mailList = 'liusong@goyoo.com';
sendMail(mailList, err.toString());
}
}
module.exports.start = function ()
{
job.start();
};
......@@ -76,6 +76,8 @@ exports.getGood = (id) => {
'platform':'1',
'num_iids':id
},function(error, response) {
console.dir(error);
console.dir(response);
if(response.results && response.results.n_tbk_item && response.results.n_tbk_item[0] && !error) r(response.results.n_tbk_item[0]);
else d(error || 'unknown error');
});
......@@ -89,8 +91,28 @@ exports.createTbkl = (title,url,pic) => {
'url':url,
'logo':pic
}, function(error, response) {
console.dir(error);
console.dir(response);
if (response && response.data && !error) r(response.data);
else d(error);
})
});
}
exports.createnormalTbkl = (title,url,pic) => {
return new Promise((r,d) => {
var data = {
'text':title,
'url':url
};
if(pic)
data['logo'] = pic;
client.execute('taobao.wireless.share.tpwd.create', {tpwd_param:data}, function(error, response) {
console.dir(error);
console.dir(response);
if (response && !error) r(response);
else d(error);
})
});
}
\ No newline at end of file
const config = require('../config/index');
const tao = require('./tao');
const mongoose = require('mongoose');
const Link = require('../db/mongo/tao-link');
const url = require('url');
global.Promise = mongoose.Promise = require('bluebird');
var map = {
"mm_32247283_40828228_165418621":"mm_26653811_40818629_165538497",
"mm_32247283_40828228_165436284":"mm_26653811_40818629_165524713",
"mm_32247283_40828228_165412765":"mm_26653811_40818629_165512995",
"mm_32247283_40828228_165428432":"mm_26653811_40818629_165556147",
"mm_32247283_40828228_165410854":"mm_26653811_40818629_165544355",
"mm_32247283_40828228_165410854":"mm_26653811_40818629_165536576",
"mm_32247283_40828228_165436294":"mm_26653811_40818629_165556151",
"mm_32247283_40828228_165426474":"mm_26653811_40818629_165516975",
"mm_32247283_40828228_165418633":"mm_26653811_40818629_165522716",
"mm_32247283_40828228_165436297":"mm_26653811_40818629_165558027",
"mm_32247283_40828228_165430368":"mm_26653811_40818629_165516976",
"mm_32247283_40828228_165404879":"mm_26653811_40818629_165534578",
"mm_32247283_40828228_165420613":"mm_26653811_40818629_165514883",
"mm_32247283_40828228_165432351":"mm_26653811_40818629_165556142",
"mm_32247283_40828228_165412776":"mm_26653811_40818629_165514897",
"mm_32247283_40828228_165428747":"mm_26653811_40818629_165526725",
"mm_32247283_40828228_165438626":"mm_26653811_40818629_165524728",
"mm_32247283_40828228_165448438":"mm_26653811_40818629_165522725",
"mm_32247283_40828228_165432741":"mm_26653811_40818629_165552199",
"mm_32247283_40828228_165442582":"mm_26653811_40818629_165530703",
"mm_32247283_40828228_165424941":"mm_26653811_40818629_165536596",
"mm_32247283_40828228_165412788":"mm_26653811_40818629_165554205",
"mm_32247283_40828228_165432381":"mm_26653811_40818629_165548277",
"mm_32247283_40828228_165448106":"mm_26653811_40818629_165542506",
"mm_32247283_40828228_165446155":"mm_26653811_40818629_165526743",
"mm_32247283_40828228_165438287":"mm_26653811_40818629_165528787",
"mm_32247283_40828228_165418651":"mm_26653811_40818629_165542512",
"mm_32247283_40828228_165438290":"mm_26653811_40818629_165520897",
"mm_32247283_40828228_165422578":"mm_26653811_40818629_165560023",
"mm_32247283_40828228_165430397":"mm_26653811_40818629_165528793",
"mm_32247283_40828228_165430398":"mm_26653811_40818629_165554217",
"mm_32247283_40828228_165448428":"mm_26653811_40818629_165558060",
"mm_32247283_40828228_165448429":"mm_26653811_40818629_165538530",
"mm_32247283_40828228_165422602":"mm_26653811_40818629_165526760",
"mm_32247283_40828228_165412828":"mm_26653811_40818629_165560042",
"mm_32247283_40828228_165408900":"mm_26653811_40818629_165562027",
"mm_32247283_40828228_165420678":"mm_26653811_40818629_165530741",
"mm_32247283_40828228_165428487":"mm_26653811_40818629_165514932",
"mm_32247283_40828228_165440306":"mm_26653811_40818629_165558078",
"mm_32247283_40828228_165424636":"mm_26653811_40818629_165528806",
"mm_32247283_40828228_165404947":"mm_26653811_40818629_165530745",
"mm_32247283_40828228_165416723":"mm_26653811_40818629_165554240",
"mm_32247283_40828228_165436350":"mm_26653811_40818629_165546312"}
function getQueryString(name,url,pid) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
var r = url.replace(reg,'&pid='+ pid +'&');
return r;
if (r != null) {
return unescape(r[2]);
}
return null;
}
const options = {
useMongoClient: true
};
mongoose.connect(config.mongo, options);
async function run(){
console.dir('items.length =======');
var items = await Link.find({});
console.dir('=======');
console.dir(items.length);
var tasks = [];
var count = 0;
items.forEach( item => {
var pid = item.pid;
count++;
/* console.log('=='+item.target);
console.log(getQueryString('pid',item.target));*/
//console.dir(item.pid == getQueryString('pid',item.target));
if(map[pid]){
tasks.push(Link.update({_id:item._id},{$set:{pid:map[pid],target:getQueryString('pid',item.target,map[pid])}}));
//var result = await Link.update({_id:_id},{$set:{pid:map[pid],target:getQueryString('pid',item.target,map[pid])}});
//console.dir(result);
}
});
var arrs = await Promise.all(tasks);
console.dir(arrs);
}
run();
\ No newline at end of file
......@@ -15,6 +15,8 @@
"cookie-parser": "^1.4.3",
"cookie-session": "^1.3.0",
"cron": "^1.2.1",
"echarts": "^3.8.5",
"echarts-for-react": "^2.0.4",
"es6-promise": "^4.0.5",
"eslint-plugin-react": "^7.1.0",
"express": "^4.14.1",
......
......@@ -20,13 +20,22 @@ router.post('/newtkl',controller.newTbkl);
router.post('/link',controller.createLink);
router.post('/put_data',controller.putGatherData);
router.post('/put_ip',controller.putIp);
router.post('/qd_update',controller.putQdUpdate);
//router.get('/details',controller.getDetails);
router.post('/tool_tbkls',controller.adminTbkl);
router.post('/tool2_tbkls',controller.admin2Tbkl);
router.get('/schedules',controller.getSchedules);
router.post('/schedule',controller.createSchedule);
router.post('/schedule_update',controller.updateSchedule);
router.post('/schedule_auto_update',controller.updateAutoSchedule);
router.get('/gathers/qd',controller.getQdGatherData);
router.get('/gatherall',controller.getAllGatherData);
router.get('/ips',controller.getIps);
module.exports = router;
\ No newline at end of file
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