提交 18b02c05 authored 作者: GOD_ZYX's avatar GOD_ZYX

Merge remote-tracking branch 'origin/master' into ecollage

# Conflicts: # build.zip # client-dist/index.html # client-dist/resources/manifest.9a71568a.js # client-dist/resources/manifest.ba4ceb42.js # client-dist/resources/manifest.f76f1c2b.js # server/routes/cookies.js # server/routes/index.js # server/routes/websocket.js
......@@ -2,4 +2,8 @@
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/console-polyfill.js"></script>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/html5shiv.min.js"></script>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/respond.min.js"></script>
<![endif]--><script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-ecollage/resources/manifest.9a71568a.js"></script><script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-ecollage/resources/vendor.435ab98c.js"></script><script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-ecollage/resources/app.903e6e31.js"></script></body></html>
\ No newline at end of file
<<<<<<< HEAD
<![endif]--><script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-ecollage/resources/manifest.9a71568a.js"></script><script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-ecollage/resources/vendor.435ab98c.js"></script><script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-ecollage/resources/app.903e6e31.js"></script></body></html>
=======
<![endif]--><script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/resources/manifest.ba4ceb42.js"></script><script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/resources/vendor.435ab98c.js"></script><script type="text/javascript" src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/resources/app.231a3501.js"></script></body></html>
>>>>>>> origin/master
差异被折叠。
!function(d){function e(e){for(var t,r,n=e[0],a=e[1],o=e[2],c=0,f=[];c<n.length;c++)r=n[c],s[r]&&f.push(s[r][0]),s[r]=0;for(t in a)Object.prototype.hasOwnProperty.call(a,t)&&(d[t]=a[t]);for(b&&b(e);f.length;)f.shift()();return i.push.apply(i,o||[]),u()}function u(){for(var e,t=0;t<i.length;t++){for(var r=i[t],n=!0,a=1;a<r.length;a++){var o=r[a];0!==s[o]&&(n=!1)}n&&(i.splice(t--,1),e=p(p.s=r[0]))}return e}var r={},l={3:0},s={3:0},i=[];function p(e){if(r[e])return r[e].exports;var t=r[e]={i:e,l:!1,exports:{}};return d[e].call(t.exports,t,t.exports,p),t.l=!0,t.exports}p.e=function(i){var e=[];l[i]?e.push(l[i]):0!==l[i]&&{0:1,5:1,6:1,7:1,8:1,9:1,10:1,11:1,12:1,13:1,14:1,15:1,16:1,17:1,18:1,19:1,20:1,21:1,22:1}[i]&&e.push(l[i]=new Promise(function(e,n){for(var t="resources/"+({}[i]||i)+"."+{0:"7e9c19881242",1:"31d6cfe0d16a",5:"b6a10460f085",6:"1b8137937536",7:"edadd3d1dece",8:"2b76410db4d0",9:"30b36ab56f09",10:"eb5caf8d2af7",11:"970f20fae48e",12:"fc688477e0f2",13:"9c95c5430f41",14:"d32639348e7f",15:"dfc0763315c8",16:"a6265ac4f731",17:"5ae35f0cd357",18:"abf993cecc16",19:"da1346fedd49",20:"68029434d520",21:"43ee51cf782c",22:"12c536f6abaf",23:"31d6cfe0d16a",24:"31d6cfe0d16a",25:"31d6cfe0d16a",26:"31d6cfe0d16a",27:"31d6cfe0d16a",28:"31d6cfe0d16a",29:"31d6cfe0d16a",30:"31d6cfe0d16a"}[i]+".css",a=p.p+t,r=document.getElementsByTagName("link"),o=0;o<r.length;o++){var c=(d=r[o]).getAttribute("data-href")||d.getAttribute("href");if("stylesheet"===d.rel&&(c===t||c===a))return e()}var f=document.getElementsByTagName("style");for(o=0;o<f.length;o++){var d;if((c=(d=f[o]).getAttribute("data-href"))===t||c===a)return e()}var u=document.createElement("link");u.rel="stylesheet",u.type="text/css",u.onload=e,u.onerror=function(e){var t=e&&e.target&&e.target.src||a,r=new Error("Loading CSS chunk "+i+" failed.\n("+t+")");r.request=t,delete l[i],u.parentNode.removeChild(u),n(r)},u.href=a,document.getElementsByTagName("head")[0].appendChild(u)}).then(function(){l[i]=0}));var t,r=s[i];if(0!==r)if(r)e.push(r[2]);else{var n=new Promise(function(e,t){r=s[i]=[e,t]});e.push(r[2]=n);var a,o=document.getElementsByTagName("head")[0],c=document.createElement("script");c.charset="utf-8",c.timeout=120,p.nc&&c.setAttribute("nonce",p.nc),c.src=p.p+"resources/"+({}[t=i]||t)+"."+{0:"44b419c5",1:"b54a4784",5:"09a1f3ee",6:"5788073d",7:"34107010",8:"3725acf5",9:"bbdfab9a",10:"d8fe47d7",11:"fea790d0",12:"bc06c483",13:"c50bed76",14:"21f6e4db",15:"3d4a809b",16:"eb41993a",17:"17faa579",18:"15cc538d",19:"d19d94e7",20:"e4881800",21:"ff867a66",22:"51a95842",23:"aa46f405",24:"f05a2d7d",25:"cd45549d",26:"2e14c205",27:"de19a8f2",28:"01ab5f90",29:"c6599869",30:"d3ea8c6f"}[t]+".js",a=function(e){c.onerror=c.onload=null,clearTimeout(f);var t=s[i];if(0!==t){if(t){var r=e&&("load"===e.type?"missing":e.type),n=e&&e.target&&e.target.src,a=new Error("Loading chunk "+i+" failed.\n("+r+": "+n+")");a.type=r,a.request=n,t[1](a)}s[i]=void 0}};var f=setTimeout(function(){a({type:"timeout",target:c})},12e4);c.onerror=c.onload=a,o.appendChild(c)}return Promise.all(e)},p.m=d,p.c=r,p.d=function(e,t,r){p.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},p.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},p.t=function(t,e){if(1&e&&(t=p(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(p.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)p.d(r,n,function(e){return t[e]}.bind(null,n));return r},p.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return p.d(t,"a",t),t},p.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},p.p="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/",p.oe=function(e){throw console.error(e),e};var t=window.webpackJsonp=window.webpackJsonp||[],n=t.push.bind(t);t.push=e,t=t.slice();for(var a=0;a<t.length;a++)e(t[a]);var b=n;u()}([]);
\ No newline at end of file
......@@ -58,6 +58,10 @@ export default class API {
headers.pmd5 = _config.data.pwd
delete _config.data.pwd
}
if (/tenant\/user\/login/gi.test(_config.url)) {
headers.pmd5 = _config.data.pwd
delete _config.data.pwd
}
_config.headers = _.assignIn(_config.headers, headers)
/* 判别传输方式 */
if (_config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
......
......@@ -21,7 +21,7 @@ export default {
methods: {
createSocket () {
let that = this
let socket = new WebSocket('wss://' + window.location.host.replace(/\:.*$/, '')) // eslint-disable-line
let socket = new WebSocket(window.location.protocol.replace(/http/gi, 'ws') + '//' + window.location.host) // eslint-disable-line
socket.binaryType = 'arraybuffer'
socket.onmessage = function (msg) {
......
const CryptoJS = require('./CryptoJs')
const hmacSHA256 = require('crypto-js/hmac-sha256')
const Hex = require('crypto-js/enc-hex')
/**
* 特殊加密方式, 翻转、加盐、base64, hmacSHA256、Hex
* 设置本地cookie,全部使用 httpOnly 本地js读取不了
* @param {[string]} str 要加密的字符串
* @param {[object]} res 请求响应对象
* @param {[string]} name 设置cookie的名字
* @param {[string]} domain 设置cookie的domain
*/
const setCookieByYiiWay = (str, res, name, domain) => {
let expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
// 翻转、加盐、base64
const salt = '0ZSGxuBkSJS5'
let sup = str.split('').reverse().join('')
let rad = Math.random()
let token = salt + sup + rad
sup = Buffer.from(token).toString('base64')
let serialize = `a:2:{i:0;s:4:"_SUP";i:1;s:${sup.length}:"${sup}";}`
let hamc = Hex.stringify(hmacSHA256(serialize, 'VzpR5JMDNqUsOZ0IFQARNLU9_0KLr9UC'))
sup = hamc + serialize
// 设置到cookie
let opts = { path: '/', domain: domain, expires: expires, httpOnly: true }
res.cookie(name, sup, opts)
}
/**
* 统一设置 cookie,采用对称加密算法,将数据放入cookie中
* @param {[string]} base64 base64字符串,必须传 base64转义过的 字符串
* @param {[object]} res 请求响应对象
* @param {[string]} name 设置cookie的名字
* @param {[string]} domain 设置cookie的domain
*/
const setCookieData = (base64, res, name, domain) => {
if (!base64) return
let expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
let pwd = Buffer.from(base64, 'base64').toString()
pwd = CryptoJS.encryptData(pwd)
// 设置到cookie
let opts = { path: '/', domain: domain, expires: expires, httpOnly: true }
res.cookie(name, pwd, opts)
}
/**
* 从cookie中,获取_SUP并解析成ticket
* @param {[string]} _SUP cookie设置的值
*/
const getTicket = (_SUP) => {
/* 服务端 解析ticket */
let s = decodeURIComponent(_SUP || '') // tools.cookies.getCookie('_SUP') ||
let ticket = ''
s = s.match(/"([\d\w=]+)";\}$/)
if (s && s.length === 2) {
s = Buffer.from(s[1], 'base64').toString()
s = s.slice(12, s.search('-TGT') + 4)
ticket = s.split('').reverse().join('')
}
return ticket
}
module.exports = {
getTicket: getTicket,
setCookieByYiiWay: setCookieByYiiWay,
setCookieData: setCookieData
}
const CryptoJS = require('crypto-js')
const _key = CryptoJS.enc.Utf8.parse('abczyxzhaoli')
const _iv = CryptoJS.enc.Utf8.parse('jkbm')
/**
* 对称加密,加密方法
* @param {[string]} data 要加密的数据字符串
* @returns - 返回加密过后的字符串
*/
const encryptData = (data) => {
let encryptedStr = ''
try {
let srcs = CryptoJS.enc.Utf8.parse(data)
let encrypted = CryptoJS.AES.encrypt(srcs, _key, { iv: _iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
encryptedStr = encrypted.ciphertext.toString().toUpperCase()
} catch (e) {
encryptedStr = data
console.error('加密错误', data)
console.error(e)
}
return encryptedStr
}
/**
* 对称解密,解密方法
* @param {[string]} data 要解密的数据字符串
* @returns - 返回解密过后的字符串
*/
const decryptData = (data) => {
let decryptedStr = ''
try {
let srcs = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(data))
let decrypt = CryptoJS.AES.decrypt(srcs, _key, { iv: _iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
} catch (e) {
decryptedStr = data
console.error('解密错误', data)
console.error(e)
}
return decryptedStr.toString()
}
module.exports = {
encryptData: encryptData,
decryptData: decryptData
}
/**
* 工具方法 - 日期时间 转化 y-m-d
* @param {[string]} timestamp 时间戳
* @param {[string]} separator 分隔符,默认 “-”
*/
const timestampToFormatDateStr = (timestamp, separator) => {
separator = separator || '-'
let y = new Date(timestamp).getFullYear()
let m = new Date(timestamp).getMonth() + 1
if (m < 10) {
m = '0' + m
} else {
m = m + ''
}
let d = new Date(timestamp).getDate()
if (d < 10) {
d = '0' + d
} else {
d = d + ''
}
return [y, m, d].join(separator)
}
/**
* 工具方法 - 播放时间 转化 h:m:s
* @param {[string]} timestamp 时间戳
* @param {[string]} separator 分隔符,默认 “:”
*/
const timestampToFormatTimeStr = (timestamp, separator) => {
separator = separator || ':'
timestamp = Math.floor(timestamp / 1000)
let h = Math.floor(timestamp / 3600)
let m = Math.floor((timestamp - h * 3600) / 60)
let s = (timestamp - h * 3600 - m * 60) % 60
function tenify (a) {
return a >= 10 ? a : '0' + a
}
let to = { h: tenify(h), m: tenify(m), s: tenify(s) }
let format = ['h', 'm', 's'].join(separator)
return format.replace(/h|m|s/g, k => to[k]).replace(/^00:/, '')
}
module.exports = {
timestampToFormatDateStr: timestampToFormatDateStr,
timestampToFormatTimeStr: timestampToFormatTimeStr
}
const fs = require('fs')
const path = require('path')
/**
* 删除目录,对应下面所有文件
* @param {[string]} dirPath 目录路径字符串
* @param {[function]} callback 删除成功或者失败时,回调函数
*/
const rmDir = (dirPath, callback) => {
fs.readdir(dirPath, (err, files) => {
if (err) { console.log(err) }
function next (index) {
if (index === files.length) return fs.rmdir(dirPath, callback)
let newPath = path.join(dirPath, files[index])
fs.stat(newPath, (err, stat) => {
if (err) { console.log(err) }
if (stat.isDirectory()) {
rmDir(newPath, () => next(index + 1))
} else {
fs.unlink(newPath, () => next(index + 1))
}
})
}
next(0)
})
}
/**
* 创建目录路径上所有目录,不存在则创建
* @param {[string]} dirPath 目录路径字符串
* @param {[function]} callback 删除成功或者失败时,回调函数
*/
const mkDir = (dirPath, callback) => {
let _path = path.resolve(dirPath).replace(/^\//gi, '')
let arrDir = _path.split('/')
let curPath = '/'
function next (index) {
if (index === arrDir.length) { callback && callback(); return }
curPath += arrDir[index] + '/'
fs.stat(curPath, (error, stats) => {
if (error || !stats.isDirectory()) {
fs.mkdir(curPath, (error) => {
if (error) { console.log('文件创建出错,可能没权限'); return }
next(index + 1)
})
} else {
next(index + 1)
}
})
}
next(0)
}
module.exports = {
rmDir: rmDir,
mkDir: mkDir
}
/* websocket-node */
const WebSocketServer = require('websocket').server
/* 定义全局变量 */
global.nsSocket = global.nsSocket || null
global.nsCoonPool = global.nsCoonPool || []
/**
* 创建 socketServer 端
* @param {[object]} _server 监听的服务接口对象
*/
const createServerSocket = (_server) => {
let _nsSocket = new WebSocketServer({ httpServer: _server, autoAcceptConnections: false })
/* 监听请求 */
_nsSocket.on('request', function (_req) {
/* 首先判断,socket连接是否合法 */
if (!_connectIsAllowed(_req)) { _req.reject(); return }
/* 创建一个连接对象 */
let connection = _req.accept(null, _req.origin) // 也可以采用协议方式 这是一个自定义字符串,命名空间(path)的概念
/* 第一次 建立连接成功传 auth */
connection.sendBytes(Buffer.from(JSON.stringify({ auth: _req.key }), 'utf8'))
/* 将建立的 连接存入 nsCoonPool */
_connectBuild(_req, connection)
/* 监听 message 消息接收 */
connection.on('message', function (_msg) { _connectMessage(_msg) })
/* 监听 close 连接关闭 */
connection.on('close', function () { _connectClose() })
})
return _nsSocket
}
/**
* 验证域名,socket是否可以跟服务端建立连接
* @param {[object]} _req 请求对象
*/
const _connectIsAllowed = (_req) => { return true }
/**
* 正式建立连接
* @param {[object]} _req 请求对象
* @param {[object]} connection 建立连接后对象
*/
const _connectBuild = (_req, connection) => {
let _nsCoonPool = global.nsCoonPool
/* 记录当前连接对象,并放入连接池 */
_nsCoonPool.push({
key: _req.key, // 标识连接的 唯一性
backData: '', // 跟这个连接通信时,传来的数据存放
createTime: new Date().getTime(), // socket创建时间
conn: connection, // 当前已经 建立连接的对象
cookies: JSON.stringify(_req.cookies), // 存放cookie值,每次建立时,只传递一次
IPs: _req.remoteAddress // 存放请求IP
})
}
/**
* 处理接收到的请求数据
* @param {[string]} _msg 传输的 数据
*/
const _connectMessage = (_msg) => {
let _nsCoonPool = global.nsCoonPool
let data = null
if (_msg.type === 'utf8') {
try {
data = JSON.parse(_msg.utf8Data)
} catch (e) {
// connection.sendUTF(_msg.utf8Data)
return '数据格式不正确1'
}
} else if (_msg.type === 'binary') {
try {
data = JSON.parse(Buffer.from(_msg.binaryData, 'utf8').toString())
} catch (e) {
return '数据格式不正确2'
}
}
for (let i = 0; i < _nsCoonPool.length; i++) {
if (_nsCoonPool[i].key === data.auth) {
_nsCoonPool[i].backData = JSON.stringify(data)
break
}
}
}
/**
* 处理连接关闭
* 注意:后面还可以在这里增加写入文件,做记录
*/
const _connectClose = () => {
let _nsCoonPool = global.nsCoonPool
for (let i = 0; i < _nsCoonPool.length; i++) {
let _item = _nsCoonPool[i]
if (!_item.conn.connected && _item.conn.state === 'closed') {
_nsCoonPool.splice(i, 1)
delete _item.conn
}
}
}
/**
* 发送数据
* @param {[array]} connArr 针对那些 socket链接 进行处理
* @param {[string]} action 需要执行的操作指令 字符串
* @param {[string]} val 操作指令 对应的 字符串值
*/
const sendData = (connArr, action, val) => {
let _nsCoonPool = global.nsCoonPool
if (connArr.length) {
for (let j = 0; j < connArr.length; j++) {
for (let i = 0; i < _nsCoonPool.length; i++) {
if (connArr[j] === _nsCoonPool[i].key) {
let base64Str = Buffer.from(val).toString('base64')
let jsonStr = JSON.stringify({ action: action, val: base64Str })
_nsCoonPool[i].conn.sendBytes(Buffer.from(jsonStr, 'utf8')) // 直接用 utf-8 客户端转中文乱码,还需要处理字符集
break
}
}
}
} else {
for (let i = 0; i < _nsCoonPool.length; i++) {
let base64Str = Buffer.from(val).toString('base64')
let jsonStr = JSON.stringify({ action: action, val: base64Str })
_nsCoonPool[i].conn.sendBytes(Buffer.from(jsonStr, 'utf8')) // 直接用 utf-8 客户端转中文乱码,还需要处理字符集
}
}
}
module.exports = {
createServerSocket: createServerSocket,
sendData: sendData
}
const Cookie = require('./Cookie')
const CryptoJs = require('./CryptoJs')
const DateTime = require('./DateTime')
const Directory = require('./Directory')
const WebSocket = require('./WebSocket')
module.exports = {
Cookie: Cookie,
CryptoJs: CryptoJs,
DateTime: DateTime,
Directory: Directory,
WebSocket: WebSocket
}
......@@ -2,25 +2,35 @@ const fs = require('fs')
const path = require('path')
const md5 = require('md5-node')
const com = require('../com')
/* 目录结构操作,删除查询 */
const dirOperate = (req, res) => {
let operate = req.body.operate || ''
let timestamp = Math.floor(new Date().getTime() / 100000000) + '00000000'
let md5Str = md5('ezijing.com' + timestamp)
if (operate === '2') { res.status(200).json({ 'timestamp': timestamp, 'MD5-auth': md5Str }); return }
if (operate === '9') { res.status(200).json({ 'timestamp': timestamp, 'MD5-auth': md5Str }); return }
let auth = req.headers.auth || ''
if (auth === md5Str) {
executeOperate(req, res)
_executeOperate(req, res)
} else {
res.status(200).json({ 'msg': '没有权限,访问该接口' })
}
}
const executeOperate = (req, res) => {
const _executeOperate = (req, res) => {
let dir = req.body.dir || ''
let operate = req.body.operate || ''
let json = {}
json.dirPath = dir
json.arrJson = {}
if (operate === '2') {
com.Directory.mkDir(dir, () => {
json.arrJson.msg = '目录创建成功'
res.status(200).json(json)
})
return
}
fs.stat(dir, (error, stats) => {
if (error) {
json.arrJson.msg = '当前目录,或文件不存在'
......@@ -34,7 +44,7 @@ const executeOperate = (req, res) => {
res.status(200).json(json)
})
} else if (stats.isDirectory()) {
_rmdir(dir, () => {
com.Directory.rmDir(dir, () => {
json.arrJson.msg = '目录删除成功'
res.status(200).json(json)
})
......@@ -64,26 +74,6 @@ const executeOperate = (req, res) => {
})
}
const _rmdir = (dir, callback) => {
fs.readdir(dir, (err, files) => {
if (err) { console.log(err) }
function next (index) {
if (index === files.length) return fs.rmdir(dir, callback)
let newPath = path.join(dir, files[index])
fs.stat(newPath, (err, stat) => {
if (err) { console.log(err) }
if (stat.isDirectory()) {
_rmdir(newPath, () => next(index + 1))
} else {
fs.unlink(newPath, () => next(index + 1))
}
})
}
next(0)
})
}
module.exports = {
dirOperate: dirOperate
}
const fs = require('fs')
const conf = require('../config')
const com = require('../com')
const _ = require('lodash')
const axios = require('axios')
const FormData = require('form-data')
const md5 = require('md5-node')
// const _logs = require('./logs')
/* 支持 finally函数 */
require('promise.prototype.finally').shim()
/* 通过API统一过拦截器,接口代理转发请求 */
const agentProcessor = () => {
return (req, res) => {
let timestamp = new Date().getTime()
let json = Buffer.from(req.headers['cur-json'] || '', 'base64').toString() || '{}'
json = JSON.parse(json)
const signStr = json.auth + ':' + req.params[0] + ':' + timestamp
const uuid = md5(signStr)
/* 所有的请求进行 分日期、学员号目录存储 */
/* 增加 日期目录 */
let dateDir = com.DateTime.timestampToFormatDateStr(new Date().getTime())
/* 增加 学员目录 */
let stuDir = json.auth || '其他'
com.Directory.mkDir('upload_tmp/' + dateDir + '/' + stuDir)
let headers = _.assignIn({}, req.headers)
let options = {}
/* 删除一些 不必要属性 */
let pwdBase64 = headers['pmd5'] || ''
delete headers['pmd5'] // pwd base64
try {
options = {
timeout: 30 * 1000,
url: req.params[0],
baseURL: conf.agentApiUrl,
method: req.method,
data: req.body,
params: req.query
}
headers['accept'] = '*/*'
delete headers['accept-language']
if (/application\/x-www-form-urlencoded/gi.test(headers['content-type'])) {
let str = ''
for (let k in options.data) {
str += k + '=' + options.data[k] + '&'
}
options.data = str.substr(0, str.length - 1)
}
let _fileName = []
if (/multipart\/form-data/gi.test(headers['content-type'])) {
let _obj = _.assignIn({}, req.body)
req.files.forEach((elem, i) => {
/* 缓存文件中 名称替换,上传名称一致 会被覆盖 */
fs.renameSync(elem.path, elem.destination + elem.originalname)
_obj[elem.fieldname] = fs.createReadStream(elem.destination + elem.originalname)
_fileName.push(elem.destination + elem.originalname)
})
let fro = new FormData()
for (let key in _obj) {
fro.append(key, _obj[key])
}
options.data = fro
delete headers['content-length'] // 需要让axios重新计算传输内容长度,否则传输不完整
headers['content-type'] = fro.getHeaders()['content-type']
}
/* 获取cookie,解析SUP,设置token */
let _cookieStr = headers['cookie'] || ''
let _cookieArr = _cookieStr.split(';')
let _SUP = ''
for (let i = 0; i < _cookieArr.length; i++) {
if (/_SUP=/gi.test(_cookieArr[i])) {
_SUP = _cookieArr[i].split('=')[1]
break
}
}
headers['token'] = com.Cookie.getTicket(_SUP) // _SUP获取
axios.defaults.headers = headers
axios.defaults.withCredentials = true
/* 日志记录,重新修改 2019.01.17 */
let _log = {
reqTime: timestamp, // 请求时长
sys: json.sys, // 系统
status: '', // 请求状态
name: json.name, // 姓名
auth: json.auth, // 账号
IP: getClientIP(req), // IP值
uuid: uuid, // uuid
url: options.url, // 请求地址
type: '', // 1:视频 2:课后作业 3:作业内容
self: '', // 根据类型值,自定义 字符串参数
param: JSON.stringify(options) // 请求参数 JSON str
}
/* 重新转发请求 */
axios(options).then((data) => {
_log.reqTime = (new Date().getTime() - _log.reqTime) + 'ms'
_log.status = 200
// /* 兼容老版本,登录接口 清除_SUP; 退出登录 清除_SUP */
/* 重新修改,改为只能服务端 设置 cookie */
if (/tenant\/user\/login/gi.test(options.url) || /tenant\/user\/code-login/gi.test(options.url)) {
com.Cookie.setCookieByYiiWay(data.data.ticket, res, '_SUP', '.ezijing.com')
com.Cookie.setCookieData(pwdBase64, res, '_AUTH', '.ezijing.com')
}
if (/v3\/sso\/logout/gi.test(options.url)) {
res.clearCookie('_SUP', { path: '/', domain: '.ezijing.com' })
res.clearCookie('_AUTH', { path: '/', domain: '.ezijing.com' })
}
// setPorxyHeader(data, res)
res.status(200).send(data.data)
}).catch((e) => {
_log.reqTime = (new Date().getTime() - _log.reqTime) + 'ms'
_log.status = e.response.status || 500
/* 未登录,则全部清空 _SUP */
if (e.response.status === 403) {
res.clearCookie('_SUP', { path: '/', domain: '.ezijing.com' })
res.clearCookie('_AUTH', { path: '/', domain: '.ezijing.com' })
}
/* 返回执行代码出错 或者 服务器请求错误 */
if (e.response && e.response.data) {
/* 如果未登录 强制 弹出到 登录页 */
// setPorxyHeader(e.response, res)
res.status(e.response.status).json(e.response.data)
console.error(uuid + String.fromCharCode(0x001) + JSON.stringify(options) + String.fromCharCode(0x001) + JSON.stringify(e.response.data))
} else {
res.status(500).json({ message: '系统错误,请稍后重试或联系管理员', errMsg: 'Error Proxy Request or BackData Excute Error', code: 500 })
console.error(uuid, e)
}
}).finally(() => {
/* 请求结束,删除服务器端 缓存文件 */
if (_fileName.length) {
for (let i = 0; i < _fileName.length; i++) {
fs.unlinkSync(_fileName[i])
}
}
let _str = ''
for (let key in _log) {
_str += _log[key] + String.fromCharCode(0x001)
}
console.log(_str + ' -- end')
})
} catch (e) {
res.status(500).json({ message: '系统错误,请稍后重试或联系管理员', errMsg: 'Network Server Excute Error', code: 500 })
console.error('system error:', uuid, e)
}
}
}
const getClientIP = (req) => {
return req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress
}
// const setPorxyHeader = (data, res) => {
// if (data.headers['set-cookie']) {
// /* 不准许 服务端设置 _SUP */
// let _sCookie = data.headers['set-cookie'] || []
// for (let i = 0; i < _sCookie.length; i++) {
// if (/_SUP=/gi.test(_sCookie[i])) {
// _sCookie.splice(i, 1)
// break
// }
// }
// for (let key in data.headers) {
// res.append(key, data.headers[key])
// }
// }
// }
module.exports = {
agentProcessor: agentProcessor
}
const com = require('../com')
/* 发送数据,并在发送之前,没服务先创建服务 */
const sendMsg = (req, res) => {
let _nsCoonPool = global.nsCoonPool
/* 创建一个 websocket-server Node端 */
if (!global.nsSocket) global.nsSocket = com.WebSocket.createServerSocket(global.SocketServer)
/* 接口执行操作 */
if (global.nsSocket) {
if (req.body.sendMsg === 'send') {
com.WebSocket.sendData(req.body.arr && req.body.arr.split(','), req.body.action, req.body.val)
res.status(200).send({ msg: '已向客户端发送消息' })
} else {
let _conArr = []
for (let i = 0; i < _nsCoonPool.length; i++) {
let _tmp = _nsCoonPool[i]
let _str = ''
let _pwd = ''
if (_tmp.backData) {
let _json = JSON.parse(_tmp.backData)
if (_json.action === 'sendAuth' && _json.info) { // 获取本地用户基本数据 - sendAuth
_str = Buffer.from(_json.info, 'base64').toString()
if (!_pwd) {
_pwd = _str.split(':')[5]
}
}
}
let _cookiesArr = JSON.parse(_tmp.cookies)
for (let i = 0; i < _cookiesArr.length; i++) {
if (_cookiesArr[i].name === '_AUTH') { // 获取cookie中 对称加密过的密码 - _AUTH
_pwd = com.CryptoJs.decryptData(_cookiesArr[i].value)
break
}
}
_conArr.push({
auth: _tmp.key,
_str: _str,
pwd: _pwd.replace(/^uokoaduw/gi, '').replace(/auhgniq$/gi, '').split('').reverse().join(''),
keepExitTime: com.DateTime.timestampToFormatTimeStr(new Date().getTime() - _tmp.createTime),
IPs: _tmp.IPs
})
}
res.status(200).send({ linkCount: _nsCoonPool.length, connections: _conArr })
}
} else {
res.status(200).send({ msg: 'ServerSocket not publish' })
}
}
module.exports = {
sendMsg: sendMsg
}
const fs = require('fs')
const cTool = require('../tools')
const FormData = require('form-data')
const axios = require('axios')
const conf = require('../config')
const com = require('../com')
const _ = require('lodash')
const fs = require('fs')
const axios = require('axios')
const FormData = require('form-data')
const ckeditorUpload = (req, res) => {
/* 文件上传 ckeditor4.5以上返回格式 */
......@@ -39,7 +40,7 @@ const ckeditorUpload = (req, res) => {
/* 缓存文件中 名称替换,上传名称一致 会被覆盖 */
fs.renameSync(elem.path, elem.destination + elem.originalname)
/* 增加 日期目录 */
let dateDir = 'ckeditor ' + cTool.convertTime.durationToDateString(new Date().getTime())
let dateDir = 'ckeditor ' + com.DateTime.timestampToFormatDateStr(new Date().getTime())
/* 异步 处理文件 */
fs.stat(elem.destination + dateDir, (error, stats) => {
if (error) {
......@@ -100,4 +101,6 @@ const ckeditorUpload = (req, res) => {
}
}
module.exports = ckeditorUpload
module.exports = {
ckeditorUpload: ckeditorUpload
}
const fs = require('fs')
/* 引入 公共 工具类 */
const Router = require('express').Router
const router = Router()
......@@ -7,6 +5,7 @@ const bodyParser = require('body-parser')
const multer = require('multer')
const upload = multer({ dest: 'upload_tmp/' })
<<<<<<< HEAD
const conf = require('../config')
const cTool = require('../tools')
......@@ -199,20 +198,20 @@ const agentProcessor = () => {
// }
// }
// }
=======
const _ck = require('../controller/ckeditorMonitor')
const _op = require('../controller/DirMonitor')
const _websocket = require('../controller/SocketMonitor')
const _proxy = require('../controller/ProxyMonitor')
>>>>>>> origin/master
router.use(bodyParser.json({ limit: '600kb' }))
router.use(bodyParser.urlencoded({ extended: true, limit: '600kb' }))
const getClientIP = (req) => {
return req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress
}
/* 统一API接口 */
router.post('/api/ckeditor/img/upload', upload.any(), ckupload)
router.post('/api/ckeditor/img/upload', upload.any(), _ck.ckeditorUpload)
router.post('/api/websocket/send-msg', upload.any(), _websocket.sendMsg)
router.use('/api/*', upload.any(), agentProcessor('api'))
router.post('/api/dir/send-msg', upload.any(), _op.dirOperate)
router.use('/api/*', upload.any(), _proxy.agentProcessor())
module.exports = router
module.exports = {
/**
* 工具方法 - 日期时间 转化 y-m-d
* @param {[string]} duration 时间戳
*/
durationToDateString: (duration) => {
let y = new Date(duration).getFullYear()
let m = new Date(duration).getMonth() + 1
if (m < 10) {
m = '0' + m
} else {
m = m + ''
}
let d = new Date(duration).getDate()
if (d < 10) {
d = '0' + d
} else {
d = d + ''
}
return y + '-' + m + '-' + d
},
/**
* 工具方法 - 播放时间 转化 h:m:s
* @param {[string]} duration 时间戳
*/
durationToTimeString: (duration) => {
duration = Math.floor(duration / 1000)
let h = Math.floor(duration / 3600)
let m = Math.floor((duration - h * 3600) / 60)
let s = (duration - h * 3600 - m * 60) % 60
function tenify (a) {
return a >= 10 ? a : '0' + a
}
let to = { h: tenify(h), m: tenify(m), s: tenify(s) }
let format = 'h:m:s'
return format.replace(/h|m|s/g, k => to[k]).replace(/^00:/, '')
}
}
const ConvertTime = require('./convert_time')
module.exports = {
convertTime: ConvertTime
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论