diff --git a/.gitignore b/.gitignore index 44013869..3278e90d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ data.db* .neutrino-proxy.license .neutrino-proxy-client.json* lib/* +SensitiveInformation.txt # Log file diff --git a/bin/client_start.sh b/bin/client_start.sh new file mode 100755 index 00000000..9bdd9178 --- /dev/null +++ b/bin/client_start.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# 中微子代理客户端启动脚本,基础参数请自行修改 + +JAVA_OPS="-server -Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/work/$NAME/heapError/" +export JAVA_HOME=/work/programs/jdk/jdk1.8.0_171 +export PATH=:$PATH:$JAVA_HOME/bin +export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar +mkdir -p /work/$NAME/heapError/ + +NAME=neutrino-proxy-client +WORK=/work/projects +OUT=$WORK/$NAME/$NAME.out +JAR_PATH=$WORK/$NAME + +function start(){ +PID=`jps -l | grep $NAME.jar | cut -d' ' -f 1` +if [ -n "$PID" ]; then +echo "kill pid : $PID" +kill $PID +fi +sleep 3 +if [ -n "$PID" ]; then +echo "kill fail & kill -9 pid : $PID" +kill -9 $PID +fi +if [ -f "$OUT" ]; then +time=$(date "+%Y%m%d-%H%M%S") +cp $OUT $JAR_PATH/logs/back_$time.out +fi +rm -f $OUT +cd $JAR_PATH +nohup java $JAVA_OPS -jar $NAME.jar > $OUT 2>&1 & +echo "sleep 15s wating service start" +sleep 15 +tail -200 $OUT +echo "start ${JAR_PATH} success ;log path:$OUT" +} + +start \ No newline at end of file diff --git a/bin/server_start.sh b/bin/server_start.sh new file mode 100755 index 00000000..ea3569f8 --- /dev/null +++ b/bin/server_start.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# 中微子代理服务端启动脚本,基础参数请自行修改 + +JAVA_OPS="-server -Xms256m -Xmx1024m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/work/$NAME/heapError/" +export JAVA_HOME=/work/programs/jdk/jdk1.8.0_171 +export PATH=:$PATH:$JAVA_HOME/bin +export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar +mkdir -p /work/$NAME/heapError/ + +NAME=neutrino-proxy-server +WORK=/work/projects +OUT=$WORK/$NAME/$NAME.out +JAR_PATH=$WORK/$NAME + +function start(){ +PID=`jps -l | grep $NAME.jar | cut -d' ' -f 1` +if [ -n "$PID" ]; then +echo "kill pid : $PID" +kill $PID +fi +sleep 3 +if [ -n "$PID" ]; then +echo "kill fail & kill -9 pid : $PID" +kill -9 $PID +fi +if [ -f "$OUT" ]; then +time=$(date "+%Y%m%d-%H%M%S") +cp $OUT $JAR_PATH/logs/back_$time.out +fi +rm -f $OUT +cd $JAR_PATH +nohup java $JAVA_OPS -jar $NAME.jar > $OUT 2>&1 & +echo "sleep 15s wating service start" +sleep 15 +tail -200 $OUT +echo "start ${JAR_PATH} success ;log path:$OUT" +} + +start + diff --git a/docs/Channel.MD b/docs/Channel.MD index 5c31b33e..28b4505b 100644 --- a/docs/Channel.MD +++ b/docs/Channel.MD @@ -31,7 +31,7 @@ - 1.3、服务端通过`CmdChannel`接收到来自客户端的`Auth`指令。若验证`license`有效,则建立`licenseId`与`CmdChannel`的映射缓存、 外网端口与`CmdChannel`的映射缓存。并启动服务端代理端口,等待用户连接。 ## 2、用户连接阶段 -- 2.1、用户访向服务端代理的外网端口发起请求,服务端建立`VisitorChannel`。 +- 2.1、用户向服务端代理的外网端口发起请求,服务端建立`VisitorChannel`。 - 2.2、根据外网端口查找`CmdChannel`,若不存在有效的`CmdChannel`,则关闭该`VisitorChannel`。否则, 设置`VisitorChannel`为不可读,并携带内网映射信息(如:`127.0.0.1:3306`)通过`CmdChannel`向客户端发送`Connect`指令。 ## 3、实际被代理服务连接阶段 diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/AsgcCompiler.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/AsgcCompiler.java index 1b040b2d..d44ef4b0 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/AsgcCompiler.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/compiler/AsgcCompiler.java @@ -171,6 +171,7 @@ public class AsgcCompiler { /** * 编译代码 + * @param pkg 包名 * @param className 类名 * @param sourceCode 源代码 */ diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/DateUtil.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/DateUtil.java index 377909b5..af093be2 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/DateUtil.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/DateUtil.java @@ -145,6 +145,19 @@ public class DateUtil { return cal.getTime(); } + /** + * 获取该日期当月第一天 + * + * @param date 日期 + * @return 结果日期 + */ + public static Date getMonthBegin(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(getDayBegin(date)); + calendar.set(Calendar.DAY_OF_MONTH, 1); + return calendar.getTime(); + } + /** * 获取该日期当月最后一天 * @@ -153,10 +166,10 @@ public class DateUtil { */ public static Date getMonthEnd(Date date) { Calendar calendar = Calendar.getInstance(); - calendar.setTime(getDayEnd(date)); + calendar.setTime(getDayBegin(date)); calendar.add(Calendar.MONTH, 1); calendar.set(Calendar.DAY_OF_MONTH, 1); - calendar.add(Calendar.DAY_OF_MONTH, -1); + calendar.add(Calendar.MILLISECOND, -1); return calendar.getTime(); } diff --git a/neutrino-proxy-admin/build/webpack.local.conf.js b/neutrino-proxy-admin/build/webpack.local.conf.js new file mode 100644 index 00000000..279389c9 --- /dev/null +++ b/neutrino-proxy-admin/build/webpack.local.conf.js @@ -0,0 +1,88 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: true, + hot: true, + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/local.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true, + favicon: resolve('favicon.ico'), + title: 'vue-element-admin', + path: config.dev.assetsPublicPath + config.dev.assetsSubDirectory + }), + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/neutrino-proxy-admin/config/dev.env.js b/neutrino-proxy-admin/config/dev.env.js index f5ee615e..f812fea4 100644 --- a/neutrino-proxy-admin/config/dev.env.js +++ b/neutrino-proxy-admin/config/dev.env.js @@ -1,5 +1,5 @@ module.exports = { NODE_ENV: '"development"', ENV_CONFIG: '"dev"', - BASE_API: '"http://localhost:8888"' + BASE_API: '"http://103.163.47.16:8888"' } diff --git a/neutrino-proxy-admin/config/local.env.js b/neutrino-proxy-admin/config/local.env.js new file mode 100644 index 00000000..8a8c18ec --- /dev/null +++ b/neutrino-proxy-admin/config/local.env.js @@ -0,0 +1,5 @@ +module.exports = { + NODE_ENV: '"development"', + ENV_CONFIG: '"local"', + BASE_API: '"http://localhost:8888"' +} diff --git a/neutrino-proxy-admin/package.json b/neutrino-proxy-admin/package.json index fed01c75..65aa382e 100644 --- a/neutrino-proxy-admin/package.json +++ b/neutrino-proxy-admin/package.json @@ -6,7 +6,9 @@ "license": "MIT", "private": true, "scripts": { - "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host=0.0.0.0", + "local": "webpack-dev-server --inline --progress --config build/webpack.local.conf.js", + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "build:local": "cross-env NODE_ENV=dev env_config=local node build/build.js", "build:dev": "cross-env NODE_ENV=dev env_config=dev node build/build.js", "build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js", "build:sit": "cross-env NODE_ENV=production env_config=sit node build/build.js", diff --git a/neutrino-proxy-admin/src/api/clientConnectLog.js b/neutrino-proxy-admin/src/api/clientConnectLog.js new file mode 100644 index 00000000..fb8df821 --- /dev/null +++ b/neutrino-proxy-admin/src/api/clientConnectLog.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +export function fetchList(query) { + return request({ + url: '/client-connect-record/page', + method: 'get', + params: query + }) +} diff --git a/neutrino-proxy-admin/src/api/license.js b/neutrino-proxy-admin/src/api/license.js index 7069e9c6..d9aa0d90 100644 --- a/neutrino-proxy-admin/src/api/license.js +++ b/neutrino-proxy-admin/src/api/license.js @@ -51,3 +51,13 @@ export function deleteLicense(id) { } }) } + +export function resetLicense(id) { + return request({ + url: '/license/reset', + method: 'post', + params: { + id: id + } + }) +} diff --git a/neutrino-proxy-admin/src/api/user.js b/neutrino-proxy-admin/src/api/user.js index 70ef71e8..0b982505 100644 --- a/neutrino-proxy-admin/src/api/user.js +++ b/neutrino-proxy-admin/src/api/user.js @@ -73,3 +73,27 @@ export function hello() { }) } +/** + * 管理员修改成员密码 + * @param params + */ +export function updatePassword(params) { + return request({ + url: '/user/update/password', + method: 'post', + data: params + }) +} + +/** + * 修改自己密码 + * @param params + */ +export function updateUserPassword(params) { + return request({ + url: '/user/current-user/update/password', + method: 'post', + data: params + }) +} + diff --git a/neutrino-proxy-admin/src/lang/zh.js b/neutrino-proxy-admin/src/lang/zh.js index fac13f8b..e021cbf8 100644 --- a/neutrino-proxy-admin/src/lang/zh.js +++ b/neutrino-proxy-admin/src/lang/zh.js @@ -54,12 +54,14 @@ export default { jobManager: '调度管理', jobLog: '调度日志', log: '日志管理', - loginLog: '登录日志' + loginLog: '登录日志', + clientConnectLog: '客户端连接日志' }, navbar: { logOut: '退出登录', dashboard: '首页', github: '项目地址', + updatePwd: '修改密码', screenfull: '全屏', theme: '换肤' }, @@ -135,11 +137,20 @@ export default { jobParam: '任务参数', alarmEmail: '任务报警邮箱', alarmDing: '任务报警钉钉', - jobLogCode: '执行结果', - jobLogMsg: '执行日志', + jobLogCode: '调度结果', + jobLogMsg: '调度日志', + jobLogTime: '调度时间', alarmStatus: '报警状态', ip: 'IP', - happendTime: '发生时间' + happendTime: '发生时间', + updatePwd: '修改密码', + msg: '消息', + outcome: '结果', + err: '异常信息', + resetKey: '重置Key' + }, + button: { + lookOver: '查看' }, errorLog: { tips: '请点击右上角bug小图标', diff --git a/neutrino-proxy-admin/src/router/index.js b/neutrino-proxy-admin/src/router/index.js index 96bfea8e..7e44c8d4 100644 --- a/neutrino-proxy-admin/src/router/index.js +++ b/neutrino-proxy-admin/src/router/index.js @@ -90,7 +90,8 @@ export const asyncRouterMap = [ }, children: [ { path: 'jobLog', component: _import('log/jobLog'), name: 'jobLog', meta: { title: 'jobLog' }}, - { path: 'loginLog', component: _import('log/loginLog'), name: 'loginLog', meta: { title: 'loginLog' }} + { path: 'loginLog', component: _import('log/loginLog'), name: 'loginLog', meta: { title: 'loginLog' }}, + { path: 'clientConnectLog', component: _import('log/clientConnectLog'), name: 'clientConnectLog', meta: { title: 'clientConnectLog' }} ] } ] diff --git a/neutrino-proxy-admin/src/styles/element-ui.scss b/neutrino-proxy-admin/src/styles/element-ui.scss index 08a7388a..528fcb49 100644 --- a/neutrino-proxy-admin/src/styles/element-ui.scss +++ b/neutrino-proxy-admin/src/styles/element-ui.scss @@ -30,7 +30,7 @@ .fixed-width{ .el-button--mini{ padding: 7px 10px; - width: 60px; + min-width: 60px; } } diff --git a/neutrino-proxy-admin/src/utils/request.js b/neutrino-proxy-admin/src/utils/request.js index 2bc8a5f7..a13d52a0 100644 --- a/neutrino-proxy-admin/src/utils/request.js +++ b/neutrino-proxy-admin/src/utils/request.js @@ -34,7 +34,7 @@ service.interceptors.response.use( type: 'error', duration: 5 * 1000 }) - if (res.code === 4 && !window.location.href.endsWith('#/login')) { + if ((res.code === 4 || res.code === 1) && !window.location.href.endsWith('#/login')) { store.dispatch('FedLogOut').then(() => { location.reload() // 为了重新实例化vue-router对象 避免bug }) diff --git a/neutrino-proxy-admin/src/views/layout/components/Navbar.vue b/neutrino-proxy-admin/src/views/layout/components/Navbar.vue index ca630f58..1c66e100 100644 --- a/neutrino-proxy-admin/src/views/layout/components/Navbar.vue +++ b/neutrino-proxy-admin/src/views/layout/components/Navbar.vue @@ -33,12 +33,17 @@ {{$t('navbar.github')}} + + {{$t('navbar.updatePwd')}} + {{$t('navbar.logOut')}} + + @@ -50,9 +55,11 @@ import ErrorLog from '@/components/ErrorLog' import Screenfull from '@/components/Screenfull' import LangSelect from '@/components/LangSelect' import ThemePicker from '@/components/ThemePicker' +import UpdatePwd from '../../system/components/update-pwd' export default { components: { + UpdatePwd, Breadcrumb, Hamburger, ErrorLog, @@ -68,6 +75,11 @@ export default { 'loginName' ]) }, + data() { + return { + updatePwdvisible: false + } + }, methods: { toggleSideBar() { this.$store.dispatch('toggleSideBar') @@ -76,6 +88,9 @@ export default { this.$store.dispatch('LogOut').then(() => { location.reload()// In order to re-instantiate the vue-router object to avoid bugs }) + }, + handleCancel() { + this.updatePwdvisible = false } } } @@ -130,12 +145,12 @@ export default { height: 40px; border-radius: 10px; } - .el-icon-caret-bottom { + /*.el-icon-caret-bottom { position: absolute; right: -20px; top: 25px; font-size: 12px; - } + }*/ } } } diff --git a/neutrino-proxy-admin/src/views/log/clientConnectLog.vue b/neutrino-proxy-admin/src/views/log/clientConnectLog.vue new file mode 100644 index 00000000..fc9c8c8a --- /dev/null +++ b/neutrino-proxy-admin/src/views/log/clientConnectLog.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/neutrino-proxy-admin/src/views/log/jobLog.vue b/neutrino-proxy-admin/src/views/log/jobLog.vue index ffffebd4..cd37202d 100644 --- a/neutrino-proxy-admin/src/views/log/jobLog.vue +++ b/neutrino-proxy-admin/src/views/log/jobLog.vue @@ -4,7 +4,7 @@ - {{$t('table.search')}} + {{$t('table.search')}} @@ -24,9 +24,9 @@ {{scope.row.code | statusName}} - + @@ -34,7 +34,7 @@ {{scope.row.alarmStatus | salarmStatusName}} - + @@ -50,6 +50,15 @@ :page-sizes="[10,20,30, 50]" :page-size="listQuery.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"> + + +
{{selectRow.msg}}
+ +
@@ -74,7 +83,9 @@ export default { pageSize: 10, jobId: undefined }, - jobList: [] + jobList: [], + dialogVisible: false, + selectRow: {} } }, filters: { @@ -119,7 +130,6 @@ export default { this.getJobList() if (this.$route.query.jobId) { this.listQuery.jobId = this.$route.query.jobId - console.log(this.listQuery.jobId, this.$route.query.jobId) this.getList() } }, @@ -143,6 +153,7 @@ export default { }, handleSizeChange(val) { this.listQuery.pageSize = val + this.listQuery.currentPage = 1 this.getList() }, handleCurrentChange(val) { @@ -151,7 +162,18 @@ export default { }, handleShowClick(row) { console.log(row) + }, + handleLookOver(row) { + this.selectRow = row + this.dialogVisible = true } } } + + diff --git a/neutrino-proxy-admin/src/views/log/loginLog.vue b/neutrino-proxy-admin/src/views/log/loginLog.vue index c4c9ad04..6920fa89 100644 --- a/neutrino-proxy-admin/src/views/log/loginLog.vue +++ b/neutrino-proxy-admin/src/views/log/loginLog.vue @@ -121,6 +121,7 @@ export default { }, handleSizeChange(val) { this.listQuery.pageSize = val + this.listQuery.currentPage = 1 this.getList() }, handleCurrentChange(val) { diff --git a/neutrino-proxy-admin/src/views/proxy/license.vue b/neutrino-proxy-admin/src/views/proxy/license.vue index 64c0bb39..ab759ded 100644 --- a/neutrino-proxy-admin/src/views/proxy/license.vue +++ b/neutrino-proxy-admin/src/views/proxy/license.vue @@ -47,14 +47,14 @@ {{scope.row.isOnline | isOnlineName}}
- +
@@ -98,7 +98,7 @@ diff --git a/neutrino-proxy-admin/src/views/system/user.vue b/neutrino-proxy-admin/src/views/system/user.vue index 9b20d580..8f3fc48d 100644 --- a/neutrino-proxy-admin/src/views/system/user.vue +++ b/neutrino-proxy-admin/src/views/system/user.vue @@ -2,7 +2,7 @@
{{$t('table.search')}} - {{$t('table.add')}} + {{$t('table.add')}}
{{scope.row.enable | statusName}} - + @@ -56,7 +56,7 @@
- + @@ -81,6 +81,8 @@ + + @@ -89,6 +91,8 @@ import waves from '@/directive/waves' // 水波纹指令 import { parseTime } from '@/utils' import ButtonPopover from '../../components/Button/buttonPopover' + import UpdatePwd from './components/update-pwd' + import { mapGetters } from 'vuex' const calendarTypeOptions = [ { key: 'CN', display_name: 'China' }, @@ -108,8 +112,14 @@ directives: { waves }, + computed: { + ...mapGetters([ + 'loginName' + ]) + }, components: { - ButtonPopover + ButtonPopover, + UpdatePwd }, data() { return { @@ -150,7 +160,9 @@ name: [{ required: true, message: '用户名必填', trigger: 'blur' }], loginName: [{ required: true, message: '登录名必填', trigger: 'blur' }] }, - downloadLoading: false + downloadLoading: false, + updatePwdvisible: false, + selectRow: null } }, filters: { @@ -327,6 +339,14 @@ return v[j] } })) + }, + handleUpdatePassword(row) { + this.selectRow = row + this.updatePwdvisible = true + }, + handleCancel() { + this.updatePwdvisible = false + this.selectRow = null } } } diff --git a/neutrino-proxy-server/pom.xml b/neutrino-proxy-server/pom.xml index aef19b8f..00dc1132 100644 --- a/neutrino-proxy-server/pom.xml +++ b/neutrino-proxy-server/pom.xml @@ -30,6 +30,11 @@ druid 1.1.24 + + mysql + mysql-connector-java + 8.0.29 + diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/DBInitialize.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/DBInitialize.java index 492bbed6..73cb862f 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/DBInitialize.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/DBInitialize.java @@ -26,8 +26,11 @@ import com.google.common.collect.Lists; import fun.asgc.neutrino.core.annotation.PreLoad; import fun.asgc.neutrino.core.db.template.JdbcTemplate; import fun.asgc.neutrino.core.util.*; -import fun.asgc.neutrino.proxy.server.base.rest.config.SqliteConfig; +import fun.asgc.neutrino.proxy.server.base.rest.config.DbConfig; +import fun.asgc.neutrino.proxy.server.constant.DbTypeEnum; import lombok.extern.slf4j.Slf4j; +import org.sqlite.SQLiteConfig; +import org.sqlite.SQLiteDataSource; import java.sql.DriverManager; import java.util.List; @@ -41,11 +44,18 @@ import java.util.List; @PreLoad("init") public class DBInitialize { private static List initDataTableNameList = Lists.newArrayList("user", "license", "port_pool", "port_mapping", "job_info"); - private static SqliteConfig sqliteConfig; + private static DbConfig dbConfig; private static JdbcTemplate jdbcTemplate; + private static DbTypeEnum dbTypeEnum; + public static void init() throws Exception { - sqliteConfig = ConfigUtil.getYmlConfig(SqliteConfig.class); + dbConfig = ConfigUtil.getYmlConfig(DbConfig.class); + Assert.notNull(dbConfig.getType(), "neutrino.data.db.type不能为空!"); + dbTypeEnum = DbTypeEnum.of(dbConfig.getType()); + Assert.notNull(dbTypeEnum, "neutrino.data.db.type取值异常!"); + + log.info("{}数据库初始化...", dbConfig.getType()); jdbcTemplate = getJdbcTemplate(); initDBStructure(); initDBData(); @@ -55,7 +65,7 @@ public class DBInitialize { * 初始化数据库结构 */ private static void initDBStructure() throws Exception { - List lines = FileUtil.readContentAsStringList("classpath:/sql/init-structure.sql"); + List lines = FileUtil.readContentAsStringList(String.format("classpath:/sql/%s/init-structure.sql", dbConfig.getType())); if (CollectionUtil.isEmpty(lines)) { return; } @@ -87,7 +97,7 @@ public class DBInitialize { if (count > 0) { continue; } - List lines = FileUtil.readContentAsStringList(String.format("classpath:/sql/%s.data.sql", tableName)); + List lines = FileUtil.readContentAsStringList(String.format("classpath:/sql/%s/%s.data.sql", dbConfig.getType(), tableName)); if (CollectionUtil.isEmpty(lines)) { return; } @@ -116,15 +126,30 @@ public class DBInitialize { () -> null == jdbcTemplate, DBInitialize.class, () -> { - Class.forName(sqliteConfig.getDriverClass()); - //建立一个数据库名data.db的连接,如果不存在就在当前目录下创建之 - DriverManager.getConnection(sqliteConfig.getUrl()); - // 创建数据源 - DruidDataSource dataSource = new DruidDataSource(); - dataSource.setUrl(sqliteConfig.getUrl()); - dataSource.setDriverClassName(sqliteConfig.getDriverClass()); - // 创建jdbcTemplate - jdbcTemplate = new JdbcTemplate(dataSource); + if (DbTypeEnum.SQLITE == dbTypeEnum) { + //建立一个数据库名data.db的连接,如果不存在就在当前目录下创建之 + DriverManager.getConnection(dbConfig.getUrl()); + // 创建数据源 + SQLiteDataSource dataSource = new SQLiteDataSource(); + dataSource.setUrl(dbConfig.getUrl()); + dataSource.setJournalMode(SQLiteConfig.JournalMode.WAL.getValue()); + // 创建jdbcTemplate + jdbcTemplate = new JdbcTemplate(dataSource); + } else if (DbTypeEnum.MYSQL == dbTypeEnum) { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setDriverClassName(dbConfig.getDriverClass()); + dataSource.setUrl(dbConfig.getUrl()); + dataSource.setInitialSize(5); + dataSource.setMinIdle(5); + dataSource.setMaxActive(20); + dataSource.setMaxWait(60000); + dataSource.setPoolPreparedStatements(true); + dataSource.setUsername(dbConfig.getUsername()); + dataSource.setPassword(dbConfig.getPassword()); + + // 创建jdbcTemplate + jdbcTemplate = new JdbcTemplate(dataSource); + } }, () -> jdbcTemplate ); diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/SqliteConfig.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/DbConfig.java similarity index 81% rename from neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/SqliteConfig.java rename to neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/DbConfig.java index e8e407b9..100ed4ae 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/SqliteConfig.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/DbConfig.java @@ -24,6 +24,7 @@ package fun.asgc.neutrino.proxy.server.base.rest.config; import fun.asgc.neutrino.core.annotation.Configuration; import fun.asgc.neutrino.core.annotation.NonIntercept; import fun.asgc.neutrino.core.annotation.Value; +import fun.asgc.neutrino.proxy.server.constant.DbTypeEnum; import lombok.Data; /** @@ -33,8 +34,14 @@ import lombok.Data; */ @Data @NonIntercept -@Configuration(prefix = "neutrino.data.sqlite") -public class SqliteConfig { +@Configuration(prefix = "neutrino.data.db") +public class DbConfig { + /** + * 数据库类型 + * {@link DbTypeEnum} + */ + @Value("type") + private String type; /** * 连接url */ @@ -45,4 +52,16 @@ public class SqliteConfig { */ @Value("driver-class") private String driverClass; + + /** + * 用户名 + */ + @Value("username") + private String username; + + /** + * 密码 + */ + @Value("password") + private String password; } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/RestConfiguration.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/RestConfiguration.java index 8dd416b2..2c42324a 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/RestConfiguration.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/config/RestConfiguration.java @@ -21,9 +21,12 @@ */ package fun.asgc.neutrino.proxy.server.base.rest.config; +import com.alibaba.druid.pool.DruidDataSource; import fun.asgc.neutrino.core.annotation.*; import fun.asgc.neutrino.core.base.Ordered; import fun.asgc.neutrino.core.db.template.JdbcTemplate; +import fun.asgc.neutrino.proxy.server.constant.DbTypeEnum; +import org.sqlite.SQLiteConfig; import org.sqlite.SQLiteDataSource; import javax.sql.DataSource; @@ -37,14 +40,31 @@ import javax.sql.DataSource; @Component public class RestConfiguration { @Autowired - private SqliteConfig sqliteConfig; + private DbConfig dbConfig; @Bean public DataSource dataSource() { - SQLiteDataSource dataSource = new SQLiteDataSource(); - dataSource.setUrl(sqliteConfig.getUrl()); - dataSource.setJournalMode("WAL"); - return dataSource; + DbTypeEnum dbTypeEnum = DbTypeEnum.of(dbConfig.getType()); + if (DbTypeEnum.SQLITE == dbTypeEnum) { + SQLiteDataSource dataSource = new SQLiteDataSource(); + dataSource.setUrl(dbConfig.getUrl()); + dataSource.setJournalMode(SQLiteConfig.JournalMode.WAL.getValue()); + return dataSource; + } else if (DbTypeEnum.MYSQL == dbTypeEnum) { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setDriverClassName(dbConfig.getDriverClass()); + dataSource.setUrl(dbConfig.getUrl()); + dataSource.setInitialSize(5); + dataSource.setMinIdle(5); + dataSource.setMaxActive(20); + dataSource.setMaxWait(60000); + dataSource.setPoolPreparedStatements(true); + dataSource.setUsername(dbConfig.getUsername()); + dataSource.setPassword(dbConfig.getPassword()); + return dataSource; + } + + return null; } @Bean diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/constant/DbTypeEnum.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/constant/DbTypeEnum.java new file mode 100644 index 00000000..0fa3a4dd --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/constant/DbTypeEnum.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 数据库类型美剧 + * @author: aoshiguchen + * @date: 2022/11/25 + */ +@Getter +@AllArgsConstructor +public enum DbTypeEnum { + SQLITE("sqlite"), + MYSQL("mysql"); + + private String type; + + private static final Map cache = Stream.of(DbTypeEnum.values()).collect(Collectors.toMap(DbTypeEnum::getType, Function.identity())); + + public static DbTypeEnum of(String type) { + return cache.get(type); + } +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/ClientConnectRecordController.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/ClientConnectRecordController.java new file mode 100644 index 00000000..8ade1dde --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/ClientConnectRecordController.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.controller; + +import fun.asgc.neutrino.core.annotation.Autowired; +import fun.asgc.neutrino.core.annotation.NonIntercept; +import fun.asgc.neutrino.core.db.page.Page; +import fun.asgc.neutrino.core.db.page.PageQuery; +import fun.asgc.neutrino.core.web.annotation.GetMapping; +import fun.asgc.neutrino.core.web.annotation.RequestMapping; +import fun.asgc.neutrino.core.web.annotation.RestController; +import fun.asgc.neutrino.proxy.server.controller.req.ClientConnectRecordListReq; +import fun.asgc.neutrino.proxy.server.controller.res.ClientConnectRecordListRes; +import fun.asgc.neutrino.proxy.server.service.ClientConnectRecordService; +import fun.asgc.neutrino.proxy.server.util.ParamCheckUtil; +import lombok.extern.slf4j.Slf4j; + +/** + * @author: aoshiguchen + * @date: 2022/11/26 + */ +@Slf4j +@NonIntercept +@RequestMapping("client-connect-record") +@RestController +public class ClientConnectRecordController { + @Autowired + private ClientConnectRecordService clientConnectRecordService; + + @GetMapping("page") + public Page page(PageQuery pageQuery, ClientConnectRecordListReq req) { + ParamCheckUtil.checkNotNull(pageQuery, "pageQuery"); + return clientConnectRecordService.page(pageQuery, req); + } +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/ReportController.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/ReportController.java index 6eda243f..053d5744 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/ReportController.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/ReportController.java @@ -21,11 +21,20 @@ */ package fun.asgc.neutrino.proxy.server.controller; +import fun.asgc.neutrino.core.annotation.Autowired; import fun.asgc.neutrino.core.annotation.NonIntercept; +import fun.asgc.neutrino.core.db.page.Page; +import fun.asgc.neutrino.core.db.page.PageQuery; import fun.asgc.neutrino.core.web.annotation.GetMapping; import fun.asgc.neutrino.core.web.annotation.RequestMapping; import fun.asgc.neutrino.core.web.annotation.RestController; +import fun.asgc.neutrino.proxy.server.controller.req.LicenseFlowReportReq; +import fun.asgc.neutrino.proxy.server.controller.req.UserFlowReportReq; +import fun.asgc.neutrino.proxy.server.controller.res.LicenseFlowReportRes; import fun.asgc.neutrino.proxy.server.controller.res.ReportDataViewRes; +import fun.asgc.neutrino.proxy.server.controller.res.UserFlowReportRes; +import fun.asgc.neutrino.proxy.server.service.ReportService; +import fun.asgc.neutrino.proxy.server.util.ParamCheckUtil; /** * 报表管理 @@ -37,6 +46,9 @@ import fun.asgc.neutrino.proxy.server.controller.res.ReportDataViewRes; @RestController public class ReportController { + @Autowired + private ReportService reportService; + /** * 数据一览: * 在线用户数 查询token有效的用户ID数 @@ -59,4 +71,30 @@ public class ReportController { .setTotalUpstreamFlow("23K").setTotalDownwardFlow("47M") ; } + + /** + * 用户流量报表分页 + * @param pageQuery + * @param req + * @return + */ + @GetMapping("user/flow-report/page") + public Page userFlowReportPage(PageQuery pageQuery, UserFlowReportReq req) { + ParamCheckUtil.checkNotNull(pageQuery, "pageQuery"); + + return reportService.userFlowReportPage(pageQuery, req); + } + + /** + * license流量报表分页 + * @param pageQuery + * @param req + * @return + */ + @GetMapping("license/flow-report/page") + public Page licenseFlowReportPage(PageQuery pageQuery, LicenseFlowReportReq req) { + ParamCheckUtil.checkNotNull(pageQuery, "pageQuery"); + + return reportService.licenseFlowReportPage(pageQuery, req); + } } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/req/ClientConnectRecordListReq.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/req/ClientConnectRecordListReq.java new file mode 100644 index 00000000..a0e3caf9 --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/req/ClientConnectRecordListReq.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.controller.req; + +import lombok.Data; + +/** + * @author: aoshiguchen + * @date: 2022/11/26 + */ +@Data +public class ClientConnectRecordListReq { + +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/req/LicenseFlowReportReq.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/req/LicenseFlowReportReq.java new file mode 100644 index 00000000..f4069327 --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/req/LicenseFlowReportReq.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.controller.req; + +import lombok.Data; + +/** + * @author: aoshiguchen + * @date: 2022/12/21 + */ +@Data +public class LicenseFlowReportReq { + +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/req/UserFlowReportReq.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/req/UserFlowReportReq.java new file mode 100644 index 00000000..66a2fd7a --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/req/UserFlowReportReq.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.controller.req; + +import lombok.Data; + +/** + * @author: aoshiguchen + * @date: 2022/12/21 + */ +@Data +public class UserFlowReportReq { + +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/res/ClientConnectRecordListRes.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/res/ClientConnectRecordListRes.java new file mode 100644 index 00000000..4c6116ea --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/res/ClientConnectRecordListRes.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.controller.res; + +import lombok.Data; + +import java.util.Date; + +/** + * @author: aoshiguchen + * @date: 2022/11/26 + */ +@Data +public class ClientConnectRecordListRes { + private Integer id; + private String ip; + private Integer licenseId; + private Integer type; + private Integer userId; + private String userName; + private String licenseName; + private String msg; + /** + * 1、成功 + * 2、失败 + */ + private Integer code; + private String err; + /** + * 创建时间 + */ + private Date createTime; +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/res/LicenseFlowReportRes.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/res/LicenseFlowReportRes.java new file mode 100644 index 00000000..9abcaf24 --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/res/LicenseFlowReportRes.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.controller.res; + +import lombok.Data; + +import java.util.Date; + +/** + * @author: aoshiguchen + * @date: 2022/12/21 + */ +@Data +public class LicenseFlowReportRes { + /** + * 用户ID + */ + private Integer userId; + /** + * 用户名称 + */ + private String userName; + /** + * licenseId + */ + private Integer licenseId; + /** + * license名称 + */ + private String licenseName; + /** + * 写入字节数 + */ + private Long writeBytes; + /** + * 读取字节数 + */ + private Long readBytes; + /** + * 写入流量描述 + */ + private String writeFlowStr; + /** + * 读取流量描述 + */ + private String readFlowStr; + /** + * 流量描述 + */ + private String flowStr; + /** + * 报表时间 + */ + private Date date; + /** + * 创建时间 + */ + private Date createTime; +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/res/UserFlowReportRes.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/res/UserFlowReportRes.java new file mode 100644 index 00000000..f854b3ac --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/res/UserFlowReportRes.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.controller.res; + +import lombok.Data; + +import java.util.Date; + +/** + * @author: aoshiguchen + * @date: 2022/12/21 + */ +@Data +public class UserFlowReportRes { + /** + * 用户ID + */ + private Integer userId; + /** + * 用户名称 + */ + private String userName; + /** + * 历史写入字节数 + */ + private Long historyWriteBytes; + /** + * 历史读取字节数 + */ + private Long historyReadBytes; + /** + * 写入字节数 + */ + private Long writeBytes; + /** + * 读取字节数 + */ + private Long readBytes; + /** + * 写入流量描述 + */ + private String writeFlowStr; + /** + * 读取流量描述 + */ + private String readFlowStr; + /** + * 流量描述 + */ + private String flowStr; + /** + * 报表时间 + */ + private Date date; + /** + * 创建时间 + */ + private Date createTime; +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/ClientConnectRecordMapper.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/ClientConnectRecordMapper.java index 42ecd441..d3edc7ea 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/ClientConnectRecordMapper.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/ClientConnectRecordMapper.java @@ -2,7 +2,12 @@ package fun.asgc.neutrino.proxy.server.dal; import fun.asgc.neutrino.core.annotation.Component; import fun.asgc.neutrino.core.aop.Intercept; +import fun.asgc.neutrino.core.db.annotation.ResultType; +import fun.asgc.neutrino.core.db.annotation.Select; import fun.asgc.neutrino.core.db.mapper.SqlMapper; +import fun.asgc.neutrino.core.db.page.Page; +import fun.asgc.neutrino.proxy.server.controller.req.ClientConnectRecordListReq; +import fun.asgc.neutrino.proxy.server.controller.res.ClientConnectRecordListRes; import fun.asgc.neutrino.proxy.server.dal.entity.ClientConnectRecordDO; /** @@ -14,4 +19,8 @@ import fun.asgc.neutrino.proxy.server.dal.entity.ClientConnectRecordDO; public interface ClientConnectRecordMapper extends SqlMapper { void add(ClientConnectRecordDO clientConnectRecordDO); + + @ResultType(ClientConnectRecordListRes.class) + @Select("select * from client_connect_record order by id desc") + void page(Page page, ClientConnectRecordListReq req); } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/DataCleanMapper.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/DataCleanMapper.java index 998ef2d2..70694712 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/DataCleanMapper.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/DataCleanMapper.java @@ -26,6 +26,8 @@ import fun.asgc.neutrino.core.aop.Intercept; import fun.asgc.neutrino.core.db.annotation.Delete; import fun.asgc.neutrino.core.db.mapper.SqlMapper; +import java.util.Date; + /** * @author: aoshiguchen * @date: 2022/9/17 @@ -35,21 +37,21 @@ import fun.asgc.neutrino.core.db.mapper.SqlMapper; public interface DataCleanMapper extends SqlMapper { @Delete("delete from `job_log` where create_time < ?") - void cleanJobLog(long date); + void cleanJobLog(Date date); @Delete("delete from `user_login_record` where create_time < ?") - void cleanUserLoginRecord(long date); + void cleanUserLoginRecord(Date date); @Delete("delete from `client_connect_record` where create_time < ?") - void cleanClientConnectRecord(long date); + void cleanClientConnectRecord(Date date); @Delete("delete from `flow_report_minute` where create_time < ?") - void cleanFlowMinuteReport(long date); + void cleanFlowMinuteReport(Date date); @Delete("delete from `flow_report_hour` where create_time < ?") - void cleanFlowHourReport(long date); + void cleanFlowHourReport(Date date); @Delete("delete from `flow_report_day` where create_time < ?") - void cleanFlowDayReport(long date); + void cleanFlowDayReport(Date date); } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/LicenseMapper.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/LicenseMapper.java index d2547af7..49bcfc27 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/LicenseMapper.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/LicenseMapper.java @@ -77,7 +77,7 @@ public interface LicenseMapper extends SqlMapper { @Update("update `license` set is_online = :isOnline, update_time = :updateTime") void updateOnlineStatus(@Param("isOnline") Integer isOnline, @Param("updateTime") Date updateTime); - @Update("update `license` set key = :key,update_time = :updateTime where id = :id") + @Update("update `license` set `key` = :key,update_time = :updateTime where id = :id") void reset(@Param("id") Integer id, @Param("key") String key, @Param("updateTime") Date updateTime); @Delete("delete from `license` where id = ?") @@ -101,6 +101,6 @@ public interface LicenseMapper extends SqlMapper { @Select("select * from `license` where user_id = :userId and name =:name and id not in (:excludeIds) limit 0,1") LicenseDO checkRepeat(@Param("userId") Integer userId, @Param("name") String name, @Param("excludeIds") Set excludeIds); - @Select("select * from `license` where key = ?") + @Select("select * from `license` where `key` = ?") LicenseDO findByKey(String licenseKey); } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/UserReportMapper.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/UserReportMapper.java new file mode 100644 index 00000000..5d387efa --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/UserReportMapper.java @@ -0,0 +1,22 @@ +package fun.asgc.neutrino.proxy.server.dal; + +import fun.asgc.neutrino.core.annotation.Component; +import fun.asgc.neutrino.core.annotation.Param; +import fun.asgc.neutrino.core.aop.Intercept; +import fun.asgc.neutrino.core.db.mapper.SqlMapper; +import fun.asgc.neutrino.core.db.page.Page; +import fun.asgc.neutrino.proxy.server.controller.res.UserFlowReportRes; + +import java.util.Date; + +/** + * @author: aoshiguchen + * @date: 2023/1/18 + */ +@Intercept(ignoreGlobal = true) +@Component +public interface UserReportMapper extends SqlMapper { + + void userFlowReportPage(Page page, @Param("todayBegin") Date todayBegin, @Param("todayEnd") Date todayEnd); + +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/UserTokenMapper.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/UserTokenMapper.java index c3673d80..eeae8fd2 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/UserTokenMapper.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/UserTokenMapper.java @@ -56,7 +56,7 @@ public interface UserTokenMapper extends SqlMapper { * @return */ // @Select("select * from user_token where token = ? and expiration_time > ?") - UserTokenDO findByAvailableToken(String token, Long time); + UserTokenDO findByAvailableToken(String token, Date date); /** * 根据token删除记录 diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/job/DataCleanJob.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/job/DataCleanJob.java index 6bcc2b22..44f43a0b 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/job/DataCleanJob.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/job/DataCleanJob.java @@ -84,37 +84,37 @@ public class DataCleanJob implements IJobHandler { { Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getJobLogKeepDays()); log.info("清理调度管理日志 date:{}", sdf.format(date)); - dataCleanMapper.cleanJobLog(date.getTime()); + dataCleanMapper.cleanJobLog(date); } { Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getUserLoginRecordKeepDays()); log.info("清理用户登录日志 date:{}", sdf.format(date)); - dataCleanMapper.cleanUserLoginRecord(date.getTime()); + dataCleanMapper.cleanUserLoginRecord(date); } { Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getClientConnectRecordKeepDays()); log.info("清理客户端连接日志 date:{}", sdf.format(date)); - dataCleanMapper.cleanClientConnectRecord(date.getTime()); + dataCleanMapper.cleanClientConnectRecord(date); } { Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getFlowMinuteReportKeepDays()); log.info("清理流通统计分钟报表日志 date:{}", sdf.format(date)); - dataCleanMapper.cleanFlowMinuteReport(date.getTime()); + dataCleanMapper.cleanFlowMinuteReport(date); } { Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getFlowHourReportKeepDays()); log.info("清理流通统计小时报表日志 date:{}", sdf.format(date)); - dataCleanMapper.cleanFlowHourReport(date.getTime()); + dataCleanMapper.cleanFlowHourReport(date); } { Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getFlowDayReportKeepDays()); log.info("清理流通统计日报表日志 date:{}", sdf.format(date)); - dataCleanMapper.cleanFlowDayReport(date.getTime()); + dataCleanMapper.cleanFlowDayReport(date); } } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/job/FlowReportForMonthJob.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/job/FlowReportForMonthJob.java index e06c2478..fdb07fdf 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/job/FlowReportForMonthJob.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/job/FlowReportForMonthJob.java @@ -63,11 +63,11 @@ public class FlowReportForMonthJob implements IJobHandler { Date now = new Date(); String dateStr = DateUtil.format(DateUtil.addDate(now, Calendar.MONTH, -1), "yyyy-MM"); Date date = DateUtil.parse(dateStr, "yyyy-MM"); - Date startDayDate = DateUtil.getDayBegin(date); - Date endEndDate = DateUtil.getDayEnd(date); + Date startDayDate = DateUtil.getMonthBegin(date); + Date endEndDate = DateUtil.getMonthEnd(date); // 删除原来的记录 - flowReportDayMapper.deleteByDateStr(dateStr); + flowReportMonthMapper.deleteByDateStr(dateStr); // 查询上个月的天级别统计数据 List flowReportDayList = flowReportDayMapper.findListByDateRange(startDayDate, endEndDate); diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/ClientConnectRecordService.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/ClientConnectRecordService.java index 83b75878..fc9fbba8 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/ClientConnectRecordService.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/ClientConnectRecordService.java @@ -24,10 +24,26 @@ package fun.asgc.neutrino.proxy.server.service; import fun.asgc.neutrino.core.annotation.Autowired; import fun.asgc.neutrino.core.annotation.Component; import fun.asgc.neutrino.core.annotation.NonIntercept; +import fun.asgc.neutrino.core.db.page.Page; +import fun.asgc.neutrino.core.db.page.PageQuery; +import fun.asgc.neutrino.core.util.CollectionUtil; +import fun.asgc.neutrino.proxy.server.base.rest.SystemContextHolder; +import fun.asgc.neutrino.proxy.server.controller.req.ClientConnectRecordListReq; +import fun.asgc.neutrino.proxy.server.controller.res.ClientConnectRecordListRes; import fun.asgc.neutrino.proxy.server.dal.ClientConnectRecordMapper; +import fun.asgc.neutrino.proxy.server.dal.LicenseMapper; +import fun.asgc.neutrino.proxy.server.dal.UserMapper; import fun.asgc.neutrino.proxy.server.dal.entity.ClientConnectRecordDO; +import fun.asgc.neutrino.proxy.server.dal.entity.LicenseDO; +import fun.asgc.neutrino.proxy.server.dal.entity.UserDO; import lombok.extern.slf4j.Slf4j; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + /** * @author: aoshiguchen * @date: 2022/11/23 @@ -38,8 +54,51 @@ import lombok.extern.slf4j.Slf4j; public class ClientConnectRecordService { @Autowired private ClientConnectRecordMapper clientConnectRecordMapper; + @Autowired + private LicenseMapper licenseMapper; + @Autowired + private UserMapper userMapper; public void add(ClientConnectRecordDO clientConnectRecordDO) { clientConnectRecordMapper.add(clientConnectRecordDO); } + + public Page page(PageQuery pageQuery, ClientConnectRecordListReq req) { + Page page = Page.create(pageQuery); + clientConnectRecordMapper.page(page, req); + if (CollectionUtil.isEmpty(page.getRecords())) { + return page; + } + Set licenseIds = page.getRecords().stream().map(ClientConnectRecordListRes::getLicenseId).collect(Collectors.toSet()); + if (CollectionUtil.isEmpty(licenseIds)) { + return page; + } + List licenseList = licenseMapper.findByIds(licenseIds); + if (CollectionUtil.isEmpty(licenseList)) { + return page; + } + Set userIds = licenseList.stream().map(LicenseDO::getUserId).collect(Collectors.toSet()); + List userList = userMapper.findByIds(userIds); + Map licenseMap = licenseList.stream().collect(Collectors.toMap(LicenseDO::getId, Function.identity())); + Map userMap = userList.stream().collect(Collectors.toMap(UserDO::getId, Function.identity())); + boolean isAdmin = SystemContextHolder.isAdmin(); + page.getRecords().forEach(item -> { + LicenseDO license = licenseMap.get(item.getLicenseId()); + if (null == license) { + return; + } + item.setLicenseName(license.getName()); + item.setUserId(license.getUserId()); + UserDO user = userMap.get(license.getUserId()); + if (null == user) { + return; + } + item.setUserName(user.getName()); + if (!isAdmin) { + // msg可能带有license等敏感信息,若登录者为游客,则不展示 + item.setMsg("******"); + } + }); + return page; + } } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/ReportService.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/ReportService.java new file mode 100644 index 00000000..40aa3543 --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/ReportService.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.service; + +import fun.asgc.neutrino.core.annotation.Autowired; +import fun.asgc.neutrino.core.annotation.Component; +import fun.asgc.neutrino.core.annotation.NonIntercept; +import fun.asgc.neutrino.core.db.page.Page; +import fun.asgc.neutrino.core.db.page.PageQuery; +import fun.asgc.neutrino.proxy.server.controller.req.LicenseFlowReportReq; +import fun.asgc.neutrino.proxy.server.controller.req.UserFlowReportReq; +import fun.asgc.neutrino.proxy.server.controller.res.LicenseFlowReportRes; +import fun.asgc.neutrino.proxy.server.controller.res.UserFlowReportRes; +import fun.asgc.neutrino.proxy.server.dal.UserReportMapper; +import lombok.extern.slf4j.Slf4j; + +/** + * @author: aoshiguchen + * @date: 2022/12/23 + */ +@Slf4j +@NonIntercept +@Component +public class ReportService { + + @Autowired + private UserReportMapper userReportMapper; + + /** + * 用户流量报表分页 + * @param pageQuery + * @param req + * @return + */ + public Page userFlowReportPage(PageQuery pageQuery, UserFlowReportReq req) { + // TODO + return null; + } + + /** + * license流量报表分页 + * @param pageQuery + * @param req + * @return + */ + public Page licenseFlowReportPage(PageQuery pageQuery, LicenseFlowReportReq req) { + // TODO + return null; + } +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/UserService.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/UserService.java index e45d08dd..4b8dbae5 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/UserService.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/UserService.java @@ -115,7 +115,7 @@ public class UserService { public UserDO findByToken(String token) { Date now = new Date(); - UserTokenDO userTokenDO = userTokenMapper.findByAvailableToken(token, now.getTime()); + UserTokenDO userTokenDO = userTokenMapper.findByAvailableToken(token, now); if (null == userTokenDO) { return null; } diff --git a/neutrino-proxy-server/src/main/resources/application.yml b/neutrino-proxy-server/src/main/resources/application.yml index 603a7fdb..f27a5842 100644 --- a/neutrino-proxy-server/src/main/resources/application.yml +++ b/neutrino-proxy-server/src/main/resources/application.yml @@ -27,6 +27,12 @@ neutrino: key-manager-password: 123456 jks-path: classpath:/test.jks data: - sqlite: + db: + type: sqlite url: jdbc:sqlite:data.db driver-class: org.sqlite.JDBC +# type: mysql +# url: jdbc:mysql://103.163.47.16:3306/neutrino-proxy?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useAffectedRows=true&useSSL=false +# driver-class: com.mysql.jdbc.Driver +# username: "******" +# password: "******" diff --git a/neutrino-proxy-server/src/main/resources/mapper/UserReportMapper.xml b/neutrino-proxy-server/src/main/resources/mapper/UserReportMapper.xml new file mode 100644 index 00000000..267d4f04 --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/mapper/UserReportMapper.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql b/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql new file mode 100644 index 00000000..60c8eab5 --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql @@ -0,0 +1,192 @@ +#############################系统管理相关表############################# +#用户表 +CREATE TABLE IF NOT EXISTS `user` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` varchar(50) NOT NULL COMMENT '用户名', + `login_name` varchar(50) NOT NULL COMMENT '登录名', + `login_password` varchar(255) NOT NULL COMMENT '登录密码', + `enable` int NOT NULL COMMENT '是否启用(1、启用 2、禁用)', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + `update_time` datetime(3) NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `I_user_login_name` (`login_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#用户token表 +CREATE TABLE IF NOT EXISTS `user_token` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `token` varchar(50) NOT NULL COMMENT 'token', + `user_id` int NOT NULL COMMENT '用户ID', + `expiration_time` datetime(3) NOT NULL COMMENT '过期时间', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + `update_time` datetime(3) NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `I_user_token_user_id` (`user_id`), + KEY `I_user_token_token` (`token`), + KEY `I_user_token_expiration_time` (`expiration_time`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#端口池 +CREATE TABLE IF NOT EXISTS `port_pool` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `port` int NOT NULL COMMENT '端口', + `enable` int NOT NULL COMMENT '是否启用(1、启用 2、禁用)', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + `update_time` datetime(3) NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `I_port_pool_port` (`port`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#############################代理配置相关表############################# +#license表 +CREATE TABLE IF NOT EXISTS `license` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` varchar(50) NOT NULL COMMENT 'license名称', + `key` varchar(100) NOT NULL COMMENT 'license key', + `user_id` int NOT NULL COMMENT '用户ID', + `is_online` int NOT NULL COMMENT '是否在线(1、在线 2、离线)', + `enable` int NOT NULL COMMENT '是否启用(1、启用 2、禁用)', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + `update_time` datetime(3) NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `I_license_key` (`key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#端口映射表 +CREATE TABLE IF NOT EXISTS `port_mapping` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `license_id` int NOT NULL COMMENT 'licenseID', + `server_port` int NOT NULL COMMENT '服务端端口', + `client_ip` varchar(20) NOT NULL COMMENT '客户端IP', + `client_port` int NOT NULL COMMENT '客户端端口', + `is_online` int NOT NULL COMMENT '是否在线(1、在线 2、离线)', + `enable` int NOT NULL COMMENT '是否启用(1、启用 2、禁用)', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + `update_time` datetime(3) NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `I_port_mapping_server_port` (`server_port`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#############################日志管理相关表############################# +#用户登录记录表 +CREATE TABLE IF NOT EXISTS `user_login_record` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `user_id` int NOT NULL COMMENT '用户ID', + `ip` varchar(50) NOT NULL COMMENT 'IP', + `token` varchar(100) NOT NULL COMMENT 'token', + `type` int NOT NULL COMMENT '类型(1、登录 2、登出)', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +#客户端连接记录表 +CREATE TABLE IF NOT EXISTS `client_connect_record` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'IP', + `license_id` int NOT NULL COMMENT 'licenseId', + `type` int NOT NULL COMMENT '类型(1、连接 2、断开连接)', + `msg` varchar(512) DEFAULT NULL COMMENT '消息', + `code` int NOT NULL COMMENT '结果 (1、成功 2、失败)', + `err` text DEFAULT NULL COMMENT '异常信息', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +#############################调度管理相关表############################# +#触发器信息表 +CREATE TABLE IF NOT EXISTS `job_info` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `desc` varchar(255) NOT NULL COMMENT '描述', + `handler` varchar(255) NOT NULL COMMENT '处理器', + `cron` varchar(128) NOT NULL COMMENT 'cron', + `param` varchar(512) DEFAULT NULL COMMENT '参数', + `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮箱', + `alarm_ding` varchar(255) DEFAULT NULL COMMENT '报警钉钉配置', + `enable` int NOT NULL COMMENT '是否启用(1、启用 2、禁用)', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + `update_time` datetime(3) NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `I_job_info_handler` (`handler`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#触发器日志表 +CREATE TABLE IF NOT EXISTS `job_log` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `job_id` int NOT NULL COMMENT 'JobId', + `handler` varchar(255) NOT NULL COMMENT '处理器', + `param` varchar(512) DEFAULT NULL COMMENT '参数', + `code` int NOT NULL COMMENT '结果(1、成功 2、失败)', + `msg` text COMMENT '消息', + `alarm_status` int NOT NULL COMMENT '报警状态(1、未报警 2、已报警)', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `I_job_log_create_time` (`create_time`) USING BTREE, + KEY `I_job_log_code` (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#############################报表管理相关表############################# +#流量统计报表-分钟(保留24小时) +CREATE TABLE IF NOT EXISTS `flow_report_minute` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `user_id` int NOT NULL COMMENT '用户ID', + `license_id` int NOT NULL COMMENT 'licenseId', + `write_bytes` int NOT NULL COMMENT '写入流量', + `read_bytes` int NOT NULL COMMENT '读取流量', + `date` datetime(3) NOT NULL COMMENT '时间', + `date_str` varchar(20) NOT NULL COMMENT '时间 yyyy-MM-dd HH:mm', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `I_flow_report_minute_create_time` (`create_time`) USING BTREE, + KEY `I_flow_report_minute_date` (`date`) USING BTREE, + KEY `I_flow_report_minute_user_id` (`user_id`), + KEY `I_flow_report_minute_license_id` (`license_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#流量统计报表-小时(保留60天) +CREATE TABLE IF NOT EXISTS `flow_report_hour` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `user_id` int NOT NULL COMMENT '用户ID', + `license_id` int NOT NULL COMMENT 'licenseId', + `write_bytes` int NOT NULL COMMENT '写入流量', + `read_bytes` int NOT NULL COMMENT '读取流量', + `date` datetime(3) NOT NULL COMMENT '时间', + `date_str` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '时间 yyyy-MM-dd HH', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `I_flow_report_hour_create_time` (`create_time`) USING BTREE, + KEY `I_flow_report_hour_date` (`date`) USING BTREE, + KEY `I_flow_report_hour_user_id` (`user_id`), + KEY `I_flow_report_hour_license_id` (`license_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#流量统计报表-天(保留1年) +CREATE TABLE IF NOT EXISTS `flow_report_day` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `user_id` int NOT NULL COMMENT '用户ID', + `license_id` int NOT NULL COMMENT 'licenseId', + `write_bytes` int NOT NULL COMMENT '写入流量', + `read_bytes` int NOT NULL COMMENT '读取流量', + `date` datetime(3) NOT NULL COMMENT '时间', + `date_str` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '时间 yyyy-MM-dd', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `I_flow_report_day_create_time` (`create_time`) USING BTREE, + KEY `I_flow_report_day_date` (`date`) USING BTREE, + KEY `I_flow_report_day_user_id` (`user_id`), + KEY `I_flow_report_day_license_id` (`license_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +#流量统计报表-月(全量保留) +CREATE TABLE IF NOT EXISTS `flow_report_month` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `user_id` int NOT NULL COMMENT '用户ID', + `license_id` int NOT NULL COMMENT 'licenseId', + `write_bytes` int NOT NULL COMMENT '写入流量', + `read_bytes` int NOT NULL COMMENT '读取流量', + `date` datetime(3) NOT NULL COMMENT '时间', + `date_str` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '时间 yyyy-MM', + `create_time` datetime(3) NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `I_flow_report_month_create_time` (`create_time`) USING BTREE, + KEY `I_flow_report_month_date` (`date`) USING BTREE, + KEY `I_flow_report_month_user_id` (`user_id`), + KEY `I_flow_report_month_license_id` (`license_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; \ No newline at end of file diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/job_info.data.sql b/neutrino-proxy-server/src/main/resources/sql/mysql/job_info.data.sql new file mode 100644 index 00000000..278387ba --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/job_info.data.sql @@ -0,0 +1,13 @@ +#job_qrtz_trigger_info +INSERT INTO job_info(`id`, `desc`, `handler`, `cron`, `param`, `enable`, `create_time`, `update_time`) VALUES +(1, '示例Job', 'DemoJob', '0/10 * * * * ?', '{"a":101}', 1, now(), now()); +INSERT INTO job_info(`id`, `desc`, `handler`, `cron`, `param`, `enable`, `create_time`, `update_time`) VALUES +(2, '数据清理任务', 'DataCleanJob', '0 0 1 * * ?', '', 1, now(), now()); +INSERT INTO job_info(`id`, `desc`, `handler`, `cron`, `param`, `enable`, `create_time`, `update_time`) VALUES +(3, '流量统计报表-分钟', 'FlowReportForMinuteJob', '0 */1 * * * ?', '', 1, now(), now()); +INSERT INTO job_info(`id`, `desc`, `handler`, `cron`, `param`, `enable`, `create_time`, `update_time`) VALUES +(4, '流量统计报表-小时', 'FlowReportForHourJob', '0 0 */1 * * ?', '', 1, now(), now()); +INSERT INTO job_info(`id`, `desc`, `handler`, `cron`, `param`, `enable`, `create_time`, `update_time`) VALUES +(5, '流量统计报表-天', 'FlowReportForDayJob', '0 0 1 * * ?', '', 1, now(), now()); +INSERT INTO job_info(`id`, `desc`, `handler`, `cron`, `param`, `enable`, `create_time`, `update_time`) VALUES +(6, '流量统计报表-月', 'FlowReportForMonthJob', '0 30 1 1 * ?', '', 1, now(), now()); \ No newline at end of file diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/license.data.sql b/neutrino-proxy-server/src/main/resources/sql/mysql/license.data.sql new file mode 100644 index 00000000..f7e239a2 --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/license.data.sql @@ -0,0 +1,3 @@ +#license +INSERT INTO license(`id`, `name`, `key`, `user_id`, `is_online`, `enable`, `create_time`, `update_time`) VALUES +(1, '我的mac', 'b0a907332b474b25897c4dcb31fc7eb6', 1, 2, 1, now(), now()); diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/port_mapping.data.sql b/neutrino-proxy-server/src/main/resources/sql/mysql/port_mapping.data.sql new file mode 100644 index 00000000..4ffcdba7 --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/port_mapping.data.sql @@ -0,0 +1,5 @@ +#port_mapping +INSERT INTO port_mapping(`id`, `license_id`, `server_port`, `client_ip`, `client_port`, `is_online`, `enable`, `create_time`, `update_time`) VALUES +(1, 1, 9101, '127.0.0.1', 8080, 2, 1, now(), now()); +INSERT INTO port_mapping(`id`, `license_id`, `server_port`, `client_ip`, `client_port`, `is_online`, `enable`, `create_time`, `update_time`) VALUES +(2, 1, 9102, '127.0.0.1', 3306, 2, 1, now(), now()); diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/port_pool.data.sql b/neutrino-proxy-server/src/main/resources/sql/mysql/port_pool.data.sql new file mode 100644 index 00000000..3949bb75 --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/port_pool.data.sql @@ -0,0 +1,41 @@ +#端口池 +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(1, 9101, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(2, 9102, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(3, 9103, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(4, 9104, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(5, 9105, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(6, 9106, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(7, 9107, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(8, 9108, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(9, 9109, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(10, 9110, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(11, 9111, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(12, 9112, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(13, 9113, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(14, 9114, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(15, 9115, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(16, 9116, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(17, 9117, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(18, 9118, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(19, 9119, 1, now(), now()); +INSERT INTO port_pool(`id`, `port`, `enable`, `create_time`, `update_time`) VALUES +(20, 9120, 1, now(), now()); diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/user.data.sql b/neutrino-proxy-server/src/main/resources/sql/mysql/user.data.sql new file mode 100644 index 00000000..1be853ba --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/user.data.sql @@ -0,0 +1,5 @@ +#用户表 6613b92b77056faeb72068f184ed4c4f +INSERT INTO `user`(`id`, `name`,`login_name`,`login_password`,`enable`,`create_time`, `update_time`) VALUES +(1, '管理员', 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, now(), now()); +INSERT INTO `user`(`id`, `name`,`login_name`,`login_password`,`enable`,`create_time`, `update_time`) VALUES +(2, '游客', 'visitor', 'e10adc3949ba59abbe56e057f20f883e', 1, now(), now()); diff --git a/neutrino-proxy-server/src/main/resources/sql/init-structure.sql b/neutrino-proxy-server/src/main/resources/sql/sqlite/init-structure.sql similarity index 100% rename from neutrino-proxy-server/src/main/resources/sql/init-structure.sql rename to neutrino-proxy-server/src/main/resources/sql/sqlite/init-structure.sql diff --git a/neutrino-proxy-server/src/main/resources/sql/job_info.data.sql b/neutrino-proxy-server/src/main/resources/sql/sqlite/job_info.data.sql similarity index 100% rename from neutrino-proxy-server/src/main/resources/sql/job_info.data.sql rename to neutrino-proxy-server/src/main/resources/sql/sqlite/job_info.data.sql diff --git a/neutrino-proxy-server/src/main/resources/sql/license.data.sql b/neutrino-proxy-server/src/main/resources/sql/sqlite/license.data.sql similarity index 100% rename from neutrino-proxy-server/src/main/resources/sql/license.data.sql rename to neutrino-proxy-server/src/main/resources/sql/sqlite/license.data.sql diff --git a/neutrino-proxy-server/src/main/resources/sql/port_mapping.data.sql b/neutrino-proxy-server/src/main/resources/sql/sqlite/port_mapping.data.sql similarity index 100% rename from neutrino-proxy-server/src/main/resources/sql/port_mapping.data.sql rename to neutrino-proxy-server/src/main/resources/sql/sqlite/port_mapping.data.sql diff --git a/neutrino-proxy-server/src/main/resources/sql/port_pool.data.sql b/neutrino-proxy-server/src/main/resources/sql/sqlite/port_pool.data.sql similarity index 100% rename from neutrino-proxy-server/src/main/resources/sql/port_pool.data.sql rename to neutrino-proxy-server/src/main/resources/sql/sqlite/port_pool.data.sql diff --git a/neutrino-proxy-server/src/main/resources/sql/user.data.sql b/neutrino-proxy-server/src/main/resources/sql/sqlite/user.data.sql similarity index 100% rename from neutrino-proxy-server/src/main/resources/sql/user.data.sql rename to neutrino-proxy-server/src/main/resources/sql/sqlite/user.data.sql diff --git a/todolist.MD b/todolist.MD index 35717e6d..f38ef29c 100644 --- a/todolist.MD +++ b/todolist.MD @@ -1,7 +1,13 @@ -# BUG -- neutrino-proxy-admin 打包后启动,token失效不会跳回登录页面 +# 功能点 +- 用户流量报表 + - 弹框展示月度明细 + - 弹框展示今日流量明细 +- License流量报表 + - 弹框展示月度明细 + - 弹框展示今日流量明细 +- 首页图表📈 -# 优化 -- 调度管理,增加查看按钮,解决异常情况下,列表展示堆栈异常信息不全,不方便查看的问题 -- 用户列表增加修改密码入口,管理员可以修改指定用户密码,无需验证原密码(仅管理员操作 -- 增加当前登录用户修改自己密码的功能,需要验证原密码 \ No newline at end of file +# Bug +- windows环境下直接运行发布版的jar包,日志输出乱码 +- 部份用户windows环境下启动客户端,扫描类个数为0个 +- 代理mysql时,使用未开启远程访问的账号走代理访问mysql,代理客户端出现断开现象 \ No newline at end of file