Authored by 周少峰

Merge branch 'feature/extWord' of git.yoho.cn:OPENTECH/yoho-node-ci into feature/extWord

... ... @@ -5,13 +5,14 @@
*/
'use strict';
const _ = require('lodash');
const Router = require('koa-router');
const moment = require('moment');
const pager = require('../utils/pager');
const Mysql = require('../../../lib/mysql-promise');
const Promise = require('bluebird');
const r = new Router();
const rp = require('request-promise');
const multiAsync=(multi)=>{
return multi.execAsync().then(function(res) {
... ... @@ -157,16 +158,138 @@ r.get('/searchKeywords', async(ctx) => {
};
});
const insertWord = (keyword, mysql) => {
return mysql.query(`SELECT id FROM seo_keywords WHERE keyword = ?`, [keyword]).then(d => {
console.log(keyword, d, '--+++++++++++++++++++++++-');
if (d.length <= 0) {
return mysql.query(
`INSERT INTO seo_keywords SET keyword = ?, is_push = ?, yoho_goods_num= ?, add_time = ?`,
[keyword, 1, -2, moment().unix()]
);
}
return d;
});
}
//redis关键词同步到mysql
r.get('/syncWord', async(ctx) => {
let mysql = new Mysql();
let r = await mysql.query(`select * from seo_keywords`);
console.log(r[0].keyword, ' ===');
ctx.body = {
code: 200,
message: 'success',
data: r
};
return getDataList(ctx, "keywords_mana_list", 0, -1).then(d => {
return getDataValues(ctx, d[0]);
}).then(ddata => {
return Promise.map(ddata, (word) => insertWord(word, mysql), {concurrency: 15});
}).then(d => {
return ctx.body = {
code: 200,
message: 'success',
data: d
};
});
});
r.get('/expand', async(ctx) => {
let resData = {};
let q = ctx.request.query;
let query = q.query || '';
let page = parseInt(`0${ctx.query.page}`, 10) || 1;
let limit = parseInt(`0${ctx.query.limit}`, 10) || 10;
let mysql = new Mysql();
let total = 0;
let typeList = [
{
type: 'keyword',
name: '关键词'
},
{
type: 'wordroot',
name: '词 根'
},
{
type: 'goodnum',
name: '商品数'
}
];
let type = q.type || typeList[0].type;
let typeName = _.result(_.find(typeList, { 'type': type}), 'name') || typeList[0].name;
let wheres = '';
let conditions = [];
switch (query && type) {
case 'keyword':
wheres = ` AND keyword like '%%${query}%'`;
break;
case 'wordroot':
wheres += ' AND root_id = ?'
conditions.push(query);
break;
case 'brand':
wheres += ' AND brand_id = ?'
conditions.push(query);
break;
case 'sort':
wheres += ' AND sort_id = ?'
conditions.push(query);
break;
case 'goodnum':
wheres += ' AND yoho_goods_num >= ?'
conditions.push(query);
break;
}
return mysql.query(`SELECT COUNT(*) as total FROM seo_keywords WHERE 1 = 1 ${wheres}`, conditions).then(d => {
total = d[0] && d[0].total || 0;
conditions.push((page - 1) * limit, limit);
return mysql.query(`SELECT * FROM seo_keywords WHERE 1 = 1 ${wheres} limit ?, ?`, conditions);
}).then(d => {
resData.pager = pager(Math.floor((total - 1) / limit) + 1, ctx.query);
resData.tabs = _.map(d, (elem) => {
return Object.assign({}, elem, {
is_push: elem.is_push ? '是' : '否',
add_time: elem.add_time && moment(elem.add_time * 1000).format('YYYY-MM-DD HH:mm'),
});
});
resData.typeList = typeList;
resData.typeName = typeName;
resData.type = type;
resData.query = query;
return ctx.render('action/keywords/expand', resData);
});
});
r.post('/expand/del', async(ctx) => {
let q = ctx.request.body;
let ids = q.ids && JSON.parse(q.ids) || [];
let len = ids.length;
let marks = [];
if (len <= 0) {
return ctx.body = {
code: 400,
message: 'ids is empty',
data: ''
};
}
let mysql = new Mysql();
for(let i = 0; i < len; i++) {
marks.push('?');
}
return mysql.query(`DELETE FROM seo_keywords WHERE id IN (${marks.join(',')})`, ids).then(d => {
return ctx.body = {
code: 200,
message: 'success',
data: d
};
});
});
module.exports = r;
... ...
... ... @@ -33,7 +33,7 @@ module.exports = function(app) {
app.use(noAuth.routes(), noAuth.allowedMethods());
app.use(async(ctx, next) => {
if (ctx.session && ctx.session.user) {
await next();
} else {
... ...
<div class="pageheader">
<div class="media">
<div class="pageicon pull-left">
<i class="fa fa-th-list"></i>
</div>
<div class="media-body">
<ul class="breadcrumb">
<li><a href="/"><i class="glyphicon glyphicon-home"></i></a></li>
<li><a href="/keywords/expand">关键词管理</a></li>
</ul>
<h4>关键词管理</h4>
</div>
</div>
<!-- media -->
</div>
<div class="contentpanel project-index-page" style="padding-bottom:0;">
<div class="panel panel-default">
<div class="panel-body">
<label style="margin-right:20px;"><input id="allSelected" type="checkbox" style="margin-right:5px;">全选</label>
<a class="btn btn-default deleteAll">删除</a>
<div class="input-append pull-right">
<form id="query-form" action="/keywords/expand" class="query-form" method="get">
<div class="btn-group">
<button class="btn" type="button">
品牌
</button>
<input class="span2 query-key" type="text" name="brand" value="{{brand}}">
<ul class="dropdown-menu brand-menu"></ul>
</div>
<div class="btn-group">
<button class="btn" type="button">
品类
</button>
<input class="span2 query-key" type="text" name="sort" value="{{brand}}">
<ul class="dropdown-menu sort-menu"></ul>
</div>
<div class="btn-group">
<button class="btn tn-default dropdown-toggle" data-toggle="dropdown">
{{typeName}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
{{# typeList}}
<li><a href="?type={{type}}">{{name}}</a></li>
{{/ typeList}}
</ul>
<input class="span2 query-key" type="text" name="query" value="{{query}}">
</div>
<input type="hidden" name="type" value="{{type}}">
<button class="btn query-submit-btn" type="submit">搜索</button>
</form>
</div>
</div>
</div>
</div>
<div class="contentpanel project-index-page" style="padding-top:0;">
<div class="panel panel-default">
<div class="panel-body">
<table id="table-oper-log" class="table table-striped table-bordered building-table">
<thead>
<tr>
<th>ID</th>
<th>关键词</th>
<th>词根</th>
<th>品牌</th>
<th>品类</th>
<th>商品数</th>
<th>是否推送</th>
<th>添加时间</th>
<th>操作</th>
</tr>
</thead>
{{# tabs}}
<tr>
<td>
<label><input type="checkbox" data-id={{id}} >{{id}}</label>
</td>
<td>
<input class="values" value="{{keyword}}" disabled>
</td>
<td>
<input class="values" value="{{root}}" disabled>
</td>
<td>
<input class="values" value="{{brand}}" disabled>
</td>
<td>
<input class="values" value="{{sort}}" disabled>
</td>
<td>
{{yoho_goods_num}}
</td>
<td>
{{is_push}}
</td>
<td>
{{add_time}}
</td>
<td>
<button class="btn btn-default nostyle delete">删除</button>
</td>
</tr>
{{/ tabs}}
</table>
</div>
</div>
</div>
{{# pager}}
<div class="text-right">
<ul class="pagination">
{{# prePage}}
<li><a href="{{url}}">上一页</a></li>
{{/ prePage}}
{{# pages}}
<li class="{{#unless url}}disabled {{/unless}}{{#if cur}}active{{/if}}">
<a {{#if url}}href="{{url}}"{{^}}href="javascript:;"{{/if}}>{{num}}</a>
</li>
{{/ pages}}
{{# nextPage}}
<li><a href="{{url}}">下一页</a></li>
{{/ nextPage}}
</ul>
</div>
{{/ pager}}
<style>
.nostyle{
background: transparent;
}
input[type=checkbox]{
vertical-align: sub;
margin-right: 5px;
}
input[disabled]{
background: transparent;
border: none;
}
.text-right{
float: right;
margin-right: 20px;
margin-top:0;
}
.pages{
cursor: pointer;
}
.query-form .btn-group {
margin-bottom: 0;
margin-right: 5px;
}
.query-form .dropdown-toggle {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.query-form .query-key {
width: 300px;
height: 39px;
font-size: 14px;
vertical-align: middle;
outline: none;
}
.query-form .query-submit-btn {
height: 39px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.query-form .brand-menu,
.query-form .sort-menu {
right: 0px;
left: 59px;
}
</style>
<script>
var currentPage=1,pageCount=10,pageTotal;
var tabHead='<thead><tr><th>ID</th><th>关键词</th><th>操作</th></tr></thead>';
//删除
$(document).on('click', '.delete', function(){
var trDom = $(this).closest('tr');
var id = trDom.find('input[type="checkbox"]').data('id');
$.post('/keywords/expand/del', {ids:JSON.stringify([id])}, function(data){
if(data.code===200){
trDom.remove();
}
});
});
//全选
$('#allSelected').on('click', function(){
var check=false;
if($(this).attr('checked')){
check=true;
}
$("table :checkbox").attr("checked", check);
});
$('.deleteAll').on('click',function(){
let arr = [];
$("table :checkbox:checked").each(function(item){
arr.push($(this).data('id'));
});
if(!arr.length)return;
$.post('/keywords/expand/del', {ids:JSON.stringify(arr)}, function(data){
if(data.code===200){
location.reload();
}
});
});
$('.query-form .query-key').keydown(function(e){
if(e.keyCode === 13){
$('.query-form').submit(); //处理事件
return false;
}
});
</script>
\ No newline at end of file
... ...
... ... @@ -61,13 +61,18 @@
</li>
</ul>
</li>
<li class="parent"><a><i class="fa fa-list"></i> <span>静态资源</span></a>
<li class="parent"><a><i class="fa fa-list"></i> <span>静态资源</span>
<ul class="children">
<li><a href="/check/list">代码检查</a></li>
</ul>
</li>
<li><a href="/seo/tdk"><i class="fa fa-file-code-o"></i> <span>TDK管理</span></a></li>
<li><a href="/keywords"><i class="fa fa-list"></i> <span>关键词管理</span></a></li>
<li class="parent"><a><i class="fa fa-list"></i> <span>SEO管理</span></a>
<ul class="children">
<li><a href="/keywords/expand"> <span>关键词管理</span></a></li>
</ul>
</li>
{{/if}}
</ul>
... ...
... ... @@ -5,15 +5,12 @@ const config = require('../config/config');
class MysqlPromise {
constructor() {
this.connect().then(conn => {
this.conn = conn;
return conn;
});
this.connect();
}
connect() {
if (this.conn) {
return Promise.resolve(this.connect);
return Promise.resolve(this.conn);
}
return mysql.createConnection({
... ... @@ -23,6 +20,7 @@ class MysqlPromise {
port: config.mysql.port,
database: config.mysql.database
}).then(conn => {
this.conn = conn;
return conn;
}).catch(err => {
console.error(`mysql connect fail, err: ${err.message}`);
... ... @@ -30,9 +28,9 @@ class MysqlPromise {
});
}
query(sql) {
query(sql, values) {
return this.connect().then(d => {
return d.query(sql);
return d.query(sql, values);
}).catch(err => {
console.error(`mysql query, err: ${err.message}`);
return [];
... ...