Showing
6 changed files
with
201 additions
and
6 deletions
@@ -5,11 +5,14 @@ | @@ -5,11 +5,14 @@ | ||
5 | */ | 5 | */ |
6 | 6 | ||
7 | const _ = require('lodash'); | 7 | const _ = require('lodash'); |
8 | +const fs = require('fs'); | ||
9 | +const Req = require('request-promise'); | ||
8 | const moment = require('moment'); | 10 | const moment = require('moment'); |
9 | const Router = require('koa-router'); | 11 | const Router = require('koa-router'); |
10 | const r = new Router(); | 12 | const r = new Router(); |
11 | const Mysql = require('../../../lib/mysql-promise'); | 13 | const Mysql = require('../../../lib/mysql-promise'); |
12 | const pager = require('../utils/pager'); | 14 | const pager = require('../utils/pager'); |
15 | +const xlsx = require('xlsx'); | ||
13 | 16 | ||
14 | const config = require('../../../config/config'); | 17 | const config = require('../../../config/config'); |
15 | const singleBrandKeyPre = config.singleBrandKeyPre; | 18 | const singleBrandKeyPre = config.singleBrandKeyPre; |
@@ -175,7 +178,59 @@ r.post('/save', async (ctx) => { | @@ -175,7 +178,59 @@ r.post('/save', async (ctx) => { | ||
175 | 178 | ||
176 | result.code = 200; | 179 | result.code = 200; |
177 | return ctx.response.body = result; | 180 | return ctx.response.body = result; |
178 | -}) | 181 | +}); |
182 | + | ||
183 | +r.post('/upload', async(ctx) => { | ||
184 | + if (ctx.request.body._files) { | ||
185 | + let file = ctx.request.body._files.up_excel; | ||
186 | + const workbook = xlsx.readFile(file.path); | ||
187 | + const sheetNames = workbook.Props.SheetNames; | ||
188 | + const worksheet = workbook.Sheets[sheetNames[0]]; | ||
189 | + | ||
190 | + let json_data = xlsx.utils.sheet_to_json(worksheet); | ||
191 | + console.log(json_data); | ||
192 | + let post_data = []; | ||
193 | + _.each(json_data, (obj, index) => { | ||
194 | + if (obj.keyword) { | ||
195 | + post_data.push({ | ||
196 | + id: index, | ||
197 | + keyword: obj.keyword, | ||
198 | + describe: obj.describe || '' | ||
199 | + }) | ||
200 | + } | ||
201 | + }); | ||
202 | + console.log(post_data); | ||
203 | + if (post_data.length > 0) { | ||
204 | + return Req({ | ||
205 | + method: 'POST', | ||
206 | + uri: 'http://spiderwebhook.yoho.cn/importApiHot', // 'http://172.16.6.84:9100/importApiHot', | ||
207 | + body: { | ||
208 | + keywords: post_data | ||
209 | + }, | ||
210 | + json: true, | ||
211 | + timeout: 5000 | ||
212 | + }).then(res => { | ||
213 | + // console.log('res:', res); | ||
214 | + return ctx.response.body = res; | ||
215 | + }).catch(err => { | ||
216 | + // console.log(err); | ||
217 | + return ctx.response.body = { | ||
218 | + code: 301, | ||
219 | + message: '接口数据处理错误' | ||
220 | + } | ||
221 | + }); | ||
222 | + | ||
223 | + } else { | ||
224 | + return ctx.response.body = { | ||
225 | + code: 400, | ||
226 | + data: post_data, | ||
227 | + message: 'excel无数据或数据格式不正确!' | ||
228 | + } | ||
229 | + } | ||
230 | + | ||
231 | + | ||
232 | + } | ||
233 | +}); | ||
179 | 234 | ||
180 | module.exports = r; | 235 | module.exports = r; |
181 | 236 |
@@ -6,6 +6,7 @@ const md5 = require('md5'); | @@ -6,6 +6,7 @@ const md5 = require('md5'); | ||
6 | const moment = require('moment'); | 6 | const moment = require('moment'); |
7 | const pager = require('../utils/pager'); | 7 | const pager = require('../utils/pager'); |
8 | const seoModel = require('../models/seoModel'); | 8 | const seoModel = require('../models/seoModel'); |
9 | +const xlsx = require('xlsx'); | ||
9 | 10 | ||
10 | let r = new Router(); | 11 | let r = new Router(); |
11 | 12 | ||
@@ -149,7 +150,6 @@ const tdk = { | @@ -149,7 +150,6 @@ const tdk = { | ||
149 | 150 | ||
150 | ctx.response.body = result; | 151 | ctx.response.body = result; |
151 | }, | 152 | }, |
152 | - | ||
153 | edit: async(ctx, next) => { | 153 | edit: async(ctx, next) => { |
154 | let result = {code: 500, message: '非法参数'}; | 154 | let result = {code: 500, message: '非法参数'}; |
155 | 155 | ||
@@ -217,6 +217,75 @@ const tdk = { | @@ -217,6 +217,75 @@ const tdk = { | ||
217 | } | 217 | } |
218 | 218 | ||
219 | ctx.response.body = result; | 219 | ctx.response.body = result; |
220 | + }, | ||
221 | + upload: async(ctx, next) => { | ||
222 | + // console.log(ctx.request.body); | ||
223 | + let result = {code: 500, message: '非法参数'}; | ||
224 | + if (ctx.request.body._files) { | ||
225 | + let file = ctx.request.body._files.up_excel; | ||
226 | + const workbook = xlsx.readFile(file.path); | ||
227 | + // console.log('workbook=',workbook); | ||
228 | + const sheetNames = workbook.Props.SheetNames; | ||
229 | + const worksheet = workbook.Sheets[sheetNames[0]]; | ||
230 | + | ||
231 | + let json_data = xlsx.utils.sheet_to_json(worksheet); | ||
232 | + | ||
233 | + let post_data = []; | ||
234 | + | ||
235 | + // 处理EXCEL数据,并插入redis | ||
236 | + let createRedisData = async function (ctx, data, index) { | ||
237 | + if (index < data.length) { | ||
238 | + let obj = data[index]; | ||
239 | + let type = obj.type || ''; | ||
240 | + let key = obj.key || ''; | ||
241 | + let title = obj.title || ''; | ||
242 | + let keywords = obj.keywords || ''; | ||
243 | + let description = obj.description || ''; | ||
244 | + // console.log(obj, index); | ||
245 | + | ||
246 | + if (_.find(TYPE_LIST, ['type', type]) && key) { | ||
247 | + // console.log('type: ', type, key); | ||
248 | + let hashKey = key; | ||
249 | + if (type === 'url') { | ||
250 | + key = _.replace(key, /http[s]?:\/\//, ''); | ||
251 | + hashKey = md5(key); | ||
252 | + } | ||
253 | + | ||
254 | + //先删除掉相同值的字段 | ||
255 | + let exist = await ctx.redis.multi([['lrem', `tdk:${type}:links`, 1, hashKey]]).execAsync(); | ||
256 | + | ||
257 | + //插入List, 插入数据 | ||
258 | + let res = await ctx.redis.multi([ | ||
259 | + ['lpushx', `tdk:${type}:links`, hashKey], | ||
260 | + ['hmset', `tdk:${type}:${hashKey}`, 'key', key, 'title', title, 'keywords', keywords, | ||
261 | + 'description', description, 'modify_time', Date.parse(new Date()) / 1000] | ||
262 | + ]).execAsync(); | ||
263 | + | ||
264 | + if (res[1]) { | ||
265 | + if (!res[0]) { | ||
266 | + ctx.redis.lpush(`tdk:${type}:links`, hashKey); | ||
267 | + } | ||
268 | + } | ||
269 | + | ||
270 | + return createRedisData(ctx, data, index + 1); | ||
271 | + | ||
272 | + } else { | ||
273 | + return createRedisData(ctx, data, index + 1); | ||
274 | + } | ||
275 | + } else { | ||
276 | + result = { | ||
277 | + code: 200, | ||
278 | + data: data, | ||
279 | + message: `导入完成${index}条` | ||
280 | + }; | ||
281 | + console.log(result); | ||
282 | + ctx.response.body = result; | ||
283 | + } | ||
284 | + | ||
285 | + }; | ||
286 | + | ||
287 | + return createRedisData(ctx, json_data, 0); | ||
288 | + } | ||
220 | } | 289 | } |
221 | }; | 290 | }; |
222 | 291 | ||
@@ -720,6 +789,7 @@ r.get('/tdk', tdk.index); | @@ -720,6 +789,7 @@ r.get('/tdk', tdk.index); | ||
720 | r.post('/tdk/add', tdk.add); | 789 | r.post('/tdk/add', tdk.add); |
721 | r.post('/tdk/edit', tdk.edit); | 790 | r.post('/tdk/edit', tdk.edit); |
722 | r.post('/tdk/delete', tdk.delete); | 791 | r.post('/tdk/delete', tdk.delete); |
792 | +r.post('/tdk/upload', tdk.upload); | ||
723 | 793 | ||
724 | // 词根管理 | 794 | // 词根管理 |
725 | r.get('/rootwords', rootWords.index); | 795 | r.get('/rootwords', rootWords.index); |
@@ -128,7 +128,15 @@ | @@ -128,7 +128,15 @@ | ||
128 | <label style="margin-right:20px;"><input type="checkbox" id="check-all" style="margin-right:5px;">全选</label> | 128 | <label style="margin-right:20px;"><input type="checkbox" id="check-all" style="margin-right:5px;">全选</label> |
129 | <a data-toggle="modal" href="#pop" class="btn btn-default" style="margin-right:10px;">增加</a> | 129 | <a data-toggle="modal" href="#pop" class="btn btn-default" style="margin-right:10px;">增加</a> |
130 | <button class="btn btn-default delete-all" type="submit">删除</button> | 130 | <button class="btn btn-default delete-all" type="submit">删除</button> |
131 | - | 131 | + <form id="uploadForm" enctype="multipart/form-data" style="display: inline-block;"> |
132 | + <div href="javascript:void(0)" class="btn btn-default btn-upload-excel" style="margin-left:10px"> | ||
133 | + <input id="up_excel" name="up_excel" | ||
134 | + accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | ||
135 | + type="file" style="position: absolute; opacity: 0; width: 100px;"> | ||
136 | + 上传EXCEL | ||
137 | + </div> | ||
138 | + </form> | ||
139 | + <span>(excel必要字段type,key,title, keywords,description)</span> | ||
132 | <div class="input-append pull-right"> | 140 | <div class="input-append pull-right"> |
133 | <form id="query-form" action="/seo/tdk" class="query-form" method="get"> | 141 | <form id="query-form" action="/seo/tdk" class="query-form" method="get"> |
134 | <div class="btn-group"> | 142 | <div class="btn-group"> |
@@ -408,5 +416,24 @@ | @@ -408,5 +416,24 @@ | ||
408 | 416 | ||
409 | delTdk([data]); | 417 | delTdk([data]); |
410 | }); | 418 | }); |
419 | + | ||
420 | + $('#up_excel').on('change', function(e) { // EXCEL上传 | ||
421 | + let $form = $('#uploadForm')[0]; | ||
422 | + let formData = new FormData($form); | ||
423 | + $.ajax({ | ||
424 | + url: '/seo/tdk/upload', // web/actions/seo.js => tdk.upload | ||
425 | + data: formData, | ||
426 | + method: 'POST', | ||
427 | + cache: false, | ||
428 | + processData: false, | ||
429 | + contentType: false, | ||
430 | + success: function(res) { | ||
431 | + if(res.code === 200) { | ||
432 | + alert('上传完成!'); | ||
433 | + document.location.reload(); | ||
434 | + } | ||
435 | + } | ||
436 | + }); | ||
437 | + }); | ||
411 | }); | 438 | }); |
412 | </script> | 439 | </script> |
@@ -14,7 +14,7 @@ const defaults = { | @@ -14,7 +14,7 @@ const defaults = { | ||
14 | }, | 14 | }, |
15 | redis: { | 15 | redis: { |
16 | connect: { | 16 | connect: { |
17 | - host: '127.0.0.1', | 17 | + host: '192.168.102.49', //'127.0.0.1', |
18 | port: '6379', | 18 | port: '6379', |
19 | retry_strategy: options => { | 19 | retry_strategy: options => { |
20 | if (options.error && options.error.code === 'ECONNREFUSED') { | 20 | if (options.error && options.error.code === 'ECONNREFUSED') { |
@@ -73,7 +73,8 @@ | @@ -73,7 +73,8 @@ | ||
73 | "ssh2": "^0.5.4", | 73 | "ssh2": "^0.5.4", |
74 | "superagent": "^3.6.0", | 74 | "superagent": "^3.6.0", |
75 | "tar": "^2.2.1", | 75 | "tar": "^2.2.1", |
76 | - "utility": "^1.8.0" | 76 | + "utility": "^1.8.0", |
77 | + "xlsx": "^0.13.0" | ||
77 | }, | 78 | }, |
78 | "devDependencies": { | 79 | "devDependencies": { |
79 | "ada": "^1.1.0", | 80 | "ada": "^1.1.0", |
@@ -361,13 +361,55 @@ class HotKeywords extends React.Component { | @@ -361,13 +361,55 @@ class HotKeywords extends React.Component { | ||
361 | record.callbackFn = this.showOptionModal.bind(this); | 361 | record.callbackFn = this.showOptionModal.bind(this); |
362 | 362 | ||
363 | return record.id; | 363 | return record.id; |
364 | - } | 364 | + }; |
365 | + const props = { | ||
366 | + name: 'up_excel', | ||
367 | + action: '/hot-keywords/upload', // web/actions/hot-keywords.js | ||
368 | + accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', | ||
369 | + headers: { | ||
370 | + authorization: 'authorization-text', | ||
371 | + }, | ||
372 | + showUploadList: false, // 不显示文件列表 | ||
373 | + onChange(info) { | ||
374 | + message.destroy(); | ||
375 | + message.info(`正在上传中...${info.file.percent || 0}%`, 2); | ||
376 | + if(info.file.status === 'done') { | ||
377 | + // 因为不知道如何清除调fileList,所以只能以最后一个上传的文件状态为当前状态 | ||
378 | + let fileLength = info.fileList.length - 1 || 0; | ||
379 | + | ||
380 | + // fileList中的response是服务端返回的数据 | ||
381 | + if (info.fileList[fileLength] && info.fileList[fileLength].response && info.fileList[fileLength].response.code) { | ||
382 | + console.log(info.fileList[fileLength].response); | ||
383 | + if (info.fileList[fileLength].response.code === 400) { | ||
384 | + let msg = info.fileList[fileLength].response.message; | ||
385 | + console.log(msg); | ||
386 | + message.error(`上传失败! ${msg}`, 5); | ||
387 | + } else if (info.fileList[fileLength].response.code === 200) { | ||
388 | + message.success(`${info.file.name} 文件上传成功!`); | ||
389 | + document.location.reload(); | ||
390 | + } | ||
391 | + | ||
392 | + } | ||
393 | + console.log(info); | ||
394 | + } | ||
395 | + if(info.file.status === 'error') { | ||
396 | + message.error(`${info.file.name} 文件上传失败!`); | ||
397 | + } | ||
398 | + console.log(info); | ||
399 | + | ||
400 | + } | ||
401 | + }; | ||
365 | 402 | ||
366 | return ( | 403 | return ( |
367 | <div> | 404 | <div> |
368 | <div style={{ paddingBottom: 10 }}> | 405 | <div style={{ paddingBottom: 10 }}> |
369 | <Button type="primary" onClick={this.deleteTableRow} disabled={!hasSelected} loading={loading}>删除</Button> | 406 | <Button type="primary" onClick={this.deleteTableRow} disabled={!hasSelected} loading={loading}>删除</Button> |
370 | <Button type="primary" style={{ marginLeft: 10 }} onClick={this.addTableRow}>添加</Button> | 407 | <Button type="primary" style={{ marginLeft: 10 }} onClick={this.addTableRow}>添加</Button> |
408 | + <Upload {...props} style={{marginLeft: 10}}> | ||
409 | + <Button type="primary"> | ||
410 | + <Icon type="upload" />上传Excel | ||
411 | + </Button> | ||
412 | + </Upload> | ||
371 | {this.optionModal(showModal)} | 413 | {this.optionModal(showModal)} |
372 | </div> | 414 | </div> |
373 | 415 |
-
Please register or login to post a comment