diff --git a/code/VideoAccess-VCMP/api/.vscode/launch.json b/code/VideoAccess-VCMP/api/.vscode/launch.json index e8d5ae1..5bef1ea 100644 --- a/code/VideoAccess-VCMP/api/.vscode/launch.json +++ b/code/VideoAccess-VCMP/api/.vscode/launch.json @@ -13,12 +13,11 @@ "NODE_ENV": "development" }, "args": [ - "-p 14000", - "-f http://localhost:14000", - // "-g postgres://postgres:123@10.8.30.32:5432/yinjiguanli", - // "-g postgres://postgres:123456@221.230.55.27:5432/yinjiguanli", - // "-g postgres://FashionAdmin:123456@10.8.30.156:5432/SmartEmergency", - "-g postgres://postgres:Mantis1921@116.63.50.139:54327/smartYingji" + "-p 4000", + "-f http://localhost:4000", + "-g postgres://postgres:123@10.8.30.32:5432/video_access", + "--redisHost 127.0.0.1", + "--redisPort 6379" ] }, { diff --git a/code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js b/code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js new file mode 100644 index 0000000..5bb4373 --- /dev/null +++ b/code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js @@ -0,0 +1,68 @@ +'use strict'; +const moment = require('moment') + +async function edit (ctx, next) { + const transaction = await ctx.fs.dc.orm.transaction(); + try { + const models = ctx.fs.dc.models; + const { userId } = ctx.fs.api + const data = ctx.request.body; + + // 或取其他服务信息 + const nvrData = { + channelCount: 8, + port: 8080, + } + + if (data.id) { + // 修改 + const storageData = Object.assign({}, data, nvrData) + await models.Nvr.update(storageData, { + where: { + id: data.id + }, + transaction + }) + } else { + // 添加 + const storageData = Object.assign({}, data, nvrData, { + createTime: moment().format(), + createUserId: userId, + delete: false, + }) + await models.Nvr.create(storageData, { transaction }) + } + + await transaction.commit(); + ctx.status = 204; + } catch (error) { + await transaction.rollback(); + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = {} + } +} + +async function del (ctx, next) { + try { + const models = ctx.fs.dc.models; + const { nvrId } = ctx.params + + await models.Nvr.destroy({ + where: { + id: nvrId + } + }) + + ctx.status = 204; + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = {} + } +} + +module.exports = { + edit, + del, +}; \ No newline at end of file diff --git a/code/VideoAccess-VCMP/api/app/lib/index.js b/code/VideoAccess-VCMP/api/app/lib/index.js index 0fd17b8..d5668f6 100644 --- a/code/VideoAccess-VCMP/api/app/lib/index.js +++ b/code/VideoAccess-VCMP/api/app/lib/index.js @@ -1,6 +1,7 @@ 'use strict'; const routes = require('./routes'); +const redisConnect = require('./service/redis') const authenticator = require('./middlewares/authenticator'); // const apiLog = require('./middlewares/api-log'); const businessRest = require('./middlewares/business-rest'); @@ -12,8 +13,10 @@ module.exports.entry = function (app, router, opts) { app.fs.api.authAttr = app.fs.api.authAttr || {}; app.fs.api.logAttr = app.fs.api.logAttr || {}; + redisConnect(app, opts) + router.use(authenticator(app, opts)); - router.use(businessRest(app, router, opts)); + // router.use(businessRest(app, router, opts)); // router.use(apiLog(app, opts)); router = routes(app, router, opts); diff --git a/code/VideoAccess-VCMP/api/app/lib/middlewares/authenticator.js b/code/VideoAccess-VCMP/api/app/lib/middlewares/authenticator.js index cdc5caf..8399456 100644 --- a/code/VideoAccess-VCMP/api/app/lib/middlewares/authenticator.js +++ b/code/VideoAccess-VCMP/api/app/lib/middlewares/authenticator.js @@ -13,13 +13,13 @@ class ExcludesUrls { this.reload(opts); } - sanitizePath(path) { + sanitizePath (path) { if (!path) return '/'; const p = '/' + path.replace(/^\/+/i, '').replace(/\/+$/, '').replace(/\/{2,}/, '/'); return p; } - reload(opts) { + reload (opts) { // load all url if (!this.allUrls) { this.allUrls = opts; @@ -37,7 +37,7 @@ class ExcludesUrls { } } - isExcluded(path, method) { + isExcluded (path, method) { return this.allUrls.some(function (url) { return !url.auth && url.pregexp.test(path) @@ -58,9 +58,7 @@ let isPathExcluded = function (opts, path, method) { if (!excludeAll) { let excludeOpts = opts.exclude || []; excludeOpts.push({ p: '/login', o: 'POST' }); - excludeOpts.push({ p: '/wxLogin', o: 'POST' }); excludeOpts.push({ p: '/logout', o: 'PUT' }); - excludeOpts.push({ p: '/wxLogout', o: 'PUT' }); excludes = new ExcludesUrls(excludeOpts); } let excluded = excludeAll || excludes.isExcluded(path, method); @@ -72,14 +70,10 @@ let authorizeToken = async function (ctx, token) { const tokenFormatRegexp = /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/g; if (token && tokenFormatRegexp.test(token)) { try { - const axyRes = await ctx.fs.dc.models.UserToken.findOne({ - where: { - token: token, - expired: { $gte: moment().format('YYYY-MM-DD HH:mm:ss') } - } - }); - const { userInfo, expired } = axyRes; - if (!expired || moment().valueOf() <= moment(expired).valueOf()) { + const expired = await ctx.redis.hget(token, 'expired'); + + if (expired && moment().valueOf() <= moment(expired).valueOf()) { + const userInfo = JSON.parse(await ctx.redis.hget(token, 'userInfo')); rslt = { 'authorized': userInfo.authorized, 'resources': (userInfo || {}).resources || [], @@ -112,13 +106,14 @@ let isResourceAvailable = function (resources, options) { return !authCode || (resources || []).some(code => code === authCode); }; -function factory(app, opts) { - return async function auth(ctx, next) { +function factory (app, opts) { + return async function auth (ctx, next) { const { path, method, header, query } = ctx; ctx.fs.logger.log('[AUTH] start', path, method); ctx.fs.api = ctx.fs.api || {}; ctx.fs.port = opts.port; ctx.redis = app.redis; + ctx.redisTools = app.redisTools; let error = null; if (path) { if (!isPathExcluded(opts, path, method)) { diff --git a/code/VideoAccess-VCMP/api/app/lib/routes/nvr/index.js b/code/VideoAccess-VCMP/api/app/lib/routes/nvr/index.js new file mode 100644 index 0000000..ed6654c --- /dev/null +++ b/code/VideoAccess-VCMP/api/app/lib/routes/nvr/index.js @@ -0,0 +1,11 @@ +'use strict'; + +const nvr = require('../../controllers/nvr'); + +module.exports = function (app, router, opts) { + app.fs.api.logAttr['POST/nvr'] = { content: '添加/修改nvr', visible: false }; + router.post('/nvr', nvr.edit); + + app.fs.api.logAttr['DEL/nvr'] = { content: '删除nvr', visible: false }; + router.del('/nvr/:nvrId', nvr.del); +}; diff --git a/code/VideoAccess-VCMP/api/app/lib/service/redis.js b/code/VideoAccess-VCMP/api/app/lib/service/redis.js new file mode 100644 index 0000000..5e38a29 --- /dev/null +++ b/code/VideoAccess-VCMP/api/app/lib/service/redis.js @@ -0,0 +1,29 @@ +'use strict'; +const redis = require("ioredis") +const moment = require('moment') + +module.exports = async function factory (app, opts) { + let client = new redis(opts.redis.port, opts.redis.host); + + client.on("error", function (err) { + app.fs.logger.error('info', '[FS-AUTH-REDIS]', 'redis connect error.'); + console.error("Error :", err); + process.exit(-1); + }); + + client.on('connect', function () { + console.log(`redis connect success ${opts.redis.host + ':' + opts.redis.port}`); + }) + + // 自定义方法 + async function hdelall (key) { + const obj = await client.hgetall(key); + const hkeys = Object.keys(obj) + await client.hdel(key, hkeys) + } + + app.redis = client + app.redisTools = { + hdelall, + } +} diff --git a/code/VideoAccess-VCMP/api/config.js b/code/VideoAccess-VCMP/api/config.js index 5537608..084a131 100644 --- a/code/VideoAccess-VCMP/api/config.js +++ b/code/VideoAccess-VCMP/api/config.js @@ -11,13 +11,20 @@ const dev = process.env.NODE_ENV == 'development'; args.option(['p', 'port'], '启动端口'); args.option(['g', 'pg'], 'postgre服务URL'); args.option(['f', 'fileHost'], '文件中心本地化存储: WebApi 服务器地址(必填), 该服务器提供文件上传Web服务'); +args.option('redisHost', 'redisHost'); +args.option('redisPort', 'redisPort'); +args.option('redisPswd', 'redisPassword'); const flags = args.parse(process.argv); const IOT_VIDEO_ACCESS_DB = process.env.IOT_VIDEO_ACCESS_DB || flags.pg; const IOT_VIDEO_ACCESS_LOCAL_SVR_ORIGIN = process.env.IOT_VIDEO_ACCESS_LOCAL_SVR_ORIGIN || flags.fileHost; -if (!IOT_VIDEO_ACCESS_DB) { +const IOTA_REDIS_SERVER_HOST = process.env.IOTA_REDIS_SERVER_HOST || flags.redisHost || "localhost";//redis IP +const IOTA_REDIS_SERVER_PORT = process.env.IOTA_REDIS_SERVER_PORT || flags.redisPort || "6379";//redis 端口 +const IOTA_REDIS_SERVER_PWD = process.env.IOTA_REDIS_SERVER_PWD || flags.redisPswd || "";//redis 密码 + +if (!IOT_VIDEO_ACCESS_DB || !IOTA_REDIS_SERVER_HOST || !IOTA_REDIS_SERVER_PORT) { console.log('缺少启动参数,异常退出'); args.showHelp(); process.exit(-1); @@ -41,6 +48,11 @@ const product = { entry: require('./app').entry, opts: { exclude: [], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由 + redis: { + host: IOTA_REDIS_SERVER_HOST, + port: IOTA_REDIS_SERVER_PORT, + pwd: IOTA_REDIS_SERVER_PWD + }, } } ], diff --git a/code/VideoAccess-VCMP/api/package.json b/code/VideoAccess-VCMP/api/package.json index 43c97b7..c4d0945 100644 --- a/code/VideoAccess-VCMP/api/package.json +++ b/code/VideoAccess-VCMP/api/package.json @@ -5,7 +5,7 @@ "main": "server.js", "scripts": { "test": "set DEBUG=true&&\"node_modules/.bin/mocha\" --harmony --reporter spec app/test/*.test.js", - "start": "set NODE_ENV=development&&node server -p 14000 -g postgres://postgres:123@10.8.30.32:5432/yinjiguanli -f http://localhost:14000", + "start": "set NODE_ENV=development&&node server -p 4000 -g postgres://postgres:123@10.8.30.32:5432/video_access -f http://localhost:4000", "start:linux": "export NODE_ENV=development&&node server -p 4000 -g postgres://FashionAdmin:123456@10.8.30.39:5432/pm1", "automate": "sequelize-automate -c sequelize-automate.config.js" }, @@ -18,7 +18,7 @@ "crypto-js": "^4.0.0", "file-saver": "^2.0.2", "fs-web-server-scaffold": "^2.0.2", - "ioredis": "^4.19.4", + "ioredis": "^5.0.4", "koa-convert": "^1.2.0", "koa-proxy": "^0.9.0", "moment": "^2.24.0",