diff --git a/front/.babelrc b/front/.babelrc new file mode 100644 index 00000000..2a818842 --- /dev/null +++ b/front/.babelrc @@ -0,0 +1,5 @@ +{ + "presets": [ + "@vue/app" + ] +} diff --git a/front/.editorconfig b/front/.editorconfig new file mode 100644 index 00000000..9d08a1a8 --- /dev/null +++ b/front/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/front/.env.development b/front/.env.development new file mode 100644 index 00000000..7c1979f5 --- /dev/null +++ b/front/.env.development @@ -0,0 +1,4 @@ +NODE_ENV=development +VUE_APP_TYPE=dev +VUE_APP_URL=http://172.16.0.145:10086/smart-admin-api/ +VUE_APP_SOCKET_URL=ws://172.16.0.145:10086/smart-admin-api/ diff --git a/front/.env.prod b/front/.env.prod new file mode 100644 index 00000000..522eeaaa --- /dev/null +++ b/front/.env.prod @@ -0,0 +1,5 @@ +NODE_ENV=production +VUE_APP_TYPE=prod +VUE_APP_URL=http://preview.smartadmin.1024lab.net/smart-admin-api/ +VUE_APP_SOCKET_URL=ws://preview.smartadmin.1024lab.net/smart-admin-api/ + diff --git a/front/.env.sit b/front/.env.sit new file mode 100644 index 00000000..ac2ac140 --- /dev/null +++ b/front/.env.sit @@ -0,0 +1,3 @@ +NODE_ENV=production +VUE_APP_TYPE=sit +VUE_APP_URL=http://172.16.0.145:10086/smart-admin-api/ diff --git a/front/.eslintignore b/front/.eslintignore new file mode 100644 index 00000000..e69de29b diff --git a/front/.eslintrc.js b/front/.eslintrc.js new file mode 100644 index 00000000..28180441 --- /dev/null +++ b/front/.eslintrc.js @@ -0,0 +1,34 @@ +module.exports = { + root: true, + "extends": [ + "plugin:vue/essential", + "@vue/standard" + ], + rules: { + "generator-star-spacing": "off", //生成器函数*的前后空格 + // allow debugger during development + "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", + "vue/no-parsing-error": [2, { + "x-invalid-end-tag": false + }], + "no-const-assign": 2, //禁止修改const声明的变量 + "no-unused-vars": [0, { //禁止声明变量后却不使用 + // 允许声明未使用变量 + "vars": "all", + // 参数不检查 + "args": "none" + }], + "quotes": [2, "single"], //单引号 + "singleQuote": true, + "indent": 2, //缩进量 + "no-var": 2, //禁用var,用let和const代替 + "camelcase": 2, //强制驼峰法命名 + "eqeqeq": 1, //要求使用 === 和 !== 代替 == 和 != 操作符 + "no-eq-null": 2, //禁止对null使用==或!=运算符 + "no-sequences": 0, //禁用逗号操作符 + "semi": [2, "always"] //强制分号 + }, + parserOptions: { + parser: "babel-eslint" + } +} diff --git a/front/.gitignore b/front/.gitignore new file mode 100644 index 00000000..17032d3d --- /dev/null +++ b/front/.gitignore @@ -0,0 +1,28 @@ +.DS_Store +node_modules +/dist + +package-lock.json + +/tests/e2e/videos/ +/tests/e2e/screenshots/ + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* + +build/env.js diff --git a/front/.postcssrc.js b/front/.postcssrc.js new file mode 100644 index 00000000..961986e2 --- /dev/null +++ b/front/.postcssrc.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} diff --git a/front/.travis.yml b/front/.travis.yml new file mode 100644 index 00000000..07c971f8 --- /dev/null +++ b/front/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: stable +script: npm run lint +notifications: + email: false diff --git a/front/LICENSE b/front/LICENSE new file mode 100644 index 00000000..7ec88ac0 --- /dev/null +++ b/front/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 iView + +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. diff --git a/front/README.md b/front/README.md new file mode 100644 index 00000000..fe637c03 --- /dev/null +++ b/front/README.md @@ -0,0 +1,13 @@ +### 启动讲解 + +###### 配置vscode +将 /vscode/settings.json文件配置到vscode中 + +###### 启动 +1 安装依赖: + +`npm install` + +2 运行本地环境 + +`npm run local` \ No newline at end of file diff --git a/front/cypress.json b/front/cypress.json new file mode 100644 index 00000000..470c7201 --- /dev/null +++ b/front/cypress.json @@ -0,0 +1,3 @@ +{ + "pluginsFile": "tests/e2e/plugins/index.js" +} diff --git a/front/doc/notice.txt b/front/doc/notice.txt new file mode 100644 index 00000000..8184781f --- /dev/null +++ b/front/doc/notice.txt @@ -0,0 +1,2 @@ +1 login-form.vue 去掉登录帐号提示 +2 login-form.vue 修改默认登录绑定帐号 \ No newline at end of file diff --git a/front/package.json b/front/package.json new file mode 100644 index 00000000..037f4779 --- /dev/null +++ b/front/package.json @@ -0,0 +1,86 @@ +{ + "name": "smart-admin", + "version": "1.0.0", + "author": "1024创新实验室<1024lab@sina.com>", + "private": false, + "scripts": { + "dev": "vue-cli-service serve --open", + "local": "vue-cli-service serve --open --mode local", + "build": "vue-cli-service build", + "lint": "vue-cli-service lint", + "test:unit": "vue-cli-service test:unit", + "test:e2e": "vue-cli-service test:e2e", + "development": "vue-cli-service build --mode development", + "sit": "vue-cli-service build --mode sit", + "prod": "vue-cli-service build --mode prod" + }, + "dependencies": { + "@antv/g2": "^3.5.8-beta.1", + "axios": "^0.18.0", + "clipboard": "^2.0.0", + "codemirror": "^5.38.0", + "countup": "^1.8.2", + "cropperjs": "^1.2.2", + "dayjs": "^1.7.7", + "decimal.js": "^10.1.1", + "echarts": "^4.0.4", + "gq-plus": "^2.1.5", + "html2canvas": "^1.0.0-alpha.12", + "jquery": "^2.2.3", + "js-cookie": "^2.2.0", + "lodash": "^4.17.15", + "mavon-editor": "^2.7.5", + "simplemde": "^1.11.2", + "sortablejs": "^1.7.0", + "tree-table-vue": "^1.1.0", + "v-org-tree": "^1.0.6", + "view-design": "^4.0.2", + "vue": "^2.5.10", + "vue-data-loading": "^0.2.4", + "vue-enum": "", + "vue-i18n": "^7.8.0", + "vue-infinite-loading": "^2.4.4", + "vue-json-viewer": "^2.2.0", + "vue-json-views": "^0.1.1", + "vue-router": "^3.1.3", + "vue-slick": "^1.1.15", + "vuedraggable": "^2.16.0", + "vuex": "^3.0.1", + "wangeditor": "^3.1.1", + "xlsx": "^0.13.3" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "^3.0.1", + "@vue/cli-plugin-eslint": "^3.0.1", + "@vue/cli-plugin-unit-mocha": "^3.0.1", + "@vue/cli-service": "^3.0.1", + "@vue/eslint-config-standard": "^3.0.0-beta.10", + "@vue/test-utils": "^1.0.0-beta.10", + "chai": "^4.1.2", + "compression-webpack-plugin": "^3.0.0", + "eslint-plugin-cypress": "^2.0.1", + "less": "^2.7.3", + "less-loader": "^4.0.5", + "lint-staged": "^6.0.0", + "uglifyjs-webpack-plugin": "^1.2.4", + "vue-template-compiler": "^2.5.13" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ], + "gitHooks": { + "pre-commit": "lint-staged" + }, + "lint-staged": { + "*.js": [ + "vue-cli-service lint", + "git add" + ], + "*.vue": [ + "vue-cli-service lint", + "git add" + ] + } +} diff --git a/front/public/favicon.ico b/front/public/favicon.ico new file mode 100644 index 00000000..5e59671b Binary files /dev/null and b/front/public/favicon.ico differ diff --git a/front/public/index.html b/front/public/index.html new file mode 100644 index 00000000..97eb0895 --- /dev/null +++ b/front/public/index.html @@ -0,0 +1,19 @@ + + + + + + + + + + + +
+ + + + diff --git a/front/src/App.vue b/front/src/App.vue new file mode 100644 index 00000000..0d189502 --- /dev/null +++ b/front/src/App.vue @@ -0,0 +1,31 @@ + + + + + + diff --git a/front/src/api/data-scope.js b/front/src/api/data-scope.js new file mode 100644 index 00000000..14799315 --- /dev/null +++ b/front/src/api/data-scope.js @@ -0,0 +1,15 @@ +import { postAxios, getAxios } from '@/lib/http'; +export const dataScopeApi = { + // 批量设置某角色数据范围 + updateDataScope: data => { + return postAxios('/dataScope/batchSet', data); + }, + // 数据权限列表 + getDataScopeList: () => { + return getAxios('/dataScope/list'); + }, + // 获取某角色所设置的数据范围 + getDataScopeByRoleId: roleId => { + return getAxios('/dataScope/listByRole/' + roleId); + } +}; diff --git a/front/src/api/department.js b/front/src/api/department.js new file mode 100644 index 00000000..2e4ebfa0 --- /dev/null +++ b/front/src/api/department.js @@ -0,0 +1,47 @@ +import { postAxios, getAxios } from '@/lib/http'; +export const departmentApi = { + // 加载所有的部门子部门 + getLoadDepartment: () => { + return getAxios('/department/list'); + }, + // 查询部门及员工列表 + getDepartmentEmployeeList: () => { + return getAxios('/department/listEmployee'); + }, + // 添加部门 + addDepartment: (data) => { + return postAxios('/department/add', data); + }, + // 编辑部门 + updateDepartment: (data) => { + return postAxios('/department/update', data); + }, + // 删除部门 + deleteDepartment: (data) => { + return postAxios('/department/delete/' + data); + }, + // 根据id获取部门信息 + getDepartmentById: (data) => { + return getAxios('/department/query/' + data); + }, + // 查询部门列表 + getDepartmentAll: () => { + return getAxios('/department/listAll'); + }, + // 根据部门名称获取员工列表 + getListEmployeeByDepartmentName: (departmentName) => { + return getAxios('/department/listEmployeeByDepartmentName?departmentName=' + departmentName); + }, + // 上下移动 + upOrDown: (departmentId, swapId) => { + return getAxios('/department/upOrDown/' + departmentId + '/' + swapId); + }, + // 升级 + upGrade: (departmentId) => { + return getAxios('/department/upgrade/' + departmentId); + }, + // 降级 + downGrade: (departmentId, preId) => { + return getAxios('/department/downgrade/' + departmentId + '/' + preId); + } +}; diff --git a/front/src/api/email.js b/front/src/api/email.js new file mode 100644 index 00000000..cb541021 --- /dev/null +++ b/front/src/api/email.js @@ -0,0 +1,27 @@ +import { postAxios, getAxios } from '@/lib/http'; +export const emailApi = { + // 新增邮件 + addEmail: (data) => { + return postAxios('/email/add', data); + }, + // 分页查询邮件 + getEmail: (data) => { + return postAxios('/email/page/query', data); + }, + // 删除邮件 + deleteEmail: (id) => { + return getAxios('/email/delete/' + id); + }, + // 查看邮件详情 + getEmailDetails: (id) => { + return getAxios('/email/detail/' + id); + }, + // 发送邮件 + sendEmail: (id) => { + return getAxios('/email/send/' + id); + }, + // 更新编辑邮件 + updateEmail: (data) => { + return postAxios('/email/update', data); + } +}; diff --git a/front/src/api/employee.js b/front/src/api/employee.js new file mode 100644 index 00000000..7f1d8001 --- /dev/null +++ b/front/src/api/employee.js @@ -0,0 +1,43 @@ +import { postAxios, getAxios } from '@/lib/http'; +export const employeeApi = { + // 员工管理查询 + getEmployeeList: (data) => { + return postAxios('/employee/query', data); + }, + // 添加员工 + addEmployee: (data) => { + return postAxios('/employee/add', data); + }, + // 更新员工信息 + updateEmployee: (data) => { + return postAxios('/employee/update', data); + }, + // 禁用启用单个员工 + updateStatus: (employeeId, status) => { + return getAxios('/employee/updateStatus/' + employeeId + '/' + status); + }, + // 批量禁用 + updateStatusBatch: (data) => { + return postAxios('/employee/batchUpdateStatus', data); + }, + // 单个员工角色授权 + updateRoles: (data) => { + return postAxios('/employee/updateRoles', data); + }, + // 修改密码 + updatePwd: (data) => { + return postAxios('/employee/updatePwd', data); + }, + // 重置密码 + resetPassword: (employeeId) => { + return getAxios('/employee/resetPasswd/' + employeeId); + }, + // 通过部门id获取当前部门的人员&没有部门的人 + getListEmployeeByDeptId: (departmentId) => { + return getAxios('/employee/listEmployeeByDeptId/' + departmentId); + }, + // 删除员工 + deleteEmployee: (employeeId) => { + return postAxios('/employee/delete/' + employeeId); + } +}; diff --git a/front/src/api/file.js b/front/src/api/file.js new file mode 100644 index 00000000..91bcc147 --- /dev/null +++ b/front/src/api/file.js @@ -0,0 +1,28 @@ +import { postAxios, getAxios } from '@/lib/http'; +import config from '@/config'; +const baseUrl = config.baseUrl.apiUrl; +export const fileApi = { + // 系统文件查询 + queryFileList: data => { + return postAxios('/api/file/query', data); + }, + // 系统文件下载通过接口 + downLoadFile: id => { + return getAxios('/api/file/downLoad?id=' + id); + }, + // 文件上传 + fileUpload: (type, data) => { + // return postAxios('/api/file/localUpload/' + type, data); + return this.fileUploadUrl; + }, + // 文件保存 + addFile: data => { + return postAxios('/api/file/save', data); + }, + // 上传路径:本地 + fileUploadLocalUrl: baseUrl + '/api/file/localUpload/', + // 上传路径:阿里OSS + fileUploadAliUrl: baseUrl + '/api/file/aliYunUpload/', + // 上传路径:七牛 + fileUploadQiNiuUrl: baseUrl + '/api/file/qiNiuUpload/' +}; diff --git a/front/src/api/heart-beat.js b/front/src/api/heart-beat.js new file mode 100644 index 00000000..c5ec2486 --- /dev/null +++ b/front/src/api/heart-beat.js @@ -0,0 +1,7 @@ +import { postAxios, getAxios } from '@/lib/http'; +export const heartBeatApi = { + // 分页查询所有岗位 + queryHeartBeatRecord: data => { + return postAxios('/heartBeat/query', data); + } +}; diff --git a/front/src/api/login.js b/front/src/api/login.js new file mode 100644 index 00000000..83338d56 --- /dev/null +++ b/front/src/api/login.js @@ -0,0 +1,19 @@ +import { postAxios, getAxios } from '@/lib/http'; +export const loginApi = { + // 登录 + login: data => { + return postAxios('/session/login', data); + }, + // 根据token获取session + getSession: () => { + return getAxios('/session/get'); + }, + // 登出 + logout: (token) => { + return getAxios(`/session/logOut?x-access-token=${token}`); + }, + // 获取验证码 + getVerificationCode: () => { + return getAxios('/session/verificationCode'); + } +}; diff --git a/front/src/api/notice.js b/front/src/api/notice.js new file mode 100644 index 00000000..fad6ad83 --- /dev/null +++ b/front/src/api/notice.js @@ -0,0 +1,43 @@ +// 任务调度API +import { + postAxios, + getAxios +} from '@/lib/http'; +export const noticeApi = { + // 查询消息列表 + getNoticeList: (data) => { + return postAxios('/notice/page/query', data); + }, + // 未读消息列表 + getNoticeUnreadList: (data) => { + return postAxios('/notice/unread/page/query', data); + }, + // 查询个人消息列表 + getPersonNoticeList: (data) => { + return postAxios('/notice/receive/page/query', data); + }, + // 添加消息 + addNotice: (data) => { + return postAxios('/notice/add', data); + }, + // 标记已读 + addNoticeRecord: (id) => { + return getAxios(`/notice/read/${id}`); + }, + // 修改消息 + updateNotice: (data) => { + return postAxios('/notice/update', data); + }, + // 删除消息 + deleteNotice: (id) => { + return getAxios(`/notice/delete/${id}`); + }, + // 获取通知详情 + getNoticeDetail: (id) => { + return getAxios(`/notice/detail/${id}`); + }, + // 发送消息 + sendNotice: (id) => { + return getAxios(`/notice/send/${id}`); + } +}; diff --git a/front/src/api/online-user.js b/front/src/api/online-user.js new file mode 100644 index 00000000..b7847b9b --- /dev/null +++ b/front/src/api/online-user.js @@ -0,0 +1,12 @@ +// 任务调度API +import { + postAxios, + getAxios +} from '@/lib/http'; +export const onlineUserApi = { + // 查询在线员工列表 + getOnlineUserList: (data) => { + return postAxios('/userOnLine/query', data); + } + +}; diff --git a/front/src/api/position.js b/front/src/api/position.js new file mode 100644 index 00000000..3756c457 --- /dev/null +++ b/front/src/api/position.js @@ -0,0 +1,19 @@ +import { postAxios, getAxios } from '@/lib/http'; +export const positionApi = { + // 分页查询所有岗位 + getPositionListPage: data => { + return postAxios('/position/getListPage', data); + }, + // 更新岗位 + updatePosition: data => { + return postAxios('/position/update', data); + }, + // 添加岗位 + addPosition: data => { + return postAxios('/position/add', data); + }, + // 根据ID删除岗位 + deletePosition: id => { + return getAxios('/position/remove/' + id); + } +}; diff --git a/front/src/api/privilege.js b/front/src/api/privilege.js new file mode 100644 index 00000000..3c7a09dd --- /dev/null +++ b/front/src/api/privilege.js @@ -0,0 +1,32 @@ +import { postAxios, getAxios } from '@/lib/http'; + +export const privilegeApi = { + // 获取所有请求路径 + getAllUrl: data => { + return getAxios('/privilege/getAllUrl'); + }, + // 获取全部菜单列表 + getMenuList: data => { + return postAxios('/privilege/menu/queryAll'); + }, + // 菜单批量保存 + addBatchSaveMenu: data => { + return postAxios('/privilege/menu/batchSaveMenu', data); + }, + // 查询菜单功能点 + queryPrivilegeFunctionList: menuKey => { + return postAxios('/privilege/function/query/' + menuKey); + }, + // 保存更新功能点 + addOrUpdate: data => { + return postAxios('/privilege/function/saveOrUpdate', data); + }, + // 更新角色权限 + getRolePower: data => { + return postAxios('/privilege/updateRolePrivilege', data); + }, + // 获取角色可选的功能权限 + getListPrivilegeByRoleId: id => { + return getAxios('/privilege/listPrivilegeByRoleId/' + id); + } +}; diff --git a/front/src/api/role.js b/front/src/api/role.js new file mode 100644 index 00000000..be5f338a --- /dev/null +++ b/front/src/api/role.js @@ -0,0 +1,58 @@ +import { postAxios, getAxios } from '@/lib/http'; +export const roleApi = { + // 添加角色 + addRole: (remark, roleName) => { + const data = { + remark: remark, + roleName: roleName + }; + return postAxios('/role/add', data); + }, + // 删除角色 + deleteRole: id => { + return getAxios('/role/delete/' + id); + }, + // 修改角色 + updateRole: (id, remark, roleName) => { + const data = { + id: id, + remark: remark, + roleName: roleName + }; + return postAxios('/role/update', data); + }, + // 获取角色数据 + getRoleDetail: id => { + return getAxios('/role/get/' + id); + }, + // 加载角色列表 + getAllRole: () => { + return getAxios('role/getAll'); + }, + // 根据角色名字获取对应成员列表 + getListEmployee: data => { + return postAxios('/role/listEmployee', data); + }, + // 根据角色id获取角色成员-员工列表 + getAllListEmployee: id => { + return getAxios('/role/listAllEmployee/' + id); + }, + // 从角色成员列表中移除员工 + deleteEmployeeRole: param => { + return getAxios('/role/removeEmployee?employeeId=' + param.employeeId + '&roleId=' + param.roleId); + }, + // 从角色成员列表中批量移除员工 + deleteEmployeeList: data => { + return postAxios('/role/removeEmployeeList', data); + }, + + // 添加角色成员方法 + addEmployeeListRole: data => { + return postAxios('/role/addEmployeeList', data); + }, + // 通过员工id获取所有角色以及员工具有的角色 + getRoles: id => { + return getAxios('/role/getRoles/' + id); + }, + +}; diff --git a/front/src/api/smart-reload.js b/front/src/api/smart-reload.js new file mode 100644 index 00000000..8ee701ed --- /dev/null +++ b/front/src/api/smart-reload.js @@ -0,0 +1,20 @@ +// smartReloadAPI +import { + postAxios, + getAxios +} from '@/lib/http'; +export const smartReloadApi = { + // 查询所有 + getSmartReloadList: () => { + return getAxios('/smartReload/all'); + }, + // 更新单条数据 + updateSmartReloadData: (data) => { + return postAxios('/smartReload/update', data); + }, + // 获取执行结果 + getSmartReloadResult: (tag) => { + return getAxios(`/smartReload/result/${tag}`); + } + +}; diff --git a/front/src/api/system-config.js b/front/src/api/system-config.js new file mode 100644 index 00000000..392dd942 --- /dev/null +++ b/front/src/api/system-config.js @@ -0,0 +1,31 @@ +// 系统参数API +import { + postAxios, + getAxios +} from '@/lib/http'; +export const systemConfigApi = { + // 查询系统参数列表 + getSystemConfigList: (data) => { + return postAxios('/systemConfig/getListPage', data); + }, + // 添加系统参数 + addSystemConfig: (data) => { + return postAxios('/systemConfig/add', data); + }, + // 更新单条系统参数 + updateSystemConfig: (data) => { + return postAxios('/systemConfig/update', data); + }, + // 通过key获取对应的信息 + getConfigListByKey: (key) => { + return getAxios(`/systemConfig/selectByKey?configKey=${key}`); + }, + // 根据分组查询所有系统配置 + getListByGroup: (group) => { + return getAxios(`/systemConfig/getListByGroup?group=${group}`); + }, + // 获取系统版本信息 + getCodeVersion: () => { + return getAxios('/codeVersion'); + } +}; diff --git a/front/src/api/task-manage.js b/front/src/api/task-manage.js new file mode 100644 index 00000000..49eec6cf --- /dev/null +++ b/front/src/api/task-manage.js @@ -0,0 +1,35 @@ +// 任务调度API +import { + postAxios, + getAxios +} from '@/lib/http'; +export const taskApi = { + // 查询任务列表 + getTaskList: (data) => { + return postAxios('/quartz/task/query', data); + }, + // 添加或更新任务 + addOrUpdateTask: (data) => { + return postAxios('/quartz/task/saveOrUpdate', data); + }, + // 查询任务日志 + getTaskLog: (data) => { + return postAxios('/quartz/task/queryLog', data); + }, + // 暂停任务 + updateTaskPause: (taskId) => { + return getAxios(`/quartz/task/pause/${taskId}`); + }, + // 运行任务 + updateTaskRun: (taskId) => { + return getAxios(`/quartz/task/run/${taskId}`); + }, + // 恢复任务 + updateTaskResume: (taskId) => { + return getAxios(`/quartz/task/resume/${taskId}`); + }, + // 删除任务 + deleteTasks: (taskId) => { + return getAxios(`/quartz/task/delete/${taskId}`); + } +}; diff --git a/front/src/api/user-log.js b/front/src/api/user-log.js new file mode 100644 index 00000000..eb3a3ad9 --- /dev/null +++ b/front/src/api/user-log.js @@ -0,0 +1,28 @@ +// 用户日志API +import { + postAxios, + getAxios +} from '@/lib/http.js'; +export const userLogApi = { + // 查询用户操作日志 + getUserOperateLogPage: (data) => { + return postAxios('/userOperateLog/page/query', data); + }, + // 用户操作日志详情 + detailUserOperateLog: (data) => { + return getAxios('/userOperateLog/detail/' + data); + }, + // 删除用户操作日志 + deleteUserOperateLog: (data) => { + return getAxios('/userOperateLog/delete/' + data); + }, + // 查询用户登录日志 + getUserLoginLogPage: (data) => { + return postAxios('/userLoginLog/page/query', data); + }, + // 删除用户登录日志 + deleteUserLoginLog: (data) => { + return getAxios('/userLoginLog/delete/' + data); + } + +}; diff --git a/front/src/api/user.js b/front/src/api/user.js new file mode 100644 index 00000000..8ac0a2a1 --- /dev/null +++ b/front/src/api/user.js @@ -0,0 +1,20 @@ +import { postAxios, getAxios } from '@/lib/http'; + +export const login = ({ userName, password }) => { + const data = { + userName, + password + }; + return postAxios('login', data); +}; + +export const getUserInfo = (token) => { + let params = { + token + }; + return getAxios('get_info', params); +}; + +export const logout = (token) => { + return postAxios('logout', {}); +}; diff --git a/front/src/assets/icons/demo.css b/front/src/assets/icons/demo.css new file mode 100644 index 00000000..a67054a0 --- /dev/null +++ b/front/src/assets/icons/demo.css @@ -0,0 +1,539 @@ +/* Logo 字体 */ +@font-face { + font-family: "iconfont logo"; + src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); + src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); +} + +.logo { + font-family: "iconfont logo"; + font-size: 160px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* tabs */ +.nav-tabs { + position: relative; +} + +.nav-tabs .nav-more { + position: absolute; + right: 0; + bottom: 0; + height: 42px; + line-height: 42px; + color: #666; +} + +#tabs { + border-bottom: 1px solid #eee; +} + +#tabs li { + cursor: pointer; + width: 100px; + height: 40px; + line-height: 40px; + text-align: center; + font-size: 16px; + border-bottom: 2px solid transparent; + position: relative; + z-index: 1; + margin-bottom: -1px; + color: #666; +} + + +#tabs .active { + border-bottom-color: #f00; + color: #222; +} + +.tab-container .content { + display: none; +} + +/* 页面布局 */ +.main { + padding: 30px 100px; + width: 960px; + margin: 0 auto; +} + +.main .logo { + color: #333; + text-align: left; + margin-bottom: 30px; + line-height: 1; + height: 110px; + margin-top: -50px; + overflow: hidden; + *zoom: 1; +} + +.main .logo a { + font-size: 160px; + color: #333; +} + +.helps { + margin-top: 40px; +} + +.helps pre { + padding: 20px; + margin: 10px 0; + border: solid 1px #e7e1cd; + background-color: #fffdef; + overflow: auto; +} + +.icon_lists { + width: 100% !important; + overflow: hidden; + *zoom: 1; +} + +.icon_lists li { + width: 100px; + margin-bottom: 10px; + margin-right: 20px; + text-align: center; + list-style: none !important; + cursor: default; +} + +.icon_lists li .code-name { + line-height: 1.2; +} + +.icon_lists .icon { + display: block; + height: 100px; + line-height: 100px; + font-size: 42px; + margin: 10px auto; + color: #333; + -webkit-transition: font-size 0.25s linear, width 0.25s linear; + -moz-transition: font-size 0.25s linear, width 0.25s linear; + transition: font-size 0.25s linear, width 0.25s linear; +} + +.icon_lists .icon:hover { + font-size: 100px; +} + +.icon_lists .svg-icon { + /* 通过设置 font-size 来改变图标大小 */ + width: 1em; + /* 图标和文字相邻时,垂直对齐 */ + vertical-align: -0.15em; + /* 通过设置 color 来改变 SVG 的颜色/fill */ + fill: currentColor; + /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 + normalize.css 中也包含这行 */ + overflow: hidden; +} + +.icon_lists li .name, +.icon_lists li .code-name { + color: #666; +} + +/* markdown 样式 */ +.markdown { + color: #666; + font-size: 14px; + line-height: 1.8; +} + +.highlight { + line-height: 1.5; +} + +.markdown img { + vertical-align: middle; + max-width: 100%; +} + +.markdown h1 { + color: #404040; + font-weight: 500; + line-height: 40px; + margin-bottom: 24px; +} + +.markdown h2, +.markdown h3, +.markdown h4, +.markdown h5, +.markdown h6 { + color: #404040; + margin: 1.6em 0 0.6em 0; + font-weight: 500; + clear: both; +} + +.markdown h1 { + font-size: 28px; +} + +.markdown h2 { + font-size: 22px; +} + +.markdown h3 { + font-size: 16px; +} + +.markdown h4 { + font-size: 14px; +} + +.markdown h5 { + font-size: 12px; +} + +.markdown h6 { + font-size: 12px; +} + +.markdown hr { + height: 1px; + border: 0; + background: #e9e9e9; + margin: 16px 0; + clear: both; +} + +.markdown p { + margin: 1em 0; +} + +.markdown>p, +.markdown>blockquote, +.markdown>.highlight, +.markdown>ol, +.markdown>ul { + width: 80%; +} + +.markdown ul>li { + list-style: circle; +} + +.markdown>ul li, +.markdown blockquote ul>li { + margin-left: 20px; + padding-left: 4px; +} + +.markdown>ul li p, +.markdown>ol li p { + margin: 0.6em 0; +} + +.markdown ol>li { + list-style: decimal; +} + +.markdown>ol li, +.markdown blockquote ol>li { + margin-left: 20px; + padding-left: 4px; +} + +.markdown code { + margin: 0 3px; + padding: 0 5px; + background: #eee; + border-radius: 3px; +} + +.markdown strong, +.markdown b { + font-weight: 600; +} + +.markdown>table { + border-collapse: collapse; + border-spacing: 0px; + empty-cells: show; + border: 1px solid #e9e9e9; + width: 95%; + margin-bottom: 24px; +} + +.markdown>table th { + white-space: nowrap; + color: #333; + font-weight: 600; +} + +.markdown>table th, +.markdown>table td { + border: 1px solid #e9e9e9; + padding: 8px 16px; + text-align: left; +} + +.markdown>table th { + background: #F7F7F7; +} + +.markdown blockquote { + font-size: 90%; + color: #999; + border-left: 4px solid #e9e9e9; + padding-left: 0.8em; + margin: 1em 0; +} + +.markdown blockquote p { + margin: 0; +} + +.markdown .anchor { + opacity: 0; + transition: opacity 0.3s ease; + margin-left: 8px; +} + +.markdown .waiting { + color: #ccc; +} + +.markdown h1:hover .anchor, +.markdown h2:hover .anchor, +.markdown h3:hover .anchor, +.markdown h4:hover .anchor, +.markdown h5:hover .anchor, +.markdown h6:hover .anchor { + opacity: 1; + display: inline-block; +} + +.markdown>br, +.markdown>p>br { + clear: both; +} + + +.hljs { + display: block; + background: white; + padding: 0.5em; + color: #333333; + overflow-x: auto; +} + +.hljs-comment, +.hljs-meta { + color: #969896; +} + +.hljs-string, +.hljs-variable, +.hljs-template-variable, +.hljs-strong, +.hljs-emphasis, +.hljs-quote { + color: #df5000; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-type { + color: #a71d5d; +} + +.hljs-literal, +.hljs-symbol, +.hljs-bullet, +.hljs-attribute { + color: #0086b3; +} + +.hljs-section, +.hljs-name { + color: #63a35c; +} + +.hljs-tag { + color: #333333; +} + +.hljs-title, +.hljs-attr, +.hljs-selector-id, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #795da3; +} + +.hljs-addition { + color: #55a532; + background-color: #eaffea; +} + +.hljs-deletion { + color: #bd2c00; + background-color: #ffecec; +} + +.hljs-link { + text-decoration: underline; +} + +/* 代码高亮 */ +/* PrismJS 1.15.0 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, +pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, +code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, +pre[class*="language-"] ::selection, +code[class*="language-"]::selection, +code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre)>code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre)>code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #9a6e3a; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function, +.token.class-name { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} + +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} diff --git a/front/src/assets/icons/demo_index.html b/front/src/assets/icons/demo_index.html new file mode 100644 index 00000000..2c777b68 --- /dev/null +++ b/front/src/assets/icons/demo_index.html @@ -0,0 +1,722 @@ + + + + + IconFont Demo + + + + + + + + + + + +
+

+ +
+
+
    + +
  • + +
    多级菜单
    +
    &#xe608;
    +
  • + +
  • + +
    导航展开
    +
    &#xe609;
    +
  • + +
  • + +
    导航折叠
    +
    &#xe60a;
    +
  • + +
  • + +
    向上箭头
    +
    &#xe60b;
    +
  • + +
  • + +
    向左箭头
    +
    &#xe60c;
    +
  • + +
  • + +
    向右箭头
    +
    &#xe60d;
    +
  • + +
  • + +
    关闭按钮
    +
    &#xe60e;
    +
  • + +
  • + +
    数据上传
    +
    &#xe60f;
    +
  • + +
  • + +
    系统监控
    +
    &#xe610;
    +
  • + +
  • + +
    邮件管理
    +
    &#xe611;
    +
  • + +
  • + +
    小屏
    +
    &#xe612;
    +
  • + +
  • + +
    人员管理
    +
    &#xe613;
    +
  • + +
  • + +
    向下拉
    +
    &#xe614;
    +
  • + +
  • + +
    excel导入导出
    +
    &#xe615;
    +
  • + +
  • + +
    向下箭头
    +
    &#xe616;
    +
  • + +
  • + +
    首页
    +
    &#xe617;
    +
  • + +
  • + +
    系统设置
    +
    &#xe618;
    +
  • + +
  • + +
    消息
    +
    &#xe619;
    +
  • + +
  • + +
    全屏
    +
    &#xe61a;
    +
  • + +
  • + +
    组件
    +
    &#xe61b;
    +
  • + +
  • + +
    news
    +
    &#xe61e;
    +
  • + +
  • + +
    定时任务
    +
    &#xe622;
    +
  • + +
  • + +
    动态加载
    +
    &#xe623;
    +
  • + +
  • + +
    接口文档
    +
    &#xe624;
    +
  • + +
+
+

Unicode 引用

+
+ +

Unicode 是字体在网页端最原始的应用方式,特点是:

+
    +
  • 兼容性最好,支持 IE6+,及所有现代浏览器。
  • +
  • 支持按字体的方式去动态调整图标大小,颜色等等。
  • +
  • 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
  • +
+
+

注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式

+
+

Unicode 使用步骤如下:

+

第一步:拷贝项目下面生成的 @font-face

+
@font-face {
+  font-family: 'iconfont';
+  src: url('iconfont.eot');
+  src: url('iconfont.eot?#iefix') format('embedded-opentype'),
+      url('iconfont.woff2') format('woff2'),
+      url('iconfont.woff') format('woff'),
+      url('iconfont.ttf') format('truetype'),
+      url('iconfont.svg#iconfont') format('svg');
+}
+
+

第二步:定义使用 iconfont 的样式

+
.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+

第三步:挑选相应图标并获取字体编码,应用于页面

+
+<span class="iconfont">&#x33;</span>
+
+
+

"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

+
+
+
+
+
    + +
  • + +
    + 多级菜单 +
    +
    .iconduojicaidan +
    +
  • + +
  • + +
    + 导航展开 +
    +
    .icondaohangzhankai +
    +
  • + +
  • + +
    + 导航折叠 +
    +
    .icondaohangzhedie +
    +
  • + +
  • + +
    + 向上箭头 +
    +
    .iconxiangshangjiantou +
    +
  • + +
  • + +
    + 向左箭头 +
    +
    .iconxiangzuojiantou +
    +
  • + +
  • + +
    + 向右箭头 +
    +
    .iconxiangyoujiantou +
    +
  • + +
  • + +
    + 关闭按钮 +
    +
    .iconguanbianniu +
    +
  • + +
  • + +
    + 数据上传 +
    +
    .iconshujushangchuan +
    +
  • + +
  • + +
    + 系统监控 +
    +
    .iconxitongjiankong +
    +
  • + +
  • + +
    + 邮件管理 +
    +
    .iconyoujianguanli +
    +
  • + +
  • + +
    + 小屏 +
    +
    .iconxiaoping +
    +
  • + +
  • + +
    + 人员管理 +
    +
    .iconrenyuanguanli +
    +
  • + +
  • + +
    + 向下拉 +
    +
    .iconxiangxiala +
    +
  • + +
  • + +
    + excel导入导出 +
    +
    .iconexceldaorudaochu +
    +
  • + +
  • + +
    + 向下箭头 +
    +
    .iconxiangxiajiantou +
    +
  • + +
  • + +
    + 首页 +
    +
    .iconshouye +
    +
  • + +
  • + +
    + 系统设置 +
    +
    .iconxitongshezhi +
    +
  • + +
  • + +
    + 消息 +
    +
    .iconxiaoxi +
    +
  • + +
  • + +
    + 全屏 +
    +
    .iconquanping +
    +
  • + +
  • + +
    + 组件 +
    +
    .iconzujian +
    +
  • + +
  • + +
    + news +
    +
    .iconnews +
    +
  • + +
  • + +
    + 定时任务 +
    +
    .icondingshirenwu +
    +
  • + +
  • + +
    + 动态加载 +
    +
    .icondongtaijiazai +
    +
  • + +
  • + +
    + 接口文档 +
    +
    .iconjiekouwendang +
    +
  • + +
+
+

font-class 引用

+
+ +

font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。

+

与 Unicode 使用方式相比,具有如下特点:

+
    +
  • 兼容性良好,支持 IE8+,及所有现代浏览器。
  • +
  • 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
  • +
  • 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
  • +
  • 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
  • +
+

使用步骤如下:

+

第一步:引入项目下面生成的 fontclass 代码:

+
<link rel="stylesheet" href="./iconfont.css">
+
+

第二步:挑选相应图标并获取类名,应用于页面:

+
<span class="iconfont iconxxx"></span>
+
+
+

" + iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

+
+
+
+
+
    + +
  • + +
    多级菜单
    +
    #iconduojicaidan
    +
  • + +
  • + +
    导航展开
    +
    #icondaohangzhankai
    +
  • + +
  • + +
    导航折叠
    +
    #icondaohangzhedie
    +
  • + +
  • + +
    向上箭头
    +
    #iconxiangshangjiantou
    +
  • + +
  • + +
    向左箭头
    +
    #iconxiangzuojiantou
    +
  • + +
  • + +
    向右箭头
    +
    #iconxiangyoujiantou
    +
  • + +
  • + +
    关闭按钮
    +
    #iconguanbianniu
    +
  • + +
  • + +
    数据上传
    +
    #iconshujushangchuan
    +
  • + +
  • + +
    系统监控
    +
    #iconxitongjiankong
    +
  • + +
  • + +
    邮件管理
    +
    #iconyoujianguanli
    +
  • + +
  • + +
    小屏
    +
    #iconxiaoping
    +
  • + +
  • + +
    人员管理
    +
    #iconrenyuanguanli
    +
  • + +
  • + +
    向下拉
    +
    #iconxiangxiala
    +
  • + +
  • + +
    excel导入导出
    +
    #iconexceldaorudaochu
    +
  • + +
  • + +
    向下箭头
    +
    #iconxiangxiajiantou
    +
  • + +
  • + +
    首页
    +
    #iconshouye
    +
  • + +
  • + +
    系统设置
    +
    #iconxitongshezhi
    +
  • + +
  • + +
    消息
    +
    #iconxiaoxi
    +
  • + +
  • + +
    全屏
    +
    #iconquanping
    +
  • + +
  • + +
    组件
    +
    #iconzujian
    +
  • + +
  • + +
    news
    +
    #iconnews
    +
  • + +
  • + +
    定时任务
    +
    #icondingshirenwu
    +
  • + +
  • + +
    动态加载
    +
    #icondongtaijiazai
    +
  • + +
  • + +
    接口文档
    +
    #iconjiekouwendang
    +
  • + +
+
+

Symbol 引用

+
+ +

这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 + 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:

+
    +
  • 支持多色图标了,不再受单色限制。
  • +
  • 通过一些技巧,支持像字体那样,通过 font-size, color 来调整样式。
  • +
  • 兼容性较差,支持 IE9+,及现代浏览器。
  • +
  • 浏览器渲染 SVG 的性能一般,还不如 png。
  • +
+

使用步骤如下:

+

第一步:引入项目下面生成的 symbol 代码:

+
<script src="./iconfont.js"></script>
+
+

第二步:加入通用 CSS 代码(引入一次就行):

+
<style>
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+</style>
+
+

第三步:挑选相应图标并获取类名,应用于页面:

+
<svg class="icon" aria-hidden="true">
+  <use xlink:href="#icon-xxx"></use>
+</svg>
+
+
+
+ +
+
+ + + diff --git a/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/demo.css b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/demo.css new file mode 100644 index 00000000..a67054a0 --- /dev/null +++ b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/demo.css @@ -0,0 +1,539 @@ +/* Logo 字体 */ +@font-face { + font-family: "iconfont logo"; + src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); + src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); +} + +.logo { + font-family: "iconfont logo"; + font-size: 160px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* tabs */ +.nav-tabs { + position: relative; +} + +.nav-tabs .nav-more { + position: absolute; + right: 0; + bottom: 0; + height: 42px; + line-height: 42px; + color: #666; +} + +#tabs { + border-bottom: 1px solid #eee; +} + +#tabs li { + cursor: pointer; + width: 100px; + height: 40px; + line-height: 40px; + text-align: center; + font-size: 16px; + border-bottom: 2px solid transparent; + position: relative; + z-index: 1; + margin-bottom: -1px; + color: #666; +} + + +#tabs .active { + border-bottom-color: #f00; + color: #222; +} + +.tab-container .content { + display: none; +} + +/* 页面布局 */ +.main { + padding: 30px 100px; + width: 960px; + margin: 0 auto; +} + +.main .logo { + color: #333; + text-align: left; + margin-bottom: 30px; + line-height: 1; + height: 110px; + margin-top: -50px; + overflow: hidden; + *zoom: 1; +} + +.main .logo a { + font-size: 160px; + color: #333; +} + +.helps { + margin-top: 40px; +} + +.helps pre { + padding: 20px; + margin: 10px 0; + border: solid 1px #e7e1cd; + background-color: #fffdef; + overflow: auto; +} + +.icon_lists { + width: 100% !important; + overflow: hidden; + *zoom: 1; +} + +.icon_lists li { + width: 100px; + margin-bottom: 10px; + margin-right: 20px; + text-align: center; + list-style: none !important; + cursor: default; +} + +.icon_lists li .code-name { + line-height: 1.2; +} + +.icon_lists .icon { + display: block; + height: 100px; + line-height: 100px; + font-size: 42px; + margin: 10px auto; + color: #333; + -webkit-transition: font-size 0.25s linear, width 0.25s linear; + -moz-transition: font-size 0.25s linear, width 0.25s linear; + transition: font-size 0.25s linear, width 0.25s linear; +} + +.icon_lists .icon:hover { + font-size: 100px; +} + +.icon_lists .svg-icon { + /* 通过设置 font-size 来改变图标大小 */ + width: 1em; + /* 图标和文字相邻时,垂直对齐 */ + vertical-align: -0.15em; + /* 通过设置 color 来改变 SVG 的颜色/fill */ + fill: currentColor; + /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 + normalize.css 中也包含这行 */ + overflow: hidden; +} + +.icon_lists li .name, +.icon_lists li .code-name { + color: #666; +} + +/* markdown 样式 */ +.markdown { + color: #666; + font-size: 14px; + line-height: 1.8; +} + +.highlight { + line-height: 1.5; +} + +.markdown img { + vertical-align: middle; + max-width: 100%; +} + +.markdown h1 { + color: #404040; + font-weight: 500; + line-height: 40px; + margin-bottom: 24px; +} + +.markdown h2, +.markdown h3, +.markdown h4, +.markdown h5, +.markdown h6 { + color: #404040; + margin: 1.6em 0 0.6em 0; + font-weight: 500; + clear: both; +} + +.markdown h1 { + font-size: 28px; +} + +.markdown h2 { + font-size: 22px; +} + +.markdown h3 { + font-size: 16px; +} + +.markdown h4 { + font-size: 14px; +} + +.markdown h5 { + font-size: 12px; +} + +.markdown h6 { + font-size: 12px; +} + +.markdown hr { + height: 1px; + border: 0; + background: #e9e9e9; + margin: 16px 0; + clear: both; +} + +.markdown p { + margin: 1em 0; +} + +.markdown>p, +.markdown>blockquote, +.markdown>.highlight, +.markdown>ol, +.markdown>ul { + width: 80%; +} + +.markdown ul>li { + list-style: circle; +} + +.markdown>ul li, +.markdown blockquote ul>li { + margin-left: 20px; + padding-left: 4px; +} + +.markdown>ul li p, +.markdown>ol li p { + margin: 0.6em 0; +} + +.markdown ol>li { + list-style: decimal; +} + +.markdown>ol li, +.markdown blockquote ol>li { + margin-left: 20px; + padding-left: 4px; +} + +.markdown code { + margin: 0 3px; + padding: 0 5px; + background: #eee; + border-radius: 3px; +} + +.markdown strong, +.markdown b { + font-weight: 600; +} + +.markdown>table { + border-collapse: collapse; + border-spacing: 0px; + empty-cells: show; + border: 1px solid #e9e9e9; + width: 95%; + margin-bottom: 24px; +} + +.markdown>table th { + white-space: nowrap; + color: #333; + font-weight: 600; +} + +.markdown>table th, +.markdown>table td { + border: 1px solid #e9e9e9; + padding: 8px 16px; + text-align: left; +} + +.markdown>table th { + background: #F7F7F7; +} + +.markdown blockquote { + font-size: 90%; + color: #999; + border-left: 4px solid #e9e9e9; + padding-left: 0.8em; + margin: 1em 0; +} + +.markdown blockquote p { + margin: 0; +} + +.markdown .anchor { + opacity: 0; + transition: opacity 0.3s ease; + margin-left: 8px; +} + +.markdown .waiting { + color: #ccc; +} + +.markdown h1:hover .anchor, +.markdown h2:hover .anchor, +.markdown h3:hover .anchor, +.markdown h4:hover .anchor, +.markdown h5:hover .anchor, +.markdown h6:hover .anchor { + opacity: 1; + display: inline-block; +} + +.markdown>br, +.markdown>p>br { + clear: both; +} + + +.hljs { + display: block; + background: white; + padding: 0.5em; + color: #333333; + overflow-x: auto; +} + +.hljs-comment, +.hljs-meta { + color: #969896; +} + +.hljs-string, +.hljs-variable, +.hljs-template-variable, +.hljs-strong, +.hljs-emphasis, +.hljs-quote { + color: #df5000; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-type { + color: #a71d5d; +} + +.hljs-literal, +.hljs-symbol, +.hljs-bullet, +.hljs-attribute { + color: #0086b3; +} + +.hljs-section, +.hljs-name { + color: #63a35c; +} + +.hljs-tag { + color: #333333; +} + +.hljs-title, +.hljs-attr, +.hljs-selector-id, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #795da3; +} + +.hljs-addition { + color: #55a532; + background-color: #eaffea; +} + +.hljs-deletion { + color: #bd2c00; + background-color: #ffecec; +} + +.hljs-link { + text-decoration: underline; +} + +/* 代码高亮 */ +/* PrismJS 1.15.0 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, +pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, +code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, +pre[class*="language-"] ::selection, +code[class*="language-"]::selection, +code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre)>code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre)>code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #9a6e3a; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function, +.token.class-name { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} + +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} diff --git a/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/demo_index.html b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/demo_index.html new file mode 100644 index 00000000..2c777b68 --- /dev/null +++ b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/demo_index.html @@ -0,0 +1,722 @@ + + + + + IconFont Demo + + + + + + + + + + + +
+

+ +
+
+
    + +
  • + +
    多级菜单
    +
    &#xe608;
    +
  • + +
  • + +
    导航展开
    +
    &#xe609;
    +
  • + +
  • + +
    导航折叠
    +
    &#xe60a;
    +
  • + +
  • + +
    向上箭头
    +
    &#xe60b;
    +
  • + +
  • + +
    向左箭头
    +
    &#xe60c;
    +
  • + +
  • + +
    向右箭头
    +
    &#xe60d;
    +
  • + +
  • + +
    关闭按钮
    +
    &#xe60e;
    +
  • + +
  • + +
    数据上传
    +
    &#xe60f;
    +
  • + +
  • + +
    系统监控
    +
    &#xe610;
    +
  • + +
  • + +
    邮件管理
    +
    &#xe611;
    +
  • + +
  • + +
    小屏
    +
    &#xe612;
    +
  • + +
  • + +
    人员管理
    +
    &#xe613;
    +
  • + +
  • + +
    向下拉
    +
    &#xe614;
    +
  • + +
  • + +
    excel导入导出
    +
    &#xe615;
    +
  • + +
  • + +
    向下箭头
    +
    &#xe616;
    +
  • + +
  • + +
    首页
    +
    &#xe617;
    +
  • + +
  • + +
    系统设置
    +
    &#xe618;
    +
  • + +
  • + +
    消息
    +
    &#xe619;
    +
  • + +
  • + +
    全屏
    +
    &#xe61a;
    +
  • + +
  • + +
    组件
    +
    &#xe61b;
    +
  • + +
  • + +
    news
    +
    &#xe61e;
    +
  • + +
  • + +
    定时任务
    +
    &#xe622;
    +
  • + +
  • + +
    动态加载
    +
    &#xe623;
    +
  • + +
  • + +
    接口文档
    +
    &#xe624;
    +
  • + +
+
+

Unicode 引用

+
+ +

Unicode 是字体在网页端最原始的应用方式,特点是:

+
    +
  • 兼容性最好,支持 IE6+,及所有现代浏览器。
  • +
  • 支持按字体的方式去动态调整图标大小,颜色等等。
  • +
  • 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
  • +
+
+

注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式

+
+

Unicode 使用步骤如下:

+

第一步:拷贝项目下面生成的 @font-face

+
@font-face {
+  font-family: 'iconfont';
+  src: url('iconfont.eot');
+  src: url('iconfont.eot?#iefix') format('embedded-opentype'),
+      url('iconfont.woff2') format('woff2'),
+      url('iconfont.woff') format('woff'),
+      url('iconfont.ttf') format('truetype'),
+      url('iconfont.svg#iconfont') format('svg');
+}
+
+

第二步:定义使用 iconfont 的样式

+
.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+

第三步:挑选相应图标并获取字体编码,应用于页面

+
+<span class="iconfont">&#x33;</span>
+
+
+

"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

+
+
+
+
+
    + +
  • + +
    + 多级菜单 +
    +
    .iconduojicaidan +
    +
  • + +
  • + +
    + 导航展开 +
    +
    .icondaohangzhankai +
    +
  • + +
  • + +
    + 导航折叠 +
    +
    .icondaohangzhedie +
    +
  • + +
  • + +
    + 向上箭头 +
    +
    .iconxiangshangjiantou +
    +
  • + +
  • + +
    + 向左箭头 +
    +
    .iconxiangzuojiantou +
    +
  • + +
  • + +
    + 向右箭头 +
    +
    .iconxiangyoujiantou +
    +
  • + +
  • + +
    + 关闭按钮 +
    +
    .iconguanbianniu +
    +
  • + +
  • + +
    + 数据上传 +
    +
    .iconshujushangchuan +
    +
  • + +
  • + +
    + 系统监控 +
    +
    .iconxitongjiankong +
    +
  • + +
  • + +
    + 邮件管理 +
    +
    .iconyoujianguanli +
    +
  • + +
  • + +
    + 小屏 +
    +
    .iconxiaoping +
    +
  • + +
  • + +
    + 人员管理 +
    +
    .iconrenyuanguanli +
    +
  • + +
  • + +
    + 向下拉 +
    +
    .iconxiangxiala +
    +
  • + +
  • + +
    + excel导入导出 +
    +
    .iconexceldaorudaochu +
    +
  • + +
  • + +
    + 向下箭头 +
    +
    .iconxiangxiajiantou +
    +
  • + +
  • + +
    + 首页 +
    +
    .iconshouye +
    +
  • + +
  • + +
    + 系统设置 +
    +
    .iconxitongshezhi +
    +
  • + +
  • + +
    + 消息 +
    +
    .iconxiaoxi +
    +
  • + +
  • + +
    + 全屏 +
    +
    .iconquanping +
    +
  • + +
  • + +
    + 组件 +
    +
    .iconzujian +
    +
  • + +
  • + +
    + news +
    +
    .iconnews +
    +
  • + +
  • + +
    + 定时任务 +
    +
    .icondingshirenwu +
    +
  • + +
  • + +
    + 动态加载 +
    +
    .icondongtaijiazai +
    +
  • + +
  • + +
    + 接口文档 +
    +
    .iconjiekouwendang +
    +
  • + +
+
+

font-class 引用

+
+ +

font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。

+

与 Unicode 使用方式相比,具有如下特点:

+
    +
  • 兼容性良好,支持 IE8+,及所有现代浏览器。
  • +
  • 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
  • +
  • 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
  • +
  • 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
  • +
+

使用步骤如下:

+

第一步:引入项目下面生成的 fontclass 代码:

+
<link rel="stylesheet" href="./iconfont.css">
+
+

第二步:挑选相应图标并获取类名,应用于页面:

+
<span class="iconfont iconxxx"></span>
+
+
+

" + iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

+
+
+
+
+
    + +
  • + +
    多级菜单
    +
    #iconduojicaidan
    +
  • + +
  • + +
    导航展开
    +
    #icondaohangzhankai
    +
  • + +
  • + +
    导航折叠
    +
    #icondaohangzhedie
    +
  • + +
  • + +
    向上箭头
    +
    #iconxiangshangjiantou
    +
  • + +
  • + +
    向左箭头
    +
    #iconxiangzuojiantou
    +
  • + +
  • + +
    向右箭头
    +
    #iconxiangyoujiantou
    +
  • + +
  • + +
    关闭按钮
    +
    #iconguanbianniu
    +
  • + +
  • + +
    数据上传
    +
    #iconshujushangchuan
    +
  • + +
  • + +
    系统监控
    +
    #iconxitongjiankong
    +
  • + +
  • + +
    邮件管理
    +
    #iconyoujianguanli
    +
  • + +
  • + +
    小屏
    +
    #iconxiaoping
    +
  • + +
  • + +
    人员管理
    +
    #iconrenyuanguanli
    +
  • + +
  • + +
    向下拉
    +
    #iconxiangxiala
    +
  • + +
  • + +
    excel导入导出
    +
    #iconexceldaorudaochu
    +
  • + +
  • + +
    向下箭头
    +
    #iconxiangxiajiantou
    +
  • + +
  • + +
    首页
    +
    #iconshouye
    +
  • + +
  • + +
    系统设置
    +
    #iconxitongshezhi
    +
  • + +
  • + +
    消息
    +
    #iconxiaoxi
    +
  • + +
  • + +
    全屏
    +
    #iconquanping
    +
  • + +
  • + +
    组件
    +
    #iconzujian
    +
  • + +
  • + +
    news
    +
    #iconnews
    +
  • + +
  • + +
    定时任务
    +
    #icondingshirenwu
    +
  • + +
  • + +
    动态加载
    +
    #icondongtaijiazai
    +
  • + +
  • + +
    接口文档
    +
    #iconjiekouwendang
    +
  • + +
+
+

Symbol 引用

+
+ +

这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 + 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:

+
    +
  • 支持多色图标了,不再受单色限制。
  • +
  • 通过一些技巧,支持像字体那样,通过 font-size, color 来调整样式。
  • +
  • 兼容性较差,支持 IE9+,及现代浏览器。
  • +
  • 浏览器渲染 SVG 的性能一般,还不如 png。
  • +
+

使用步骤如下:

+

第一步:引入项目下面生成的 symbol 代码:

+
<script src="./iconfont.js"></script>
+
+

第二步:加入通用 CSS 代码(引入一次就行):

+
<style>
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+</style>
+
+

第三步:挑选相应图标并获取类名,应用于页面:

+
<svg class="icon" aria-hidden="true">
+  <use xlink:href="#icon-xxx"></use>
+</svg>
+
+
+
+ +
+
+ + + diff --git a/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.css b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.css new file mode 100644 index 00000000..8c269496 --- /dev/null +++ b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.css @@ -0,0 +1,113 @@ +@font-face {font-family: "iconfont"; + src: url('iconfont.eot?t=1567826173562'); /* IE9 */ + src: url('iconfont.eot?t=1567826173562#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAABHoAAsAAAAAIcQAABGZAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCFQgqxHKV3ATYCJANkCzQABCAFhG0HgwcbIhsz0lHSipfsvzrgDeWN7mGGx2JaRxQWOkpQJ+9hJazgItaLPcwpUZjctwwMwn32fdA/7fc65wH9uwFmC0AS0YjYAkpdpbdkRALgB9rmvwvqjjjibCS0WRH24uxVgPoHzvgTV+3WLCJgxSpc909x1aCL/oD1o2DwveqTnXtKFj/F4Ai0nQP9lPymv8FgwfLOe5AHNUCwbFo3p3Col70hz/7y03M0QLrSh6Tr/9ZSe1sGj1tCYWLlzOxecn92JrnZ4NyWNsQbniuCCqhGFUji87ch3iK4pArYkTQVslpWOF+DsZmHi36zcKJg4ph+9P0hoKCNEbSytnNCRoRBhQavTw9XZKl0ojsLRZaaUIaM0HeIyYIPqAv45v9+/WdKGQTEIUafB/ertyz4zPeEb0Fy6obAFCeB3XAQAiNABPpJdT6HIYz4VkHzRlwCmekfgG/20T72/V1orM2rw/BUZMaYTsh/4AWERMQkpGTkFJQwHGWUU0ElVVRTQy111NMASjDqG4Am9PIG8Jm9EQKfG7PPCgjCKythIyLwthExeIf1nfgybEQKvpwillWAAlYJClgVKGDVoIDVgAJWCwpYHShg9aCANYAC1ggKWBMoYM2ggLWBAtYFClg3KGA9AJAHNLpDTAH3kJVB/oTBf/kyITanSotITkusdIkiWOGSlhE5UdKiyMvMVRiWOZFaJBww52YbbVkVoVl+qqmrqdWgzVwly4VN7ROqtq/f7Oq0K1WNFlWNHqfNg15LKxwXp8rcHpF1nfIWS6zbKO8goRvTiAXJmnw4D5QM/ncuQPUsovGQhq4QlJR522I3JIFtWQOTGk7fUfScFMgVZKYv+Ry+8MN0Xps//VQMdaS/LPV1WxDN4h78uxC1112QBPlwUIMfZy76HNL4EZ3X5U8/GUMtkU7BEwFE1BP7mSPWXt4Y3jMPKFffJ+7EzcZ+yQ5kD6h7YaO2t0LJPtEU3C3IoWccR94NmjJZRGP30L9VS9R9aYMZJYdx64+ae5RyBQDCmTSyERkFgoeaWSBpJTwpXF9xDlQqTqlkWRNVLtuuotJgH6/dgvT2iGdLpvTpqPa655YflHv1mnTnhzwPbDcevyc4JwJXq9lK5ULZLms2sU6COXxkhWapyDRFGRX8tiIpjc0W5wg5uCe2k4yJ6gYwcbaIu1J2RimMs0PN0Dd5vjZ2u0gOIS89fiPjE/xd/7rUt6atnN/wrjog0V4Zl7B33WfT9xcfPX7/B6mTs8IPpDtnjp27rwifh+kzNU52h6TxBGMb4gcPGAspvTZiwy6mWPXRsHVZ5XeF4ND/uvDKwI3BwzSkMcZdV4eulYkWwNE5KlsfXR+Cl4e8P3z9vMkI/j2mUlLuomu+T1N4B9e5PqSeckUEp+mH/arGfFaNqVQ2ygEf8PjfSKm0a5rGge1Fikhxrft5VF6fKh8O7ryvocGmMptfphrGA3kjpj9CtcCCMUMX4SD/0QTEOO9kxmApPW0pz+m6ALYRxBjXOLl5XYi+yjBFkp3n9WVKYVep2BRdhSXKXKGKPI0RNVHKNBWUBUtIQ+IC0mSggmG5OhahDkRO44gZSEasb6JoqjHd3+X5J4MEvvcruvB0sPz7ztWhewM2fH90fcqOGiImW6LMhJTb/vk+NH4uyjp43AJsnenBudxrSwipwnjJDSj0BqXgb1Sies4BEHWb9yY1WHsZ0jglLZueLKfaUzWB96yEhc3xnSzXfJ247Igrjh4ddQYAXbuBEKSVAtT9XQmQF8FEIRqMVEUxoHsEtFGuCq5p+pGCIVWq23UVwBgVRQL7samax/fjZ96U+7WW8t5W+ndUBy3eu8u6+odVIq9pubabX+KwEHoT6Tmoks7PJ1pT8otpj61j9ehjfPf7RG50jIyPq2XBNIvtt77GP/vIdAuw2OcxDID9b6c70oUh31YoLPQFq37SmGoAu3/l/rIMWniImFZaGbSm8o1XgoGdj5ONPUlT6mE8WVd4tSmZaxv2xRa6+yijHrmhnn+AXfPeN03Mzbcljof4zzItfWhzWmVBvOhac6bYPvyrIy80P2WPexJ9KgoQpdjOgITSV2IaDfYqoXCJZqht03Xw30hFrnAV1NNN/E6QcY6oNPTbArNB2Pj2qVOwiglDfQMxSdVF9ZGdDYjqJeF1TWuYUErG8+S5fQIi8AX3CbBpSZ7Pd2EM+qRheFr39yh17HVN3zRsUP9maTPtGe8bsaf0GXb1QcL3ixBi1yVPNJVH8WzCe0GHJAWEriMeADCEAMrjt4c6XUOwMsEEJYS0c682VeNc83gFGaJ0LPRlwjUVTNDIQKZSUC5sr8yYBdds/pk6EKZLirxVK/lB+GZ5eVU/jecpUuMwjd0QgPQ8beA29jEZB+8rswpmX+Vksbv2Eel1F4vdvHxgV09jUBXZfUjntnrvae/fWp69Wf3Ak149Gh+f5xzgK0QY9gxjRuOVQWrG72WVhxVafVR9770hKd0voS3P42mWtB3C8QMwZe5cqr/bxpIpDXcmMyzQwDnIrl+B7RG+MQ2OzN00LD57bcCTd72Mx85ywJzxFffxjJ2t2n3RQpFUsovrPU3/Vue8OmC8s7gErsk93oE8fjXu6bZodGYoE+/8FCKfSNw6kVMoi3nh2GWc2HOPVUSzvMvWuXtKu5JMiZG4C8l2AQ0EVhAgVYfgR+lM+ojmCJPJHKE7diaQHEfpo3AiXtAUW3Pk7oNBn//xK3RQv4IL8MtMkLmMp+qaQy6gZhZRZfxlQXNSloCXJUEq2uju3hk1/gTfjBneQhqyJMEDD9ShAYGZ6uaQC/QUMvVFc0KWsF5gPp7+JtJwaPg+J5fp1kA7BgQYxpvoZZjAAAfdMH/+61jQ78zJKVAGHKZ93RhfolPspw8P8NFD9UlaNmUYT2ID0y3kzs0Y+NSXEDptDayTCkKrizE5Nq0DeNPI/Rb6jfeMcCXn3WL5yJoqqxcydlbF1Wz7qgkJ6ourrMpiSeWaWVWIiVwUvgfdxZZJ0BcpnT5zMML3h/pOKA96lqujZLSmNGHQocJiY5++BRG7YrOrBiVM//GZI0q93HNQecIX6uebkWkzkVLo23Rs8H8fKJDnRg0bFpUnz98qL4jKHT48Wa9AvjVfnkeZsS0qkhdBnhegj+EC3tqauICdb2u9h5/D29qcd+58a9uuU+ja14lMUcyMxK+8WHVJ4t+SL4maub+mfeGpBBCO3RDF9bXJlBXx064k/sNTMa+S/6H/I/KqS/5O/Cr9mhg/NpYvimgSZDCVhjJpNiEBulMv+zn7FODncTBnOG6y3gUvAmvO7xeFC8rkKs5SV2OXRtdSSnx6o03R9Y/1r36a7lF2UXqmf1vX7/yB8/vB8tyf5EkOOIwJyG6JugrVkqsnu8bax8wR18DVqLcD7Q7H4SeveJTM73DYY7ue3Dl74KPIqxKr5OrNDrElrj/Jl1Qza+zkUnq11qzId+9IIMkbApG3tcXItBmIRZ9cMu7zh5Ga2eeRSfQf9WPoMI5ASJGccFkdjc50HpsuUN3Mpgb8XJ5cgqKWGTNKZuYhFgvkmchtlofE3wteLsHDBHG3DQqGn5hyiwVJ+ivGTuWpLryBFSrAHxkQgkOx27+zvn4ohaRBQw82KssLCyhO27Yh0vPtDE8p/fbN1Vk4zZG5pDjh13RsJxZp1Bo/gTGHcRbNybJuHqMtx1knsOLEmjlFhmcEp5N2zKbqLBrnhFyiMVswuUN7SVZPPDKwBg05QrNwTq+aRUtXsDoht9RyTFOhvybFW7qpjgJ5paE+opwc0T1vw1xeOW9Yr/wNcyHt4RQb92p/s7vfb8Wl9Rwb9Cs6zPeSp/ke4jDhd+UeUmw5I+uaOzx3gZYws8RP+MgDfA9ZQWrAtfuII/9f08HpI+xkgGh3AjyOBhVc4CDpSm1I2sn3kRzSS2qOj5yyxSJgJyvJaL4VBJfwOu8km+/jQ8PWdf4H//d/9Nkw2Lgc69r/dYgKPc70WxSf0mN8ZtNdZNHATselKparf1d82UDTldbyqwOMI1gxmaZO2SruqF2LLoXfvpHZ7BBfmr9rBVfFMKbMGNaIwcZaQP9AsnMQuzqrABlSjhSayG1WgMSfVNZjTLk4tNqQjtVqbqvfo7ZLEXpGF+Yah75TPW/vyjAYYQMTocSEV8PNjTAqIqZHJTahJtRqyEBrNXfU77BxlyNwbHGMSBtex/5+1E0VhW5RYvePJlmiVTMjYPodqbgC4ppO3FBJBWeyI2YNPLt1Xhw81q4b1CsPlxRWZOWdlLynWJVb9upmZUfeuSFBNxxnnXn8fh+nBe83ddrnmBsveqxba9S2w6SpkqzcU+JJ9vGJOAP93kFd3itgs4zy8VsQ6wguufAiVaU0SeaJTSoj/MxfGDYSsY7ZUiJnJTggl1Eq7WBUM1RO1NY6vWQt6QvxkfhyrNPqUPE627/n2Dkj8BDDuVvKR5Rv4Q7/7n2t003UEh6WCJ+47qj5FY1SGs7C8SrfL7WkhwnnMf7RHj4M/F9eE8VNvtcr/INZ+OuLZTnrB8Q4GwP1okCjoFU2aeiTswW7WfUhomfiThVaoXxx2mI59xT7rHPMj8JfTgtHfSRGmlPDpDQZtfi2Mj8XFTNIt5WpP98HgYeasF4ZJ1Hm52BIXm4nwJFH+y8IQDhOQAl8nFnPqIEftENb19goPWWzrUMGaocNoIa+EIkE1I2G0oR0bIAEzc0FHeO/DuUj1prkfO6UcWusXDaGxu/1qLVQfj13SqGs+wlqq96cMdOcLrMTfztlxVuMYc87/hyG3Fx74v6p9BuK2oznYSsLh6eXY2x4gFqWLLSgQ9A1K7DSn9iRiOY7qJ52QiSYIoDwJv4UflANN4K+bAoHvTvRrv0rmi7DdLjchG6OvCg/xJ3OPVS+QtubtNNNmJLH87gRzxahr2n3NT0Vl6J7GaN7Xu4ZbbIilwN0jPa6VNCPBibmg9mC5CH5ZnO+hzaAoDOzpcclnosoJVxSSG0WL+yPl0VckV4BQxO1A+pggR32Pdfecg5zFoDvQDecFccIL8kjvYTWGu/nTJBrK0xKh8gkdDSZmhxCk8gx6cJiyTORblLfmnA7rZNILznbol17Q0QIISQo6PpH9Gy0i3aItjQuTVs6zs7dwXVwe2pNv6R/EdmFobcaHb+ziKDO/9b14MOVSdJIMDNn+8yZU6RuqdWrY5V6pfMrt0ayzC31G2chjBnzK5MUeWBOMEgMX+wseg0geNdJTEu0e1xH08aX1eFhKZiMLH9pPxZf1uY0hrNOPbXrHPoqzQ0iJmsXXkCnXO9xEIsTCXebTtbx8/7U4QhkCLyetvyRUVj75Y+tx9ot99uBiSs+mohF/0ncFdApfWrKRJ1/55L/JZ/3wp79v58brAvDNv+uNZnNP4BNxtPwa7KREY6f/17b6HBlOLRAXoICAGEWAgTB2CMBz7A4zWz+sczpGGEXB+QA7MpjoeFT2+ksIMGgs4EL3XQCNFA4PAlSmAAYIDgPAJJhoaYjQMFxHQUhXNcxoKBew6e6dRaEgFdnA4VgOgFFiHSMpA1e9LR5DaAZUvXsFRqqrJXFm6DhFzgpdEgm+8v+IEQsVLfkmq38hAqCiH5i4+7MVtlApfrQHgyKglQdKAPDiWeuH5eLpfWbGCpHG14DaHbXTRXPfkc0VNn2eZP79V/gpNDhzlEvO/5BiHjrihsJVwbt06qYjjoUNTbuDhNplX1goFLxQSQUZhkpanpnGRhO8A1K6gcXcjbLaiXd83JdXAYUGOPfqEChIsVKlCpTrkIlmZzKVK4KVapK1apRrepUrwY1qontrVCGRmOqq4PtIa8rNzhFucZ90gspwrnDA41XyMI8Jjme6dD08MvSnmTB1gk8430rlGP0kklDYXxR+aFDJiGQ+3zfgDDLAldcJNVYtDpA1Yu1EY0dpdAn6AwUQxNBgIWlHunhbvdbRE/Sw66NmtHD4HHBE9li9S+ICE5fDN3FzSpo4y7FKoA3t5V9yi5Z4x0YZKBmCDlJC5V8Ym40AgAA') format('woff2'), + url('iconfont.woff?t=1567826173562') format('woff'), + url('iconfont.ttf?t=1567826173562') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ + url('iconfont.svg?t=1567826173562#iconfont') format('svg'); /* iOS 4.1- */ +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.iconduojicaidan:before { + content: "\e608"; +} + +.icondaohangzhankai:before { + content: "\e609"; +} + +.icondaohangzhedie:before { + content: "\e60a"; +} + +.iconxiangshangjiantou:before { + content: "\e60b"; +} + +.iconxiangzuojiantou:before { + content: "\e60c"; +} + +.iconxiangyoujiantou:before { + content: "\e60d"; +} + +.iconguanbianniu:before { + content: "\e60e"; +} + +.iconshujushangchuan:before { + content: "\e60f"; +} + +.iconxitongjiankong:before { + content: "\e610"; +} + +.iconyoujianguanli:before { + content: "\e611"; +} + +.iconxiaoping:before { + content: "\e612"; +} + +.iconrenyuanguanli:before { + content: "\e613"; +} + +.iconxiangxiala:before { + content: "\e614"; +} + +.iconexceldaorudaochu:before { + content: "\e615"; +} + +.iconxiangxiajiantou:before { + content: "\e616"; +} + +.iconshouye:before { + content: "\e617"; +} + +.iconxitongshezhi:before { + content: "\e618"; +} + +.iconxiaoxi:before { + content: "\e619"; +} + +.iconquanping:before { + content: "\e61a"; +} + +.iconzujian:before { + content: "\e61b"; +} + +.iconnews:before { + content: "\e61e"; +} + +.icondingshirenwu:before { + content: "\e622"; +} + +.icondongtaijiazai:before { + content: "\e623"; +} + +.iconjiekouwendang:before { + content: "\e624"; +} + diff --git a/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.eot b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.eot new file mode 100644 index 00000000..cf0b3fbd Binary files /dev/null and b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.eot differ diff --git a/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.js b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.js new file mode 100644 index 00000000..6a3315a1 --- /dev/null +++ b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.js @@ -0,0 +1 @@ +!function(e){var c,t='',h=(c=document.getElementsByTagName("script"))[c.length-1].getAttribute("data-injectcss");if(h&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}!function(c){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(c,0);else{var h=function(){document.removeEventListener("DOMContentLoaded",h,!1),c()};document.addEventListener("DOMContentLoaded",h,!1)}else document.attachEvent&&(a=c,o=e.document,l=!1,(i=function(){try{o.documentElement.doScroll("left")}catch(c){return void setTimeout(i,50)}t()})(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,t())});function t(){l||(l=!0,a())}var a,o,l,i}(function(){var c,h;(c=document.createElement("div")).innerHTML=t,t=null,(h=c.getElementsByTagName("svg")[0])&&(h.setAttribute("aria-hidden","true"),h.style.position="absolute",h.style.width=0,h.style.height=0,h.style.overflow="hidden",function(c,h){h.firstChild?function(c,h){h.parentNode.insertBefore(c,h)}(c,h.firstChild):h.appendChild(c)}(h,document.body))})}(window); \ No newline at end of file diff --git a/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.svg b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.svg new file mode 100644 index 00000000..a349f5e2 --- /dev/null +++ b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.svg @@ -0,0 +1,98 @@ + + + + + +Created by iconfont + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.ttf b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.ttf new file mode 100644 index 00000000..69587d9e Binary files /dev/null and b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.ttf differ diff --git a/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.woff b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.woff new file mode 100644 index 00000000..fc0da088 Binary files /dev/null and b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.woff differ diff --git a/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.woff2 b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.woff2 new file mode 100644 index 00000000..89c0d09e Binary files /dev/null and b/front/src/assets/icons/download (4)/font_1299963_2zqwx2axi0j/iconfont.woff2 differ diff --git a/front/src/assets/icons/iconfont.css b/front/src/assets/icons/iconfont.css new file mode 100644 index 00000000..8c269496 --- /dev/null +++ b/front/src/assets/icons/iconfont.css @@ -0,0 +1,113 @@ +@font-face {font-family: "iconfont"; + src: url('iconfont.eot?t=1567826173562'); /* IE9 */ + src: url('iconfont.eot?t=1567826173562#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAABHoAAsAAAAAIcQAABGZAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCFQgqxHKV3ATYCJANkCzQABCAFhG0HgwcbIhsz0lHSipfsvzrgDeWN7mGGx2JaRxQWOkpQJ+9hJazgItaLPcwpUZjctwwMwn32fdA/7fc65wH9uwFmC0AS0YjYAkpdpbdkRALgB9rmvwvqjjjibCS0WRH24uxVgPoHzvgTV+3WLCJgxSpc909x1aCL/oD1o2DwveqTnXtKFj/F4Ai0nQP9lPymv8FgwfLOe5AHNUCwbFo3p3Col70hz/7y03M0QLrSh6Tr/9ZSe1sGj1tCYWLlzOxecn92JrnZ4NyWNsQbniuCCqhGFUji87ch3iK4pArYkTQVslpWOF+DsZmHi36zcKJg4ph+9P0hoKCNEbSytnNCRoRBhQavTw9XZKl0ojsLRZaaUIaM0HeIyYIPqAv45v9+/WdKGQTEIUafB/ertyz4zPeEb0Fy6obAFCeB3XAQAiNABPpJdT6HIYz4VkHzRlwCmekfgG/20T72/V1orM2rw/BUZMaYTsh/4AWERMQkpGTkFJQwHGWUU0ElVVRTQy111NMASjDqG4Am9PIG8Jm9EQKfG7PPCgjCKythIyLwthExeIf1nfgybEQKvpwillWAAlYJClgVKGDVoIDVgAJWCwpYHShg9aCANYAC1ggKWBMoYM2ggLWBAtYFClg3KGA9AJAHNLpDTAH3kJVB/oTBf/kyITanSotITkusdIkiWOGSlhE5UdKiyMvMVRiWOZFaJBww52YbbVkVoVl+qqmrqdWgzVwly4VN7ROqtq/f7Oq0K1WNFlWNHqfNg15LKxwXp8rcHpF1nfIWS6zbKO8goRvTiAXJmnw4D5QM/ncuQPUsovGQhq4QlJR522I3JIFtWQOTGk7fUfScFMgVZKYv+Ry+8MN0Xps//VQMdaS/LPV1WxDN4h78uxC1112QBPlwUIMfZy76HNL4EZ3X5U8/GUMtkU7BEwFE1BP7mSPWXt4Y3jMPKFffJ+7EzcZ+yQ5kD6h7YaO2t0LJPtEU3C3IoWccR94NmjJZRGP30L9VS9R9aYMZJYdx64+ae5RyBQDCmTSyERkFgoeaWSBpJTwpXF9xDlQqTqlkWRNVLtuuotJgH6/dgvT2iGdLpvTpqPa655YflHv1mnTnhzwPbDcevyc4JwJXq9lK5ULZLms2sU6COXxkhWapyDRFGRX8tiIpjc0W5wg5uCe2k4yJ6gYwcbaIu1J2RimMs0PN0Dd5vjZ2u0gOIS89fiPjE/xd/7rUt6atnN/wrjog0V4Zl7B33WfT9xcfPX7/B6mTs8IPpDtnjp27rwifh+kzNU52h6TxBGMb4gcPGAspvTZiwy6mWPXRsHVZ5XeF4ND/uvDKwI3BwzSkMcZdV4eulYkWwNE5KlsfXR+Cl4e8P3z9vMkI/j2mUlLuomu+T1N4B9e5PqSeckUEp+mH/arGfFaNqVQ2ygEf8PjfSKm0a5rGge1Fikhxrft5VF6fKh8O7ryvocGmMptfphrGA3kjpj9CtcCCMUMX4SD/0QTEOO9kxmApPW0pz+m6ALYRxBjXOLl5XYi+yjBFkp3n9WVKYVep2BRdhSXKXKGKPI0RNVHKNBWUBUtIQ+IC0mSggmG5OhahDkRO44gZSEasb6JoqjHd3+X5J4MEvvcruvB0sPz7ztWhewM2fH90fcqOGiImW6LMhJTb/vk+NH4uyjp43AJsnenBudxrSwipwnjJDSj0BqXgb1Sies4BEHWb9yY1WHsZ0jglLZueLKfaUzWB96yEhc3xnSzXfJ247Igrjh4ddQYAXbuBEKSVAtT9XQmQF8FEIRqMVEUxoHsEtFGuCq5p+pGCIVWq23UVwBgVRQL7samax/fjZ96U+7WW8t5W+ndUBy3eu8u6+odVIq9pubabX+KwEHoT6Tmoks7PJ1pT8otpj61j9ehjfPf7RG50jIyPq2XBNIvtt77GP/vIdAuw2OcxDID9b6c70oUh31YoLPQFq37SmGoAu3/l/rIMWniImFZaGbSm8o1XgoGdj5ONPUlT6mE8WVd4tSmZaxv2xRa6+yijHrmhnn+AXfPeN03Mzbcljof4zzItfWhzWmVBvOhac6bYPvyrIy80P2WPexJ9KgoQpdjOgITSV2IaDfYqoXCJZqht03Xw30hFrnAV1NNN/E6QcY6oNPTbArNB2Pj2qVOwiglDfQMxSdVF9ZGdDYjqJeF1TWuYUErG8+S5fQIi8AX3CbBpSZ7Pd2EM+qRheFr39yh17HVN3zRsUP9maTPtGe8bsaf0GXb1QcL3ixBi1yVPNJVH8WzCe0GHJAWEriMeADCEAMrjt4c6XUOwMsEEJYS0c682VeNc83gFGaJ0LPRlwjUVTNDIQKZSUC5sr8yYBdds/pk6EKZLirxVK/lB+GZ5eVU/jecpUuMwjd0QgPQ8beA29jEZB+8rswpmX+Vksbv2Eel1F4vdvHxgV09jUBXZfUjntnrvae/fWp69Wf3Ak149Gh+f5xzgK0QY9gxjRuOVQWrG72WVhxVafVR9770hKd0voS3P42mWtB3C8QMwZe5cqr/bxpIpDXcmMyzQwDnIrl+B7RG+MQ2OzN00LD57bcCTd72Mx85ywJzxFffxjJ2t2n3RQpFUsovrPU3/Vue8OmC8s7gErsk93oE8fjXu6bZodGYoE+/8FCKfSNw6kVMoi3nh2GWc2HOPVUSzvMvWuXtKu5JMiZG4C8l2AQ0EVhAgVYfgR+lM+ojmCJPJHKE7diaQHEfpo3AiXtAUW3Pk7oNBn//xK3RQv4IL8MtMkLmMp+qaQy6gZhZRZfxlQXNSloCXJUEq2uju3hk1/gTfjBneQhqyJMEDD9ShAYGZ6uaQC/QUMvVFc0KWsF5gPp7+JtJwaPg+J5fp1kA7BgQYxpvoZZjAAAfdMH/+61jQ78zJKVAGHKZ93RhfolPspw8P8NFD9UlaNmUYT2ID0y3kzs0Y+NSXEDptDayTCkKrizE5Nq0DeNPI/Rb6jfeMcCXn3WL5yJoqqxcydlbF1Wz7qgkJ6ourrMpiSeWaWVWIiVwUvgfdxZZJ0BcpnT5zMML3h/pOKA96lqujZLSmNGHQocJiY5++BRG7YrOrBiVM//GZI0q93HNQecIX6uebkWkzkVLo23Rs8H8fKJDnRg0bFpUnz98qL4jKHT48Wa9AvjVfnkeZsS0qkhdBnhegj+EC3tqauICdb2u9h5/D29qcd+58a9uuU+ja14lMUcyMxK+8WHVJ4t+SL4maub+mfeGpBBCO3RDF9bXJlBXx064k/sNTMa+S/6H/I/KqS/5O/Cr9mhg/NpYvimgSZDCVhjJpNiEBulMv+zn7FODncTBnOG6y3gUvAmvO7xeFC8rkKs5SV2OXRtdSSnx6o03R9Y/1r36a7lF2UXqmf1vX7/yB8/vB8tyf5EkOOIwJyG6JugrVkqsnu8bax8wR18DVqLcD7Q7H4SeveJTM73DYY7ue3Dl74KPIqxKr5OrNDrElrj/Jl1Qza+zkUnq11qzId+9IIMkbApG3tcXItBmIRZ9cMu7zh5Ga2eeRSfQf9WPoMI5ASJGccFkdjc50HpsuUN3Mpgb8XJ5cgqKWGTNKZuYhFgvkmchtlofE3wteLsHDBHG3DQqGn5hyiwVJ+ivGTuWpLryBFSrAHxkQgkOx27+zvn4ohaRBQw82KssLCyhO27Yh0vPtDE8p/fbN1Vk4zZG5pDjh13RsJxZp1Bo/gTGHcRbNybJuHqMtx1knsOLEmjlFhmcEp5N2zKbqLBrnhFyiMVswuUN7SVZPPDKwBg05QrNwTq+aRUtXsDoht9RyTFOhvybFW7qpjgJ5paE+opwc0T1vw1xeOW9Yr/wNcyHt4RQb92p/s7vfb8Wl9Rwb9Cs6zPeSp/ke4jDhd+UeUmw5I+uaOzx3gZYws8RP+MgDfA9ZQWrAtfuII/9f08HpI+xkgGh3AjyOBhVc4CDpSm1I2sn3kRzSS2qOj5yyxSJgJyvJaL4VBJfwOu8km+/jQ8PWdf4H//d/9Nkw2Lgc69r/dYgKPc70WxSf0mN8ZtNdZNHATselKparf1d82UDTldbyqwOMI1gxmaZO2SruqF2LLoXfvpHZ7BBfmr9rBVfFMKbMGNaIwcZaQP9AsnMQuzqrABlSjhSayG1WgMSfVNZjTLk4tNqQjtVqbqvfo7ZLEXpGF+Yah75TPW/vyjAYYQMTocSEV8PNjTAqIqZHJTahJtRqyEBrNXfU77BxlyNwbHGMSBtex/5+1E0VhW5RYvePJlmiVTMjYPodqbgC4ppO3FBJBWeyI2YNPLt1Xhw81q4b1CsPlxRWZOWdlLynWJVb9upmZUfeuSFBNxxnnXn8fh+nBe83ddrnmBsveqxba9S2w6SpkqzcU+JJ9vGJOAP93kFd3itgs4zy8VsQ6wguufAiVaU0SeaJTSoj/MxfGDYSsY7ZUiJnJTggl1Eq7WBUM1RO1NY6vWQt6QvxkfhyrNPqUPE627/n2Dkj8BDDuVvKR5Rv4Q7/7n2t003UEh6WCJ+47qj5FY1SGs7C8SrfL7WkhwnnMf7RHj4M/F9eE8VNvtcr/INZ+OuLZTnrB8Q4GwP1okCjoFU2aeiTswW7WfUhomfiThVaoXxx2mI59xT7rHPMj8JfTgtHfSRGmlPDpDQZtfi2Mj8XFTNIt5WpP98HgYeasF4ZJ1Hm52BIXm4nwJFH+y8IQDhOQAl8nFnPqIEftENb19goPWWzrUMGaocNoIa+EIkE1I2G0oR0bIAEzc0FHeO/DuUj1prkfO6UcWusXDaGxu/1qLVQfj13SqGs+wlqq96cMdOcLrMTfztlxVuMYc87/hyG3Fx74v6p9BuK2oznYSsLh6eXY2x4gFqWLLSgQ9A1K7DSn9iRiOY7qJ52QiSYIoDwJv4UflANN4K+bAoHvTvRrv0rmi7DdLjchG6OvCg/xJ3OPVS+QtubtNNNmJLH87gRzxahr2n3NT0Vl6J7GaN7Xu4ZbbIilwN0jPa6VNCPBibmg9mC5CH5ZnO+hzaAoDOzpcclnosoJVxSSG0WL+yPl0VckV4BQxO1A+pggR32Pdfecg5zFoDvQDecFccIL8kjvYTWGu/nTJBrK0xKh8gkdDSZmhxCk8gx6cJiyTORblLfmnA7rZNILznbol17Q0QIISQo6PpH9Gy0i3aItjQuTVs6zs7dwXVwe2pNv6R/EdmFobcaHb+ziKDO/9b14MOVSdJIMDNn+8yZU6RuqdWrY5V6pfMrt0ayzC31G2chjBnzK5MUeWBOMEgMX+wseg0geNdJTEu0e1xH08aX1eFhKZiMLH9pPxZf1uY0hrNOPbXrHPoqzQ0iJmsXXkCnXO9xEIsTCXebTtbx8/7U4QhkCLyetvyRUVj75Y+tx9ot99uBiSs+mohF/0ncFdApfWrKRJ1/55L/JZ/3wp79v58brAvDNv+uNZnNP4BNxtPwa7KREY6f/17b6HBlOLRAXoICAGEWAgTB2CMBz7A4zWz+sczpGGEXB+QA7MpjoeFT2+ksIMGgs4EL3XQCNFA4PAlSmAAYIDgPAJJhoaYjQMFxHQUhXNcxoKBew6e6dRaEgFdnA4VgOgFFiHSMpA1e9LR5DaAZUvXsFRqqrJXFm6DhFzgpdEgm+8v+IEQsVLfkmq38hAqCiH5i4+7MVtlApfrQHgyKglQdKAPDiWeuH5eLpfWbGCpHG14DaHbXTRXPfkc0VNn2eZP79V/gpNDhzlEvO/5BiHjrihsJVwbt06qYjjoUNTbuDhNplX1goFLxQSQUZhkpanpnGRhO8A1K6gcXcjbLaiXd83JdXAYUGOPfqEChIsVKlCpTrkIlmZzKVK4KVapK1apRrepUrwY1qontrVCGRmOqq4PtIa8rNzhFucZ90gspwrnDA41XyMI8Jjme6dD08MvSnmTB1gk8430rlGP0kklDYXxR+aFDJiGQ+3zfgDDLAldcJNVYtDpA1Yu1EY0dpdAn6AwUQxNBgIWlHunhbvdbRE/Sw66NmtHD4HHBE9li9S+ICE5fDN3FzSpo4y7FKoA3t5V9yi5Z4x0YZKBmCDlJC5V8Ym40AgAA') format('woff2'), + url('iconfont.woff?t=1567826173562') format('woff'), + url('iconfont.ttf?t=1567826173562') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ + url('iconfont.svg?t=1567826173562#iconfont') format('svg'); /* iOS 4.1- */ +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.iconduojicaidan:before { + content: "\e608"; +} + +.icondaohangzhankai:before { + content: "\e609"; +} + +.icondaohangzhedie:before { + content: "\e60a"; +} + +.iconxiangshangjiantou:before { + content: "\e60b"; +} + +.iconxiangzuojiantou:before { + content: "\e60c"; +} + +.iconxiangyoujiantou:before { + content: "\e60d"; +} + +.iconguanbianniu:before { + content: "\e60e"; +} + +.iconshujushangchuan:before { + content: "\e60f"; +} + +.iconxitongjiankong:before { + content: "\e610"; +} + +.iconyoujianguanli:before { + content: "\e611"; +} + +.iconxiaoping:before { + content: "\e612"; +} + +.iconrenyuanguanli:before { + content: "\e613"; +} + +.iconxiangxiala:before { + content: "\e614"; +} + +.iconexceldaorudaochu:before { + content: "\e615"; +} + +.iconxiangxiajiantou:before { + content: "\e616"; +} + +.iconshouye:before { + content: "\e617"; +} + +.iconxitongshezhi:before { + content: "\e618"; +} + +.iconxiaoxi:before { + content: "\e619"; +} + +.iconquanping:before { + content: "\e61a"; +} + +.iconzujian:before { + content: "\e61b"; +} + +.iconnews:before { + content: "\e61e"; +} + +.icondingshirenwu:before { + content: "\e622"; +} + +.icondongtaijiazai:before { + content: "\e623"; +} + +.iconjiekouwendang:before { + content: "\e624"; +} + diff --git a/front/src/assets/icons/iconfont.eot b/front/src/assets/icons/iconfont.eot new file mode 100644 index 00000000..cf0b3fbd Binary files /dev/null and b/front/src/assets/icons/iconfont.eot differ diff --git a/front/src/assets/icons/iconfont.js b/front/src/assets/icons/iconfont.js new file mode 100644 index 00000000..6a3315a1 --- /dev/null +++ b/front/src/assets/icons/iconfont.js @@ -0,0 +1 @@ +!function(e){var c,t='',h=(c=document.getElementsByTagName("script"))[c.length-1].getAttribute("data-injectcss");if(h&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}!function(c){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(c,0);else{var h=function(){document.removeEventListener("DOMContentLoaded",h,!1),c()};document.addEventListener("DOMContentLoaded",h,!1)}else document.attachEvent&&(a=c,o=e.document,l=!1,(i=function(){try{o.documentElement.doScroll("left")}catch(c){return void setTimeout(i,50)}t()})(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,t())});function t(){l||(l=!0,a())}var a,o,l,i}(function(){var c,h;(c=document.createElement("div")).innerHTML=t,t=null,(h=c.getElementsByTagName("svg")[0])&&(h.setAttribute("aria-hidden","true"),h.style.position="absolute",h.style.width=0,h.style.height=0,h.style.overflow="hidden",function(c,h){h.firstChild?function(c,h){h.parentNode.insertBefore(c,h)}(c,h.firstChild):h.appendChild(c)}(h,document.body))})}(window); \ No newline at end of file diff --git a/front/src/assets/icons/iconfont.svg b/front/src/assets/icons/iconfont.svg new file mode 100644 index 00000000..a349f5e2 --- /dev/null +++ b/front/src/assets/icons/iconfont.svg @@ -0,0 +1,98 @@ + + + + + +Created by iconfont + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/front/src/assets/icons/iconfont.ttf b/front/src/assets/icons/iconfont.ttf new file mode 100644 index 00000000..69587d9e Binary files /dev/null and b/front/src/assets/icons/iconfont.ttf differ diff --git a/front/src/assets/icons/iconfont.woff b/front/src/assets/icons/iconfont.woff new file mode 100644 index 00000000..fc0da088 Binary files /dev/null and b/front/src/assets/icons/iconfont.woff differ diff --git a/front/src/assets/icons/iconfont.woff2 b/front/src/assets/icons/iconfont.woff2 new file mode 100644 index 00000000..89c0d09e Binary files /dev/null and b/front/src/assets/icons/iconfont.woff2 differ diff --git a/front/src/assets/images/default_icon.png b/front/src/assets/images/default_icon.png new file mode 100644 index 00000000..1e0872fd Binary files /dev/null and b/front/src/assets/images/default_icon.png differ diff --git a/front/src/assets/images/error-page/error-401.svg b/front/src/assets/images/error-page/error-401.svg new file mode 100644 index 00000000..19e2f9fa --- /dev/null +++ b/front/src/assets/images/error-page/error-401.svg @@ -0,0 +1 @@ +tasting \ No newline at end of file diff --git a/front/src/assets/images/error-page/error-404.svg b/front/src/assets/images/error-page/error-404.svg new file mode 100644 index 00000000..77d97f71 --- /dev/null +++ b/front/src/assets/images/error-page/error-404.svg @@ -0,0 +1 @@ +drone_delivery \ No newline at end of file diff --git a/front/src/assets/images/error-page/error-500.svg b/front/src/assets/images/error-page/error-500.svg new file mode 100644 index 00000000..ef72fd32 --- /dev/null +++ b/front/src/assets/images/error-page/error-500.svg @@ -0,0 +1 @@ +co-working \ No newline at end of file diff --git a/front/src/assets/images/icon-qr-qq-wechat.png b/front/src/assets/images/icon-qr-qq-wechat.png new file mode 100644 index 00000000..c5f6b185 Binary files /dev/null and b/front/src/assets/images/icon-qr-qq-wechat.png differ diff --git a/front/src/assets/images/icon-social-bilibili.svg b/front/src/assets/images/icon-social-bilibili.svg new file mode 100644 index 00000000..d655a329 --- /dev/null +++ b/front/src/assets/images/icon-social-bilibili.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front/src/assets/images/icon-social-juejin.svg b/front/src/assets/images/icon-social-juejin.svg new file mode 100644 index 00000000..c0ad2aeb --- /dev/null +++ b/front/src/assets/images/icon-social-juejin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front/src/assets/images/icon-social-twitter.svg b/front/src/assets/images/icon-social-twitter.svg new file mode 100644 index 00000000..cef3ec09 --- /dev/null +++ b/front/src/assets/images/icon-social-twitter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front/src/assets/images/icon-social-zhihu.svg b/front/src/assets/images/icon-social-zhihu.svg new file mode 100644 index 00000000..3a82ca82 --- /dev/null +++ b/front/src/assets/images/icon-social-zhihu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front/src/assets/images/login-alipay.png b/front/src/assets/images/login-alipay.png new file mode 100644 index 00000000..7d9f0306 Binary files /dev/null and b/front/src/assets/images/login-alipay.png differ diff --git a/front/src/assets/images/login-bg.jpg b/front/src/assets/images/login-bg.jpg new file mode 100644 index 00000000..04c27b4f Binary files /dev/null and b/front/src/assets/images/login-bg.jpg differ diff --git a/front/src/assets/images/login-logo.png b/front/src/assets/images/login-logo.png new file mode 100644 index 00000000..61765e6d Binary files /dev/null and b/front/src/assets/images/login-logo.png differ diff --git a/front/src/assets/images/login-sina.png b/front/src/assets/images/login-sina.png new file mode 100644 index 00000000..950619fd Binary files /dev/null and b/front/src/assets/images/login-sina.png differ diff --git a/front/src/assets/images/login-taobao.png b/front/src/assets/images/login-taobao.png new file mode 100644 index 00000000..ecaa608a Binary files /dev/null and b/front/src/assets/images/login-taobao.png differ diff --git a/front/src/assets/images/login_desc_bg.png b/front/src/assets/images/login_desc_bg.png new file mode 100644 index 00000000..70d8d62f Binary files /dev/null and b/front/src/assets/images/login_desc_bg.png differ diff --git a/front/src/assets/images/login_logo.png b/front/src/assets/images/login_logo.png new file mode 100644 index 00000000..2955b838 Binary files /dev/null and b/front/src/assets/images/login_logo.png differ diff --git a/front/src/assets/images/logo-min.png b/front/src/assets/images/logo-min.png new file mode 100644 index 00000000..b586a64b Binary files /dev/null and b/front/src/assets/images/logo-min.png differ diff --git a/front/src/assets/images/logo.png b/front/src/assets/images/logo.png new file mode 100644 index 00000000..f338302e Binary files /dev/null and b/front/src/assets/images/logo.png differ diff --git a/front/src/assets/images/message.png b/front/src/assets/images/message.png new file mode 100644 index 00000000..b713953e Binary files /dev/null and b/front/src/assets/images/message.png differ diff --git a/front/src/assets/images/shadow.png b/front/src/assets/images/shadow.png new file mode 100644 index 00000000..79cc097f Binary files /dev/null and b/front/src/assets/images/shadow.png differ diff --git a/front/src/assets/images/slider/sub_slider_active.png b/front/src/assets/images/slider/sub_slider_active.png new file mode 100644 index 00000000..bc2ec9aa Binary files /dev/null and b/front/src/assets/images/slider/sub_slider_active.png differ diff --git a/front/src/assets/images/slider/sub_slider_default.png b/front/src/assets/images/slider/sub_slider_default.png new file mode 100644 index 00000000..67a4f279 Binary files /dev/null and b/front/src/assets/images/slider/sub_slider_default.png differ diff --git a/front/src/assets/style/lib/animate.css b/front/src/assets/style/lib/animate.css new file mode 100644 index 00000000..6c72f594 --- /dev/null +++ b/front/src/assets/style/lib/animate.css @@ -0,0 +1,3625 @@ +@charset "UTF-8"; + +/*! + * animate.css -https://daneden.github.io/animate.css/ + * Version - 3.7.2 + * Licensed under the MIT license - http://opensource.org/licenses/MIT + * + * Copyright (c) 2019 Daniel Eden + */ + +@-webkit-keyframes bounce { + from, + 20%, + 53%, + 80%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 40%, + 43% { + -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + -webkit-transform: translate3d(0, -30px, 0); + transform: translate3d(0, -30px, 0); + } + + 70% { + -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + -webkit-transform: translate3d(0, -15px, 0); + transform: translate3d(0, -15px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -4px, 0); + transform: translate3d(0, -4px, 0); + } +} + +@keyframes bounce { + from, + 20%, + 53%, + 80%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 40%, + 43% { + -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + -webkit-transform: translate3d(0, -30px, 0); + transform: translate3d(0, -30px, 0); + } + + 70% { + -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + -webkit-transform: translate3d(0, -15px, 0); + transform: translate3d(0, -15px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -4px, 0); + transform: translate3d(0, -4px, 0); + } +} + +.bounce { + -webkit-animation-name: bounce; + animation-name: bounce; + -webkit-transform-origin: center bottom; + transform-origin: center bottom; +} + +@-webkit-keyframes flash { + from, + 50%, + to { + opacity: 1; + } + + 25%, + 75% { + opacity: 0; + } +} + +@keyframes flash { + from, + 50%, + to { + opacity: 1; + } + + 25%, + 75% { + opacity: 0; + } +} + +.flash { + -webkit-animation-name: flash; + animation-name: flash; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes pulse { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 50% { + -webkit-transform: scale3d(1.05, 1.05, 1.05); + transform: scale3d(1.05, 1.05, 1.05); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes pulse { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 50% { + -webkit-transform: scale3d(1.05, 1.05, 1.05); + transform: scale3d(1.05, 1.05, 1.05); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.pulse { + -webkit-animation-name: pulse; + animation-name: pulse; +} + +@-webkit-keyframes rubberBand { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 30% { + -webkit-transform: scale3d(1.25, 0.75, 1); + transform: scale3d(1.25, 0.75, 1); + } + + 40% { + -webkit-transform: scale3d(0.75, 1.25, 1); + transform: scale3d(0.75, 1.25, 1); + } + + 50% { + -webkit-transform: scale3d(1.15, 0.85, 1); + transform: scale3d(1.15, 0.85, 1); + } + + 65% { + -webkit-transform: scale3d(0.95, 1.05, 1); + transform: scale3d(0.95, 1.05, 1); + } + + 75% { + -webkit-transform: scale3d(1.05, 0.95, 1); + transform: scale3d(1.05, 0.95, 1); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes rubberBand { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 30% { + -webkit-transform: scale3d(1.25, 0.75, 1); + transform: scale3d(1.25, 0.75, 1); + } + + 40% { + -webkit-transform: scale3d(0.75, 1.25, 1); + transform: scale3d(0.75, 1.25, 1); + } + + 50% { + -webkit-transform: scale3d(1.15, 0.85, 1); + transform: scale3d(1.15, 0.85, 1); + } + + 65% { + -webkit-transform: scale3d(0.95, 1.05, 1); + transform: scale3d(0.95, 1.05, 1); + } + + 75% { + -webkit-transform: scale3d(1.05, 0.95, 1); + transform: scale3d(1.05, 0.95, 1); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.rubberBand { + -webkit-animation-name: rubberBand; + animation-name: rubberBand; +} + +@-webkit-keyframes shake { + from, + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 10%, + 30%, + 50%, + 70%, + 90% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 20%, + 40%, + 60%, + 80% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } +} + +@keyframes shake { + from, + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 10%, + 30%, + 50%, + 70%, + 90% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 20%, + 40%, + 60%, + 80% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } +} + +.shake { + -webkit-animation-name: shake; + animation-name: shake; +} + +@-webkit-keyframes headShake { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 6.5% { + -webkit-transform: translateX(-6px) rotateY(-9deg); + transform: translateX(-6px) rotateY(-9deg); + } + + 18.5% { + -webkit-transform: translateX(5px) rotateY(7deg); + transform: translateX(5px) rotateY(7deg); + } + + 31.5% { + -webkit-transform: translateX(-3px) rotateY(-5deg); + transform: translateX(-3px) rotateY(-5deg); + } + + 43.5% { + -webkit-transform: translateX(2px) rotateY(3deg); + transform: translateX(2px) rotateY(3deg); + } + + 50% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes headShake { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 6.5% { + -webkit-transform: translateX(-6px) rotateY(-9deg); + transform: translateX(-6px) rotateY(-9deg); + } + + 18.5% { + -webkit-transform: translateX(5px) rotateY(7deg); + transform: translateX(5px) rotateY(7deg); + } + + 31.5% { + -webkit-transform: translateX(-3px) rotateY(-5deg); + transform: translateX(-3px) rotateY(-5deg); + } + + 43.5% { + -webkit-transform: translateX(2px) rotateY(3deg); + transform: translateX(2px) rotateY(3deg); + } + + 50% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +.headShake { + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-name: headShake; + animation-name: headShake; +} + +@-webkit-keyframes swing { + 20% { + -webkit-transform: rotate3d(0, 0, 1, 15deg); + transform: rotate3d(0, 0, 1, 15deg); + } + + 40% { + -webkit-transform: rotate3d(0, 0, 1, -10deg); + transform: rotate3d(0, 0, 1, -10deg); + } + + 60% { + -webkit-transform: rotate3d(0, 0, 1, 5deg); + transform: rotate3d(0, 0, 1, 5deg); + } + + 80% { + -webkit-transform: rotate3d(0, 0, 1, -5deg); + transform: rotate3d(0, 0, 1, -5deg); + } + + to { + -webkit-transform: rotate3d(0, 0, 1, 0deg); + transform: rotate3d(0, 0, 1, 0deg); + } +} + +@keyframes swing { + 20% { + -webkit-transform: rotate3d(0, 0, 1, 15deg); + transform: rotate3d(0, 0, 1, 15deg); + } + + 40% { + -webkit-transform: rotate3d(0, 0, 1, -10deg); + transform: rotate3d(0, 0, 1, -10deg); + } + + 60% { + -webkit-transform: rotate3d(0, 0, 1, 5deg); + transform: rotate3d(0, 0, 1, 5deg); + } + + 80% { + -webkit-transform: rotate3d(0, 0, 1, -5deg); + transform: rotate3d(0, 0, 1, -5deg); + } + + to { + -webkit-transform: rotate3d(0, 0, 1, 0deg); + transform: rotate3d(0, 0, 1, 0deg); + } +} + +.swing { + -webkit-transform-origin: top center; + transform-origin: top center; + -webkit-animation-name: swing; + animation-name: swing; +} + +@-webkit-keyframes tada { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 10%, + 20% { + -webkit-transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); + transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); + } + + 30%, + 50%, + 70%, + 90% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + } + + 40%, + 60%, + 80% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes tada { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 10%, + 20% { + -webkit-transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); + transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); + } + + 30%, + 50%, + 70%, + 90% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + } + + 40%, + 60%, + 80% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.tada { + -webkit-animation-name: tada; + animation-name: tada; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes wobble { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 15% { + -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + } + + 30% { + -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + } + + 45% { + -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + } + + 60% { + -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + } + + 75% { + -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes wobble { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 15% { + -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + } + + 30% { + -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + } + + 45% { + -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + } + + 60% { + -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + } + + 75% { + -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.wobble { + -webkit-animation-name: wobble; + animation-name: wobble; +} + +@-webkit-keyframes jello { + from, + 11.1%, + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 22.2% { + -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); + transform: skewX(-12.5deg) skewY(-12.5deg); + } + + 33.3% { + -webkit-transform: skewX(6.25deg) skewY(6.25deg); + transform: skewX(6.25deg) skewY(6.25deg); + } + + 44.4% { + -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); + transform: skewX(-3.125deg) skewY(-3.125deg); + } + + 55.5% { + -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); + transform: skewX(1.5625deg) skewY(1.5625deg); + } + + 66.6% { + -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); + transform: skewX(-0.78125deg) skewY(-0.78125deg); + } + + 77.7% { + -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); + transform: skewX(0.390625deg) skewY(0.390625deg); + } + + 88.8% { + -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); + transform: skewX(-0.1953125deg) skewY(-0.1953125deg); + } +} + +@keyframes jello { + from, + 11.1%, + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 22.2% { + -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); + transform: skewX(-12.5deg) skewY(-12.5deg); + } + + 33.3% { + -webkit-transform: skewX(6.25deg) skewY(6.25deg); + transform: skewX(6.25deg) skewY(6.25deg); + } + + 44.4% { + -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); + transform: skewX(-3.125deg) skewY(-3.125deg); + } + + 55.5% { + -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); + transform: skewX(1.5625deg) skewY(1.5625deg); + } + + 66.6% { + -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); + transform: skewX(-0.78125deg) skewY(-0.78125deg); + } + + 77.7% { + -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); + transform: skewX(0.390625deg) skewY(0.390625deg); + } + + 88.8% { + -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); + transform: skewX(-0.1953125deg) skewY(-0.1953125deg); + } +} + +.jello { + -webkit-animation-name: jello; + animation-name: jello; + -webkit-transform-origin: center; + transform-origin: center; +} + +@-webkit-keyframes heartBeat { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 14% { + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + + 28% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 42% { + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + + 70% { + -webkit-transform: scale(1); + transform: scale(1); + } +} + +@keyframes heartBeat { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 14% { + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + + 28% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 42% { + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + + 70% { + -webkit-transform: scale(1); + transform: scale(1); + } +} + +.heartBeat { + -webkit-animation-name: heartBeat; + animation-name: heartBeat; + -webkit-animation-duration: 1.3s; + animation-duration: 1.3s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; +} + +@-webkit-keyframes bounceIn { + from, + 20%, + 40%, + 60%, + 80%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + 20% { + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + 40% { + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(1.03, 1.03, 1.03); + transform: scale3d(1.03, 1.03, 1.03); + } + + 80% { + -webkit-transform: scale3d(0.97, 0.97, 0.97); + transform: scale3d(0.97, 0.97, 0.97); + } + + to { + opacity: 1; + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes bounceIn { + from, + 20%, + 40%, + 60%, + 80%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + 20% { + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + 40% { + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(1.03, 1.03, 1.03); + transform: scale3d(1.03, 1.03, 1.03); + } + + 80% { + -webkit-transform: scale3d(0.97, 0.97, 0.97); + transform: scale3d(0.97, 0.97, 0.97); + } + + to { + opacity: 1; + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.bounceIn { + -webkit-animation-duration: 0.75s; + animation-duration: 0.75s; + -webkit-animation-name: bounceIn; + animation-name: bounceIn; +} + +@-webkit-keyframes bounceInDown { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -3000px, 0); + transform: translate3d(0, -3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, 25px, 0); + transform: translate3d(0, 25px, 0); + } + + 75% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, 5px, 0); + transform: translate3d(0, 5px, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes bounceInDown { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -3000px, 0); + transform: translate3d(0, -3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, 25px, 0); + transform: translate3d(0, 25px, 0); + } + + 75% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, 5px, 0); + transform: translate3d(0, 5px, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.bounceInDown { + -webkit-animation-name: bounceInDown; + animation-name: bounceInDown; +} + +@-webkit-keyframes bounceInLeft { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(-3000px, 0, 0); + transform: translate3d(-3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(25px, 0, 0); + transform: translate3d(25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(5px, 0, 0); + transform: translate3d(5px, 0, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes bounceInLeft { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(-3000px, 0, 0); + transform: translate3d(-3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(25px, 0, 0); + transform: translate3d(25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(5px, 0, 0); + transform: translate3d(5px, 0, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.bounceInLeft { + -webkit-animation-name: bounceInLeft; + animation-name: bounceInLeft; +} + +@-webkit-keyframes bounceInRight { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + from { + opacity: 0; + -webkit-transform: translate3d(3000px, 0, 0); + transform: translate3d(3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(-25px, 0, 0); + transform: translate3d(-25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(-5px, 0, 0); + transform: translate3d(-5px, 0, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes bounceInRight { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + from { + opacity: 0; + -webkit-transform: translate3d(3000px, 0, 0); + transform: translate3d(3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(-25px, 0, 0); + transform: translate3d(-25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(-5px, 0, 0); + transform: translate3d(-5px, 0, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.bounceInRight { + -webkit-animation-name: bounceInRight; + animation-name: bounceInRight; +} + +@-webkit-keyframes bounceInUp { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + from { + opacity: 0; + -webkit-transform: translate3d(0, 3000px, 0); + transform: translate3d(0, 3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + 75% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -5px, 0); + transform: translate3d(0, -5px, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes bounceInUp { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + from { + opacity: 0; + -webkit-transform: translate3d(0, 3000px, 0); + transform: translate3d(0, 3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + 75% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -5px, 0); + transform: translate3d(0, -5px, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.bounceInUp { + -webkit-animation-name: bounceInUp; + animation-name: bounceInUp; +} + +@-webkit-keyframes bounceOut { + 20% { + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } + + 50%, + 55% { + opacity: 1; + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } +} + +@keyframes bounceOut { + 20% { + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } + + 50%, + 55% { + opacity: 1; + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } +} + +.bounceOut { + -webkit-animation-duration: 0.75s; + animation-duration: 0.75s; + -webkit-animation-name: bounceOut; + animation-name: bounceOut; +} + +@-webkit-keyframes bounceOutDown { + 20% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 40%, + 45% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +@keyframes bounceOutDown { + 20% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 40%, + 45% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +.bounceOutDown { + -webkit-animation-name: bounceOutDown; + animation-name: bounceOutDown; +} + +@-webkit-keyframes bounceOutLeft { + 20% { + opacity: 1; + -webkit-transform: translate3d(20px, 0, 0); + transform: translate3d(20px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +@keyframes bounceOutLeft { + 20% { + opacity: 1; + -webkit-transform: translate3d(20px, 0, 0); + transform: translate3d(20px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +.bounceOutLeft { + -webkit-animation-name: bounceOutLeft; + animation-name: bounceOutLeft; +} + +@-webkit-keyframes bounceOutRight { + 20% { + opacity: 1; + -webkit-transform: translate3d(-20px, 0, 0); + transform: translate3d(-20px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +@keyframes bounceOutRight { + 20% { + opacity: 1; + -webkit-transform: translate3d(-20px, 0, 0); + transform: translate3d(-20px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +.bounceOutRight { + -webkit-animation-name: bounceOutRight; + animation-name: bounceOutRight; +} + +@-webkit-keyframes bounceOutUp { + 20% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 40%, + 45% { + opacity: 1; + -webkit-transform: translate3d(0, 20px, 0); + transform: translate3d(0, 20px, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +@keyframes bounceOutUp { + 20% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 40%, + 45% { + opacity: 1; + -webkit-transform: translate3d(0, 20px, 0); + transform: translate3d(0, 20px, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +.bounceOutUp { + -webkit-animation-name: bounceOutUp; + animation-name: bounceOutUp; +} + +@-webkit-keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +.fadeIn { + -webkit-animation-name: fadeIn; + animation-name: fadeIn; +} + +@-webkit-keyframes fadeInDown { + from { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInDown { + from { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInDown { + -webkit-animation-name: fadeInDown; + animation-name: fadeInDown; +} + +@-webkit-keyframes fadeInDownBig { + from { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInDownBig { + from { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInDownBig { + -webkit-animation-name: fadeInDownBig; + animation-name: fadeInDownBig; +} + +@-webkit-keyframes fadeInLeft { + from { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInLeft { + from { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInLeft { + -webkit-animation-name: fadeInLeft; + animation-name: fadeInLeft; +} + +@-webkit-keyframes fadeInLeftBig { + from { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInLeftBig { + from { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInLeftBig { + -webkit-animation-name: fadeInLeftBig; + animation-name: fadeInLeftBig; +} + +@-webkit-keyframes fadeInRight { + from { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInRight { + from { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInRight { + -webkit-animation-name: fadeInRight; + animation-name: fadeInRight; +} + +@-webkit-keyframes fadeInRightBig { + from { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInRightBig { + from { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInRightBig { + -webkit-animation-name: fadeInRightBig; + animation-name: fadeInRightBig; +} + +@-webkit-keyframes fadeInUp { + from { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInUp { + from { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInUp { + -webkit-animation-name: fadeInUp; + animation-name: fadeInUp; +} + +@-webkit-keyframes fadeInUpBig { + from { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInUpBig { + from { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInUpBig { + -webkit-animation-name: fadeInUpBig; + animation-name: fadeInUpBig; +} + +@-webkit-keyframes fadeOut { + from { + opacity: 1; + } + + to { + opacity: 0; + } +} + +@keyframes fadeOut { + from { + opacity: 1; + } + + to { + opacity: 0; + } +} + +.fadeOut { + -webkit-animation-name: fadeOut; + animation-name: fadeOut; +} + +@-webkit-keyframes fadeOutDown { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +@keyframes fadeOutDown { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +.fadeOutDown { + -webkit-animation-name: fadeOutDown; + animation-name: fadeOutDown; +} + +@-webkit-keyframes fadeOutDownBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +@keyframes fadeOutDownBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +.fadeOutDownBig { + -webkit-animation-name: fadeOutDownBig; + animation-name: fadeOutDownBig; +} + +@-webkit-keyframes fadeOutLeft { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +@keyframes fadeOutLeft { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.fadeOutLeft { + -webkit-animation-name: fadeOutLeft; + animation-name: fadeOutLeft; +} + +@-webkit-keyframes fadeOutLeftBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +@keyframes fadeOutLeftBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +.fadeOutLeftBig { + -webkit-animation-name: fadeOutLeftBig; + animation-name: fadeOutLeftBig; +} + +@-webkit-keyframes fadeOutRight { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +@keyframes fadeOutRight { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +.fadeOutRight { + -webkit-animation-name: fadeOutRight; + animation-name: fadeOutRight; +} + +@-webkit-keyframes fadeOutRightBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +@keyframes fadeOutRightBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +.fadeOutRightBig { + -webkit-animation-name: fadeOutRightBig; + animation-name: fadeOutRightBig; +} + +@-webkit-keyframes fadeOutUp { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +@keyframes fadeOutUp { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +.fadeOutUp { + -webkit-animation-name: fadeOutUp; + animation-name: fadeOutUp; +} + +@-webkit-keyframes fadeOutUpBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +@keyframes fadeOutUpBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +.fadeOutUpBig { + -webkit-animation-name: fadeOutUpBig; + animation-name: fadeOutUpBig; +} + +@-webkit-keyframes flip { + from { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) + rotate3d(0, 1, 0, -360deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, -360deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 40% { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -190deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -190deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 50% { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -170deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -170deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 80% { + -webkit-transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + to { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, 0deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } +} + +@keyframes flip { + from { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) + rotate3d(0, 1, 0, -360deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, -360deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 40% { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -190deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -190deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 50% { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -170deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -170deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 80% { + -webkit-transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + to { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, 0deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } +} + +.animated.flip { + -webkit-backface-visibility: visible; + backface-visibility: visible; + -webkit-animation-name: flip; + animation-name: flip; +} + +@-webkit-keyframes flipInX { + from { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + } + + to { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +@keyframes flipInX { + from { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + } + + to { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +.flipInX { + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipInX; + animation-name: flipInX; +} + +@-webkit-keyframes flipInY { + from { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + } + + to { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +@keyframes flipInY { + from { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + } + + to { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +.flipInY { + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipInY; + animation-name: flipInY; +} + +@-webkit-keyframes flipOutX { + from { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + opacity: 1; + } + + to { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + opacity: 0; + } +} + +@keyframes flipOutX { + from { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + opacity: 1; + } + + to { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + opacity: 0; + } +} + +.flipOutX { + -webkit-animation-duration: 0.75s; + animation-duration: 0.75s; + -webkit-animation-name: flipOutX; + animation-name: flipOutX; + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; +} + +@-webkit-keyframes flipOutY { + from { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + opacity: 1; + } + + to { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + opacity: 0; + } +} + +@keyframes flipOutY { + from { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + opacity: 1; + } + + to { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + opacity: 0; + } +} + +.flipOutY { + -webkit-animation-duration: 0.75s; + animation-duration: 0.75s; + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipOutY; + animation-name: flipOutY; +} + +@-webkit-keyframes lightSpeedIn { + from { + -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); + transform: translate3d(100%, 0, 0) skewX(-30deg); + opacity: 0; + } + + 60% { + -webkit-transform: skewX(20deg); + transform: skewX(20deg); + opacity: 1; + } + + 80% { + -webkit-transform: skewX(-5deg); + transform: skewX(-5deg); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes lightSpeedIn { + from { + -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); + transform: translate3d(100%, 0, 0) skewX(-30deg); + opacity: 0; + } + + 60% { + -webkit-transform: skewX(20deg); + transform: skewX(20deg); + opacity: 1; + } + + 80% { + -webkit-transform: skewX(-5deg); + transform: skewX(-5deg); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.lightSpeedIn { + -webkit-animation-name: lightSpeedIn; + animation-name: lightSpeedIn; + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; +} + +@-webkit-keyframes lightSpeedOut { + from { + opacity: 1; + } + + to { + -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); + transform: translate3d(100%, 0, 0) skewX(30deg); + opacity: 0; + } +} + +@keyframes lightSpeedOut { + from { + opacity: 1; + } + + to { + -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); + transform: translate3d(100%, 0, 0) skewX(30deg); + opacity: 0; + } +} + +.lightSpeedOut { + -webkit-animation-name: lightSpeedOut; + animation-name: lightSpeedOut; + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; +} + +@-webkit-keyframes rotateIn { + from { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, -200deg); + transform: rotate3d(0, 0, 1, -200deg); + opacity: 0; + } + + to { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateIn { + from { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, -200deg); + transform: rotate3d(0, 0, 1, -200deg); + opacity: 0; + } + + to { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateIn { + -webkit-animation-name: rotateIn; + animation-name: rotateIn; +} + +@-webkit-keyframes rotateInDownLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateInDownLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateInDownLeft { + -webkit-animation-name: rotateInDownLeft; + animation-name: rotateInDownLeft; +} + +@-webkit-keyframes rotateInDownRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateInDownRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateInDownRight { + -webkit-animation-name: rotateInDownRight; + animation-name: rotateInDownRight; +} + +@-webkit-keyframes rotateInUpLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateInUpLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateInUpLeft { + -webkit-animation-name: rotateInUpLeft; + animation-name: rotateInUpLeft; +} + +@-webkit-keyframes rotateInUpRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -90deg); + transform: rotate3d(0, 0, 1, -90deg); + opacity: 0; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateInUpRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -90deg); + transform: rotate3d(0, 0, 1, -90deg); + opacity: 0; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateInUpRight { + -webkit-animation-name: rotateInUpRight; + animation-name: rotateInUpRight; +} + +@-webkit-keyframes rotateOut { + from { + -webkit-transform-origin: center; + transform-origin: center; + opacity: 1; + } + + to { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, 200deg); + transform: rotate3d(0, 0, 1, 200deg); + opacity: 0; + } +} + +@keyframes rotateOut { + from { + -webkit-transform-origin: center; + transform-origin: center; + opacity: 1; + } + + to { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, 200deg); + transform: rotate3d(0, 0, 1, 200deg); + opacity: 0; + } +} + +.rotateOut { + -webkit-animation-name: rotateOut; + animation-name: rotateOut; +} + +@-webkit-keyframes rotateOutDownLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } +} + +@keyframes rotateOutDownLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } +} + +.rotateOutDownLeft { + -webkit-animation-name: rotateOutDownLeft; + animation-name: rotateOutDownLeft; +} + +@-webkit-keyframes rotateOutDownRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +@keyframes rotateOutDownRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +.rotateOutDownRight { + -webkit-animation-name: rotateOutDownRight; + animation-name: rotateOutDownRight; +} + +@-webkit-keyframes rotateOutUpLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +@keyframes rotateOutUpLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +.rotateOutUpLeft { + -webkit-animation-name: rotateOutUpLeft; + animation-name: rotateOutUpLeft; +} + +@-webkit-keyframes rotateOutUpRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 90deg); + transform: rotate3d(0, 0, 1, 90deg); + opacity: 0; + } +} + +@keyframes rotateOutUpRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 90deg); + transform: rotate3d(0, 0, 1, 90deg); + opacity: 0; + } +} + +.rotateOutUpRight { + -webkit-animation-name: rotateOutUpRight; + animation-name: rotateOutUpRight; +} + +@-webkit-keyframes hinge { + 0% { + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 20%, + 60% { + -webkit-transform: rotate3d(0, 0, 1, 80deg); + transform: rotate3d(0, 0, 1, 80deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 40%, + 80% { + -webkit-transform: rotate3d(0, 0, 1, 60deg); + transform: rotate3d(0, 0, 1, 60deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + opacity: 1; + } + + to { + -webkit-transform: translate3d(0, 700px, 0); + transform: translate3d(0, 700px, 0); + opacity: 0; + } +} + +@keyframes hinge { + 0% { + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 20%, + 60% { + -webkit-transform: rotate3d(0, 0, 1, 80deg); + transform: rotate3d(0, 0, 1, 80deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 40%, + 80% { + -webkit-transform: rotate3d(0, 0, 1, 60deg); + transform: rotate3d(0, 0, 1, 60deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + opacity: 1; + } + + to { + -webkit-transform: translate3d(0, 700px, 0); + transform: translate3d(0, 700px, 0); + opacity: 0; + } +} + +.hinge { + -webkit-animation-duration: 2s; + animation-duration: 2s; + -webkit-animation-name: hinge; + animation-name: hinge; +} + +@-webkit-keyframes jackInTheBox { + from { + opacity: 0; + -webkit-transform: scale(0.1) rotate(30deg); + transform: scale(0.1) rotate(30deg); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + } + + 50% { + -webkit-transform: rotate(-10deg); + transform: rotate(-10deg); + } + + 70% { + -webkit-transform: rotate(3deg); + transform: rotate(3deg); + } + + to { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } +} + +@keyframes jackInTheBox { + from { + opacity: 0; + -webkit-transform: scale(0.1) rotate(30deg); + transform: scale(0.1) rotate(30deg); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + } + + 50% { + -webkit-transform: rotate(-10deg); + transform: rotate(-10deg); + } + + 70% { + -webkit-transform: rotate(3deg); + transform: rotate(3deg); + } + + to { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } +} + +.jackInTheBox { + -webkit-animation-name: jackInTheBox; + animation-name: jackInTheBox; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollIn { + from { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes rollIn { + from { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.rollIn { + -webkit-animation-name: rollIn; + animation-name: rollIn; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollOut { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + } +} + +@keyframes rollOut { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + } +} + +.rollOut { + -webkit-animation-name: rollOut; + animation-name: rollOut; +} + +@-webkit-keyframes zoomIn { + from { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + 50% { + opacity: 1; + } +} + +@keyframes zoomIn { + from { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + 50% { + opacity: 1; + } +} + +.zoomIn { + -webkit-animation-name: zoomIn; + animation-name: zoomIn; +} + +@-webkit-keyframes zoomInDown { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomInDown { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomInDown { + -webkit-animation-name: zoomInDown; + animation-name: zoomInDown; +} + +@-webkit-keyframes zoomInLeft { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomInLeft { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomInLeft { + -webkit-animation-name: zoomInLeft; + animation-name: zoomInLeft; +} + +@-webkit-keyframes zoomInRight { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomInRight { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomInRight { + -webkit-animation-name: zoomInRight; + animation-name: zoomInRight; +} + +@-webkit-keyframes zoomInUp { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomInUp { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomInUp { + -webkit-animation-name: zoomInUp; + animation-name: zoomInUp; +} + +@-webkit-keyframes zoomOut { + from { + opacity: 1; + } + + 50% { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + to { + opacity: 0; + } +} + +@keyframes zoomOut { + from { + opacity: 1; + } + + 50% { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + to { + opacity: 0; + } +} + +.zoomOut { + -webkit-animation-name: zoomOut; + animation-name: zoomOut; +} + +@-webkit-keyframes zoomOutDown { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomOutDown { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomOutDown { + -webkit-animation-name: zoomOutDown; + animation-name: zoomOutDown; +} + +@-webkit-keyframes zoomOutLeft { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: scale(0.1) translate3d(-2000px, 0, 0); + transform: scale(0.1) translate3d(-2000px, 0, 0); + -webkit-transform-origin: left center; + transform-origin: left center; + } +} + +@keyframes zoomOutLeft { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: scale(0.1) translate3d(-2000px, 0, 0); + transform: scale(0.1) translate3d(-2000px, 0, 0); + -webkit-transform-origin: left center; + transform-origin: left center; + } +} + +.zoomOutLeft { + -webkit-animation-name: zoomOutLeft; + animation-name: zoomOutLeft; +} + +@-webkit-keyframes zoomOutRight { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: scale(0.1) translate3d(2000px, 0, 0); + transform: scale(0.1) translate3d(2000px, 0, 0); + -webkit-transform-origin: right center; + transform-origin: right center; + } +} + +@keyframes zoomOutRight { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: scale(0.1) translate3d(2000px, 0, 0); + transform: scale(0.1) translate3d(2000px, 0, 0); + -webkit-transform-origin: right center; + transform-origin: right center; + } +} + +.zoomOutRight { + -webkit-animation-name: zoomOutRight; + animation-name: zoomOutRight; +} + +@-webkit-keyframes zoomOutUp { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomOutUp { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomOutUp { + -webkit-animation-name: zoomOutUp; + animation-name: zoomOutUp; +} + +@-webkit-keyframes slideInDown { + from { + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes slideInDown { + from { + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.slideInDown { + -webkit-animation-name: slideInDown; + animation-name: slideInDown; +} + +@-webkit-keyframes slideInLeft { + from { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes slideInLeft { + from { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.slideInLeft { + -webkit-animation-name: slideInLeft; + animation-name: slideInLeft; +} + +@-webkit-keyframes slideInRight { + from { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes slideInRight { + from { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.slideInRight { + -webkit-animation-name: slideInRight; + animation-name: slideInRight; +} + +@-webkit-keyframes slideInUp { + from { + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes slideInUp { + from { + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.slideInUp { + -webkit-animation-name: slideInUp; + animation-name: slideInUp; +} + +@-webkit-keyframes slideOutDown { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +@keyframes slideOutDown { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +.slideOutDown { + -webkit-animation-name: slideOutDown; + animation-name: slideOutDown; +} + +@-webkit-keyframes slideOutLeft { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +@keyframes slideOutLeft { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.slideOutLeft { + -webkit-animation-name: slideOutLeft; + animation-name: slideOutLeft; +} + +@-webkit-keyframes slideOutRight { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +@keyframes slideOutRight { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +.slideOutRight { + -webkit-animation-name: slideOutRight; + animation-name: slideOutRight; +} + +@-webkit-keyframes slideOutUp { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +@keyframes slideOutUp { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +.slideOutUp { + -webkit-animation-name: slideOutUp; + animation-name: slideOutUp; +} + +.animated { + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.animated.infinite { + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; +} + +.animated.delay-1s { + -webkit-animation-delay: 1s; + animation-delay: 1s; +} + +.animated.delay-2s { + -webkit-animation-delay: 2s; + animation-delay: 2s; +} + +.animated.delay-3s { + -webkit-animation-delay: 3s; + animation-delay: 3s; +} + +.animated.delay-4s { + -webkit-animation-delay: 4s; + animation-delay: 4s; +} + +.animated.delay-5s { + -webkit-animation-delay: 5s; + animation-delay: 5s; +} + +.animated.fast { + -webkit-animation-duration: 800ms; + animation-duration: 800ms; +} + +.animated.faster { + -webkit-animation-duration: 500ms; + animation-duration: 500ms; +} + +.animated.slow { + -webkit-animation-duration: 2s; + animation-duration: 2s; +} + +.animated.slower { + -webkit-animation-duration: 3s; + animation-duration: 3s; +} + +@media (print), (prefers-reduced-motion: reduce) { + .animated { + -webkit-animation-duration: 1ms !important; + animation-duration: 1ms !important; + -webkit-transition-duration: 1ms !important; + transition-duration: 1ms !important; + -webkit-animation-iteration-count: 1 !important; + animation-iteration-count: 1 !important; + } +} \ No newline at end of file diff --git a/front/src/components/active-plate/active-plate.vue b/front/src/components/active-plate/active-plate.vue new file mode 100644 index 00000000..237e2e05 --- /dev/null +++ b/front/src/components/active-plate/active-plate.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/front/src/components/charts/bar.vue b/front/src/components/charts/bar.vue new file mode 100644 index 00000000..49dcd500 --- /dev/null +++ b/front/src/components/charts/bar.vue @@ -0,0 +1,73 @@ + + + diff --git a/front/src/components/charts/index.js b/front/src/components/charts/index.js new file mode 100644 index 00000000..cd86f348 --- /dev/null +++ b/front/src/components/charts/index.js @@ -0,0 +1,3 @@ +import ChartPie from './pie.vue'; +import ChartBar from './bar.vue'; +export { ChartPie, ChartBar }; diff --git a/front/src/components/charts/pie.vue b/front/src/components/charts/pie.vue new file mode 100644 index 00000000..4c4ffc7d --- /dev/null +++ b/front/src/components/charts/pie.vue @@ -0,0 +1,85 @@ + + + diff --git a/front/src/components/charts/theme.json b/front/src/components/charts/theme.json new file mode 100644 index 00000000..909b518a --- /dev/null +++ b/front/src/components/charts/theme.json @@ -0,0 +1,490 @@ +{ + "color": [ + "#2d8cf0", + "#19be6b", + "#ff9900", + "#E46CBB", + "#9A66E4", + "#ed3f14" + ], + "backgroundColor": "rgba(0,0,0,0)", + "textStyle": {}, + "title": { + "textStyle": { + "color": "#516b91" + }, + "subtextStyle": { + "color": "#93b7e3" + } + }, + "line": { + "itemStyle": { + "normal": { + "borderWidth": "2" + } + }, + "lineStyle": { + "normal": { + "width": "2" + } + }, + "symbolSize": "6", + "symbol": "emptyCircle", + "smooth": true + }, + "radar": { + "itemStyle": { + "normal": { + "borderWidth": "2" + } + }, + "lineStyle": { + "normal": { + "width": "2" + } + }, + "symbolSize": "6", + "symbol": "emptyCircle", + "smooth": true + }, + "bar": { + "itemStyle": { + "normal": { + "barBorderWidth": 0, + "barBorderColor": "#ccc" + }, + "emphasis": { + "barBorderWidth": 0, + "barBorderColor": "#ccc" + } + } + }, + "pie": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "scatter": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "boxplot": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "parallel": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "sankey": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "funnel": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "gauge": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "candlestick": { + "itemStyle": { + "normal": { + "color": "#edafda", + "color0": "transparent", + "borderColor": "#d680bc", + "borderColor0": "#8fd3e8", + "borderWidth": "2" + } + } + }, + "graph": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + } + }, + "lineStyle": { + "normal": { + "width": 1, + "color": "#aaa" + } + }, + "symbolSize": "6", + "symbol": "emptyCircle", + "smooth": true, + "color": [ + "#2d8cf0", + "#19be6b", + "#f5ae4a", + "#9189d5", + "#56cae2", + "#cbb0e3" + ], + "label": { + "normal": { + "textStyle": { + "color": "#eee" + } + } + } + }, + "map": { + "itemStyle": { + "normal": { + "areaColor": "#f3f3f3", + "borderColor": "#516b91", + "borderWidth": 0.5 + }, + "emphasis": { + "areaColor": "rgba(165,231,240,1)", + "borderColor": "#516b91", + "borderWidth": 1 + } + }, + "label": { + "normal": { + "textStyle": { + "color": "#000" + } + }, + "emphasis": { + "textStyle": { + "color": "rgb(81,107,145)" + } + } + } + }, + "geo": { + "itemStyle": { + "normal": { + "areaColor": "#f3f3f3", + "borderColor": "#516b91", + "borderWidth": 0.5 + }, + "emphasis": { + "areaColor": "rgba(165,231,240,1)", + "borderColor": "#516b91", + "borderWidth": 1 + } + }, + "label": { + "normal": { + "textStyle": { + "color": "#000" + } + }, + "emphasis": { + "textStyle": { + "color": "rgb(81,107,145)" + } + } + } + }, + "categoryAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "valueAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "logAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "timeAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "toolbox": { + "iconStyle": { + "normal": { + "borderColor": "#999" + }, + "emphasis": { + "borderColor": "#666" + } + } + }, + "legend": { + "textStyle": { + "color": "#999999" + } + }, + "tooltip": { + "axisPointer": { + "lineStyle": { + "color": "#ccc", + "width": 1 + }, + "crossStyle": { + "color": "#ccc", + "width": 1 + } + } + }, + "timeline": { + "lineStyle": { + "color": "#8fd3e8", + "width": 1 + }, + "itemStyle": { + "normal": { + "color": "#8fd3e8", + "borderWidth": 1 + }, + "emphasis": { + "color": "#8fd3e8" + } + }, + "controlStyle": { + "normal": { + "color": "#8fd3e8", + "borderColor": "#8fd3e8", + "borderWidth": 0.5 + }, + "emphasis": { + "color": "#8fd3e8", + "borderColor": "#8fd3e8", + "borderWidth": 0.5 + } + }, + "checkpointStyle": { + "color": "#8fd3e8", + "borderColor": "rgba(138,124,168,0.37)" + }, + "label": { + "normal": { + "textStyle": { + "color": "#8fd3e8" + } + }, + "emphasis": { + "textStyle": { + "color": "#8fd3e8" + } + } + } + }, + "visualMap": { + "color": [ + "#516b91", + "#59c4e6", + "#a5e7f0" + ] + }, + "dataZoom": { + "backgroundColor": "rgba(0,0,0,0)", + "dataBackgroundColor": "rgba(255,255,255,0.3)", + "fillerColor": "rgba(167,183,204,0.4)", + "handleColor": "#a7b7cc", + "handleSize": "100%", + "textStyle": { + "color": "#333" + } + }, + "markPoint": { + "label": { + "normal": { + "textStyle": { + "color": "#eee" + } + }, + "emphasis": { + "textStyle": { + "color": "#eee" + } + } + } + } +} \ No newline at end of file diff --git a/front/src/components/common-icon/common-icon.vue b/front/src/components/common-icon/common-icon.vue new file mode 100644 index 00000000..03cbc0e8 --- /dev/null +++ b/front/src/components/common-icon/common-icon.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/front/src/components/common-icon/index.js b/front/src/components/common-icon/index.js new file mode 100644 index 00000000..ca1bd334 --- /dev/null +++ b/front/src/components/common-icon/index.js @@ -0,0 +1,2 @@ +import CommonIcon from './common-icon.vue'; +export default CommonIcon; diff --git a/front/src/components/count-to/count-to.vue b/front/src/components/count-to/count-to.vue new file mode 100644 index 00000000..4c8f274e --- /dev/null +++ b/front/src/components/count-to/count-to.vue @@ -0,0 +1,198 @@ + + + diff --git a/front/src/components/count-to/index.js b/front/src/components/count-to/index.js new file mode 100644 index 00000000..52c7fb88 --- /dev/null +++ b/front/src/components/count-to/index.js @@ -0,0 +1,2 @@ +import countTo from './count-to.vue'; +export default countTo; diff --git a/front/src/components/count-to/index.less b/front/src/components/count-to/index.less new file mode 100644 index 00000000..e17d7c60 --- /dev/null +++ b/front/src/components/count-to/index.less @@ -0,0 +1,10 @@ +@prefix: ~"count-to"; + +.@{prefix}-wrapper{ + .content-outer{ + display: inline-block; + .@{prefix}-unit-text{ + font-style: normal; + } + } +} diff --git a/front/src/components/editor/editor.vue b/front/src/components/editor/editor.vue new file mode 100644 index 00000000..da3123dc --- /dev/null +++ b/front/src/components/editor/editor.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/front/src/components/editor/index.js b/front/src/components/editor/index.js new file mode 100644 index 00000000..58c0cd58 --- /dev/null +++ b/front/src/components/editor/index.js @@ -0,0 +1,2 @@ +import Editor from './editor.vue'; +export default Editor; diff --git a/front/src/components/icons/icons.vue b/front/src/components/icons/icons.vue new file mode 100644 index 00000000..08112f96 --- /dev/null +++ b/front/src/components/icons/icons.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/front/src/components/icons/index.js b/front/src/components/icons/index.js new file mode 100644 index 00000000..9bce89b3 --- /dev/null +++ b/front/src/components/icons/index.js @@ -0,0 +1,2 @@ +import Icons from './icons.vue'; +export default Icons; diff --git a/front/src/components/main/components/a-back-top/index.js b/front/src/components/main/components/a-back-top/index.js new file mode 100644 index 00000000..7c87382d --- /dev/null +++ b/front/src/components/main/components/a-back-top/index.js @@ -0,0 +1,2 @@ +import ABackTop from './index.vue'; +export default ABackTop; diff --git a/front/src/components/main/components/a-back-top/index.vue b/front/src/components/main/components/a-back-top/index.vue new file mode 100644 index 00000000..e13c5621 --- /dev/null +++ b/front/src/components/main/components/a-back-top/index.vue @@ -0,0 +1,130 @@ + + diff --git a/front/src/components/main/components/fullscreen/fullscreen.vue b/front/src/components/main/components/fullscreen/fullscreen.vue new file mode 100644 index 00000000..b5fb231c --- /dev/null +++ b/front/src/components/main/components/fullscreen/fullscreen.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/front/src/components/main/components/fullscreen/index.js b/front/src/components/main/components/fullscreen/index.js new file mode 100644 index 00000000..45c287e9 --- /dev/null +++ b/front/src/components/main/components/fullscreen/index.js @@ -0,0 +1,2 @@ +import Fullscreen from './fullscreen.vue'; +export default Fullscreen; diff --git a/front/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less b/front/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less new file mode 100644 index 00000000..1ace1eb8 --- /dev/null +++ b/front/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less @@ -0,0 +1,4 @@ +.custom-bread-crumb{ + display: inline-block; + vertical-align: top; +} diff --git a/front/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue b/front/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue new file mode 100644 index 00000000..63bd2281 --- /dev/null +++ b/front/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue @@ -0,0 +1,44 @@ + + diff --git a/front/src/components/main/components/header-bar/custom-bread-crumb/index.js b/front/src/components/main/components/header-bar/custom-bread-crumb/index.js new file mode 100644 index 00000000..a360517d --- /dev/null +++ b/front/src/components/main/components/header-bar/custom-bread-crumb/index.js @@ -0,0 +1,2 @@ +import customBreadCrumb from './custom-bread-crumb.vue'; +export default customBreadCrumb; diff --git a/front/src/components/main/components/header-bar/header-bar.less b/front/src/components/main/components/header-bar/header-bar.less new file mode 100644 index 00000000..17077577 --- /dev/null +++ b/front/src/components/main/components/header-bar/header-bar.less @@ -0,0 +1,14 @@ +.header-bar{ + width: 100%; + height: 100%; + position: relative; + .custom-content-con{ + float: right; + height: auto; + padding-right: 20px; + // line-height: 64px; + & > *{ + float: right; + } + } +} diff --git a/front/src/components/main/components/header-bar/header-bar.vue b/front/src/components/main/components/header-bar/header-bar.vue new file mode 100644 index 00000000..1b9d41f5 --- /dev/null +++ b/front/src/components/main/components/header-bar/header-bar.vue @@ -0,0 +1,39 @@ + + diff --git a/front/src/components/main/components/header-bar/index.js b/front/src/components/main/components/header-bar/index.js new file mode 100644 index 00000000..7559bb43 --- /dev/null +++ b/front/src/components/main/components/header-bar/index.js @@ -0,0 +1,2 @@ +import HeaderBar from './header-bar'; +export default HeaderBar; diff --git a/front/src/components/main/components/header-bar/sider-trigger/index.js b/front/src/components/main/components/header-bar/sider-trigger/index.js new file mode 100644 index 00000000..e474a26d --- /dev/null +++ b/front/src/components/main/components/header-bar/sider-trigger/index.js @@ -0,0 +1,2 @@ +import siderTrigger from './sider-trigger.vue'; +export default siderTrigger; diff --git a/front/src/components/main/components/header-bar/sider-trigger/sider-trigger.less b/front/src/components/main/components/header-bar/sider-trigger/sider-trigger.less new file mode 100644 index 00000000..bb852980 --- /dev/null +++ b/front/src/components/main/components/header-bar/sider-trigger/sider-trigger.less @@ -0,0 +1,21 @@ +.trans{ + transition: transform .2s ease; +} +@size: 40px; +.sider-trigger-a{ + padding: 6px; + width: @size; + height: @size; + display: inline-block; + text-align: center; + color: #5c6b77; + margin-top: 10px; + i{ + .trans; + vertical-align: top; + } + &.collapsed i{ + transform: rotateZ(180deg); + .trans; + } +} diff --git a/front/src/components/main/components/header-bar/sider-trigger/sider-trigger.vue b/front/src/components/main/components/header-bar/sider-trigger/sider-trigger.vue new file mode 100644 index 00000000..71971884 --- /dev/null +++ b/front/src/components/main/components/header-bar/sider-trigger/sider-trigger.vue @@ -0,0 +1,35 @@ + + + diff --git a/front/src/components/main/components/language/index.js b/front/src/components/main/components/language/index.js new file mode 100644 index 00000000..74d5e61b --- /dev/null +++ b/front/src/components/main/components/language/index.js @@ -0,0 +1,2 @@ +import Language from './language.vue'; +export default Language; diff --git a/front/src/components/main/components/language/language.vue b/front/src/components/main/components/language/language.vue new file mode 100644 index 00000000..29a8cbb0 --- /dev/null +++ b/front/src/components/main/components/language/language.vue @@ -0,0 +1,54 @@ + + + diff --git a/front/src/components/main/components/notice/notice.vue b/front/src/components/main/components/notice/notice.vue new file mode 100644 index 00000000..337d09ae --- /dev/null +++ b/front/src/components/main/components/notice/notice.vue @@ -0,0 +1,371 @@ + + + + + diff --git a/front/src/components/main/components/side-menu/collapsed-menu.vue b/front/src/components/main/components/side-menu/collapsed-menu.vue new file mode 100644 index 00000000..6011e12b --- /dev/null +++ b/front/src/components/main/components/side-menu/collapsed-menu.vue @@ -0,0 +1,84 @@ + + diff --git a/front/src/components/main/components/side-menu/index.js b/front/src/components/main/components/side-menu/index.js new file mode 100644 index 00000000..4a51d599 --- /dev/null +++ b/front/src/components/main/components/side-menu/index.js @@ -0,0 +1,2 @@ +import SideMenu from './side-menu.vue'; +export default SideMenu; diff --git a/front/src/components/main/components/side-menu/item-mixin.js b/front/src/components/main/components/side-menu/item-mixin.js new file mode 100644 index 00000000..921342fe --- /dev/null +++ b/front/src/components/main/components/side-menu/item-mixin.js @@ -0,0 +1,30 @@ +export default { + props: { + // 父文件 + parentItem: { + type: Object, + default: () => { } + }, + // 主题 + theme: { + type: String, + require: false + }, + // 图标尺寸 + iconSize: { + type: Number, + require: false + } + }, + computed: { + parentName () { + return this.parentItem.name; + }, + children () { + return this.parentItem.children; + }, + textColor () { + return this.theme === 'dark' ? '#fff' : '#495060'; + } + } +}; diff --git a/front/src/components/main/components/side-menu/mixin.js b/front/src/components/main/components/side-menu/mixin.js new file mode 100644 index 00000000..5650c5ee --- /dev/null +++ b/front/src/components/main/components/side-menu/mixin.js @@ -0,0 +1,18 @@ +import CommonIcon from '_c/common-icon'; +import { showTitle } from '@/lib/menu-func'; +export default { + components: { + CommonIcon + }, + methods: { + showTitle (item) { + return showTitle(item, this); + }, + showChildren (item) { + return item.children && (item.children.length > 1 || (item.meta && item.meta.showAlways)); + }, + getNameOrHref (item, children0) { + return item.href ? `isTurnByHref_${item.href}` : (children0 ? item.children[0].name : item.name); + } + } +}; diff --git a/front/src/components/main/components/side-menu/side-menu-item.vue b/front/src/components/main/components/side-menu/side-menu-item.vue new file mode 100644 index 00000000..d236b7a5 --- /dev/null +++ b/front/src/components/main/components/side-menu/side-menu-item.vue @@ -0,0 +1,35 @@ + + diff --git a/front/src/components/main/components/side-menu/side-menu.less b/front/src/components/main/components/side-menu/side-menu.less new file mode 100644 index 00000000..e50fae79 --- /dev/null +++ b/front/src/components/main/components/side-menu/side-menu.less @@ -0,0 +1,39 @@ +.side-menu-wrapper{ + user-select: none; + .menu-collapsed{ + padding-top: 10px; + + .ivu-dropdown{ + .ivu-dropdown-rel a{ + width: 100%; + } + } + .ivu-tooltip{ + width: 100%; + .ivu-tooltip-rel{ + width: 100%; + } + .ivu-tooltip-popper .ivu-tooltip-content{ + .ivu-tooltip-arrow{ + border-right-color: #fff; + } + .ivu-tooltip-inner{ + background: #fff; + color: #495060; + } + } + } + + + } + a.drop-menu-a{ + display: inline-block; + padding: 6px 15px; + width: 100%; + text-align: center; + color: #495060; + } +} +.menu-title{ + padding-left: 6px; +} diff --git a/front/src/components/main/components/side-menu/side-menu.vue b/front/src/components/main/components/side-menu/side-menu.vue new file mode 100644 index 00000000..6bae34c6 --- /dev/null +++ b/front/src/components/main/components/side-menu/side-menu.vue @@ -0,0 +1,187 @@ + + + diff --git a/front/src/components/main/components/tags-nav/index.js b/front/src/components/main/components/tags-nav/index.js new file mode 100644 index 00000000..56d2f1c2 --- /dev/null +++ b/front/src/components/main/components/tags-nav/index.js @@ -0,0 +1,2 @@ +import TagsNav from './tags-nav.vue'; +export default TagsNav; diff --git a/front/src/components/main/components/tags-nav/tags-nav.less b/front/src/components/main/components/tags-nav/tags-nav.less new file mode 100644 index 00000000..ddb05134 --- /dev/null +++ b/front/src/components/main/components/tags-nav/tags-nav.less @@ -0,0 +1,136 @@ +.no-select{ + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.size{ + height: 100%; +} +.tags-nav{ + position: relative; + margin:0 auto; + // border-top: 1px solid #F0F0F0; + // border-bottom: 1px solid #F0F0F0; + background: #f4f6f8; + padding:0 20px; + + .no-select; + .size; + .close-con{ + position: absolute; + right: 0; + top: 5px; + height: 30px; + width: 42px; + background: #f3f5f7; + text-align: center; + z-index: 10; + margin-top:5px; + + border-top: 1px solid #F5F7FC; + border-bottom: 1px solid #F5F7FC; + i{ + color:#666666; + } + button{ + margin-top:3px; + + } + } + .btn-con{ + margin-top:10px; + position: absolute; + top: 0px; + height: 30px; + line-height: 30px; + // padding:0 10px; + background: #f3f5f7; + z-index: 10; + + button{ + position: relative; + top:-1px; + line-height: 14px; + text-align: center; + color:#666666; + + } + &.left-btn{ + left: 0px; + border: 1px solid #F5F7FC; + } + &.right-btn{ + right: 42px; + border: 1px solid #F5F7FC; + } + } + .scroll-outer{ + position: absolute; + left: 52px; + right: 61px; + top: 0; + bottom: 0; + padding:10px 0; + .scroll-body{ + display: inline-block; + position: absolute; + box-shadow: border-box; + overflow: visible; + white-space: nowrap; + transition: left .3s ease; + .ivu-tag{ + height:34px; + margin:0; + } + .ivu-tag{ + // min-width:10px; + height:30px; + line-height: 30px; + border-radius: 3px; + padding:0 10px; + background: #fff!important; + border:none; + text-align: center; + color:#1C2B36; + font-size: 14px; + margin:0 5px; + span{ + color:#1C2B36!important; + padding:0 5px; + } + i{ + color:#1C2B36!important; + font-size: 4px; + } + } + .ivu-tag-primary{ + transition: background .2s ease; + background: #2D8CF0!important; + span,i{ + color:#fff!important; + } + } + } + } + .contextmenu { + position: absolute; + margin: 0; + padding: 5px 0; + background: #fff; + z-index: 1000; + list-style-type: none; + border-radius: 3px; + box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .1); + li { + margin: 0; + padding: 5px 15px; + cursor: pointer; + &:hover { + background: #eee; + } + } + } +} diff --git a/front/src/components/main/components/tags-nav/tags-nav.vue b/front/src/components/main/components/tags-nav/tags-nav.vue new file mode 100644 index 00000000..00909fa0 --- /dev/null +++ b/front/src/components/main/components/tags-nav/tags-nav.vue @@ -0,0 +1,256 @@ + + + + + diff --git a/front/src/components/main/components/user/index.js b/front/src/components/main/components/user/index.js new file mode 100644 index 00000000..54d7ca0b --- /dev/null +++ b/front/src/components/main/components/user/index.js @@ -0,0 +1,2 @@ +import User from './user.vue'; +export default User; diff --git a/front/src/components/main/components/user/user.less b/front/src/components/main/components/user/user.less new file mode 100644 index 00000000..9c5eeba7 --- /dev/null +++ b/front/src/components/main/components/user/user.less @@ -0,0 +1,25 @@ +.user-avatar-dropdown{ + padding-left:20px; + color:#909ca4; + .dropdown-arrows{ + margin:0 10px; + } + .head{ + position: relative; + top:-2px; + } +} +.user{ + + &-avatar-dropdown{ + cursor: pointer; + display: inline-block; + // height: 64px; + vertical-align: middle; + // line-height: 64px; + .ivu-badge-dot{ + top: 16px; + } + } + +} diff --git a/front/src/components/main/components/user/user.vue b/front/src/components/main/components/user/user.vue new file mode 100644 index 00000000..d7f0324a --- /dev/null +++ b/front/src/components/main/components/user/user.vue @@ -0,0 +1,131 @@ + + + + diff --git a/front/src/components/main/index.js b/front/src/components/main/index.js new file mode 100644 index 00000000..87be9ddf --- /dev/null +++ b/front/src/components/main/index.js @@ -0,0 +1,2 @@ +import Main from './main.vue'; +export default Main; diff --git a/front/src/components/main/main.less b/front/src/components/main/main.less new file mode 100644 index 00000000..7a6d4c83 --- /dev/null +++ b/front/src/components/main/main.less @@ -0,0 +1,129 @@ +//滚动条样式 +.scrollbar(@width: 2px){ + &::-webkit-scrollbar { width: @width; height: 8px; } + &::-webkit-scrollbar-thumb { border-radius: 5px; -webkit-box-shadow: inset 0 0 5px rgb(185, 185, 185); background: #c7c5c8; } + &::-webkit-scrollbar-track { border-radius: 0; background: #ddd; } +} +.no-scrollbar{ + &::-webkit-scrollbar {display:none} +} +.main{ + .scrollbar, + .ivu-table-overflowX, + .content-wrapper, + .w-e-text{ + .scrollbar; + } + iframe body{ + .scrollbar; + } + .logo-con{ + padding: 19px 0 15px 20px; + &.collapsed{ + padding: 19px 0 15px; + text-align: center; + } + } + .menu-dropdown{ + margin-left: 200px; + } + .search-bar{ + padding:0 20px; + margin-bottom: 20px; + &.collapsed{ + padding:0 12px; + i{ + width: 40px; + + } + } + input{ + width: 100%; + height:36px; + background: #152a3a; + color:#44505c; + font-size: 14px; + outline: none; + + &::placeholder{ + color:#44505c; + } + &:focus{ + border:none; + outline: none; + background: #fff; + } + border:none; + } + i{ + line-height: 36px; + color:#44505c; + } + } + .header-con{ + background: #fff; + padding: 0 10px; + width: 100%; + } + .main-layout-con{ + height: 100%; + overflow: hidden; + } + .main-content-con{ + height: ~"calc(100% - 60px)"; + overflow: hidden; + } + .tag-nav-wrapper{ + padding: 0; + height:50px; + // background:#F0F0F0; + } + .content-wrapper{ + padding: 0 18px 18px; + height: ~"calc(100% - 80px)"; + overflow: auto; + } + .left-sider{ + .ivu-layout-sider-children{ + overflow-y: scroll; + margin-right: -18px; + } + } +} +.ivu-menu-light.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu):after{ + right: inherit; left: 0; +} +.ivu-menu-item > i{ + margin-right: 12px !important; +} +.ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i { + margin-right: 8px !important; +} +.collased-menu-dropdown{ + width: 100%; + margin: 0; + line-height: normal; + padding: 7px 0 6px 16px; + clear: both; + font-size: 12px !important; + white-space: nowrap; + list-style: none; + cursor: pointer; + transition: background 0.2s ease-in-out; + &:hover{ + background: rgba(100, 100, 100, 0.1); + } + & * { + color: #515a6e; + } + .ivu-menu-item > i{ + margin-right: 12px !important; + } + .ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i { + margin-right: 8px !important; + } +} + +.ivu-select-dropdown.ivu-dropdown-transfer{ + max-height: 400px; +} diff --git a/front/src/components/main/main.vue b/front/src/components/main/main.vue new file mode 100644 index 00000000..5004c1b1 --- /dev/null +++ b/front/src/components/main/main.vue @@ -0,0 +1,443 @@ + + + diff --git a/front/src/components/tables/edit.vue b/front/src/components/tables/edit.vue new file mode 100644 index 00000000..55c142ac --- /dev/null +++ b/front/src/components/tables/edit.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/front/src/components/tables/handle-btns.js b/front/src/components/tables/handle-btns.js new file mode 100644 index 00000000..7254b3e1 --- /dev/null +++ b/front/src/components/tables/handle-btns.js @@ -0,0 +1,70 @@ +// 验证 +const validate = { + operation: (params) => { + if (params.operation === 0) { + return false; + } + return true; + }, + audit: (params) => { + if (params.audit === 0) { + return false; + } + return true; + } +}; +const btns = { + // 删除:需要判定 + delete: (h, params, vm) => { + let disabledFlag = false; + return h('Tooltip', { + props: { + content: '删除', + placement: 'top', + transfer: true + } + }, [h('Button', { + props: { + type: 'error', + size: 'small', + icon: 'md-trash', + disabled: disabledFlag + }, + style: { + marginRight: '5px' + }, + on: { + click: () => { + vm.$emit('on-delete', params); + } + } + })]); + }, + edit: (h, params, vm) => { + let disabledFlag = false; + return h('Tooltip', { + props: { + content: '编辑', + placement: 'top', + transfer: true + } + }, [h('Button', { + props: { + type: 'primary', + size: 'small', + icon: 'md-trash', + disabled: disabledFlag + }, + style: { + marginRight: '5px' + }, + on: { + click: () => { + vm.$emit('on-edit', params); + } + } + })]); + } +}; + +export default btns; diff --git a/front/src/components/tables/index.js b/front/src/components/tables/index.js new file mode 100644 index 00000000..899190c0 --- /dev/null +++ b/front/src/components/tables/index.js @@ -0,0 +1,2 @@ +import Tables from './tables.vue'; +export default Tables; diff --git a/front/src/components/tables/index.less b/front/src/components/tables/index.less new file mode 100644 index 00000000..3c352e11 --- /dev/null +++ b/front/src/components/tables/index.less @@ -0,0 +1,17 @@ +.search-con{ + padding: 10px 0; + .search{ + &-col{ + display: inline-block; + width: 200px; + } + &-input{ + display: inline-block; + width: 200px; + margin-left: 2px; + } + &-btn{ + margin-left: 2px; + } + } +} diff --git a/front/src/components/tables/tables.vue b/front/src/components/tables/tables.vue new file mode 100644 index 00000000..0c2329b4 --- /dev/null +++ b/front/src/components/tables/tables.vue @@ -0,0 +1,342 @@ + + + diff --git a/front/src/config/index.js b/front/src/config/index.js new file mode 100644 index 00000000..a80b6815 --- /dev/null +++ b/front/src/config/index.js @@ -0,0 +1,38 @@ +console.log('api url : ', process.env.VUE_APP_URL); +console.log('websocket url : ', process.env.VUE_APP_SOCKET_URL); +export default { + /** + * @description 配置显示在浏览器标签的title + */ + title: 'Smart-Admin', + /** + * @description token在Cookie中存储的天数,默认1天 + */ + cookieExpires: 3, + /** + * @description 是否使用国际化,默认为false + * 如果不使用,则需要在路由中给需要在菜单中展示的路由设置meta: {title: 'xxx'} + * 用来在菜单中显示文字 + */ + useI18n: false, + /** + * @description api请求基础路径 + */ + baseUrl: { + apiUrl: process.env.VUE_APP_URL, + webSocketUrl: process.env.VUE_APP_SOCKET_URL + }, + /** + * @description 默认打开的首页的路由name值,默认为home + */ + homeName: 'Home', + /** + * @description 需要加载的插件 + */ + plugin: { + 'error-store': { + showInHeader: true, // 设为false后不会在顶部显示错误日志徽标 + developmentOff: true // 设为true后在开发环境不会收集错误信息,方便开发中排查错误 + } + } +}; diff --git a/front/src/constants/file.js b/front/src/constants/file.js new file mode 100644 index 00000000..6a205f55 --- /dev/null +++ b/front/src/constants/file.js @@ -0,0 +1,24 @@ +export const FILE_TYPE = { + LOCAL: { + value: 1, + desc: '本地文件服务' + }, + ALI_OSS: { + value: 2, + desc: '阿里OSS文件服务' + }, + QI_NIU_OSS: { + value: 3, + desc: '七牛文件服务' + } +}; +export const SERVICE_TYPE = { + BACK_USER: { + value: '1', + desc: '用户后台' + } +}; +export default { + FILE_TYPE, + SERVICE_TYPE +}; diff --git a/front/src/constants/index.js b/front/src/constants/index.js new file mode 100644 index 00000000..55101226 --- /dev/null +++ b/front/src/constants/index.js @@ -0,0 +1,10 @@ +import notice from './notice.js'; +import login from './login.js'; +import file from './file.js'; +import privilege from './privilege'; +export default { + ...notice, + ...login, + ...file, + ...privilege +}; diff --git a/front/src/constants/login.js b/front/src/constants/login.js new file mode 100644 index 00000000..fb28973b --- /dev/null +++ b/front/src/constants/login.js @@ -0,0 +1,13 @@ +export const PRIVILEGE_TYPE = { + MENU: { + value: 1, + desc: '是' + }, + POINTS: { + value: 2, + desc: '否' + } +}; +export default { + PRIVILEGE_TYPE +}; diff --git a/front/src/constants/notice.js b/front/src/constants/notice.js new file mode 100644 index 00000000..0d5315fa --- /dev/null +++ b/front/src/constants/notice.js @@ -0,0 +1,13 @@ +export const NOTICE_STATUS = { + YES: { + value: 1, + desc: '是' + }, + NO: { + value: 0, + desc: '否' + } +}; +export default { + NOTICE_STATUS +}; diff --git a/front/src/constants/privilege.js b/front/src/constants/privilege.js new file mode 100644 index 00000000..885e86d6 --- /dev/null +++ b/front/src/constants/privilege.js @@ -0,0 +1,14 @@ +export const PRIVILEGE_TYPE_ENUM = { + MENU: { + value: 1, + desc: '菜单' + }, + POINTS: { + value: 2, + desc: '功能点' + } +}; + +export default { + PRIVILEGE_TYPE_ENUM +}; diff --git a/front/src/directives/directives.js b/front/src/directives/directives.js new file mode 100644 index 00000000..701eec5d --- /dev/null +++ b/front/src/directives/directives.js @@ -0,0 +1,11 @@ +import draggable from './module/draggable'; +import clipboard from './module/clipboard'; +import privilege from './module/privilege'; + +const directives = { + draggable, + clipboard, + privilege +}; + +export default directives; diff --git a/front/src/directives/index.js b/front/src/directives/index.js new file mode 100644 index 00000000..dcc9ffb3 --- /dev/null +++ b/front/src/directives/index.js @@ -0,0 +1,31 @@ +import directive from './directives'; + +const importDirective = Vue => { + /** + * 拖拽指令 v-draggable="options" + * options = { + * trigger: /这里传入作为拖拽触发器的CSS选择器/, + * body: /这里传入需要移动容器的CSS选择器/, + * recover: /拖动结束之后是否恢复到原来的位置/ + * } + */ + Vue.directive('draggable', directive.draggable); + /** + * clipboard指令 v-draggable="options" + * options = { + * value: /在输入框中使用v-model绑定的值/, + * success: /复制成功后的回调/, + * error: /复制失败后的回调/ + * } + */ + Vue.directive('clipboard', directive.clipboard); + /** + * privilege指令 v-privilege="options" + * options = { + * value: /当前按钮的唯一权限识别/, + * } + */ + Vue.directive('privilege', directive.privilege); +}; + +export default importDirective; diff --git a/front/src/directives/module/clipboard.js b/front/src/directives/module/clipboard.js new file mode 100644 index 00000000..0684eb61 --- /dev/null +++ b/front/src/directives/module/clipboard.js @@ -0,0 +1,30 @@ +import Clipboard from 'clipboard'; +export default { + bind: (el, binding) => { + const clipboard = new Clipboard(el, { + text: () => binding.value.value + }); + el.__success_callback__ = binding.value.success; + el.__error_callback__ = binding.value.error; + clipboard.on('success', e => { + const callback = el.__success_callback__; + callback && callback(e); + }); + clipboard.on('error', e => { + const callback = el.__error_callback__; + callback && callback(e); + }); + el.__clipboard__ = clipboard; + }, + update: (el, binding) => { + el.__clipboard__.text = () => binding.value.value; + el.__success_callback__ = binding.value.success; + el.__error_callback__ = binding.value.error; + }, + unbind: (el, binding) => { + delete el.__success_callback__; + delete el.__error_callback__; + el.__clipboard__.destroy(); + delete el.__clipboard__; + } +}; diff --git a/front/src/directives/module/draggable.js b/front/src/directives/module/draggable.js new file mode 100644 index 00000000..8bf798b3 --- /dev/null +++ b/front/src/directives/module/draggable.js @@ -0,0 +1,42 @@ +import { on } from '@/lib/util'; +export default { + inserted: (el, binding, vnode) => { + let triggerDom = document.querySelector(binding.value.trigger); + triggerDom.style.cursor = 'move'; + let bodyDom = document.querySelector(binding.value.body); + let pageX = 0; + let pageY = 0; + let transformX = 0; + let transformY = 0; + let canMove = false; + const handleMousedown = e => { + let transform = /\(.*\)/.exec(bodyDom.style.transform); + if (transform) { + transform = transform[0].slice(1, transform[0].length - 1); + let splitxy = transform.split('px, '); + transformX = parseFloat(splitxy[0]); + transformY = parseFloat(splitxy[1].split('px')[0]); + } + pageX = e.pageX; + pageY = e.pageY; + canMove = true; + }; + const handleMousemove = e => { + let xOffset = e.pageX - pageX + transformX; + let yOffset = e.pageY - pageY + transformY; + if (canMove) + {bodyDom.style.transform = `translate(${xOffset}px, ${yOffset}px)`;} + }; + const handleMouseup = e => { + canMove = false; + }; + on(triggerDom, 'mousedown', handleMousedown); + on(document, 'mousemove', handleMousemove); + on(document, 'mouseup', handleMouseup); + }, + update: (el, binding, vnode) => { + if (!binding.value.recover) return; + let bodyDom = document.querySelector(binding.value.body); + bodyDom.style.transform = ''; + } +}; diff --git a/front/src/directives/module/privilege.js b/front/src/directives/module/privilege.js new file mode 100644 index 00000000..ecfaf7e1 --- /dev/null +++ b/front/src/directives/module/privilege.js @@ -0,0 +1,23 @@ +// 页面内按钮过滤 +import store from '@/store/index'; +export default { + inserted: function (el, binding, vnode) { + // 获取当前路由name + // 如果页面为同一模块下的子页面则取最上级权限 + let routeName = vnode.context.$route.meta.group + ? vnode.context.$route.meta.group + : vnode.context.$route.name; + // 超级管理员 + if (store.state.user.userLoginInfo.isSuperMan) { + return true; + } + // 获取功能点权限 + let functionList = store.state.user.privilegeFunctionPointsMap.get(routeName); + // 有权限 + if (functionList && functionList.includes(binding.value)) { + + } else { + el.parentNode.removeChild(el); + } + } +}; diff --git a/front/src/filters/index.js b/front/src/filters/index.js new file mode 100644 index 00000000..e69de29b diff --git a/front/src/lib/cookie.js b/front/src/lib/cookie.js new file mode 100644 index 00000000..83386119 --- /dev/null +++ b/front/src/lib/cookie.js @@ -0,0 +1,21 @@ +import Cookies from 'js-cookie'; +import config from '@/config'; +const { cookieExpires } = config; +export const TOKEN_KEY = 'token'; + +export default { + setToken: token => { + Cookies.set(TOKEN_KEY, token, { + // token在Cookie中存储的天数,默认1天 + expires: cookieExpires || 7 + }); + }, + getToken: () => { + const token = Cookies.get(TOKEN_KEY); + if (token) return token; + else return null; + }, + clearToken: () => { + Cookies.remove(TOKEN_KEY); + } +}; diff --git a/front/src/lib/http.js b/front/src/lib/http.js new file mode 100644 index 00000000..12a7b39d --- /dev/null +++ b/front/src/lib/http.js @@ -0,0 +1,91 @@ +import Axios from 'axios'; +import config from '@/config'; +import { Message, Spin } from 'iview'; +import cookie from '@/lib/cookie'; +// 之所以封装这个axios,是因为在一些请求中,无法上传信息,很尴尬,估计原因是继承的有问题,无法携带headers +export const baseUrl = config.baseUrl.apiUrl; +export const socketBaseUrl = config.baseUrl.webSocketUrl; + +let axios = Axios.create({ + baseURL: baseUrl, + timeout: 30000, + headers: { + 'Content-Type': 'application/json; charset=utf-8' + } +}); +// 添加请求拦截器 + +// download url +const downloadUrl = url => { + let iframe = document.createElement('iframe'); + iframe.style.display = 'none'; + iframe.src = url; + iframe.onload = function () { + document.body.removeChild(iframe); + }; + document.body.appendChild(iframe); +}; + +axios.interceptors.request.use( + function (config) { + // 在发送请求之前做些什么 + if (cookie.getToken()) { + config.headers['x-access-token'] = cookie.getToken(); + } + return config; + }, + function (error) { + // 对请求错误做些什么 + Spin.hide(); + return Promise.reject(error); + } +); +// 添加响应拦截器 +axios.interceptors.response.use( + res => { + // 处理请求是下载的接口 + if ( + res.headers && + (res.headers['content-type'] === 'application/x-msdownload' || + res.headers['content-type'] === + 'application/octet-stream;charset=utf-8') + ) { + downloadUrl(res.request.responseURL); + res.data = ''; + res.headers['content-type'] = 'text/json'; + return res; + } + let { data } = res; + if (data.code !== 1) { + if (data.code === 1001) { + cookie.clearToken(); + localStorage.clear(); + window.location.href = window.location.pathname + '#/login'; + Message.error('未登录,或登录失效,请登录'); + } else if (data.code === 502) { + window.location.href = window.location.pathname + '#/500'; + } else { + Message.error(data.msg); + } + Spin.hide(); + return Promise.reject(res); + } + return data; + }, + error => { + Spin.hide(); + Message.error('服务内部错误'); + console.log('1111', error); + // 对响应错误做点什么 + return Promise.reject(error); + } +); + +export const postAxios = (url, data) => { + return axios.post(url, data); +}; +export const getAxios = (url, data) => { + return axios.get(url, { + params: data + }); +}; diff --git a/front/src/lib/local.js b/front/src/lib/local.js new file mode 100644 index 00000000..c19d7e3d --- /dev/null +++ b/front/src/lib/local.js @@ -0,0 +1,8 @@ +export const localSave = (key, value) => { + localStorage.setItem(key, value); +}; + +export const localRead = key => { + return localStorage.getItem(key) || ''; +}; + diff --git a/front/src/lib/menu-func.js b/front/src/lib/menu-func.js new file mode 100644 index 00000000..70a94ff9 --- /dev/null +++ b/front/src/lib/menu-func.js @@ -0,0 +1,306 @@ +import { forEach, hasOneOf, objEqual } from '@/lib/util'; +import config from '@/config'; +import { localRead, localSave } from '@/lib/local'; +const { title, useI18n } = config; +export const hasChild = item => { + return item.children && item.children.length !== 0; +}; +const showThisMenuEle = (item, access) => { + if (item.meta && item.meta.access && item.meta.access.length) { + if (hasOneOf(item.meta.access, access)) return true; + else return false; + } else return true; +}; +/** + * @param {Array} list 通过路由列表得到菜单列表 + * @returns {Array} + */ +export const getMenuByRouter = (list, access) => { + let res = []; + forEach(list, item => { + if (!item.meta || (item.meta && !item.meta.hideInMenu)) { + let obj = { + icon: (item.meta && item.meta.icon) || '', + name: item.name, + meta: item.meta + }; + if ( + (hasChild(item) || (item.meta && item.meta.showAlways)) && + showThisMenuEle(item, access) + ) { + obj.children = getMenuByRouter(item.children, access); + } + if (item.meta && item.meta.href) obj.href = item.meta.href; + if (showThisMenuEle(item, access)) res.push(obj); + } + }); + return res; +}; +/** + * 通过权限过滤菜单 + * @param {Object} map 权限对象 + * @param {Array} menuList 菜单列表 + * @returns {Array} + */ +export const getShowMenu = (map = {}, menuList, access = false) => { + // 判断是否为超级管理员 + if (access) { + return menuList; + } + // 返回的菜单列表 + let result = []; + for (let menuItem of menuList) { + let routerObj = JSON.parse(JSON.stringify(menuItem)); + if ( + map.hasOwnProperty(menuItem.name) && + (menuItem.name !== 'home' && menuItem.name !== '_home') + ) { + // 判断该菜单权限下是否为数组,若为数组,则为功能点权限否则为子菜单 + if (getType(map[routerObj.name]) === 'array') { + let funcPrivilege = localRead('funcPrivilegeInfo') + ? JSON.parse(localRead('funcPrivilegeInfo')) + : {}; + localSave( + 'funcPrivilegeInfo', + JSON.stringify({ + ...funcPrivilege, + [routerObj.name]: map[routerObj.name] + }) + ); + } else if ( + getType(map[routerObj.name]) !== 'array' && + !routerObj.children + ) { + // 判断是否为二级菜单,若是则需要多枚举一层赋值 + let funcPrivilege = localRead('funcPrivilegeInfo') + ? JSON.parse(localRead('funcPrivilegeInfo')) + : {}; + localSave( + 'funcPrivilegeInfo', + JSON.stringify({ + ...funcPrivilege, + [routerObj.name]: map[routerObj.name][routerObj.name] + }) + ); + } else if ( + getType(map[routerObj.name]) !== 'array' && + routerObj.children + ) { + // 循环子菜单权限 + routerObj.children = getShowMenu( + map[routerObj.name], + routerObj.children + ); + } + result.push(routerObj); + } + } + return result; +}; +// 获取数据类型 +export const getType = obj => { + return {}.toString + .call(obj) + .match(/\s([a-zA-Z]+)/)[1] + .toLowerCase(); +}; + +/** + * @description 本地存储和获取标签导航列表 + */ +export const setTagNavListInLocalStorage = list => { + localStorage.tagNaveList = JSON.stringify(list); +}; +/** + * @returns {Array} 其中的每个元素只包含路由原信息中的name, path, meta三项 + */ +export const getTagNavListFromLocalStorage = () => { + const list = localStorage.tagNaveList; + return list ? JSON.parse(list) : []; +}; +export const getBreadCrumbList = (route, homeRoute) => { + let homeItem = { + ...homeRoute, + icon: homeRoute.meta.icon + }; + let routeMatched = route.matched; + if (routeMatched.some(item => item.name === homeRoute.name)) { + return [homeItem]; + } + let res = routeMatched + .filter(item => { + return item.meta === undefined || !item.meta.hideInBread; + }) + .map(item => { + let meta = { + ...item.meta + }; + if (meta.title && typeof meta.title === 'function') { + meta.__titleIsFunction__ = true; + meta.title = meta.title(route); + } + let obj = { + icon: (item.meta && item.meta.icon) || '', + name: item.name, + meta: meta + }; + return obj; + }); + res = res.filter(item => { + return !item.meta.hideInMenu; + }); + return [...res]; +}; +/** + * @param {Array} routers 路由列表数组 + * @description 用于找到路由列表中name为home的对象 + */ +export const getHomeRoute = (routers, homeName = 'Home') => { + let i = -1; + let len = routers.length; + let homeRoute = {}; + while (++i < len) { + let item = routers[i]; + if (item.children && item.children.length) { + let res = getHomeRoute(item.children, homeName); + if (res.name) return res; + } else { + if (item.name === homeName) homeRoute = item; + } + } + return homeRoute; +}; +/** + * @param {Array} list 标签列表 + * @param {String} name 当前关闭的标签的name + */ +export const getNextRoute = (list, route) => { + let res = {}; + if (list.length === 2) { + res = getHomeRoute(list); + } else { + const index = list.findIndex(item => routeEqual(item, route)); + if (index === list.length - 1) res = list[list.length - 2]; + else res = list[index + 1]; + } + return res; +}; + +/** + * 判断打开的标签列表里是否已存在这个新添加的路由对象 + */ +export const routeHasExist = (tagNavList, routeItem) => { + let len = tagNavList.length; + let res = false; + doCustomTimes(len, index => { + if (routeEqual(tagNavList[index], routeItem)) res = true; + }); + return res; +}; +/** + * @param {*} list 现有标签导航列表 + * @param {*} newRoute 新添加的路由原信息对象 + * @description 如果该newRoute已经存在则不再添加 + */ +export const getNewTagList = (list, newRoute) => { + const { name, path, meta, query } = newRoute; + let newList = [...list]; + let index = newList.findIndex(item => item.name === name); + if (index >= 0) { + newList[index] = { name, path, meta, query }; + } else newList.push({ name, path, meta, query }); + return newList; +}; +export const routeEqual = (route1, route2) => { + return route1.name === route2.name; +}; +export const getRouteTitleHandled = route => { + let router = { + ...route + }; + let meta = { + ...route.meta + }; + let title = ''; + if (meta.title) { + if (typeof meta.title === 'function') { + meta.__titleIsFunction__ = true; + title = meta.title(router); + } else title = meta.title; + } + meta.title = title; + router.meta = meta; + return router; +}; +/** + * @param {Number} times 回调函数需要执行的次数 + * @param {Function} callback 回调函数 + */ +export const doCustomTimes = (times, callback) => { + let i = -1; + while (++i < times) { + callback(i); + } +}; +export const showTitle = (item, vm) => { + let { title, __titleIsFunction__ } = item.meta; + if (!title) return; + if (useI18n) { + if (title.includes('{{') && title.includes('}}') && useI18n) { + title = title.replace(/({{[\s\S]+?}})/, (m, str) => + str.replace(/{{([\s\S]*)}}/, (m, _) => vm.$t(_.trim())) + ); + } else if (__titleIsFunction__) title = item.meta.title; + else title = vm.$t(item.name); + } else title = (item.meta && item.meta.title) || item.name; + return title; +}; +/** + * @description 根据当前跳转的路由设置显示在浏览器标签的title + * @param {Object} routeItem 路由对象 + * @param {Object} vm Vue实例 + */ +export const setTitle = (routeItem, vm) => { + const handledRoute = getRouteTitleHandled(routeItem); + const pageTitle = showTitle(handledRoute, vm); + const resTitle = pageTitle ? `${pageTitle} - ${title}` : title; + window.document.title = resTitle; +}; + +export const findNodeUpper = (ele, tag) => { + if (ele.parentNode) { + if (ele.parentNode.tagName === tag.toUpperCase()) { + return ele.parentNode; + } else { + return findNodeUpper(ele.parentNode, tag); + } + } +}; + +export const findNodeUpperByClasses = (ele, classes) => { + let parentNode = ele.parentNode; + if (parentNode) { + let classList = parentNode.classList; + if ( + classList && + classes.every(className => classList.contains(className)) + ) { + return parentNode; + } else { + return findNodeUpperByClasses(parentNode, classes); + } + } +}; + +export const findNodeDownward = (ele, tag) => { + const tagName = tag.toUpperCase(); + if (ele.childNodes.length) { + let i = -1; + let len = ele.childNodes.length; + while (++i < len) { + let child = ele.childNodes[i]; + if (child.tagName === tagName) return child; + else return findNodeDownward(child, tag); + } + } +}; diff --git a/front/src/lib/printPlugs.js b/front/src/lib/printPlugs.js new file mode 100644 index 00000000..9c4295dd --- /dev/null +++ b/front/src/lib/printPlugs.js @@ -0,0 +1,133 @@ +// 打印类属性、方法定义 +/* eslint-disable */ +//第二个参数表明是否要关闭当前窗口 +const Print = function(dom, close, options) { + if (!(this instanceof Print)) return new Print(dom, close, options); + + this.options = this.extend( + { + noPrint: '.no-print' + }, + options + ); + + if (typeof dom === 'string') { + this.dom = document.querySelector(dom); + } else { + this.dom = dom; + } + + this.init(close); +}; +Print.prototype = { + init: function(close) { + var content = this.getStyle() + this.getHtml(); + this.writeIframe(content, close); + }, + extend: function(obj, obj2) { + for (var k in obj2) { + obj[k] = obj2[k]; + } + return obj; + }, + + getStyle: function() { + var str = '', + styles = document.querySelectorAll('style,link'); + for (var i = 0; i < styles.length; i++) { + str += styles[i].outerHTML; + } + str += + ''; + + return str; + }, + + getHtml: function() { + var inputs = document.querySelectorAll('input'); + var textareas = document.querySelectorAll('textarea'); + var selects = document.querySelectorAll('select'); + + for (var k in inputs) { + if (inputs[k].type == 'checkbox' || inputs[k].type == 'radio') { + if (inputs[k].checked == true) { + inputs[k].setAttribute('checked', 'checked'); + } else { + inputs[k].removeAttribute('checked'); + } + } else if (inputs[k].type == 'text') { + inputs[k].setAttribute('value', inputs[k].value); + } + } + + for (var k2 in textareas) { + if (textareas[k2].type == 'textarea') { + textareas[k2].innerHTML = textareas[k2].value; + } + } + + for (var k3 in selects) { + if (selects[k3].type == 'select-one') { + var child = selects[k3].children; + for (var i in child) { + if (child[i].tagName == 'OPTION') { + if (child[i].selected == true) { + child[i].setAttribute('selected', 'selected'); + } else { + child[i].removeAttribute('selected'); + } + } + } + } + } + return this.dom.outerHTML; + }, + + writeIframe: function(content, close) { + var w, + doc, + iframe = document.createElement('iframe'), + f = document.body.appendChild(iframe); + iframe.id = 'myIframe'; + iframe.style = 'position:absolute;'; + + w = f.contentWindow || f.contentDocument; + doc = f.contentDocument || f.contentWindow.document; + doc.open(); + doc.write(content); + doc.close(); + this.toPrint(w, close); + setTimeout(function() { + document.body.removeChild(iframe); + }, 500); + }, + + toPrint: function(frameWindow, close) { + try { + setTimeout(function() { + frameWindow.focus(); + try { + if (!frameWindow.document.execCommand('print', false, null)) { + frameWindow.print(); + } + } catch (e) { + frameWindow.print(); + } + frameWindow.close(); + if (close) { + window.close(); + } + }, 500); + } catch (err) { + console.log('err', err); + } + } +}; +const MyPlugin = {}; +MyPlugin.install = function(Vue, options) { + // 4. 添加实例方法 + Vue.prototype.$print = Print; +}; +export default MyPlugin; diff --git a/front/src/lib/render-dom.js b/front/src/lib/render-dom.js new file mode 100644 index 00000000..1cad207e --- /dev/null +++ b/front/src/lib/render-dom.js @@ -0,0 +1,10 @@ +export default { + name: 'RenderDom', + functional: true, + props: { + render: Function + }, + render: (h, ctx) => { + return ctx.props.render(h); + } +}; diff --git a/front/src/lib/table-action.js b/front/src/lib/table-action.js new file mode 100644 index 00000000..f9a541fc --- /dev/null +++ b/front/src/lib/table-action.js @@ -0,0 +1,84 @@ +// 处理table操作按钮 +const tableAction = (h, array) => { + let btnArray = []; + let btnMore = []; + array.map((item, index) => { + if (index < 2) { + let btn = h( + 'a', + { + props: { + type: !index ? 'primary' : 'info', + size: 'small', + to: item.to ? item.to : '', + target: item.target ? item.target : '_self', + ghost: true + }, + style: { + marginLeft: '5px' + }, + directives: item.directives, + on: { + click: item.action + } + }, + item.title + ); + btnArray.push(btn); + } else { + btnMore.push( + h( + 'DropdownItem', + { + nativeOn: { + click: item.action + } + }, + item.title + ) + ); + } + }); + let dropdown = h( + 'Dropdown', + { + props: { + transfer: true + } + }, + [ + h( + 'a', + { + props: { + type: 'default', + size: 'small' + }, + style: { + marginLeft: '5px' + } + }, + [ + h('span', '更多'), + h('Icon', { + props: { + type: 'ios-arrow-down' + } + }) + ] + ), + h( + 'DropdownMenu', + { + slot: 'list' + }, + btnMore + ) + ] + ); + if (array.length > 2) { + btnArray.push(dropdown); + } + return btnArray; +}; +export default tableAction; diff --git a/front/src/lib/util.js b/front/src/lib/util.js new file mode 100644 index 00000000..9e254c5d --- /dev/null +++ b/front/src/lib/util.js @@ -0,0 +1,499 @@ +/** + * @param {String} url + * @description 从URL中解析参数 + */ +export const getParams = url => { + const keyValueArr = url.split('?')[1].split('&'); + let paramObj = {}; + keyValueArr.forEach(item => { + const keyValue = item.split('='); + paramObj[keyValue[0]] = keyValue[1]; + }); + return paramObj; +}; + +/** + * @param {Any} obj + * @description 获取数据类型 + */ +export const getType = obj => { + return {}.toString + .call(obj) + .match(/\s([a-zA-Z]+)/)[1] + .toLowerCase(); +}; +// 日期格式 +export const dateFormat = { + YMD: 'YMD', + YMDHM: 'YMDHM', + YMDHMS: 'YMDHMS' +}; +export const forEach = (arr, fn) => { + if (!arr.length || !fn) return; + let i = -1; + let len = arr.length; + while (++i < len) { + let item = arr[i]; + fn(item, i, arr); + } +}; + +/** + * @param {Array} arr1 + * @param {Array} arr2 + * @description 得到两个数组的交集, 两个数组的元素为数值或字符串 + */ +export const getIntersection = (arr1, arr2) => { + let len = Math.min(arr1.length, arr2.length); + let i = -1; + let res = []; + while (++i < len) { + const item = arr2[i]; + if (arr1.indexOf(item) > -1) res.push(item); + } + return res; +}; + +/** + * @param {Array} arr1 + * @param {Array} arr2 + * @description 得到两个数组的并集, 两个数组的元素为数值或字符串 + */ +export const getUnion = (arr1, arr2) => { + return Array.from(new Set([...arr1, ...arr2])); +}; + +/** + * @param {Array} target 目标数组 + * @param {Array} arr 需要查询的数组 + * @description 判断要查询的数组是否至少有一个元素包含在目标数组中 + */ +export const hasOneOf = (targetarr, arr) => { + return targetarr.some(_ => arr.indexOf(_) > -1); +}; + +/** + * @param {String|Number} value 要验证的字符串或数值 + * @param {*} validList 用来验证的列表 + */ +export function oneOf (value, validList) { + for (let i = 0; i < validList.length; i++) { + if (value === validList[i]) { + return true; + } + } + return false; +} + +/** + * @param {Number} timeStamp 判断时间戳格式是否是毫秒 + * @returns {Boolean} + */ +const isMillisecond = timeStamp => { + const timeStr = String(timeStamp); + return timeStr.length > 10; +}; + +/** + * @param {Number} timeStamp 传入的时间戳 + * @param {Number} currentTime 当前时间时间戳 + * @returns {Boolean} 传入的时间戳是否早于当前时间戳 + */ +const isEarly = (timeStamp, currentTime) => { + return timeStamp < currentTime; +}; + +/** + * @param {Number} num 数值 + * @returns {String} 处理后的字符串 + * @description 如果传入的数值小于10,即位数只有1位,则在前面补充0 + */ +const getHandledValue = num => { + return num < 10 ? '0' + num : num; +}; + +/** + * @param {Number} timeStamp 传入的时间戳 + * @param {Number} startType 要返回的时间字符串的格式类型,传入'year'则返回年开头的完整时间 + */ +const getDate = (timeStamp, startType) => { + const d = new Date(timeStamp * 1000); + const year = d.getFullYear(); + const month = getHandledValue(d.getMonth() + 1); + const date = getHandledValue(d.getDate()); + const hours = getHandledValue(d.getHours()); + const minutes = getHandledValue(d.getMinutes()); + const second = getHandledValue(d.getSeconds()); + let resStr = ''; + if (startType === 'year') + {resStr = + year + + '-' + + month + + '-' + + date + + ' ' + + hours + + ':' + + minutes + + ':' + + second;} + else resStr = month + '-' + date + ' ' + hours + ':' + minutes; + return resStr; +}; + +/** + * @param {String|Number} timeStamp 时间戳 + * @returns {String} 相对时间字符串 + */ +export const getRelativeTime = timeStamp => { + // 判断当前传入的时间戳是秒格式还是毫秒 + const IS_MILLISECOND = isMillisecond(timeStamp); + // 如果是毫秒格式则转为秒格式 + if (IS_MILLISECOND) Math.floor((timeStamp /= 1000)); + // 传入的时间戳可以是数值或字符串类型,这里统一转为数值类型 + timeStamp = Number(timeStamp); + // 获取当前时间时间戳 + const currentTime = Math.floor(Date.parse(new Date()) / 1000); + // 判断传入时间戳是否早于当前时间戳 + const IS_EARLY = isEarly(timeStamp, currentTime); + // 获取两个时间戳差值 + let diff = currentTime - timeStamp; + // 如果IS_EARLY为false则差值取反 + if (!IS_EARLY) diff = -diff; + let resStr = ''; + const dirStr = IS_EARLY ? '前' : '后'; + // 少于等于59秒 + if (diff <= 59) resStr = diff + '秒' + dirStr; + // 多于59秒,少于等于59分钟59秒 + else if (diff > 59 && diff <= 3599) + {resStr = Math.floor(diff / 60) + '分钟' + dirStr;} + // 多于59分钟59秒,少于等于23小时59分钟59秒 + else if (diff > 3599 && diff <= 86399) + {resStr = Math.floor(diff / 3600) + '小时' + dirStr;} + // 多于23小时59分钟59秒,少于等于29天59分钟59秒 + else if (diff > 86399 && diff <= 2623859) + {resStr = Math.floor(diff / 86400) + '天' + dirStr;} + // 多于29天59分钟59秒,少于364天23小时59分钟59秒,且传入的时间戳早于当前 + else if (diff > 2623859 && diff <= 31567859 && IS_EARLY) + {resStr = getDate(timeStamp);} + else resStr = getDate(timeStamp, 'year'); + return resStr; +}; + +/** + * @returns {String} 当前浏览器名称 + */ +export const getExplorer = () => { + const ua = window.navigator.userAgent; + const isExplorer = exp => { + return ua.indexOf(exp) > -1; + }; + if (isExplorer('MSIE')) return 'IE'; + else if (isExplorer('Firefox')) return 'Firefox'; + else if (isExplorer('Chrome')) return 'Chrome'; + else if (isExplorer('Opera')) return 'Opera'; + else if (isExplorer('Safari')) return 'Safari'; +}; + +/** + * @description 绑定事件 on(element, event, handler) + */ +export const on = (function () { + if (document.addEventListener) { + return function (element, event, handler) { + if (element && event && handler) { + element.addEventListener(event, handler, false); + } + }; + } else { + return function (element, event, handler) { + if (element && event && handler) { + element.attachEvent('on' + event, handler); + } + }; + } +})(); + +/** + * @description 解绑事件 off(element, event, handler) + */ +export const off = (function () { + if (document.removeEventListener) { + return function (element, event, handler) { + if (element && event) { + element.removeEventListener(event, handler, false); + } + }; + } else { + return function (element, event, handler) { + if (element && event) { + element.detachEvent('on' + event, handler); + } + }; + } +})(); + +/** + * 判断一个对象是否存在key,如果传入第二个参数key,则是判断这个obj对象是否存在key这个属性 + * 如果没有传入key这个参数,则判断obj对象是否有键值对 + */ +export const hasKey = (obj, key) => { + if (key) return key in obj; + else { + let keysArr = Object.keys(obj); + return keysArr.length; + } +}; + +/** + * @param {*} obj1 对象 + * @param {*} obj2 对象 + * @description 判断两个对象是否相等,这两个对象的值只能是数字或字符串 + */ +export const objEqual = (obj1, obj2) => { + const keysArr1 = Object.keys(obj1); + const keysArr2 = Object.keys(obj2); + if (keysArr1.length !== keysArr2.length) return false; + else if (keysArr1.length === 0 && keysArr2.length === 0) return true; + /* eslint-disable-next-line */ else + {return !keysArr1.some(key => obj1[key] != obj2[key]);} +}; + +// 相关工具类 +export const utils = { + /** + * @description table实现反选 + * @param {Object} vm Vue实例 + * @param {Array} tableSelectDate 选中的数据 + * @param {Array} allData 所有数据 + * @param {Array} key 数据中的唯一值 + */ + reverseSelect (vm, tableSelectDate, allData, key) { + let copyMess = JSON.parse(JSON.stringify(tableSelectDate)); + // 流程:先全部选中->再部分选中 + vm.handleSelectAll(false); + // 选中的idList + let idList = copyMess.map(item => item[key]); + console.log(idList); + for (let item of allData) { + if (idList.every(id => id !== item.id)) { + vm.$set(item, '_checked', true); + tableSelectDate.push(item); + } else { + vm.$set(item, '_checked', false); + } + } + }, + // 校验字符串是否相同 合同使用 + contrastString (originStr, changeStr) { + let origin = originStr + .replace(/\s*/g, '') + .replace(/"/g, '\'') + .replace(/ /g, '') + .replace(/disabled=\/'\/'/g, 'disabled'); + let change = changeStr + .replace(/\s*/g, '') + .replace(/"/g, '\'') + .replace(/ /g, '') + .replace(/disabled=\/'\/'/g, 'disabled'); + return origin === change; + }, + // 获取当前日期getDateStr(0)、前几天getDateStr(-10)、后几天getDateStr(20) + getDateStr (AddDayCount, format) { + let date = new Date(); + // 获取AddDayCount天后的日期 + date.setDate(date.getDate() + AddDayCount); + return this.getDate(date, format); + }, + getDate (date, format) { + let year = date.getFullYear(); + // day获取当前几号,不足10补0 + let day = date.getDate() > 9 ? date.getDate() : '0' + date.getDate(); + // month获取当前月份的日期,不足10补0 + let month = + date.getMonth() + 1 > 9 + ? date.getMonth() + 1 + : '0' + (date.getMonth() + 1); + // h获取当前小时,不足10补0 + let h = date.getHours() > 9 ? date.getHours() : '0' + date.getHours(); + // s获取当前分钟,不足10补0 + let m = date.getMinutes() > 9 ? date.getMinutes() : '0' + date.getMinutes(); + // s获取当前秒数,不足10补0 + let s = date.getSeconds() > 9 ? date.getSeconds() : '0' + date.getSeconds(); + let resultDate = ''; + if (format === dateFormat.YMD) { + resultDate = year + '-' + month + '-' + day; + } + if (format === dateFormat.YMDHM) { + resultDate = year + '-' + month + '-' + day + ' ' + h + ':' + m; + } + if (format === dateFormat.YMDHMS) { + resultDate = year + '-' + month + '-' + day + ' ' + h + ':' + m + ':' + s; + } + return resultDate; + }, + // 获取周一和周日日期,返回两种格式时间 + getDateWeek () { + let now = new Date(); + let nowTime = now.getTime(); + let day = now.getDay(); + let oneDayLong = 1000 * 60 * 60 * 24; + let MondayTime = nowTime - (day - 1) * oneDayLong; + let SundayTime = nowTime + (7 - day) * oneDayLong; + let monday = new Date(MondayTime); + let sunday = new Date(SundayTime); + return { + // first: this.getDateAll(monday), + // last: this.getDateAll(sunday), + firstDate: monday, + lastDate: sunday + }; + }, + // 获取月初与月末日期,返回两种时间格式 + getDateMonth () { + let dateFirter = new Date(); + let dateLast = new Date(); + dateFirter.setDate(1); + + let currentMonth = dateLast.getMonth(); + let nextMonth = ++currentMonth; + let nextMonthFirstDay = new Date(dateLast.getFullYear(), nextMonth, 1); + let oneDay = 1000 * 60 * 60 * 24; + dateLast = new Date(nextMonthFirstDay - oneDay); + + return { + // first: this.getDateAll(dateFirter), + // last: this.getDateAll(dateLast), + firstDate: dateFirter, + lastDate: dateLast + }; + }, + // 计算天数 + getDayBetweenDate (date) { + date = this.getDate(new Date(date), 'YMD'); + let startTime = Date.parse(new Date(date)); // IE支持“yyyy/MM/dd”格式 + let endTime = Date.parse(this.getDate(new Date(), 'YMD')); + let day = parseInt((endTime - startTime) / (1000 * 60 * 60 * 24)); + return day; + }, + getDateIntervalYear (firstDate, secondDate) { + if (!firstDate || !secondDate) { + return 0; + } + let first = new Date(firstDate); + let second = new Date(secondDate); + let firstYear = first.getFullYear(); + let secondYear = second.getFullYear(); + let intervalYear = secondYear - firstYear; + return intervalYear < 0 ? 0 : intervalYear; + }, + getDateIntervalYearFixed2 (firstDate, secondDate) { + if (!firstDate || !secondDate) { + return 0; + } + // 格式化时间 + let startDate = new Date(this.getDate(new Date(firstDate), 'YMD')); + let endDate = new Date(this.getDate(new Date(secondDate), 'YMD')); + // 得到毫秒值 + let startTime = Date.parse(startDate); + let endTime = Date.parse(endDate); + // 得到差了多少天 + let day = parseInt((endTime - startTime) / (1000 * 60 * 60 * 24)); + if (day <= 0) { + return 0; + } + // 得到差的多少年 保留两位小数 + let resultYear = parseFloat((day / (30 * 12)).toFixed(2)); + return resultYear; + }, + // 数字转化为中文大写 + // 代码如下所示: + convertCurrency (money) { + // 汉字的数字 + let cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']; + // 基本单位 + let cnIntRadice = ['', '拾', '佰', '仟']; + // 对应整数部分扩展单位 + let cnIntUnits = ['', '万', '亿', '兆']; + // 对应小数部分单位 + let cnDecUnits = ['角', '分', '毫', '厘']; + // 整数金额时后面跟的字符 + let cnInteger = '整'; + // 整型完以后的单位 + let cnIntLast = '元'; + // 最大处理的数字 + let maxNum = 999999999999999.9999; + // 金额整数部分 + let integerNum; + // 金额小数部分 + let decimalNum; + // 输出的中文金额字符串 + let chineseStr = ''; + // 分离金额后用的数组,预定义 + let parts; + if (money === '') { + return ''; + } + money = parseFloat(money); + if (money >= maxNum) { + // 超出最大处理数字 + return ''; + } + if (money === 0) { + chineseStr = cnNums[0] + cnIntLast + cnInteger; + return chineseStr; + } + // 转换为字符串 + money = money.toString(); + if (money.indexOf('.') === -1) { + integerNum = money; + decimalNum = ''; + } else { + parts = money.split('.'); + integerNum = parts[0]; + decimalNum = parts[1].substr(0, 4); + } + // 获取整型部分转换 + if (parseInt(integerNum, 10) > 0) { + let zeroCount = 0; + let IntLen = integerNum.length; + for (let i = 0; i < IntLen; i++) { + let n = integerNum.substr(i, 1); + let p = IntLen - i - 1; + let q = p / 4; + let m = p % 4; + if (n === '0') { + zeroCount++; + } else { + if (zeroCount > 0) { + chineseStr += cnNums[0]; + } + // 归零 + zeroCount = 0; + chineseStr += cnNums[parseInt(n)] + cnIntRadice[m]; + } + if (m === 0 && zeroCount < 4) { + chineseStr += cnIntUnits[q]; + } + } + chineseStr += cnIntLast; + } + // 小数部分 + if (decimalNum !== '') { + let decLen = decimalNum.length; + for (let i = 0; i < decLen; i++) { + let n = decimalNum.substr(i, 1); + if (n !== '0') { + chineseStr += cnNums[Number(n)] + cnDecUnits[i]; + } + } + } + if (chineseStr === '') { + chineseStr += cnNums[0] + cnIntLast + cnInteger; + } else if (decimalNum === '') { + chineseStr += cnInteger; + } + return chineseStr; + } +}; diff --git a/front/src/locale/index.js b/front/src/locale/index.js new file mode 100644 index 00000000..e9dd62c3 --- /dev/null +++ b/front/src/locale/index.js @@ -0,0 +1,37 @@ +import Vue from 'vue'; +import VueI18n from 'vue-i18n'; +import { localRead } from '@/lib/local'; +import customZhCn from './lang/zh-CN'; +import customZhTw from './lang/zh-TW'; +import customEnUs from './lang/en-US'; +import zhCnLocale from 'iview/src/locale/lang/zh-CN'; +import enUsLocale from 'iview/src/locale/lang/en-US'; +import zhTwLocale from 'iview/src/locale/lang/zh-TW'; + +Vue.use(VueI18n); + +// 自动根据浏览器系统语言设置语言 +const navLang = navigator.language; +const localLang = (navLang === 'zh-CN' || navLang === 'en-US') ? navLang : false; +let lang = localLang || localRead('local') || 'zh-CN'; + +Vue.config.lang = lang; + +// vue-i18n 6.x+写法 +Vue.locale = () => { }; +const messages = { + 'zh-CN': Object.assign(zhCnLocale, customZhCn), + 'zh-TW': Object.assign(zhTwLocale, customZhTw), + 'en-US': Object.assign(enUsLocale, customEnUs) +}; +const i18n = new VueI18n({ + locale: lang, + messages +}); + +export default i18n; + +// vue-i18n 5.x写法 +// Vue.locale('zh-CN', Object.assign(zhCnLocale, customZhCn)) +// Vue.locale('en-US', Object.assign(zhTwLocale, customZhTw)) +// Vue.locale('zh-TW', Object.assign(enUsLocale, customEnUs)) diff --git a/front/src/locale/lang/en-US.js b/front/src/locale/lang/en-US.js new file mode 100644 index 00000000..dc20d8f6 --- /dev/null +++ b/front/src/locale/lang/en-US.js @@ -0,0 +1,46 @@ +export default { + home: 'Home', + login: 'Login', + components: 'Components', + count_to_page: 'Count-to', + tables_page: 'Table', + split_pane_page: 'Split-pane', + markdown_page: 'Markdown-editor', + editor_page: 'Rich-Text-Editor', + icons_page: 'Custom-icon', + img_cropper_page: 'Image-editor', + update: 'Update', + doc: 'Document', + join_page: 'QQ Group', + update_table_page: 'Update .CSV', + update_paste_page: 'Paste Table Data', + multilevel: 'multilevel', + directive_page: 'Directive', + level_1: 'Level-1', + level_2: 'Level-2', + level_2_1: 'Level-2-1', + level_2_3: 'Level-2-3', + level_2_2: 'Level-2-2', + level_2_2_1: 'Level-2-2-1', + level_2_2_2: 'Level-2-2-2', + excel: 'Excel', + 'upload-excel': 'Upload Excel', + 'export-excel': 'Export Excel', + tools_methods_page: 'Tools Methods', + drag_list_page: 'Drag-list', + i18n_page: 'Internationalization', + modalTitle: 'Modal Title', + content: 'This is the modal box content.', + buttonText: 'Show Modal', + 'i18n-tip': 'Note: Only this page is multi-language, other pages do not add language content to the multi-language package.', + error_store_page: 'Error Collection', + error_logger_page: 'Error Logger', + query: 'Query', + params: 'Params', + cropper_page: 'Cropper', + message_page: 'Message Center', + tree_table_page: 'Tree Table', + org_tree_page: 'Org Tree', + drag_drawer_page: 'Draggable Drawer', + tree_select_page: 'Tree Selector' +} diff --git a/front/src/locale/lang/zh-CN.js b/front/src/locale/lang/zh-CN.js new file mode 100644 index 00000000..9e402562 --- /dev/null +++ b/front/src/locale/lang/zh-CN.js @@ -0,0 +1,46 @@ +export default { + home: '首页', + login: '登录', + components: '组件', + count_to_page: '数字渐变', + tables_page: '多功能表格', + split_pane_page: '分割窗口', + markdown_page: 'Markdown编辑器', + editor_page: '富文本编辑器', + icons_page: '自定义图标', + img_cropper_page: '图片编辑器', + update: '上传数据', + join_page: 'QQ群', + doc: '文档', + update_table_page: '上传CSV文件', + update_paste_page: '粘贴表格数据', + multilevel: '多级菜单', + directive_page: '指令', + level_1: 'Level-1', + level_2: 'Level-2', + level_2_1: 'Level-2-1', + level_2_3: 'Level-2-3', + level_2_2: 'Level-2-2', + level_2_2_1: 'Level-2-2-1', + level_2_2_2: 'Level-2-2-2', + excel: 'Excel', + 'upload-excel': '上传excel', + 'export-excel': '导出excel', + tools_methods_page: '工具函数', + drag_list_page: '拖拽列表', + i18n_page: '多语言', + modalTitle: '模态框题目', + content: '这是模态框内容', + buttonText: '显示模态框', + 'i18n-tip': '注:仅此页做了多语言,其他页面没有在多语言包中添加语言内容', + error_store_page: '错误收集', + error_logger_page: '错误日志', + query: '带参路由', + params: '动态路由', + cropper_page: '图片裁剪', + message_page: '消息中心', + tree_table_page: '树状表格', + org_tree_page: '组织结构树', + drag_drawer_page: '可拖动抽屉', + tree_select_page: '树状下拉选择器' +} diff --git a/front/src/locale/lang/zh-TW.js b/front/src/locale/lang/zh-TW.js new file mode 100644 index 00000000..ce51c428 --- /dev/null +++ b/front/src/locale/lang/zh-TW.js @@ -0,0 +1,46 @@ +export default { + home: '首頁', + login: '登錄', + components: '组件', + count_to_page: '数字渐变', + tables_page: '多功能表格', + split_pane_page: '分割窗口', + markdown_page: 'Markdown編輯器', + editor_page: '富文本編輯器', + icons_page: '自定義圖標', + img_cropper_page: '圖片編輯器', + update: '上傳數據', + join_page: 'QQ群', + doc: '文檔', + update_table_page: '上傳CSV文件', + update_paste_page: '粘貼表格數據', + multilevel: '多级菜单', + directive_page: '指令', + level_1: 'Level-1', + level_2: 'Level-2', + level_2_1: 'Level-2-1', + level_2_3: 'Level-2-3', + level_2_2: 'Level-2-2', + level_2_2_1: 'Level-2-2-1', + level_2_2_2: 'Level-2-2-2', + excel: 'Excel', + 'upload-excel': '上傳excel', + 'export-excel': '導出excel', + tools_methods_page: '工具函數', + drag_list_page: '拖拽列表', + i18n_page: '多語言', + modalTitle: '模態框題目', + content: '這是模態框內容', + buttonText: '顯示模態框', + 'i18n-tip': '注:僅此頁做了多語言,其他頁面沒有在多語言包中添加語言內容', + error_store_page: '錯誤收集', + error_logger_page: '錯誤日誌', + query: '帶參路由', + params: '動態路由', + cropper_page: '圖片裁剪', + message_page: '消息中心', + tree_table_page: '樹狀表格', + org_tree_page: '組織結構樹', + drag_drawer_page: '可拖動抽屜', + tree_select_page: '樹狀下拉選擇器' +} diff --git a/front/src/main.js b/front/src/main.js new file mode 100644 index 00000000..7a1e8807 --- /dev/null +++ b/front/src/main.js @@ -0,0 +1,64 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue'; +import App from './App'; +import router from './router'; +import store from './store'; +import iView from 'iview'; +import i18n from '@/locale'; +import config from '@/config'; +import importDirective from '@/directives'; +import JsonViewer from 'vue-json-viewer'; +import _ from 'lodash'; +// import { directive as clickOutside } from 'v-click-outside-x'; +import * as vClickOutside from 'v-click-outside-x'; +import installPlugin from '@/plugins'; +import './themes/index.less'; +import '@/assets/icons/iconfont.css'; +import 'slick-carousel/slick/slick.css'; +import { Decimal } from 'decimal.js'; +// 枚举管理 +import Enum from 'vue-enum'; +import enumInfo from '@/constants'; +// 处理table操作按钮 +import tableAction from './lib/table-action'; +Vue.prototype.$tableAction = tableAction; +Vue.use(Enum, { enumInfo }); +Vue.use(iView, { + i18n: (key, value) => i18n.t(key, value) +}); +Vue.use(JsonViewer); +Vue.use(vClickOutside); +Number.prototype.toFixed = function (length) { + let x = new Decimal(this); + return x.toFixed(length); +}; + +/** + * @description 注册admin内置插件 + */ +installPlugin(Vue); +/** + * @description 生产环境关掉提示 + */ +Vue.config.productionTip = false; +/** + * @description 全局注册应用配置 + */ +Vue.prototype.$config = config; +/** + * 注册指令 + */ +importDirective(Vue); +// Vue.directive('clickOutside', clickOutside); + +window._ = _; + +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + i18n, + store, + render: h => h(App) +}); diff --git a/front/src/main.less b/front/src/main.less new file mode 100644 index 00000000..72a1a030 --- /dev/null +++ b/front/src/main.less @@ -0,0 +1,37 @@ +.warp-card { + margin-top: 10px; + &:first-child { + margin-top: 0; + } + .action-show { + .ivu-btn { + margin: 0 3px; + } + } + .action-hide { + .ivu-btn { + margin: 0 3px; + span { + //display: none; + } + } + } + .add-form { + padding-top: 15px; + } +} +.areaSelect .areaBox .areaArrow.active { + border-color: #689df6 !important; +} + +.areaSelect .areaBox .areaInput:hover, .areaSelect .areaBox .areaInput:focus { + border-color: #689df6 !important; +} + +.areaSelect .areaBox .areaModal ul li.active[data-v-16a01167] { + background: #fff !important; + color: #689df6 !important; +} +.main{ + .side-menu-wrapper .ivu-menu-dark .ivu-menu .ivu-menu-submenu-has-parent-submenu{ padding-left: 41px; } +} diff --git a/front/src/plugins/error-store/index.js b/front/src/plugins/error-store/index.js new file mode 100644 index 00000000..c8b35b8f --- /dev/null +++ b/front/src/plugins/error-store/index.js @@ -0,0 +1,4 @@ +import store from '@/store'; +export default { + install(Vue, options) {} +}; diff --git a/front/src/plugins/index.js b/front/src/plugins/index.js new file mode 100644 index 00000000..1a1c1870 --- /dev/null +++ b/front/src/plugins/index.js @@ -0,0 +1,12 @@ +import config from '@/config'; +const { plugin } = config; + +export default Vue => { + for (let name in plugin) { + const value = plugin[name]; + Vue.use( + require(`./${name}`).default, + typeof value === 'object' ? value : undefined + ); + } +}; diff --git a/front/src/router/before-close.js b/front/src/router/before-close.js new file mode 100644 index 00000000..01ba93d7 --- /dev/null +++ b/front/src/router/before-close.js @@ -0,0 +1,17 @@ +import { Modal } from 'iview'; + +const beforeClose = { + before_close_normal: resolve => { + Modal.confirm({ + title: '确定要关闭这一页吗', + onOk: () => { + resolve(true); + }, + onCancel: () => { + resolve(false); + } + }); + } +}; + +export default beforeClose; diff --git a/front/src/router/index.js b/front/src/router/index.js new file mode 100644 index 00000000..aeaba49c --- /dev/null +++ b/front/src/router/index.js @@ -0,0 +1,142 @@ +import Vue from 'vue'; +import Router from 'vue-router'; +import { routers } from './routers'; +import store from '@/store'; +import iView from 'iview'; +import cookie from '@/lib/cookie'; +import { localRead } from '@/lib/local'; +import { setTitle } from '@/lib/menu-func'; + +Vue.use(Router); +const router = new Router({ + routes: routers + // mode: 'history' +}); +const LOGIN_PAGE_NAME = 'login'; + +// 防止用户刷新丢失登录信息 +if ( + Object.keys(store.state.user.userLoginInfo).length === 0 && + localRead('userLoginInfo') +) { + store.commit('setUserLoginInfo', JSON.parse(localRead('userLoginInfo'))); +} +// 解决路由跳转相同的地址报错 +const originalPush = Router.prototype.push; +Router.prototype.push = function (location) { + try { + return originalPush.call(this, location).catch(err => err); + } catch (error) { + // TODO zhuoda sentry + console.error(error); + } +}; + +// 关于当前页面 +Router.prototype.closeCurrentPage = function () { + let current = this.history.current; + store.commit('closeTag', current); + store.commit('deleteKeepAliveIncludes', current.name); +}; + +// 关闭当前页面然后跳转到指定页面 +Router.prototype.closeCurrentPageAndPush = function (pushParam) { + let current = this.history.current; + store.commit('closeTagNotPushNextRoute', current); + store.commit('deleteKeepAliveIncludes', current.name); + this.push(pushParam); +}; +let storeSelf = store; +router.beforeEach((to, from, next) => { + console.log(to); + iView.LoadingBar.start(); + const token = cookie.getToken(); + if (!token && to.name !== LOGIN_PAGE_NAME) { + // 未登录且要跳转的页面不是登录页 + next({ + name: LOGIN_PAGE_NAME // 跳转到登录页 + }); + } else if (!token && to.name === LOGIN_PAGE_NAME) { + // 未登陆且要跳转的页面是登录页 + next(); // 跳转 + } else if (token && to.name === LOGIN_PAGE_NAME) { + // 已登录且要跳转的页面是登录页 + next({ + name: 'home' // 跳转到home页 + }); + } else { + // 特殊页面直接放行 + if (to.meta.access) { + next(); + return; + } + + // 去掉/之后第一个字母 + let key = to.path.substr(1, 1); + let pathArray = storeSelf.state.user.privilegeRouterPathMap.get(key); + if (!(pathArray && pathArray.indexOf(to.path) >= 0)) { + next({ + name: 'Error401' + }); + } else { + next(); + } + } +}); + +router.afterEach(to => { + setTitle(to, router.app); + iView.LoadingBar.finish(); + window.scrollTo(0, 0); +}); + +let tempCheckObj = { + checkRouterNameMap: new Map(), + checkRouterPathMap: new Map() +}; + +function recursionRouter (routerArray) { + for (let routerItem of routerArray) { + if (!routerItem.name) { + console.error('没有配置router name', routerItem); + } else { + let existNameRouter = tempCheckObj.checkRouterNameMap.get( + routerItem.name + ); + if (typeof existNameRouter !== 'undefined') { + console.error('存在相同的router name', routerItem, existNameRouter); + } else { + tempCheckObj.checkRouterNameMap.set(routerItem.name, routerItem); + } + } + + if (!routerItem.path) { + console.error('没有配置router path', routerItem); + } else { + // path必须以 / 开头 + if (routerItem.path !== '*' && routerItem.path.indexOf('/') !== 0) { + console.error('path 没有以/开头 ', routerItem); + } + + let existPathRouter = tempCheckObj.checkRouterPathMap.get( + routerItem.path + ); + if (typeof existPathRouter !== 'undefined') { + console.error('存在相同的router path', routerItem, existPathRouter); + } else { + tempCheckObj.checkRouterPathMap.set(routerItem.path, routerItem); + } + } + + if (routerItem.children) { + recursionRouter(routerItem.children); + } + } +} + +recursionRouter(routers); + +delete tempCheckObj.checkRouterNameMap; +delete tempCheckObj.checkRouterPathMap; + +export default router; diff --git a/front/src/router/module/api-doc.js b/front/src/router/module/api-doc.js new file mode 100644 index 00000000..5c611a81 --- /dev/null +++ b/front/src/router/module/api-doc.js @@ -0,0 +1,25 @@ +import Main from '@/components/main'; +// 接口文档 +export const apiDoc = [ + { + path: '/api-doc', + component: Main, + name: 'ApiDoc', + meta: { + title: '接口文档', + icon: 'icon iconfont iconjiekouwendang' + }, + + children: [ + { + path: '/api-doc/swagger', + name: 'Swagger', + meta: { + title: 'Swagger接口文档', + icon: 'icon iconfont iconjiekouwendang' + }, + component: () => import('@/views/api-doc/swagger.vue') + } + ] + } +]; diff --git a/front/src/router/module/email.js b/front/src/router/module/email.js new file mode 100644 index 00000000..9fb26781 --- /dev/null +++ b/front/src/router/module/email.js @@ -0,0 +1,40 @@ +import Main from '@/components/main'; +// 基础设置 +export const emailSetting = [ + { + path: '/email', + name: 'Email', + component: Main, + meta: { + title: '邮件管理', + icon: 'icon iconfont iconyoujianguanli' + }, + children: [ + // 发送email + { + path: '/email/email-list', + name: 'EmailList', + meta: { + title: '邮件管理', + childrenPoints: [ + { title: '查询', name: 'email-query' }, + { title: '新增', name: 'email-add' }, + { title: '编辑', name: 'email-update' }, + { title: '删除', name: 'email-delete' } + ] + }, + component: () => import('@/views/email/email-list.vue') + }, + // 发送email + { + path: '/email/send-mail', + name: 'SendMail', + meta: { + title: '发送邮件', + childrenPoints: [{ title: '发送', name: 'email-send' }] + }, + component: () => import('@/views/email/send-mail.vue') + } + ] + } +]; diff --git a/front/src/router/module/employee.js b/front/src/router/module/employee.js new file mode 100644 index 00000000..5c735b6a --- /dev/null +++ b/front/src/router/module/employee.js @@ -0,0 +1,149 @@ +import Main from '@/components/main'; +// 基础设置 +export const employee = [ + { + path: '/employee', + component: Main, + name: 'Employee', + meta: { + title: '人员管理', + icon: 'icon iconfont iconrenyuanguanli' + }, + children: [ + // 角色管理页面路由 + { + path: '/employee/role', + name: 'RoleManage', + meta: { + title: '角色管理', + childrenPoints: [ + { + title: '添加角色', + name: 'add-role' + }, + { + title: '删除角色', + name: 'delete-role' + }, + { + title: '编辑角色', + name: 'update-role' + }, + { + title: '修改角色权限', + name: 'update-role-privilege' + }, + { + title: '添加成员', + name: 'add-employee-role' + }, + { + title: '移除成员', + name: 'delete-employee-role' + }, + { + title: '批量移除', + name: 'delete-employee-role-batch' + }, + { + title: '查询成员', + name: 'search-employee-list' + }, + { + title: '查询数据范围', + name: 'query-data-scope' + }, + { + title: '更新数据范围', + name: 'update-data-scope' + } + ] + }, + component: () => import('@/views/employee/role/role-manage.vue') + }, + // 岗位管理页面路由 新 + { + path: '/employee/position', + name: 'PositionList', + meta: { + title: '岗位管理', + childrenPoints: [ + { + title: '查询', + name: 'search-position' + }, + { + title: '添加', + name: 'add-position' + }, + { + title: '修改', + name: 'update-position' + }, + { + title: '删除', + name: 'delete-position' + } + ] + }, + component: () => import('@/views/employee/position/position-list.vue') + }, + // 人员管理页面路由 + { + path: '/employee/role-employee-manage', + name: 'RoleEmployeeManage', + meta: { + title: '员工管理', + childrenPoints: [ + { + title: '添加部门', + name: 'add-department' + }, + { + title: '编辑部门', + name: 'update-department' + }, + { + title: '删除部门', + name: 'delete-department' + }, + { + title: '查询', + name: 'search-department' + }, + { + title: '添加成员', + name: 'add-employee' + }, + { + title: '编辑成员', + name: 'update-employee' + }, + { + title: '禁用', + name: 'disabled-employee' + }, + { + title: '批量操作', + name: 'disabled-employee-batch' + }, + { + title: '员工角色编辑', + name: 'update-employee-role' + }, + { + title: '删除员工', + name: 'delete-employee' + }, + { + title: '重置密码', + name: 'reset-employee-password' + } + ] + }, + component: () => + import('@/views/employee/role-employee/role-employee-manage.vue') + } + ] + } +]; diff --git a/front/src/router/module/error.js b/front/src/router/module/error.js new file mode 100644 index 00000000..3c890ce3 --- /dev/null +++ b/front/src/router/module/error.js @@ -0,0 +1,30 @@ +// 错误页 +export const error = [ + { + path: '/401', + name: 'Error401', + meta: { + hideInMenu: true, + access: true + }, + component: () => import('@/views/error-page/401.vue') + }, + { + path: '/500', + name: 'Error500', + meta: { + hideInMenu: true, + access: true + }, + component: () => import('@/views/error-page/500.vue') + }, + { + path: '*', + name: 'http://localhost:8080/#employee/role-employee-manage', + meta: { + hideInMenu: true, + access: true + }, + component: () => import('@/views/error-page/404.vue') + } +]; diff --git a/front/src/router/module/file.js b/front/src/router/module/file.js new file mode 100644 index 00000000..ac77299a --- /dev/null +++ b/front/src/router/module/file.js @@ -0,0 +1,29 @@ +import Main from '@/components/main'; +// 文件服务 +export const file = [ + { + path: '/file', + name: 'File', + component: Main, + meta: { + title: '文件服务', + icon: 'ios-cloud-upload' + }, + children: [ + { + path: '/file/file-list', + name: 'FileList', + meta: { + title: '文件列表', + icon: 'ios-cloud-upload', + childrenPoints: [ + { title: '查询', name: 'file-filePage-query' }, + { title: '上传', name: 'file-filePage-upload' }, + { title: '下载', name: 'file-filePage-download' } + ] + }, + component: () => import('@/views/file/file-list.vue') + } + ] + } +]; diff --git a/front/src/router/module/heart-beat.js b/front/src/router/module/heart-beat.js new file mode 100644 index 00000000..99dfbb9e --- /dev/null +++ b/front/src/router/module/heart-beat.js @@ -0,0 +1,31 @@ +import Main from '@/components/main'; +// 心跳服务 +export const heartBeat = [ + { + path: '/heart-beat', + name: 'HeartBeat', + component: Main, + meta: { + title: '心跳服务', + icon: 'icon iconfont icondingshirenwu' + }, + + children: [ + { + path: '/heart-beat/heart-beat-list', + name: 'HeartBeatList', + meta: { + title: '心跳服务', + icon: 'icon iconfont icondingshirenwu', + childrenPoints: [ + { + title: '查询任务', + name: 'heart-beat-query' + } + ] + }, + component: () => import('@/views/heart-beat/heart-beat-list.vue') + } + ] + } +]; diff --git a/front/src/router/module/home.js b/front/src/router/module/home.js new file mode 100644 index 00000000..e843b3b6 --- /dev/null +++ b/front/src/router/module/home.js @@ -0,0 +1,28 @@ +import Main from '@/components/main'; +// 首页 +export const home = [ + { + path: '/', + name: '_home', + redirect: '/home', + component: Main, + meta: { + noKeepAlive: true, + hideInMenu: true, + access: true, + icon: 'icon iconfont iconxitongshezhi' + }, + children: [ + { + path: '/home', + name: 'Home', + meta: { + title: '首页', + access: true, + noKeepAlive: true + }, + component: () => import('@/views/home') + } + ] + } +]; diff --git a/front/src/router/module/keep-alive.js b/front/src/router/module/keep-alive.js new file mode 100644 index 00000000..38ef2173 --- /dev/null +++ b/front/src/router/module/keep-alive.js @@ -0,0 +1,31 @@ +import Main from '@/components/main'; +// 接口文档 +export const keepAlive = [ + { + path: '/keep-alive', + name: 'KeepAlive', + component: Main, + meta: { + title: 'KeepAlive', + icon: 'icon iconfont iconxitongshezhi' + }, + children: [ + { + path: '/keep-alive/content-list', + name: 'KeepAliveContentList', + meta: { + title: 'KeepAlive列表' + }, + component: () => import('@/views/keep-alive/content-list.vue') + }, + { + path: '/keep-alive/add-content', + name: 'KeepAliveAddContent', + meta: { + title: 'KeepAlive表单' + }, + component: () => import('@/views/keep-alive/add-content.vue') + } + ] + } +]; diff --git a/front/src/router/module/monitor.js b/front/src/router/module/monitor.js new file mode 100644 index 00000000..c072f4fd --- /dev/null +++ b/front/src/router/module/monitor.js @@ -0,0 +1,33 @@ +import Main from '@/components/main'; +// 系统监控 +export const monitor = [ + { + path: '/monitor', + component: Main, + name: 'Monitor', + meta: { + title: '系统监控', + icon: 'icon iconfont iconxitongjiankong' + }, + children: [ + { + path: '/monitor/online-user', + name: 'OnlineUser', + meta: { + title: '在线人数', + childrenPoints: [{ title: '查询', name: 'online-user-search' }] + }, + component: () => import('@/views/monitor/online-user.vue') + }, + // SQL监控 + { + path: '/monitor/sql', + name: 'Sql', + meta: { + title: 'SQL监控' + }, + component: () => import('@/views/monitor/sql.vue') + } + ] + } +]; diff --git a/front/src/router/module/notice.js b/front/src/router/module/notice.js new file mode 100644 index 00000000..ea4c6f4c --- /dev/null +++ b/front/src/router/module/notice.js @@ -0,0 +1,43 @@ +import Main from '@/components/main'; +// 消息管理 +export const notice = [ + { + path: '/notice', + name: 'Notice', + component: Main, + meta: { + title: '消息管理', + icon: 'icon iconfont iconnews' + }, + children: [ + { + path: '/notice/notice-list', + name: 'NoticeList', + meta: { + title: '通知管理', + childrenPoints: [ + { title: '查询', name: 'notice-query' }, + { title: '添加', name: 'notice-add' }, + { title: '修改', name: 'notice-edit' }, + { title: '删除', name: 'notice-delete' }, + { title: '详情', name: 'notice-detail' }, + { title: '发送', name: 'notice-send' } + ] + }, + component: () => import('@/views/notice/notice-list.vue') + }, + { + path: '/notice/person-notice', + name: 'PersonNotice', + meta: { + title: '个人消息', + childrenPoints: [ + { title: '查询', name: 'person-notice-query' }, + { title: '详情', name: 'person-notice-detail' } + ] + }, + component: () => import('@/views/notice/person-notice.vue') + } + ] + } +]; diff --git a/front/src/router/module/reload.js b/front/src/router/module/reload.js new file mode 100644 index 00000000..958bd2d7 --- /dev/null +++ b/front/src/router/module/reload.js @@ -0,0 +1,40 @@ +import Main from '@/components/main'; +// 动态加载 +export const reload = [ + { + path: '/reload', + name: 'Reload', + component: Main, + meta: { + title: '动态加载', + icon: 'icon iconfont icondongtaijiazai' + }, + + children: [ + { + path: '/reload/smart-reload-list', + name: 'SmartReloadList', + meta: { + title: 'SmartReload', + icon: 'icon iconfont icondongtaijiazai', + childrenPoints: [ + { + title: '查询', + name: 'smart-reload-search' + }, + { + title: '执行reload', + name: 'smart-reload-update' + }, + { + title: '查看执行结果', + name: 'smart-reload-result' + } + ] + }, + component: () => + import('@/views/reload/smart-reload/smart-reload-list.vue') + } + ] + } +]; diff --git a/front/src/router/module/system-setting.js b/front/src/router/module/system-setting.js new file mode 100644 index 00000000..e85884f8 --- /dev/null +++ b/front/src/router/module/system-setting.js @@ -0,0 +1,62 @@ +import Main from '@/components/main'; +// 基础设置 +export const systemSetting = [ + { + path: '/system-setting', + name: 'SystemSetting', + component: Main, + meta: { + title: '系统设置', + icon: 'icon iconfont iconxitongshezhi' + }, + + children: [ + { + path: '/system-setting/system-config', + name: 'SystemConfig', + meta: { + title: '系统参数', + childrenPoints: [ + { + title: '查询系统参数', + name: 'system-params-search' + }, + { + title: '添加系统参数', + name: 'system-params-add' + }, + { + title: '修改系统参数', + name: 'system-config-update' + }, + { + title: '搜索系统参数', + name: 'system-config-search' + } + ] + }, + component: () => + import('@/views/system-setting/system-config/system-config.vue') + }, + { + path: '/system-setting/system-privilege', + name: 'SystemPrivilege', + meta: { + title: '菜单管理', + childrenPoints: [ + { + title: '编辑', + name: 'privilege-main-update' + }, + { + title: '查询', + name: 'privilege-main-search' + } + ] + }, + component: () => + import('@/views/system-setting/system-privilege/system-privilege.vue') + } + ] + } +]; diff --git a/front/src/router/module/task.js b/front/src/router/module/task.js new file mode 100644 index 00000000..7779e2ae --- /dev/null +++ b/front/src/router/module/task.js @@ -0,0 +1,63 @@ +import Main from '@/components/main'; +// 任务调度 +export const task = [ + { + path: '/task', + name: 'Task', + component: Main, + meta: { + title: '定时任务', + icon: 'icon iconfont icondingshirenwu' + }, + + children: [ + { + path: '/system-setting/task-list', + name: 'TaskList', + meta: { + title: '任务管理', + icon: 'icon iconfont icondingshirenwu', + childrenPoints: [ + { + title: '查询任务', + name: 'task-search' + }, + { + title: '刷新任务', + name: 'task-refresh' + }, + { + title: '添加任务', + name: 'task-add' + }, + { + title: '编辑任务', + name: 'task-update' + }, + { + title: '暂停任务', + name: 'task-pause' + }, + { + title: '恢复任务', + name: 'task-resume' + }, + { + title: '立即运行任务', + name: 'task-run' + }, + { + title: '查看任务日志', + name: 'task-query-log' + }, + { + title: '删除任务', + name: 'task-delete' + } + ] + }, + component: () => import('@/views/task/task-list.vue') + } + ] + } +]; diff --git a/front/src/router/module/three-router.js b/front/src/router/module/three-router.js new file mode 100644 index 00000000..b1a9a409 --- /dev/null +++ b/front/src/router/module/three-router.js @@ -0,0 +1,62 @@ +import Main from '@/components/main'; +// 三级路由演示 +export const threeRouter = [ + { + path: '/three-router', + name: 'ThreeRouter', + component: Main, + meta: { + title: '三级路由', + icon: 'icon iconfont iconzujian' + }, + children: [ + // 最大支持到三级菜单 + { + path: '/three-router/level-two', + name: 'LevelTwo', + meta: { + title: '三级菜单' + }, + component: () => import('@/views/home'), + children: [ + { + path: '/three-router/level-two/level-three1', + name: 'RoleOneTwo', + meta: { + title: '三级A', + childrenPoints: [ + { title: '添加', name: 'roleOneTwo-add' }, + { title: '删除', name: 'roleOneTwo-delete' } + ] + }, + component: () => import('@/views/home') + }, + { + path: '/three-router/level-two/level-three2', + name: 'RoleTwoTwo', + meta: { + title: '三级B', + childrenPoints: [ + { title: '添加', name: 'roleTwoTwo-add' }, + { title: '删除', name: 'roleTwoTwo-delete' } + ] + }, + component: () => import('@/views/home') + } + ] + }, + { + path: '/three-router/level-two2', + name: 'RoleOneOne', + meta: { + title: '二级菜单', + childrenPoints: [ + { title: '添加', name: 'roleOneOne-add' }, + { title: '删除', name: 'roleOneOne-delete' } + ] + }, + component: () => import('@/views/home') + } + ] + } +]; diff --git a/front/src/router/module/user-log.js b/front/src/router/module/user-log.js new file mode 100644 index 00000000..15765ffb --- /dev/null +++ b/front/src/router/module/user-log.js @@ -0,0 +1,42 @@ +import Main from '@/components/main'; +// 用户日志 +export const userLog = [ + { + path: '/user-log', + name: 'UserLog', + component: Main, + meta: { + title: '用户日志', + icon: 'ios-paper-outline' + }, + children: [ + // 发送email + { + path: '/user-log/user-operate-log', + name: 'UserOperateLog', + meta: { + title: '用户操作日志', + childrenPoints: [ + { title: '查询', name: 'user-operate-log-search' }, + { title: '详情', name: 'user-operate-log-detail' }, + { title: '删除', name: 'user-operate-log-delete' } + ] + }, + component: () => import('@/views/user-log/user-operate-log.vue') + }, + // 人员管理页面路由 + { + path: '/user-log/user-login-log', + name: 'UserLoginLog', + meta: { + title: '用户登录日志', + childrenPoints: [ + { title: '查询', name: 'user-login-log-search' }, + { title: '删除', name: 'user-login-log-delete' } + ] + }, + component: () => import('@/views/user-log/user-login-log.vue') + } + ] + } +]; diff --git a/front/src/router/routers.js b/front/src/router/routers.js new file mode 100644 index 00000000..25492ecf --- /dev/null +++ b/front/src/router/routers.js @@ -0,0 +1,61 @@ +import { home } from './module/home'; +import { employee } from './module/employee'; +import { systemSetting } from './module/system-setting'; +import { notice } from './module/notice'; +import { emailSetting } from './module/email'; +import { monitor } from './module/monitor'; +import { userLog } from './module/user-log'; +import { error } from './module/error'; +import { task } from './module/task'; +import { reload } from './module/reload'; +import { apiDoc } from './module/api-doc'; +import { threeRouter } from './module/three-router'; +import { keepAlive } from './module/keep-alive'; +import { heartBeat } from './module/heart-beat'; +import { file } from './module/file'; + +/** + * + * iview-admin中meta除了原生参数外可配置的参数: + * meta: { + * title: { String|Number|Function } + * 显示在侧边栏、面包屑和标签栏的文字 + * 使用'{{ 多语言字段 }}'形式结合多语言使用,例子看多语言的路由配置; + * 可以传入一个回调函数,参数是当前路由对象,例子看动态路由和带参路由 + * hideInBread: (false) 设为true后此级路由将不会出现在面包屑中,示例看QQ群路由配置 + * hideInMenu: (false) 设为true后在左侧菜单不会显示该页面选项, + * group:{String} 同一功能模块下子页面的功能点权限继承菜单模块创建的路由权限 by lihaifan&lipeng + * noKeepAlive: (false) 设为true后页面在切换标签后不会缓存,如果需要缓存,无需设置这个字段,而且需要设置页面组件name属性和路由配置的name一致 + * access: (null) 可访问该页面的权限数组,当前路由设置的权限会影响子路由 + * } + */ +// 登录模块 +export const login = { + path: '/login', + name: 'login', + meta: { + hideInMenu: true, + title: 'Login - 登录' + }, + component: () => import('@/views/login/login.vue') +}; + +// 全部路由 +export const routers = [ + login, + ...home, + ...employee, + ...systemSetting, + ...notice, + ...emailSetting, + ...userLog, + ...monitor, + ...error, + ...task, + ...reload, + ...apiDoc, + ...threeRouter, + ...keepAlive, + ...heartBeat, + ...file +]; diff --git a/front/src/store/index.js b/front/src/store/index.js new file mode 100644 index 00000000..6883f539 --- /dev/null +++ b/front/src/store/index.js @@ -0,0 +1,25 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; + +import user from './module/user'; +import app from './module/app'; +import notice from './module/notice'; + +Vue.use(Vuex); + +export default new Vuex.Store({ + state: { + // + }, + mutations: { + // + }, + actions: { + // + }, + modules: { + user, + notice, + app + } +}); diff --git a/front/src/store/module/app.js b/front/src/store/module/app.js new file mode 100644 index 00000000..b7c028c3 --- /dev/null +++ b/front/src/store/module/app.js @@ -0,0 +1,131 @@ +import { + getBreadCrumbList, + setTagNavListInLocalStorage, + getMenuByRouter, + getTagNavListFromLocalStorage, + getHomeRoute, + getNextRoute, + routeHasExist, + routeEqual, + getRouteTitleHandled +} from '@/lib/menu-func'; +import { localSave, localRead } from '@/lib/local'; +import router from '@/router'; +import { routers } from '@/router/routers'; +import config from '@/config'; +const { homeName } = config; +// 关闭页面+tag +const closePage = (state, route) => { + const nextRoute = getNextRoute(state.tagNavList, route); + state.tagNavList = state.tagNavList.filter(item => { + return !routeEqual(item, route); + }); + router.push(nextRoute); +}; + +export default { + state: { + // 缓存路由 + keepAliveIncludes: [], + // 面包屑列表 + breadCrumbList: [], + // tag列表 + tagNavList: [], + // 首页路由 + homeRoute: {}, + // 本地缓存 + local: localRead('local'), + // 错误列表 + errorList: [], + hasReadErrorPage: false + }, + getters: { + // 左侧菜单 + menuList: (state, getters, rootState) => + getMenuByRouter(routers, rootState.user.access), + errorCount: state => state.errorList.length + }, + mutations: { + // 加入缓存 + pushKeepAliveIncludes (state, val) { + if (state.keepAliveIncludes.length < 30) { + let number = state.keepAliveIncludes.findIndex(e => e === val); + if (number === -1) { + state.keepAliveIncludes.push(val); + } + } + }, + // 删除缓存 + deleteKeepAliveIncludes (state, val) { + let number = state.keepAliveIncludes.findIndex(e => e === val); + if (number !== -1) { + state.keepAliveIncludes.splice(number, 1); + } + }, + // 清空缓存 + clearKeepAliveIncludes (state, val) { + state.keepAliveIncludes = [val]; + }, + // 关闭其他 + deleteOtherKeepAliveIncludes (state, val) { + state.keepAliveIncludes.forEach((item, index, arr) => { + if (item !== config.homeName && item !== val) { + arr.splice(index, 1); + } + }); + }, + // 设置其是否出现在面包屑中 + setBreadCrumb (state, route) { + state.breadCrumbList = getBreadCrumbList(route, state.homeRoute); + }, + // 初始化首页使用 + setHomeRoute (state, routes) { + state.homeRoute = getHomeRoute(routes, homeName); + }, + // 设置tag列表 + setTagNavList (state, list) { + let tagList = []; + if (list) { + tagList = [...list]; + } else tagList = getTagNavListFromLocalStorage() || []; + if (tagList[0] && tagList[0].name !== homeName) tagList.shift(); + let homeTagIndex = tagList.findIndex(item => item.name === homeName); + if (homeTagIndex > 0) { + let homeTag = tagList.splice(homeTagIndex, 1)[0]; + tagList.unshift(homeTag); + } + state.tagNavList = tagList; + setTagNavListInLocalStorage([...tagList]); + }, + // 关闭tag + closeTag (state, route) { + let tag = state.tagNavList.filter(item => routeEqual(item, route)); + route = tag[0] ? tag[0] : null; + if (!route) return; + closePage(state, route); + }, + // 关闭当前tag,且不进行跳转 + closeTagNotPushNextRoute (state, route) { + state.tagNavList = state.tagNavList.filter(item => { + return !routeEqual(item, route); + }); + }, + // 新增tag + addTag (state, { route, type = 'unshift' }) { + let router = getRouteTitleHandled(route); + if (!routeHasExist(state.tagNavList, router)) { + if (type === 'push') state.tagNavList.push(router); + else { + if (router.name === homeName) state.tagNavList.unshift(router); + else state.tagNavList.splice(1, 0, router); + } + setTagNavListInLocalStorage([...state.tagNavList]); + } + }, + // 保存本地信息 + setLocal (state, lang) { + localSave('local', lang); + state.local = lang; + } + } +}; diff --git a/front/src/store/module/notice.js b/front/src/store/module/notice.js new file mode 100644 index 00000000..3cff149e --- /dev/null +++ b/front/src/store/module/notice.js @@ -0,0 +1,19 @@ +import { noticeApi } from '@/api/notice'; +export default { + state: { + noticeList: [], + noticeNumber: 0 + }, + mutations: { + updateNotice(state, data) { + state.noticeList = [...state.noticeList, ...data]; + }, + updateNoticeNum(state, data) { + state.noticeNumber = data; + }, + restNotice(state) { + state.noticeList = []; + state.noticeNumber = 0; + } + } +}; diff --git a/front/src/store/module/user.js b/front/src/store/module/user.js new file mode 100644 index 00000000..eb2ca10a --- /dev/null +++ b/front/src/store/module/user.js @@ -0,0 +1,122 @@ +import cookie from '@/lib/cookie.js'; +import { loginApi } from '@/api/login'; +import { localSave, localRead } from '@/lib/local'; +import { getType } from '@/lib/util'; +import { PRIVILEGE_TYPE_ENUM } from '@/constants/privilege'; + +const localReadRouterPrivilege = () => { + let map = new Map(); + let userRouterPrivilegeString = localRead('userRouterPrivilege'); + if (userRouterPrivilegeString) { + let privilegeList = JSON.parse(userRouterPrivilegeString); + if (privilegeList) { + for (const path of privilegeList) { + let key = path.substr(1, 1); + let pathArray = map.get(key); + if (pathArray) { + pathArray.push(path); + } else { + pathArray = []; + pathArray.push(path); + map.set(key, pathArray); + } + } + } + } + return map; +}; + +export default { + state: { + token: cookie.getToken(), + // session信息 + userLoginInfo: {}, + isUpdatePrivilege: false, + // key为router name, value为 key的集合,用于v-privilege,页面功能点判断 + privilegeFunctionPointsMap: new Map(), + // 菜单key权限集合,用于左侧是否有菜单权限判断 + privilegeMenuKeyList: [], + /** + * key为 router path的首字母,value为集合 + * 这样做是为了提高查询效率,用于vue-router拦截判断path + */ + privilegeRouterPathMap: localReadRouterPrivilege() + + }, + mutations: { + // 设置token + setToken (state, token) { + state.token = token; + cookie.setToken(token); + }, + // 保存用户登录信息 + setUserLoginInfo (state, userLoginInfo) { + state.userLoginInfo = userLoginInfo; + localSave('userLoginInfo', JSON.stringify(userLoginInfo)); + }, + setUserPrivilege (state, privilegeList) { + state.isUpdatePrivilege = true; + let routerPathArray = []; + for (const privilege of privilegeList) { + // 是菜单权限 + if (privilege.type === PRIVILEGE_TYPE_ENUM.MENU.value) { + state.privilegeMenuKeyList.push(privilege.key); + if (privilege.url) { + routerPathArray.push(privilege.url); + // 去掉/之后第一个字母 + let key = privilege.url.substr(1, 1); + let pathArray = state.privilegeRouterPathMap.get(key); + if (pathArray) { + pathArray.push(privilege.url); + } else { + pathArray = []; + pathArray.push(privilege.url); + state.privilegeRouterPathMap.set(key, pathArray); + } + } + } + // 如果是功能点 + if (privilege.type === PRIVILEGE_TYPE_ENUM.POINTS.value) { + if (privilege.parentKey) { + let pointArray = state.privilegeFunctionPointsMap.get(privilege.parentKey); + if (pointArray) { + pointArray.push(privilege.key); + } else { + pointArray = []; + pointArray.push(privilege.key); + state.privilegeFunctionPointsMap.set(privilege.parentKey, pointArray); + } + } + } + } + localSave('userRouterPrivilege', JSON.stringify(routerPathArray)); + } + }, + getters: { + // 用户功能点权限 + userFuncPrivilegeInfo: () => localRead('funcPrivilegeInfo'), + // 用户菜单权限 + userMenuPrivilege: state => state.userLoginInfo.privilegeList + }, + actions: { + // 登录 + handleLogin ({ commit }, params) { + params.loginName = params.loginName.trim(); + return new Promise((resolve, reject) => { + loginApi + .login(params) + .then(res => { + localStorage.clear(); + const data = res.data; + commit('setToken', data.xaccessToken); + // 保存用户登录 + commit('setUserLoginInfo', data); + resolve(); + }) + .catch(err => { + reject(err); + }); + }); + } + } +}; diff --git a/front/src/themes/ReadMe.md b/front/src/themes/ReadMe.md new file mode 100644 index 00000000..57ab76e4 --- /dev/null +++ b/front/src/themes/ReadMe.md @@ -0,0 +1 @@ +这是配置主题及颜色的 diff --git a/front/src/themes/index.less b/front/src/themes/index.less new file mode 100644 index 00000000..2a2286f0 --- /dev/null +++ b/front/src/themes/index.less @@ -0,0 +1,302 @@ +@import '~iview/src/styles/index.less'; +/************** + 导航栏 +**************/ +// 导航栏背景 +@menu-dark-title: #001529; +@menu-dark-active-bg: #000c17; +@layout-sider-background: #001529; +@primary-color: #2d8cf0; +@blue: #2d8cf0; +@blueA100: #2e3c5a; +@blueA200: #e7f3ff; +@blueA300: #f0f7fd; +@blueA400: #001529; +@garyA100: #f5f5f5; +@garyA200: #666; +@garyA300: #999; +@tableColor: #eee; +@black: #444; + +.side-menu-wrapper { + // 一级菜单 高亮颜色 + .ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), + .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){ + color: #fff; + } + .ivu-menu-dark { + .ivu-menu { + .ivu-menu-submenu { + margin-bottom: 0; + } + + .ivu-menu-submenu-title { + padding: 10px 24px !important; + } + + .ivu-menu-submenu-has-parent-submenu { + padding-left: 51px; + } + + // 二级菜单 + .ivu-menu-item, + .ivu-menu-submenu-has-parent-submenu { + padding: 9px 0 9px 65px !important; + background: url('../assets/images/slider/sub_slider_default.png') 30px 0 + no-repeat !important; + + &:hover { + background: url('../assets/images/slider/sub_slider_default.png') 30px + 0 no-repeat !important; + } + + &.ivu-menu-item-active { + background: url('../assets/images/slider/sub_slider_active.png') 30px + 0 no-repeat !important; + border-right: 5px @primary-color solid; + + &:hover { + background: url('../assets/images/slider/sub_slider_active.png') + 30px 0 no-repeat !important; + border-right: 5px @primary-color solid; + } + } + } + .ivu-menu-submenu-has-parent-submenu { + padding-left: 41px !important; + .ivu-menu-submenu-title { + padding: 0 24px !important; + } + &.ivu-menu-child-item-active { + background: url('../assets/images/slider/sub_slider_active.png') 30px + 0 no-repeat !important; + border-right: 0; + } + .ivu-menu { + padding-top: 10px; + } + .ivu-menu-item, + .ivu-menu-item-active:hover { + background: none !important; + padding-left: 52px !important; + } + } + } + } +} + +// 导航栏 +.menu-collapsed { + text-align: center; + padding-top: 0 !important; +} + +// 左侧导航收缩 +.ivu-layout-sider-collapsed { + .ivu-dropdown { + text-align: center; + line-height: 38px; + margin: 0px auto; + color: #515a6e; + + &:hover { + color: @primary-color; + } + } + .ivu-tooltip { + line-height: 38px; + } +} +// 收缩导航栏鼠标经过下拉 +.menu-dropdown { + width: 160px; + left: 65px !important; + background: #001529; + border-radius: 3px; + color: #fff; + .ivu-dropdown-item { + color: #fff; + height: 40px; + line-height: 40px; + padding: 0 20px; + box-sizing: border-box; + .menu-title { + // padding:5px 0; + } + &:hover { + background: none; + border-right: 4px @primary-color solid; + } + } +} +/************** + header +**************/ +@layout-header-height: 52px; + +//面包屑 +.ivu-breadcrumb { + color: #515a6e; +} + +.ivu-breadcrumb-item-separator { + color: #515a6e; +} + + +/************** + table +**************/ +@table-thead-bg: #F7F7F9; +@border-color-split: #F7F7F9; +// @border-color-base: #F7F7F9; + +.ivu-table { + height: auto; + + table { + border-spacing: 0; + width: 100%; + tr { + &.ivu-table-row-hover { + tr, td { + animation: tableHover 0.5s; + } + } + th, td { + border: 1px @tableColor solid; + border-left: 0; + border-top: 0; + text-align: center; + &.ivu-table-column-left { + text-align: left; + } + &:nth-child(1) { + border-left: 0; + } + .ivu-table-cell { + padding: 0 8px; + } + .table-line { + background: @tableColor; + height: 1px; + margin: 8px -18px; + } + } + th { + color: @garyA200; + background: @garyA100; + height: 42px; + font-size: 14px; + color: #808080; + text-align: left; + } + td { + font-weight: normal; + padding: 2px 0; + height: 32px; + text-align: left; + font-size: 12px; + border-bottom: 1px solid #F7F7F9; + .ivu-table-cell-with-expand{ + height: 32px; + line-height: 32px; + } + } + } + } +} + +.ivu-table-body { + &::-webkit-scrollbar { + width: 10px; + height: 10px; + } +} + +.ivu-card-extra { + position: absolute; + right: 8px; + top: 8px; +} + +.ivu-card-head { + background: #fafafa; + border-radius: 4px 4px 0 0; + padding: 12px 16px; + font-size: 14px; + font-weight: bold; + .ivu-icon { + color: #666; + } +} + +.ivu-select-dropdown { + z-index: 10000; + &::-webkit-scrollbar { + width: 10px; + height: 10px; + } +} + +.ivu-dropdown-transfer, +.ivu-select-dropdown-transfer { + position: fixed; +} + +.ivu-table-fixed-body { + overflow: inherit; +} +.ivu-card{ + box-shadow: none !important; +} +// 表单类 +.ivu-btn{ + &:focus{ + box-shadow: none; + } +} +.ivu-form-item{ + margin-bottom: 15px; +} +.ivu-spin-fix{ + background-color: rgba(255, 255, 255, 0.3); +} + +// 重写4.0 table样式 +.ivu-table-wrapper{ + border: 1px solid #dcdee2; + border-bottom: 0; + border-right: 0; + .ivu-table{ + &:after{ + content: ""; + position: absolute; + background-color: #dcdee2; + width: 1px; + height: 100%; + top: 0; + right: 0; + z-index: 3; + } + } +} +// 重写字体大小 +.ivu-select, +.ivu-select-single .ivu-select-selection .ivu-select-placeholder, +.ivu-select-single .ivu-select-selection .ivu-select-selected-value, +.ivu-select-input, +.ivu-input, +textarea.ivu-input, +.ivu-btn, +.ivu-checkbox-wrapper, +.ivu-form .ivu-form-item-label{ + font-size: 12px; +} +.ivu-btn-large{ + font-size: 14px; +} +.ivu-select-item, +.ivu-dropdown-item{ + font-size: 12px !important; +} \ No newline at end of file diff --git a/front/src/views/api-doc/swagger.vue b/front/src/views/api-doc/swagger.vue new file mode 100644 index 00000000..c05f5e73 --- /dev/null +++ b/front/src/views/api-doc/swagger.vue @@ -0,0 +1,33 @@ + + + diff --git a/front/src/views/email/email-list.vue b/front/src/views/email/email-list.vue new file mode 100644 index 00000000..357998a8 --- /dev/null +++ b/front/src/views/email/email-list.vue @@ -0,0 +1,214 @@ + + + diff --git a/front/src/views/email/send-mail.vue b/front/src/views/email/send-mail.vue new file mode 100644 index 00000000..ae4bb47e --- /dev/null +++ b/front/src/views/email/send-mail.vue @@ -0,0 +1,214 @@ + + + + diff --git a/front/src/views/employee/components/department-employee-tree-item/department-employee-tree-item.vue b/front/src/views/employee/components/department-employee-tree-item/department-employee-tree-item.vue new file mode 100644 index 00000000..8f64b4d5 --- /dev/null +++ b/front/src/views/employee/components/department-employee-tree-item/department-employee-tree-item.vue @@ -0,0 +1,124 @@ + + + + diff --git a/front/src/views/employee/components/department-employee-tree/department-employee-tree.vue b/front/src/views/employee/components/department-employee-tree/department-employee-tree.vue new file mode 100644 index 00000000..d3367d81 --- /dev/null +++ b/front/src/views/employee/components/department-employee-tree/department-employee-tree.vue @@ -0,0 +1,251 @@ + + + + diff --git a/front/src/views/employee/position/position-list.vue b/front/src/views/employee/position/position-list.vue new file mode 100644 index 00000000..98870609 --- /dev/null +++ b/front/src/views/employee/position/position-list.vue @@ -0,0 +1,366 @@ + + + + diff --git a/front/src/views/employee/role-employee/components/employee-table-add/employee-table-add.vue b/front/src/views/employee/role-employee/components/employee-table-add/employee-table-add.vue new file mode 100644 index 00000000..e93daec4 --- /dev/null +++ b/front/src/views/employee/role-employee/components/employee-table-add/employee-table-add.vue @@ -0,0 +1,527 @@ + + + diff --git a/front/src/views/employee/role-employee/components/employee-table-detail/employee-table-detail.vue b/front/src/views/employee/role-employee/components/employee-table-detail/employee-table-detail.vue new file mode 100644 index 00000000..a2cc214d --- /dev/null +++ b/front/src/views/employee/role-employee/components/employee-table-detail/employee-table-detail.vue @@ -0,0 +1,72 @@ + + + diff --git a/front/src/views/employee/role-employee/components/employee-table/employee-table.vue b/front/src/views/employee/role-employee/components/employee-table/employee-table.vue new file mode 100644 index 00000000..fc2ef709 --- /dev/null +++ b/front/src/views/employee/role-employee/components/employee-table/employee-table.vue @@ -0,0 +1,569 @@ + + + diff --git a/front/src/views/employee/role-employee/role-employee-manage.vue b/front/src/views/employee/role-employee/role-employee-manage.vue new file mode 100644 index 00000000..034407a7 --- /dev/null +++ b/front/src/views/employee/role-employee/role-employee-manage.vue @@ -0,0 +1,831 @@ + + + + diff --git a/front/src/views/employee/role/components/role-data-scope/role-data-scope.vue b/front/src/views/employee/role/components/role-data-scope/role-data-scope.vue new file mode 100644 index 00000000..0413ce76 --- /dev/null +++ b/front/src/views/employee/role/components/role-data-scope/role-data-scope.vue @@ -0,0 +1,144 @@ + + + + diff --git a/front/src/views/employee/role/components/role-list/role-list.vue b/front/src/views/employee/role/components/role-list/role-list.vue new file mode 100644 index 00000000..bfef12f5 --- /dev/null +++ b/front/src/views/employee/role/components/role-list/role-list.vue @@ -0,0 +1,407 @@ + + + + diff --git a/front/src/views/employee/role/components/role-tree/role-tree.vue b/front/src/views/employee/role/components/role-tree/role-tree.vue new file mode 100644 index 00000000..9721599d --- /dev/null +++ b/front/src/views/employee/role/components/role-tree/role-tree.vue @@ -0,0 +1,403 @@ + + + + diff --git a/front/src/views/employee/role/role-manage.vue b/front/src/views/employee/role/role-manage.vue new file mode 100644 index 00000000..9765f362 --- /dev/null +++ b/front/src/views/employee/role/role-manage.vue @@ -0,0 +1,339 @@ + + + diff --git a/front/src/views/error-page/401.vue b/front/src/views/error-page/401.vue new file mode 100644 index 00000000..70b3c366 --- /dev/null +++ b/front/src/views/error-page/401.vue @@ -0,0 +1,19 @@ + + + diff --git a/front/src/views/error-page/404.vue b/front/src/views/error-page/404.vue new file mode 100644 index 00000000..291406f6 --- /dev/null +++ b/front/src/views/error-page/404.vue @@ -0,0 +1,19 @@ + + + diff --git a/front/src/views/error-page/500.vue b/front/src/views/error-page/500.vue new file mode 100644 index 00000000..e2a6c249 --- /dev/null +++ b/front/src/views/error-page/500.vue @@ -0,0 +1,19 @@ + + + diff --git a/front/src/views/error-page/back-btn-group.vue b/front/src/views/error-page/back-btn-group.vue new file mode 100644 index 00000000..7966849b --- /dev/null +++ b/front/src/views/error-page/back-btn-group.vue @@ -0,0 +1,40 @@ + + + diff --git a/front/src/views/error-page/error-content.vue b/front/src/views/error-page/error-content.vue new file mode 100644 index 00000000..d81d965e --- /dev/null +++ b/front/src/views/error-page/error-content.vue @@ -0,0 +1,28 @@ + + + diff --git a/front/src/views/error-page/error.less b/front/src/views/error-page/error.less new file mode 100644 index 00000000..63802459 --- /dev/null +++ b/front/src/views/error-page/error.less @@ -0,0 +1,46 @@ +.error-page{ + width: 100%; + height: 100%; + position: relative; + background: #f8f8f9; + .content-con{ + width: 700px; + height: 600px; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -60%); + img{ + display: block; + width: 100%; + height: 100%; + } + .text-con{ + position: absolute; + left: 0px; + top: 0px; + h4{ + position: absolute; + left: 0px; + top: 0px; + font-size: 80px; + font-weight: 700; + color: #348EED; + } + h5{ + position: absolute; + width: 700px; + left: 0px; + top: 100px; + font-size: 20px; + font-weight: 700; + color: #67647D; + } + } + .back-btn-group{ + position: absolute; + right: 0px; + bottom: 20px; + } + } +} diff --git a/front/src/views/file/file-list.vue b/front/src/views/file/file-list.vue new file mode 100644 index 00000000..9f79d984 --- /dev/null +++ b/front/src/views/file/file-list.vue @@ -0,0 +1,279 @@ + + + diff --git a/front/src/views/heart-beat/heart-beat-list.vue b/front/src/views/heart-beat/heart-beat-list.vue new file mode 100644 index 00000000..1637378e --- /dev/null +++ b/front/src/views/heart-beat/heart-beat-list.vue @@ -0,0 +1,115 @@ + + diff --git a/front/src/views/home/components/card.vue b/front/src/views/home/components/card.vue new file mode 100644 index 00000000..763eabf4 --- /dev/null +++ b/front/src/views/home/components/card.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/front/src/views/home/components/chart-bar.vue b/front/src/views/home/components/chart-bar.vue new file mode 100644 index 00000000..8130be3c --- /dev/null +++ b/front/src/views/home/components/chart-bar.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/front/src/views/home/components/chart-funnel.vue b/front/src/views/home/components/chart-funnel.vue new file mode 100644 index 00000000..dd076399 --- /dev/null +++ b/front/src/views/home/components/chart-funnel.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/front/src/views/home/components/chart-gauge.vue b/front/src/views/home/components/chart-gauge.vue new file mode 100644 index 00000000..99750aa7 --- /dev/null +++ b/front/src/views/home/components/chart-gauge.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/front/src/views/home/components/chart-line.vue b/front/src/views/home/components/chart-line.vue new file mode 100644 index 00000000..d7aeed44 --- /dev/null +++ b/front/src/views/home/components/chart-line.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/front/src/views/home/components/chart-pie.vue b/front/src/views/home/components/chart-pie.vue new file mode 100644 index 00000000..01037399 --- /dev/null +++ b/front/src/views/home/components/chart-pie.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/front/src/views/home/components/home-circle.vue b/front/src/views/home/components/home-circle.vue new file mode 100644 index 00000000..903ec4e2 --- /dev/null +++ b/front/src/views/home/components/home-circle.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/front/src/views/home/components/home-progress.vue b/front/src/views/home/components/home-progress.vue new file mode 100644 index 00000000..dc9682a7 --- /dev/null +++ b/front/src/views/home/components/home-progress.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/front/src/views/home/components/theme.json b/front/src/views/home/components/theme.json new file mode 100644 index 00000000..909b518a --- /dev/null +++ b/front/src/views/home/components/theme.json @@ -0,0 +1,490 @@ +{ + "color": [ + "#2d8cf0", + "#19be6b", + "#ff9900", + "#E46CBB", + "#9A66E4", + "#ed3f14" + ], + "backgroundColor": "rgba(0,0,0,0)", + "textStyle": {}, + "title": { + "textStyle": { + "color": "#516b91" + }, + "subtextStyle": { + "color": "#93b7e3" + } + }, + "line": { + "itemStyle": { + "normal": { + "borderWidth": "2" + } + }, + "lineStyle": { + "normal": { + "width": "2" + } + }, + "symbolSize": "6", + "symbol": "emptyCircle", + "smooth": true + }, + "radar": { + "itemStyle": { + "normal": { + "borderWidth": "2" + } + }, + "lineStyle": { + "normal": { + "width": "2" + } + }, + "symbolSize": "6", + "symbol": "emptyCircle", + "smooth": true + }, + "bar": { + "itemStyle": { + "normal": { + "barBorderWidth": 0, + "barBorderColor": "#ccc" + }, + "emphasis": { + "barBorderWidth": 0, + "barBorderColor": "#ccc" + } + } + }, + "pie": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "scatter": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "boxplot": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "parallel": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "sankey": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "funnel": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "gauge": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "candlestick": { + "itemStyle": { + "normal": { + "color": "#edafda", + "color0": "transparent", + "borderColor": "#d680bc", + "borderColor0": "#8fd3e8", + "borderWidth": "2" + } + } + }, + "graph": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + } + }, + "lineStyle": { + "normal": { + "width": 1, + "color": "#aaa" + } + }, + "symbolSize": "6", + "symbol": "emptyCircle", + "smooth": true, + "color": [ + "#2d8cf0", + "#19be6b", + "#f5ae4a", + "#9189d5", + "#56cae2", + "#cbb0e3" + ], + "label": { + "normal": { + "textStyle": { + "color": "#eee" + } + } + } + }, + "map": { + "itemStyle": { + "normal": { + "areaColor": "#f3f3f3", + "borderColor": "#516b91", + "borderWidth": 0.5 + }, + "emphasis": { + "areaColor": "rgba(165,231,240,1)", + "borderColor": "#516b91", + "borderWidth": 1 + } + }, + "label": { + "normal": { + "textStyle": { + "color": "#000" + } + }, + "emphasis": { + "textStyle": { + "color": "rgb(81,107,145)" + } + } + } + }, + "geo": { + "itemStyle": { + "normal": { + "areaColor": "#f3f3f3", + "borderColor": "#516b91", + "borderWidth": 0.5 + }, + "emphasis": { + "areaColor": "rgba(165,231,240,1)", + "borderColor": "#516b91", + "borderWidth": 1 + } + }, + "label": { + "normal": { + "textStyle": { + "color": "#000" + } + }, + "emphasis": { + "textStyle": { + "color": "rgb(81,107,145)" + } + } + } + }, + "categoryAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "valueAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "logAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "timeAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "toolbox": { + "iconStyle": { + "normal": { + "borderColor": "#999" + }, + "emphasis": { + "borderColor": "#666" + } + } + }, + "legend": { + "textStyle": { + "color": "#999999" + } + }, + "tooltip": { + "axisPointer": { + "lineStyle": { + "color": "#ccc", + "width": 1 + }, + "crossStyle": { + "color": "#ccc", + "width": 1 + } + } + }, + "timeline": { + "lineStyle": { + "color": "#8fd3e8", + "width": 1 + }, + "itemStyle": { + "normal": { + "color": "#8fd3e8", + "borderWidth": 1 + }, + "emphasis": { + "color": "#8fd3e8" + } + }, + "controlStyle": { + "normal": { + "color": "#8fd3e8", + "borderColor": "#8fd3e8", + "borderWidth": 0.5 + }, + "emphasis": { + "color": "#8fd3e8", + "borderColor": "#8fd3e8", + "borderWidth": 0.5 + } + }, + "checkpointStyle": { + "color": "#8fd3e8", + "borderColor": "rgba(138,124,168,0.37)" + }, + "label": { + "normal": { + "textStyle": { + "color": "#8fd3e8" + } + }, + "emphasis": { + "textStyle": { + "color": "#8fd3e8" + } + } + } + }, + "visualMap": { + "color": [ + "#516b91", + "#59c4e6", + "#a5e7f0" + ] + }, + "dataZoom": { + "backgroundColor": "rgba(0,0,0,0)", + "dataBackgroundColor": "rgba(255,255,255,0.3)", + "fillerColor": "rgba(167,183,204,0.4)", + "handleColor": "#a7b7cc", + "handleSize": "100%", + "textStyle": { + "color": "#333" + } + }, + "markPoint": { + "label": { + "normal": { + "textStyle": { + "color": "#eee" + } + }, + "emphasis": { + "textStyle": { + "color": "#eee" + } + } + } + } +} \ No newline at end of file diff --git a/front/src/views/home/home.vue b/front/src/views/home/home.vue new file mode 100644 index 00000000..6992ab69 --- /dev/null +++ b/front/src/views/home/home.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/front/src/views/home/index.js b/front/src/views/home/index.js new file mode 100644 index 00000000..5f66ed9d --- /dev/null +++ b/front/src/views/home/index.js @@ -0,0 +1,2 @@ +import home from './home.vue'; +export default home; diff --git a/front/src/views/keep-alive/add-content.vue b/front/src/views/keep-alive/add-content.vue new file mode 100644 index 00000000..0c2290dd --- /dev/null +++ b/front/src/views/keep-alive/add-content.vue @@ -0,0 +1,94 @@ + + + + diff --git a/front/src/views/keep-alive/content-list.vue b/front/src/views/keep-alive/content-list.vue new file mode 100644 index 00000000..11b34887 --- /dev/null +++ b/front/src/views/keep-alive/content-list.vue @@ -0,0 +1,80 @@ + + + + diff --git a/front/src/views/login/canvas.js b/front/src/views/login/canvas.js new file mode 100644 index 00000000..37976ad7 --- /dev/null +++ b/front/src/views/login/canvas.js @@ -0,0 +1,289 @@ +// 离子波浪 +export const lonWave = () => { + var starlings = function (n, r, t, o, e, u, i, f) { + var a = f.onSetup + void 0 === a && (a = null) + var v = f.onRepeat + void 0 === v && (v = null) + var c = f.modifier + void 0 === c && (c = null) + var l = f.perspective + void 0 === l && (l = 1) + var d = f.pixelRatio + void 0 === d && (d = 1) + var m = f.triangles + void 0 === m && (m = !1) + var s + var p + var y = r.length + var w = function (n, r) { + let t = s.createShader(n) + return s.shaderSource(t, r), s.compileShader(t), t + } + var b = function () { + for (var n = 0; n < o.length; n += 1) { + for (var r = s.createBuffer(), e = o[n], u = e.data(0, 0).length, i = new Float32Array(t * y * u), f = 0; f < t; f += 1) { + for (var a = e.data(f, t), v = f * y * u, l = 0; l < y; l += 1) { + for (var d = 0; d < u; d += 1) { + c !== null && e.name === c.attribute ? i[v] = c.value(i[v], a, d, l) : i[v] = a[d] + v += 1 + } + } + } + s.bindBuffer(s.ARRAY_BUFFER, r) + s.bufferData(s.ARRAY_BUFFER, i, s.STATIC_DRAW) + var m = s.getAttribLocation(p, o[n].name) + s.enableVertexAttribArray(m) + s.vertexAttribPointer(m, u, s.FLOAT, !1, !1, 0, 0) + } + } + var A = function () { + e.push({ + name: 'uMVP', + type: 'mat4' + }) + for (var n = 0; n < e.length; n += 1) { + var r = s.getUniformLocation(p, e[n].name) + e[n].location = r + } + } + var F = { + float: function (n, r) { + return s.uniform1f(n, r) + }, + vec2: function (n, r) { + return s.uniform2fv(n, r) + }, + vec3: function (n, r) { + return s.uniform3fv(n, r) + }, + vec4: function (n, r) { + return s.uniform4fv(n, r) + }, + mat2: function (n, r) { + return s.uniformMatrix2fv(n, !1, r) + }, + mat3: function (n, r) { + return s.uniformMatrix3fv(n, !1, r) + }, + mat4: function (n, r) { + return s.uniformMatrix4fv(n, !1, r) + } + } + var g = function () { + s.clear(16640) + s.useProgram(p) + v !== null && v(s, p, e) + for (var n = 0; n < e.length; n += 1) F[e[n].type](e[n].location, e[n].value) + s.drawArrays(m ? s.TRIANGLES : s.POINTS, 0, y * t) + requestAnimationFrame(g) + } + var h = function () { + n.width = n.clientWidth * d + n.height = n.clientHeight * d + var r = s.drawingBufferWidth + var t = s.drawingBufferHeight + s.viewport(0, 0, r, t) + e[e.length - 1].value = [l / (r / t), 0, 0, 0, 0, l, 0, 0, 0, 0, -1, -1, 0, 0, 1, 1] + } + s = n.getContext('webgl') + p = s.createProgram() + s.attachShader(p, w(s.VERTEX_SHADER, u)) + s.attachShader(p, w(s.FRAGMENT_SHADER, i)) + s.linkProgram(p) + A() + h() + b() + a !== null && a(s) + g() + window.addEventListener('resize', h, !1) + } + + // Do you like rainbow waves? + var rainbow = false + + // Need more performance? + var HD = true + + var canvas = document.getElementById('canvas') + var background = document.querySelector('.background') + var bar = document.querySelector('.progress') + var initialize = function initialize (vertices) { + var pixelRatio = HD ? window.devicePixelRatio : 1 + var rows = HD ? 90 : 90 + var multiplier = rows * rows + var duration = 0.4 + var geometry = [{ + x: 0, + y: 0, + z: 0 + }] + var pointSize = (HD ? 6 : 2).toFixed(1) + + var step = 0.004 + var size = 5 + var attributes = [{ + name: 'aPositionStart', + data: function data (i, total) { + return [size - (i % rows / rows + 0.5 / rows) * (size * 2), -1, (size - (Math.floor(i / rows) / rows + 0.5 / rows) * size * 2) * -1] + } + }, + { + name: 'aControlPointOne', + data: function data (i) { + return [size - (i % rows / rows + 0.5 / rows) * (size * 2), -0.5 + getRandom(0.2), (size - (Math.floor(i / rows) / rows + 0.5 / rows) * size * 2) * -1] + } + }, + { + name: 'aControlPointTwo', + data: function data (i) { + return [size - (i % rows / rows + 0.5 / rows) * (size * 2), -0.5 + getRandom(0.2), (size - (Math.floor(i / rows) / rows + 0.5 / rows) * size * 2) * -1] + } + }, + { + name: 'aPositionEnd', + data: function data (i) { + return [size - (i % rows / rows + 0.5 / rows) * (size * 2), -1, (size - (Math.floor(i / rows) / rows + 0.5 / rows) * size * 2) * -1] + } + }, + { + name: 'aOffset', + data: function data (i) { + return [i * ((1 - duration) / (multiplier - 1))] + } + }, + { + name: 'aColor', + data: function data (i, total) { + return getHSL(rainbow ? i / total * 1.0 : 0.5 + i / total * 0.4, 0.5, 0.5) + } + }] + + var uniforms = [{ + name: 'uProgress', + type: 'float', + value: 0.8 + }] + + var vertexShader = '\n attribute vec3 aPositionStart;\n attribute vec3 aControlPointOne;\n attribute vec3 aControlPointTwo;\n attribute vec3 aPositionEnd;\n attribute float aOffset;\n attribute vec3 aColor;\n\n uniform float uProgress;\n uniform mat4 uMVP;\n\n varying vec3 vColor;\n\n vec3 bezier4(vec3 a, vec3 b, vec3 c, vec3 d, float t) {\n return mix(mix(mix(a, b, t), mix(b, c, t), t), mix(mix(b, c, t), mix(c, d, t), t), t);\n }\n\n float easeInOutQuint(float t){\n return t < 0.5 ? 16.0 * t * t * t * t * t : 1.0 + 16.0 * (--t) * t * t * t * t;\n }\n\n void main () {\n float tProgress = easeInOutQuint(min(1.0, max(0.0, (uProgress - aOffset)) / ' + duration + '));\n vec3 newPosition = bezier4(aPositionStart, aControlPointOne, aControlPointTwo, aPositionEnd, tProgress);\n gl_PointSize = ' + pointSize + ' + ((newPosition.y + 1.0) * 80.0);\n gl_Position = uMVP * vec4(newPosition, 1.0);\n vColor = aColor;\n }\n' + + var fragmentShader = '\n precision mediump float;\n\n varying vec3 vColor;\n\n void main() {\n vec2 pc = 2.0 * gl_PointCoord - 1.0;\n gl_FragColor = vec4(vColor, 1.0 - dot(pc, pc));\n }\n' + + var onSetup = function onSetup (gl) { + gl.blendFunc(gl.SRC_ALPHA, gl.ONE) + gl.enable(gl.BLEND) + } + + var onRepeat = function onRepeat () { + rotateY(uniforms[uniforms.length - 1].value, 0.002) + if (uniforms[0].value < 0) { + uniforms[0].value = 1 + } + uniforms[0].value -= step + } + + var options = { + onSetup: onSetup, + onRepeat: onRepeat, + pixelRatio: pixelRatio + } + + starlings(canvas, geometry, multiplier, attributes, uniforms, vertexShader, fragmentShader, options) + } + + var getRandom = function getRandom (value) { + return Math.random() * value - value / 2 + } + + var rotateY = function rotateY (matrix, angle) { + var sin = Math.sin(angle) + var cos = Math.cos(angle) + var clone = JSON.parse(JSON.stringify(matrix)) + + matrix[0] = clone[0] * cos - clone[8] * sin + matrix[1] = clone[1] * cos - clone[9] * sin + matrix[2] = clone[2] * cos - clone[10] * sin + matrix[3] = clone[3] * cos - clone[11] * sin + matrix[8] = clone[0] * sin + clone[8] * cos + matrix[9] = clone[1] * sin + clone[9] * cos + matrix[10] = clone[2] * sin + clone[10] * cos + matrix[11] = clone[3] * sin + clone[11] * cos + } + + var h2r = function h2r (p, q, t) { + if (t < 0) t += 1 + if (t > 1) t -= 1 + if (t < 1 / 6) return p + (q - p) * 6 * t + if (t < 1 / 2) return q + if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t) + return p + } + + var getHSL = function getHSL (h, s, l) { + h = (h % 1 + 1) % 1 + s = Math.max(0, Math.min(1, s)) + l = Math.max(0, Math.min(1, l)) + if (s === 0) return [l, l, l] + var p = l <= 0.5 ? l * (1 + s) : l + s - l * s + var q = 2 * l - p + return [h2r(q, p, h + 1 / 3), h2r(q, p, h), h2r(q, p, h - 1 / 3)] + } + initialize() +} + +// 随机线条 +export const canvasParticle = (function () { + function getElementByTag (name) { return document.getElementsByTagName(name) } + function getELementById (id) { return document.getElementById(id) } + function canvasInit (canvasConfig) { + canvasConfig = canvasConfig || {} + var html = getElementByTag('html')[0] + var body = document.getElementById('canvasView') + var canvasObj = document.createElement('canvas') + var canvas = { element: canvasObj, points: [], config: { vx: canvasConfig.vx || 4, vy: canvasConfig.vy || 4, height: canvasConfig.height || 2, width: canvasConfig.width || 2, count: canvasConfig.count || 100, color: canvasConfig.color || '121, 162, 185', stroke: canvasConfig.stroke || '130,255,255', dist: canvasConfig.dist || 6000, e_dist: canvasConfig.e_dist || 20000, max_conn: 10 } }; if (canvas.element.getContext('2d')) { canvas.context = canvas.element.getContext('2d') } else { return null } + body.style.padding = '0'; body.style.margin = '0'; body.appendChild(canvas.element); canvas.element.style = 'position: fixed; top: 0; left: 0; z-index: -1;'; canvasSize(canvas.element); window.onresize = function () { canvasSize(canvas.element) } + body.onmousemove = function (e) { var event = e || window.event; canvas.mouse = { x: event.clientX, y: event.clientY } } + document.onmouseleave = function () { canvas.mouse = undefined } + setInterval(function () { drawPoint(canvas) }, 40) + } + function canvasSize (canvas) { + var width = document.getElementById('canvasView').style.width + var height = document.getElementById('canvasView').style.height + width = parseInt(width); height = parseInt(height) + canvas.width = width || window.innerWeight || document.documentElement.clientWidth || document.body.clientWidth; canvas.height = height || window.innerWeight || document.documentElement.clientHeight || document.body.clientHeight + } + function drawPoint (canvas) { + var context = canvas.context + var point + var dist + context.clearRect(0, 0, canvas.element.width, canvas.element.height); context.beginPath(); context.fillStyle = 'rgb(' + canvas.config.color + ')'; for (var i = 0, len = canvas.config.count; i < len; i++) { + if (canvas.points.length != canvas.config.count) { point = { x: Math.floor(Math.random() * canvas.element.width), y: Math.floor(Math.random() * canvas.element.height), vx: canvas.config.vx / 2 - Math.random() * canvas.config.vx, vy: canvas.config.vy / 2 - Math.random() * canvas.config.vy } } else { point = borderPoint(canvas.points[i], canvas) } + context.fillRect(point.x - canvas.config.width / 2, point.y - canvas.config.height / 2, canvas.config.width, canvas.config.height); canvas.points[i] = point + } + drawLine(context, canvas, canvas.mouse); context.closePath() + } + function borderPoint (point, canvas) { + var p = point; if (point.x <= 0 || point.x >= canvas.element.width) { p.vx = -p.vx; p.x += p.vx } else if (point.y <= 0 || point.y >= canvas.element.height) { p.vy = -p.vy; p.y += p.vy } else { p = { x: p.x + p.vx, y: p.y + p.vy, vx: p.vx, vy: p.vy } } + return p + } + function drawLine (context, canvas, mouse) { + let dist + context = context || canvas.context; for (var i = 0, len = canvas.config.count; i < len; i++) { + canvas.points[i].max_conn = 0; for (var j = 0; j < len; j++) { + if (i != j) { + dist = Math.round(canvas.points[i].x - canvas.points[j].x) * Math.round(canvas.points[i].x - canvas.points[j].x) + + Math.round(canvas.points[i].y - canvas.points[j].y) * Math.round(canvas.points[i].y - canvas.points[j].y); if (dist <= canvas.config.dist && canvas.points[i].max_conn < canvas.config.max_conn) { + canvas.points[i].max_conn++; context.lineWidth = 0.5 - dist / canvas.config.dist; context.strokeStyle = 'rgba(' + canvas.config.stroke + ',' + (1 - dist / canvas.config.dist) + ')' + context.beginPath(); context.moveTo(canvas.points[i].x, canvas.points[i].y); context.lineTo(canvas.points[j].x, canvas.points[j].y); context.stroke() + } + } + } + if (mouse) { + dist = Math.round(canvas.points[i].x - mouse.x) * Math.round(canvas.points[i].x - mouse.x) + + Math.round(canvas.points[i].y - mouse.y) * Math.round(canvas.points[i].y - mouse.y); if (dist > canvas.config.dist && dist <= canvas.config.e_dist) { canvas.points[i].x = canvas.points[i].x + (mouse.x - canvas.points[i].x) / 20; canvas.points[i].y = canvas.points[i].y + (mouse.y - canvas.points[i].y) / 20 } + if (dist <= canvas.config.e_dist) { context.lineWidth = 1; context.strokeStyle = 'rgba(' + canvas.config.stroke + ',' + (1 - dist / canvas.config.e_dist) + ')'; context.beginPath(); context.moveTo(canvas.points[i].x, canvas.points[i].y); context.lineTo(mouse.x, mouse.y); context.stroke() } + } + } + } + return canvasInit +})() diff --git a/front/src/views/login/components/login-form.vue b/front/src/views/login/components/login-form.vue new file mode 100644 index 00000000..558d4bc6 --- /dev/null +++ b/front/src/views/login/components/login-form.vue @@ -0,0 +1,133 @@ + + \ No newline at end of file diff --git a/front/src/views/login/login.less b/front/src/views/login/login.less new file mode 100644 index 00000000..d1d6fc2b --- /dev/null +++ b/front/src/views/login/login.less @@ -0,0 +1,128 @@ +.center { + text-align: center; +} + +.login { + font-family: Arial, "PingFang SC", "Microsoft YaHei"; + width: 100%; + height: 100%; + background: url(../../assets/images/login-bg.jpg) no-repeat fixed; + background-size: cover; + + .content { + width: 424px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -56%) + } + .ivu-card { + background: rgba(255, 255, 255, 0.95); + border-radius: 10px; + box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3); + } + .form-con { + margin: 32px 0; + width: 424px; + background: #fff; + padding: 32px 32px; + border-radius: 0 8px 8px 0; + .ivu-input { + border: 1px solid #E8E8EE; + border-radius: 4px; + font-size: 16px; + color: #525252; + padding: 0 20px; + &:focus { + border: 1px solid #0097F6; + box-shadow: none; + } + } + .ivu-form-item-error-tip { + height: 30px; + line-height: 30px; + padding: 0; + color: #f66; + top:90%; + } + .ivu-form-item { + margin-bottom: 22px; + } + .remember { + margin: -10px 0 10px; + } + .ivu-input, + .ivu-btn { + height: 48px; + } + .ivu-btn { + font-size: 16px; + } + .ivu-input-group-prepend { + padding: 4px 15px; + } + .code-input { + width: 172px; + } + .codeUrl { + height: 80%; + position: absolute; + z-index: 3; + top: 0; + bottom: 0; + margin: auto; + right: 24px; + border-radius: 0 4px 4px 0; + cursor: pointer; + } + } + .login-tip { + font-size: 10px; + text-align: center; + color: #c3c3c3; + } + .footerDesc { + font-family: "MicrosoftYaHei"; + color: #A6A6A8; + font-size: 14px; + } + .otherWay { + font-size: 14px; + font-family: "Microsoft YaHei"; + .inline { + display: inline-block; + } + .align { + vertical-align: middle; + } + .marginLeft { + margin-left: 20px; + float:right; + } + } + .remember { + font-size: 14px; + } +} +.draw { + position: fixed; + width: 1px; + z-index: 99999; + line-height: 1px; + pointer-events: none; +} + +@keyframes floatOne { + 0% { + opacity: 1; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + transform: translate3D(0, -20px, 0) scale(5) rotate(45deg); + } +} \ No newline at end of file diff --git a/front/src/views/login/login.vue b/front/src/views/login/login.vue new file mode 100644 index 00000000..89e4fd19 --- /dev/null +++ b/front/src/views/login/login.vue @@ -0,0 +1,52 @@ + + + + diff --git a/front/src/views/monitor/online-user.vue b/front/src/views/monitor/online-user.vue new file mode 100644 index 00000000..b133c303 --- /dev/null +++ b/front/src/views/monitor/online-user.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/front/src/views/monitor/sql.vue b/front/src/views/monitor/sql.vue new file mode 100644 index 00000000..ced71bf8 --- /dev/null +++ b/front/src/views/monitor/sql.vue @@ -0,0 +1,33 @@ + + + diff --git a/front/src/views/notice/notice-list.vue b/front/src/views/notice/notice-list.vue new file mode 100644 index 00000000..933675e6 --- /dev/null +++ b/front/src/views/notice/notice-list.vue @@ -0,0 +1,397 @@ + + + + + diff --git a/front/src/views/notice/person-notice.vue b/front/src/views/notice/person-notice.vue new file mode 100644 index 00000000..cc2fec01 --- /dev/null +++ b/front/src/views/notice/person-notice.vue @@ -0,0 +1,221 @@ + + + + + diff --git a/front/src/views/reload/smart-reload/smart-reload-list.vue b/front/src/views/reload/smart-reload/smart-reload-list.vue new file mode 100644 index 00000000..b0027c4c --- /dev/null +++ b/front/src/views/reload/smart-reload/smart-reload-list.vue @@ -0,0 +1,273 @@ + + diff --git a/front/src/views/system-setting/system-config/system-config.vue b/front/src/views/system-setting/system-config/system-config.vue new file mode 100644 index 00000000..0fd884a4 --- /dev/null +++ b/front/src/views/system-setting/system-config/system-config.vue @@ -0,0 +1,397 @@ + + + diff --git a/front/src/views/system-setting/system-privilege/components/privilege-form.vue b/front/src/views/system-setting/system-privilege/components/privilege-form.vue new file mode 100644 index 00000000..6233c82f --- /dev/null +++ b/front/src/views/system-setting/system-privilege/components/privilege-form.vue @@ -0,0 +1,144 @@ + + + diff --git a/front/src/views/system-setting/system-privilege/system-privilege.vue b/front/src/views/system-setting/system-privilege/system-privilege.vue new file mode 100644 index 00000000..c6b33e4e --- /dev/null +++ b/front/src/views/system-setting/system-privilege/system-privilege.vue @@ -0,0 +1,318 @@ + + + diff --git a/front/src/views/task/task-list.vue b/front/src/views/task/task-list.vue new file mode 100644 index 00000000..26942927 --- /dev/null +++ b/front/src/views/task/task-list.vue @@ -0,0 +1,545 @@ + + + + + diff --git a/front/src/views/user-log/user-login-log.vue b/front/src/views/user-log/user-login-log.vue new file mode 100644 index 00000000..f326625c --- /dev/null +++ b/front/src/views/user-log/user-login-log.vue @@ -0,0 +1,181 @@ + + + diff --git a/front/src/views/user-log/user-operate-log.vue b/front/src/views/user-log/user-operate-log.vue new file mode 100644 index 00000000..db47df63 --- /dev/null +++ b/front/src/views/user-log/user-operate-log.vue @@ -0,0 +1,252 @@ + + + + + diff --git a/front/tests/e2e/.eslintrc b/front/tests/e2e/.eslintrc new file mode 100644 index 00000000..02023fba --- /dev/null +++ b/front/tests/e2e/.eslintrc @@ -0,0 +1,12 @@ +{ + "plugins": [ + "cypress" + ], + "env": { + "mocha": true, + "cypress/globals": true + }, + "rules": { + "strict": "off" + } +} diff --git a/front/tests/e2e/plugins/index.js b/front/tests/e2e/plugins/index.js new file mode 100644 index 00000000..cfefc78b --- /dev/null +++ b/front/tests/e2e/plugins/index.js @@ -0,0 +1,9 @@ +// https://docs.cypress.io/guides/guides/plugins-guide.html + +module.exports = (on, config) => Object.assign({}, config, { + fixturesFolder: 'tests/e2e/fixtures', + integrationFolder: 'tests/e2e/specs', + screenshotsFolder: 'tests/e2e/screenshots', + videosFolder: 'tests/e2e/videos', + supportFile: 'tests/e2e/support/index.js' +}) diff --git a/front/tests/e2e/specs/test.js b/front/tests/e2e/specs/test.js new file mode 100644 index 00000000..41ad94a0 --- /dev/null +++ b/front/tests/e2e/specs/test.js @@ -0,0 +1,8 @@ +// https://docs.cypress.io/api/introduction/api.html + +describe('My First Test', () => { + it('Visits the app root url', () => { + cy.visit('/') + cy.contains('h1', 'Welcome to Your Vue.js App') + }) +}) diff --git a/front/tests/e2e/support/commands.js b/front/tests/e2e/support/commands.js new file mode 100644 index 00000000..c1f5a772 --- /dev/null +++ b/front/tests/e2e/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add("login", (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This is will overwrite an existing command -- +// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/front/tests/e2e/support/index.js b/front/tests/e2e/support/index.js new file mode 100644 index 00000000..d68db96d --- /dev/null +++ b/front/tests/e2e/support/index.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/front/tests/unit/.eslintrc.js b/front/tests/unit/.eslintrc.js new file mode 100644 index 00000000..8038afe9 --- /dev/null +++ b/front/tests/unit/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + env: { + mocha: true + }, + rules: { + 'import/no-extraneous-dependencies': 'off' + } +} diff --git a/front/tests/unit/HelloWorld.spec.js b/front/tests/unit/HelloWorld.spec.js new file mode 100644 index 00000000..bb668bf4 --- /dev/null +++ b/front/tests/unit/HelloWorld.spec.js @@ -0,0 +1,13 @@ +import { expect } from 'chai' +import { shallow } from '@vue/test-utils' +import HelloWorld from '@/components/HelloWorld.vue' + +describe('HelloWorld.vue', () => { + it('renders props.msg when passed', () => { + const msg = 'new message' + const wrapper = shallow(HelloWorld, { + propsData: { msg } + }) + expect(wrapper.text()).to.include(msg) + }) +}) diff --git a/front/vscode/settings.json b/front/vscode/settings.json new file mode 100644 index 00000000..ab4bb79a --- /dev/null +++ b/front/vscode/settings.json @@ -0,0 +1,43 @@ +{ + "terminal.integrated.shell.windows": "C:\\WINDOWS\\System32\\cmd.exe", + "jetbrainsKeymap.promptV3Features": true, + "editor.multiCursorModifier": "ctrlCmd", + "editor.formatOnPaste": true, + "debug.allowBreakpointsEverywhere": true, + "files.autoSave": "afterDelay", + "workbench.colorTheme": "One Dark Pro", + "workbench.iconTheme": "vscode-icons", + "vetur.validation.template": false, + "[javascript]": { + "editor.defaultFormatter": "vscode.typescript-language-features" + }, + "[less]": { + "editor.defaultFormatter": "HookyQR.beautify" + }, + "javascript.format.insertSpaceBeforeFunctionParenthesis": true, + "eslint.autoFixOnSave": true, + "eslint.alwaysShowStatus": true, + "workbench.startupEditor": "newUntitledFile", + //"vetur.format.defaultFormatter.html": "js-beautify-html", + //"vetur.format.defaultFormatter.js": "vscode-typescript", //让vue中的js按编辑器自带的ts格式进行格式化 + "vetur.format.defaultFormatterOptions": { + // "js-beautify-html": { + // // force|force-aligned | force-expand-multiline + // "wrap_line_length": 100, + // "wrap_attributes": "auto", + // "end_with_newline": false + // //"wrap_attributes": "auto" + // }, + "prettyhtml": { + "printWidth": 100, + "singleQuote": false, + "wrapAttributes": false, + "sortAttributes": true + }, + "prettier": { + "semi": true, + "singleQuote": true + } + }, + "search.location": "panel", +} diff --git a/front/vue.config.js b/front/vue.config.js new file mode 100644 index 00000000..827c711d --- /dev/null +++ b/front/vue.config.js @@ -0,0 +1,78 @@ +const path = require('path'); +const resolve = dir => { + return path.join(__dirname, dir); +}; +const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); +const CompressionWebpackPlugin = require('compression-webpack-plugin'); +const productionGzipExtensions = ['js', 'css']; +// 项目部署基础 +// 默认情况下,我们假设你的应用将被部署在域的根目录下, +// 例如:https://www.my-app.com/ +// 默认:'/' +// 如果您的应用程序部署在子路径中,则需要在这指定子路径 +// 例如:https://www.foobar.com/my-app/ +// 需要将它改为'/my-app/' +// iview-admin线上演示打包路径: https://file.iviewui.com-dist/ +const publicPath = process.env.NODE_ENV === 'production' ? '/' : '/'; +const lintOnSave = process.env.NODE_ENV === 'production'; + +module.exports = { + // Project deployment base + // By default we assume your app will be deployed at the root of a domain, + // e.g. https://www.my-app.com/ + // If your app is deployed at a sub-path, you will need to specify that + // sub-path here. For example, if your app is deployed at + // https://www.foobar.com/my-app/ + // then change this to '/my-app/' + publicPath, + // tweak internal webpack configuration. + // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md + // 如果你不需要使用eslint,把lintOnSave设为false即可 + lintOnSave, + chainWebpack: config => { + config.entry = { + main: ['babel-polyfill', './src/main'], + vendors: './src/vendors' + }; + config.module + .rule('iview') + .test(/iview.src.*?js$/) + .use('babel') + .loader('babel-loader') + .end(); + config.resolve.alias + .set('@', resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components')) + .set('_c', resolve('src/components')); + }, + // 设为false打包时不生成.map文件 + productionSourceMap: false, + // 这里写你调用接口的基础路径,来解决跨域,如果设置了代理,那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串 + // devServer: { + // proxy: 'localhost:3000' + // } + configureWebpack: { + plugins: [ + // 开启gzip压缩 + new CompressionWebpackPlugin({ + algorithm: 'gzip', + test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), + threshold: 10240, + minRatio: 0.8 + }) + ], + optimization: { + minimizer: [ + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: true, + drop_console: true, // console + drop_debugger: true, + pure_funcs: ['console.log'] // 移除console + } + } + }) + ] + } + } +}; diff --git a/java/smart-admin-api/doc/readme.txt b/java/smart-admin-api/doc/readme.txt new file mode 100644 index 00000000..e5cd39c0 --- /dev/null +++ b/java/smart-admin-api/doc/readme.txt @@ -0,0 +1,17 @@ +1 更新密码 +com.gangquan360.smartadmin.module.employee.EmployeeController.updatePwd + +2 更新功能点 +PrivilegeController functionSaveOrUpdate和menuBatchSave + +3 超管默认账号 +sa/123456 + +4 执行脚本: +先执行:src/main/resources/sql/smart-admin.sql +再执行:src/main/resources/sql/quartz_mysql_2.3.0.sql + +5 除dev之外文件 + +6 刷新页面,获取权限是否走缓存 +com.gangquan360.smartadmin.module.login.LoginService.getSession \ No newline at end of file diff --git a/java/smart-admin-api/pom.xml b/java/smart-admin-api/pom.xml new file mode 100644 index 00000000..c40ad514 --- /dev/null +++ b/java/smart-admin-api/pom.xml @@ -0,0 +1,386 @@ + + + com.gangquan360 + smart-admin-parent + 1.0.0 + + + 4.0.0 + smart-admin-api + jar + + smart-admin-api + + + UTF-8 + UTF-8 + + + + + + velocity + + + commons-collections + commons-collections + + + org.apache.velocity + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + org.apache.logging.log4j + log4j-web + 2.10.0 + + + + org.springframework.boot + spring-boot-starter-actuator + + + logback-classic + ch.qos.logback + + + spring-boot-starter-logging + org.springframework.boot + + + + + + org.springframework.boot + spring-boot-starter-websocket + + + + org.projectlombok + lombok + provided + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter + + + + + + com.microsoft.sqlserver + mssql-jdbc + + + + + com.alibaba + druid + + + + com.alibaba + fastjson + + + + org.springframework.boot + spring-boot-starter-jdbc + + + logback-classic + ch.qos.logback + + + spring-boot-starter + org.springframework.boot + + + + + + mysql + mysql-connector-java + + + + com.baomidou + mybatisplus-spring-boot-starter + + + spring-boot-starter-logging + org.springframework.boot + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-devtools + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + io.jsonwebtoken + jjwt + + + + org.springframework.boot + spring-boot-starter-mail + + + spring-boot-starter + org.springframework.boot + + + + + org.springframework.boot + spring-boot-starter-quartz + + + org.quartz-scheduler + quartz + + + org.quartz-scheduler + quartz-jobs + + + + org.apache.commons + commons-lang3 + + + + + io.springfox + springfox-swagger2 + + + + io.springfox + springfox-swagger-ui + + + + com.googlecode.concurrentlinkedhashmap + concurrentlinkedhashmap-lru + + + + org.springframework.boot + spring-boot-starter-aop + + + + org.apache.velocity + velocity-engine-core + test + + + + + redis.clients + jedis + + + + cn.afterturn + easypoi-base + + + javassist + org.javassist + + + + + + cn.afterturn + easypoi-web + + + + cn.afterturn + easypoi-annotation + + + + org.apache.poi + poi + + + + org.apache.poi + poi-ooxml-schemas + + + + org.apache.poi + poi-ooxml + + + + commons-beanutils + commons-beanutils + + + + com.thoughtworks.xstream + xstream + 1.4.10 + + + + org.springframework.boot + spring-boot-test + + + + + com.qiniu + qiniu-java-sdk + + + + + com.aliyun.oss + aliyun-sdk-oss + + + commons-lang + commons-lang + + + commons-logging + commons-logging + + + commons-collections + commons-collections + + + + + + com.baomidou + mybatis-plus + + + + eu.bitwalker + UserAgentUtils + + + + com.github.penggle + kaptcha + + + + com.squareup.okhttp3 + okhttp + + + + + + + + src/main/java + + **/*.* + + + + false + src/main/resources + + dev/* + sit/* + pre/* + prod/* + + + + src/main/resources/${profiles.active} + true + + *.properties + *.xml + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + pl.project13.maven + git-commit-id-plugin + 2.2.4 + + + get-the-git-infos + + revision + + + + + ${project.basedir}/.git + git + false + true + ${project.build.outputDirectory}/git.properties + json + + false + false + -dirty + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/SmartAdminApplication.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/SmartAdminApplication.java new file mode 100644 index 00000000..2ef566e1 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/SmartAdminApplication.java @@ -0,0 +1,28 @@ +package com.gangquan360.smartadmin; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * [ admin 项目启动类 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@SpringBootApplication(scanBasePackages = {"com.gangquan360.smartadmin", "cn.afterturn.easypoi"}) +@EnableCaching +@EnableScheduling +@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true) +public class SmartAdminApplication { + + public static void main(String[] args) { + SpringApplication.run(SmartAdminApplication.class, args); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/ApiModelPropertyEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/ApiModelPropertyEnum.java new file mode 100644 index 00000000..39b2f92f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/ApiModelPropertyEnum.java @@ -0,0 +1,35 @@ +package com.gangquan360.smartadmin.common.anno; + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 枚举类字段属性的注解 + * + * @author listen + * @date 2019/05/16 15:18 + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ApiModelPropertyEnum { + + /** + * 枚举类对象 + * + * @return + */ + Class value(); + + String example() default ""; + + boolean required() default true; + + String dataType() default ""; + + String enumDesc() default ""; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/DataScope.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/DataScope.java new file mode 100644 index 00000000..ec58da8c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/DataScope.java @@ -0,0 +1,34 @@ +package com.gangquan360.smartadmin.common.anno; + +import com.gangquan360.smartadmin.module.datascope.constant.DataScopeTypeEnum; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * [ 数据范围 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface DataScope { + + DataScopeTypeEnum dataScopeType() default DataScopeTypeEnum.DEFAULT; + + /** + * 第几个where 条件 从0开始 + * @return + */ + int whereIndex() default 0; + + String joinSql() default ""; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/NoNeedLogin.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/NoNeedLogin.java new file mode 100644 index 00000000..4bb314a8 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/NoNeedLogin.java @@ -0,0 +1,22 @@ +package com.gangquan360.smartadmin.common.anno; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * [ 不需要登陆 ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface NoNeedLogin { +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/NoValidPrivilege.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/NoValidPrivilege.java new file mode 100644 index 00000000..4ba657c3 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/NoValidPrivilege.java @@ -0,0 +1,20 @@ +package com.gangquan360.smartadmin.common.anno; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * + * [ 不需要权限验证 ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface NoValidPrivilege { + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/OperateLog.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/OperateLog.java new file mode 100644 index 00000000..c6762082 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/anno/OperateLog.java @@ -0,0 +1,20 @@ +package com.gangquan360.smartadmin.common.anno; + +import java.lang.annotation.*; + +/** + * [ 用户操作日志 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +public @interface OperateLog { + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/constant/CommentSortTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/constant/CommentSortTypeEnum.java new file mode 100644 index 00000000..da4d561c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/constant/CommentSortTypeEnum.java @@ -0,0 +1,57 @@ +package com.gangquan360.smartadmin.common.constant; + + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +/** + * 全局排序枚举类 + * + * @author listen + * @date 2018/01/13 14:24 + */ +public enum CommentSortTypeEnum implements BaseEnum { + + /** + * 正序 ASC 1 + */ + ASC(1, "ASC"), + + /** + * 倒序 DESC 2 + */ + DESC(2, "DESC"); + + private Integer value; + + private String desc; + + /** + * 排序类型:1正序 | 2倒序 + */ + public static final String INFO = "排序类型:1正序 | 2倒序"; + + CommentSortTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + /** + * 获取枚举类的值 + * + * @return Integer + */ + @Override + public Integer getValue() { + return value; + } + + /** + * 获取枚举类的说明 + * + * @return String + */ + @Override + public String getDesc() { + return desc; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/constant/JudgeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/constant/JudgeEnum.java new file mode 100644 index 00000000..dda791a5 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/constant/JudgeEnum.java @@ -0,0 +1,52 @@ +package com.gangquan360.smartadmin.common.constant; + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +import java.util.Arrays; +import java.util.Optional; + +/** + * + * [ 是与否] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +public enum JudgeEnum implements BaseEnum { + + NO(0, "否"), + + YES(1, "是"); + + private Integer value; + private String desc; + + JudgeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + @Override + public String getDesc() { + return desc; + } + + public static JudgeEnum valueOf(Integer status) { + JudgeEnum[] values = JudgeEnum.values(); + Optional first = Arrays.stream(values).filter(e -> e.getValue().equals(status)).findFirst(); + return !first.isPresent() ? null : first.get(); + } + + public static boolean isExist(Integer status) { + JudgeEnum judgeEnum = valueOf(status); + return judgeEnum != null; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/constant/ResponseCodeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/constant/ResponseCodeConst.java new file mode 100644 index 00000000..df0cef93 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/constant/ResponseCodeConst.java @@ -0,0 +1,183 @@ +package com.gangquan360.smartadmin.common.constant; + +import com.gangquan360.smartadmin.module.department.DepartmentResponseCodeConst; +import com.gangquan360.smartadmin.module.employee.constant.EmployeeResponseCodeConst; +import com.gangquan360.smartadmin.module.file.constant.FileResponseCodeConst; +import com.gangquan360.smartadmin.module.log.orderoperatelog.constant.OrderOperateLogOperateTypeConst; +import com.gangquan360.smartadmin.module.login.LoginResponseCodeConst; +import com.gangquan360.smartadmin.module.position.PositionResponseCodeConst; +import com.gangquan360.smartadmin.module.privilege.constant.PrivilegeResponseCodeConst; +import com.gangquan360.smartadmin.module.role.basic.RoleResponseCodeConst; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigResponseCodeConst; +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +/** + * 每个业务,100个范围值就够了. + */ +@Slf4j +public class ResponseCodeConst { + + // 范围声明 + static { + // 系统功能,从0开始,step=1000 + ResponseCodeContainer.register(ResponseCodeConst.class, 0, 1000); + ResponseCodeContainer.register(LoginResponseCodeConst.class, 1001, 1999); + ResponseCodeContainer.register(DepartmentResponseCodeConst.class, 2001, 2999); + ResponseCodeContainer.register(EmployeeResponseCodeConst.class, 3001, 3999); + ResponseCodeContainer.register(FileResponseCodeConst.class, 4001, 4999); + ResponseCodeContainer.register(SystemConfigResponseCodeConst.class, 5001, 5999); + ResponseCodeContainer.register(RoleResponseCodeConst.class, 6001, 6999); + ResponseCodeContainer.register(PrivilegeResponseCodeConst.class, 7001, 7999); + ResponseCodeContainer.register(OrderOperateLogOperateTypeConst.class, 8001, 8999); + ResponseCodeContainer.register(PositionResponseCodeConst.class, 13000, 13999); + + } + + public static final ResponseCodeConst SUCCESS = new ResponseCodeConst(1, "success", true); + + public static final ResponseCodeConst COMMON_ERROR = new ResponseCodeConst(2, "我错了...."); + + public static final ResponseCodeConst ERROR_PARAM = new ResponseCodeConst(101, "参数异常!"); + + public static final ResponseCodeConst ERROR_PARAM_ANY = new ResponseCodeConst(102, "%s参数异常!"); + + public static final ResponseCodeConst SYSTEM_ERROR = new ResponseCodeConst(111, "系统错误"); + + public static final ResponseCodeConst DEVELOPMENT = new ResponseCodeConst(112, "此功能正在开发中"); + + public static final ResponseCodeConst NOT_EXISTS = new ResponseCodeConst(113, "数据不存在"); + + public static ResponseCodeConst REQUEST_METHOD_ERROR = new ResponseCodeConst(114, "请求方式错误"); + + public static ResponseCodeConst JSON_FORMAT_ERROR = new ResponseCodeConst(115, "JSON格式错误"); + + protected int code; + + protected String msg; + + protected boolean success; + + public ResponseCodeConst() { + } + + protected ResponseCodeConst(int code, String msg) { + super(); + this.code = code; + this.msg = msg; + ResponseCodeContainer.put(this); + } + + protected ResponseCodeConst(int code, String msg, boolean success) { + super(); + this.code = code; + this.msg = msg; + this.success = success; + ResponseCodeContainer.put(this); + } + + protected ResponseCodeConst(int code) { + super(); + this.code = code; + ResponseCodeContainer.put(this); + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static void init() { + log.info("ResponseCodeConst init...."); + } + + // =======================分割======================= + + /** + * 内部类,用于检测code范围 + * + * @author Anders + */ + @Slf4j + private static class ResponseCodeContainer { + + private static final Map RESPONSE_CODE_MAP = new HashMap<>(); + + private static final Map, int[]> RESPONSE_CODE_RANGE_MAP = new HashMap<>(); + + /** + * id的范围:[start, end]左闭右闭 + * + * @param clazz + * @param start + * @param end + */ + private static void register(Class clazz, int start, int end) { + if (start > end) { + throw new IllegalArgumentException(" start > end!"); + } + + if (RESPONSE_CODE_RANGE_MAP.containsKey(clazz)) { + throw new IllegalArgumentException(String.format(" Class:%s already exist!", clazz.getSimpleName())); + } + RESPONSE_CODE_RANGE_MAP.forEach((k, v) -> { + if ((start >= v[0] && start <= v[1]) || (end >= v[0] && end <= v[1])) { + throw new IllegalArgumentException(String.format(" Class:%s 's id range[%d,%d] has " + "intersection with " + "class:%s", clazz.getSimpleName(), start, end, + k.getSimpleName())); + } + }); + + RESPONSE_CODE_RANGE_MAP.put(clazz, new int[]{start, end}); + + // 提前初始化static变量,进行范围检测 + Field[] fields = clazz.getFields(); + if (fields.length != 0) { + try { + fields[0].get(clazz); + } catch (IllegalArgumentException | IllegalAccessException e) { + log.error("", e); + } + } + } + + public static void put(ResponseCodeConst codeConst) { + int[] idRange = RESPONSE_CODE_RANGE_MAP.get(codeConst.getClass()); + if (idRange == null) { + throw new IllegalArgumentException(String.format(" Class:%s has not been registered!", codeConst.getClass().getSimpleName())); + } + int code = codeConst.code; + if (code < idRange[0] || code > idRange[1]) { + throw new IllegalArgumentException(String.format(" Id(%d) out of range[%d,%d], " + "class:%s", code, idRange[0], idRange[1], codeConst.getClass().getSimpleName())); + } + if (RESPONSE_CODE_MAP.keySet().contains(code)) { + log.error(String.format(" Id(%d) out of range[%d,%d], " + "class:%s code is repeat!", code, idRange[0], idRange[1], codeConst.getClass().getSimpleName())); + System.exit(0); + } + RESPONSE_CODE_MAP.put(code, codeConst); + } + + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/BaseEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/BaseEntity.java new file mode 100644 index 00000000..507fb215 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/BaseEntity.java @@ -0,0 +1,38 @@ +package com.gangquan360.smartadmin.common.domain; + +import com.baomidou.mybatisplus.annotations.TableId; +import com.baomidou.mybatisplus.enums.IdType; +import lombok.Data; + +import java.util.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 上午 11:15 + * @since JDK1.8 + */ +@Data +public class BaseEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 创建时间 + */ + private Date createTime; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/BaseEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/BaseEnum.java new file mode 100644 index 00000000..7e194637 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/BaseEnum.java @@ -0,0 +1,97 @@ +package com.gangquan360.smartadmin.common.domain; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONAware; +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.CaseFormat; +import lombok.Data; + +import java.util.LinkedHashMap; +import java.util.Objects; + +/** + * @author listen + * @date 2018-07-17 下午 3:52 + */ +public interface BaseEnum { + + /** + * 获取枚举类的值 + * + * @return Object + */ + Object getValue(); + + /** + * 获取枚举类的说明 + * + * @return String + */ + String getDesc(); + + /** + * 比较参数是否与枚举类的value相同 + * + * @param value + * @return boolean + */ + default boolean equalsValue(Object value) { + return Objects.equals(getValue(), value); + } + + /** + * 比较枚举类是否相同 + * + * @param baseEnum + * @return boolean + */ + default boolean equals(BaseEnum baseEnum) { + return Objects.equals(getValue(), baseEnum.getValue()) && Objects.equals(getDesc(), baseEnum.getDesc()); + } + + /** + * 返回枚举类的说明 + * + * @param clazz 枚举类类对象 + * @return + */ + static String getInfo(Class clazz) { + BaseEnum[] enums = clazz.getEnumConstants(); + LinkedHashMap json = new LinkedHashMap<>(enums.length); + for (BaseEnum e : enums) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("value", new DeletedQuotationAware(e.getValue())); + jsonObject.put("desc", new DeletedQuotationAware(e.getDesc())); + json.put(e.toString(), jsonObject); + } + + String enumJson = JSON.toJSONString(json, true); + enumJson = enumJson.replaceAll("\"", ""); + enumJson= enumJson.replaceAll("\t","  "); + enumJson = enumJson.replaceAll("\n","
"); + String prefix = "
export const
" + CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, clazz.getSimpleName() + " =
"); + return prefix + "" + enumJson + "
"; + } + + + @Data + class DeletedQuotationAware implements JSONAware { + + private String value; + + public DeletedQuotationAware(Object value) { + if(value == null){ + this.value = ""; + }else if (value instanceof String) { + this.value = "'" + value + "'"; + }else { + this.value = value.toString(); + } + } + + @Override + public String toJSONString() { + return value; + } + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/PageParamDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/PageParamDTO.java new file mode 100644 index 00000000..7d768fb2 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/PageParamDTO.java @@ -0,0 +1,35 @@ +package com.gangquan360.smartadmin.common.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Max; +import javax.validation.constraints.NotNull; + +/** + * 分页基础参数 + * + * @author lihaifan + * @Date Created in 2017/10/28 16:19 + */ +@Data +public class PageParamDTO { + + @NotNull(message = "分页参数不能为空") + @ApiModelProperty(value = "页码(不能为空)", example = "1") + protected Integer pageNum; + + @NotNull(message = "每页数量不能为空") + @ApiModelProperty(value = "每页数量(不能为空)", example = "10") + @Max(value = 200, message = "每页最大为200") + protected Integer pageSize; + + @ApiModelProperty("排序规则:true正序 | false 倒序") + protected Boolean sort; + + @ApiModelProperty("排序字段") + protected String orderByField; + + @ApiModelProperty("是否查询总条数") + protected Boolean searchCount; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/PageResultDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/PageResultDTO.java new file mode 100644 index 00000000..94e3d803 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/PageResultDTO.java @@ -0,0 +1,47 @@ +package com.gangquan360.smartadmin.common.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * Page返回对象 + * + * @Author lihaifan + * @Date Created in 2017/10/31 15:05 + */ +@Data +public class PageResultDTO { + + /** + * 当前页 + */ + @ApiModelProperty(value = "当前页") + private Integer pageNum; + + /** + * 每页的数量 + */ + @ApiModelProperty(value = "每页的数量") + private Integer pageSize; + + /** + * 总记录数 + */ + @ApiModelProperty(value = "总记录数") + private Long total; + + /** + * 总页数 + */ + @ApiModelProperty(value = "总页数") + private Integer pages; + + /** + * 结果集 + */ + @ApiModelProperty(value = "结果集") + private List list; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/ResponseDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/ResponseDTO.java new file mode 100644 index 00000000..df28466c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/domain/ResponseDTO.java @@ -0,0 +1,128 @@ +package com.gangquan360.smartadmin.common.domain; + + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + +/** + * 返回类 + * + * @param + * @author gangquan + */ +public class ResponseDTO { + + protected Integer code; + + protected String msg; + + protected Boolean success; + + protected T data; + + public ResponseDTO() { + } + + public ResponseDTO(ResponseCodeConst responseCodeConst, String msg) { + this.code = responseCodeConst.getCode(); + this.msg = msg; + this.success = responseCodeConst.isSuccess(); + } + + public ResponseDTO(ResponseCodeConst responseCodeConst, T data) { + super(); + this.code = responseCodeConst.getCode(); + this.msg = responseCodeConst.getMsg(); + this.data = data; + this.success = responseCodeConst.isSuccess(); + } + + public ResponseDTO(ResponseCodeConst responseCodeConst, T data, String msg) { + super(); + this.code = responseCodeConst.getCode(); + this.msg = msg; + this.data = data; + this.success = responseCodeConst.isSuccess(); + } + + private ResponseDTO(ResponseCodeConst responseCodeConst) { + this.code = responseCodeConst.getCode(); + this.msg = responseCodeConst.getMsg(); + this.success = responseCodeConst.isSuccess(); + } + + public ResponseDTO(ResponseDTO responseDTO) { + this.code = responseDTO.getCode(); + this.msg = responseDTO.getMsg(); + this.success = responseDTO.isSuccess(); + } + + public static ResponseDTO succ() { + return new ResponseDTO(ResponseCodeConst.SUCCESS); + } + + public static ResponseDTO succData(T data, String msg) { + return new ResponseDTO(ResponseCodeConst.SUCCESS, data, msg); + } + + public static ResponseDTO succData(T data) { + return new ResponseDTO(ResponseCodeConst.SUCCESS, data); + } + + public static ResponseDTO succMsg(String msg) { + return new ResponseDTO(ResponseCodeConst.SUCCESS, msg); + } + + + public static ResponseDTO wrap(ResponseCodeConst codeConst) { + return new ResponseDTO<>(codeConst); + } + + public static ResponseDTO wrap(ResponseCodeConst codeConst, T t) { + return new ResponseDTO(codeConst, t); + } + + public static ResponseDTO wrap(ResponseCodeConst codeConst, String msg) { + return new ResponseDTO(codeConst, msg); + } + + public String getMsg() { + return msg; + } + + public ResponseDTO setMsg(String msg) { + this.msg = msg; + return this; + } + + public int getCode() { + return code; + } + + public ResponseDTO setCode(Integer code) { + this.code = code; + return this; + } + + public T getData() { + return data; + } + + public ResponseDTO setData(T data) { + this.data = data; + return this; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + @Override + public String toString() { + return "ResponseDTO{" + "code=" + code + ", msg='" + msg + '\'' + ", success=" + success + ", data=" + data + + '}'; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/exception/SmartBusinessException.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/exception/SmartBusinessException.java new file mode 100644 index 00000000..2a35552b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/exception/SmartBusinessException.java @@ -0,0 +1,33 @@ +package com.gangquan360.smartadmin.common.exception; +/** + * + * [ 业务逻辑异常,全局异常拦截后统一返回ResponseCodeConst.SYSTEM_ERROR ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +public class SmartBusinessException extends RuntimeException { + + public SmartBusinessException() { + } + + public SmartBusinessException(String message) { + super(message); + } + + public SmartBusinessException(String message, Throwable cause) { + super(message, cause); + } + + public SmartBusinessException(Throwable cause) { + super(cause); + } + + public SmartBusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/exception/SmartResponseCodeException.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/exception/SmartResponseCodeException.java new file mode 100644 index 00000000..f0edc118 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/exception/SmartResponseCodeException.java @@ -0,0 +1,24 @@ +package com.gangquan360.smartadmin.common.exception; + +/** + * [ 全局异常拦截后保留ResponseCode码的异常] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/7 0007 下午 16:11 + * @since JDK1.8 + */ +public class SmartResponseCodeException extends RuntimeException{ + private Integer code; + + public SmartResponseCodeException(Integer code, String message) { + super(message); + this.code = code; + } + + public Integer getCode() { + return code; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/AbstractHeartBeatCommand.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/AbstractHeartBeatCommand.java new file mode 100644 index 00000000..d2a3412d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/AbstractHeartBeatCommand.java @@ -0,0 +1,90 @@ +package com.gangquan360.smartadmin.common.heartbeat; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.util.Date; +import java.util.List; +import java.util.concurrent.*; + + +/** +* @Description: 心跳服务 +* @Author: simajinqiang +* @Date: 2018/7/9 16:26 +*/ +public abstract class AbstractHeartBeatCommand implements HeartBeatRecordCommendInterface { + + + ScheduledExecutorService executorService; + + int threadNum = 1; + + /** + * 项目路径 + */ + private String projectPath; + /** + * 服务器ip(多网卡) + */ + private List serverIps; + /** + * 进程号 + */ + private Integer processNo; + /** + * 进程开启时间 + */ + private Date processStartTime; + + HeartBeatLogger logger; + + /** + * 初始化 + */ + public void init(HeartBeatConfig config, HeartBeatLogger logger){ + this.handlerHeartBeat(); + ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("AbstractHeartBeatCommand-%s").build(); + executorService = Executors.newScheduledThreadPool(threadNum, threadFactory); + executorService.scheduleWithFixedDelay(new DoHeartBeat(), config.getDelayHandlerTime(), config.getIntervalTime(), TimeUnit.MILLISECONDS); + } + + public void handlerHeartBeat(){ + try { + projectPath = HeatBeatRecordHelper.getProjectPath(); + serverIps = IpUtil.getLocalIPS(); + processNo = HeatBeatRecordHelper.getProcessID(); + processStartTime = HeatBeatRecordHelper.getStartTime(); + }catch (Throwable e){ + logger.error("get heart beat info error.", e); + } + } + + /** + * 销毁线程池 + */ + public void destroy(){ + if (executorService != null && !executorService.isShutdown()) { + executorService.shutdown(); + executorService = null; + } + } + + public class DoHeartBeat implements Runnable{ + + @Override + public void run() { + try { + HeartBeatRecordDTO heartBeatRecord = new HeartBeatRecordDTO(); + heartBeatRecord.setProjectPath(projectPath); + heartBeatRecord.setServerIp(StringUtil.join(serverIps,";")); + heartBeatRecord.setProcessNo(processNo); + heartBeatRecord.setProcessStartTime(processStartTime); + heartBeatRecord.setHeartBeatTime(new Date()); + handler(heartBeatRecord); + }catch (Throwable t){ + logger.error("handler heartbeat error.", t); + } + + } + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatConfig.java new file mode 100644 index 00000000..7e6f5f0a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatConfig.java @@ -0,0 +1,29 @@ +package com.gangquan360.smartadmin.common.heartbeat; + +import lombok.Builder; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/8 0008 下午 16:22 + * @since JDK1.8 + */ +@Data +@Builder +public class HeartBeatConfig { + + /** + * 延迟执行时间 + */ + private Long delayHandlerTime; + + /** + * 间隔执行时间 + */ + private Long intervalTime; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatLogger.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatLogger.java new file mode 100644 index 00000000..b624fe1e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatLogger.java @@ -0,0 +1,20 @@ +package com.gangquan360.smartadmin.common.heartbeat; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/8 0008 下午 16:23 + * @since JDK1.8 + */ +public interface HeartBeatLogger { + + void error(String string); + + void error(String string, Throwable e); + + void info(String string); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatRecordCommendInterface.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatRecordCommendInterface.java new file mode 100644 index 00000000..943836a9 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatRecordCommendInterface.java @@ -0,0 +1,17 @@ +package com.gangquan360.smartadmin.common.heartbeat; + + + +/** +* @Description: +* @Author: simajinqiang +* @Date: 2018/7/9 14:06 +*/ +public interface HeartBeatRecordCommendInterface { + /** + * 处理 + * @param heartBeatRecord + */ + void handler(HeartBeatRecordDTO heartBeatRecord); + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatRecordDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatRecordDTO.java new file mode 100644 index 00000000..83914968 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeartBeatRecordDTO.java @@ -0,0 +1,37 @@ +package com.gangquan360.smartadmin.common.heartbeat; + +import lombok.Data; + +import java.util.Date; + +/** +* @Description: 心跳记录日志 +* @Author: simajinqiang +* @Date: 2018/7/9 11:11 +*/ +@Data +public class HeartBeatRecordDTO { + + /** + * 项目名字 + */ + private String projectPath; + /** + * 服务器ip + */ + private String serverIp; + /** + * 进程号 + */ + private Integer processNo; + /** + * 进程开启时间 + */ + private Date processStartTime; + /** + * 心跳当前时间 + */ + private Date heartBeatTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeatBeatRecordHelper.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeatBeatRecordHelper.java new file mode 100644 index 00000000..41e4ed3d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/HeatBeatRecordHelper.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.common.heartbeat; + + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.Date; + +/** +* @Description: 心跳工具类 +* @Author: simajinqiang +* @Date: 2018/7/9 11:48 +*/ +public class HeatBeatRecordHelper { + + /** + * 获取进程号 + * @return + */ + public static final Integer getProcessID() { + RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); + return Integer.valueOf(runtimeMXBean.getName().split("@")[0]) + .intValue(); + } + + /** + * 获取项目名称 + * @return + */ + public static final String getProjectPath(){ + return System.getProperty("user.dir"); + } + + /** + * 获取进程启动时间 + * @return + */ + public static final Date getStartTime(){ + RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); + return new Date(runtimeMXBean.getStartTime()); + } + + + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/IpUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/IpUtil.java new file mode 100644 index 00000000..d3359bdc --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/IpUtil.java @@ -0,0 +1,81 @@ +package com.gangquan360.smartadmin.common.heartbeat; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +/** +* @Description: ip工具类 +* @Author: sbq +* @CreateDate: 2019/8/8 10:33 +* @Version: 1.0 +*/ +public class IpUtil { + /** + * 获得服务器的IP地址 + */ + public static String getLocalIP() { + String sIP = ""; + InetAddress ip = null; + try { + boolean bFindIP = false; + Enumeration netInterfaces = (Enumeration) NetworkInterface + .getNetworkInterfaces(); + while (netInterfaces.hasMoreElements()) { + if (bFindIP) { + break; + } + NetworkInterface ni = (NetworkInterface) netInterfaces + .nextElement(); + Enumeration ips = ni.getInetAddresses(); + while (ips.hasMoreElements()) { + ip = (InetAddress) ips.nextElement(); + if (!ip.isLoopbackAddress() + && ip.getHostAddress().matches( + "(\\d{1,3}\\.){3}\\d{1,3}")) { + bFindIP = true; + break; + } + } + } + } catch (Exception e) { + } + if (null != ip) { + sIP = ip.getHostAddress(); + } + return sIP; + } + + /** + * @Description: 获得服务器的IP地址(多网卡) + * @Author: sbq + * @CreateDate: 2019/8/8 10:34 + * @Version: 1.0 + */ + public static List getLocalIPS() { + InetAddress ip = null; + List ipList = new ArrayList(); + try { + Enumeration netInterfaces = (Enumeration) NetworkInterface + .getNetworkInterfaces(); + while (netInterfaces.hasMoreElements()) { + NetworkInterface ni = (NetworkInterface) netInterfaces + .nextElement(); + Enumeration ips = ni.getInetAddresses(); + while (ips.hasMoreElements()) { + ip = (InetAddress) ips.nextElement(); + if (!ip.isLoopbackAddress() + && ip.getHostAddress().matches( + "(\\d{1,3}\\.){3}\\d{1,3}")) { + ipList.add(ip.getHostAddress()); + } + } + } + } catch (Exception e) { + } + return ipList; + } + +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/StringUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/StringUtil.java new file mode 100644 index 00000000..bcbffa59 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/heartbeat/StringUtil.java @@ -0,0 +1,60 @@ +package com.gangquan360.smartadmin.common.heartbeat; + +import java.util.Iterator; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/8 0008 下午 16:27 + * @since JDK1.8 + */ +public class StringUtil { + + + + public static String join(Iterable iterable, String separator) { + return iterable == null ? null : join(iterable.iterator(), separator); + } + + + public static String join(Iterator iterator, String separator) { + if (iterator == null) { + return null; + } else if (!iterator.hasNext()) { + return ""; + } else { + Object first = iterator.next(); + if (!iterator.hasNext()) { + String result = toString(first); + return result; + } else { + StringBuilder buf = new StringBuilder(256); + if (first != null) { + buf.append(first); + } + + while(iterator.hasNext()) { + if (separator != null) { + buf.append(separator); + } + + Object obj = iterator.next(); + if (obj != null) { + buf.append(obj); + } + } + + return buf.toString(); + } + } + } + + public static String toString(Object obj) { + return obj == null ? "" : obj.toString(); + } + +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/json/LongJsonDeserializer.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/json/LongJsonDeserializer.java new file mode 100644 index 00000000..50d809a5 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/json/LongJsonDeserializer.java @@ -0,0 +1,21 @@ +package com.gangquan360.smartadmin.common.json; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; + +public class LongJsonDeserializer extends JsonDeserializer { + + @Override + public Long deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + String value = jsonParser.getText(); + try { + return value == null ? null : Long.parseLong(value); + } catch (NumberFormatException e) { + return null; + } + } +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/json/LongJsonSerializer.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/json/LongJsonSerializer.java new file mode 100644 index 00000000..1682357b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/json/LongJsonSerializer.java @@ -0,0 +1,19 @@ +package com.gangquan360.smartadmin.common.json; + + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +public class LongJsonSerializer extends JsonSerializer { + @Override + public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + String text = (value == null ? null : String.valueOf(value)); + if (text != null) { + jsonGenerator.writeString(text); + } + } +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/kaptcha/KaptchaColor.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/kaptcha/KaptchaColor.java new file mode 100644 index 00000000..638ac106 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/kaptcha/KaptchaColor.java @@ -0,0 +1,39 @@ +package com.gangquan360.smartadmin.common.kaptcha; + +import com.google.common.collect.Lists; + +import java.awt.*; +import java.util.List; +import java.util.Random; + +/** + * [ 验证码颜色 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/6 0006 上午 10:51 + * @since JDK1.8 + */ +public class KaptchaColor { + + public static Color getColor() { + + List colors = Lists.newArrayList(); + colors.add(new Color(0, 135, 255)); + colors.add(new Color(51, 153, 51)); + colors.add(new Color(255, 102, 102)); + colors.add(new Color(255, 153, 0)); + colors.add(new Color(153, 102, 0)); + colors.add(new Color(153, 102, 153)); + colors.add(new Color(51, 153, 153)); + colors.add(new Color(102, 102, 255)); + colors.add(new Color(0, 102, 204)); + colors.add(new Color(204, 51, 51)); + colors.add(new Color(128, 153, 65)); + Random random = new Random(); + int colorIndex = random.nextInt(10); + return colors.get(colorIndex); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/kaptcha/KaptchaNoise.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/kaptcha/KaptchaNoise.java new file mode 100644 index 00000000..3af2a7ad --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/kaptcha/KaptchaNoise.java @@ -0,0 +1,44 @@ +package com.gangquan360.smartadmin.common.kaptcha; + +import com.google.code.kaptcha.NoiseProducer; +import com.google.code.kaptcha.util.Configurable; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.Random; + +/** + * [ 验证码加噪处理 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/6 0006 上午 10:47 + * @since JDK1.8 + */ +public class KaptchaNoise extends Configurable implements NoiseProducer { + public KaptchaNoise() { + } + + @Override + public void makeNoise(BufferedImage image, float factorOne, float factorTwo, float factorThree, float factorFour) { + + int width = image.getWidth(); + int height = image.getHeight(); + Graphics2D graph = (Graphics2D)image.getGraphics(); + graph.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)); + graph.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + Random random = new Random(); + int noiseLineNum = random.nextInt(3); + if(noiseLineNum == 0){ + noiseLineNum = 1; + } + for (int i = 0; i < noiseLineNum; i++){ + graph.setColor(KaptchaColor.getColor()); + graph.drawLine(random.nextInt(width), random.nextInt(height), 10 + random.nextInt(20), 10 + random.nextInt(20)); + } + + graph.dispose(); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/kaptcha/KaptchaWordRenderer.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/kaptcha/KaptchaWordRenderer.java new file mode 100644 index 00000000..ef0269b1 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/kaptcha/KaptchaWordRenderer.java @@ -0,0 +1,75 @@ +package com.gangquan360.smartadmin.common.kaptcha; + +import com.google.code.kaptcha.util.Configurable; + +import java.awt.*; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.image.BufferedImage; +import java.util.Random; + +/** + * [ 验证码字体生成 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/6 0006 上午 9:43 + * @since JDK1.8 + */ +public class KaptchaWordRenderer extends Configurable implements com.google.code.kaptcha.text.WordRenderer { + + public KaptchaWordRenderer() { + } + + @Override + public BufferedImage renderWord(String word, int width, int height) { + int fontSize = this.getConfig().getTextProducerFontSize(); + Font[] fonts = this.getConfig().getTextProducerFonts(fontSize); + int charSpace = this.getConfig().getTextProducerCharSpace(); + BufferedImage image = new BufferedImage(width, height, 2); + + Graphics2D g2D = image.createGraphics(); + g2D.setColor(Color.WHITE); + RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)); + g2D.setRenderingHints(hints); + g2D.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + + FontRenderContext frc = g2D.getFontRenderContext(); + Random random = new Random(); + int startPosY = (height - fontSize) / 5 + fontSize; + char[] wordChars = word.toCharArray(); + Font[] chosenFonts = new Font[wordChars.length]; + int[] charWidths = new int[wordChars.length]; + int widthNeeded = 0; + + int startPosX; + for(startPosX = 0; startPosX < wordChars.length; ++startPosX) { + chosenFonts[startPosX] = fonts[random.nextInt(fonts.length)]; + char[] charToDraw = new char[]{wordChars[startPosX]}; + GlyphVector gv = chosenFonts[startPosX].createGlyphVector(frc, charToDraw); + charWidths[startPosX] = (int)gv.getVisualBounds().getWidth(); + if (startPosX > 0) { + widthNeeded += 2; + } + + widthNeeded += charWidths[startPosX]; + } + + startPosX = (width - widthNeeded) / 2; + + for(int i = 0; i < wordChars.length; ++i) { + g2D.setColor(KaptchaColor.getColor()); + g2D.setFont(chosenFonts[i].deriveFont(Font.PLAIN)); + char[] charToDraw = new char[]{wordChars[i]}; + g2D.drawChars(charToDraw, 0, charToDraw.length, startPosX, startPosY); + startPosX = startPosX + charWidths[i] + charSpace; + } + + return image; + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/SmartReloadManager.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/SmartReloadManager.java new file mode 100644 index 00000000..f6e7352e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/SmartReloadManager.java @@ -0,0 +1,134 @@ +package com.gangquan360.smartadmin.common.reload; + +import com.gangquan360.smartadmin.common.reload.annotation.SmartReload; +import com.gangquan360.smartadmin.common.reload.domain.AbstractSmartReloadObject; +import com.gangquan360.smartadmin.common.reload.domain.AnnotationReloadObject; +import com.gangquan360.smartadmin.common.reload.domain.InterfaceReloadObject; +import com.gangquan360.smartadmin.common.reload.domain.entity.ReloadItem; +import com.gangquan360.smartadmin.common.reload.domain.entity.SmartReloadResult; +import com.gangquan360.smartadmin.common.reload.interfaces.SmartReloadCommandInterface; +import com.gangquan360.smartadmin.common.reload.interfaces.SmartReloadThreadLogger; +import com.gangquan360.smartadmin.common.reload.interfaces.SmartReloadable; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import static java.util.Objects.requireNonNull; + +/** + * SmartReloadManager 管理器 + *

+ * 可以在此类中添加 检测任务 以及注册 处理程序 + * + * @author zhuoda + */ +public class SmartReloadManager { + + private Map tagReloadObject; + + private SmartReloadScheduler reloadScheduler; + + private SmartReloadThreadLogger logger; + + public SmartReloadManager(SmartReloadThreadLogger logger, int threadCount) { + this.tagReloadObject = new ConcurrentHashMap<>(); + if (logger == null) { + throw new ExceptionInInitializerError("SmartReloadLoggerImp cannot be null"); + } + + if (threadCount < 1) { + throw new ExceptionInInitializerError("threadCount must be greater than 1"); + } + + this.logger = logger; + this.reloadScheduler = new SmartReloadScheduler(this.logger, threadCount); + } + + /** + * 默认创建单个线程 + * + * @param logger + */ + public SmartReloadManager(SmartReloadThreadLogger logger) { + this(logger, 1); + } + + /** + * 停止 + */ + public void shutdown() { + reloadScheduler.shutdown(); + } + + /** + * 添加任务 + * + * @param command SmartReloadCommand实现类 + * @param initialDelay 第一次执行前的延迟时间 + * @param delay 任务间隔时间 + * @param unit 延迟单位 TimeUnit 天、小时、分、秒等 + */ + public void addCommand(SmartReloadCommandInterface command, long initialDelay, long delay, TimeUnit unit) { + reloadScheduler.addCommand(command, initialDelay, delay, unit); + } + + /** + * 注册 实现接口的方式 + * + * @param tag + * @param reloadable + */ + public void register(String tag, SmartReloadable reloadable) { + requireNonNull(reloadable); + requireNonNull(tag); + if (tagReloadObject.containsKey(tag)) { + logger.error("<> register duplicated tag reload : " + tag + " , and it will be cover!"); + } + tagReloadObject.put(tag, new InterfaceReloadObject(reloadable)); + } + + /** + * 注册 要求此类必须包含使用了SmartReload注解的方法 + * + * @param reloadObject + */ + public void register(Object reloadObject) { + requireNonNull(reloadObject); + Method[] declaredMethods = reloadObject.getClass().getDeclaredMethods(); + if (declaredMethods != null) { + for (int i = 0; i < declaredMethods.length; i++) { + Method method = declaredMethods[i]; + SmartReload annotation = method.getAnnotation(SmartReload.class); + if (annotation != null) { + String reloadTag = annotation.value(); + this.register(reloadTag, new AnnotationReloadObject(reloadObject, method)); + } + } + } + } + + private void register(String tag, AbstractSmartReloadObject reloadObject) { + if (tagReloadObject.containsKey(tag)) { + logger.error("<> register duplicated tag reload : " + tag + " , and it will be cover!"); + } + tagReloadObject.put(tag, reloadObject); + } + + /** + * Reload 已注册的ReloadItem + * + * @param reloadItem + * @return SmartReloadResult + */ + public SmartReloadResult doReload(ReloadItem reloadItem) { + AbstractSmartReloadObject reloadObject = tagReloadObject.get(reloadItem.getTag()); + if (reloadObject != null) { + return reloadObject.reload(reloadItem); + } + // 返回注册结果 + return new SmartReloadResult(reloadItem.getTag(), reloadItem.getArgs(), reloadItem.getIdentification(), false, "No registered reload handler was found"); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/SmartReloadScheduler.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/SmartReloadScheduler.java new file mode 100644 index 00000000..d0dc0587 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/SmartReloadScheduler.java @@ -0,0 +1,87 @@ +package com.gangquan360.smartadmin.common.reload; + +import com.gangquan360.smartadmin.common.reload.interfaces.SmartReloadCommandInterface; +import com.gangquan360.smartadmin.common.reload.interfaces.SmartReloadThreadLogger; + +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Reload 调度器 + * + * @author zhuoda + */ +public class SmartReloadScheduler { + + private ScheduledThreadPoolExecutor executor; + + private SmartReloadThreadLogger logger; + + SmartReloadScheduler(SmartReloadThreadLogger logger, int threadCount) { + this.executor = new ScheduledThreadPoolExecutor(threadCount, new SmartReloadSchedulerThreadFactory()); + this.logger = logger; + } + + void shutdown() { + try { + executor.shutdown(); + } catch (Throwable e) { + logger.error("<> shutdown ", e); + } + } + + void addCommand(SmartReloadCommandInterface command, long initialDelay, long delay, TimeUnit unit) { + executor.scheduleWithFixedDelay(new ScheduleRunnable(command, this.logger), initialDelay, delay, unit); + } + + static class ScheduleRunnable implements Runnable { + + private SmartReloadCommandInterface command; + + private SmartReloadThreadLogger logger; + + public ScheduleRunnable(SmartReloadCommandInterface command, SmartReloadThreadLogger logger) { + this.command = command; + this.logger = logger; + } + + @Override + public void run() { + try { + command.doTask(); + } catch (Throwable e) { + logger.error("", e); + } + } + } + + static class SmartReloadSchedulerThreadFactory implements ThreadFactory { + + private static final AtomicInteger poolNumber = new AtomicInteger(1); + + private final ThreadGroup group; + + private final AtomicInteger threadNumber = new AtomicInteger(1); + + private final String namePrefix; + + SmartReloadSchedulerThreadFactory() { + SecurityManager s = System.getSecurityManager(); + group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); + namePrefix = "smartreload-" + poolNumber.getAndIncrement() + "-thread-"; + } + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); + if (t.isDaemon()) + t.setDaemon(false); + if (t.getPriority() != Thread.NORM_PRIORITY) + t.setPriority(Thread.NORM_PRIORITY); + return t; + } + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/abstracts/AbstractSmartReloadCommand.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/abstracts/AbstractSmartReloadCommand.java new file mode 100644 index 00000000..b5b90aac --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/abstracts/AbstractSmartReloadCommand.java @@ -0,0 +1,66 @@ +package com.gangquan360.smartadmin.common.reload.abstracts; + +import com.gangquan360.smartadmin.common.reload.SmartReloadManager; +import com.gangquan360.smartadmin.common.reload.domain.entity.ReloadItem; +import com.gangquan360.smartadmin.common.reload.interfaces.SmartReloadCommandInterface; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 检测是否 Reload 的类 + * + * @author zhuoda + */ +public abstract class AbstractSmartReloadCommand implements SmartReloadCommandInterface { + + /** + * 当前ReloadItem的存储器 + */ + private ConcurrentHashMap currentTags = null; + + /** + * Reload的执行类 + */ + private SmartReloadManager reloadManager; + + public AbstractSmartReloadCommand(SmartReloadManager reloadManager) { + this.reloadManager = reloadManager; + this.currentTags = new ConcurrentHashMap<>(); + // 初始获取ReloadItem数据 + List readTagStatesFromDb = readReloadItem(); + if (readTagStatesFromDb != null) { + for (ReloadItem reloadItem : readTagStatesFromDb) { + String tag = reloadItem.getTag(); + String tagChangeIdentifier = reloadItem.getIdentification(); + this.currentTags.put(tag, tagChangeIdentifier); + } + } + } + /** + * 任务: + * 读取数据库中 ReloadItem 数据 + * 校验是否发生变化 + * 执行重加载动作 + */ + @Override + public void doTask() { + // 获取数据库数据 + List readTagStatesFromDb = readReloadItem(); + String tag; + String tagIdentifier; + String preTagChangeIdentifier; + for (ReloadItem reloadItem : readTagStatesFromDb) { + tag = reloadItem.getTag(); + tagIdentifier = reloadItem.getIdentification(); + preTagChangeIdentifier = currentTags.get(tag); + // 数据不一致 + if (preTagChangeIdentifier == null || ! preTagChangeIdentifier.equals(tagIdentifier)) { + // 更新map数据 + currentTags.put(tag, tagIdentifier); + // 执行重新加载此项的动作 + handleReloadResult(this.reloadManager.doReload(reloadItem)); + } + } + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/abstracts/AbstractSmartReloadCommand4Spring.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/abstracts/AbstractSmartReloadCommand4Spring.java new file mode 100644 index 00000000..4b550591 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/abstracts/AbstractSmartReloadCommand4Spring.java @@ -0,0 +1,68 @@ +package com.gangquan360.smartadmin.common.reload.abstracts; + +import com.gangquan360.smartadmin.common.reload.SmartReloadManager; +import com.gangquan360.smartadmin.common.reload.domain.entity.ReloadItem; +import com.gangquan360.smartadmin.common.reload.interfaces.SmartReloadCommandInterface; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.PostConstruct; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 检测是否 Reload 的类 + * + * @author zhuoda + */ +public abstract class AbstractSmartReloadCommand4Spring implements SmartReloadCommandInterface { + + /** + * 当前ReloadItem的存储器 + */ + protected ConcurrentHashMap currentTags = new ConcurrentHashMap<>(); + + /** + * Reload的执行类 + */ + @Autowired + protected SmartReloadManager reloadManager; + +// @PostConstruct + public void init() { + List readTagStatesFromDb = readReloadItem(); + if (readTagStatesFromDb != null) { + for (ReloadItem reloadItem : readTagStatesFromDb) { + String tag = reloadItem.getTag(); + String tagChangeIdentifier = reloadItem.getIdentification(); + this.currentTags.put(tag, tagChangeIdentifier); + } + } + } + + /** + * 任务: + * 读取数据库中 ReloadItem 数据 + * 校验是否发生变化 + * 执行重加载动作 + */ + @Override + public void doTask() { + // 获取数据库数据 + List readTagStatesFromDb = readReloadItem(); + String tag; + String tagIdentifier; + String preTagChangeIdentifier; + for (ReloadItem reloadItem : readTagStatesFromDb) { + tag = reloadItem.getTag(); + tagIdentifier = reloadItem.getIdentification(); + preTagChangeIdentifier = currentTags.get(tag); + // 数据不一致 + if (preTagChangeIdentifier == null || ! preTagChangeIdentifier.equals(tagIdentifier)) { + // 更新map数据 + currentTags.put(tag, tagIdentifier); + // 执行重新加载此项的动作 + handleReloadResult(this.reloadManager.doReload(reloadItem)); + } + } + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/annotation/SmartReload.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/annotation/SmartReload.java new file mode 100644 index 00000000..6176ae2d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/annotation/SmartReload.java @@ -0,0 +1,18 @@ +package com.gangquan360.smartadmin.common.reload.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 定义 SmartReload 注解 + * + * @author zhuoda + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SmartReload { + + String value(); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/AbstractSmartReloadObject.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/AbstractSmartReloadObject.java new file mode 100644 index 00000000..1f37569d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/AbstractSmartReloadObject.java @@ -0,0 +1,31 @@ +package com.gangquan360.smartadmin.common.reload.domain; + +import com.gangquan360.smartadmin.common.reload.domain.entity.ReloadItem; +import com.gangquan360.smartadmin.common.reload.domain.entity.SmartReloadResult; + +import java.io.PrintWriter; +import java.io.StringWriter; +/** + * AbstractSmartReloadObject 处理程序的抽象类 + * + * @author zhuoda + */ +public abstract class AbstractSmartReloadObject { + + protected String getStackTrace(Throwable e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + return sw.toString(); + } + + /** + * 通过reloadItem参数reload,获得结果 + * + * @param reloadItem + * @return boolean + * @author zhuokongming + * @date 2016年10月21日 下午2:09:44 + */ + public abstract SmartReloadResult reload(ReloadItem reloadItem); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/AnnotationReloadObject.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/AnnotationReloadObject.java new file mode 100644 index 00000000..21ea4dea --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/AnnotationReloadObject.java @@ -0,0 +1,44 @@ +package com.gangquan360.smartadmin.common.reload.domain; + +import com.gangquan360.smartadmin.common.reload.annotation.SmartReload; +import com.gangquan360.smartadmin.common.reload.domain.entity.ReloadItem; +import com.gangquan360.smartadmin.common.reload.domain.entity.SmartReloadResult; + +import java.lang.reflect.Method; + +/** + * Reload 处理程序的实现类 + * 用于包装以注解 SmartReload 实现的处理类 + * + * @author zhuoda + */ +public class AnnotationReloadObject extends AbstractSmartReloadObject { + + private Object reloadObject; + + private Method method; + + public AnnotationReloadObject(Object reloadObject, Method method) { + super(); + this.reloadObject = reloadObject; + this.method = method; + this.method.setAccessible(true); + } + + @Override + public SmartReloadResult reload(ReloadItem reloadItem) { + SmartReloadResult result = new SmartReloadResult(); + String tag = method.getAnnotation(SmartReload.class).value(); + result.setTag(tag); + result.setArgs(reloadItem.getArgs()); + result.setIdentification(reloadItem.getIdentification()); + try { + Object invoke = method.invoke(reloadObject, reloadItem.getArgs()); + result.setResult((Boolean) invoke); + } catch (Throwable e) { + result.setException(getStackTrace(e)); + } + return result; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/InterfaceReloadObject.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/InterfaceReloadObject.java new file mode 100644 index 00000000..409aba0f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/InterfaceReloadObject.java @@ -0,0 +1,37 @@ +package com.gangquan360.smartadmin.common.reload.domain; + +import com.gangquan360.smartadmin.common.reload.domain.entity.ReloadItem; +import com.gangquan360.smartadmin.common.reload.domain.entity.SmartReloadResult; +import com.gangquan360.smartadmin.common.reload.interfaces.SmartReloadable; + +/** + * Reload 处理程序的实现类 + * 用于处理以接口实现的处理类 + * + * @author zhuoda + */ +public class InterfaceReloadObject extends AbstractSmartReloadObject { + + private SmartReloadable object; + + public InterfaceReloadObject(SmartReloadable object) { + super(); + this.object = object; + } + + @Override + public SmartReloadResult reload(ReloadItem reloadItem) { + SmartReloadResult reloadResult = new SmartReloadResult(); + reloadResult.setArgs(reloadItem.getArgs()); + reloadResult.setIdentification(reloadItem.getIdentification()); + reloadResult.setTag(reloadItem.getTag()); + try { + boolean res = object.reload(reloadItem); + reloadResult.setResult(res); + } catch (Throwable e) { + reloadResult.setException(getStackTrace(e)); + } + return reloadResult; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/entity/ReloadItem.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/entity/ReloadItem.java new file mode 100644 index 00000000..a2e9a40d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/entity/ReloadItem.java @@ -0,0 +1,55 @@ +package com.gangquan360.smartadmin.common.reload.domain.entity; +/** + * ReloadItem 类 + * + * @author zhuoda + */ +public class ReloadItem { + + /** + * 项名称 + */ + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 标识 + */ + private String identification; + + public ReloadItem() { + + } + public ReloadItem(String tag, String identification, String args) { + this.tag = tag; + this.identification = identification; + this.args = args; + } + + public String getTag() { + return tag; + } + public void setTag(String tag) { + this.tag = tag; + } + public String getIdentification() { + return identification; + } + public void setIdentification(String identification) { + this.identification = identification; + } + public String getArgs() { + return args; + } + public void setArgs(String args) { + this.args = args; + } + @Override + public String toString() { + return "ReloadItem{" + "tag='" + tag + '\'' + ", identification='" + identification + '\'' + ", args='" + args + '\'' + '}'; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/entity/SmartReloadResult.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/entity/SmartReloadResult.java new file mode 100644 index 00000000..a22fba47 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/domain/entity/SmartReloadResult.java @@ -0,0 +1,102 @@ +package com.gangquan360.smartadmin.common.reload.domain.entity; +/** + * t_reload_result 表 实体类 + * + * @author zhuoda + */ +public class SmartReloadResult { + + /** + * 项名称 + */ + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 标识 + */ + private String identification; + + /** + * 处理结果 + */ + private boolean result; + + /** + * 异常说明 + */ + private String exception; + + public SmartReloadResult() { + } + + public SmartReloadResult(String tag, String args, boolean result, String exception) { + this.tag = tag; + this.args = args; + this.result = result; + this.exception = exception; + } + + public SmartReloadResult(String tag, String args, String identification, boolean result, String exception) { + this.tag = tag; + this.args = args; + this.identification = identification; + this.result = result; + this.exception = exception; + } + + public void setTag(String tag) { + this.tag = tag; + } + + public void setArgs(String args) { + this.args = args; + } + + public void setIdentification(String identification) { + this.identification = identification; + } + + public void setResult(boolean result) { + this.result = result; + } + + public void setException(String exception) { + this.exception = exception; + } + + public String getTag() { + return tag; + } + + public String getArgs() { + return args; + } + + public String getIdentification() { + return identification; + } + + public boolean isResult() { + return result; + } + + public String getException() { + return exception; + } + + @Override + public String toString() { + return "SmartReloadResult{" + + "tag='" + tag + '\'' + + ", args='" + args + '\'' + + ", identification='" + identification + '\'' + + ", result=" + result + + ", exception='" + exception + '\'' + + '}'; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/interfaces/SmartReloadCommandInterface.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/interfaces/SmartReloadCommandInterface.java new file mode 100644 index 00000000..6adbed3e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/interfaces/SmartReloadCommandInterface.java @@ -0,0 +1,38 @@ +package com.gangquan360.smartadmin.common.reload.interfaces; + +import com.gangquan360.smartadmin.common.reload.domain.entity.ReloadItem; +import com.gangquan360.smartadmin.common.reload.domain.entity.SmartReloadResult; + +import java.util.List; + +/** + * 检测是否 Reload 的类 + * + * @author zhuoda + */ +public interface SmartReloadCommandInterface { + + /** + * 任务: + * 读取数据库中 ReloadItem 数据 + * 校验是否发生变化 + * 执行重加载动作 + */ + void doTask(); + + /** + * 该方法返回一个List:
+ * ReloadItem对象的tagIdentify为:该tag的 状态(状态其实就是个字符串,如果该字符串跟上次有变化则进行reload操作)
+ * ReloadItem对象的args为: reload操作需要的参数

+ * + * @return List + */ + List readReloadItem(); + + /** + * 处理Reload结果 + * + * @param reloadResult + */ + void handleReloadResult(SmartReloadResult reloadResult); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/interfaces/SmartReloadThreadLogger.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/interfaces/SmartReloadThreadLogger.java new file mode 100644 index 00000000..5db12541 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/interfaces/SmartReloadThreadLogger.java @@ -0,0 +1,12 @@ +package com.gangquan360.smartadmin.common.reload.interfaces; + +/** + * SmartReloadThreadLogger 日志类 + */ +public interface SmartReloadThreadLogger { + + void error(String string); + + void error(String string, Throwable e); + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/interfaces/SmartReloadable.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/interfaces/SmartReloadable.java new file mode 100644 index 00000000..66122413 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/reload/interfaces/SmartReloadable.java @@ -0,0 +1,18 @@ +package com.gangquan360.smartadmin.common.reload.interfaces; + +import com.gangquan360.smartadmin.common.reload.domain.entity.ReloadItem; +/** + * reload 接口
+ * 需要reload的业务实现类 + */ +@FunctionalInterface +public interface SmartReloadable { + + /** + * reload + * + * @param reloadItem + * @return boolean + */ + boolean reload(ReloadItem reloadItem); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/swagger/SmartSwaggerApiModelEnumPlugin.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/swagger/SmartSwaggerApiModelEnumPlugin.java new file mode 100644 index 00000000..cc863c48 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/swagger/SmartSwaggerApiModelEnumPlugin.java @@ -0,0 +1,91 @@ +/* + * + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package com.gangquan360.smartadmin.common.swagger; + +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.common.domain.BaseEnum; +import com.google.common.base.Function; +import com.google.common.base.Optional; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin; +import springfox.documentation.spi.schema.contexts.ModelPropertyContext; +import springfox.documentation.swagger.common.SwaggerPluginSupport; + +import java.lang.reflect.AnnotatedElement; + +import static springfox.documentation.schema.Annotations.findPropertyAnnotation; + +/** + * swagger 用于说明枚举类字段说明 + * SWAGGER_PLUGIN_ORDER+1 是将此配置放在原来的后面执行 + * + * @author listen + * @date 2019年5月16日 15:36:56 + */ +public class SmartSwaggerApiModelEnumPlugin implements ModelPropertyBuilderPlugin { + + @Override + public void apply(ModelPropertyContext context) { + Optional annotation = Optional.absent(); + + if (context.getAnnotatedElement().isPresent()) { + annotation = annotation.or(findApiModePropertyAnnotation(context.getAnnotatedElement().get())); + } + if (context.getBeanPropertyDefinition().isPresent()) { + annotation = annotation.or(findPropertyAnnotation(context.getBeanPropertyDefinition().get(), ApiModelPropertyEnum.class)); + } + + if (annotation.isPresent()) { + Class aClass = annotation.get().value(); + String enumInfo = BaseEnum.getInfo(aClass); + String enumDesc = annotation.get().enumDesc(); + context.getBuilder().required(annotation.transform(toIsRequired()).or(false)) + .description(enumDesc +":"+enumInfo) + .example(annotation.transform(toExample()).orNull()); + } + } + + @Override + public boolean supports(DocumentationType delimiter) { + return SwaggerPluginSupport.pluginDoesApply(delimiter); + } + + static Function toIsRequired() { + return annotation -> annotation.required(); + } + + public static Optional findApiModePropertyAnnotation(AnnotatedElement annotated) { + return Optional.fromNullable(AnnotationUtils.getAnnotation(annotated, ApiModelPropertyEnum.class)); + } + + static Function toExample() { + return annotation -> { + String example = annotation.example(); + if (StringUtils.isBlank(example)) { + return ""; + } + return example; + }; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/bigdecimal/BigDecimalValidator.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/bigdecimal/BigDecimalValidator.java new file mode 100644 index 00000000..ed0a91fb --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/bigdecimal/BigDecimalValidator.java @@ -0,0 +1,73 @@ +package com.gangquan360.smartadmin.common.validator.bigdecimal; + +import com.gangquan360.smartadmin.util.SmartBigDecimalUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.math.BigDecimal; + +/** + * BigDecimal 类校验器 + * + * @author listen + * @date 2018年3月20日 13:51:46 + */ +public class BigDecimalValidator implements ConstraintValidator { + + /** + * 获取定义的数值 + */ + private BigDecimal value; + + /** + * 获取比较符 + */ + private ComparisonSymbolEnum symbolEnum; + + /** + * 是否必须 + */ + private boolean required; + + @Override + public void initialize(CheckBigDecimal constraintAnnotation) { + // 初始化属性 + value = new BigDecimal(constraintAnnotation.value()); + symbolEnum = constraintAnnotation.symbolEnum(); + required = constraintAnnotation.required(); + } + + @Override + public boolean isValid(BigDecimal decimal, ConstraintValidatorContext constraintValidatorContext) { + + // 如果数值为空,校验是否必须 + if (null == decimal) { + return ! required; + } + + // 根据操作符,校验结果 + switch (symbolEnum) { + // 等于 + case EQUAL: + return SmartBigDecimalUtil.equals(decimal, value); + // 不等于 + case NOT_EQUAL: + return ! SmartBigDecimalUtil.equals(decimal, value); + // 小于 + case LESS_THAN: + return SmartBigDecimalUtil.isLessThan(decimal, value); + // 小于等于 + case LESS_THAN_OR_EQUAL: + return SmartBigDecimalUtil.isLessThan(decimal, value) || SmartBigDecimalUtil.equals(decimal, value); + // 大于 + case GREATER_THAN: + return SmartBigDecimalUtil.isGreaterThan(decimal, value); + // 大于等于 + case GREATER_THAN_OR_EQUAL: + return SmartBigDecimalUtil.isGreaterThan(decimal, value) || SmartBigDecimalUtil.equals(decimal, value); + default: + } + + return false; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/bigdecimal/CheckBigDecimal.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/bigdecimal/CheckBigDecimal.java new file mode 100644 index 00000000..a005fd8b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/bigdecimal/CheckBigDecimal.java @@ -0,0 +1,53 @@ +package com.gangquan360.smartadmin.common.validator.bigdecimal; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义的属性校验注解 + * + * @author listen + * @date 2018年3月20日 13:53:33 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = BigDecimalValidator.class)// 自定义验证的处理类 +public @interface CheckBigDecimal { + + /** + * 与这个数值校验 + * + * @return + */ + String value(); + + /** + * 比较符 请使用 ComparisonSymbolEnum 枚举类 + * + * @return + */ + ComparisonSymbolEnum symbolEnum(); + + /** + * 默认的错误提示信息 + * + * @return String + */ + String message() default "非法的数值"; + + /** + * 是否必须 : 默认 true + * + * @return boolean + */ + boolean required() default true; + + //下面这两个属性必须添加 :不然会报错 + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/bigdecimal/ComparisonSymbolEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/bigdecimal/ComparisonSymbolEnum.java new file mode 100644 index 00000000..f25948cc --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/bigdecimal/ComparisonSymbolEnum.java @@ -0,0 +1,40 @@ +package com.gangquan360.smartadmin.common.validator.bigdecimal; + +/** + * 比较符枚举类 + * + * @author listen + * @date 2018/03/20 14:01 + */ +public enum ComparisonSymbolEnum { + + /** + * 等于 + */ + EQUAL, + + /** + * 不等于 + */ + NOT_EQUAL, + + /** + * 小于 + */ + LESS_THAN, + + /** + * 小于等于 + */ + LESS_THAN_OR_EQUAL, + + /** + * 大于 + */ + GREATER_THAN, + + /** + * 大于等于 + */ + GREATER_THAN_OR_EQUAL, +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/en/CheckEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/en/CheckEnum.java new file mode 100644 index 00000000..662dc7ed --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/en/CheckEnum.java @@ -0,0 +1,51 @@ +package com.gangquan360.smartadmin.common.validator.en; + + +import com.gangquan360.smartadmin.common.domain.BaseEnum; +import com.gangquan360.smartadmin.common.validator.en.EnumValidator; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义的属性校验注解 + * 为了方便与校验属性的值是否为合法的枚举值 + * + * @author listen + * @date 2017/11/11 15:31 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = EnumValidator.class)// 自定义验证的处理类 +public @interface CheckEnum { + + /** + * 默认的错误提示信息 + * + * @return String + */ + String message() default "非法的枚举值"; + + /** + * 枚举类对象 必须实现BaseEnum接口 + * + * @return + */ + Class enumClazz(); + + /** + * 是否必须 + * + * @return boolean + */ + boolean required() default false; + + //下面这两个属性必须添加 :不然会报错 + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/en/EnumValidator.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/en/EnumValidator.java new file mode 100644 index 00000000..8cb3004d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/common/validator/en/EnumValidator.java @@ -0,0 +1,80 @@ +package com.gangquan360.smartadmin.common.validator.en; + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.List; + +/** + * 枚举类校验器 + * + * @author listen + * @date 2017/11/11 15:34 + */ +public class EnumValidator implements ConstraintValidator { + + /** + * 枚举类的类对象 + */ + private Class enumClass; + + /** + * 是否必须 + */ + private boolean required; + + @Override + public void initialize(CheckEnum constraintAnnotation) { + // 获取注解传入的枚举类对象 + enumClass = constraintAnnotation.enumClazz(); + required = constraintAnnotation.required(); + } + + @Override + public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) { + // 判断是否必须 + if (null == value) { + return !required; + } + + if (value instanceof List) { + // 如果为 List 集合数据 + return this.checkList((List) value); + } + + // 校验是否为合法的枚举值 + return this.hasEnum(value); + } + + /** + * 校验集合类型 + * + * @param list + * @return + */ + private boolean checkList(List list) { + if (required && list.isEmpty()) { + // 必须的情况下 list 不能为空 + return false; + } + for (Object obj : list) { + boolean hasEnum = this.hasEnum(obj); + if (!hasEnum) { + return false; + } + } + return true; + } + + private boolean hasEnum(Object value) { + // 校验是否为合法的枚举值 + BaseEnum[] enums = enumClass.getEnumConstants(); + for (BaseEnum baseEnum : enums) { + if (baseEnum.getValue().equals(value)) { + return true; + } + } + return false; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartAdminWebAppConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartAdminWebAppConfig.java new file mode 100644 index 00000000..b4ee830f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartAdminWebAppConfig.java @@ -0,0 +1,29 @@ +package com.gangquan360.smartadmin.config; + +import com.gangquan360.smartadmin.interceptor.SmartAuthenticationInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.*; + +/** + * @Description + * @Author lihaifan + * @Date Created in 2017/10/24 13:48 + */ +@Configuration +public class SmartAdminWebAppConfig implements WebMvcConfigurer{ + @Autowired + private SmartAuthenticationInterceptor smartAuthenticationInterceptor; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(smartAuthenticationInterceptor).addPathPatterns("/**"); + } + + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/druidMonitor").setViewName("redirect:/druid/index.html"); + registry.addViewController("/swaggerApi").setViewName("redirect:/swagger-ui.html"); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartDruidDataSourceConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartDruidDataSourceConfig.java new file mode 100644 index 00000000..b05932ab --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartDruidDataSourceConfig.java @@ -0,0 +1,170 @@ +package com.gangquan360.smartadmin.config; + +import com.alibaba.druid.filter.Filter; +import com.alibaba.druid.filter.stat.StatFilter; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.support.http.StatViewServlet; +import com.alibaba.druid.support.http.WebStatFilter; +import com.alibaba.druid.support.spring.stat.DruidStatInterceptor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.JdkRegexpMethodPointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/** + * [ 数据源配置 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Slf4j +@Configuration +public class SmartDruidDataSourceConfig { + + @Value("${spring.datasource.driver-class-name}") + String driver; + + @Value("${spring.datasource.url}") + String url; + + @Value("${spring.datasource.username}") + String username; + + @Value("${spring.datasource.password}") + String password; + + @Value("${spring.datasource.initial-size}") + int initialSize; + + @Value("${spring.datasource.min-idle}") + int minIdle; + + @Value("${spring.datasource.max-active}") + int maxActive; + + @Value("${spring.datasource.max-wait}") + long maxWait; + + @Value("${spring.datasource.time-between-eviction-runs-millis}") + long timeBetweenEvictionRunsMillis; + + @Value("${spring.datasource.min-evictable-edle-time-millis}") + long minEvictableIdleTimeMillis; + + @Value("${spring.datasource.filters}") + String filters; + + @Value("${spring.datasource.druid.username}") + String druidUserName; + + @Value("${spring.datasource.druid.password}") + String druidPassword; + + @Value("${spring.datasource.druid.login.enabled}") + boolean druidLoginEnable; + + @Autowired + private StatFilter logSlowSql; + + @Autowired + private DruidStatInterceptor druidStatInterceptor; + + @Bean + @Primary + public DataSource druidDataSource() { + DruidDataSource druidDataSource = new DruidDataSource(); + druidDataSource.setDriverClassName(driver); + druidDataSource.setUrl(url); + druidDataSource.setUsername(username); + druidDataSource.setPassword(password); + druidDataSource.setInitialSize(initialSize); + druidDataSource.setMinIdle(minIdle); + druidDataSource.setMaxActive(maxActive); + druidDataSource.setMaxWait(maxWait); + druidDataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + druidDataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + try { + druidDataSource.setFilters(filters); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(logSlowSql); + druidDataSource.setProxyFilters(arrayList); + druidDataSource.init(); + } catch (SQLException e) { + log.error("初始化数据源出错", e); + } + + return druidDataSource; + } + + @Bean + public ServletRegistrationBean druidServlet() { + ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(); + servletRegistrationBean.setServlet(new StatViewServlet()); + servletRegistrationBean.addUrlMappings("/druid/*"); + Map initParameters = new HashMap(); + //不设置用户名密码可以直接通过druid/index.html访问 + if (druidLoginEnable) { + initParameters.put("loginUsername", druidUserName); + initParameters.put("loginPassword", druidPassword); + } + initParameters.put("resetEnable", "false"); + servletRegistrationBean.setInitParameters(initParameters); + return servletRegistrationBean; + } + + @Bean + public FilterRegistrationBean filterRegistrationBean() { + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); + filterRegistrationBean.setFilter(new WebStatFilter()); + filterRegistrationBean.addUrlPatterns("/*"); + filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); + return filterRegistrationBean; + } + + @Bean + public StatFilter logSlowSql() { + StatFilter statFilter = new StatFilter(); + statFilter.setMergeSql(true); + statFilter.setSlowSqlMillis(300); + statFilter.setLogSlowSql(true); + return statFilter; + } + + @Bean(name = "druid-stat-interceptor") + public DruidStatInterceptor druidStatInterceptor() { + DruidStatInterceptor dsInterceptor = new DruidStatInterceptor(); + return dsInterceptor; + } + + @Bean + public JdkRegexpMethodPointcut jdkRegexpMethodPointcut() { + JdkRegexpMethodPointcut jdkRegexpMethodPointcut = new JdkRegexpMethodPointcut(); + jdkRegexpMethodPointcut.setPatterns("com.gangquan360.smartadmin.module..*Service.*"); + return jdkRegexpMethodPointcut; + } + + @Bean + public DefaultPointcutAdvisor defaultPointcutAdvisor() { + DefaultPointcutAdvisor pointcutAdvisor = new DefaultPointcutAdvisor(); + pointcutAdvisor.setPointcut(jdkRegexpMethodPointcut()); + pointcutAdvisor.setAdvice(druidStatInterceptor); + return pointcutAdvisor; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartHeartBeatConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartHeartBeatConfig.java new file mode 100644 index 00000000..7e572a84 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartHeartBeatConfig.java @@ -0,0 +1,33 @@ +package com.gangquan360.smartadmin.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +@Configuration +public class SmartHeartBeatConfig { + + /** + * 延迟执行时间 + */ + @Value("${heart-beat.delayHandlerTime}") + private Long delayHandlerTime; + + /** + * 间隔执行时间 + */ + @Value("${heart-beat.intervalTime}") + private Long intervalTime; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartKaptchaConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartKaptchaConfig.java new file mode 100644 index 00000000..e29d98bf --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartKaptchaConfig.java @@ -0,0 +1,49 @@ +package com.gangquan360.smartadmin.config; + +import com.gangquan360.smartadmin.common.kaptcha.KaptchaNoise; +import com.gangquan360.smartadmin.common.kaptcha.KaptchaWordRenderer; +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Properties; + +/** + * [ 验证码配置 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/4 0004 上午 9:40 + * @since JDK1.8 + */ +@Configuration +public class SmartKaptchaConfig { + + @Bean + public DefaultKaptcha getDefaultKaptcha(){ + DefaultKaptcha defaultKaptcha=new DefaultKaptcha(); + Properties properties=new Properties(); + properties.setProperty("kaptcha.border", "no"); + properties.setProperty("kaptcha.border.color", "34,114,200"); + properties.setProperty("kaptcha.image.width", "125"); + properties.setProperty("kaptcha.image.height", "45"); + properties.setProperty("kaptcha.textproducer.char.string", "ABCDEFG23456789"); + properties.setProperty("kaptcha.textproducer.char.length", "5"); + properties.setProperty("kaptcha.textproducer.font.names", "Arial,Arial Narrow,Serif,Helvetica,Tahoma,Times New Roman,Verdana"); + properties.setProperty("kaptcha.textproducer.font.size", "38"); + + properties.setProperty("kaptcha.background.clear.from", "white"); + properties.setProperty("kaptcha.background.clear.to", "white"); + + properties.setProperty("kaptcha.word.impl",KaptchaWordRenderer.class.getName()); + properties.setProperty("kaptcha.noise.impl", KaptchaNoise.class.getName()); + + Config config=new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartMybatisPlusConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartMybatisPlusConfig.java new file mode 100644 index 00000000..5cdb86a1 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartMybatisPlusConfig.java @@ -0,0 +1,39 @@ +package com.gangquan360.smartadmin.config; + +import com.baomidou.mybatisplus.plugins.PaginationInterceptor; +import com.baomidou.mybatisplus.plugins.PerformanceInterceptor; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * description + * + * @author listen + * @date 2017/12/19 13:54 + */ +@EnableTransactionManagement +@Configuration +@MapperScan(basePackages = {"com.gangquan360.smartadmin.module.*"}) +public class SmartMybatisPlusConfig { + + /** + * 分页插件 + */ + @Bean + public PaginationInterceptor paginationInterceptor() { + return new PaginationInterceptor(); + } + + /** + * mybatis-plus SQL执行效率插件【生产环境可以关闭】 + */ + @Bean + @Conditional(SystemEnvironmentCondition.class) + public PerformanceInterceptor performanceInterceptor() { + return new PerformanceInterceptor(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartRedisConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartRedisConfig.java new file mode 100644 index 00000000..881d54ac --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartRedisConfig.java @@ -0,0 +1,74 @@ +package com.gangquan360.smartadmin.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.*; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * [ redis配置 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Configuration +public class SmartRedisConfig { + + @Autowired + private RedisConnectionFactory factory; + + @Bean + public RedisTemplate redisTemplate() { + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + RedisTemplate template = new RedisTemplate(); + template.setConnectionFactory(factory); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(jackson2JsonRedisSerializer); + template.setHashKeySerializer(jackson2JsonRedisSerializer); + template.setHashValueSerializer(jackson2JsonRedisSerializer); + template.setDefaultSerializer(new StringRedisSerializer()); + template.afterPropertiesSet(); + return template; + } + + @Bean + public HashOperations hashOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForHash(); + } + + @Bean + public ValueOperations valueOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForValue(); + } + + @Bean + public ListOperations listOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForList(); + } + + @Bean + public SetOperations setOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForSet(); + } + + @Bean + public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForZSet(); + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartReloadConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartReloadConfig.java new file mode 100644 index 00000000..8b2f2ec8 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartReloadConfig.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.config; + +import com.gangquan360.smartadmin.common.reload.SmartReloadManager; +import com.gangquan360.smartadmin.common.reload.interfaces.SmartReloadThreadLogger; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/28 0028 下午 20:15 + * @since JDK1.8 + */ +@Slf4j +@Configuration +public class SmartReloadConfig { + + @Value("${smart-reload.thread-count}") + private Integer threadCount; + + @Bean + public SmartReloadManager initSmartReloadManager() { + /** + * 创建 Reload Manager 调度器 + */ + SmartReloadManager smartReloadManager = new SmartReloadManager(new SmartReloadThreadLogger() { + @Override + public void error(String string) { + log.error(string); + } + + @Override + public void error(String string, Throwable e) { + log.error(string, e); + } + }, threadCount); + return smartReloadManager; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartRestTemplateConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartRestTemplateConfig.java new file mode 100644 index 00000000..da3eac8c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartRestTemplateConfig.java @@ -0,0 +1,109 @@ +package com.gangquan360.smartadmin.config; + +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.converter.FormHttpMessageConverter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Configuration +public class SmartRestTemplateConfig { + + + @Value("${http.pool.max-total}") + private Integer maxTotal; + @Value("${http.pool.default-max-per-route}") + private Integer defaultMaxPerRoute; + @Value("${http.pool.socket-timeout}") + private Integer socketTimeout; + @Value("${http.pool.connect-timeout}") + private Integer connectTimeout; + @Value("${http.pool.connection-request-timeout}") + private Integer connectionRequestTimeout; + + + @Bean + public RestTemplate restTemplate(ClientHttpRequestFactory factory) { + return new RestTemplate(factory); + } + + @Bean + public ClientHttpRequestFactory httpRequestFactory() { + HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient()); + return factory; + } + + /** + * fastJsonRestTemplate + * + * @return + */ + @Bean(name = "fastJsonRestTemplate") + public RestTemplate fastJsonRestTemplate() { + RestTemplate restTemplate = new RestTemplate(httpRequestFactory()); + + HttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8")); + + FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); + List fastMediaTypes = new ArrayList<>(); + fastMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); + fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); + fastConverter.setSupportedMediaTypes(fastMediaTypes); + List> converters = restTemplate.getMessageConverters(); + converters.add(1,converter); + converters.add(fastConverter); + return restTemplate; + } + + + @Bean + public HttpClient httpClient() { + Registry registry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.getSocketFactory()) + .register("https", SSLConnectionSocketFactory.getSocketFactory()) + .build(); + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); + connectionManager.setMaxTotal(maxTotal); + connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); + + RequestConfig requestConfig = RequestConfig.custom() + .setSocketTimeout(socketTimeout) + .setConnectTimeout(connectTimeout) + .setConnectionRequestTimeout(connectionRequestTimeout) + .build(); + return HttpClientBuilder.create() + .setDefaultRequestConfig(requestConfig) + .setConnectionManager(connectionManager) + .build(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartSwaggerApiModelEnumConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartSwaggerApiModelEnumConfig.java new file mode 100644 index 00000000..93d9427c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartSwaggerApiModelEnumConfig.java @@ -0,0 +1,29 @@ +package com.gangquan360.smartadmin.config; + +import com.gangquan360.smartadmin.common.swagger.SmartSwaggerApiModelEnumPlugin; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.core.annotation.Order; +import springfox.documentation.swagger.common.SwaggerPluginSupport; + +/** + * [ 对于枚举类进行swagger注解,与前端的vue-enum相匹配 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/9 0009 上午 9:46 + * @since JDK1.8 + */ +@Configuration +@Profile({"dev", "sit", "pre", "prod"}) +public class SmartSwaggerApiModelEnumConfig { + + @Bean + @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1) + public SmartSwaggerApiModelEnumPlugin swaggerEnum(){ + return new SmartSwaggerApiModelEnumPlugin(); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartSwaggerDynamicGroupConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartSwaggerDynamicGroupConfig.java new file mode 100644 index 00000000..efe1eda8 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartSwaggerDynamicGroupConfig.java @@ -0,0 +1,217 @@ +package com.gangquan360.smartadmin.config; + +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.RequestHandler; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.*; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * [ 根据SwaggerTagConst内部类动态生成Swagger group ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/7 0007 下午 19:20 + * @since JDK1.8 + */ +@Slf4j +@EnableSwagger2 +@Configuration +@Profile({"dev", "sit", "pre", "prod"}) +public class SmartSwaggerDynamicGroupConfig implements EnvironmentAware, BeanDefinitionRegistryPostProcessor { + + /** + * 分组名称 + */ + private String apiGroupName; + + /** + * 文档标题 + */ + private String title; + + /** + * 文档描述 + */ + private String description; + + /** + * api版本 + */ + private String version; + + /** + * service url + */ + private String serviceUrl; + + /** + * controller 包路径 + */ + private String packAge; + + private int groupIndex = 0; + + private String groupName = "default"; + + private List groupList = Lists.newArrayList(); + + private Map> groupMap = Maps.newHashMap(); + + @Override + public void setEnvironment(Environment environment) { + this.apiGroupName = environment.getProperty("swagger.apiGroupName"); + this.title = environment.getProperty("swagger.title"); + this.description = environment.getProperty("swagger.description"); + this.version = environment.getProperty("swagger.version"); + this.serviceUrl = environment.getProperty("swagger.serviceUrl"); + this.packAge = environment.getProperty("swagger.packAge"); + } + + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + this.groupBuild(); + for (Map.Entry> entry : groupMap.entrySet()) { + String group = entry.getKey(); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Docket.class, this :: baseDocket); + BeanDefinition beanDefinition = builder.getRawBeanDefinition(); + registry.registerBeanDefinition(group + "Api", beanDefinition); + } + } + + private void groupBuild() { + Class clazz = SwaggerTagConst.class; + Class[] innerClazz = clazz.getDeclaredClasses(); + for (Class cls : innerClazz) { + String group = cls.getSimpleName(); + List apiTags = Lists.newArrayList(); + Field[] fields = cls.getDeclaredFields(); + for (Field field : fields) { + boolean isFinal = Modifier.isFinal(field.getModifiers()); + if (isFinal) { + try { + apiTags.add(field.get(null).toString()); + } catch (Exception e) { + log.error("", e); + } + } + } + groupList.add(group); + groupMap.put(group, apiTags); + } + } + + private Docket baseDocket() { + // 请求类型过滤规则 + Predicate controllerPredicate = getControllerPredicate(); + // controller 包路径 + Predicate controllerPackage = RequestHandlerSelectors.basePackage(packAge); + return new Docket(DocumentationType.SWAGGER_2) + .groupName(groupName) + .forCodeGeneration(true) + .select() + .apis(controllerPackage) + .apis(controllerPredicate) + .paths(PathSelectors.any()) + .build() + .apiInfo(this.serviceApiInfo()) + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()); + } + + private List securitySchemes() { + List apiKeyList= new ArrayList<>(); + apiKeyList.add(new ApiKey("x-access-token", "x-access-token", "header")); + return apiKeyList; + } + + private List securityContexts() { + List securityContexts=new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.any()) + .build()); + return securityContexts; + } + + List defaultAuth() { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences=new ArrayList<>(); + securityReferences.add(new SecurityReference("x-access-token", authorizationScopes)); + return securityReferences; + } + + private Predicate getControllerPredicate() { + groupName = groupList.get(groupIndex); + List apiTags = groupMap.get(groupName); + Predicate methodPredicate = (input) -> { + Api api = null; + Optional apiOptional = input.findControllerAnnotation(Api.class); + if (apiOptional.isPresent()) { + api = apiOptional.get(); + } + List tags = Arrays.asList(api.tags()); + if (api != null && apiTags.containsAll(tags)) { + return true; + } + return false; + }; + groupIndex++; + return Predicates.and(RequestHandlerSelectors.withClassAnnotation(RestController.class), methodPredicate); + } + + private ApiInfo serviceApiInfo() { + return new ApiInfoBuilder() + .title(title) + .description(description) + .version(version) + .license("Apache License Version 2.0") + .contact(new Contact("1024创新实验室", "http://www.1024lab.net", "")) + .termsOfServiceUrl(serviceUrl) + .build(); + } + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { + + } + + + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartWebSocketConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartWebSocketConfig.java new file mode 100644 index 00000000..3087d2ec --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SmartWebSocketConfig.java @@ -0,0 +1,25 @@ +package com.gangquan360.smartadmin.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * [ WebSocketConfig ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/10 0010 下午 16:07 + * @since JDK1.8 + */ +@Configuration +public class SmartWebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SystemEnvironmentCondition.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SystemEnvironmentCondition.java new file mode 100644 index 00000000..46755115 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/config/SystemEnvironmentCondition.java @@ -0,0 +1,22 @@ +package com.gangquan360.smartadmin.config; +import com.gangquan360.smartadmin.constant.SystemEnvironmentEnum; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.type.AnnotatedTypeMetadata; +/** + * 是否是正式环境 + * + * @author listen + * @date 2019/08/27 08:56 + */ +public class SystemEnvironmentCondition implements Condition { + + @Value("${spring.profiles.active}") + private String systemEnvironment; + + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { + return ! SystemEnvironmentEnum.PROD.equalsValue(systemEnvironment); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/CommonConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/CommonConst.java new file mode 100644 index 00000000..1b482e0c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/CommonConst.java @@ -0,0 +1,51 @@ +package com.gangquan360.smartadmin.constant; + +import com.google.common.collect.ImmutableSet; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.Set; + +/** + * + * [ 通用常量 ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +public class CommonConst { + + + public static final class Page { + public static final Integer SIZE = 10; + } + + public static final class Password { + public static final String DEFAULT = "123456"; + public static final String SALT_FORMAT = "smart_%s_admin"; + } + + public static final String IGNORE_H5_URL_MAPPING = "/h5/api"; + + public static final class CommonCollection { + public static final Set IGNORE_URL = ImmutableSet.of("/swagger", "Excel"); + + public static final Set IGNORE_URL_MAPPING = ImmutableSet.of(IGNORE_H5_URL_MAPPING); + + public static Boolean contain(Set ignores, String uri) { + if (CollectionUtils.isEmpty(ignores)) { + return false; + } + for (String ignoreUrl : ignores) { + if (uri.startsWith(ignoreUrl)) { + return true; + } + } + return false; + } + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/SmartReloadTagConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/SmartReloadTagConst.java new file mode 100644 index 00000000..f5ed6e68 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/SmartReloadTagConst.java @@ -0,0 +1,16 @@ +package com.gangquan360.smartadmin.constant; +/** + * smart initDefines 项 常量 + * + * @author listen + * @date 2018/02/10 14:29 + */ +public class SmartReloadTagConst { + + /** + * 系统环境设置 DEMO + */ + public static final String SYSTEM_CONFIG = "system_config"; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/SwaggerTagConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/SwaggerTagConst.java new file mode 100644 index 00000000..6ce07b85 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/SwaggerTagConst.java @@ -0,0 +1,69 @@ +package com.gangquan360.smartadmin.constant; + +/** + * [] + * + * @author yandanyang + * @version 1.0 + * @since JDK1.8 + */ +public class SwaggerTagConst { + + + public static class Admin { + public static final String MANAGER_SYSTEM_CONFIG = "管理端-系统配置"; + + public static final String MANAGER_USER = "管理端-用户"; + + public static final String MANAGER_USER_LOGIN = "管理端-用户登录"; + + public static final String MANAGER_DEPARTMENT = "管理端-部门"; + + public static final String MANAGER_ROLE = "管理端-角色"; + + public static final String MANAGER_ROLE_USER = "管理端-角色用户"; + + public static final String MANAGER_ROLE_PRIVILEGE = "管理端-角色权限"; + + public static final String MANAGER_SMART_RELOAD = "管理端-smart reload"; + + public static final String MANAGER_ORDER_OPERATE_LOG = "管理端-单据操作日志"; + + public static final String MANAGER_TASK_SCHEDULER = "管理端-任务调度"; + + public static final String MANAGER_USER_LOGIN_LOG = "管理端-用户登录日志"; + + public static final String MANAGER_USER_OPERATE_LOG = "管理端-用户操作日志"; + + public static final String MANAGER_DATA_SCOPE = "管理端-数据范围"; + + public static final String MANAGER_JOB = "管理端-岗位"; + + public static final String MANAGER_NOTICE = "管理端-系统通知"; + + public static final String MANAGER_FILE = "通用-文件服务"; + + public static final String MANAGER_PRIVILEGE = "通用-权限"; + + public static final String MANAGER_EMAIL = "通用-邮件发送"; + + public static final String MANAGER_HEART_BEAT = "通用-心跳服务"; + } + + /** + * 自定义分组2 + */ + public static class Group2 { + + + } + + /** + * 自定义分组2 + */ + public static class Group3 { + + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/SystemEnvironmentEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/SystemEnvironmentEnum.java new file mode 100644 index 00000000..07ba8b54 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/constant/SystemEnvironmentEnum.java @@ -0,0 +1,60 @@ +package com.gangquan360.smartadmin.constant; + +import com.gangquan360.smartadmin.common.domain.BaseEnum; +/** + * 系统环境枚举类 + * + * @author listen + * @date 2019年4月11日 17:34:59 + */ +public enum SystemEnvironmentEnum implements BaseEnum { + + /** + * dev + */ + DEV("dev", "开发环境"), + + /** + * sit + */ + SIT("sit", "测试环境"), + + /** + * pre + */ + PRE("pre", "预发布环境"), + + /** + * prod + */ + PROD("prod", "生产环境"); + + private String value; + + private String desc; + + SystemEnvironmentEnum(String value, String desc) { + this.value = value; + this.desc = desc; + } + /** + * 获取定义枚举value值 + * + * @return Integer + */ + @Override + public String getValue() { + return value; + } + + /** + * 获取枚举类的说明 + * + * @return String + */ + @Override + public String getDesc() { + return desc; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/handler/SmartGlobalExceptionHandler.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/handler/SmartGlobalExceptionHandler.java new file mode 100644 index 00000000..29f779a4 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/handler/SmartGlobalExceptionHandler.java @@ -0,0 +1,73 @@ +package com.gangquan360.smartadmin.handler; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.common.exception.SmartBusinessException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.TypeMismatchException; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.validation.FieldError; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * [ 全局异常拦截 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Slf4j +@ControllerAdvice +public class SmartGlobalExceptionHandler { + + /** + * 添加全局异常处理流程 + * + * @param e + * @return + * @throws Exception + */ + @ResponseBody + @ExceptionHandler(Exception.class) + public ResponseDTO exceptionHandler(Exception e) { + // http 请求方式错误 + if (e instanceof HttpRequestMethodNotSupportedException) { + return ResponseDTO.wrap(ResponseCodeConst.REQUEST_METHOD_ERROR); + } + + // 参数类型错误 + if (e instanceof TypeMismatchException) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM); + } + + // json 格式错误 + if (e instanceof HttpMessageNotReadableException) { + return ResponseDTO.wrap(ResponseCodeConst.JSON_FORMAT_ERROR); + } + + // 参数校验未通过 + if (e instanceof MethodArgumentNotValidException) { + List fieldErrors = ((MethodArgumentNotValidException) e).getBindingResult().getFieldErrors(); + List msgList = fieldErrors.stream().map(FieldError :: getDefaultMessage).collect(Collectors.toList()); + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, String.join(",", msgList)); + } + + if (e instanceof SmartBusinessException) { + return ResponseDTO.wrap(ResponseCodeConst.SYSTEM_ERROR); + } + + log.error("error:", e); + + return ResponseDTO.wrap(ResponseCodeConst.SYSTEM_ERROR); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/handler/SmartOperateLogAspect.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/handler/SmartOperateLogAspect.java new file mode 100644 index 00000000..dc2dccdc --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/handler/SmartOperateLogAspect.java @@ -0,0 +1,167 @@ +package com.gangquan360.smartadmin.handler; + +import com.alibaba.fastjson.JSON; +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import com.gangquan360.smartadmin.module.log.LogService; +import com.gangquan360.smartadmin.module.log.useroperatelog.domain.UserOperateLogEntity; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.util.SmartRequestTokenUtil; +import com.gangquan360.smartadmin.util.SmartStringUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Method; +/** + * [ 操作日志记录处理,对所有OperateLog注解的Controller进行操作日志监控 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Slf4j +@Aspect +@Component +public class SmartOperateLogAspect { + + @Autowired + private LogService logService; + + @Pointcut("execution(* com.gangquan360.smartadmin.module..*Controller.*(..)))") + public void logPointCut() { + } + + @AfterReturning(pointcut = "logPointCut()") + public void doAfterReturning(JoinPoint joinPoint) { + handleLog(joinPoint, null); + } + + @AfterThrowing(value = "logPointCut()", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Exception e) { + handleLog(joinPoint, e); + } + + protected void handleLog(final JoinPoint joinPoint, final Exception e) { + try { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + OperateLog operateLog = this.getAnnotationLog(joinPoint); + if (operateLog == null) { + return; + } + RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser(); + if (requestToken == null) { + return; + } + // 设置方法名称 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + String operateMethod = className + "." + methodName; + Object[] args = joinPoint.getArgs(); + StringBuilder sb = new StringBuilder(); + for (Object obj : args) { + sb.append(obj.getClass().getSimpleName()); + sb.append("["); + sb.append(JSON.toJSONString(obj)); + sb.append("]"); + } + String params = sb.toString(); + String failReason = null; + Integer result = JudgeEnum.YES.getValue(); + if (e != null) { + result = JudgeEnum.NO.getValue(); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw, true); + e.printStackTrace(pw); + failReason = sw.toString(); + pw.flush(); + pw.close(); + sw.flush(); + sw.close(); + } + UserOperateLogEntity operateLogEntity = + UserOperateLogEntity.builder().userId(requestToken.getRequestUserId()).userName(requestToken.getEmployeeBO().getActualName()).url(request.getRequestURI()).method(operateMethod).param(params).failReason(failReason).result(result).build(); + ApiOperation apiOperation = this.getApiOperation(joinPoint); + if (apiOperation != null) { + operateLogEntity.setContent(apiOperation.value()); + } + Api api = this.getApi(joinPoint); + if (api != null) { + String[] tags = api.tags(); + operateLogEntity.setModule(SmartStringUtil.join(tags, ",")); + } + logService.addLog(operateLogEntity); + } catch (Exception exp) { + log.error("保存操作日志异常:{}", exp.getMessage()); + exp.printStackTrace(); + } + } + + private OperateLog getAnnotationLog(JoinPoint joinPoint) throws Exception { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + OperateLog classAnnotation = AnnotationUtils.findAnnotation(method.getDeclaringClass(), OperateLog.class); + + if (method != null) { + return classAnnotation; + } + return null; + } + + /** + * swagger API + * + * @param joinPoint + * @return + * @throws Exception + */ + private Api getApi(JoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + Api classAnnotation = AnnotationUtils.findAnnotation(method.getDeclaringClass(), Api.class); + + if (method != null) { + return classAnnotation; + } + return null; + } + + /** + * swagger ApiOperation + * + * @param joinPoint + * @return + * @throws Exception + */ + private ApiOperation getApiOperation(JoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + + if (method != null) { + return method.getAnnotation(ApiOperation.class); + } + return null; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/interceptor/SmartAuthenticationInterceptor.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/interceptor/SmartAuthenticationInterceptor.java new file mode 100644 index 00000000..83879e54 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/interceptor/SmartAuthenticationInterceptor.java @@ -0,0 +1,158 @@ +package com.gangquan360.smartadmin.interceptor; + +import com.alibaba.fastjson.JSONObject; +import com.gangquan360.smartadmin.common.anno.NoNeedLogin; +import com.gangquan360.smartadmin.common.anno.NoValidPrivilege; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.CommonConst; +import com.gangquan360.smartadmin.module.login.LoginResponseCodeConst; +import com.gangquan360.smartadmin.module.login.LoginTokenService; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.module.privilege.service.PrivilegeEmployeeService; +import com.gangquan360.smartadmin.util.SmartRequestTokenUtil; +import com.gangquan360.smartadmin.util.SmartStringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.List; + +/** + * [ 登录拦截器 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Component +public class SmartAuthenticationInterceptor extends HandlerInterceptorAdapter { + + private static final String TOKEN_NAME = "x-access-token"; + + @Value("${access-control-allow-origin}") + private String accessControlAllowOrigin; + + @Autowired + private LoginTokenService loginTokenService; + + @Autowired + private PrivilegeEmployeeService privilegeEmployeeService; + + /** + * 拦截服务器端响应处理ajax请求返回结果 + * + * @param request + * @param response + * @param handler + * @return + * @throws Exception + */ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + //跨域设置 + this.crossDomainConfig(response); + boolean isHandlerMethod = handler instanceof HandlerMethod; + if (! isHandlerMethod) { + return true; + } + + //不需要登录的注解 + Boolean isNoNeedLogin = ((HandlerMethod) handler).getMethodAnnotation(NoNeedLogin.class) != null; + if (isNoNeedLogin) { + return true; + } + + //放行的Uri前缀 + String uri = request.getRequestURI(); + String contextPath = request.getContextPath(); + String target = uri.replaceFirst(contextPath, ""); + if (CommonConst.CommonCollection.contain(CommonConst.CommonCollection.IGNORE_URL, target)) { + return true; + } + + //需要做token校验, 消息头的token优先于请求query参数的token + String xHeaderToken = request.getHeader(TOKEN_NAME); + String xRequestToken = request.getParameter(TOKEN_NAME); + String xAccessToken = null != xHeaderToken ? xHeaderToken : xRequestToken; + if (null == xAccessToken) { + this.outputResult(response, LoginResponseCodeConst.LOGIN_ERROR); + return false; + } + + //根据token获取登录用户 + RequestTokenBO requestToken = loginTokenService.getEmployeeTokenInfo(xAccessToken); + if (null == requestToken) { + this.outputResult(response, LoginResponseCodeConst.LOGIN_ERROR); + return false; + } + + //判断接口权限 + String methodName = ((HandlerMethod) handler).getMethod().getName(); + String className = ((HandlerMethod) handler).getBeanType().getName(); + List list = SmartStringUtil.splitConvertToList(className, "\\."); + String controllerName = list.get(list.size() - 1); + Method m = ((HandlerMethod) handler).getMethod(); + Class cls = ((HandlerMethod) handler).getBeanType(); + boolean isClzAnnotation = cls.isAnnotationPresent(NoValidPrivilege.class); + boolean isMethodAnnotation = m.isAnnotationPresent(NoValidPrivilege.class); + NoValidPrivilege noValidPrivilege = null; + if (isClzAnnotation) { + noValidPrivilege = cls.getAnnotation(NoValidPrivilege.class); + } else if (isMethodAnnotation) { + noValidPrivilege = m.getAnnotation(NoValidPrivilege.class); + } + //不需验证权限 + if (noValidPrivilege != null) { + SmartRequestTokenUtil.setUser(request, requestToken); + return true; + } + //需要验证权限 + Boolean privilegeValidPass = privilegeEmployeeService.checkEmployeeHavePrivilege(requestToken, controllerName, methodName); + if (! privilegeValidPass) { + this.outputResult(response, LoginResponseCodeConst.NOT_HAVE_PRIVILEGES); + return false; + } + SmartRequestTokenUtil.setUser(request, requestToken); + return true; + } + + /** + * 配置跨域 + * + * @param response + */ + private void crossDomainConfig(HttpServletResponse response) { + response.setHeader("Access-Control-Allow-Origin", accessControlAllowOrigin); + response.setHeader("Access-Control-Allow-Credentials", "true"); + response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH"); + response.setHeader("Access-Control-Expose-Headers", "*"); + response.setHeader("Access-Control-Allow-Headers", "Authentication,Origin, X-Requested-With, Content-Type, " + "Accept, x-access-token"); + response.setHeader("Cache-Control", "no-cache"); + response.setHeader("Pragma", "no-cache"); + response.setHeader("Expires ", "-1"); + } + + /** + * 错误输出 + * + * @param response + * @param responseCodeConst + * @throws IOException + */ + private void outputResult(HttpServletResponse response, LoginResponseCodeConst responseCodeConst) throws IOException { + ResponseDTO wrap = ResponseDTO.wrap(responseCodeConst); + String msg = JSONObject.toJSONString(wrap); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write(msg); + response.flushBuffer(); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/listener/SmartAdminStartupRunner.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/listener/SmartAdminStartupRunner.java new file mode 100644 index 00000000..f19aa9b7 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/listener/SmartAdminStartupRunner.java @@ -0,0 +1,22 @@ +package com.gangquan360.smartadmin.listener; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +/** + * 应用启动以后检测code码 + * + * @author zhuo + * @version 1.0 + * @since JDK1.8 + */ + +@Component +public class SmartAdminStartupRunner implements CommandLineRunner { + + @Override + public void run(String... args) { + ResponseCodeConst.init(); + } +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/constant/SqlOperateTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/constant/SqlOperateTypeEnum.java new file mode 100644 index 00000000..49186aff --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/constant/SqlOperateTypeEnum.java @@ -0,0 +1,36 @@ +package com.gangquan360.smartadmin.module.codegenerator.constant; + + +/** + * [ gt,lt 目前只支持Date] + * + * @author yandanyang + * @version 1.0 + * @since JDK1.8 + */ +public enum SqlOperateTypeEnum{ + + + LIKE(1, "like"), + EQUALS(2, "equals"), + IN(3, "in"), + TIME_EQUALS(5, "time_equals"), + TIME_BETWEEN(6, "time_between"); + + private Integer type; + + private String name; + + SqlOperateTypeEnum(Integer type, String name) { + this.type = type; + this.name = name; + } + + public Integer getType() { + return type; + } + + public String getName() { + return name; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/dao/TableDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/dao/TableDao.java new file mode 100644 index 00000000..e772b0f3 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/dao/TableDao.java @@ -0,0 +1,40 @@ +package com.gangquan360.smartadmin.module.codegenerator.dao; + +import com.gangquan360.smartadmin.module.codegenerator.domain.ColumnVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/10 0010 下午 18:59 + * @since JDK1.8 + */ +@Mapper +@Component +public interface TableDao { + + + /** + * 查询表描述 + * @param tableName + * @return + */ + String selectTableDesc(@Param("tableName") String tableName); + + /** + * 查询表列信息 + * @param tableName + * @return + */ + List selectTableColumn(@Param("tableName") String tableName); + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/CodeGeneratorDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/CodeGeneratorDTO.java new file mode 100644 index 00000000..adff6c5f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/CodeGeneratorDTO.java @@ -0,0 +1,51 @@ +package com.gangquan360.smartadmin.module.codegenerator.domain; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/11 0011 上午 10:12 + * @since JDK1.8 + */ +@Data +@Builder +public class CodeGeneratorDTO { + + /** + * 需要生成代码的表名 + */ + private String tableName; + + /** + * 表前缀 + */ + private String tablePrefix; + + /** + * 基础包路径 + */ + private String basePackage; + + /** + * 公司 + */ + private String company; + + /** + * 作者 + */ + private String author; + + /** + * 需要构建查询方法的列 + */ + private List queryColumnList; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/CodeGeneratorQueryColumnDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/CodeGeneratorQueryColumnDTO.java new file mode 100644 index 00000000..d945c652 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/CodeGeneratorQueryColumnDTO.java @@ -0,0 +1,30 @@ +package com.gangquan360.smartadmin.module.codegenerator.domain; + +import com.gangquan360.smartadmin.module.codegenerator.constant.SqlOperateTypeEnum; +import lombok.Builder; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/11 0011 上午 10:13 + * @since JDK1.8 + */ +@Data +@Builder +public class CodeGeneratorQueryColumnDTO { + + /** + * 生成查询方法的查询列名 + */ + private String columnName; + + /** + * 此列的查询动作 + */ + private SqlOperateTypeEnum sqlOperate; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/ColumnVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/ColumnVO.java new file mode 100644 index 00000000..3d23b9d8 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/ColumnVO.java @@ -0,0 +1,30 @@ +package com.gangquan360.smartadmin.module.codegenerator.domain; + +import lombok.Builder; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/10 0010 下午 17:55 + * @since JDK1.8 + */ +@Data +@Builder +public class ColumnVO { + + private String columnName; + + private String columnType; + + private String columnDesc; + + private String fieldType; + + private String fieldName; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/QueryFieldVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/QueryFieldVO.java new file mode 100644 index 00000000..fc5c1036 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/domain/QueryFieldVO.java @@ -0,0 +1,30 @@ +package com.gangquan360.smartadmin.module.codegenerator.domain; + +import lombok.Builder; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/10 0010 下午 17:56 + * @since JDK1.8 + */ +@Data +@Builder +public class QueryFieldVO { + + private String fieldName; + + private String columnName; + + private String columnDesc; + + private String fieldType; + + private String sqlOperate; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/service/CodeGeneratorComponent.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/service/CodeGeneratorComponent.java new file mode 100644 index 00000000..724fb4be --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/service/CodeGeneratorComponent.java @@ -0,0 +1,74 @@ +package com.gangquan360.smartadmin.module.codegenerator.service; + +import com.google.common.collect.Lists; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/11 0011 上午 8:33 + * @since JDK1.8 + */ +@Component +public class CodeGeneratorComponent { + + private static Map dataMap = new HashMap<>(16); + + static { + dataMap(); + } + + public static void dataMap(){ + dataMap.put("int","Integer"); + dataMap.put("tinyint","Integer"); + dataMap.put("smallint","Integer"); + dataMap.put("integer","Integer"); + dataMap.put("bigint","Long"); + dataMap.put("float","Float"); + dataMap.put("double","Double"); + dataMap.put("decimal","BigDecimal"); + + dataMap.put("char","String"); + dataMap.put("varchar","String"); + dataMap.put("tinytext","String"); + dataMap.put("text","String"); + dataMap.put("longtext","String"); + + dataMap.put("date","Date"); + dataMap.put("datetime","Date"); + dataMap.put("timestamp","Date"); + + } + + + public Map codeTemplates(String moduleClass, String basePackage, String modulePackage){ + String javaPackagePath = "src"+File.separator+"main" + File.separator + "java" + File.separator; + javaPackagePath = javaPackagePath + basePackage.replace(".", File.separator) + File.separator+"module"+File.separator + modulePackage + File.separator; + String xmlPackagePath = "src"+File.separator+"main" + File.separator + "resources" + File.separator +"mapper"+File.separator+ modulePackage + File.separator; + Map templateMap = new HashMap<>(7); + templateMap.put("templates/codegenerator/Controller.java.vm",javaPackagePath+"controller"+File.separator+moduleClass+"Controller.java"); + templateMap.put("templates/codegenerator/Dao.java.vm",javaPackagePath+"dao"+File.separator+moduleClass+"Dao.java"); + templateMap.put("templates/codegenerator/Dao.xml.vm",xmlPackagePath+moduleClass+"Mapper.xml"); + templateMap.put("templates/codegenerator/DTO.java.vm",javaPackagePath+"domain"+File.separator+"dto"+File.separator+moduleClass+"DTO.java"); + templateMap.put("templates/codegenerator/Entity.java.vm",javaPackagePath+"domain"+File.separator+"entity"+File.separator+moduleClass+"Entity.java"); + templateMap.put("templates/codegenerator/QueryDTO.java.vm",javaPackagePath+"domain"+File.separator+"dto"+File.separator+moduleClass+"QueryDTO.java"); + templateMap.put("templates/codegenerator/Service.java.vm",javaPackagePath+"service"+File.separator+moduleClass+"Service.java"); + return templateMap; + } + + public String getJavaType(String mysqlType ){ + String javaType = dataMap.get(mysqlType); + return javaType; + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/service/CodeGeneratorService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/service/CodeGeneratorService.java new file mode 100644 index 00000000..b1158d19 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/codegenerator/service/CodeGeneratorService.java @@ -0,0 +1,313 @@ +package com.gangquan360.smartadmin.module.codegenerator.service; + +import com.gangquan360.smartadmin.module.codegenerator.dao.TableDao; +import com.gangquan360.smartadmin.module.codegenerator.domain.CodeGeneratorDTO; +import com.gangquan360.smartadmin.module.codegenerator.domain.CodeGeneratorQueryColumnDTO; +import com.gangquan360.smartadmin.module.codegenerator.domain.ColumnVO; +import com.gangquan360.smartadmin.module.codegenerator.domain.QueryFieldVO; +import com.gangquan360.smartadmin.util.SmartDateUtil; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.WordUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.ResourceUtils; + +import java.io.File; +import java.io.FileWriter; +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/11 0011 上午 9:36 + * @since JDK1.8 + */ +@Slf4j +@Service +public class CodeGeneratorService { + + @Autowired + private TableDao tableDao; + + @Autowired + private CodeGeneratorComponent codeGeneratorComponent; + + /** + * 大家注意了开始生成代码了 + * + * @param codeGenerator + * @throws Exception + */ + public void codeGenerator(CodeGeneratorDTO codeGenerator) throws Exception { + this.basicValid(codeGenerator); + String date = SmartDateUtil.formatYMDHMS(new Date()); + String tableDesc = this.getTableDesc(codeGenerator.getTableName()); + String author = codeGenerator.getAuthor(); + String basePackage = codeGenerator.getBasePackage(); + if (StringUtils.isEmpty(basePackage)) { + basePackage = "com.gangquan360.smartadmin"; + } + String moduleClass = this.tableName2Class(codeGenerator.getTableName(), codeGenerator.getTablePrefix()); + String moduleVar = this.tableName2Var(codeGenerator.getTableName(), codeGenerator.getTablePrefix()); + String modulePackage = this.tableName2Package(codeGenerator.getTableName(), codeGenerator.getTablePrefix()); + + List columnList = this.columnList(codeGenerator.getTableName()); + List queryFieldList = this.buildQueryField(codeGenerator, columnList); + Map codeTemplates = codeGeneratorComponent.codeTemplates(moduleClass, basePackage, modulePackage); + List queryImports = this.buildQueryImport(queryFieldList); + List dtoImports = this.buildDTOImport(columnList); + List entityImports = this.buildEntityImport(columnList); + Properties p = new Properties(); + p.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + p.put("directive.foreach.counter.name", "velocityCount"); + p.put("directive.foreach.counter.initial.value", "1"); + Velocity.init(p); + Map map = new HashMap<>(); + map.put("company", codeGenerator.getCompany()); + map.put("tableName", codeGenerator.getTableName()); + map.put("basePackage", basePackage); + map.put("modulePackage", modulePackage); + map.put("moduleClass", moduleClass); + map.put("tableDesc", tableDesc); + map.put("author", author); + map.put("date", date); + map.put("moduleVar", moduleVar); + map.put("columnList", columnList); + map.put("queryFieldList", queryFieldList); + map.put("queryImports", queryImports); + map.put("dtoImports", dtoImports); + map.put("entityImports", entityImports); + VelocityContext context = new VelocityContext(map); + this.codeGenerator(context, codeTemplates); + } + + private List buildQueryImport(List queryFieldList) { + List queryImports = Lists.newArrayList(); + if (CollectionUtils.isNotEmpty(queryFieldList)) { + queryFieldList.forEach(e -> { + importPackage(queryImports, e.getFieldType()); + if ("in".equals(e.getSqlOperate())) { + queryImports.add("import java.util.List;"); + } + }); + } + return queryImports; + } + + private List buildDTOImport(List columnList) { + List dtoImports = Lists.newArrayList(); + if (CollectionUtils.isNotEmpty(columnList)) { + columnList.forEach(e -> { + importPackage(dtoImports, e.getFieldType()); + }); + } + return dtoImports; + } + + private List buildEntityImport(List columnList) { + List entityImports = Lists.newArrayList(); + if (CollectionUtils.isNotEmpty(columnList)) { + columnList.forEach(e -> { + if (! e.getFieldName().equals("createTime") && ! e.getFieldName().equals("updateTime") && ! e.getFieldName().equals("id")) { + importPackage(entityImports, e.getFieldType()); + } + }); + } + return entityImports; + } + + private void importPackage(List imports, String fieldType) { + if ("Date".equals(fieldType) && ! imports.contains("import java.util.Date;")) { + imports.add("import java.util.Date;"); + } + if ("BigDecimal".equals(fieldType) && ! imports.contains("import java.math.BigDecimal;")) { + imports.add("import java.math.BigDecimal;"); + } + } + + /** + * 生成代码 + * + * @param context + * @param codeTemplates + */ + private void codeGenerator(VelocityContext context, Map codeTemplates) throws Exception { + String projectPath = ResourceUtils.getURL("classpath:").getPath(); + String targetDir = "target"; + int targetIndex = StringUtils.indexOf(projectPath, targetDir); + projectPath = projectPath.substring(0, targetIndex + targetDir.length() + 1); + projectPath = projectPath.replace("target/", "").replaceFirst("/", ""); + for (Entry entry : codeTemplates.entrySet()) { + String template = entry.getKey(); + String filePath = projectPath + entry.getValue(); + String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1); + String fileDir = filePath.replace(fileName, ""); + File directory = new File(fileDir); + if (! directory.exists()) { + directory.mkdirs(); + } + FileWriter writer; + try { + writer = new FileWriter(filePath); + Template tpl = Velocity.getTemplate(template, "UTF-8"); + tpl.merge(context, writer); + writer.flush(); + writer.close(); + } catch (Exception e) { + log.error("", e); + } + } + } + + public static void main(String[] args) { + try { + int i = 1 / 0; + } catch (Exception e) { + log.error("", e); + } + } + + private void basicValid(CodeGeneratorDTO codeGenerator) throws Exception { + if (StringUtils.isEmpty(codeGenerator.getTableName())) { + throw new Exception("你没建表吗?"); + } + if (StringUtils.isEmpty(codeGenerator.getTablePrefix())) { + throw new Exception("你的表没前缀吗?"); + } + if (StringUtils.isEmpty(codeGenerator.getAuthor())) { + throw new Exception("输入下你的大名"); + } + } + + /** + * 构建查询集合 + * + * @param codeGenerator + * @param columnList + * @return + * @throws Exception + */ + private List buildQueryField(CodeGeneratorDTO codeGenerator, List columnList) throws Exception { + List queryFieldList = Lists.newArrayList(); + Map storageMap = columnList.stream().collect(Collectors.toMap(ColumnVO:: getColumnName, e -> e)); + List queryColumnList = codeGenerator.getQueryColumnList(); + if (CollectionUtils.isEmpty(queryColumnList)) { + return queryFieldList; + } + for (CodeGeneratorQueryColumnDTO queryColumn : queryColumnList) { + ColumnVO columnDTO = storageMap.get(queryColumn.getColumnName()); + if (columnDTO == null) { + String errorMsg = "sql列[" + queryColumn.getColumnName() + "]在表[" + codeGenerator.getTableName() + "]中不存在。"; + log.error(errorMsg); + throw new Exception(errorMsg); + } + QueryFieldVO queryField = + QueryFieldVO.builder().fieldName(columnDTO.getFieldName()).fieldType(columnDTO.getFieldType()).columnName(columnDTO.getColumnName()).columnDesc(columnDTO.getColumnDesc()).sqlOperate(queryColumn.getSqlOperate().getName()).build(); + queryFieldList.add(queryField); + } + return queryFieldList; + } + + /** + * 列数据 组合 + * + * @param tableName + * @return + * @throws Exception + */ + private List columnList(String tableName) throws Exception { + List list = tableDao.selectTableColumn(tableName); + for (ColumnVO column : list) { + String javaType = codeGeneratorComponent.getJavaType(column.getColumnType()); + if (StringUtils.isEmpty(javaType)) { + String errorMsg = "sql数据类型[" + column.getColumnType() + "]缺少对应的java类型。"; + log.error(errorMsg); + throw new Exception(errorMsg); + } + if ("Integer".equals(javaType) && column.getColumnName().contains("id")) { + column.setFieldType("Long"); + } else { + column.setFieldType(javaType); + } + column.setFieldName(this.columnName2Field(column.getColumnName())); + } + return list; + } + + /** + * 获取列注释为类描述 + * + * @param tableName + * @return + */ + private String getTableDesc(String tableName) { + return tableDao.selectTableDesc(tableName); + } + + /** + * 列名转字段名 + * + * @param columnName + * @return + */ + private String columnName2Field(String columnName) { + String transName = WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", ""); + return WordUtils.uncapitalize(transName); + } + + /** + * 表名转类名前缀 + * + * @param tableName + * @param tablePrefix + * @return + */ + private String tableName2Class(String tableName, String tablePrefix) { + if (StringUtils.isNotBlank(tablePrefix)) { + tableName = tableName.replaceFirst(tablePrefix, ""); + } + return WordUtils.capitalizeFully(tableName, new char[]{'_'}).replace("_", ""); + } + + /** + * 表名转包名 + * + * @param tableName + * @param tablePrefix + * @return + */ + private String tableName2Package(String tableName, String tablePrefix) { + if (StringUtils.isNotBlank(tablePrefix)) { + tableName = tableName.replaceFirst(tablePrefix, ""); + } + return tableName.replace("_", ""); + } + + /** + * 表名转 java变量前缀 + * + * @param tableName + * @param tablePrefix + * @return + */ + private String tableName2Var(String tableName, String tablePrefix) { + if (StringUtils.isNotBlank(tablePrefix)) { + tableName = tableName.replaceFirst(tablePrefix, ""); + } + String transName = WordUtils.capitalizeFully(tableName, new char[]{'_'}).replace("_", ""); + return WordUtils.uncapitalize(transName); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/DataScopeController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/DataScopeController.java new file mode 100644 index 00000000..91a31754 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/DataScopeController.java @@ -0,0 +1,57 @@ +package com.gangquan360.smartadmin.module.datascope; + +import com.gangquan360.smartadmin.common.anno.NoValidPrivilege; +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.datascope.domain.dto.*; +import com.gangquan360.smartadmin.module.datascope.service.DataScopeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/27 0027 下午 15:12 + * @since JDK1.8 + */ +@Api(tags = {SwaggerTagConst.Admin.MANAGER_DATA_SCOPE}) +@OperateLog +@RestController +public class DataScopeController { + + @Autowired + private DataScopeService dataScopeService; + + @ApiOperation(value = "获取当前系统所配置的所有数据范围") + @GetMapping("/dataScope/list") + @NoValidPrivilege + public ResponseDTO> dataScopeList() { + return dataScopeService.dataScopeList(); + } + + @ApiOperation(value = "获取某角色所设置的数据范围") + @GetMapping("/dataScope/listByRole/{roleId}") + @NoValidPrivilege + public ResponseDTO> dataScopeListByRole(@PathVariable Long roleId) { + return dataScopeService.dataScopeListByRole(roleId); + } + + @ApiOperation(value = "批量设置某角色数据范围") + @PostMapping("/dataScope/batchSet") + @NoValidPrivilege + public ResponseDTO dataScopeBatchSet(@RequestBody @Valid DataScopeBatchSetRoleDTO batchSetRoleDTO) { + return dataScopeService.dataScopeBatchSet(batchSetRoleDTO); + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/DataScopeRoleDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/DataScopeRoleDao.java new file mode 100644 index 00000000..750571dd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/DataScopeRoleDao.java @@ -0,0 +1,52 @@ +package com.gangquan360.smartadmin.module.datascope; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.gangquan360.smartadmin.module.datascope.domain.entity.DataScopeRoleEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/27 0027 下午 14:41 + * @since JDK1.8 + */ +@Mapper +@Component +public interface DataScopeRoleDao extends BaseMapper { + + /** + * 获取某个角色的设置信息 + * @param roleId + * @return + */ + List listByRoleId(@Param("roleId") Long roleId); + + /** + * 获取某批角色的所有数据范围配置信息 + * @param roleIdList + * @return + */ + List listByRoleIdList(@Param("roleIdList") List roleIdList); + + /** + * 删除某个角色的设置信息 + * @param roleId + * @return + */ + void deleteByRoleId(@Param("roleId") Long roleId); + + + /** + * 批量添加设置信息 + * @param list + */ + void batchInsert(@Param("list")List list); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/MyBatisPlugin.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/MyBatisPlugin.java new file mode 100644 index 00000000..64625ce3 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/MyBatisPlugin.java @@ -0,0 +1,152 @@ +package com.gangquan360.smartadmin.module.datascope; + +import com.gangquan360.smartadmin.module.datascope.domain.dto.DataScopeSqlConfigDTO; +import com.gangquan360.smartadmin.module.datascope.service.DataScopeSqlConfigService; +import com.gangquan360.smartadmin.third.SmartApplicationContext; +import com.gangquan360.smartadmin.util.SmartStringUtil; +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.mapping.*; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Properties; + +/** + * [ mybaits sql 拦截 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Intercepts({@Signature(type = org.apache.ibatis.executor.Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})}) +@Component +public class MyBatisPlugin implements Interceptor { + + @Override + public Object intercept(Invocation invocation) throws Throwable { + MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; + Object parameter = invocation.getArgs()[1]; + BoundSql boundSql = mappedStatement.getBoundSql(parameter); + String originalSql = boundSql.getSql().trim(); + String id = mappedStatement.getId(); + List methodStrList = SmartStringUtil.splitConvertToList(id, "\\."); + String path = methodStrList.get(methodStrList.size() - 2) + "." + methodStrList.get(methodStrList.size() - 1); + DataScopeSqlConfigService dataScopeSqlConfigService = this.dataScopeSqlConfigService(); + if (dataScopeSqlConfigService == null) { + return invocation.proceed(); + } + DataScopeSqlConfigDTO sqlConfigDTO = dataScopeSqlConfigService.getSqlConfig(path); + if (sqlConfigDTO != null) { + BoundSql newBoundSql = copyFromBoundSql(mappedStatement, boundSql, this.joinSql(originalSql, sqlConfigDTO)); + ParameterMap map = mappedStatement.getParameterMap(); + MappedStatement newMs = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql), map); + invocation.getArgs()[0] = newMs; + } + + Object obj = invocation.proceed(); + return obj; + } + + private String joinSql(String sql, DataScopeSqlConfigDTO sqlConfigDTO) { + if (null == sqlConfigDTO) { + return sql; + } + String appendSql = this.dataScopeSqlConfigService().getJoinSql(sqlConfigDTO); + if (StringUtils.isEmpty(appendSql)) { + return sql; + } + Integer appendSqlWhereIndex = sqlConfigDTO.getWhereIndex(); + String where = "where"; + String order = "order by"; + String group = "group by"; + int whereIndex = StringUtils.ordinalIndexOf(sql.toLowerCase(), where, appendSqlWhereIndex + 1); + int orderIndex = sql.toLowerCase().indexOf(order); + int groupIndex = sql.toLowerCase().indexOf(group); + if (whereIndex > - 1) { + String subSql = sql.substring(0, whereIndex + where.length() + 1); + subSql = subSql + " " + appendSql + " AND " + sql.substring(whereIndex + where.length() + 1); + return subSql; + } + + if (groupIndex > - 1) { + String subSql = sql.substring(0, groupIndex); + subSql = subSql + " where " + appendSql + " " + sql.substring(groupIndex); + return subSql; + } + if (orderIndex > - 1) { + String subSql = sql.substring(0, orderIndex); + subSql = subSql + " where " + appendSql + " " + sql.substring(orderIndex); + return subSql; + } + sql += " where " + appendSql; + return sql; + } + + public DataScopeSqlConfigService dataScopeSqlConfigService() { + return (DataScopeSqlConfigService) SmartApplicationContext.getBean("dataScopeSqlConfigService"); + } + + public class BoundSqlSqlSource implements SqlSource { + + BoundSql boundSql; + + public BoundSqlSqlSource(BoundSql boundSql) { + this.boundSql = boundSql; + } + @Override + public BoundSql getBoundSql(Object parameterObject) { + return boundSql; + } + } + + /** + * 复制MappedStatement对象 + */ + private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource, ParameterMap parameterMap) { + + MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType()); + builder.resource(ms.getResource()); + builder.fetchSize(ms.getFetchSize()); + builder.statementType(ms.getStatementType()); + builder.keyGenerator(ms.getKeyGenerator()); + builder.timeout(ms.getTimeout()); + builder.parameterMap(parameterMap); + builder.resultMaps(ms.getResultMaps()); + builder.resultSetType(ms.getResultSetType()); + builder.cache(ms.getCache()); + builder.flushCacheRequired(ms.isFlushCacheRequired()); + builder.useCache(ms.isUseCache()); + return builder.build(); + } + + /** + * 复制BoundSql对象 + */ + private BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql, String sql) { + BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject()); + for (ParameterMapping mapping : boundSql.getParameterMappings()) { + String prop = mapping.getProperty(); + if (boundSql.hasAdditionalParameter(prop)) { + newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop)); + } + } + return newBoundSql; + } + + @Override + public Object plugin(Object arg0) { + return Plugin.wrap(arg0, this); + } + + @Override + public void setProperties(Properties arg0) { + + } + +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/constant/DataScopeTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/constant/DataScopeTypeEnum.java new file mode 100644 index 00000000..8fba7ff8 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/constant/DataScopeTypeEnum.java @@ -0,0 +1,47 @@ +package com.gangquan360.smartadmin.module.datascope.constant; + + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/28 0028 下午 15:37 + * @since JDK1.8 + */ +public enum DataScopeTypeEnum { + + DEFAULT(0,0,"默认类型","数据范围样例"); + + private Integer type; + private Integer sort; + private String name; + private String desc; + + DataScopeTypeEnum(Integer type,Integer sort,String name,String desc) { + this.type = type; + this.sort = sort; + this.name = name; + this.desc = desc; + } + + public Integer getType() { + return type; + } + + public Integer getSort() { + return sort; + } + + public String getDesc() { + return desc; + } + + public String getName() { + return name; + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/constant/DataScopeViewTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/constant/DataScopeViewTypeEnum.java new file mode 100644 index 00000000..0ff89c04 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/constant/DataScopeViewTypeEnum.java @@ -0,0 +1,55 @@ +package com.gangquan360.smartadmin.module.datascope.constant; + + +import java.util.Arrays; +import java.util.Optional; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/28 0028 下午 15:37 + * @since JDK1.8 + */ +public enum DataScopeViewTypeEnum { + + ME(0,0,"本人"), + + DEPARTMENT(1,5,"本部门"), + + DEPARTMENT_AND_SUB(2,10,"本部门及下属子部门"), + + ALL(3,15,"全部"); + + private Integer type; + private Integer level; + private String name; + + DataScopeViewTypeEnum(Integer type,Integer level, String name) { + this.type = type; + this.level = level; + this.name = name; + } + + public Integer getType() { + return type; + } + + public Integer getLevel() { + return level; + } + + public String getName() { + return name; + } + + public static DataScopeViewTypeEnum valueOf(Integer type) { + DataScopeViewTypeEnum[] values = DataScopeViewTypeEnum.values(); + Optional first = Arrays.stream(values).filter(e -> e.getType().equals(type)).findFirst(); + return !first.isPresent() ? null : first.get(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/constant/DataScopeWhereInTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/constant/DataScopeWhereInTypeEnum.java new file mode 100644 index 00000000..8008c428 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/constant/DataScopeWhereInTypeEnum.java @@ -0,0 +1,37 @@ +package com.gangquan360.smartadmin.module.datascope.constant; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/8 0008 下午 16:00 + * @since JDK1.8 + */ +public enum DataScopeWhereInTypeEnum { + + EMPLOYEE(0,"以员工IN"), + + DEPARTMENT(1,"以部门IN"); + + private Integer type; + private String desc; + + DataScopeWhereInTypeEnum(Integer type, String desc) { + this.type = type; + this.desc = desc; + } + + public Integer getType() { + return type; + } + + + public String getDesc() { + return desc; + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeAndViewTypeVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeAndViewTypeVO.java new file mode 100644 index 00000000..1dd55a68 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeAndViewTypeVO.java @@ -0,0 +1,36 @@ +package com.gangquan360.smartadmin.module.datascope.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/27 0027 下午 16:37 + * @since JDK1.8 + */ +@Data +public class DataScopeAndViewTypeVO { + + @ApiModelProperty("数据范围类型") + private Integer dataScopeType; + + @ApiModelProperty("数据范围名称") + private String dataScopeTypeName; + + @ApiModelProperty("描述") + private String dataScopeTypeDesc; + + @ApiModelProperty("顺序") + private Integer dataScopeTypeSort; + + @ApiModelProperty("可见范围列表") + private List viewTypeList; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeBatchSetDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeBatchSetDTO.java new file mode 100644 index 00000000..3d361d91 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeBatchSetDTO.java @@ -0,0 +1,28 @@ +package com.gangquan360.smartadmin.module.datascope.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/27 0027 下午 16:51 + * @since JDK1.8 + */ +@Data +public class DataScopeBatchSetDTO { + + @ApiModelProperty("数据范围类型") + @NotNull(message = "数据范围类型不能为空") + private Integer dataScopeType; + + @ApiModelProperty("可见范围") + @NotNull(message = "可见范围不能为空") + private Integer viewType; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeBatchSetRoleDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeBatchSetRoleDTO.java new file mode 100644 index 00000000..7b64750d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeBatchSetRoleDTO.java @@ -0,0 +1,30 @@ +package com.gangquan360.smartadmin.module.datascope.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/27 0027 下午 16:47 + * @since JDK1.8 + */ +@Data +public class DataScopeBatchSetRoleDTO { + + @ApiModelProperty("角色id") + @NotNull(message = "角色id不能为空") + private Long roleId; + + @ApiModelProperty("设置信息") + @Valid + private List batchSetList; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeDTO.java new file mode 100644 index 00000000..11718988 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeDTO.java @@ -0,0 +1,36 @@ +package com.gangquan360.smartadmin.module.datascope.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/27 0027 下午 16:37 + * @since JDK1.8 + */ +@Data +@Builder +public class DataScopeDTO { + + @ApiModelProperty("数据范围类型") + private Integer dataScopeType; + + @ApiModelProperty("数据范围名称") + private String dataScopeTypeName; + + @ApiModelProperty("描述") + private String dataScopeTypeDesc; + + @ApiModelProperty("顺序") + private Integer dataScopeTypeSort; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeSelectVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeSelectVO.java new file mode 100644 index 00000000..3f0ddf8c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeSelectVO.java @@ -0,0 +1,24 @@ +package com.gangquan360.smartadmin.module.datascope.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/27 0027 下午 16:43 + * @since JDK1.8 + */ +@Data +public class DataScopeSelectVO { + + @ApiModelProperty("数据范围id") + private Integer dataScopeType; + + @ApiModelProperty("可见范围") + private Integer viewType; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeSqlConfigDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeSqlConfigDTO.java new file mode 100644 index 00000000..64f83755 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeSqlConfigDTO.java @@ -0,0 +1,25 @@ +package com.gangquan360.smartadmin.module.datascope.domain.dto; + +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/28 0028 下午 17:21 + * @since JDK1.8 + */ +@Data +public class DataScopeSqlConfigDTO { + + private Integer dataScopeType; + + private String joinSql; + + private Integer whereIndex; + + private Integer dataScopeWhereInType; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeViewTypeVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeViewTypeVO.java new file mode 100644 index 00000000..fd4acffa --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/dto/DataScopeViewTypeVO.java @@ -0,0 +1,28 @@ +package com.gangquan360.smartadmin.module.datascope.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/28 0028 下午 15:41 + * @since JDK1.8 + */ +@Data +@Builder +public class DataScopeViewTypeVO { + + @ApiModelProperty("可见范围") + private Integer viewType; + @ApiModelProperty("可见范围名称") + private String viewTypeName; + + @ApiModelProperty("级别,用于表示范围大小") + private Integer viewTypeLevel; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/entity/DataScopeRoleEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/entity/DataScopeRoleEntity.java new file mode 100644 index 00000000..cb0de325 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/domain/entity/DataScopeRoleEntity.java @@ -0,0 +1,33 @@ +package com.gangquan360.smartadmin.module.datascope.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * [ 数据范围与角色关系 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/27 0027 下午 14:43 + * @since JDK1.8 + */ +@Data +@TableName("t_role_data_scope") +public class DataScopeRoleEntity extends BaseEntity{ + + /** + * 数据范围id + */ + private Integer dataScopeType; + /** + * 数据范围类型 + */ + private Integer viewType; + /** + * 角色id + */ + private Long roleId; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/service/DataScopeService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/service/DataScopeService.java new file mode 100644 index 00000000..b2169b4d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/service/DataScopeService.java @@ -0,0 +1,118 @@ +package com.gangquan360.smartadmin.module.datascope.service; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.datascope.DataScopeRoleDao; +import com.gangquan360.smartadmin.module.datascope.constant.DataScopeTypeEnum; +import com.gangquan360.smartadmin.module.datascope.constant.DataScopeViewTypeEnum; +import com.gangquan360.smartadmin.module.datascope.domain.dto.*; +import com.gangquan360.smartadmin.module.datascope.domain.entity.DataScopeRoleEntity; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.google.common.collect.Lists; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.Comparator; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/27 0027 下午 14:52 + * @since JDK1.8 + */ +@Service +public class DataScopeService { + + @Autowired + private DataScopeRoleDao dataScopeRoleDao; + + /** + * 获取所有可以进行数据范围配置的信息 + * + * @return + */ + public ResponseDTO> dataScopeList() { + List dataScopeList = this.getDataScopeType(); + List dataScopeAndTypeList = SmartBeanUtil.copyList(dataScopeList, DataScopeAndViewTypeVO.class); + List typeList = this.getViewType(); + dataScopeAndTypeList.forEach(e -> { + e.setViewTypeList(typeList); + }); + return ResponseDTO.succData(dataScopeAndTypeList); + } + + /** + * 获取当前系统存在的数据可见范围 + * + * @return + */ + public List getViewType() { + List viewTypeList = Lists.newArrayList(); + DataScopeViewTypeEnum[] enums = DataScopeViewTypeEnum.class.getEnumConstants(); + DataScopeViewTypeVO dataScopeViewTypeDTO; + for (DataScopeViewTypeEnum viewTypeEnum : enums) { + dataScopeViewTypeDTO = DataScopeViewTypeVO.builder().viewType(viewTypeEnum.getType()).viewTypeLevel(viewTypeEnum.getLevel()).viewTypeName(viewTypeEnum.getName()).build(); + viewTypeList.add(dataScopeViewTypeDTO); + } + Comparator comparator = (h1, h2) -> h1.getViewTypeLevel().compareTo(h2.getViewTypeLevel()); + viewTypeList.sort(comparator); + return viewTypeList; + } + + public List getDataScopeType() { + List dataScopeTypeList = Lists.newArrayList(); + DataScopeTypeEnum[] enums = DataScopeTypeEnum.class.getEnumConstants(); + DataScopeDTO dataScopeDTO; + for (DataScopeTypeEnum typeEnum : enums) { + dataScopeDTO = + DataScopeDTO.builder().dataScopeType(typeEnum.getType()).dataScopeTypeDesc(typeEnum.getDesc()).dataScopeTypeName(typeEnum.getName()).dataScopeTypeSort(typeEnum.getSort()).build(); + dataScopeTypeList.add(dataScopeDTO); + } + Comparator comparator = (h1, h2) -> h1.getDataScopeTypeSort().compareTo(h2.getDataScopeTypeSort()); + dataScopeTypeList.sort(comparator); + return dataScopeTypeList; + } + + /** + * 获取某个角色的数据范围设置信息 + * + * @param roleId + * @return + */ + public ResponseDTO> dataScopeListByRole(Long roleId) { + + List dataScopeRoleEntityList = dataScopeRoleDao.listByRoleId(roleId); + if (CollectionUtils.isEmpty(dataScopeRoleEntityList)) { + return ResponseDTO.succData(Lists.newArrayList()); + } + List dataScopeSelects = SmartBeanUtil.copyList(dataScopeRoleEntityList, DataScopeSelectVO.class); + return ResponseDTO.succData(dataScopeSelects); + } + + /** + * 批量设置某个角色的数据范围设置信息 + * + * @param batchSetRoleDTO + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO dataScopeBatchSet(DataScopeBatchSetRoleDTO batchSetRoleDTO) { + List batchSetList = batchSetRoleDTO.getBatchSetList(); + if (CollectionUtils.isEmpty(batchSetList)) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "缺少配置信息"); + } + List dataScopeRoleEntityList = SmartBeanUtil.copyList(batchSetList, DataScopeRoleEntity.class); + dataScopeRoleEntityList.forEach(e -> e.setRoleId(batchSetRoleDTO.getRoleId())); + dataScopeRoleDao.deleteByRoleId(batchSetRoleDTO.getRoleId()); + dataScopeRoleDao.batchInsert(dataScopeRoleEntityList); + return ResponseDTO.succ(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/service/DataScopeSqlConfigService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/service/DataScopeSqlConfigService.java new file mode 100644 index 00000000..82d744dd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/service/DataScopeSqlConfigService.java @@ -0,0 +1,121 @@ +package com.gangquan360.smartadmin.module.datascope.service; + +import com.gangquan360.smartadmin.common.anno.DataScope; +import com.gangquan360.smartadmin.module.datascope.constant.DataScopeWhereInTypeEnum; +import com.gangquan360.smartadmin.module.datascope.domain.dto.DataScopeSqlConfigDTO; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.util.SmartRequestTokenUtil; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.reflections.Reflections; +import org.reflections.scanners.MethodAnnotationsScanner; +import org.reflections.util.ClasspathHelper; +import org.reflections.util.ConfigurationBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/29 0029 上午 10:12 + * @since JDK1.8 + */ +@Service +public class DataScopeSqlConfigService { + + private ConcurrentHashMap dataScopeMethodMap = new ConcurrentHashMap<>(); + + @Autowired + private DataScopeViewService dataScopeViewService; + + @Value("${swagger.packAge}") + private String scanPackage; + + /** + * 注解joinsql 参数 + */ + private static final String EMPLOYEE_PARAM = "#employeeIds"; + + private static final String DEPARTMENT_PARAM = "#departmentIds"; + + @PostConstruct + private void initDataScopeMethodMap() { + this.refreshDataScopeMethodMap(); + } + + /** + * 刷新 所有添加数据范围注解的接口方法配置 + * + * @return + */ + private Map refreshDataScopeMethodMap() { + Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(scanPackage)).setScanners(new MethodAnnotationsScanner())); + Set methods = reflections.getMethodsAnnotatedWith(DataScope.class); + for (Method method : methods) { + DataScope dataScopeAnnotation = method.getAnnotation(DataScope.class); + if (dataScopeAnnotation != null) { + DataScopeSqlConfigDTO configDTO = new DataScopeSqlConfigDTO(); + configDTO.setDataScopeType(dataScopeAnnotation.dataScopeType().getType()); + configDTO.setJoinSql(dataScopeAnnotation.joinSql()); + configDTO.setWhereIndex(dataScopeAnnotation.whereIndex()); + dataScopeMethodMap.put(method.getDeclaringClass().getSimpleName() + "." + method.getName(), configDTO); + } + } + return dataScopeMethodMap; + } + + /** + * 根据调用的方法获取,此方法的配置信息 + * + * @param method + * @return + */ + public DataScopeSqlConfigDTO getSqlConfig(String method) { + DataScopeSqlConfigDTO sqlConfigDTO = this.dataScopeMethodMap.get(method); + return sqlConfigDTO; + } + + /** + * 组装需要拼接的sql + * + * @param sqlConfigDTO + * @return + */ + public String getJoinSql(DataScopeSqlConfigDTO sqlConfigDTO) { + Integer dataScopeType = sqlConfigDTO.getDataScopeType(); + String joinSql = sqlConfigDTO.getJoinSql(); + RequestTokenBO requestToken = SmartRequestTokenUtil.getThreadLocalUser(); + Long employeeId = requestToken.getRequestUserId(); + if (DataScopeWhereInTypeEnum.EMPLOYEE.getType().equals(sqlConfigDTO.getDataScopeWhereInType())) { + List canViewEmployeeIds = dataScopeViewService.getCanViewEmployeeId(dataScopeType, employeeId); + if (CollectionUtils.isEmpty(canViewEmployeeIds)) { + return ""; + } + String employeeIds = StringUtils.join(canViewEmployeeIds, ","); + String sql = joinSql.replaceAll(EMPLOYEE_PARAM, employeeIds); + return sql; + } + if (DataScopeWhereInTypeEnum.DEPARTMENT.getType().equals(sqlConfigDTO.getDataScopeWhereInType())) { + List canViewDepartmentIds = dataScopeViewService.getCanViewDepartmentId(dataScopeType, employeeId); + if (CollectionUtils.isEmpty(canViewDepartmentIds)) { + return ""; + } + String departmentIds = StringUtils.join(canViewDepartmentIds, ","); + String sql = joinSql.replaceAll(DEPARTMENT_PARAM, departmentIds); + return sql; + } + return ""; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/service/DataScopeViewService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/service/DataScopeViewService.java new file mode 100644 index 00000000..e2481284 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/datascope/service/DataScopeViewService.java @@ -0,0 +1,168 @@ +package com.gangquan360.smartadmin.module.datascope.service; + +import com.gangquan360.smartadmin.module.datascope.DataScopeRoleDao; +import com.gangquan360.smartadmin.module.datascope.constant.DataScopeViewTypeEnum; +import com.gangquan360.smartadmin.module.datascope.domain.entity.DataScopeRoleEntity; +import com.gangquan360.smartadmin.module.department.DepartmentTreeService; +import com.gangquan360.smartadmin.module.employee.EmployeeDao; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import com.gangquan360.smartadmin.module.employee.domain.entity.EmployeeEntity; +import com.gangquan360.smartadmin.module.employee.domain.vo.EmployeeVO; +import com.gangquan360.smartadmin.module.privilege.service.PrivilegeEmployeeService; +import com.gangquan360.smartadmin.module.role.roleemployee.RoleEmployeeDao; +import com.gangquan360.smartadmin.module.systemconfig.SystemConfigService; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigEnum; +import com.gangquan360.smartadmin.module.systemconfig.domain.dto.SystemConfigDTO; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/28 0028 下午 15:56 + * @since JDK1.8 + */ +@Service +public class DataScopeViewService { + + @Autowired + private RoleEmployeeDao roleEmployeeDao; + + @Autowired + private DataScopeRoleDao dataScopeRoleDao; + + @Autowired + private DepartmentTreeService departmentTreeService; + + @Autowired + private EmployeeDao employeeDao; + + @Autowired + private PrivilegeEmployeeService privilegeEmployeeService; + + /** + * 获取某人可以查看的所有人员信息 + * + * @param dataScopeType + * @param employeeId + * @return + */ + public List getCanViewEmployeeId(Integer dataScopeType, Long employeeId) { + Integer viewType = this.getEmployeeDataScopeViewType(dataScopeType, employeeId); + if (DataScopeViewTypeEnum.ME.getType().equals(viewType)) { + return this.getMeEmployeeIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT.getType().equals(viewType)) { + return this.getDepartmentEmployeeIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT_AND_SUB.getType().equals(viewType)) { + return this.getDepartmentAndSubEmployeeIdList(employeeId); + } + return Lists.newArrayList(); + } + + public List getCanViewDepartmentId(Integer dataScopeType, Long employeeId) { + Integer viewType = this.getEmployeeDataScopeViewType(dataScopeType, employeeId); + if (DataScopeViewTypeEnum.ME.getType().equals(viewType)) { + return this.getMeDepartmentIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT.getType().equals(viewType)) { + return this.getMeDepartmentIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT_AND_SUB.getType().equals(viewType)) { + return this.getDepartmentAndSubIdList(employeeId); + } + return Lists.newArrayList(); + } + + private List getMeDepartmentIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + return Lists.newArrayList(employeeEntity.getDepartmentId()); + } + + private List getDepartmentAndSubIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + List allDepartmentIds = Lists.newArrayList(); + departmentTreeService.buildIdList(employeeEntity.getDepartmentId(), allDepartmentIds); + return allDepartmentIds; + } + + /** + * 根据员工id 获取各数据范围最大的可见范围 map + * + * @param employeeId + * @return + */ + private Integer getEmployeeDataScopeViewType(Integer dataScopeType, Long employeeId) { + if (employeeId == null) { + return DataScopeViewTypeEnum.ME.getType(); + } + + if (privilegeEmployeeService.isSuperman(employeeId)) { + return DataScopeViewTypeEnum.ALL.getType(); + } + List roleIdList = roleEmployeeDao.selectRoleIdByEmployeeId(employeeId); + //未设置角色 默认本人 + if (CollectionUtils.isEmpty(roleIdList)) { + return DataScopeViewTypeEnum.ME.getType(); + } + //未设置角色数据范围 默认本人 + List dataScopeRoleList = dataScopeRoleDao.listByRoleIdList(roleIdList); + if (CollectionUtils.isEmpty(dataScopeRoleList)) { + return DataScopeViewTypeEnum.ME.getType(); + } + Map> listMap = dataScopeRoleList.stream().collect(Collectors.groupingBy(DataScopeRoleEntity :: getDataScopeType)); + List viewLevelList = listMap.get(dataScopeType); + DataScopeRoleEntity maxLevel = viewLevelList.stream().max(Comparator.comparing(e -> DataScopeViewTypeEnum.valueOf(e.getViewType()).getLevel())).get(); + return maxLevel.getViewType(); + } + + /** + * 获取本人相关 可查看员工id + * + * @param employeeId + * @return + */ + private List getMeEmployeeIdList(Long employeeId) { + return Lists.newArrayList(employeeId); + } + /** + * 获取本部门相关 可查看员工id + * + * @param employeeId + * @return + */ + private List getDepartmentEmployeeIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + List employeeList = employeeDao.getEmployeeIdByDeptId(employeeEntity.getDepartmentId()); + List employeeIdList = employeeList.stream().map(e -> e.getId()).collect(Collectors.toList()); + return employeeIdList; + } + + /** + * 获取本部门及下属子部门相关 可查看员工id + * + * @param employeeId + * @return + */ + private List getDepartmentAndSubEmployeeIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + List allDepartmentIds = Lists.newArrayList(); + departmentTreeService.buildIdList(employeeEntity.getDepartmentId(), allDepartmentIds); + List employeeList = employeeDao.getEmployeeIdByDeptIds(allDepartmentIds); + List employeeIdList = employeeList.stream().map(e -> e.getId()).collect(Collectors.toList()); + return employeeIdList; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentController.java new file mode 100644 index 00000000..ffa65490 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentController.java @@ -0,0 +1,99 @@ +package com.gangquan360.smartadmin.module.department; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.department.domain.dto.DepartmentCreateDTO; +import com.gangquan360.smartadmin.module.department.domain.dto.DepartmentUpdateDTO; +import com.gangquan360.smartadmin.module.department.domain.dto.DepartmentVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 部门管理路由器 + * + * @author listen + * @date 2017/12/19 14:29 + */ +@Api(tags = {SwaggerTagConst.Admin.MANAGER_DEPARTMENT}) +@OperateLog +@RestController +public class DepartmentController { + + @Autowired + private DepartmentService departmentService; + + @ApiOperation(value = "查询部门树形列表", notes = "查询部门列表") + @GetMapping("/department/list") + public ResponseDTO> listDepartment() { + return departmentService.listDepartment(); + } + + @ApiOperation(value = "查询部门及员工列表", notes = "查询部门及员工列表") + @GetMapping("/department/listEmployee") + public ResponseDTO> listDepartmentEmployee() { + return departmentService.listAllDepartmentEmployee(null); + } + + @ApiOperation(value = "根据部门名称查询部门及员工列表", notes = "根据部门名称查询部门及员工列表") + @GetMapping("/department/listEmployeeByDepartmentName") + public ResponseDTO> listDepartmentEmployee(String departmentName) { + return departmentService.listAllDepartmentEmployee(departmentName); + } + + @ApiOperation(value = "添加部门", notes = "添加部门") + @PostMapping("/department/add") + public ResponseDTO addDepartment(@Valid @RequestBody DepartmentCreateDTO departmentCreateDTO) { + return departmentService.addDepartment(departmentCreateDTO); + } + + @ApiOperation(value = "更新部门信息", notes = "更新部门信息") + @PostMapping("/department/update") + public ResponseDTO updateDepartment(@Valid @RequestBody DepartmentUpdateDTO departmentUpdateDTO) { + return departmentService.updateDepartment(departmentUpdateDTO); + } + + @ApiOperation(value = "删除部门", notes = "删除部门") + @PostMapping("/department/delete/{departmentId}") + public ResponseDTO delDepartment(@PathVariable("departmentId") Long departmentId) { + return departmentService.delDepartment(departmentId); + } + + @ApiOperation(value = "获取部门信息", notes = "获取部门") + @GetMapping("/department/query/{departmentId}") + public ResponseDTO getDepartment(@PathVariable("departmentId") Long departmentId) { + return departmentService.getDepartmentById(departmentId); + } + + @ApiOperation(value = "查询部门列表", notes = "查询部门列表") + @GetMapping("/department/listAll") + public ResponseDTO> listAll() { + return departmentService.listAll(); + } + + + @ApiOperation(value = "上下移动") + @GetMapping("/department/upOrDown/{departmentId}/{swapId}") + public ResponseDTO upOrDown(@PathVariable("departmentId") Long departmentId,@PathVariable("swapId") Long swapId) { + return departmentService.upOrDown(departmentId,swapId); + } + + @ApiOperation(value = "升级") + @GetMapping("/department/upgrade/{departmentId}") + public ResponseDTO upgrade(@PathVariable("departmentId") Long departmentId) { + return departmentService.upgrade(departmentId); + } + + @ApiOperation(value = "降级") + @GetMapping("/department/downgrade/{departmentId}/{preId}") + public ResponseDTO downgrade(@PathVariable("departmentId") Long departmentId,@PathVariable("preId") Long preId) { + return departmentService.downgrade(departmentId,preId); + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentDao.java new file mode 100644 index 00000000..5c3e3b65 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentDao.java @@ -0,0 +1,48 @@ +package com.gangquan360.smartadmin.module.department; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.gangquan360.smartadmin.module.department.domain.dto.DepartmentVO; +import com.gangquan360.smartadmin.module.department.domain.entity.DepartmentEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * t_department dao接口 + * + * @author listen + * @date 2017/12/19 10:58 + */ +@Component +@Mapper +public interface DepartmentDao extends BaseMapper { + + + /** + * 根据部门id,查询此部门子部门的数量 + * + * @param departmentId + * @return int 子部门的数量 + */ + Integer countSubDepartment(@Param("departmentId") Long departmentId); + + /** + * 获取全部部门列表 + * + * @return List + */ + List listAll(); + + /** + * 功能描述: 根据父部门id查询 + * + * @param + * @return + * @auther yandanyang + * @date 2018/8/25 0025 上午 9:46 + */ + List selectByParentId(@Param("departmentId") Long departmentId); + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentResponseCodeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentResponseCodeConst.java new file mode 100644 index 00000000..b84c2f5e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentResponseCodeConst.java @@ -0,0 +1,39 @@ +package com.gangquan360.smartadmin.module.department; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + +/** + * 部门返回信息常量类 + * 2001 - 2999 + * + * @author listen + * @date 2017/12/19 18:52 + */ +public class DepartmentResponseCodeConst extends ResponseCodeConst { + + /** + * 部门不存在 1001 + */ + public static final DepartmentResponseCodeConst DEPT_NOT_EXISTS = new DepartmentResponseCodeConst(2001, "部门不存在!"); + + /** + * 当前部门有子级部门 不能删除 10003 + */ + public static final DepartmentResponseCodeConst CANNOT_DEL_DEPARTMENT_WITH_CHILD = new + DepartmentResponseCodeConst(2002, "当前部门有子级部门,无法删除!"); + + /** + * 当前部门有员工 不能删除 10004 + */ + public static final DepartmentResponseCodeConst CANNOT_DEL_DEPARTMENT_WITH_EMPLOYEE = new + DepartmentResponseCodeConst(2003, "当前部门有员工,无法删除!"); + + /** + * + */ + public static final DepartmentResponseCodeConst PARENT_ID_ERROR = new DepartmentResponseCodeConst(2004, "上级部门id不能等于当前部门id"); + + public DepartmentResponseCodeConst(int code, String msg) { + super(code, msg); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentService.java new file mode 100644 index 00000000..aea9b092 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentService.java @@ -0,0 +1,282 @@ +package com.gangquan360.smartadmin.module.department; + +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.department.domain.dto.DepartmentCreateDTO; +import com.gangquan360.smartadmin.module.department.domain.dto.DepartmentUpdateDTO; +import com.gangquan360.smartadmin.module.department.domain.dto.DepartmentVO; +import com.gangquan360.smartadmin.module.department.domain.entity.DepartmentEntity; +import com.gangquan360.smartadmin.module.employee.EmployeeDao; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 部门管理业务类 + * + * @author listen + * @date 2017/12/19 14:25 + */ +@Service +public class DepartmentService { + + @Autowired + private DepartmentDao departmentDao; + + @Autowired + private EmployeeDao employeeDao; + + @Autowired + private DepartmentTreeService departmentTreeService; + + /** + * 获取部门树形结构 + * + * @return + */ + public ResponseDTO> listDepartment() { + List departmentVOList = departmentDao.listAll(); + List result = departmentTreeService.buildTree(departmentVOList); + return ResponseDTO.succData(result); + } + + /** + * 获取所有部门和员工信息 + * + * @param departmentName + * @return + */ + public ResponseDTO> listAllDepartmentEmployee(String departmentName) { + + // 获取全部部门列表 + List departmentVOList = departmentDao.listAll(); + if (StringUtils.isNotBlank(departmentName)) { + // 检索条件不为空的时候 过滤部门列表 + departmentVOList = filterDepartment(departmentVOList, departmentName); + } + + Map departmentMap = departmentVOList.stream().collect(Collectors.toMap(DepartmentVO :: getId, Function.identity())); + // 获取全部员工列表 + List employeeList = employeeDao.listAll(); + employeeList.forEach(employeeDTO -> { + + DepartmentVO departmentVO = departmentMap.get(employeeDTO.getDepartmentId()); + if (null == departmentVO) { + return; + } + List employeeDTOList = departmentVO.getEmployees(); + if (null == employeeDTOList) { + employeeDTOList = new ArrayList<>(); + } + employeeDTOList.add(employeeDTO); + departmentVO.setEmployees(employeeDTOList); + }); + List result = departmentTreeService.buildTree(departmentVOList); + return ResponseDTO.succData(result); + } + + /** + * 过滤部门名称,获取过滤后的结果 + * + * @author lidoudou + * @date 2019/4/28 20:17 + */ + private List filterDepartment(List departmentVOList, String departmentName) { + Map departmentMap = new HashMap<>(); + departmentVOList.forEach(item -> { + if (item.getName().indexOf(departmentName) < 0) { + return; + } + // 当前部门包含关键字 + departmentMap.put(item.getId(), item); + Long parentId = item.getParentId(); + if (null != parentId) { + List filterResult = new ArrayList<>(); + getParentDepartment(departmentVOList, parentId, filterResult); + for (DepartmentVO dto : filterResult) { + if (! departmentMap.containsKey(dto.getId())) { + departmentMap.put(dto.getId(), dto); + } + } + } + }); + return departmentMap.values().stream().collect(Collectors.toList()); + } + + private List getParentDepartment(List departmentVOList, Long parentId, List result) { + List deptList = departmentVOList.stream().filter(e -> e.getId().equals(parentId)).collect(Collectors.toList()); + for (DepartmentVO item : deptList) { + result.add(item); + if (item.getParentId() != 0 && item.getParentId() != null) { + result.addAll(getParentDepartment(departmentVOList, item.getParentId(), result)); + } + } + return result; + } + + /** + * 新增添加部门 + * + * @param departmentCreateDTO + * @return AjaxResult + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO addDepartment(DepartmentCreateDTO departmentCreateDTO) { + DepartmentEntity departmentEntity = SmartBeanUtil.copy(departmentCreateDTO, DepartmentEntity.class); + departmentEntity.setSort(0L); + departmentDao.insert(departmentEntity); + departmentEntity.setSort(departmentEntity.getId()); + departmentDao.updateById(departmentEntity); + return ResponseDTO.succ(); + } + + /** + * 更新部门信息 + * + * @param updateDTO + * @return AjaxResult + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateDepartment(DepartmentUpdateDTO updateDTO) { + if (updateDTO.getParentId() == null) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.PARENT_ID_ERROR); + } + DepartmentEntity entity = departmentDao.selectById(updateDTO.getId()); + if (entity == null) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.NOT_EXISTS); + } + DepartmentEntity departmentEntity = SmartBeanUtil.copy(updateDTO, DepartmentEntity.class); + departmentEntity.setSort(entity.getSort()); + departmentDao.updateById(departmentEntity); + return ResponseDTO.succ(); + } + + /** + * 根据id删除部门 + * 1、需要判断当前部门是否有子部门,有子部门则不允许删除 + * 2、需要判断当前部门是否有员工,有员工则不能删除 + * + * @param departmentId + * @return AjaxResult + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO delDepartment(Long departmentId) { + // 是否有子级部门 + int subDepartmentNum = departmentDao.countSubDepartment(departmentId); + if (subDepartmentNum > 0) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.CANNOT_DEL_DEPARTMENT_WITH_CHILD); + } + + // 是否有员工 + int employeeNum = employeeDao.countByDepartmentId(departmentId); + if (employeeNum > 0) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.CANNOT_DEL_DEPARTMENT_WITH_EMPLOYEE); + } + departmentDao.deleteById(departmentId); + return ResponseDTO.succ(); + } + + /** + * 根据id获取部门信息 + * + * @param departmentId + * @return AjaxResult + */ + public ResponseDTO getDepartmentById(Long departmentId) { + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + if (departmentEntity == null) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.DEPT_NOT_EXISTS); + } + DepartmentVO departmentVO = SmartBeanUtil.copy(departmentEntity, DepartmentVO.class); + return ResponseDTO.succData(departmentVO); + } + + /** + * 获取所有部门 + * + * @return + */ + public ResponseDTO> listAll() { + List departmentVOList = departmentDao.listAll(); + return ResponseDTO.succData(departmentVOList); + } + + /** + * 上下移动 + * + * @param departmentId + * @param swapId + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO upOrDown(Long departmentId, Long swapId) { + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + if (departmentEntity == null) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.NOT_EXISTS); + } + DepartmentEntity swapEntity = departmentDao.selectById(swapId); + if (swapEntity == null) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.NOT_EXISTS); + } + Long departmentSort = departmentEntity.getSort(); + departmentEntity.setSort(swapEntity.getSort()); + departmentDao.updateById(departmentEntity); + swapEntity.setSort(departmentSort); + departmentDao.updateById(swapEntity); + return ResponseDTO.succ(); + } + + /** + * 部门升级 + * + * @param departmentId + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO upgrade(Long departmentId) { + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + if (departmentEntity == null) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.NOT_EXISTS); + } + if (departmentEntity.getParentId() == null || departmentEntity.getParentId().equals(0)) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.ERROR_PARAM, "此部门已经是根节点无法移动"); + } + DepartmentEntity parentEntity = departmentDao.selectById(departmentEntity.getParentId()); + + departmentEntity.setParentId(parentEntity.getParentId()); + departmentDao.updateById(departmentEntity); + return ResponseDTO.succ(); + } + + /** + * 部门降级 + * + * @param departmentId + * @param preId + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO downgrade(Long departmentId, Long preId) { + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + if (departmentEntity == null) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.NOT_EXISTS); + } + DepartmentEntity preEntity = departmentDao.selectById(preId); + if (preEntity == null) { + return ResponseDTO.wrap(DepartmentResponseCodeConst.NOT_EXISTS); + } + departmentEntity.setParentId(preEntity.getId()); + departmentDao.updateById(departmentEntity); + return ResponseDTO.succ(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentTreeService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentTreeService.java new file mode 100644 index 00000000..034fcde9 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/DepartmentTreeService.java @@ -0,0 +1,99 @@ +package com.gangquan360.smartadmin.module.department; + +import com.gangquan360.smartadmin.module.department.domain.dto.DepartmentVO; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/29 0029 下午 13:52 + * @since JDK1.8 + */ +@Service +public class DepartmentTreeService { + + @Autowired + private DepartmentDao departmentDao; + + /** + * 构建部门树结构 + * @param departmentVOList + * @return + */ + public List buildTree(List departmentVOList) { + if(CollectionUtils.isEmpty(departmentVOList)){ + return Lists.newArrayList(); + } + List list = departmentVOList.stream().filter(e -> e.getParentId() == null || e.getParentId() == 0).collect(Collectors.toList()); + if(CollectionUtils.isEmpty(list)){ + return Lists.newArrayList(); + } + this.buildTree(list,departmentVOList); + return list; + } + + private void buildTree(List nodeList,List departmentVOList){ + int nodeSize = nodeList.size(); + for(int i =0 ;i< nodeSize;i++){ + int preIndex = i-1; + int nextIndex = i+1; + DepartmentVO node = nodeList.get(i); + if(preIndex>-1){ + node.setPreId(nodeList.get(preIndex).getId()); + } + if(nextIndex departmentVOList) { + List children = getChildren(node, departmentVOList); + if (CollectionUtils.isNotEmpty(children)) { + node.setChildrenDepartment(children); + this.buildTree(children,departmentVOList); + } + } + + private List getChildren(DepartmentVO node, List departmentVOList) { + Long id = node.getId(); + return departmentVOList.stream().filter(e -> id.equals(e.getParentId())).collect(Collectors.toList()); + } + + + + /** + * 通过部门id,获取当前以及下属部门 + */ + public void buildIdList(Long deptId, List result) { + List departmentVOList = departmentDao.listAll(); + result.add(deptId); + if (null == deptId) { + result.addAll(departmentVOList.stream().map(DepartmentVO::getId).collect(Collectors.toList())); + return; + } + List children = getChildrenIdList(deptId, departmentVOList); + if (!children.isEmpty()) { + result.addAll(children.stream().map(DepartmentVO::getId).collect(Collectors.toList())); + for (DepartmentVO child : children) { + buildTree(child, departmentVOList); + } + } + } + + private List getChildrenIdList(Long deptId, List departmentVOList) { + return departmentVOList.stream().filter(e -> deptId.equals(e.getParentId())).collect(Collectors.toList()); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/dto/DepartmentCreateDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/dto/DepartmentCreateDTO.java new file mode 100644 index 00000000..58174a5b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/dto/DepartmentCreateDTO.java @@ -0,0 +1,38 @@ +package com.gangquan360.smartadmin.module.department.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +public class DepartmentCreateDTO { + + + @ApiModelProperty("部门名称") + @Length(min = 1, max = 50, message = "请输入正确的部门名称(1-50个字符)") + @NotNull(message = "请输入正确的部门名称(1-50个字符)") + private String name; + + @ApiModelProperty("部门简称") + private String shortName; + + @ApiModelProperty("部门负责人id") + private Long managerId; + + @ApiModelProperty("上级部门id (可选)") + private Long parentId; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/dto/DepartmentUpdateDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/dto/DepartmentUpdateDTO.java new file mode 100644 index 00000000..2f3278a4 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/dto/DepartmentUpdateDTO.java @@ -0,0 +1,25 @@ +package com.gangquan360.smartadmin.module.department.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Data +public class DepartmentUpdateDTO extends DepartmentCreateDTO { + + @ApiModelProperty("部门id") + @NotNull(message = "部门id不能为空") + private Long id; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/dto/DepartmentVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/dto/DepartmentVO.java new file mode 100644 index 00000000..a76b3b73 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/dto/DepartmentVO.java @@ -0,0 +1,58 @@ +package com.gangquan360.smartadmin.module.department.domain.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +public class DepartmentVO { + + @ApiModelProperty("部门id") + private Long id; + + @ApiModelProperty("部门名称") + private String name; + + @ApiModelProperty("部门简称") + private String shortName; + + @ApiModelProperty("部门负责人姓名") + private String managerName; + + @ApiModelProperty("部门负责人id") + private Long managerId; + + @ApiModelProperty("子部门") + @JsonProperty("children") + private List childrenDepartment; + + @ApiModelProperty("父级部门id") + private Long parentId; + + @ApiModelProperty("同级上一个元素id") + private Long preId; + + @ApiModelProperty("同级下一个元素id") + private Long nextId; + + @ApiModelProperty("排序") + private Long sort; + + @ApiModelProperty("父级部门名称") + private String parentName; + + @ApiModelProperty("部门员工列表") + private List employees; + + @ApiModelProperty("上次更新时间") + private Date updateTime; + + @ApiModelProperty("创建时间") + private Date createTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/entity/DepartmentEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/entity/DepartmentEntity.java new file mode 100644 index 00000000..f24cd594 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/department/domain/entity/DepartmentEntity.java @@ -0,0 +1,48 @@ +package com.gangquan360.smartadmin.module.department.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +import java.io.Serializable; + +/** + * 部门实体类 + * t_department 数据表 + * + * @author listen + * @date 2017/12/19 10:45 + */ +@Data +@TableName(value = "t_department") +public class DepartmentEntity extends BaseEntity implements Serializable { + + private static final long serialVersionUID = -6787726615141147044L; + + /** + * 部门名称 + */ + private String name; + + /** + * 部门简称 + */ + private String shortName; + + /** + * 负责人员工 id + */ + private Long managerId; + + /** + * 部门父级id + */ + private Long parentId; + + /** + * 排序 + */ + private Long sort; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailController.java new file mode 100644 index 00000000..a04aff8d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailController.java @@ -0,0 +1,80 @@ +package com.gangquan360.smartadmin.module.email; + +import com.gangquan360.smartadmin.common.anno.NoValidPrivilege; +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.email.domain.dto.EmailDTO; +import com.gangquan360.smartadmin.module.email.domain.dto.EmailQueryDTO; +import com.gangquan360.smartadmin.module.email.domain.dto.EmailVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-05-13 17:10:16 + * @since JDK1.8 + */ +@RestController +@OperateLog +@Api(tags = {SwaggerTagConst.Admin.MANAGER_EMAIL}) +public class EmailController { + + @Autowired + private EmailService emailService; + + @ApiOperation(value = "分页查询",notes = "@author yandanyang") + @PostMapping("/email/page/query") + @NoValidPrivilege + public ResponseDTO> queryByPage(@RequestBody EmailQueryDTO queryDTO) { + return emailService.queryByPage(queryDTO); + } + + @ApiOperation(value = "添加",notes = "@author yandanyang") + @PostMapping("/email/add") + @NoValidPrivilege + public ResponseDTO add(@RequestBody @Valid EmailDTO addTO){ + return emailService.add(addTO); + } + + @ApiOperation(value="修改",notes = "@author yandanyang") + @PostMapping("/email/update") + @NoValidPrivilege + public ResponseDTO update(@RequestBody @Valid EmailDTO updateDTO){ + return emailService.update(updateDTO); + } + + + @ApiOperation(value="删除",notes = "@author yandanyang") + @GetMapping("/email/delete/{id}") + @NoValidPrivilege + public ResponseDTO delete(@PathVariable("id") Long id){ + return emailService.delete(id); + } + + + @ApiOperation(value="详情",notes = "@author yandanyang") + @GetMapping("/email/detail/{id}") + @NoValidPrivilege + public ResponseDTO detail(@PathVariable("id") Long id){ + return emailService.detail(id); + } + + + @ApiOperation(value="发送",notes = "@author yandanyang") + @GetMapping("/email/send/{id}") + @NoValidPrivilege + public ResponseDTO send(@PathVariable("id") Long id){ + return emailService.send(id); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailDao.java new file mode 100644 index 00000000..e7fd5e76 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailDao.java @@ -0,0 +1,47 @@ +package com.gangquan360.smartadmin.module.email; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.pagination.Pagination; +import com.gangquan360.smartadmin.module.email.domain.dto.EmailQueryDTO; +import com.gangquan360.smartadmin.module.email.domain.entity.EmailEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-05-13 17:10:16 + * @since JDK1.8 + */ +@Mapper +@Component +public interface EmailDao extends BaseMapper { + + /** + * 分页查询 + * @param queryDTO + * @return EmailEntity + */ + List queryByPage(Pagination page, @Param("queryDTO") EmailQueryDTO queryDTO); + + /** + * 根据id删除 + * @param id + * @return + */ + void deleteById(@Param("id") Long id); + + /** + * 批量删除 + * @param idList + * @return + */ + void deleteByIds(@Param("idList") List idList); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailSendStatusEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailSendStatusEnum.java new file mode 100644 index 00000000..ba8e6e85 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailSendStatusEnum.java @@ -0,0 +1,37 @@ +package com.gangquan360.smartadmin.module.email; + + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/28 0028 下午 15:37 + * @since JDK1.8 + */ +public enum EmailSendStatusEnum { + + NOT_SEND(0,"未发送"), + + SEND(1,"已发送"); + + private Integer type; + private String desc; + + EmailSendStatusEnum(Integer type, String desc) { + this.type = type; + this.desc = desc; + } + + public Integer getType() { + return type; + } + + public String getDesc() { + return desc; + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailService.java new file mode 100644 index 00000000..483490c1 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/EmailService.java @@ -0,0 +1,122 @@ +package com.gangquan360.smartadmin.module.email; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.email.domain.dto.EmailConfigDTO; +import com.gangquan360.smartadmin.module.email.domain.dto.EmailDTO; +import com.gangquan360.smartadmin.module.email.domain.dto.EmailQueryDTO; +import com.gangquan360.smartadmin.module.email.domain.dto.EmailVO; +import com.gangquan360.smartadmin.module.email.domain.entity.EmailEntity; +import com.gangquan360.smartadmin.module.systemconfig.SystemConfigService; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigEnum; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import com.gangquan360.smartadmin.util.SmartSendMailUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-05-13 17:10:16 + * @since JDK1.8 + */ +@Service +public class EmailService { + + @Autowired + private EmailDao emailDao; + + @Autowired + private SystemConfigService systemConfigService; + + /** + * @author yandanyang + * @description 分页查询 + * @date 2019-05-13 17:10:16 + */ + public ResponseDTO> queryByPage(EmailQueryDTO queryDTO) { + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List entities = emailDao.queryByPage(page, queryDTO); + List dtoList = SmartBeanUtil.copyList(entities, EmailVO.class); + page.setRecords(dtoList); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * @author yandanyang + * @description 添加 + * @date 2019-05-13 17:10:16 + */ + public ResponseDTO add(EmailDTO addDTO) { + EmailEntity entity = SmartBeanUtil.copy(addDTO, EmailEntity.class); + emailDao.insert(entity); + return ResponseDTO.succData(entity.getId()); + } + + /** + * @author yandanyang + * @description 编辑 + * @date 2019-05-13 17:10:16 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO update(EmailDTO updateDTO) { + EmailEntity entity = SmartBeanUtil.copy(updateDTO, EmailEntity.class); + emailDao.updateById(entity); + return ResponseDTO.succData(entity.getId()); + } + + /** + * @author yandanyang + * @description 删除 + * @date 2019-05-13 17:10:16 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO delete(Long id) { + emailDao.deleteById(id); + return ResponseDTO.succ(); + } + + /** + * @author yandanyang + * @description 根据ID查询 + * @date 2019-05-13 17:10:16 + */ + public ResponseDTO detail(Long id) { + EmailEntity entity = emailDao.selectById(id); + EmailVO dto = SmartBeanUtil.copy(entity, EmailVO.class); + return ResponseDTO.succData(dto); + } + + /** + * 发送某个已创建的邮件 + * + * @param id + * @return + */ + public ResponseDTO send(Long id) { + EmailEntity entity = emailDao.selectById(id); + EmailConfigDTO emailConfig = systemConfigService.selectByKey2Obj(SystemConfigEnum.Key.EMAIL_CONFIG.name(), EmailConfigDTO.class); + String toEmails = entity.getToEmails(); + if (StringUtils.isEmpty(toEmails)) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "收件人信息为空"); + } + String[] emails = toEmails.split(";"); + SmartSendMailUtil.sendMail(emailConfig.getUsername(), emailConfig.getPassword(), emailConfig.getUsername(), emails, "", emailConfig.getSmtpHost(), entity.getTitle(), entity.getContent()); + entity.setSendStatus(EmailSendStatusEnum.SEND.getType()); + emailDao.updateById(entity); + return ResponseDTO.succ(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailConfigDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailConfigDTO.java new file mode 100644 index 00000000..84974033 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailConfigDTO.java @@ -0,0 +1,30 @@ +package com.gangquan360.smartadmin.module.email.domain.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/13 0013 下午 16:52 + * @since JDK1.8 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EmailConfigDTO { + + private String smtpHost; + + private String username; + + private String password; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailDTO.java new file mode 100644 index 00000000..86b23076 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailDTO.java @@ -0,0 +1,44 @@ +package com.gangquan360.smartadmin.module.email.domain.dto; +import lombok.Data; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 12:27 + * @since JDK1.8 + */ +@Data +public class EmailDTO { + + @ApiModelProperty("主键") + private Long id; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("收件人") + private String toEmails; + + @ApiModelProperty("发送状态 0未发送 1已发送") + private Integer sendStatus; + + @ApiModelProperty("邮件内容") + private String content; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + + @ApiModelProperty("更新时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date updateTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailQueryDTO.java new file mode 100644 index 00000000..4aea64bc --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailQueryDTO.java @@ -0,0 +1,35 @@ +package com.gangquan360.smartadmin.module.email.domain.dto; + +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-05-13 17:10:16 + * @since JDK1.8 + */ +@Data +public class EmailQueryDTO extends PageParamDTO { + + + @ApiModelProperty("开始日期") + private String startDate; + + @ApiModelProperty("结束日期") + private String endDate; + + + @ApiModelProperty("标题") + private String title; + + + @ApiModelProperty("发送状态 0未发送 1已发送") + private Integer sendStatus; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailVO.java new file mode 100644 index 00000000..29545058 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/dto/EmailVO.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.module.email.domain.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 12:27 + * @since JDK1.8 + */ +@Data +public class EmailVO { + + @ApiModelProperty("主键") + private Long id; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("收件人") + private String toEmails; + + @ApiModelProperty("发送状态 0未发送 1已发送") + private Integer sendStatus; + + @ApiModelProperty("邮件内容") + private String content; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + + @ApiModelProperty("更新时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date updateTime; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/entity/EmailEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/entity/EmailEntity.java new file mode 100644 index 00000000..92951595 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/email/domain/entity/EmailEntity.java @@ -0,0 +1,40 @@ +package com.gangquan360.smartadmin.module.email.domain.entity; +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-05-13 17:10:16 + * @since JDK1.8 + */ +@Data +@TableName("t_email") +public class EmailEntity extends BaseEntity { + + /** + * 标题 + */ + private String title; + + /** + * 收件人 + */ + private String toEmails; + + /** + * 发送状态 0未发送 1已发送 + */ + private Integer sendStatus; + + /** + * 邮件内容 + */ + private String content; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/EmployeeController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/EmployeeController.java new file mode 100644 index 00000000..18af9fd8 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/EmployeeController.java @@ -0,0 +1,95 @@ +package com.gangquan360.smartadmin.module.employee; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.employee.domain.dto.*; +import com.gangquan360.smartadmin.module.employee.domain.vo.EmployeeVO; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.util.SmartRequestTokenUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 员工管理 + * + * @author lidoudou + * @date 2017年12月19日上午11:34:52 + */ +@RestController +@Api(tags = {SwaggerTagConst.Admin.MANAGER_USER}) +@OperateLog +public class EmployeeController { + + @Autowired + private EmployeeService employeeService; + + @PostMapping("/employee/query") + @ApiOperation(value = "员工管理查询", notes = "员工管理查询 @author lidoudou") + public ResponseDTO> query(@RequestBody EmployeeQueryDTO query) { + return employeeService.selectEmployeeList(query); + } + + @ApiOperation(value = "添加员工", notes = "@author yandanyang") + @PostMapping("/employee/add") + public ResponseDTO addEmployee(@Valid @RequestBody EmployeeAddDTO emp) { + RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser(); + return employeeService.addEmployee(emp, requestToken); + } + + @ApiOperation(value = "禁用单个员工", notes = "@author yandanyang") + @GetMapping("/employee/updateStatus/{employeeId}/{status}") + public ResponseDTO updateStatus(@PathVariable("employeeId") Long employeeId, @PathVariable("status") Integer status) { + return employeeService.updateStatus(employeeId, status); + } + + @ApiOperation(value = "批量禁用", notes = "@author yandanyang") + @PostMapping("/employee/batchUpdateStatus") + public ResponseDTO batchUpdateStatus(@Valid @RequestBody EmployeeBatchUpdateStatusDTO batchUpdateStatusDTO) { + return employeeService.batchUpdateStatus(batchUpdateStatusDTO); + } + + @ApiOperation(value = "更新员工信息", notes = "@author yandanyang") + @PostMapping("/employee/update") + public ResponseDTO updateEmployee(@Valid @RequestBody EmployeeUpdateDTO employeeUpdateDto) { + return employeeService.updateEmployee(employeeUpdateDto); + } + + @ApiOperation(value = "删除员工信息", notes = "@author yandanyang") + @PostMapping("/employee/delete/{employeeId}") + public ResponseDTO deleteEmployeeById(@PathVariable("employeeId") Long employeeId) { + return employeeService.deleteEmployeeById(employeeId); + } + + @ApiOperation(value = "单个员工角色授权", notes = "@author yandanyang") + @PostMapping("/employee/updateRoles") + public ResponseDTO updateRoles(@Valid @RequestBody EmployeeUpdateRolesDTO updateRolesDTO) { + return employeeService.updateRoles(updateRolesDTO); + } + + @ApiOperation(value = "修改密码", notes = "@author yandanyang") + @PostMapping("/employee/updatePwd") + public ResponseDTO updatePwd(@Valid @RequestBody EmployeeUpdatePwdDTO updatePwdDTO) { + RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser(); + return employeeService.updatePwd(updatePwdDTO, requestToken); + } + + @ApiOperation(value = "通过部门id获取当前部门的人员&没有部门的人", notes = "@author yandanyang") + @GetMapping("/employee/listEmployeeByDeptId/{deptId}") + public ResponseDTO> listEmployeeByDeptId(@PathVariable Long deptId) { + return employeeService.getEmployeeByDeptId(deptId); + } + + @ApiOperation(value = "员工重置密码", notes = "@author lizongliang") + @GetMapping("/employee/resetPasswd/{employeeId}") + public ResponseDTO resetPasswd(@PathVariable("employeeId") Integer employeeId) { + return employeeService.resetPasswd(employeeId); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/EmployeeDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/EmployeeDao.java new file mode 100644 index 00000000..7191f1b1 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/EmployeeDao.java @@ -0,0 +1,129 @@ +package com.gangquan360.smartadmin.module.employee; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeQueryDTO; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeQueryExportDTO; +import com.gangquan360.smartadmin.module.employee.domain.entity.EmployeeEntity; +import com.gangquan360.smartadmin.module.employee.domain.vo.EmployeeVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +/** + * 员工dao接口 + * + * @author lidoudou + * @date 2017年12月19日下午1:36:30 + */ +@Mapper +@Component +public interface EmployeeDao extends BaseMapper { + /** + * 查询员工列表 + * + * @param page + * @param queryDTO + * @return + */ + List selectEmployeeList(Page page, @Param("queryDTO") EmployeeQueryDTO queryDTO); + + /** + * 不带分页查询员工列表 + * @param queryDTO + * @return + */ + List selectEmployeeList(@Param("queryDTO") EmployeeQueryExportDTO queryDTO); + + /** + * 批量更新禁用状态 + * + * @param employeeIds + * @param isDisabled + */ + void batchUpdateStatus(@Param("employeeIds") List employeeIds, @Param("isDisabled") Integer isDisabled); + + /** + * 登录 + * + * @param loginName + * @param loginPwd + * @return + */ + EmployeeDTO login(@Param("loginName") String loginName, @Param("loginPwd") String loginPwd); + + /** + * 通过登录名查询 + * + * @param loginName + * @param isDisabled + * @return + */ + EmployeeDTO getByLoginName(@Param("loginName") String loginName, @Param("isDisabled") Integer isDisabled); + + /** + * 通过手机号查询 + * + * @param phone + * @param isDisabled + * @return + */ + EmployeeDTO getByPhone(@Param("phone") String phone, @Param("isDisabled") Integer isDisabled); + + /** + * 获取所有员工 + * + * @return + */ + List listAll(); + + /** + * 获取某个部门员工数 + * + * @param departmentId + * @return + */ + Integer countByDepartmentId(@Param("departmentId") Long departmentId); + + /** + * 获取一批员工 + * + * @param employeeIds + * @return + */ + List getEmployeeByIds(@Param("ids") Collection employeeIds); + + + EmployeeDTO getEmployeeById(@Param("id") Long employeeId); + /** + * 获取某个部门的员工 + * + * @param departmentId + * @return + */ + List getEmployeeIdByDeptId(@Param("departmentId") Long departmentId); + + /** + * 获取某批部门的员工 + * + * @param departmentIds + * @return + */ + List getEmployeeIdByDeptIds(@Param("departmentIds") List departmentIds); + + + /** + * 员工重置密码 + * + * @param employeeId + * @param password + * @return + */ + Integer updatePassword(@Param("employeeId") Integer employeeId, @Param("password") String password); + + +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/EmployeeService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/EmployeeService.java new file mode 100644 index 00000000..34c0cf30 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/EmployeeService.java @@ -0,0 +1,342 @@ +package com.gangquan360.smartadmin.module.employee; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.CommonConst; +import com.gangquan360.smartadmin.module.department.DepartmentDao; +import com.gangquan360.smartadmin.module.department.domain.entity.DepartmentEntity; +import com.gangquan360.smartadmin.module.employee.constant.EmployeeResponseCodeConst; +import com.gangquan360.smartadmin.module.employee.constant.EmployeeStatusEnum; +import com.gangquan360.smartadmin.module.employee.domain.bo.EmployeeBO; +import com.gangquan360.smartadmin.module.employee.domain.dto.*; +import com.gangquan360.smartadmin.module.employee.domain.entity.EmployeeEntity; +import com.gangquan360.smartadmin.module.employee.domain.vo.EmployeeVO; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.module.position.PositionService; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionRelationAddDTO; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionRelationResultDTO; +import com.gangquan360.smartadmin.module.privilege.service.PrivilegeEmployeeService; +import com.gangquan360.smartadmin.module.role.roleemployee.RoleEmployeeDao; +import com.gangquan360.smartadmin.module.role.roleemployee.domain.RoleEmployeeEntity; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartDigestUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import com.gangquan360.smartadmin.util.SmartVerificationUtil; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * 员工管理 + * + * @author lidoudou + * @date 2017年12月21日上午11:54:52 + */ +@Service +public class EmployeeService { + + private static final String RESET_PASSWORD = "123456"; + + @Autowired + private EmployeeDao employeeDao; + + @Autowired + private DepartmentDao departmentDao; + + @Autowired + private RoleEmployeeDao roleEmployeeDao; + + @Autowired + private PositionService positionService; + + @Autowired + private PrivilegeEmployeeService privilegeEmployeeService; + + /** + * 员工基本信息的缓存 + */ + private static final ConcurrentHashMap employeeCache = new ConcurrentHashMap<>(); + + + public EmployeeBO getById(Long id) { + EmployeeBO employeeBO = employeeCache.get(id); + if (employeeBO == null) { + EmployeeEntity employeeEntity = employeeDao.selectById(id); + if (employeeEntity != null) { + Boolean superman = privilegeEmployeeService.isSuperman(id); + employeeBO = new EmployeeBO(employeeEntity, superman); + employeeCache.put(employeeEntity.getId(), employeeBO); + } + } + return employeeBO; + } + + /** + * 查询员工列表 + * + * @param queryDTO + * @return + */ + public ResponseDTO> selectEmployeeList(EmployeeQueryDTO queryDTO) { + Page pageParam = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + queryDTO.setIsDelete(JudgeEnum.NO.getValue()); + List empList = employeeDao.selectEmployeeList(pageParam, queryDTO); + empList.stream().forEach(e -> { + List positionRelationList = positionService.queryPositionByEmployeeId(e.getId()); + if (CollectionUtils.isNotEmpty(positionRelationList)) { + e.setPositionRelationList(positionRelationList); + e.setPositionName(positionRelationList.stream().map(PositionRelationResultDTO::getPositionName).collect(Collectors.joining(","))); + } + }); + return ResponseDTO.succData(SmartPaginationUtil.convert2PageInfoDTO(pageParam, empList, EmployeeVO.class)); + } + + /** + * 新增员工 + * + * @param employeeAddDto + * @param requestToken + * @return + */ + public ResponseDTO addEmployee(EmployeeAddDTO employeeAddDto, RequestTokenBO requestToken) { + EmployeeEntity entity = SmartBeanUtil.copy(employeeAddDto, EmployeeEntity.class); + if (StringUtils.isNotEmpty(employeeAddDto.getIdCard())) { + boolean checkResult = Pattern.matches(SmartVerificationUtil.ID_CARD, employeeAddDto.getIdCard()); + if (!checkResult) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.ID_CARD_ERROR); + } + } + if (StringUtils.isNotEmpty(employeeAddDto.getBirthday())) { + boolean checkResult = Pattern.matches(SmartVerificationUtil.DATE, employeeAddDto.getBirthday()); + if (!checkResult) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.BIRTHDAY_ERROR); + } + } + //同名员工 + EmployeeDTO sameNameEmployee = employeeDao.getByLoginName(entity.getLoginName(), EmployeeStatusEnum.NORMAL.getValue()); + if (null != sameNameEmployee) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.LOGIN_NAME_EXISTS); + } + //同电话员工 + EmployeeDTO samePhoneEmployee = employeeDao.getByPhone(entity.getLoginName(), EmployeeStatusEnum.NORMAL.getValue()); + if (null != samePhoneEmployee) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.PHONE_EXISTS); + } + Long departmentId = entity.getDepartmentId(); + DepartmentEntity department = departmentDao.selectById(departmentId); + if (department == null) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.DEPT_NOT_EXIST); + } + + //如果没有密码 默认设置为123456 + String pwd = entity.getLoginPwd(); + if (StringUtils.isBlank(pwd)) { + entity.setLoginPwd(SmartDigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, RESET_PASSWORD)); + } else { + entity.setLoginPwd(SmartDigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, entity.getLoginPwd())); + } + + entity.setCreateUser(requestToken.getRequestUserId()); + if (StringUtils.isEmpty(entity.getBirthday())) { + entity.setBirthday(null); + } + employeeDao.insert(entity); + + PositionRelationAddDTO positionRelAddDTO = new PositionRelationAddDTO(employeeAddDto.getPositionIdList(), entity.getId()); + //存储所选岗位信息 + positionService.addPositionRelation(positionRelAddDTO); + + return ResponseDTO.succ(); + } + + /** + * 更新禁用状态 + * + * @param employeeId + * @param status + * @return + */ + public ResponseDTO updateStatus(Long employeeId, Integer status) { + if (null == employeeId) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.EMP_NOT_EXISTS); + } + EmployeeBO entity = getById(employeeId); + if (null == entity) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.EMP_NOT_EXISTS); + } + List empIds = Lists.newArrayList(); + empIds.add(employeeId); + employeeDao.batchUpdateStatus(empIds, status); + employeeCache.remove(employeeId); + return ResponseDTO.succ(); + } + + /** + * 批量更新员工状态 + * + * @param batchUpdateStatusDTO + * @return + */ + public ResponseDTO batchUpdateStatus(EmployeeBatchUpdateStatusDTO batchUpdateStatusDTO) { + employeeDao.batchUpdateStatus(batchUpdateStatusDTO.getEmployeeIds(), batchUpdateStatusDTO.getStatus()); + if (batchUpdateStatusDTO.getEmployeeIds() != null) { + batchUpdateStatusDTO.getEmployeeIds().forEach(e -> employeeCache.remove(e)); + } + return ResponseDTO.succ(); + } + + /** + * 更新员工 + * + * @param updateDTO + * @return + */ + public ResponseDTO updateEmployee(EmployeeUpdateDTO updateDTO) { + Long employeeId = updateDTO.getId(); + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (null == employeeEntity) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.EMP_NOT_EXISTS); + } + if (StringUtils.isNotBlank(updateDTO.getIdCard())) { + boolean checkResult = Pattern.matches(SmartVerificationUtil.ID_CARD, updateDTO.getIdCard()); + if (!checkResult) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.ID_CARD_ERROR); + } + } + if (StringUtils.isNotEmpty(updateDTO.getBirthday())) { + boolean checkResult = Pattern.matches(SmartVerificationUtil.DATE, updateDTO.getBirthday()); + if (!checkResult) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.BIRTHDAY_ERROR); + } + } + Long departmentId = updateDTO.getDepartmentId(); + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + if (departmentEntity == null) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.DEPT_NOT_EXIST); + } + EmployeeDTO sameNameEmployee = employeeDao.getByLoginName(updateDTO.getLoginName(), EmployeeStatusEnum.NORMAL.getValue()); + if (null != sameNameEmployee && !sameNameEmployee.getId().equals(employeeId)) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.LOGIN_NAME_EXISTS); + } + EmployeeDTO samePhoneEmployee = employeeDao.getByPhone(updateDTO.getLoginName(), EmployeeStatusEnum.NORMAL.getValue()); + if (null != samePhoneEmployee && !samePhoneEmployee.getId().equals(employeeId)) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.PHONE_EXISTS); + } + String newPwd = updateDTO.getLoginPwd(); + if (!StringUtils.isBlank(newPwd)) { + updateDTO.setLoginPwd(SmartDigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, updateDTO.getLoginPwd())); + } else { + updateDTO.setLoginPwd(employeeEntity.getLoginPwd()); + } + EmployeeEntity entity = SmartBeanUtil.copy(updateDTO, EmployeeEntity.class); + entity.setUpdateTime(new Date()); + if (StringUtils.isEmpty(entity.getBirthday())) { + entity.setBirthday(null); + } + if (CollectionUtils.isNotEmpty(updateDTO.getPositionIdList())) { + //删除旧的关联关系 添加新的关联关系 + positionService.removePositionRelation(entity.getId()); + PositionRelationAddDTO positionRelAddDTO = new PositionRelationAddDTO(updateDTO.getPositionIdList(), entity.getId()); + positionService.addPositionRelation(positionRelAddDTO); + } + entity.setIsDisabled(employeeEntity.getIsDisabled()); + entity.setIsLeave(employeeEntity.getIsLeave()); + entity.setCreateUser(employeeEntity.getCreateUser()); + entity.setCreateTime(employeeEntity.getCreateTime()); + entity.setUpdateTime(new Date()); + employeeDao.updateById(entity); + employeeCache.remove(employeeId); + return ResponseDTO.succ(); + } + + /** + * 删除员工 + * + * @param employeeId 员工ID + * @return + */ + public ResponseDTO deleteEmployeeById(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (null == employeeEntity) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.EMP_NOT_EXISTS); + } + //假删 + employeeEntity.setIsDelete(JudgeEnum.YES.getValue().longValue()); + employeeDao.updateById(employeeEntity); + employeeCache.remove(employeeId); + return ResponseDTO.succ(); + } + + /** + * 更新用户角色 + * + * @param updateRolesDTO + * @return + */ + public ResponseDTO updateRoles(EmployeeUpdateRolesDTO updateRolesDTO) { + roleEmployeeDao.deleteByEmployeeId(updateRolesDTO.getEmployeeId()); + if (CollectionUtils.isNotEmpty(updateRolesDTO.getRoleIds())) { + List roleEmployeeEntities = Lists.newArrayList(); + RoleEmployeeEntity roleEmployeeEntity; + for (Long roleId : updateRolesDTO.getRoleIds()) { + roleEmployeeEntity = new RoleEmployeeEntity(); + roleEmployeeEntity.setEmployeeId(updateRolesDTO.getEmployeeId()); + roleEmployeeEntity.setRoleId(roleId); + roleEmployeeEntities.add(roleEmployeeEntity); + } + roleEmployeeDao.batchInsert(roleEmployeeEntities); + } + return ResponseDTO.succ(); + } + + /** + * 更新密码 + * + * @param updatePwdDTO + * @param requestToken + * @return + */ + public ResponseDTO updatePwd(EmployeeUpdatePwdDTO updatePwdDTO, RequestTokenBO requestToken) { + Long employeeId = requestToken.getRequestUserId(); + EmployeeEntity employee = employeeDao.selectById(employeeId); + if (employee == null) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.EMP_NOT_EXISTS); + } + if (!employee.getLoginPwd().equals(SmartDigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, updatePwdDTO.getOldPwd()))) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.PASSWORD_ERROR); + } + employee.setLoginPwd(SmartDigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, updatePwdDTO.getPwd())); + employeeDao.updateById(employee); + employeeCache.remove(employeeId); + return ResponseDTO.succ(); + } + + public ResponseDTO> getEmployeeByDeptId(Long departmentId) { + List list = employeeDao.getEmployeeIdByDeptId(departmentId); + return ResponseDTO.succData(list); + } + + /** + * 重置密码 + * + * @param employeeId + * @return + */ + public ResponseDTO resetPasswd(Integer employeeId) { + String md5Password = SmartDigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, RESET_PASSWORD); + employeeDao.updatePassword(employeeId, md5Password); + employeeCache.remove(employeeId); + return ResponseDTO.succ(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/constant/EmployeeResponseCodeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/constant/EmployeeResponseCodeConst.java new file mode 100644 index 00000000..5e3d45f7 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/constant/EmployeeResponseCodeConst.java @@ -0,0 +1,61 @@ +package com.gangquan360.smartadmin.module.employee.constant; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + +/** + * 员工常量类 + * 3001-3999 + * + * @author lidoudou + * @date 2017年12月19日下午19:04:52 + */ +public class EmployeeResponseCodeConst extends ResponseCodeConst { + + /** + * 员工不存在 + */ + public static final EmployeeResponseCodeConst EMP_NOT_EXISTS = new EmployeeResponseCodeConst(3001, "员工不存在!"); + + /** + * 更新员工信息失败 + */ + public static final EmployeeResponseCodeConst UPDATE_FAILED = new EmployeeResponseCodeConst(3002, "员工更新失败!"); + + /** + * 部门信息不存在 + */ + public static final EmployeeResponseCodeConst DEPT_NOT_EXIST = new EmployeeResponseCodeConst(3003, "部门信息不存在!"); + + /** + * 用户名或密码错误 + */ + public static final EmployeeResponseCodeConst LOGIN_FAILED = new EmployeeResponseCodeConst(3004, "用户名或密码错误!"); + + /** + * 您的账号已被禁用,不得登录系统 + */ + public static final EmployeeResponseCodeConst IS_DISABLED = new EmployeeResponseCodeConst(3005, "您的账号已被禁用,不得登录系统!"); + + /** + * 登录名已存在 + */ + public static final EmployeeResponseCodeConst LOGIN_NAME_EXISTS = new EmployeeResponseCodeConst(3006, "登录名已存在!"); + /** + * 密码输入有误,请重新输入 10115 + */ + public static final EmployeeResponseCodeConst PASSWORD_ERROR = new EmployeeResponseCodeConst(3007, "密码输入有误,请重新输入"); + /** + * 手机号已存在 + */ + public static final EmployeeResponseCodeConst PHONE_EXISTS = new EmployeeResponseCodeConst(3008, "手机号已经存在"); + + public static final EmployeeResponseCodeConst ID_CARD_ERROR = new EmployeeResponseCodeConst(3009, "请输入正确的身份证号"); + + public static final EmployeeResponseCodeConst BIRTHDAY_ERROR = new EmployeeResponseCodeConst(3010, "生日格式不正确"); + + public static final EmployeeResponseCodeConst VERIFICATION_CODE_INVALID = new EmployeeResponseCodeConst(3011, "验证码无效"); + + public EmployeeResponseCodeConst(int code, String msg) { + super(code, msg); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/constant/EmployeeStatusEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/constant/EmployeeStatusEnum.java new file mode 100644 index 00000000..45eafe0e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/constant/EmployeeStatusEnum.java @@ -0,0 +1,56 @@ +package com.gangquan360.smartadmin.module.employee.constant; + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 16:22 + * @since JDK1.8 + */ + +public enum EmployeeStatusEnum implements BaseEnum { + + /** + * 用户正常状态 1 + */ + NORMAL(0, "正常"), + + /** + * 用户已被禁用 0 + */ + DISABLED(1, "禁用"); + + private Integer value; + + private String desc; + + EmployeeStatusEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + /** + * 获取枚举类的值 + * + * @return Integer + */ + @Override + public Integer getValue() { + return value; + } + + /** + * 获取枚举类的说明 + * + * @return String + */ + @Override + public String getDesc() { + return this.desc; + } +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/bo/EmployeeBO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/bo/EmployeeBO.java new file mode 100644 index 00000000..ed22d060 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/bo/EmployeeBO.java @@ -0,0 +1,73 @@ +package com.gangquan360.smartadmin.module.employee.domain.bo; + +import com.gangquan360.smartadmin.module.employee.domain.entity.EmployeeEntity; +import lombok.Getter; + + +@Getter +public class EmployeeBO { + + /** + * 主键id + */ + private Long id; + + /** + * 登录账号 + */ + private String loginName; + + /** + * 员工名称 + */ + private String actualName; + + /** + * 别名 + */ + private String nickName; + + /** + * 手机号码 + */ + private String phone; + + /** + * 部门id + */ + private Long departmentId; + + /** + * 是否离职 + */ + private Integer isLeave; + + /** + * 是否被禁用 + */ + private Integer isDisabled; + + /** + * 删除状态 0否 1是 + */ + private Long isDelete; + + /** + * 是否为超级管理员 + */ + private Boolean isSuperman; + + public EmployeeBO(EmployeeEntity employeeEntity, boolean isSuperman) { + this.id = employeeEntity.getId(); + this.loginName = employeeEntity.getLoginName(); + this.actualName = employeeEntity.getActualName(); + this.nickName = employeeEntity.getNickName(); + this.phone = employeeEntity.getPhone(); + this.departmentId = employeeEntity.getDepartmentId(); + this.isLeave = employeeEntity.getIsLeave(); + this.isDisabled = employeeEntity.getIsDisabled(); + this.isDelete = employeeEntity.getIsDelete(); + this.isSuperman = isSuperman; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeAddDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeAddDTO.java new file mode 100644 index 00000000..4a9c95c7 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeAddDTO.java @@ -0,0 +1,63 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import com.gangquan360.smartadmin.util.SmartVerificationUtil; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import java.util.List; + +/** + * 添加员工 + * + * @author lidoudou + * @date 2017年12月19日下午2:06:31 + */ +@Data +public class EmployeeAddDTO { + + @ApiModelProperty("姓名") + @NotNull(message = "姓名不能为空") + private String actualName; + + @ApiModelProperty("登录名") + @NotNull(message = "姓名不能为空") + private String loginName; + + @ApiModelProperty("别名") + private String nickName; + + @ApiModelProperty("部门id") + @NotNull(message = "部门id不能为空") + private Long departmentId; + + @ApiModelProperty("是否启用") + @NotNull(message = "是否被禁用不能为空") + private Integer isDisabled; + + @ApiModelProperty("手机号") + @NotNull(message = "手机号不能为空") + @Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确") + private String phone; + + @ApiModelProperty("身份证(可选)") + private String idCard; + + @ApiModelProperty("生日(可选)") + private String birthday; + + @ApiModelProperty("密码") + // @NotNull(message = "密码不能为空") + // @Length(min = 6, message = "密码最少为6位字符") + private String loginPwd; + + @ApiModelProperty("邮箱") + private String email; + + @ApiModelProperty("岗位ID 集合") + @NotEmpty(message = "岗位ID 集合不能为空") + private List positionIdList; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeBaseDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeBaseDTO.java new file mode 100644 index 00000000..35099d88 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeBaseDTO.java @@ -0,0 +1,52 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import com.gangquan360.smartadmin.util.SmartVerificationUtil; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * 添加员工 + * + * @author lidoudou + * @date 2017年12月19日下午2:06:31 + */ +@Data +public class EmployeeBaseDTO { + + @ApiModelProperty("姓名") + @NotNull(message = "姓名不能为空") + private String actualName; + + @ApiModelProperty("登录名") + @NotNull(message = "姓名不能为空") + private String loginName; + + @ApiModelProperty("别名") + private String nickName; + + @ApiModelProperty("部门id") + @NotNull(message = "部门id不能为空") + private Long departmentId; + + @ApiModelProperty("是否启用") + @NotNull(message = "是否被禁用不能为空") + private Integer isDisabled; + + @ApiModelProperty("手机号") + @NotNull(message = "手机号不能为空") + @Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确") + private String phone; + + @ApiModelProperty("身份证(可选)") + private String idCard; + + @ApiModelProperty("生日(可选)") + private String birthday; + + @ApiModelProperty("邮箱") + private String email; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeBatchUpdateStatusDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeBatchUpdateStatusDTO.java new file mode 100644 index 00000000..1f2a2c29 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeBatchUpdateStatusDTO.java @@ -0,0 +1,26 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 批量更新 + * + * @author lidoudou + * @date 2017年12月21日上午13:17:52 + */ +@Data +public class EmployeeBatchUpdateStatusDTO { + + @ApiModelProperty("员工ids") + @NotNull(message = "员工ids不能为空") + private List employeeIds; + + @ApiModelProperty("状态") + @NotNull(message = "状态不能为空") + private Integer status; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeDTO.java new file mode 100644 index 00000000..f5033ec4 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeDTO.java @@ -0,0 +1,73 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionRelationResultDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 员工列表DTO + * + * @author lidoudou + * @date 2017年12月21日上午09:09:31 + */ +@Data +public class EmployeeDTO { + + @ApiModelProperty("主键id") + private Long id; + + @ApiModelProperty("登录账号") + private String loginName; + + @ApiModelProperty("别名") + private String nickName; + + @ApiModelProperty("员工名称") + private String actualName; + + @ApiModelProperty("手机号码") + private String phone; + + @ApiModelProperty("身份证") + private String idCard; + + @ApiModelProperty("出生日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date birthday; + + @ApiModelProperty("创建者id") + private Long createUser; + + @ApiModelProperty("部门id") + private Long departmentId; + + @ApiModelProperty("是否离职") + private Integer isLeave; + + @ApiModelProperty("是否被禁用") + private Integer isDisabled; + + @ApiModelProperty("是否删除") + private Integer isDelete; + + @ApiModelProperty("部门名称") + private String departmentName; + + @ApiModelProperty("邮箱") + private String email; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + + @ApiModelProperty("岗位关联信息") + private List positionRelationList; + + @ApiModelProperty("岗位名称") + private String positionName; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeLoginFormDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeLoginFormDTO.java new file mode 100644 index 00000000..c4220a64 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeLoginFormDTO.java @@ -0,0 +1,33 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 登录 + * + * @author lidoudou + * @date 2017年12月19日上午11:49:46 + */ +@Data +public class EmployeeLoginFormDTO { + + @NotNull(message = "登录名不能为空") + @ApiModelProperty(example = "sa") + private String loginName; + + @NotNull(message = "密码不能为空") + @ApiModelProperty(example = "123456") + private String loginPwd; + + @NotNull(message = "验证码id不能为空") + @ApiModelProperty(value = "验证码uuid") + private String codeUuid; + + @NotNull(message = "验证码不能为空") + @ApiModelProperty(value = "验证码") + private String code; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeQueryDTO.java new file mode 100644 index 00000000..c023261e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeQueryDTO.java @@ -0,0 +1,39 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 员工列表DTO + * + * @author lidoudou + * @date 2017年12月21日上午09:09:31 + */ +@Data +public class EmployeeQueryDTO extends PageParamDTO { + + private String phone; + + private String actualName; + + private String keyword; + + private Long departmentId; + + private Integer isLeave; + + private Integer isDisabled; + + /** + * 删除状态 0否 1是 + */ + @ApiModelProperty("删除状态 0否 1是 不需要传") + private Integer isDelete; + + @ApiModelProperty("员工id集合") + private List employeeIds; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeQueryExportDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeQueryExportDTO.java new file mode 100644 index 00000000..c94da314 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeQueryExportDTO.java @@ -0,0 +1,42 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author zzr + * 不带分页的查询条件 + */ +@Data +public class EmployeeQueryExportDTO { + + @ApiModelProperty(hidden = true) + private String phone; + + @ApiModelProperty("姓名") + private String actualName; + + @ApiModelProperty(hidden = true) + private String keyword; + + @ApiModelProperty(hidden = true) + private Long departmentId; + + @ApiModelProperty(hidden = true) + private Integer isLeave; + + @ApiModelProperty(hidden = true) + private Integer isDisabled; + + /** + * 删除状态 0否 1是 + */ + @ApiModelProperty(value = "删除状态 0否 1是 不需要传", hidden = true) + private Integer isDelete; + + @ApiModelProperty(value = "员工ID集合", hidden = true) + private List employeeIds; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeUpdateDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeUpdateDTO.java new file mode 100644 index 00000000..d266fd5d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeUpdateDTO.java @@ -0,0 +1,28 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 添加员工 + * + * @author lidoudou + * @date 2017年12月19日下午2:06:31 + */ +@Data +public class EmployeeUpdateDTO extends EmployeeBaseDTO { + + @ApiModelProperty("员工id") + @NotNull(message = "员工id不能为空") + private Long id; + + @ApiModelProperty("密码") + private String loginPwd; + + @ApiModelProperty("岗位ID 集合") + private List positionIdList; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeUpdatePwdDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeUpdatePwdDTO.java new file mode 100644 index 00000000..2056c178 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeUpdatePwdDTO.java @@ -0,0 +1,25 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 修改密码所需参数 + * + * @author cyj + * @date 2018-02-23 下午 4:53 + */ +@Data +public class EmployeeUpdatePwdDTO { + + @ApiModelProperty("新密码") + @NotNull + private String pwd; + + @ApiModelProperty("原密码") + @NotNull + private String oldPwd; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeUpdateRolesDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeUpdateRolesDTO.java new file mode 100644 index 00000000..b81b826f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/dto/EmployeeUpdateRolesDTO.java @@ -0,0 +1,29 @@ +package com.gangquan360.smartadmin.module.employee.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Data +public class EmployeeUpdateRolesDTO { + + @ApiModelProperty("员工id") + @NotNull(message = "员工id不能为空") + private Long employeeId; + + @ApiModelProperty("角色ids") + private List roleIds; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/entity/EmployeeEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/entity/EmployeeEntity.java new file mode 100644 index 00000000..b4b1da84 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/entity/EmployeeEntity.java @@ -0,0 +1,91 @@ +package com.gangquan360.smartadmin.module.employee.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +import java.io.Serializable; + +/** + * 员工实体类 + * + * @author lidoudou + * @date 2017年12月19日下午1:34:48 + */ +@Data +@TableName("t_employee") +public class EmployeeEntity extends BaseEntity implements Serializable { + + private static final long serialVersionUID = -8794328598524272806L; + + /** + * 登录账号 + */ + private String loginName; + + /** + * 登录密码 + */ + private String loginPwd; + + /** + * 员工名称 + */ + private String actualName; + + /** + * 别名 + */ + private String nickName; + + /** + * 手机号码 + */ + private String phone; + + /** + * 身份证 + */ + private String idCard; + + /** + * 出生日期 + */ + private String birthday; + + + /** + * 部门id + */ + private Long departmentId; + + /** + * 是否离职 + */ + private Integer isLeave; + + /** + * 是否被禁用 + */ + private Integer isDisabled; + /** + * 邮箱 + */ + private String email; + + /** + * 备注 + */ + private String remark; + + /** + * 创建者id + */ + private Long createUser; + + /** + * 删除状态 0否 1是 + */ + private Long isDelete; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/vo/EmployeeVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/vo/EmployeeVO.java new file mode 100644 index 00000000..8f9e9d36 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/employee/domain/vo/EmployeeVO.java @@ -0,0 +1,72 @@ +package com.gangquan360.smartadmin.module.employee.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionRelationResultDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * @author bhr + * @Description: 员工信息 + * @date 2019/8/28 9:04 + */ + +@Data +public class EmployeeVO { + + @ApiModelProperty("主键id") + private Long id; + + @ApiModelProperty("登录账号") + private String loginName; + + @ApiModelProperty("别名") + private String nickName; + + @ApiModelProperty("员工名称") + private String actualName; + + @ApiModelProperty("手机号码") + private String phone; + + @ApiModelProperty("身份证") + private String idCard; + + @ApiModelProperty("出生日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date birthday; + + @ApiModelProperty("创建者id") + private Long createUser; + + @ApiModelProperty("部门id") + private Long departmentId; + + @ApiModelProperty("是否离职") + private Integer isLeave; + + @ApiModelProperty("是否被禁用") + private Integer isDisabled; + + @ApiModelProperty("是否删除") + private Integer isDelete; + + @ApiModelProperty("部门名称") + private String departmentName; + + @ApiModelProperty("邮箱") + private String email; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + + @ApiModelProperty("岗位关联信息") + private List positionRelationList; + + @ApiModelProperty("岗位名称") + private String positionName; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/FileController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/FileController.java new file mode 100644 index 00000000..bdb908af --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/FileController.java @@ -0,0 +1,93 @@ +package com.gangquan360.smartadmin.module.file; + +import com.gangquan360.smartadmin.common.anno.NoNeedLogin; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.file.constant.FileServiceTypeEnum; +import com.gangquan360.smartadmin.module.file.domain.dto.FileAddDTO; +import com.gangquan360.smartadmin.module.file.domain.dto.FileQueryDTO; +import com.gangquan360.smartadmin.module.file.domain.vo.FileVO; +import com.gangquan360.smartadmin.module.file.domain.vo.UploadVO; +import com.gangquan360.smartadmin.module.file.service.FileService; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.util.SmartRequestTokenUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +/** + * @Description: 文件服务 + * @Author: sbq + * @CreateDate: 2019/7/18 9:36 + * @Version: 1.0 + */ +@RestController +@Api(tags = {SwaggerTagConst.Admin.MANAGER_FILE}) +public class FileController { + + @Autowired + private FileService fileService; + + @ApiOperation(value = "文件本地上传", notes = "文件本地上传") + @PostMapping("/api/file/localUpload/{moduleType}") + public ResponseDTO localUpload(MultipartFile file, @PathVariable Integer moduleType) throws Exception { + return fileService.fileUpload(file, FileServiceTypeEnum.LOCAL, moduleType); + } + + @ApiOperation(value = "获取本地文件URL", notes = "获取文件URL") + @PostMapping("/api/file/get") + public ResponseDTO localGetFile(String path) { + return fileService.getFileUrl(path, FileServiceTypeEnum.LOCAL); + } + + @ApiOperation(value = "文件阿里云上传", notes = "文件阿里云上传") + @PostMapping("/api/file/aliYunUpload/{moduleType}") + public ResponseDTO aliYunUpload(MultipartFile file, @PathVariable Integer moduleType) throws Exception { + return fileService.fileUpload(file, FileServiceTypeEnum.ALI_OSS, moduleType); + } + + @ApiOperation(value = "获取阿里云文件URL", notes = "获取阿里云文件URL") + @PostMapping("/api/file/aliYunGet") + public ResponseDTO aliYunGet(String path) { + return fileService.getFileUrl(path, FileServiceTypeEnum.ALI_OSS); + } + + @ApiOperation(value = "文件七牛云上传", notes = "文件七牛云上传") + @PostMapping("/api/file/qiNiuUpload/{moduleType}") + public ResponseDTO qiNiuUpload(MultipartFile file, @PathVariable Integer moduleType) throws Exception { + return fileService.fileUpload(file, FileServiceTypeEnum.QI_NIU_OSS, moduleType); + } + + @ApiOperation(value = "获取七牛云文件URL", notes = "获取七牛云URL") + @PostMapping("/api/file/qiNiuGet") + public ResponseDTO qiNiuGet(String path) { + return fileService.getFileUrl(path, FileServiceTypeEnum.QI_NIU_OSS); + } + + @ApiOperation(value = "系统文件查询") + @PostMapping("/api/file/query") + public ResponseDTO> queryListByPage(@RequestBody FileQueryDTO queryDTO) { + return fileService.queryListByPage(queryDTO); + } + + @ApiOperation(value = "系统文件下载通用接口(流下载)") + @GetMapping("/api/file/downLoad") + @NoNeedLogin + public ResponseEntity downLoadById(Long id, HttpServletRequest request) { + return fileService.downLoadById(id, request); + } + + @ApiOperation(value = "系统文件保存通用接口") + @PostMapping("/api/file/save") + public ResponseDTO saveFile(@Valid @RequestBody FileAddDTO addDTO) { + RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser(); + return fileService.saveFile(addDTO,requestToken); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/FileDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/FileDao.java new file mode 100644 index 00000000..01c3faa6 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/FileDao.java @@ -0,0 +1,72 @@ +package com.gangquan360.smartadmin.module.file; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.module.file.domain.dto.FileDTO; +import com.gangquan360.smartadmin.module.file.domain.dto.FileQueryDTO; +import com.gangquan360.smartadmin.module.file.domain.entity.FileEntity; +import com.gangquan360.smartadmin.module.file.domain.vo.FileVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author cyj + * @date 2018-01-05 上午 9:49 + */ +@Mapper +@Component +public interface FileDao extends BaseMapper { + + /** + * 批量添加上传文件 + * + * @param fileDTOList + * @return + */ + Integer insertFileBatch(List fileDTOList); + + + /** + * 批量添加上传文件 + * + * @param fileDTOList + * @return + */ + Integer insertFileEntityBatch(List fileDTOList); + + /** + * 批量删除 + * + * @param moduleId + * @return + */ + Integer deleteFilesByModuleId(@Param("moduleId") String moduleId); + + /** + * 批量删除 + * + * @param moduleId + * @param moduleType + * @return + */ + Integer deleteFilesByModuleIdAndModuleType(@Param("moduleId") String moduleId, @Param("moduleType") String moduleType); + + /** + * @param moduleId + * @return + */ + List listFilesByModuleId(@Param("moduleId") String moduleId); + + List listFilesByFileIds(@Param("fileIds") List fileIds); + + List listFilesByModuleIdAndModuleType(@Param("moduleId") String moduleId, @Param("moduleType") String moduleType); + + List listFilesByModuleIdAndModuleTypes(@Param("moduleId") String moduleId, @Param("moduleTypes") List moduleTypes); + + List listFilesByModuleIdsAndModuleType(@Param("moduleIds") List moduleIds, @Param("moduleType") String moduleType); + + List queryListByPage(Page page, @Param("queryDTO") FileQueryDTO queryDTO); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileModuleTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileModuleTypeEnum.java new file mode 100644 index 00000000..78670f2c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileModuleTypeEnum.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.module.file.constant; + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +/** + * [] + * + * @author yandanyang + * @version 1.0 + * @since JDK1.8 + */ +public enum FileModuleTypeEnum implements BaseEnum { + + /** + * path 首字符不能包含\ 或者/ + */ + + BACK_USER(1, "backUser/config", "backUser"); + + private Integer value; + + private String path; + + private String desc; + + FileModuleTypeEnum(Integer value, String path, String desc) { + this.value = value; + this.path = path; + this.desc = desc; + } + + public String getPath() { + return path; + } + + @Override + public Integer getValue() { + return this.value; + } + + @Override + public String getDesc() { + return this.desc; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileResponseCodeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileResponseCodeConst.java new file mode 100644 index 00000000..795bed17 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileResponseCodeConst.java @@ -0,0 +1,37 @@ +package com.gangquan360.smartadmin.module.file.constant; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +public class FileResponseCodeConst extends ResponseCodeConst { + + /** + * 4001 -4999 + */ + public static final FileResponseCodeConst FILE_EMPTY = new FileResponseCodeConst(4001, "上传文件不存在!"); + + public static final FileResponseCodeConst FILE_SIZE_ERROR = new FileResponseCodeConst(4002, "上传文件超过%s,请重新上传!"); + + public static final FileResponseCodeConst UNKNOWN_FILE_TYPE = new FileResponseCodeConst(4003, "未知的文件类型!"); + + public static final FileResponseCodeConst LOCAL_UPDATE_PREFIX_ERROR = new FileResponseCodeConst(4004, "文件本地上传缺少URL前缀配置[local_upload_url_prefix]"); + + public static final FileResponseCodeConst UPLOAD_ERROR = new FileResponseCodeConst(4005, "上传失败"); + + public static final FileResponseCodeConst URL_ERROR = new FileResponseCodeConst(4006, "获取URL失败"); + + public static final FileResponseCodeConst FILE_MODULE_ERROR = new FileResponseCodeConst(4007, "文件目录类型错误"); + + public FileResponseCodeConst(int code, String msg) { + super(code, msg); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileServiceNameConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileServiceNameConst.java new file mode 100644 index 00000000..96c649f3 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileServiceNameConst.java @@ -0,0 +1,24 @@ +package com.gangquan360.smartadmin.module.file.constant; +/** + * 文件服务名称常量 + * + * @author listen + * @date 2019/08/27 15:24 + */ +public class FileServiceNameConst { + + /** + * 阿里OSS文件服务 + */ + public static final String ALI_OSS = "ali_oss"; + + /** + * 七牛文件服务 + */ + public static final String QI_NIU_OSS = "qi_niu_oss"; + + /** + * 本地文件服务 + */ + public static final String LOCAL = "local"; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileServiceTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileServiceTypeEnum.java new file mode 100644 index 00000000..04046b20 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/constant/FileServiceTypeEnum.java @@ -0,0 +1,52 @@ +package com.gangquan360.smartadmin.module.file.constant; + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +/** + * 文件服务枚举类 + * + * @author listen + * @date 2019年8月27日 14:27:16 + */ +public enum FileServiceTypeEnum implements BaseEnum { + + /** + * 本地文件服务 + */ + LOCAL(1, FileServiceNameConst.LOCAL, "本地文件服务"), + + /** + * 阿里OSS文件服务 + */ + ALI_OSS(2, FileServiceNameConst.ALI_OSS, "阿里OSS文件服务"), + + /** + * 七牛文件服务 + */ + QI_NIU_OSS(3, FileServiceNameConst.QI_NIU_OSS, "七牛文件服务"); + + private Integer locationType; + + private String serviceName; + + private String desc; + + FileServiceTypeEnum(Integer locationType, String serviceName, String desc) { + this.locationType = locationType; + this.serviceName = serviceName; + this.desc = desc; + } + + public String getServiceName() { + return serviceName; + } + @Override + public Integer getValue() { + return this.locationType; + } + + @Override + public String getDesc() { + return this.desc; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/FileAddDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/FileAddDTO.java new file mode 100644 index 00000000..9121b56f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/FileAddDTO.java @@ -0,0 +1,40 @@ +package com.gangquan360.smartadmin.module.file.domain.dto; + +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.common.validator.en.CheckEnum; +import com.gangquan360.smartadmin.module.file.constant.FileServiceTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** +* @Description: 文件保存DTO +* @Author: sbq +* @CreateDate: 2019/9/11 15:05 +* @Version: 1.0 +*/ +@Data +public class FileAddDTO { + + @ApiModelProperty("相关业务id(无业务可写死一个id)") + @NotBlank(message = "相关业务id不能为空") + private String moduleId; + + @ApiModelProperty("相关业务类型(无模块写1)") + @NotBlank(message = "相关业务类型不能为空") + private String moduleType; + + @ApiModelPropertyEnum(enumDesc = "文件类型",value = FileServiceTypeEnum.class) + @CheckEnum(enumClazz = FileServiceTypeEnum.class,message = "文件类型错误") + private Integer fileLocationType; + + @ApiModelProperty("文件名称") + @NotBlank(message = "文件名称不能为空") + private String fileName; + + @ApiModelProperty("文件路径") + @NotBlank(message = "文件路径不能为空") + private String filePath; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/FileDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/FileDTO.java new file mode 100644 index 00000000..a6998cf0 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/FileDTO.java @@ -0,0 +1,58 @@ +package com.gangquan360.smartadmin.module.file.domain.dto; + +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.module.file.constant.FileServiceTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.sql.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Data +public class FileDTO { + + @ApiModelProperty("主键") + private Long id; + + @ApiModelProperty("相关业务id") + private String moduleId; + + @ApiModelProperty("相关业务类型") + private String moduleType; + + @ApiModelPropertyEnum(FileServiceTypeEnum.class) + private Integer fileLocationType; + + @ApiModelProperty("文件名称") + private String fileName; + + @ApiModelProperty("文件大小") + private String fileSize; + + @ApiModelProperty("文件类型") + private String fileType; + + @ApiModelProperty("文件路径") + private String filePath; + + @ApiModelProperty("上传人") + private Long createUser; + + @ApiModelProperty("updateTime") + private Date updateTime; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("文件展示url(可用于下载,注:七牛云下载url要拼接 ?attname=文件名.jpg)") + private String fileUrl; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/FileQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/FileQueryDTO.java new file mode 100644 index 00000000..d6e547bd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/FileQueryDTO.java @@ -0,0 +1,33 @@ +package com.gangquan360.smartadmin.module.file.domain.dto; + +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import com.gangquan360.smartadmin.common.validator.en.CheckEnum; +import com.gangquan360.smartadmin.module.file.constant.FileModuleTypeEnum; +import com.gangquan360.smartadmin.module.file.constant.FileServiceTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @Description: 文件信息查询dto + * @Author: sbq + * @CreateDate: 2019/7/3 17:38 + * @Version: 1.0 + */ +@Data +public class FileQueryDTO extends PageParamDTO { + + @ApiModelProperty(value = "文件名称") + private String fileName; + + @ApiModelProperty(value = "业务类型") + @ApiModelPropertyEnum(FileModuleTypeEnum.class) + @CheckEnum(enumClazz = FileModuleTypeEnum.class, message = "文件业务类型错误") + private Integer moduleType; + + @ApiModelProperty(value = "文件位置") + @ApiModelPropertyEnum(FileServiceTypeEnum.class) + @CheckEnum(enumClazz = FileServiceTypeEnum.class, message = "文件位置类型错误") + private Integer fileLocationType; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/OSSConfig.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/OSSConfig.java new file mode 100644 index 00000000..cd4013a9 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/dto/OSSConfig.java @@ -0,0 +1,36 @@ +package com.gangquan360.smartadmin.module.file.domain.dto; + +import com.alibaba.fastjson.JSON; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/11 0011 下午 16:05 + * @since JDK1.8 + */ +@Data +public class OSSConfig { + + private String endpoint; + + private String accessKeyId; + + private String accessKeySecret; + + private String bucketName; + + @Override + public String toString() { + return "OSSConfig{" + + "endpoint='" + endpoint + '\'' + + ", accessKeyId='" + accessKeyId + '\'' + + ", accessKeySecret='" + accessKeySecret + '\'' + + ", bucketName='" + bucketName + '\'' + + '}'; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/entity/FileEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/entity/FileEntity.java new file mode 100644 index 00000000..b99e4dcd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/entity/FileEntity.java @@ -0,0 +1,58 @@ +package com.gangquan360.smartadmin.module.file.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +@TableName(value = "t_file") +public class FileEntity extends BaseEntity{ + + + /** + * 相关业务id + */ + private String moduleId; + /** + * 相关业务类型 + */ + private String moduleType; + /** + * 文件位置类型 + */ + private Integer fileLocationType; + /** + * 文件名称 + */ + private String fileName; + /** + * 文件大小 + */ + private String fileSize; + /** + * 文件类型,程序中枚举控制,文件类型:如身份证正面,三证合一等等 + */ + private String fileType; + /** + * 文件key,用于文件下载 + */ + private String filePath; + /** + * 创建人,即上传人 + */ + private Long createrUser; + +} + diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/vo/FileVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/vo/FileVO.java new file mode 100644 index 00000000..336282fd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/vo/FileVO.java @@ -0,0 +1,58 @@ +package com.gangquan360.smartadmin.module.file.domain.vo; + +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.module.file.constant.FileServiceTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.sql.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Data +public class FileVO { + + @ApiModelProperty("主键") + private Long id; + + @ApiModelProperty("相关业务id") + private String moduleId; + + @ApiModelProperty("相关业务类型") + private String moduleType; + + @ApiModelPropertyEnum(FileServiceTypeEnum.class) + private Integer fileLocationType; + + @ApiModelProperty("文件名称") + private String fileName; + + @ApiModelProperty("文件大小") + private String fileSize; + + @ApiModelProperty("文件类型") + private String fileType; + + @ApiModelProperty("文件路径") + private String filePath; + + @ApiModelProperty("上传人") + private Long createUser; + + @ApiModelProperty("updateTime") + private Date updateTime; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("文件展示url(可用于下载,注:七牛云下载url要拼接 ?attname=文件名.jpg)") + private String fileUrl; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/vo/UploadVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/vo/UploadVO.java new file mode 100644 index 00000000..aff3a02e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/domain/vo/UploadVO.java @@ -0,0 +1,27 @@ +package com.gangquan360.smartadmin.module.file.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2018/12/11 0011 上午 10:57 + * @since JDK1.8 + */ +@Data +public class UploadVO { + + @ApiModelProperty(value = "文件名称") + private String fileName; + @ApiModelProperty(value = "url") + private String url; + @ApiModelProperty(value = "filePath") + private String filePath; + @ApiModelProperty(value = "文件大小") + private Long fileSize; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileService.java new file mode 100644 index 00000000..51c0d75b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileService.java @@ -0,0 +1,197 @@ +package com.gangquan360.smartadmin.module.file.service; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.file.FileDao; +import com.gangquan360.smartadmin.module.file.constant.FileModuleTypeEnum; +import com.gangquan360.smartadmin.module.file.constant.FileResponseCodeConst; +import com.gangquan360.smartadmin.module.file.constant.FileServiceTypeEnum; +import com.gangquan360.smartadmin.module.file.domain.dto.FileAddDTO; +import com.gangquan360.smartadmin.module.file.domain.dto.FileDTO; +import com.gangquan360.smartadmin.module.file.domain.dto.FileQueryDTO; +import com.gangquan360.smartadmin.module.file.domain.entity.FileEntity; +import com.gangquan360.smartadmin.module.file.domain.vo.FileVO; +import com.gangquan360.smartadmin.module.file.domain.vo.UploadVO; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.util.SmartBaseEnumUtil; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Service +public class FileService { + + @Autowired + private FileDao fileDao; + + @Autowired + private java.util.Map fileServiceMap; + + /** + * 获取文件服务实现 + * + * @param typeEnum + * @return + */ + private IFileService getFileService(FileServiceTypeEnum typeEnum) { + /** + * 获取文件服务 + */ + String serviceName = typeEnum.getServiceName(); + IFileService fileService = fileServiceMap.get(serviceName); + if (null == fileService) { + throw new RuntimeException("未找到文件服务实现类:" + serviceName); + } + return fileService; + } + + /** + * 文件上传服务 + * + * @param file + * @param typeEnum 文件服务类型枚举类 + * @param moduleType 文件夹类型 + * @return + */ + public ResponseDTO fileUpload(MultipartFile file, FileServiceTypeEnum typeEnum, Integer moduleType) { + FileModuleTypeEnum moduleTypeEnum = SmartBaseEnumUtil.getEnumByValue(moduleType, FileModuleTypeEnum.class); + if (null == moduleTypeEnum) { + return ResponseDTO.wrap(FileResponseCodeConst.FILE_MODULE_ERROR); + } + // 获取文件服务 + IFileService fileService = this.getFileService(typeEnum); + ResponseDTO response = fileService.fileUpload(file, moduleTypeEnum.getPath()); + return response; + } + + /** + * 根据文件绝对路径 获取文件URL + * + * @param path + * @return + */ + public ResponseDTO getFileUrl(String path, FileServiceTypeEnum typeEnum) { + IFileService fileService = this.getFileService(typeEnum); + return fileService.getFileUrl(path); + } + + /** + * 批量插入 + * + * @param fileDTOList + */ + public void insertFileBatch(List fileDTOList) { + fileDao.insertFileBatch(fileDTOList); + } + + /** + * 根据module 删除文件信息 + * + * @param moduleId + * @return + */ + public void deleteFilesByModuleId(String moduleId) { + fileDao.deleteFilesByModuleId(moduleId); + } + + /** + * 根据module 获取文件信息 + * + * @param moduleId + * @return + */ + public List listFilesByModuleId(String moduleId) { + return fileDao.listFilesByModuleId(moduleId); + } + + /** + * @param filesStr 逗号分隔文件id字符串 + * @return + */ + public List getFileDTOList(String filesStr) { + if (StringUtils.isEmpty(filesStr)) { + return Lists.newArrayList(); + } + String[] fileIds = filesStr.split(","); + List fileIdList = Arrays.asList(fileIds).stream().map(e -> Long.valueOf(e)).collect(Collectors.toList()); + List files = fileDao.listFilesByFileIds(fileIdList); + return files; + } + + /** + * 分页查询文件列表 + * + * @param queryDTO + * @return + */ + public ResponseDTO> queryListByPage(FileQueryDTO queryDTO) { + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List fileList = fileDao.queryListByPage(page, queryDTO); + if (CollectionUtils.isNotEmpty(fileList)) { + fileList.forEach(e -> { + // 根据文件服务类 获取对应文件服务 查询 url + FileServiceTypeEnum serviceTypeEnum = SmartBaseEnumUtil.getEnumByValue(e.getFileLocationType(), FileServiceTypeEnum.class); + IFileService fileService = this.getFileService(serviceTypeEnum); + e.setFileUrl(fileService.getFileUrl(e.getFilePath()).getData()); + }); + } + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page, fileList); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * 根据id 下载文件 + * + * @param id + * @param request + * @return + */ + public ResponseEntity downLoadById(Long id, HttpServletRequest request) { + FileEntity entity = fileDao.selectById(id); + if (null == entity) { + throw new RuntimeException("文件信息不存在"); + } + + // 根据文件服务类 获取对应文件服务 查询 url + FileServiceTypeEnum serviceTypeEnum = SmartBaseEnumUtil.getEnumByValue(entity.getFileLocationType(), FileServiceTypeEnum.class); + IFileService fileService = this.getFileService(serviceTypeEnum); + ResponseEntity stream = fileService.fileDownload(entity.getFilePath(), entity.getFileName(), request); + return stream; + } + + /** + * 系统文件保存通用接口 + * @param addDTO + * @return + */ + public ResponseDTO saveFile(FileAddDTO addDTO, RequestTokenBO requestToken) { + FileEntity entity = SmartBeanUtil.copy(addDTO,FileEntity.class); + entity.setCreaterUser(requestToken.getRequestUserId()); + entity.setCreateTime(new Date()); + fileDao.insert(entity); + return ResponseDTO.succ(); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileServiceAliYun.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileServiceAliYun.java new file mode 100644 index 00000000..1872be3e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileServiceAliYun.java @@ -0,0 +1,182 @@ +package com.gangquan360.smartadmin.module.file.service; + +import com.aliyun.oss.OSSClient; +import com.aliyun.oss.model.OSSObject; +import com.aliyun.oss.model.ObjectMetadata; +import com.aliyun.oss.model.PutObjectRequest; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.file.constant.FileResponseCodeConst; +import com.gangquan360.smartadmin.module.file.constant.FileServiceNameConst; +import com.gangquan360.smartadmin.module.file.domain.dto.OSSConfig; +import com.gangquan360.smartadmin.module.file.domain.vo.UploadVO; +import com.gangquan360.smartadmin.module.systemconfig.SystemConfigService; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigEnum; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/10 0010 上午 8:29 + * @since JDK1.8 + */ +@Slf4j +@Service(FileServiceNameConst.ALI_OSS) +public class FileServiceAliYun implements IFileService { + + @Autowired + private SystemConfigService systemConfigService; + + OSSClient ossClient = null; + + String accessConfig = null; + + @Override + public ResponseDTO fileUpload(MultipartFile multipartFile, String path) { + OSSConfig ossConfig = systemConfigService.selectByKey2Obj(SystemConfigEnum.Key.ALI_OSS.name(), OSSConfig.class); + try { + InputStream inputStream = new ByteArrayInputStream(multipartFile.getBytes()); + if (! ossConfig.toString().equals(accessConfig)) { + //accessKeyId 发生变动自动创建新的 + if (ossClient != null) { + ossClient.shutdown(); + } + ossClient = new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()); + accessConfig = ossConfig.toString(); + } + String uuid = UUID.randomUUID().toString().replace("-", ""); + String ossPath = path + "/" + uuid; + String fileName = multipartFile.getOriginalFilename(); + String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1); + ObjectMetadata meta = new ObjectMetadata(); + meta.setContentDisposition("attachment;filename=" + fileName); + Map userMetadata = new HashMap(); + userMetadata.put("fileName", fileName); + userMetadata.put("fileExt", fileExt); + userMetadata.put("fileSize", String.valueOf(multipartFile.getSize())); + meta.setUserMetadata(userMetadata); + meta.setContentType(this.getContentType(fileExt)); + PutObjectRequest putObjectRequest = new PutObjectRequest(ossConfig.getBucketName(), ossPath, inputStream, meta); + ossClient.putObject(putObjectRequest); + UploadVO localUploadVO = new UploadVO(); + localUploadVO.setUrl(this.getUrl(ossPath, ossConfig.getBucketName(), ossClient)); + localUploadVO.setFileName(fileName); + localUploadVO.setFilePath(ossPath); + localUploadVO.setFileSize(multipartFile.getSize()); + return ResponseDTO.succData(localUploadVO); + } catch (Exception e) { + log.error("ALI UPLOAD ERROR : {}", e); + } + return ResponseDTO.wrap(FileResponseCodeConst.UPLOAD_ERROR); + } + + @Override + public ResponseDTO getFileUrl(String path) { + OSSConfig ossConfig = systemConfigService.selectByKey2Obj(SystemConfigEnum.Key.ALI_OSS.name(), OSSConfig.class); + try { + if (! ossConfig.toString().equals(accessConfig)) { + //accessKeyId 发生变动自动创建新的 + if (ossClient != null) { + ossClient.shutdown(); + } + ossClient = new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()); + accessConfig = ossConfig.toString(); + } + String url = this.getUrl(path, ossConfig.getBucketName(), ossClient); + return ResponseDTO.succData(url); + } catch (Exception e) { + log.error("ALI getFileUrl ERROR : {}", e); + } + return ResponseDTO.wrap(FileResponseCodeConst.URL_ERROR); + } + + private String getUrl(String path, String bucketName, OSSClient ossClient) { + Date expiration = new Date(System.currentTimeMillis() + (60 * 60 * 1000)); + URL url = ossClient.generatePresignedUrl(bucketName, path, expiration); + return url.toString(); + } + + /** + * 流式下载(名称为原文件) + */ + @Override + public ResponseEntity fileDownload(String key, String fileName, HttpServletRequest request) { + File file = this.getFile(key, fileName); + if (file == null) { + throw new RuntimeException("文件不存在"); + } + return this.downloadMethod(file, request); + } + + /** + * 根据osskey获取文件 + * + * @param key + * @return + */ + public File getFile(String key, String fileName) { + OSSConfig ossConfig = systemConfigService.selectByKey2Obj(SystemConfigEnum.Key.ALI_OSS.name(), OSSConfig.class); + if (! ossConfig.toString().equals(accessConfig)) { + //accessKeyId 发生变动自动创建新的 + if (ossClient != null) { + ossClient.shutdown(); + } + ossClient = new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()); + accessConfig = ossConfig.toString(); + } + //获取oss对象 + OSSObject ossObject = ossClient.getObject(ossConfig.getBucketName(), key); + if (StringUtils.isBlank(fileName)) { + // 获取元信息 + ObjectMetadata objectMetadata = ossObject.getObjectMetadata(); + // 获取下载时文件名 + Map userMetadata = objectMetadata.getUserMetadata(); + fileName = userMetadata == null ? "" : userMetadata.get("filename"); + if (StringUtils.isBlank(fileName)) { + fileName = objectMetadata.getContentDisposition(); + } + } + // 创建文件 + File file = new File(fileName); + // 获得输入流 + InputStream objectContent = ossObject.getObjectContent(); + try { + // 输入流转换为字节流 + byte[] buffer = FileCopyUtils.copyToByteArray(objectContent); + // 字节流写入文件 + FileCopyUtils.copy(buffer, file); + // 关闭输入流 + objectContent.close(); + } catch (IOException e) { + log.error("文件获取失败:" + e); + return null; + } finally { + try { + ossObject.close(); + } catch (IOException e) { + log.error("", e); + } + } + return file; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileServiceLocal.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileServiceLocal.java new file mode 100644 index 00000000..a11a20ce --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileServiceLocal.java @@ -0,0 +1,123 @@ +package com.gangquan360.smartadmin.module.file.service; + +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.file.constant.FileResponseCodeConst; +import com.gangquan360.smartadmin.module.file.constant.FileServiceNameConst; +import com.gangquan360.smartadmin.module.file.domain.vo.UploadVO; +import com.gangquan360.smartadmin.module.systemconfig.SystemConfigDao; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigEnum; +import com.gangquan360.smartadmin.module.systemconfig.domain.entity.SystemConfigEntity; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.IOException; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/11 0011 下午 16:15 + * @since JDK1.8 + */ +@Slf4j +@Service(FileServiceNameConst.LOCAL) +public class FileServiceLocal implements IFileService { + + @Autowired + private SystemConfigDao systemConfigDao; + + @Value("${spring.servlet.multipart.max-file-size}") + private String maxFileSize; + + @Value("${file-upload-service.path}") + private String fileParentPath; + + private static final Long DEFAULT_SIZE = 10 * 1024 * 1024L; + + @Override + public ResponseDTO fileUpload(MultipartFile multipartFile, String path) { + if (null == multipartFile) { + return ResponseDTO.wrap(FileResponseCodeConst.FILE_EMPTY); + } + Long maxSize = DEFAULT_SIZE; + if (StringUtils.isNotEmpty(maxFileSize)) { + String maxSizeStr = maxFileSize.toLowerCase().replace("mb", ""); + maxSize = Integer.valueOf(maxSizeStr) * 1024 * 1024L; + } + if (multipartFile.getSize() > maxSize) { + return ResponseDTO.wrap(FileResponseCodeConst.FILE_SIZE_ERROR, String.format(FileResponseCodeConst.FILE_SIZE_ERROR.getMsg(), maxFileSize)); + } + String filePath = fileParentPath; + String urlParent = this.localUrlPrefix(); + if (urlParent == null) { + return ResponseDTO.wrap(FileResponseCodeConst.LOCAL_UPDATE_PREFIX_ERROR); + } + if (StringUtils.isNotEmpty(path)) { + filePath = filePath + path + "/"; + urlParent = urlParent + path + "/"; + } + File directory = new File(filePath); + if (!directory.exists()) { + // 目录不存在,新建 + directory.mkdirs(); + } + UploadVO localUploadVO = new UploadVO(); + String newFileName; + File fileTemp; + String originalFileName; + originalFileName = multipartFile.getOriginalFilename(); + newFileName = this.generateFileName(originalFileName); + fileTemp = new File(new File(filePath + newFileName).getAbsolutePath()); + try { + multipartFile.transferTo(fileTemp); + localUploadVO.setUrl(urlParent + newFileName); + localUploadVO.setFileName(newFileName); + localUploadVO.setFilePath(path + "/" + newFileName); + localUploadVO.setFileSize(multipartFile.getSize()); + } catch (IOException e) { + if (fileTemp.exists() && fileTemp.isFile()) { + fileTemp.delete(); + } + log.error("", e); + return ResponseDTO.wrap(FileResponseCodeConst.UPLOAD_ERROR); + } + return ResponseDTO.succData(localUploadVO); + } + + @Override + public ResponseDTO getFileUrl(String path) { + String urlParent = this.localUrlPrefix(); + if (urlParent == null) { + return ResponseDTO.wrap(FileResponseCodeConst.LOCAL_UPDATE_PREFIX_ERROR); + } + String url = urlParent + path; + return ResponseDTO.succData(url); + } + + private String localUrlPrefix() { + SystemConfigEntity configEntity = systemConfigDao.getByKey(SystemConfigEnum.Key.LOCAL_UPLOAD_URL_PREFIX.name()); + if (configEntity == null) { + return null; + } + return configEntity.getConfigValue(); + } + + @Override + public ResponseEntity fileDownload(String key, String fileName, HttpServletRequest request) { + + String url = fileParentPath + key; + // 创建文件 + File file = new File(url); + return this.downloadMethod(file, request); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileServiceQiNiuYun.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileServiceQiNiuYun.java new file mode 100644 index 00000000..f09aeb6a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/FileServiceQiNiuYun.java @@ -0,0 +1,175 @@ +package com.gangquan360.smartadmin.module.file.service; + +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.file.constant.FileResponseCodeConst; +import com.gangquan360.smartadmin.module.file.constant.FileServiceNameConst; +import com.gangquan360.smartadmin.module.file.domain.dto.OSSConfig; +import com.gangquan360.smartadmin.module.file.domain.vo.UploadVO; +import com.gangquan360.smartadmin.module.systemconfig.SystemConfigService; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigEnum; +import com.qiniu.http.Response; +import com.qiniu.storage.Configuration; +import com.qiniu.storage.UploadManager; +import com.qiniu.util.Auth; +import lombok.extern.slf4j.Slf4j; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.ResponseBody; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.UUID; + +/** + * [ 七牛云 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/10 0010 上午 8:30 + * @since JDK1.8 + */ +@Slf4j +@Service(FileServiceNameConst.QI_NIU_OSS) +public class FileServiceQiNiuYun implements IFileService { + + //1小时,可以自定义链接过期时间 + private static final Long expireInSeconds = 3600L; + + @Autowired + private SystemConfigService systemConfigService; + + UploadManager ossClient = null; + + String accessConfig = null; + + String token = null; + + @Override + public ResponseDTO fileUpload(MultipartFile multipartFile, String path) { + OSSConfig ossConfig = systemConfigService.selectByKey2Obj(SystemConfigEnum.Key.QI_NIU_OSS.name(), OSSConfig.class); + try { + InputStream inputStream = new ByteArrayInputStream(multipartFile.getBytes()); + if (! ossConfig.toString().equals(accessConfig)) { + //accessKeyId 发生变动自动重新创建新的UploadManager + ossClient = new UploadManager(new Configuration()); + token = Auth.create(ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()). + uploadToken(ossConfig.getBucketName()); + accessConfig = ossConfig.toString(); + } + String uuid = UUID.randomUUID().toString().replace("-", ""); + String ossPath = path + "/" + uuid; + String fileName = multipartFile.getOriginalFilename(); + String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1); + String mime = this.getContentType(fileExt); + Response res = ossClient.put(inputStream, ossPath, token, null, mime); + if (! res.isOK()) { + log.error("QINIU fileUpload ERROR : {}", res.toString()); + return ResponseDTO.wrap(FileResponseCodeConst.UPLOAD_ERROR); + } + UploadVO localUploadVO = new UploadVO(); + localUploadVO.setUrl(this.getFileUrl(ossPath).getData()); + localUploadVO.setFileName(fileName); + localUploadVO.setFilePath(ossPath); + localUploadVO.setFileSize(multipartFile.getSize()); + return ResponseDTO.succData(localUploadVO); + } catch (Exception e) { + log.error("QINIU fileUpload ERROR : {}", e); + } + return ResponseDTO.wrap(FileResponseCodeConst.UPLOAD_ERROR); + } + + @Override + public ResponseDTO getFileUrl(String path) { + OSSConfig ossConfig = systemConfigService.selectByKey2Obj(SystemConfigEnum.Key.QI_NIU_OSS.name(), OSSConfig.class); + try { + if (! ossConfig.toString().equals(accessConfig)) { + //accessKeyId 发生变动自动重新创建新的UploadManager + ossClient = new UploadManager(new Configuration()); + token = Auth.create(ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()). + uploadToken(ossConfig.getBucketName()); + accessConfig = ossConfig.toString(); + } + String encodedFileName = URLEncoder.encode(path, "utf-8"); + String domainOfBucket = ossConfig.getEndpoint(); + String publicUrl = String.format("%s/%s", domainOfBucket, encodedFileName); + String accessKey = ossConfig.getAccessKeyId(); + String secretKey = ossConfig.getAccessKeySecret(); + Auth auth = Auth.create(accessKey, secretKey); + //1小时,可以自定义链接过期时间 + long expireInSeconds = 3600; + String finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds); + return ResponseDTO.succData(finalUrl); + } catch (Exception e) { + log.error("QINIU getFileUrl ERROR : {}", e); + } + return ResponseDTO.wrap(FileResponseCodeConst.URL_ERROR); + } + + @Override + public ResponseEntity fileDownload(String key, String fileName, HttpServletRequest request) { + File file = this.getFile(key, fileName); + if (file == null) { + throw new RuntimeException("文件不存在"); + } + return this.downloadMethod(file, request); + } + + /** + * 获取下载路径 + */ + public String getDownloadUrl(String key) { + OSSConfig ossConfig = systemConfigService.selectByKey2Obj(SystemConfigEnum.Key.QI_NIU_OSS.name(), OSSConfig.class); + String domainOfBucket = ossConfig.getEndpoint(); + String finalUrl = ""; + try { + String encodedFileName = URLEncoder.encode(key, "utf-8").replace("+", "%20"); + String publicUrl = String.format("%s/%s", domainOfBucket, encodedFileName); + Auth auth = Auth.create(ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()); + finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds); + } catch (Exception e) { + log.error("QINIU download ERROR : {}", e); + } + return finalUrl; + } + + /** + * 获取文件 + */ + public File getFile(String key, String fileName) { + String finalUrl = getDownloadUrl(key); + OkHttpClient client = new OkHttpClient(); + Request req = new Request.Builder().url(finalUrl).build(); + okhttp3.Response resp = null; + File file = new File(fileName); + try { + resp = client.newCall(req).execute(); + if (resp.isSuccessful()) { + ResponseBody body = resp.body(); + InputStream objectContent = body.byteStream(); + // 输入流转换为字节流 + byte[] buffer = FileCopyUtils.copyToByteArray(objectContent); + // 字节流写入文件 + FileCopyUtils.copy(buffer, file); + // 关闭输入流 + objectContent.close(); + } + + } catch (IOException e) { + log.error("文件获取失败:" + e); + return null; + } finally { + } + return file; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/IFileService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/IFileService.java new file mode 100644 index 00000000..0cc35f36 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/file/service/IFileService.java @@ -0,0 +1,152 @@ +package com.gangquan360.smartadmin.module.file.service; + +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.file.domain.vo.UploadVO; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.UUID; + +/** + * 文件服务接口 + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/11 0011 下午 16:42 + * @since JDK1.8 + */ +public interface IFileService { + + /** + * 文件上传 + * + * @param multipartFile + * @param path + * @return + */ + ResponseDTO fileUpload(MultipartFile multipartFile, String path); + + /** + * 获取文件url + * + * @param path + * @return + */ + ResponseDTO getFileUrl(String path); + + /** + * 文件下载 + * + * @param key + * @param fileName + * @param request + * @return + */ + ResponseEntity fileDownload(String key, String fileName, HttpServletRequest request); + + /** + * 生成文件名字 + * 当前年月日时分秒 +32位 uuid + 文件格式后缀 + * + * @param originalFileName + * @return String + */ + default String generateFileName(String originalFileName) { + String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmms")); + String uuid = UUID.randomUUID().toString().replaceAll("-", ""); + String fileType = originalFileName.substring(originalFileName.lastIndexOf(".")); + return time + uuid + fileType; + } + + /** + * 获取文件类型 + * + * @param fileExt + * @return + */ + default String getContentType(String fileExt) { + // 文件的后缀名 + if ("bmp".equalsIgnoreCase(fileExt)) { + return "image/bmp"; + } + if ("gif".equalsIgnoreCase(fileExt)) { + return "image/gif"; + } + if ("jpeg".equalsIgnoreCase(fileExt) || "jpg".equalsIgnoreCase(fileExt) || ".png".equalsIgnoreCase(fileExt)) { + return "image/jpeg"; + } + if ("png".equalsIgnoreCase(fileExt)) { + return "image/png"; + } + if ("html".equalsIgnoreCase(fileExt)) { + return "text/html"; + } + if ("txt".equalsIgnoreCase(fileExt)) { + return "text/plain"; + } + if ("vsd".equalsIgnoreCase(fileExt)) { + return "application/vnd.visio"; + } + if ("ppt".equalsIgnoreCase(fileExt) || "pptx".equalsIgnoreCase(fileExt)) { + return "application/vnd.ms-powerpoint"; + } + if ("doc".equalsIgnoreCase(fileExt) || "docx".equalsIgnoreCase(fileExt)) { + return "application/msword"; + } + if ("xml".equalsIgnoreCase(fileExt)) { + return "text/xml"; + } + return ""; + } + + default ResponseEntity downloadMethod(File file, HttpServletRequest request) { + HttpHeaders heads = new HttpHeaders(); + heads.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream; charset=utf-8"); + String fileName = file.getName(); + try { + if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) { + // firefox浏览器 + fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1"); + } else if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) { + // IE浏览器 + fileName = URLEncoder.encode(fileName, "UTF-8"); + } else if (request.getHeader("User-Agent").toUpperCase().indexOf("EDGE") > 0) { + // WIN10浏览器 + fileName = URLEncoder.encode(fileName, "UTF-8"); + } else if (request.getHeader("User-Agent").toUpperCase().indexOf("CHROME") > 0) { + // 谷歌 + fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1"); + } else { + //万能乱码问题解决 + fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1"); + } + } catch (UnsupportedEncodingException e) { + // log.error("", e); + } + heads.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName); + try { + InputStream in = new FileInputStream(file); + // 输入流转换为字节流 + byte[] buffer = FileCopyUtils.copyToByteArray(in); + ResponseEntity responseEntity = new ResponseEntity<>(buffer, heads, HttpStatus.OK); + //file.delete(); + return responseEntity; + } catch (Exception e) { + // log.error("", e); + } + return null; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatController.java new file mode 100644 index 00000000..b40c8454 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatController.java @@ -0,0 +1,32 @@ +package com.gangquan360.smartadmin.module.heartbeat; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + + +@Api(tags = {SwaggerTagConst.Admin.MANAGER_HEART_BEAT}) +@OperateLog +@RestController +public class HeartBeatController { + + @Autowired + private HeartBeatService heartBeatService; + + @PostMapping("/heartBeat/query") + @ApiOperation("查询心跳记录 @author zhuoda") + public ResponseDTO> query(@RequestBody @Valid PageParamDTO pageParamDTO){ + return heartBeatService.pageQuery(pageParamDTO); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatRecordDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatRecordDao.java new file mode 100644 index 00000000..ca9fc96f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatRecordDao.java @@ -0,0 +1,53 @@ +package com.gangquan360.smartadmin.module.heartbeat; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.pagination.Pagination; +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.List; + +/** + * 心跳日志数据库操作 + * + * @author : simajinqiang + * Date: 2018/7/9 + * Time: 17:37 + */ +@Component +@Mapper +public interface HeartBeatRecordDao extends BaseMapper { + + /** + * 新增心跳日志 + * + * @param heartBeatRecordEntity + */ + void insertHeartBeat(HeartBeatRecordEntity heartBeatRecordEntity); + + /** + * 更新心跳日志 + * + * @param id + * @param heartBeatTime + */ + void updateHeartBeatTimeById(@Param("id") Long id, @Param("heartBeatTime") Date heartBeatTime); + + /** + * 查询心跳日志 + * + * @param heartBeatRecordEntity + * @return + */ + HeartBeatRecordEntity query(HeartBeatRecordEntity heartBeatRecordEntity); + + + /** + * 分页查询心跳记录 + * @return + */ + List pageQuery(Pagination page); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatRecordEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatRecordEntity.java new file mode 100644 index 00000000..3df2490d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatRecordEntity.java @@ -0,0 +1,42 @@ +package com.gangquan360.smartadmin.module.heartbeat; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 心跳记录日志 + * User: simajinqiang + * Date: 2018/7/9 + * Time: 11:11 + */ +@Data +@TableName(value = "t_heart_beat_record") +public class HeartBeatRecordEntity extends BaseEntity implements Serializable { + + /** + * 项目名字 + */ + private String projectPath; + /** + * 服务器ip + */ + private String serverIp; + /** + * 进程号 + */ + private Integer processNo; + /** + * 进程开启时间 + */ + private Date processStartTime; + /** + * 心跳当前时间 + */ + private Date heartBeatTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatRecordVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatRecordVO.java new file mode 100644 index 00000000..bea39703 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatRecordVO.java @@ -0,0 +1,36 @@ +package com.gangquan360.smartadmin.module.heartbeat; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 心跳记录日志 + * User: simajinqiang + * Date: 2018/7/9 + * Time: 11:11 + */ +@Data +public class HeartBeatRecordVO implements Serializable { + + private Integer id; + + @ApiModelProperty("项目名字") + private String projectPath; + + @ApiModelProperty("服务器ip") + private String serverIp; + + @ApiModelProperty("进程号") + private Integer processNo; + + @ApiModelProperty("进程开启时间") + private Date processStartTime; + + @ApiModelProperty("心跳当前时间") + private Date heartBeatTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatService.java new file mode 100644 index 00000000..21579985 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/heartbeat/HeartBeatService.java @@ -0,0 +1,91 @@ +package com.gangquan360.smartadmin.module.heartbeat; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.common.heartbeat.AbstractHeartBeatCommand; +import com.gangquan360.smartadmin.common.heartbeat.HeartBeatConfig; +import com.gangquan360.smartadmin.common.heartbeat.HeartBeatLogger; +import com.gangquan360.smartadmin.common.heartbeat.HeartBeatRecordDTO; +import com.gangquan360.smartadmin.config.SmartHeartBeatConfig; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Slf4j +@Service +public class HeartBeatService extends AbstractHeartBeatCommand { + + @Autowired + private HeartBeatRecordDao heartBeatRecordDao; + + @Autowired + private SmartHeartBeatConfig heartBeatConfig; + + @PostConstruct + public void init() { + + HeartBeatConfig config = HeartBeatConfig.builder().delayHandlerTime(heartBeatConfig.getDelayHandlerTime()).intervalTime(heartBeatConfig.getIntervalTime()).build(); + + super.init(config, new HeartBeatLogger() { + @Override + public void error(String string) { + log.error(string); + } + + @Override + public void error(String string, Throwable e) { + log.error(string, e); + } + + @Override + public void info(String string) { + log.info(string); + } + }); + } + + @PreDestroy + @Override + public void destroy() { + super.destroy(); + } + + @Override + public void handler(HeartBeatRecordDTO heartBeatRecordDTO) { + HeartBeatRecordEntity heartBeatRecordEntity = SmartBeanUtil.copy(heartBeatRecordDTO, HeartBeatRecordEntity.class); + HeartBeatRecordEntity heartBeatRecordOld = heartBeatRecordDao.query(heartBeatRecordEntity); + if (heartBeatRecordOld == null) { + heartBeatRecordDao.insertHeartBeat(heartBeatRecordEntity); + } else { + heartBeatRecordDao.updateHeartBeatTimeById(heartBeatRecordOld.getId(), heartBeatRecordEntity.getHeartBeatTime()); + } + + } + + public ResponseDTO> pageQuery(PageParamDTO pageParamDTO) { + Page pageQueryInfo = SmartPaginationUtil.convert2PageQueryInfo(pageParamDTO); + List recordVOList = heartBeatRecordDao.pageQuery(pageQueryInfo); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(pageQueryInfo, recordVOList); + return ResponseDTO.succData(pageResultDTO); + + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/IdGeneratorDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/IdGeneratorDao.java new file mode 100644 index 00000000..c2e31e45 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/IdGeneratorDao.java @@ -0,0 +1,37 @@ +package com.gangquan360.smartadmin.module.idgenerator; + + +import com.gangquan360.smartadmin.module.idgenerator.domain.IdGeneratorEntity; +import com.gangquan360.smartadmin.module.idgenerator.domain.IdGeneratorLastNumberDTO; +import com.gangquan360.smartadmin.module.idgenerator.domain.IdGeneratorRecordDTO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * + * zhuo + */ +@Mapper +public interface IdGeneratorDao { + + IdGeneratorLastNumberDTO selectLastNumber(Long id); + + List selectAll(); + + void updateLastNumber(@Param("generatorId") Long generatorId, @Param("lastNumber") Long lastNumber); + + int replaceIdGeneratorRecord(@Param("generatorId") Long generatorId,// + @Param("year") int year,// + @Param("month") int month,// + @Param("day") int day,// + @Param("lastNumber") Long lastNumber); + + IdGeneratorRecordDTO selectHistoryLastNumber(@Param("generatorId") Long generatorId, + @Param("year") int year, + @Param("month") int month, + @Param("day") int day); + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/IdGeneratorManager.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/IdGeneratorManager.java new file mode 100644 index 00000000..de976b3b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/IdGeneratorManager.java @@ -0,0 +1,66 @@ +package com.gangquan360.smartadmin.module.idgenerator; + +import com.gangquan360.smartadmin.common.exception.SmartBusinessException; +import com.gangquan360.smartadmin.module.idgenerator.domain.IdGeneratorLastNumberDTO; +import com.gangquan360.smartadmin.module.idgenerator.domain.IdGeneratorPOJO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.Date; + +/** + * 全局id生成器 + * zhuo + */ +@Service +public class IdGeneratorManager { + + @Autowired + private IdGeneratorDao idGeneratorDao; + + @Transactional(rollbackFor = Exception.class) + public long[] generate(IdGeneratorPOJO idGeneratorPOJO, int stepLength) { + IdGeneratorLastNumberDTO idGeneratorLastNumberDTO = idGeneratorDao.selectLastNumber(idGeneratorPOJO.getIdGeneratorEntity().getId()); + if (idGeneratorLastNumberDTO == null) { + throw new SmartBusinessException("IdGenerator, id 数据库不存在" + idGeneratorPOJO.getIdGeneratorEntity().getId()); + } + + Long lastNumber = idGeneratorLastNumberDTO.getLastNumber(); + if (lastNumber == null) { + lastNumber = idGeneratorPOJO.getIdGeneratorEntity().getInitNumber(); + } else { + lastNumber = lastNumber + 1; + } + + Date updateTime = idGeneratorLastNumberDTO.getUpdateTime(); + if (updateTime == null) { + updateTime = idGeneratorLastNumberDTO.getDatabaseTime(); + } + + Long startValue = -1L, endValue = -1L; + switch (idGeneratorPOJO.getIdGeneratorRuleTypeEnum()) { + case NO_CYCLE: + startValue = lastNumber.longValue(); + endValue = startValue + stepLength; + break; + default: + SimpleDateFormat format = new SimpleDateFormat(idGeneratorPOJO.getIdGeneratorRuleTypeEnum().getExt()); + if (format.format(idGeneratorLastNumberDTO.getDatabaseTime()).equals(format.format(updateTime))) { + startValue = lastNumber.longValue(); + endValue = startValue + stepLength; + } else { + startValue = idGeneratorPOJO.getIdGeneratorEntity().getInitNumber(); + endValue = startValue + stepLength; + } + break; + } + + idGeneratorDao.updateLastNumber(idGeneratorPOJO.getIdGeneratorEntity().getId(), endValue - 1); + LocalDate localDate = LocalDate.now(); + idGeneratorDao.replaceIdGeneratorRecord(idGeneratorPOJO.getIdGeneratorEntity().getId(), localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth(), endValue - 1); + return new long[]{startValue, endValue}; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/IdGeneratorService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/IdGeneratorService.java new file mode 100644 index 00000000..079c6a41 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/IdGeneratorService.java @@ -0,0 +1,140 @@ +package com.gangquan360.smartadmin.module.idgenerator; + +import com.gangquan360.smartadmin.common.exception.SmartBusinessException; +import com.gangquan360.smartadmin.module.idgenerator.constant.IdGeneratorEnum; +import com.gangquan360.smartadmin.module.idgenerator.constant.IdGeneratorRuleTypeEnum; +import com.gangquan360.smartadmin.module.idgenerator.domain.IdGeneratorEntity; +import com.gangquan360.smartadmin.module.idgenerator.domain.IdGeneratorPOJO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 全局id生成器 + * zhuo + */ +@Slf4j +@Service +public class IdGeneratorService { + + private Map idGeneratorMap; + + @Autowired + private IdGeneratorDao idGeneratorDao; + + @Autowired + private IdGeneratorManager idGeneratorManager; + + @PostConstruct + void init() { + this.idGeneratorMap = new ConcurrentHashMap<>(); + List idGeneratorEntities = idGeneratorDao.selectAll(); + if (idGeneratorEntities != null) { + idGeneratorEntities.forEach(e -> { + IdGeneratorRuleTypeEnum idGeneratorRuleTypeEnum = this.getIdGeneratorRuleTypeEnum(e.getRuleType()); + if (idGeneratorRuleTypeEnum != null) { + IdGeneratorPOJO idGeneratorPOJO = new IdGeneratorPOJO(idGeneratorRuleTypeEnum, e); + String ruleFormat = e.getRuleFormat(); + int startNInx = ruleFormat.indexOf("[n"); + int endNInx = ruleFormat.indexOf("n]"); + idGeneratorPOJO.setNumberCount(endNInx - startNInx); + idGeneratorPOJO.setHaveDay(ruleFormat.contains("[dd]")); + idGeneratorPOJO.setHaveMonth(ruleFormat.contains("[mm]")); + idGeneratorPOJO.setHaveYear(ruleFormat.contains("[yyyy]")); + this.idGeneratorMap.put(e.getId(), idGeneratorPOJO); + } else { + log.error("cannot find rule type , id : {}, key name : {} ", e.getId(), e.getKeyName()); + } + }); + } + } + + public String generate(IdGeneratorEnum idGeneratorEnum) { + return generate(idGeneratorEnum, 1).get(0); + } + + /** + * @param idGeneratorEnum + * @param stepLength + * @return + */ + public List generate(IdGeneratorEnum idGeneratorEnum, int stepLength) { + IdGeneratorPOJO idGeneratorPOJO = validateParams(idGeneratorEnum, stepLength); + long[] generateIds = idGeneratorManager.generate(idGeneratorPOJO, stepLength); + Long startValue = generateIds[0], endValue = generateIds[1]; + LocalDate now = LocalDate.now(); + String year = String.valueOf(now.getYear()); + String month = now.getMonthValue() > 9 ? String.valueOf(now.getMonthValue()) : "0" + now.getMonthValue(); + String day = now.getDayOfMonth() > 9 ? String.valueOf(now.getDayOfMonth()) : "0" + now.getDayOfMonth(); + ArrayList codeList = new ArrayList<>(); + for (long loop = startValue; loop < endValue; loop++) { + String generateBillCode = this.replaceAndFill(idGeneratorPOJO, loop, year, month, day); + codeList.add(generateBillCode); + } + return codeList; + } + + private IdGeneratorRuleTypeEnum getIdGeneratorRuleTypeEnum(String ruleType) { + for (IdGeneratorRuleTypeEnum en : IdGeneratorRuleTypeEnum.values()) { + if (en.name().equalsIgnoreCase(ruleType)) { + return en; + } + } + return null; + } + + private IdGeneratorPOJO validateParams(IdGeneratorEnum idGeneratorEnum, int stepLength) { + if (stepLength < 1) { + throw new SmartBusinessException("IdGenerator, step过短" + stepLength); + } + + IdGeneratorPOJO idGeneratorPOJO = this.idGeneratorMap.get(idGeneratorEnum.getId()); + if (idGeneratorPOJO == null) { + throw new SmartBusinessException("IdGenerator, id 不存在" + idGeneratorEnum); + } + return idGeneratorPOJO; + } + + /** + * 替换特殊rule,即替换[yyyy][mm][dd][nnn]等规则 + */ + private String replaceAndFill(IdGeneratorPOJO idGeneratorPOJO, Long number, String year, String month, String day) { + StringBuilder numberStringBuilder = new StringBuilder(); + int curNumberCount = String.valueOf(number).length(); + + if (idGeneratorPOJO.getNumberCount() > curNumberCount) { + int remain = idGeneratorPOJO.getNumberCount() - curNumberCount; + for (int i = 0; i < remain; i++) { + numberStringBuilder.append(0); + } + } + numberStringBuilder.append(number); + + StringBuilder nStringBuilder = new StringBuilder(); + nStringBuilder.append("\\["); + for (int i = 0; i < idGeneratorPOJO.getNumberCount(); i++) { + nStringBuilder.append("n"); + } + nStringBuilder.append("\\]"); + + String tempRuleFormat = new String(idGeneratorPOJO.getIdGeneratorEntity().getRuleFormat().getBytes()); + if (idGeneratorPOJO.isHaveYear()) { + tempRuleFormat = tempRuleFormat.replaceAll("\\[yyyy\\]", year); + } + if (idGeneratorPOJO.isHaveMonth()) { + tempRuleFormat = tempRuleFormat.replaceAll("\\[mm\\]", month); + } + if (idGeneratorPOJO.isHaveDay()) { + tempRuleFormat = tempRuleFormat.replaceAll("\\[dd\\]", day); + } + + return tempRuleFormat.replaceAll(nStringBuilder.toString(), numberStringBuilder.toString()); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/constant/IdGeneratorEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/constant/IdGeneratorEnum.java new file mode 100644 index 00000000..9d72dda2 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/constant/IdGeneratorEnum.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.module.idgenerator.constant; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/8 0008 下午 13:43 + * @since JDK1.8 + */ +public enum IdGeneratorEnum { + + + /** + * 测试generate + */ + TEST_ID_GENERATOR(2, "testIdGenerator"), + + + ORDER(1, "order"); + + private int id; + private String keyName; + + IdGeneratorEnum(int id, String keyName) { + this.id = id; + this.keyName = keyName; + } + + @Override + public String toString() { + return "IdGeneratorEnum{" + "id=" + id + ", keyName='" + keyName + '\'' + '}'; + } + + public int getId() { + return id; + } + + public String getKeyName() { + return keyName; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/constant/IdGeneratorRuleTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/constant/IdGeneratorRuleTypeEnum.java new file mode 100644 index 00000000..d087354b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/constant/IdGeneratorRuleTypeEnum.java @@ -0,0 +1,40 @@ +package com.gangquan360.smartadmin.module.idgenerator.constant; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/8 0008 下午 13:43 + * @since JDK1.8 + */ +public enum IdGeneratorRuleTypeEnum { + /** + * 没有周期 + */ + NO_CYCLE(""), + /** + * 年周期 + */ + YEAR_CYCLE("yyyy"), + /** + * 月周期 + */ + MONTH_CYCLE("yyyyMM"), + /** + * 日周期 + */ + DAY_CYCLE("yyyyMMdd"); + + private String ext; + + IdGeneratorRuleTypeEnum(String ext) { + this.ext = ext; + } + + public String getExt() { + return ext; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorEntity.java new file mode 100644 index 00000000..a245ff53 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorEntity.java @@ -0,0 +1,47 @@ +package com.gangquan360.smartadmin.module.idgenerator.domain; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author sun + * @Auther: anders + * @Date: 2018/8/7 0007 13:33 + * @Description: + */ +@Data +@TableName(value = "t_id_generator") +public class IdGeneratorEntity extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 5582354131134766548L; + /** + * 英文key + */ + private String keyName; + /** + * 规则格式 + */ + private String ruleFormat; + /** + * 类型 + */ + private String ruleType; + /** + * 初始值 + */ + private Long initNumber; + /** + * 上次产生的id + */ + private Long lastNumber; + /** + * 备注 + */ + private String remark; + private Date updateTime; + private Date createTime; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorLastNumberDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorLastNumberDTO.java new file mode 100644 index 00000000..771c7b96 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorLastNumberDTO.java @@ -0,0 +1,38 @@ +package com.gangquan360.smartadmin.module.idgenerator.domain; + +import java.util.Date; + +/** + * @Auther: yandanyang + * @Date: 2018/8/7 0007 13:33 + * @Description: + */ +public class IdGeneratorLastNumberDTO { + private Date updateTime; + private Long lastNumber; + private Date databaseTime; + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public Long getLastNumber() { + return lastNumber; + } + + public void setLastNumber(Long lastNumber) { + this.lastNumber = lastNumber; + } + + public Date getDatabaseTime() { + return databaseTime; + } + + public void setDatabaseTime(Date databaseTime) { + this.databaseTime = databaseTime; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorPOJO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorPOJO.java new file mode 100644 index 00000000..210bfc26 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorPOJO.java @@ -0,0 +1,71 @@ +package com.gangquan360.smartadmin.module.idgenerator.domain; + +import com.gangquan360.smartadmin.module.idgenerator.constant.IdGeneratorRuleTypeEnum; + +/** + * @Auther: yandanyang + * @Date: 2018/8/7 0007 13:33 + * @Description: + */ +public class IdGeneratorPOJO { + + private IdGeneratorRuleTypeEnum idGeneratorRuleTypeEnum; + private IdGeneratorEntity idGeneratorEntity; + private int numberCount = 0; + private boolean haveYear = false; + private boolean haveMonth = false; + private boolean haveDay = false; + + public IdGeneratorPOJO(IdGeneratorRuleTypeEnum idGeneratorRuleTypeEnum, IdGeneratorEntity idGeneratorEntity) { + this.idGeneratorRuleTypeEnum = idGeneratorRuleTypeEnum; + this.idGeneratorEntity = idGeneratorEntity; + } + + public IdGeneratorRuleTypeEnum getIdGeneratorRuleTypeEnum() { + return idGeneratorRuleTypeEnum; + } + + public void setIdGeneratorRuleTypeEnum(IdGeneratorRuleTypeEnum idGeneratorRuleTypeEnum) { + this.idGeneratorRuleTypeEnum = idGeneratorRuleTypeEnum; + } + + public IdGeneratorEntity getIdGeneratorEntity() { + return idGeneratorEntity; + } + + public void setIdGeneratorEntity(IdGeneratorEntity idGeneratorEntity) { + this.idGeneratorEntity = idGeneratorEntity; + } + + public int getNumberCount() { + return numberCount; + } + + public void setNumberCount(int numberCount) { + this.numberCount = numberCount; + } + + public boolean isHaveYear() { + return haveYear; + } + + public void setHaveYear(boolean haveYear) { + this.haveYear = haveYear; + } + + public boolean isHaveMonth() { + return haveMonth; + } + + public void setHaveMonth(boolean haveMonth) { + this.haveMonth = haveMonth; + } + + public boolean isHaveDay() { + return haveDay; + } + + public void setHaveDay(boolean haveDay) { + this.haveDay = haveDay; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorRecordDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorRecordDTO.java new file mode 100644 index 00000000..3e13344c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/idgenerator/domain/IdGeneratorRecordDTO.java @@ -0,0 +1,22 @@ +package com.gangquan360.smartadmin.module.idgenerator.domain; + +import lombok.Data; + +/** + * @Auther: yandanyang + * @Date: 2018/8/7 0007 13:33 + * @Description: + */ +@Data +public class IdGeneratorRecordDTO { + + private Long generatorId; + + private Integer year; + + private Integer month; + + private Integer day; + + private Long lastNumber; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/LogService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/LogService.java new file mode 100644 index 00000000..06df389e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/LogService.java @@ -0,0 +1,75 @@ +package com.gangquan360.smartadmin.module.log; + +import com.gangquan360.smartadmin.module.log.orderoperatelog.OrderOperateLogDao; +import com.gangquan360.smartadmin.module.log.orderoperatelog.domain.entity.OrderOperateLogEntity; +import com.gangquan360.smartadmin.module.log.userloginlog.UserLoginLogDao; +import com.gangquan360.smartadmin.module.log.userloginlog.domain.UserLoginLogEntity; +import com.gangquan360.smartadmin.module.log.useroperatelog.UserOperateLogDao; +import com.gangquan360.smartadmin.module.log.useroperatelog.domain.UserOperateLogEntity; +import com.gangquan360.smartadmin.util.SmartThreadFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/4 0004 下午 16:19 + * @since JDK1.8 + */ +@Slf4j +@Service +public class LogService { + + private ThreadPoolExecutor threadPoolExecutor; + + @Autowired + private UserLoginLogDao userLoginLogDao; + + @Autowired + private OrderOperateLogDao orderOperateLogDao; + + @Autowired + private UserOperateLogDao userOperateLogDao; + + @PostConstruct + void init() { + if (threadPoolExecutor == null) { + threadPoolExecutor = new ThreadPoolExecutor(1, 1, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(2000), SmartThreadFactory.create("LogAspect")); + } + } + + @PreDestroy + void destroy() { + if (threadPoolExecutor != null) { + threadPoolExecutor.shutdown(); + threadPoolExecutor = null; + } + } + + public void addLog(Object object) { + try { + if (object instanceof UserLoginLogEntity) { + threadPoolExecutor.execute(() -> userLoginLogDao.insert((UserLoginLogEntity) object)); + } + if (object instanceof OrderOperateLogEntity) { + threadPoolExecutor.execute(() -> orderOperateLogDao.insert((OrderOperateLogEntity) object)); + } + if (object instanceof UserOperateLogEntity) { + threadPoolExecutor.execute(() -> userOperateLogDao.insert((UserOperateLogEntity) object)); + } + } catch (Throwable e) { + log.error("userLogAfterAdvice:{}", e); + } + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/OrderOperateLogController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/OrderOperateLogController.java new file mode 100644 index 00000000..2d847080 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/OrderOperateLogController.java @@ -0,0 +1,44 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.log.orderoperatelog.constant.OrderOperateLogOrderTypeEnum; +import com.gangquan360.smartadmin.module.log.orderoperatelog.domain.vo.OrderOperateLogVO; +import com.gangquan360.smartadmin.util.SmartStringUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 单据操作记录Controller + * + * @author lidoudou + * @date: 2018/1/31 16:56 + */ + +@Api(tags = {SwaggerTagConst.Admin.MANAGER_ORDER_OPERATE_LOG}) +@OperateLog +@RestController +public class OrderOperateLogController { + + @Autowired + private OrderOperateLogService orderOperateLogService; + + @ApiOperation(value = "查询单据操作日志", notes = "查询单据操作日志") + @GetMapping("/orderOperateLog/list/{orderId}") + @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "业务id", paramType = "path"), @ApiImplicitParam(name = "orderType", value = "业务类型" + OrderOperateLogOrderTypeEnum.INFO, paramType + = "query")}) + public ResponseDTO> list(@PathVariable Long orderId, String orderType) { + List orderTypeList = SmartStringUtil.splitConverToIntSet(orderType, ",").stream().collect(Collectors.toList()); + return orderOperateLogService.listOrderOperateLogsByOrderTypeAndOrderId(orderId, orderTypeList); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/OrderOperateLogDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/OrderOperateLogDao.java new file mode 100644 index 00000000..4d075b9e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/OrderOperateLogDao.java @@ -0,0 +1,30 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.gangquan360.smartadmin.module.log.orderoperatelog.domain.entity.OrderOperateLogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + *

+ * 各种单据操作记录 + * Mapper 接口 + *

+ * + * @author anders + * @since 2018-01-09 + */ +@Mapper +@Component +public interface OrderOperateLogDao extends BaseMapper { + + List listOrderOperateLogsByOrderTypeAndOrderId(@Param("orderId") Long orderId, @Param("orderTypeList") List orderTypeList); + + List listOrderOperateLogsByOrderTypeAndOrderIds(@Param("orderIds") List orderIds, @Param("orderTypeList") List orderTypeList); + + void batchInsert(List list); + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/OrderOperateLogService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/OrderOperateLogService.java new file mode 100644 index 00000000..cea07785 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/OrderOperateLogService.java @@ -0,0 +1,63 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog; + +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.log.orderoperatelog.domain.dto.OrderOperateLogSaveDTO; +import com.gangquan360.smartadmin.module.log.orderoperatelog.domain.entity.OrderOperateLogEntity; +import com.gangquan360.smartadmin.module.log.orderoperatelog.domain.vo.OrderOperateLogVO; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartStringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 各种单据操作记录 + * 服务实现类 + *

+ * + * @author anders + * @since 2018-01-09 + */ +@Service +public class OrderOperateLogService { + + @Autowired + private OrderOperateLogDao orderOperateLogDao; + + public void batchSaveOrderOperateLog(List orderOperateLogSaveDTOList) { + List entityList = new ArrayList<>(); + orderOperateLogSaveDTOList.forEach(e -> { + OrderOperateLogEntity orderOperateLogEntity = SmartBeanUtil.copy(e, OrderOperateLogEntity.class); + orderOperateLogEntity.setOperateType(e.getOperateType().getCode()); + if (SmartStringUtil.isNotBlank(e.getOperateContent())) { + orderOperateLogEntity.setOperateContent(e.getOperateContent()); + } else { + orderOperateLogEntity.setOperateContent(e.getOperateType().getMsg()); + } + orderOperateLogEntity.setOperateRemark(e.getOperateRemark()); + orderOperateLogEntity.setExtData(e.getExtData()); + orderOperateLogEntity.setCreateTime(new Date()); + orderOperateLogEntity.setOrderType(e.getOrderType().getType()); + entityList.add(orderOperateLogEntity); + }); + //批量添加 + orderOperateLogDao.batchInsert(entityList); + } + + public ResponseDTO> listOrderOperateLogsByOrderTypeAndOrderId(Long orderId, List orderTypeList) { + List orderOperateLogEntities = orderOperateLogDao.listOrderOperateLogsByOrderTypeAndOrderId(orderId, orderTypeList); + List dtoList = orderOperateLogEntities.stream().map(e -> SmartBeanUtil.copy(e, OrderOperateLogVO.class)).collect(Collectors.toList()); + return ResponseDTO.succData(dtoList); + } + + public ResponseDTO> listOrderOperateLogsByOrderTypeAndOrderIds(List orderIds, List orderTypeList) { + List orderOperateLogEntities = orderOperateLogDao.listOrderOperateLogsByOrderTypeAndOrderIds(orderIds, orderTypeList); + List dtoList = orderOperateLogEntities.stream().map(e -> SmartBeanUtil.copy(e, OrderOperateLogVO.class)).collect(Collectors.toList()); + return ResponseDTO.succData(dtoList); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/constant/OrderOperateLogDefaultEmpEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/constant/OrderOperateLogDefaultEmpEnum.java new file mode 100644 index 00000000..f066be65 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/constant/OrderOperateLogDefaultEmpEnum.java @@ -0,0 +1,37 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog.constant; + +/** + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +public enum OrderOperateLogDefaultEmpEnum { + + DEFAULT_EMP(0,"系统"); + + + private Integer empId; + + private String empName; + + OrderOperateLogDefaultEmpEnum(Integer empId,String empName) { + this.empId = empId; + this.empName = empName; + } + + public int getEmpId() { + return empId; + } + + public String getEmpName() { + return empName; + } + + + +} + diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/constant/OrderOperateLogOperateTypeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/constant/OrderOperateLogOperateTypeConst.java new file mode 100644 index 00000000..66ed165c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/constant/OrderOperateLogOperateTypeConst.java @@ -0,0 +1,30 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog.constant; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + +/** + * [ 8001 -8999 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +public class OrderOperateLogOperateTypeConst extends ResponseCodeConst { + + + public static final OrderOperateLogOperateTypeConst ADD = new OrderOperateLogOperateTypeConst(8001, "创建并提交"); + + public static final OrderOperateLogOperateTypeConst UPDATE = new OrderOperateLogOperateTypeConst(8002, "修改并提交"); + + public static final OrderOperateLogOperateTypeConst DELETE = new OrderOperateLogOperateTypeConst(8003, "删除"); + + + private OrderOperateLogOperateTypeConst(int code, String msg) { + super(code, msg); + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/constant/OrderOperateLogOrderTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/constant/OrderOperateLogOrderTypeEnum.java new file mode 100644 index 00000000..eeb5a3f0 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/constant/OrderOperateLogOrderTypeEnum.java @@ -0,0 +1,51 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog.constant; + +import java.util.Arrays; +import java.util.Optional; + +/** + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +public enum OrderOperateLogOrderTypeEnum { + + EXAMPLE(1, "样例"); + + + public static final String INFO = ""; + + private int type; + + private String typeName; + + OrderOperateLogOrderTypeEnum(int type, String typeName) { + this.type = type; + this.typeName = typeName; + } + + public int getType() { + return type; + } + + public String getTypeName() { + return typeName; + } + + public static OrderOperateLogOrderTypeEnum getValueByName(String name) { + OrderOperateLogOrderTypeEnum[] values = OrderOperateLogOrderTypeEnum.values(); + Optional first = Arrays.stream(values).filter(e -> e.getTypeName().equals(name)).findFirst(); + if (!first.isPresent()) { + return null; + } + if (!first.isPresent()) { + return null; + } + OrderOperateLogOrderTypeEnum orderType = first.get(); + return orderType; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/dto/OrderOperateLogSaveDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/dto/OrderOperateLogSaveDTO.java new file mode 100644 index 00000000..fb82c244 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/dto/OrderOperateLogSaveDTO.java @@ -0,0 +1,79 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog.domain.dto; + + +import com.gangquan360.smartadmin.module.log.orderoperatelog.constant.OrderOperateLogOperateTypeConst; +import com.gangquan360.smartadmin.module.log.orderoperatelog.constant.OrderOperateLogOrderTypeEnum; +import lombok.Data; +/** + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Data +public class OrderOperateLogSaveDTO { + + /** + * 各种单据的id + */ + private Long orderId; + + /** + * 单据类型 + */ + private OrderOperateLogOrderTypeEnum orderType; + + /** + * 操作类型 + */ + private OrderOperateLogOperateTypeConst operateType; + + /** + *操作类型 对应的中文 + */ + private String operateContent; + + /** + * 操作备注 + */ + private String operateRemark; + + /** + * 员工id + */ + private Long employeeId; + + /** + * 员工名称 + */ + private String employeeName; + + /** + * 额外信息 + */ + private String extData; + + public OrderOperateLogSaveDTO() { + } + + public OrderOperateLogSaveDTO(Long orderId, OrderOperateLogOrderTypeEnum orderType, OrderOperateLogOperateTypeConst operateType, String + operateRemark, Long employeeId, String employeeName, String extData) { + this.orderId = orderId; + this.orderType = orderType; + this.operateType = operateType; + this.operateRemark = operateRemark; + this.employeeId = employeeId; + this.employeeName = employeeName; + this.extData = extData; + } + + @Override + public String toString() { + return "OrderOperateLogSaveDTO{" + "orderId=" + orderId + ", orderType=" + orderType + ", operateType=" + operateType + ", operateRemark='" + + operateRemark + '\'' + ", employeeId=" + employeeId + ", employeeName='" + employeeName + '\'' + ", extData='" + extData + '\'' + '}'; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/dto/SupplierOrderOperateVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/dto/SupplierOrderOperateVO.java new file mode 100644 index 00000000..6329b588 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/dto/SupplierOrderOperateVO.java @@ -0,0 +1,44 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog.domain.dto; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 预存款申请/提取单流水临时文件 + * @author zzr + */ +@Data +public class SupplierOrderOperateVO { + + /** + * 流水类型 + */ + private Integer tradingType; + + /** + * 总重 + */ + private BigDecimal totalWeight; + + /** + * 金额 + */ + private BigDecimal amount; + + /** + * 操作人名称 + */ + private String buyerName; + + /** + * 备注 + */ + private String remark; + + /** + * 创建时间 + */ + private Date createTime; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/entity/OrderOperateLogEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/entity/OrderOperateLogEntity.java new file mode 100644 index 00000000..4836c919 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/entity/OrderOperateLogEntity.java @@ -0,0 +1,60 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Builder; +import lombok.Data; + +import java.util.Date; + +/** + *

+ * 各种单据操作记录 + * + *

+ * + * @author anders + * @since 2018-01-09 + */ + +@Data +@Builder +@TableName("t_order_operate_log") +public class OrderOperateLogEntity extends BaseEntity{ + + /** + * 各种单据的id + */ + private Long orderId; + /** + * 单据类型 + */ + private Integer orderType; + /** + * 操作类型 + */ + private Integer operateType; + /** + * 操作类型 对应的中文 + */ + private String operateContent; + /** + * 操作备注 + */ + private String operateRemark; + /** + * 员工id + */ + private Long employeeId; + /** + * 员工名称 + */ + private String employeeName; + /** + * 额外信息 + */ + private String extData; + + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/vo/OrderOperateLogVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/vo/OrderOperateLogVO.java new file mode 100644 index 00000000..f4d511da --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/orderoperatelog/domain/vo/OrderOperateLogVO.java @@ -0,0 +1,69 @@ +package com.gangquan360.smartadmin.module.log.orderoperatelog.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * @author bhr + * @Description: 操作日志 + * @date 2019/8/28 9:31 + */ +@Data +public class OrderOperateLogVO { + + private Long id; + /** + * 各种单据的id + */ + @ApiModelProperty("各种单据的id") + private Long orderId; + /** + * 单据类型 + */ + @ApiModelProperty("单据类型") + private Integer orderType; + /** + * 操作类型 + */ + @ApiModelProperty("操作类型") + private Integer operateType; + /** + * 操作类型 对应的中文 + */ + @ApiModelProperty("操作类型 对应的中文") + private String operateContent; + /** + * 操作备注 + */ + @ApiModelProperty("操作备注") + private String operateRemark; + @ApiModelProperty("操作备注,包含审批人名使用别名显示") + private String operateSecondRemark; + /** + * 员工id + */ + @ApiModelProperty("员工id") + private Long employeeId; + /** + * 员工名称 + */ + @ApiModelProperty("员工名称") + private String employeeName; + /** + * 员工名称 + */ + @ApiModelProperty("员工别名") + private String employeeSecondName; + /** + * 额外信息 + */ + @ApiModelProperty("额外信息") + private String extData; + /** + * 创建时间 + */ + @ApiModelProperty("创建时间") + private Date createTime; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/UserLoginLogController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/UserLoginLogController.java new file mode 100644 index 00000000..dcfea4fa --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/UserLoginLogController.java @@ -0,0 +1,54 @@ +package com.gangquan360.smartadmin.module.log.userloginlog; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeQueryDTO; +import com.gangquan360.smartadmin.module.employee.domain.vo.EmployeeVO; +import com.gangquan360.smartadmin.module.log.userloginlog.domain.UserLoginLogDTO; +import com.gangquan360.smartadmin.module.log.userloginlog.domain.UserLoginLogQueryDTO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * [ 用户登录日志 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-05-15 10:25:21 + * @since JDK1.8 + */ +@RestController +@Api(tags = {SwaggerTagConst.Admin.MANAGER_USER_LOGIN_LOG}) +@OperateLog +public class UserLoginLogController { + + @Autowired + private UserLoginLogService userLoginLogService; + + @ApiOperation(value = "分页查询用户登录日志", notes = "@author yandanyang") + @PostMapping("/userLoginLog/page/query") + public ResponseDTO> queryByPage(@RequestBody UserLoginLogQueryDTO queryDTO) { + return userLoginLogService.queryByPage(queryDTO); + } + + @ApiOperation(value = "删除用户登录日志", notes = "@author yandanyang") + @GetMapping("/userLoginLog/delete/{id}") + public ResponseDTO delete(@PathVariable("id") Long id) { + return userLoginLogService.delete(id); + } + + @ApiOperation(value = "查询员工在线状态", notes = "@author zzr") + @PostMapping("/userOnLine/query") + public ResponseDTO> queryUserOnLine(@RequestBody @Valid EmployeeQueryDTO queryDTO) { + return userLoginLogService.queryUserOnLine(queryDTO); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/UserLoginLogDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/UserLoginLogDao.java new file mode 100644 index 00000000..2392bc96 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/UserLoginLogDao.java @@ -0,0 +1,47 @@ +package com.gangquan360.smartadmin.module.log.userloginlog; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.pagination.Pagination; +import com.gangquan360.smartadmin.module.log.userloginlog.domain.UserLoginLogQueryDTO; +import com.gangquan360.smartadmin.module.log.userloginlog.domain.UserLoginLogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ 用户登录日志 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-05-15 10:25:21 + * @since JDK1.8 + */ +@Mapper +@Component +public interface UserLoginLogDao extends BaseMapper { + + /** + * 分页查询 + * @param queryDTO + * @return UserLoginLogEntity + */ + List queryByPage(Pagination page, @Param("queryDTO") UserLoginLogQueryDTO queryDTO); + + /** + * 根据id删除 + * @param id + * @return + */ + void deleteById(@Param("id") Long id); + + /** + * 批量删除 + * @param idList + * @return + */ + void deleteByIds(@Param("idList") List idList); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/UserLoginLogService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/UserLoginLogService.java new file mode 100644 index 00000000..083e0f73 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/UserLoginLogService.java @@ -0,0 +1,82 @@ +package com.gangquan360.smartadmin.module.log.userloginlog; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.employee.EmployeeService; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeQueryDTO; +import com.gangquan360.smartadmin.module.employee.domain.vo.EmployeeVO; +import com.gangquan360.smartadmin.module.log.userloginlog.domain.UserLoginLogDTO; +import com.gangquan360.smartadmin.module.log.userloginlog.domain.UserLoginLogEntity; +import com.gangquan360.smartadmin.module.log.userloginlog.domain.UserLoginLogQueryDTO; +import com.gangquan360.smartadmin.module.websocket.WebSocketServer; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * [ 用户登录日志 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-05-15 10:25:21 + * @since JDK1.8 + */ +@Service +public class UserLoginLogService { + + @Autowired + private UserLoginLogDao userLoginLogDao; + + @Autowired + private EmployeeService employeeService; + + /** + * @author yandanyang + * @description 分页查询 + * @date 2019-05-15 10:25:21 + */ + public ResponseDTO> queryByPage(UserLoginLogQueryDTO queryDTO) { + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List entities = userLoginLogDao.queryByPage(page, queryDTO); + List dtoList = SmartBeanUtil.copyList(entities, UserLoginLogDTO.class); + page.setRecords(dtoList); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * @author yandanyang + * @description 删除 + * @date 2019-05-15 10:25:21 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO delete(Long id) { + userLoginLogDao.deleteById(id); + return ResponseDTO.succ(); + } + + /** + * 查询员工在线状态 + * + * @param queryDTO + * @return + */ + public ResponseDTO> queryUserOnLine(EmployeeQueryDTO queryDTO) { + List onLineUserList = WebSocketServer.getOnLineUserList(); + if (CollectionUtils.isEmpty(onLineUserList)) { + return ResponseDTO.succ(); + } + queryDTO.setEmployeeIds(onLineUserList); + ResponseDTO> employeeList = employeeService.selectEmployeeList(queryDTO); + return employeeList; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/domain/UserLoginLogDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/domain/UserLoginLogDTO.java new file mode 100644 index 00000000..9b0118d4 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/domain/UserLoginLogDTO.java @@ -0,0 +1,53 @@ +package com.gangquan360.smartadmin.module.log.userloginlog.domain; +import lombok.Data; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; + +/** + * [ 用户登录日志 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 12:27 + * @since JDK1.8 + */ +@Data +public class UserLoginLogDTO { + + @ApiModelProperty("主键") + private Long id; + + @ApiModelProperty("员工id") + private Long userId; + + @ApiModelProperty("用户名") + private String userName; + + @ApiModelProperty("用户ip") + private String remoteIp; + + @ApiModelProperty("用户端口") + private Integer remotePort; + + @ApiModelProperty("浏览器") + private String remoteBrowser; + + @ApiModelProperty("操作系统") + private String remoteOs; + + @ApiModelProperty("登录状态") + private Integer loginStatus; + + @ApiModelProperty("更新时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date updateTime; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/domain/UserLoginLogEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/domain/UserLoginLogEntity.java new file mode 100644 index 00000000..5e04165d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/domain/UserLoginLogEntity.java @@ -0,0 +1,60 @@ +package com.gangquan360.smartadmin.module.log.userloginlog.domain; +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.*; + + +/** + * [ 用户登录日志] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-05-15 10:25:21 + * @since JDK1.8 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("t_user_login_log") +public class UserLoginLogEntity extends BaseEntity{ + + /** + * 员工id + */ + private Long userId; + + /** + * 用户名 + */ + private String userName; + /** + * 用户ip + */ + private String remoteIp; + + /** + * 用户端口 + */ + private Integer remotePort; + + /** + * 浏览器 + */ + private String remoteBrowser; + + /** + * 操作系统 + */ + private String remoteOs; + + /** + * 登录状态 + */ + private Integer loginStatus; + + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/domain/UserLoginLogQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/domain/UserLoginLogQueryDTO.java new file mode 100644 index 00000000..02cb5ad2 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/userloginlog/domain/UserLoginLogQueryDTO.java @@ -0,0 +1,31 @@ +package com.gangquan360.smartadmin.module.log.userloginlog.domain; + +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ 用户登录日志 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-05-15 10:25:21 + * @since JDK1.8 + */ +@Data +public class UserLoginLogQueryDTO extends PageParamDTO { + + + @ApiModelProperty("开始日期") + private String startDate; + + @ApiModelProperty("结束日期") + private String endDate; + + + @ApiModelProperty("用户名") + private String userName; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/UserOperateLogController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/UserOperateLogController.java new file mode 100644 index 00000000..a2f48f69 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/UserOperateLogController.java @@ -0,0 +1,50 @@ +package com.gangquan360.smartadmin.module.log.useroperatelog; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.log.useroperatelog.domain.UserOperateLogDTO; +import com.gangquan360.smartadmin.module.log.useroperatelog.domain.UserOperateLogQueryDTO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-05-15 11:32:14 + * @since JDK1.8 + */ +@RestController +@Api(tags = {SwaggerTagConst.Admin.MANAGER_USER_OPERATE_LOG}) +@OperateLog +public class UserOperateLogController { + + @Autowired + private UserOperateLogService userOperateLogService; + + @ApiOperation(value = "分页查询",notes = "@author yandanyang") + @PostMapping("/userOperateLog/page/query") + public ResponseDTO> queryByPage(@RequestBody UserOperateLogQueryDTO queryDTO) { + return userOperateLogService.queryByPage(queryDTO); + } + + @ApiOperation(value="删除",notes = "@author yandanyang") + @GetMapping("/userOperateLog/delete/{id}") + public ResponseDTO delete(@PathVariable("id") Long id){ + return userOperateLogService.delete(id); + } + + + @ApiOperation(value="详情",notes = "@author yandanyang") + @GetMapping("/userOperateLog/detail/{id}") + public ResponseDTO detail(@PathVariable("id") Long id){ + return userOperateLogService.detail(id); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/UserOperateLogDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/UserOperateLogDao.java new file mode 100644 index 00000000..9441a474 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/UserOperateLogDao.java @@ -0,0 +1,47 @@ +package com.gangquan360.smartadmin.module.log.useroperatelog; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.pagination.Pagination; +import com.gangquan360.smartadmin.module.log.useroperatelog.domain.UserOperateLogQueryDTO; +import com.gangquan360.smartadmin.module.log.useroperatelog.domain.UserOperateLogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-05-15 11:32:14 + * @since JDK1.8 + */ +@Mapper +@Component +public interface UserOperateLogDao extends BaseMapper { + + /** + * 分页查询 + * @param queryDTO + * @return UserOperateLogEntity + */ + List queryByPage(Pagination page, @Param("queryDTO") UserOperateLogQueryDTO queryDTO); + + /** + * 根据id删除 + * @param id + * @return + */ + void deleteById(@Param("id") Long id); + + /** + * 批量删除 + * @param idList + * @return + */ + void deleteByIds(@Param("idList") List idList); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/UserOperateLogService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/UserOperateLogService.java new file mode 100644 index 00000000..f3aba984 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/UserOperateLogService.java @@ -0,0 +1,91 @@ +package com.gangquan360.smartadmin.module.log.useroperatelog; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.log.useroperatelog.domain.UserOperateLogDTO; +import com.gangquan360.smartadmin.module.log.useroperatelog.domain.UserOperateLogEntity; +import com.gangquan360.smartadmin.module.log.useroperatelog.domain.UserOperateLogQueryDTO; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-05-15 11:32:14 + * @since JDK1.8 + */ +@Service +public class UserOperateLogService { + + @Autowired + private UserOperateLogDao userOperateLogDao; + + /** + * @author yandanyang + * @description 分页查询 + * @date 2019-05-15 11:32:14 + */ + public ResponseDTO> queryByPage(UserOperateLogQueryDTO queryDTO) { + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List entities = userOperateLogDao.queryByPage(page, queryDTO); + List dtoList = SmartBeanUtil.copyList(entities, UserOperateLogDTO.class); + page.setRecords(dtoList); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * @author yandanyang + * @description 添加 + * @date 2019-05-15 11:32:14 + */ + public ResponseDTO add(UserOperateLogDTO addDTO) { + UserOperateLogEntity entity = SmartBeanUtil.copy(addDTO, UserOperateLogEntity.class); + userOperateLogDao.insert(entity); + return ResponseDTO.succ(); + } + + /** + * @author yandanyang + * @description 编辑 + * @date 2019-05-15 11:32:14 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO update(UserOperateLogDTO updateDTO) { + UserOperateLogEntity entity = SmartBeanUtil.copy(updateDTO, UserOperateLogEntity.class); + userOperateLogDao.updateById(entity); + return ResponseDTO.succ(); + } + + /** + * @author yandanyang + * @description 删除 + * @date 2019-05-15 11:32:14 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO delete(Long id) { + userOperateLogDao.deleteById(id); + return ResponseDTO.succ(); + } + + /** + * @author yandanyang + * @description 根据ID查询 + * @date 2019-05-15 11:32:14 + */ + public ResponseDTO detail(Long id) { + UserOperateLogEntity entity = userOperateLogDao.selectById(id); + UserOperateLogDTO dto = SmartBeanUtil.copy(entity, UserOperateLogDTO.class); + return ResponseDTO.succData(dto); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/domain/UserOperateLogDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/domain/UserOperateLogDTO.java new file mode 100644 index 00000000..ac23994f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/domain/UserOperateLogDTO.java @@ -0,0 +1,59 @@ +package com.gangquan360.smartadmin.module.log.useroperatelog.domain; +import lombok.Data; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 12:27 + * @since JDK1.8 + */ +@Data +public class UserOperateLogDTO { + + @ApiModelProperty("主键") + private Long id; + + @ApiModelProperty("用户id") + private Long userId; + + @ApiModelProperty("用户名称") + private String userName; + + @ApiModelProperty("操作模块") + private String module; + + @ApiModelProperty("操作内容") + private String content; + + @ApiModelProperty("请求路径") + private String url; + + @ApiModelProperty("请求方法") + private String method; + + @ApiModelProperty("请求参数") + private String param; + + @ApiModelProperty("请求结果 0失败 1成功") + private Integer result; + + @ApiModelProperty("失败原因") + private String failReason; + + @ApiModelProperty("更新时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date updateTime; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/domain/UserOperateLogEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/domain/UserOperateLogEntity.java new file mode 100644 index 00000000..e578dcae --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/domain/UserOperateLogEntity.java @@ -0,0 +1,74 @@ +package com.gangquan360.smartadmin.module.log.useroperatelog.domain; +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-05-15 11:32:14 + * @since JDK1.8 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("t_user_operate_log") +public class UserOperateLogEntity extends BaseEntity{ + + + + /** + * 用户id + */ + private Long userId; + + /** + * 用户名称 + */ + private String userName; + /** + * 操作模块 + */ + private String module; + + /** + * 操作内容 + */ + private String content; + + /** + * 请求路径 + */ + private String url; + + /** + * 请求方法 + */ + private String method; + + /** + * 请求参数 + */ + private String param; + + /** + * 请求结果 0失败 1成功 + */ + private Integer result; + + /** + * 失败原因 + */ + private String failReason; + + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/domain/UserOperateLogQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/domain/UserOperateLogQueryDTO.java new file mode 100644 index 00000000..4995dc6a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/log/useroperatelog/domain/UserOperateLogQueryDTO.java @@ -0,0 +1,34 @@ +package com.gangquan360.smartadmin.module.log.useroperatelog.domain; + +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-05-15 11:32:14 + * @since JDK1.8 + */ +@Data +public class UserOperateLogQueryDTO extends PageParamDTO { + + + @ApiModelProperty("开始日期") + private String startDate; + + @ApiModelProperty("结束日期") + private String endDate; + + + @ApiModelProperty("用户名称") + private String userName; + + @ApiModelProperty("请求结果 0失败 1成功") + private Integer resultFlag; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginController.java new file mode 100644 index 00000000..95022466 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginController.java @@ -0,0 +1,72 @@ +package com.gangquan360.smartadmin.module.login; + +import com.gangquan360.smartadmin.common.anno.NoNeedLogin; +import com.gangquan360.smartadmin.common.anno.NoValidPrivilege; +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeLoginFormDTO; +import com.gangquan360.smartadmin.module.login.domain.KaptchaVO; +import com.gangquan360.smartadmin.module.login.domain.LoginDetailVO; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.util.SmartRequestTokenUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +/** + * 后台登录 + * + * @author lidoudou + * @date 2017年12月19日上午11:46:04 + */ +@RestController +@Api(tags = {SwaggerTagConst.Admin.MANAGER_USER_LOGIN}) +@OperateLog +public class LoginController { + + @Autowired + private LoginService loginService; + + @PostMapping("/session/login") + @ApiOperation(value = "登录", notes = "登录") + @NoNeedLogin + public ResponseDTO login(@Valid @RequestBody EmployeeLoginFormDTO loginForm, HttpServletRequest request) { + return loginService.login(loginForm, request); + } + + + @GetMapping("/session/get") + @ApiOperation(value = "获取session", notes = "获取session") + @NoValidPrivilege + public ResponseDTO getSession() { + RequestTokenBO requestUser = SmartRequestTokenUtil.getRequestUser(); + return ResponseDTO.succData(loginService.getSession(requestUser)); + } + + @GetMapping("/session/logOut") + @ApiOperation(value = "退出登陆", notes = "退出登陆") + @NoValidPrivilege + public ResponseDTO logOut() { + RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser(); + if (null == requestToken) { + return ResponseDTO.wrap(LoginResponseCodeConst.LOGIN_ERROR); + } + return loginService.logoutByToken(requestToken); + } + + @GetMapping("/session/verificationCode") + @ApiOperation(value = "获取验证码", notes = "获取验证码") + @NoNeedLogin + public ResponseDTO verificationCode() { + return loginService.verificationCode(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginResponseCodeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginResponseCodeConst.java new file mode 100644 index 00000000..f12a3a3a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginResponseCodeConst.java @@ -0,0 +1,21 @@ +package com.gangquan360.smartadmin.module.login; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + +/** + * 员工常量类 + * 1001-1999 + * + * @author lidoudou + * @date 2017年12月19日下午19:04:52 + */ +public class LoginResponseCodeConst extends ResponseCodeConst { + + public static final LoginResponseCodeConst LOGIN_ERROR = new LoginResponseCodeConst(1001, "您还未登录或登录失效,请重新登录!"); + + public static final LoginResponseCodeConst NOT_HAVE_PRIVILEGES = new LoginResponseCodeConst(1002, "对不起,您没有权限哦!"); + + public LoginResponseCodeConst(int code, String msg) { + super(code, msg); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginService.java new file mode 100644 index 00000000..220bc7bc --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginService.java @@ -0,0 +1,210 @@ +package com.gangquan360.smartadmin.module.login; + +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.CommonConst; +import com.gangquan360.smartadmin.module.department.DepartmentDao; +import com.gangquan360.smartadmin.module.department.domain.entity.DepartmentEntity; +import com.gangquan360.smartadmin.module.employee.EmployeeDao; +import com.gangquan360.smartadmin.module.employee.constant.EmployeeResponseCodeConst; +import com.gangquan360.smartadmin.module.employee.constant.EmployeeStatusEnum; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeLoginFormDTO; +import com.gangquan360.smartadmin.module.log.LogService; +import com.gangquan360.smartadmin.module.log.userloginlog.domain.UserLoginLogEntity; +import com.gangquan360.smartadmin.module.login.domain.KaptchaVO; +import com.gangquan360.smartadmin.module.login.domain.LoginDetailVO; +import com.gangquan360.smartadmin.module.login.domain.LoginPrivilegeDTO; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.module.privilege.domain.entity.PrivilegeEntity; +import com.gangquan360.smartadmin.module.privilege.service.PrivilegeEmployeeService; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartDigestUtil; +import com.gangquan360.smartadmin.util.SmartIPUtil; +import com.google.code.kaptcha.impl.DefaultKaptcha; +import eu.bitwalker.useragentutils.UserAgent; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Service; + +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 18:10 + * @since JDK1.8 + */ +@Slf4j +@Service +public class LoginService { + + private static final String VERIFICATION_CODE_REDIS_PREFIX = "vc_%s"; + + @Autowired + private EmployeeDao employeeDao; + + @Autowired + private DepartmentDao departmentDao; + + @Autowired + private PrivilegeEmployeeService privilegeEmployeeService; + + @Autowired + private LoginTokenService loginTokenService; + + @Autowired + private LogService logService; + + @Autowired + private DefaultKaptcha defaultKaptcha; + + @Autowired + private ValueOperations redisValueOperations; + + /** + * 登陆 + * + * @param loginForm 登录名 密码 + * @return 登录用户基本信息 + */ + public ResponseDTO login(@Valid EmployeeLoginFormDTO loginForm, HttpServletRequest request) { + String redisVerificationCode = redisValueOperations.get(loginForm.getCodeUuid()); + //增加删除已使用的验证码方式 频繁登录 + redisValueOperations.getOperations().delete(loginForm.getCodeUuid()); + if (StringUtils.isEmpty(redisVerificationCode)) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.VERIFICATION_CODE_INVALID); + } + if (!redisVerificationCode.equalsIgnoreCase(loginForm.getCode())) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.VERIFICATION_CODE_INVALID); + } + String loginPwd = SmartDigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, loginForm.getLoginPwd()); + EmployeeDTO employeeDTO = employeeDao.login(loginForm.getLoginName(), loginPwd); + if (null == employeeDTO) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.LOGIN_FAILED); + } + if (EmployeeStatusEnum.DISABLED.equalsValue(employeeDTO.getIsDisabled())) { + return ResponseDTO.wrap(EmployeeResponseCodeConst.IS_DISABLED); + } + //jwt token赋值 + String compactJws = loginTokenService.generateToken(employeeDTO); + + LoginDetailVO loginDTO = SmartBeanUtil.copy(employeeDTO, LoginDetailVO.class); + + //获取前端功能权限 + loginDTO.setPrivilegeList(initEmployeePrivilege(employeeDTO.getId())); + + loginDTO.setXAccessToken(compactJws); + DepartmentEntity departmentEntity = departmentDao.selectById(employeeDTO.getDepartmentId()); + loginDTO.setDepartmentName(departmentEntity.getName()); + + //判断是否为超管 + Boolean isSuperman = privilegeEmployeeService.isSuperman(loginDTO.getId()); + loginDTO.setIsSuperMan(isSuperman); + //登陆操作日志 + UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent")); + UserLoginLogEntity logEntity = + UserLoginLogEntity.builder() + .userId(employeeDTO.getId()) + .userName(employeeDTO.getActualName()) + .remoteIp(SmartIPUtil.getRemoteIp(request)) + .remotePort(request.getRemotePort()) + .remoteBrowser(userAgent.getBrowser().getName()) + .remoteOs(userAgent.getOperatingSystem().getName()) + .loginStatus(JudgeEnum.YES.getValue()).build(); + logService.addLog(logEntity); + return ResponseDTO.succData(loginDTO); + } + + /** + * 手机端退出登陆,清除token缓存 + * + * @param requestToken + * @return 退出登陆是否成功,bool + */ + public ResponseDTO logoutByToken(RequestTokenBO requestToken) { + privilegeEmployeeService.removeCache(requestToken.getRequestUserId()); + return ResponseDTO.succ(); + } + + /** + * 获取验证码 + * + * @return + */ + public ResponseDTO verificationCode() { + KaptchaVO kaptchaVO = new KaptchaVO(); + String uuid = buildVerificationCodeRedisKey(UUID.randomUUID().toString()); + String kaptchaText = defaultKaptcha.createText(); + + String base64Code = ""; + + BufferedImage image = defaultKaptcha.createImage(kaptchaText); + ByteArrayOutputStream outputStream = null; + try { + outputStream = new ByteArrayOutputStream(); + ImageIO.write(image, "jpg", outputStream); + base64Code = Base64.encodeBase64String(outputStream.toByteArray()); + } catch (Exception e) { + log.error("verificationCode exception .{}", e); + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (Exception e) { + log.error("verificationCode outputStream close exception .{}", e); + } + } + } + kaptchaVO.setUuid(uuid); + kaptchaVO.setCode("data:image/png;base64," + base64Code); + redisValueOperations.set(uuid, kaptchaText, 60L, TimeUnit.SECONDS); + return ResponseDTO.succData(kaptchaVO); + } + + private String buildVerificationCodeRedisKey(String uuid) { + return String.format(VERIFICATION_CODE_REDIS_PREFIX, uuid); + } + + /** + * 初始化员工权限 + * + * @param employeeId + * @return + */ + public List initEmployeePrivilege(Long employeeId) { + List privilegeList = privilegeEmployeeService.getPrivilegesByEmployeeId(employeeId); + privilegeEmployeeService.updateCachePrivilege(employeeId, privilegeList); + return SmartBeanUtil.copyList(privilegeList, LoginPrivilegeDTO.class); + } + + public LoginDetailVO getSession(RequestTokenBO requestUser) { + LoginDetailVO loginDTO = SmartBeanUtil.copy(requestUser.getEmployeeBO(), LoginDetailVO.class); + List privilegeEntityList = privilegeEmployeeService.getEmployeeAllPrivilege(requestUser.getRequestUserId()); + if (privilegeEntityList == null) { + List loginPrivilegeDTOS = initEmployeePrivilege(requestUser.getRequestUserId()); + loginDTO.setPrivilegeList(loginPrivilegeDTOS); + } else { + loginDTO.setPrivilegeList(SmartBeanUtil.copyList(privilegeEntityList, LoginPrivilegeDTO.class)); + } + + //判断是否为超管 + Boolean isSuperman = privilegeEmployeeService.isSuperman(loginDTO.getId()); + loginDTO.setIsSuperMan(isSuperman); + return loginDTO; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginTokenService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginTokenService.java new file mode 100644 index 00000000..80e3ef4a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/LoginTokenService.java @@ -0,0 +1,118 @@ +package com.gangquan360.smartadmin.module.login; + +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import com.gangquan360.smartadmin.module.employee.EmployeeService; +import com.gangquan360.smartadmin.module.employee.constant.EmployeeStatusEnum; +import com.gangquan360.smartadmin.module.employee.domain.bo.EmployeeBO; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.UUID; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Slf4j +@Service +public class LoginTokenService { + + /** + * 过期时间一天 + */ + private static final int EXPIRE_SECONDS = 1 * 24 * 3600; + /** + * jwt加密字段 + */ + private static final String CLAIM_ID_KEY = "id"; + + @Value("${jwt.key}") + private String jwtKey; + + @Autowired + private EmployeeService employeeService; + + + /** + * 功能描述: 生成JWT TOKEN + * + * @param employeeDTO + * @return + * @auther yandanyang + * @date 2018/9/12 0012 上午 10:08 + */ + public String generateToken(EmployeeDTO employeeDTO) { + Long id = employeeDTO.getId(); + /**将token设置为jwt格式*/ + String baseToken = UUID.randomUUID().toString(); + LocalDateTime localDateTimeNow = LocalDateTime.now(); + LocalDateTime localDateTimeExpire = localDateTimeNow.plusSeconds(EXPIRE_SECONDS); + Date from = Date.from(localDateTimeNow.atZone(ZoneId.systemDefault()).toInstant()); + Date expire = Date.from(localDateTimeExpire.atZone(ZoneId.systemDefault()).toInstant()); + + Claims jwtClaims = Jwts.claims().setSubject(baseToken); + jwtClaims.put(CLAIM_ID_KEY, id); + String compactJws = Jwts.builder().setClaims(jwtClaims).setNotBefore(from).setExpiration(expire).signWith(SignatureAlgorithm.HS512, jwtKey).compact(); + + EmployeeBO employeeBO = employeeService.getById(id); + RequestTokenBO tokenBO = new RequestTokenBO(employeeBO); + + return compactJws; + } + + /** + * 功能描述: 根据登陆token获取登陆信息 + * + * @param + * @return + * @auther yandanyang + * @date 2018/9/12 0012 上午 10:11 + */ + public RequestTokenBO getEmployeeTokenInfo(String token) { + Long employeeId = -1L; + try { + Claims claims = Jwts.parser().setSigningKey(jwtKey).parseClaimsJws(token).getBody(); + String idStr = claims.get(CLAIM_ID_KEY).toString(); + employeeId = Long.valueOf(idStr); + } catch (Exception e) { + log.error("getEmployeeTokenInfo error:{}", e); + return null; + } + + EmployeeBO employeeBO = employeeService.getById(employeeId); + if (employeeBO == null) { + return null; + } + + if (EmployeeStatusEnum.DISABLED.getValue().equals(employeeBO.getIsDisabled())) { + return null; + } + + if (JudgeEnum.YES.equals(employeeBO.getIsLeave())) { + return null; + } + + if (JudgeEnum.YES.equals(employeeBO.getIsDelete())) { + return null; + } + + return new RequestTokenBO(employeeBO); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/KaptchaVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/KaptchaVO.java new file mode 100644 index 00000000..ce730e6a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/KaptchaVO.java @@ -0,0 +1,28 @@ +package com.gangquan360.smartadmin.module.login.domain; + +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/4 0004 上午 10:11 + * @since JDK1.8 + */ +@Data +public class KaptchaVO { + + /** + * 验证码UUID + */ + private String uuid; + + /** + * base64 验证码 + */ + private String code; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/LoginCacheDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/LoginCacheDTO.java new file mode 100644 index 00000000..7dd6e9ed --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/LoginCacheDTO.java @@ -0,0 +1,28 @@ +package com.gangquan360.smartadmin.module.login.domain; + +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/9 0009 下午 17:32 + * @since JDK1.8 + */ +@Data +public class LoginCacheDTO { + + /** + * 基本信息 + */ + private EmployeeDTO employeeDTO; + + /** + * 过期时间 + */ + private Long expireTime; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/LoginDetailVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/LoginDetailVO.java new file mode 100644 index 00000000..671fc951 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/LoginDetailVO.java @@ -0,0 +1,70 @@ +package com.gangquan360.smartadmin.module.login.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 登录返回DTO + * + * @author lidoudou + * @date 2017年12月21日上午09:06:31 + */ +@Data +public class LoginDetailVO { + + @ApiModelProperty("主键id") + private Long id; + + @ApiModelProperty("登录账号") + private String loginName; + + @ApiModelProperty("别名") + private String nickName; + + @ApiModelProperty("员工名称") + private String actualName; + + @ApiModelProperty("手机号码") + private String phone; + + @ApiModelProperty("身份证") + private String idCard; + + @ApiModelProperty("出生日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date birthday; + + @ApiModelProperty("创建者id") + private Long createUser; + + @ApiModelProperty("部门id") + private Long departmentId; + + @ApiModelProperty("是否离职") + private Integer isLeave; + + @ApiModelProperty("是否被禁用") + private Integer isDisabled; + + @ApiModelProperty("部门名称") + private String departmentName; + + @ApiModelProperty("邮箱") + private String email; + + @ApiModelProperty("登陆token") + private String xAccessToken; + + @ApiModelProperty("是否为超管") + private Boolean isSuperMan; + + @ApiModelProperty("权限列表") + private List privilegeList; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/LoginPrivilegeDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/LoginPrivilegeDTO.java new file mode 100644 index 00000000..1329964e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/LoginPrivilegeDTO.java @@ -0,0 +1,35 @@ +package com.gangquan360.smartadmin.module.login.domain; + +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.module.privilege.constant.PrivilegeTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/21 0021 上午 10:28 + * @since JDK1.8 + */ +@Data +public class LoginPrivilegeDTO { + + @ApiModelProperty("权限key") + private String key; + + @ApiModelPropertyEnum(enumDesc = "菜单类型",value = PrivilegeTypeEnum.class) + private Integer type; + + @ApiModelProperty("url") + private String url; + + @ApiModelProperty("父级key") + private String parentKey; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/RequestTokenBO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/RequestTokenBO.java new file mode 100644 index 00000000..e4019f6d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/login/domain/RequestTokenBO.java @@ -0,0 +1,26 @@ +package com.gangquan360.smartadmin.module.login.domain; + +import com.gangquan360.smartadmin.module.employee.domain.bo.EmployeeBO; +import lombok.Getter; + + +@Getter +public class RequestTokenBO { + + private Long requestUserId; + + private EmployeeBO employeeBO; + + public RequestTokenBO(EmployeeBO employeeBO) { + this.requestUserId = employeeBO.getId(); + this.employeeBO = employeeBO; + } + + @Override + public String toString() { + return "RequestTokenBO{" + + "requestUserId=" + requestUserId + + ", employeeBO=" + employeeBO + + '}'; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/NoticeController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/NoticeController.java new file mode 100644 index 00000000..28681cc8 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/NoticeController.java @@ -0,0 +1,96 @@ +package com.gangquan360.smartadmin.module.notice; + +import com.gangquan360.smartadmin.common.anno.NoValidPrivilege; +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.notice.domain.dto.*; +import com.gangquan360.smartadmin.util.SmartRequestTokenUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-07-11 16:19:48 + * @since JDK1.8 + */ +@RestController +@Api(tags = {SwaggerTagConst.Admin.MANAGER_NOTICE}) +public class NoticeController { + + @Autowired + private NoticeService noticeService; + + @ApiOperation(value = "分页查询全部消息", notes = "@author yandanyang") + @PostMapping("/notice/page/query") + @NoValidPrivilege + public ResponseDTO> queryByPage(@RequestBody NoticeQueryDTO queryDTO) { + return noticeService.queryByPage(queryDTO); + } + + @ApiOperation(value = "获取已收取的所有消息", notes = "@author yandanyang") + @PostMapping("/notice/receive/page/query") + @NoValidPrivilege + public ResponseDTO> queryReceiveByPage(@RequestBody NoticeReceiveQueryDTO queryDTO) { + return noticeService.queryReceiveByPage(queryDTO, SmartRequestTokenUtil.getRequestUser()); + } + + @ApiOperation(value = "分页查询未读消息", notes = "@author yandanyang") + @PostMapping("/notice/unread/page/query") + @NoValidPrivilege + public ResponseDTO> queryUnreadByPage(@RequestBody PageParamDTO queryDTO) { + return noticeService.queryUnreadByPage(queryDTO, SmartRequestTokenUtil.getRequestUser()); + } + + @ApiOperation(value = "添加", notes = "@author yandanyang") + @PostMapping("/notice/add") + @NoValidPrivilege + public ResponseDTO add(@RequestBody @Valid NoticeAddDTO addTO) { + return noticeService.add(addTO, SmartRequestTokenUtil.getRequestUser()); + } + + @ApiOperation(value = "修改", notes = "@author yandanyang") + @PostMapping("/notice/update") + @NoValidPrivilege + public ResponseDTO update(@RequestBody @Valid NoticeUpdateDTO updateDTO) { + return noticeService.update(updateDTO); + } + + @ApiOperation(value = "删除", notes = "@author yandanyang") + @GetMapping("/notice/delete/{id}") + @NoValidPrivilege + public ResponseDTO delete(@PathVariable("id") Long id) { + return noticeService.delete(id); + } + + @ApiOperation(value = "详情", notes = "@author yandanyang") + @GetMapping("/notice/detail/{id}") + @NoValidPrivilege + public ResponseDTO detail(@PathVariable("id") Long id) { + return noticeService.detail(id); + } + + @ApiOperation(value = "发送", notes = "@author yandanyang") + @GetMapping("/notice/send/{id}") + @NoValidPrivilege + public ResponseDTO send(@PathVariable("id") Long id) { + return noticeService.send(id, SmartRequestTokenUtil.getRequestUser()); + } + + @ApiOperation(value = "读取消息", notes = "@author yandanyang") + @GetMapping("/notice/read/{id}") + @NoValidPrivilege + public ResponseDTO read(@PathVariable("id") Long id) { + return noticeService.read(id, SmartRequestTokenUtil.getRequestUser()); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/NoticeManage.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/NoticeManage.java new file mode 100644 index 00000000..fa26796c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/NoticeManage.java @@ -0,0 +1,96 @@ +package com.gangquan360.smartadmin.module.notice; + +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.module.notice.dao.NoticeDao; +import com.gangquan360.smartadmin.module.notice.dao.NoticeReceiveRecordDao; +import com.gangquan360.smartadmin.module.notice.domain.dto.NoticeUpdateDTO; +import com.gangquan360.smartadmin.module.notice.domain.entity.NoticeEntity; +import com.gangquan360.smartadmin.module.notice.domain.entity.NoticeReceiveRecordEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/13 0013 下午 17:33 + * @since JDK1.8 + */ +@Service +public class NoticeManage { + + @Autowired + private NoticeDao noticeDao; + @Autowired + private NoticeReceiveRecordDao noticeReceiveRecordDao; + + /** + * 发送消息 + * @param entity + * @param requestToken + */ + @Transactional(rollbackFor = Exception.class) + public void send(NoticeEntity entity, RequestTokenBO requestToken){ + + entity.setSendStatus(JudgeEnum.YES.getValue()); + noticeDao.updateById(entity); + //默认发件人 已读此消息 + NoticeReceiveRecordEntity recordEntity = new NoticeReceiveRecordEntity(); + recordEntity.setEmployeeId(requestToken.getRequestUserId()); + recordEntity.setNoticeId(entity.getId()); + recordEntity.setCreateTime(new Date()); + recordEntity.setUpdateTime(new Date()); + noticeReceiveRecordDao.insert(recordEntity); + } + + + /** + * 保存读取记录 + * @param noticeId + * @param requestToken + */ + public void saveReadRecord(Long noticeId, RequestTokenBO requestToken){ + NoticeReceiveRecordEntity recordEntity = new NoticeReceiveRecordEntity(); + recordEntity.setEmployeeId(requestToken.getRequestUserId()); + recordEntity.setNoticeId(noticeId); + recordEntity.setCreateTime(new Date()); + recordEntity.setUpdateTime(new Date()); + noticeReceiveRecordDao.insert(recordEntity); + } + + + /** + * 消息删除 + * @param entity + */ + @Transactional(rollbackFor = Exception.class) + public void delete(NoticeEntity entity) { + if(JudgeEnum.YES.getValue().equals(entity.getSendStatus())){ + //消息已发送 执行逻辑删除 + noticeDao.logicDeleteById(entity.getId(),JudgeEnum.YES.getValue()); + }else{ + //消息未发送 执行真实删除 + noticeDao.deleteById(entity.getId()); + } + } + + /** + * 更新消息 + * @param entity + * @param updateDTO + */ + public void update(NoticeEntity entity,NoticeUpdateDTO updateDTO) { + entity.setTitle(updateDTO.getTitle()); + entity.setContent(updateDTO.getContent()); + entity.setSendStatus(JudgeEnum.NO.getValue()); + entity.setDeleted(JudgeEnum.NO.getValue()); + noticeDao.updateById(entity); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/NoticeService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/NoticeService.java new file mode 100644 index 00000000..b98f1dd0 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/NoticeService.java @@ -0,0 +1,234 @@ +package com.gangquan360.smartadmin.module.notice; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.module.notice.dao.NoticeDao; +import com.gangquan360.smartadmin.module.notice.dao.NoticeReceiveRecordDao; +import com.gangquan360.smartadmin.module.notice.domain.dto.*; +import com.gangquan360.smartadmin.module.notice.domain.entity.NoticeEntity; +import com.gangquan360.smartadmin.module.notice.domain.entity.NoticeReceiveRecordEntity; +import com.gangquan360.smartadmin.module.websocket.WebSocketServer; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-07-11 16:19:48 + * @since JDK1.8 + */ +@Service +public class NoticeService { + + @Autowired + private NoticeDao noticeDao; + + @Autowired + private NoticeReceiveRecordDao noticeReceiveRecordDao; + + @Autowired + private NoticeManage noticeManage; + + /** + * @author yandanyang + * @description 分页查询 + * @date 2019-07-11 16:19:48 + */ + public ResponseDTO> queryByPage(NoticeQueryDTO queryDTO) { + queryDTO.setDeleted(JudgeEnum.NO.getValue()); + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List dtoList = noticeDao.queryByPage(page, queryDTO); + page.setRecords(dtoList); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * 获取当前登录人的消息列表 + * + * @param queryDTO + * @param requestToken + * @return + */ + public ResponseDTO> queryReceiveByPage(NoticeReceiveQueryDTO queryDTO, RequestTokenBO requestToken) { + queryDTO.setEmployeeId(requestToken.getRequestUserId()); + queryDTO.setSendStatus(JudgeEnum.YES.getValue()); + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List dtoList = noticeDao.queryReceiveByPage(page, queryDTO); + dtoList.forEach(e -> { + if (e.getReceiveTime() == null) { + e.setReadStatus(JudgeEnum.NO.getValue()); + } else { + e.setReadStatus(JudgeEnum.YES.getValue()); + } + }); + page.setRecords(dtoList); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * 获取我的未读消息 + * + * @param queryDTO + * @param requestToken + * @return + */ + public ResponseDTO> queryUnreadByPage(PageParamDTO queryDTO, RequestTokenBO requestToken) { + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List dtoList = noticeDao.queryUnreadByPage(page, requestToken.getRequestUserId(), JudgeEnum.YES.getValue()); + page.setRecords(dtoList); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * @author yandanyang + * @description 添加 + * @date 2019-07-11 16:19:48 + */ + public ResponseDTO add(NoticeAddDTO addDTO, RequestTokenBO requestToken) { + NoticeEntity entity = SmartBeanUtil.copy(addDTO, NoticeEntity.class); + entity.setCreateTime(new Date()); + entity.setUpdateTime(new Date()); + entity.setCreateUser(requestToken.getRequestUserId()); + entity.setSendStatus(JudgeEnum.NO.getValue()); + entity.setDeleted(JudgeEnum.NO.getValue()); + noticeDao.insert(entity); + return ResponseDTO.succ(); + } + + /** + * @author yandanyang + * @description 编辑 + * @date 2019-07-11 16:19:48 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO update(NoticeUpdateDTO updateDTO) { + NoticeEntity entity = noticeDao.selectById(updateDTO.getId()); + if (entity == null) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "此系统通知不存在"); + } + if (JudgeEnum.YES.getValue().equals(entity.getSendStatus())) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "此系统通知已发送无法修改"); + } + noticeManage.update(entity, updateDTO); + return ResponseDTO.succ(); + } + + /** + * @author yandanyang + * @description 删除 + * @date 2019-07-11 16:19:48 + */ + public ResponseDTO delete(Long id) { + NoticeEntity entity = noticeDao.selectById(id); + if (entity == null) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "此系统通知不存在"); + } + noticeManage.delete(entity); + return ResponseDTO.succ(); + } + + /** + * @author yandanyang + * @description 根据ID查询 + * @date 2019-07-11 16:19:48 + */ + public ResponseDTO detail(Long id) { + NoticeDetailVO noticeDTO = noticeDao.detail(id); + return ResponseDTO.succData(noticeDTO); + } + + /** + * 获取某人的未读消息数 + * + * @param employeeId + * @return + */ + private Integer getUnreadCount(Long employeeId) { + return noticeDao.noticeUnreadCount(employeeId, JudgeEnum.YES.getValue()); + } + + /** + * 发送给所有在线用户未读消息数 + * + * @param id + * @param requestToken + * @return + */ + public ResponseDTO send(Long id, RequestTokenBO requestToken) { + NoticeEntity entity = noticeDao.selectById(id); + if (entity == null) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "此系统通知不存在"); + } + noticeManage.send(entity, requestToken); + this.sendMessage(requestToken); + return ResponseDTO.succ(); + } + + /** + * 发送系统通知 ,发送人不进行接收,需再事务外调用 以防止数据隔离级别不同造成未读消息数异常 + * + * @param requestToken + */ + private void sendMessage(RequestTokenBO requestToken) { + List onLineEmployeeIds = WebSocketServer.getOnLineUserList(); + if (CollectionUtils.isEmpty(onLineEmployeeIds)) { + return; + } + //在线用户已读消息数 + Map readCountMap = new HashMap<>(); + List readCountList = noticeDao.readCount(onLineEmployeeIds); + if (CollectionUtils.isNotEmpty(readCountList)) { + readCountMap = readCountList.stream().collect(Collectors.toMap(NoticeReadCountDTO :: getEmployeeId, NoticeReadCountDTO :: getReadCount)); + } + //已发送消息数 + Integer noticeCount = noticeDao.noticeCount(JudgeEnum.YES.getValue()); + for (Long employeeId : onLineEmployeeIds) { + Integer readCount = readCountMap.get(employeeId) == null ? 0 : readCountMap.get(employeeId); + Integer unReadCount = noticeCount - readCount; + if (! requestToken.getRequestUserId().equals(employeeId)) { + WebSocketServer.sendOneOnLineUser(unReadCount.toString(), employeeId); + } + } + } + + /** + * 读取消息 + * + * @param id + * @param requestToken + * @return + */ + public ResponseDTO read(Long id, RequestTokenBO requestToken) { + NoticeDetailVO noticeDTO = noticeDao.detail(id); + + NoticeReceiveRecordEntity recordEntity = noticeReceiveRecordDao.selectByEmployeeAndNotice(requestToken.getRequestUserId(), id); + if (recordEntity != null) { + return ResponseDTO.succData(noticeDTO); + } + noticeManage.saveReadRecord(id, requestToken); + this.sendMessage(requestToken); + return ResponseDTO.succData(noticeDTO); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/dao/NoticeDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/dao/NoticeDao.java new file mode 100644 index 00000000..7c3235e9 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/dao/NoticeDao.java @@ -0,0 +1,99 @@ +package com.gangquan360.smartadmin.module.notice.dao; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.pagination.Pagination; +import com.gangquan360.smartadmin.module.notice.domain.dto.*; +import com.gangquan360.smartadmin.module.notice.domain.entity.NoticeEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-07-11 16:19:48 + * @since JDK1.8 + */ +@Mapper +@Component +public interface NoticeDao extends BaseMapper { + + /** + * 分页查询 + * @param queryDTO + * @return NoticeEntity + */ + List queryByPage(Pagination page, @Param("queryDTO") NoticeQueryDTO queryDTO); + + + /** + * 获取某人的未读消息 + * @param page + * @param employeeId + * @return + */ + List queryUnreadByPage(Pagination page, @Param("employeeId") Long employeeId, @Param("sendStatus") Integer sendStatus); + + + /** + * 获取 + * @param page + * @param queryDTO + * @return + */ + List queryReceiveByPage(Pagination page, @Param("queryDTO") NoticeReceiveQueryDTO queryDTO); + + /** + * 详情 + * @param id + * @return + */ + NoticeDetailVO detail(@Param("id") Long id); + + /** + * 根据id删除 逻辑删除 + * @param id + * @param deletedFlag + */ + void logicDeleteById(@Param("id") Long id,@Param("deletedFlag") Integer deletedFlag); + + + + /** + * 批量逻辑删除 + * @param idList + * @param deletedFlag + * @return + */ + void logicDeleteByIds(@Param("idList") List idList,@Param("deletedFlag") Integer deletedFlag); + + /** + * 获取消息总数 + * @return + */ + Integer noticeCount(@Param("sendStatus") Integer sendStatus); + + + /** + * 获取已读消息数 + * @param employeeIds + * @return + */ + List readCount(@Param("employeeIds") List employeeIds); + + + /** + * 获取某人的未读消息数 + * @param employeeId + * @param sendStatus + * @return + */ + Integer noticeUnreadCount(@Param("employeeId") Long employeeId, @Param("sendStatus") Integer sendStatus); + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/dao/NoticeReceiveRecordDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/dao/NoticeReceiveRecordDao.java new file mode 100644 index 00000000..f91bc31f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/dao/NoticeReceiveRecordDao.java @@ -0,0 +1,48 @@ +package com.gangquan360.smartadmin.module.notice.dao; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.gangquan360.smartadmin.module.notice.domain.entity.NoticeReceiveRecordEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-07-11 16:19:48 + * @since JDK1.8 + */ +@Mapper +@Component +public interface NoticeReceiveRecordDao extends BaseMapper { + + /** + * 批量删除 + * + * @param noticeId + * @return + */ + void deleteByNoticeId(@Param("noticeId") Long noticeId); + + /** + * 批量插入 + * + * @param rolePrivilegeList + */ + void batchInsert(List rolePrivilegeList); + + /** + * 根据员工和系统通知获取读取记录 + * + * @param employeeId + * @param noticeId + * @return + */ + NoticeReceiveRecordEntity selectByEmployeeAndNotice(@Param("employeeId") Long employeeId, @Param("noticeId") Long noticeId); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeAddDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeAddDTO.java new file mode 100644 index 00000000..29dc1d1b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeAddDTO.java @@ -0,0 +1,28 @@ +package com.gangquan360.smartadmin.module.notice.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 12:27 + * @since JDK1.8 + */ +@Data +public class NoticeAddDTO { + + @ApiModelProperty("消息标题") + @Length(max = 200) + private String title; + + @ApiModelProperty("消息内容") + @Length(max = 5000) + private String content; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeDetailVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeDetailVO.java new file mode 100644 index 00000000..1083cfc4 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeDetailVO.java @@ -0,0 +1,30 @@ +package com.gangquan360.smartadmin.module.notice.domain.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 12:27 + * @since JDK1.8 + */ +@Data +public class NoticeDetailVO extends NoticeVO { + + + @ApiModelProperty("消息内容") + private String content; + + @ApiModelProperty("更新时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date updateTime; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeQueryDTO.java new file mode 100644 index 00000000..d20ccedd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeQueryDTO.java @@ -0,0 +1,34 @@ +package com.gangquan360.smartadmin.module.notice.domain.dto; + +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date 2019-07-11 16:19:48 + * @since JDK1.8 + */ +@Data +public class NoticeQueryDTO extends PageParamDTO { + + + @ApiModelProperty("开始日期") + private String startDate; + + @ApiModelProperty("结束日期") + private String endDate; + + + @ApiModelProperty("消息标题") + private String title; + + @ApiModelProperty(value = "是否删除",hidden = true) + private Integer deleted; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeReadCountDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeReadCountDTO.java new file mode 100644 index 00000000..e6245d00 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeReadCountDTO.java @@ -0,0 +1,26 @@ +package com.gangquan360.smartadmin.module.notice.domain.dto; + +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/12 0012 上午 8:11 + * @since JDK1.8 + */ +@Data +public class NoticeReadCountDTO { + /** + * 员工id + */ + private Long employeeId; + /** + * 已读消息数 + */ + private Integer readCount; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeReceiveDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeReceiveDTO.java new file mode 100644 index 00000000..055af2b6 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeReceiveDTO.java @@ -0,0 +1,43 @@ +package com.gangquan360.smartadmin.module.notice.domain.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/12 0012 上午 11:53 + * @since JDK1.8 + */ +@Data +public class NoticeReceiveDTO{ + + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("消息标题") + private String title; + + + @ApiModelProperty("消息创建人") + private Long createUser; + + @ApiModelProperty("消息创建人名称") + private String createUserName; + + @ApiModelProperty("结束时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date receiveTime; + + @ApiModelPropertyEnum(enumDesc = "读取状态",value = JudgeEnum.class) + private Integer readStatus; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeReceiveQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeReceiveQueryDTO.java new file mode 100644 index 00000000..2f93b651 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeReceiveQueryDTO.java @@ -0,0 +1,25 @@ +package com.gangquan360.smartadmin.module.notice.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/12 0012 下午 12:32 + * @since JDK1.8 + */ +@Data +public class NoticeReceiveQueryDTO extends NoticeQueryDTO{ + + @ApiModelProperty(value = "当前登录人",hidden = true) + private Long employeeId; + + @ApiModelProperty(value = "发送状态",hidden = true) + private Integer sendStatus; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeUpdateDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeUpdateDTO.java new file mode 100644 index 00000000..48ec9056 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeUpdateDTO.java @@ -0,0 +1,21 @@ +package com.gangquan360.smartadmin.module.notice.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/11 0011 下午 16:24 + * @since JDK1.8 + */ +@Data +public class NoticeUpdateDTO extends NoticeAddDTO{ + + @ApiModelProperty("id") + private Long id; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeVO.java new file mode 100644 index 00000000..de5ab85c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/dto/NoticeVO.java @@ -0,0 +1,42 @@ +package com.gangquan360.smartadmin.module.notice.domain.dto; +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import lombok.Data; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 12:27 + * @since JDK1.8 + */ +@Data +public class NoticeVO { + + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("消息标题") + private String title; + + + @ApiModelProperty("消息创建人") + private Long createUser; + + @ApiModelPropertyEnum(enumDesc = "发送状态",value = JudgeEnum.class) + private Integer sendStatus; + + @ApiModelProperty("消息创建人名称") + private String createUserName; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/entity/NoticeEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/entity/NoticeEntity.java new file mode 100644 index 00000000..782e8ae6 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/entity/NoticeEntity.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.module.notice.domain.entity; +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-07-11 16:19:48 + * @since JDK1.8 + */ +@Data +@TableName("t_notice") +public class NoticeEntity extends BaseEntity { + + /** + * 消息标题 + */ + private String title; + + /** + * 消息内容 + */ + private String content; + + /** + * 消息创建人 + */ + private Long createUser; + + /** + * 发送状态 + */ + private Integer sendStatus; + + /** + * 删除状态 + */ + private Integer deleted; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/entity/NoticeReceiveRecordEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/entity/NoticeReceiveRecordEntity.java new file mode 100644 index 00000000..6af997ea --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/notice/domain/entity/NoticeReceiveRecordEntity.java @@ -0,0 +1,33 @@ +package com.gangquan360.smartadmin.module.notice.domain.entity; +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019-07-11 16:19:48 + * @since JDK1.8 + */ +@Data +@TableName("t_notice_receive_record") +public class NoticeReceiveRecordEntity extends BaseEntity{ + + + /** + * 消息id + */ + private Long noticeId; + + /** + * 消息接收人 + */ + private Long employeeId; + + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionController.java new file mode 100644 index 00000000..548068ca --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionController.java @@ -0,0 +1,59 @@ +package com.gangquan360.smartadmin.module.position; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionAddDTO; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionQueryDTO; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionResultVO; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionUpdateDTO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * @author zzr + */ +@Api(tags = {SwaggerTagConst.Admin.MANAGER_JOB}) +@OperateLog +@RestController +public class PositionController { + + @Autowired + private PositionService positionService; + + @ApiOperation(value = "分页查询所有岗位", notes = "分页查询所有岗位 @author zzr") + @PostMapping("/position/getListPage") + public ResponseDTO> getJobPage(@RequestBody @Valid PositionQueryDTO queryDTO) { + return positionService.queryPositionByPage(queryDTO); + } + + @ApiOperation(value = "添加岗位", notes = "添加岗位 @author zzr") + @PostMapping("/position/add") + public ResponseDTO addJob(@RequestBody @Valid PositionAddDTO addDTO) { + return positionService.addPosition(addDTO); + } + + @ApiOperation(value = "更新岗位", notes = "更新岗位 @author zzr") + @PostMapping("/position/update") + public ResponseDTO updateJob(@RequestBody @Valid PositionUpdateDTO updateDTO) { + return positionService.updatePosition(updateDTO); + } + + @ApiOperation(value = "根据ID查询岗位", notes = "根据ID查询岗位 @author zzr") + @GetMapping("/position/queryById/{id}") + public ResponseDTO queryJobById(@PathVariable Long id) { + return positionService.queryPositionById(id); + } + + @ApiOperation(value = "根据ID删除岗位", notes = "根据ID删除岗位 @author zzr") + @GetMapping("/position/remove/{id}") + public ResponseDTO removeJob(@PathVariable Long id) { + return positionService.removePosition(id); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionDao.java new file mode 100644 index 00000000..ebb0a968 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionDao.java @@ -0,0 +1,56 @@ +package com.gangquan360.smartadmin.module.position; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.pagination.Pagination; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionQueryDTO; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionRelationAddDTO; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionRelationQueryDTO; +import com.gangquan360.smartadmin.module.position.domain.dto.PositionRelationResultDTO; +import com.gangquan360.smartadmin.module.position.domain.entity.PositionEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author zzr + */ +@Mapper +@Component +public interface PositionDao extends BaseMapper { + + /** + * 查询岗位列表 + * + * @param page + * @param queryDTO + * @return + */ + List selectByPage(Pagination page, PositionQueryDTO queryDTO); + + /** + * 查询岗位与人员关系 + * + * @param positionRelationQueryDTO + * @return + */ + List selectRelation(PositionRelationQueryDTO positionRelationQueryDTO); + + /** + * 批量添加岗位 人员 关联关系 + * + * @param positionRelationAddDTO + * @return + */ + Integer insertBatchRelation(@Param("batchDTO")PositionRelationAddDTO positionRelationAddDTO); + + /** + * 删除指定人员的 岗位关联关系 + * + * @param employeeId + * @return + */ + Integer deleteRelationByEmployeeId(@Param("employeeId") Long employeeId); + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionResponseCodeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionResponseCodeConst.java new file mode 100644 index 00000000..5e8d66da --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionResponseCodeConst.java @@ -0,0 +1,16 @@ +package com.gangquan360.smartadmin.module.position; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + +/** + * @author zzr + */ +public class PositionResponseCodeConst extends ResponseCodeConst { + + public static final PositionResponseCodeConst REMOVE_DEFINE = new PositionResponseCodeConst(13000, "还有人关联该岗位,不能删除"); + + protected PositionResponseCodeConst(int code, String msg) { + super(code, msg); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionService.java new file mode 100644 index 00000000..60a7c8db --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/PositionService.java @@ -0,0 +1,124 @@ +package com.gangquan360.smartadmin.module.position; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.position.domain.dto.*; +import com.gangquan360.smartadmin.module.position.domain.entity.PositionEntity; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author zzr + */ +@Service +public class PositionService { + + @Autowired + private PositionDao positionDao; + + /** + * 查询岗位 + * + * @param queryDTO + * @return + */ + public ResponseDTO> queryPositionByPage(PositionQueryDTO queryDTO) { + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List entityList = positionDao.selectByPage(page, queryDTO); + page.setRecords(entityList.stream().map(e -> SmartBeanUtil.copy(e, PositionResultVO.class)).collect(Collectors.toList())); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * 新增岗位 + * + * @param addDTO + * @return + */ + public ResponseDTO addPosition(PositionAddDTO addDTO) { + PositionEntity positionEntity = SmartBeanUtil.copy(addDTO, PositionEntity.class); + positionDao.insert(positionEntity); + return ResponseDTO.succ(); + } + + /** + * 修改岗位 + * + * @param updateDTO + * @return + */ + public ResponseDTO updatePosition(PositionUpdateDTO updateDTO) { + PositionEntity positionEntity = SmartBeanUtil.copy(updateDTO, PositionEntity.class); + positionDao.updateById(positionEntity); + return ResponseDTO.succ(); + } + + /** + * 根据ID查询 + * + * @param id + * @return + */ + public ResponseDTO queryPositionById(Long id) { + return ResponseDTO.succData(SmartBeanUtil.copy(positionDao.selectById(id), PositionResultVO.class)); + } + + /** + * 删除岗位 + */ + public ResponseDTO removePosition(Long id) { + //查询是否还有人关联该岗位 + PositionRelationQueryDTO positionRelationQueryDTO = new PositionRelationQueryDTO(); + positionRelationQueryDTO.setPositionId(id); + List dtoList = positionDao.selectRelation(positionRelationQueryDTO); + if (CollectionUtils.isNotEmpty(dtoList)) { + return ResponseDTO.wrap(PositionResponseCodeConst.REMOVE_DEFINE); + } + positionDao.deleteById(id); + return ResponseDTO.succ(); + } + + /** + * 添加岗位关联关系 + * + * @param positionRelAddDTO + * @return + */ + public ResponseDTO addPositionRelation(PositionRelationAddDTO positionRelAddDTO) { + positionDao.insertBatchRelation(positionRelAddDTO); + return ResponseDTO.succ(); + } + + /** + * 删除指定用户的岗位关联关系 + * + * @param employeeId + * @return + */ + public ResponseDTO removePositionRelation(Long employeeId) { + positionDao.deleteRelationByEmployeeId(employeeId); + return ResponseDTO.succ(); + } + + /** + * 根据员工ID查询 所关联的岗位信息 + * + * @param employeeId + * @return + */ + public List queryPositionByEmployeeId(Long employeeId) { + PositionRelationQueryDTO positionRelationQueryDTO = new PositionRelationQueryDTO(); + positionRelationQueryDTO.setEmployeeId(employeeId); + List positionRelationList = positionDao.selectRelation(positionRelationQueryDTO); + return positionRelationList; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionAddDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionAddDTO.java new file mode 100644 index 00000000..b061af61 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionAddDTO.java @@ -0,0 +1,28 @@ +package com.gangquan360.smartadmin.module.position.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 岗位 + * + * @author zzr + */ +@Data +public class PositionAddDTO { + + /** + * 岗位名称 + */ + @ApiModelProperty("岗位名称") + @NotBlank(message = "岗位名称不能为空") + private String positionName; + + /** + * 岗位描述 + */ + @ApiModelProperty("岗位描述") + private String remark; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionQueryDTO.java new file mode 100644 index 00000000..b4bd5d8e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionQueryDTO.java @@ -0,0 +1,18 @@ +package com.gangquan360.smartadmin.module.position.domain.dto; + +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 岗位 + * + * @author zzr + */ +@Data +public class PositionQueryDTO extends PageParamDTO { + + @ApiModelProperty("岗位名称") + private String positionName; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionRelationAddDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionRelationAddDTO.java new file mode 100644 index 00000000..fbbbaaf1 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionRelationAddDTO.java @@ -0,0 +1,32 @@ +package com.gangquan360.smartadmin.module.position.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 岗位关系 + * + * @author zzr + */ +@Data +public class PositionRelationAddDTO { + + @ApiModelProperty("岗位ID") + @NotNull(message = "岗位ID 不能为空") + private List positionIdList; + + @ApiModelProperty("员工ID") + @NotNull(message = "员工ID 不能为空") + private Long employeeId; + + public PositionRelationAddDTO() { + } + + public PositionRelationAddDTO(List positionIdList, Long employeeId) { + this.positionIdList = positionIdList; + this.employeeId = employeeId; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionRelationQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionRelationQueryDTO.java new file mode 100644 index 00000000..ed6803f5 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionRelationQueryDTO.java @@ -0,0 +1,20 @@ +package com.gangquan360.smartadmin.module.position.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 岗位关系 + * + * @author zzr + */ +@Data +public class PositionRelationQueryDTO { + + @ApiModelProperty("岗位ID") + private Long positionId; + + @ApiModelProperty("员工ID") + private Long employeeId; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionRelationResultDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionRelationResultDTO.java new file mode 100644 index 00000000..865e3431 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionRelationResultDTO.java @@ -0,0 +1,40 @@ +package com.gangquan360.smartadmin.module.position.domain.dto; + +import lombok.Data; + +import java.util.Date; + +/** + * 岗位关联关系 + * + * @author zzr + */ +@Data +public class PositionRelationResultDTO { + + /** + * 岗位ID + */ + private Long positionId; + + /** + * 员工ID + */ + private Long employeeId; + + /** + * 岗位名称 + */ + private String positionName; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 创建时间 + */ + private Date createTime; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionResultVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionResultVO.java new file mode 100644 index 00000000..ff317fb0 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionResultVO.java @@ -0,0 +1,41 @@ +package com.gangquan360.smartadmin.module.position.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * @author zzr + */ +@Data +public class PositionResultVO { + + @ApiModelProperty("主键") + private Long id; + + /** + * 更新时间 + */ + @ApiModelProperty("更新时间") + private Date updateTime; + + /** + * 创建时间 + */ + @ApiModelProperty("创建时间") + private Date createTime; + + /** + * 岗位名称 + */ + @ApiModelProperty("岗位名称") + private String positionName; + + /** + * 岗位描述 + */ + @ApiModelProperty("岗位描述") + private String remark; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionUpdateDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionUpdateDTO.java new file mode 100644 index 00000000..52c2e1cd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/dto/PositionUpdateDTO.java @@ -0,0 +1,16 @@ +package com.gangquan360.smartadmin.module.position.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 岗位 + * + * @author zzr + */ +@Data +public class PositionUpdateDTO extends PositionAddDTO { + + @ApiModelProperty("主键") + private Long id; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/entity/PositionEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/entity/PositionEntity.java new file mode 100644 index 00000000..23d1c9d6 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/entity/PositionEntity.java @@ -0,0 +1,26 @@ +package com.gangquan360.smartadmin.module.position.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * 岗位 + * + * @author zzr + */ +@Data +@TableName("t_position") +public class PositionEntity extends BaseEntity { + + /** + * 岗位名称 + */ + private String positionName; + + /** + * 岗位描述 + */ + private String remark; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/entity/PositionRelationEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/entity/PositionRelationEntity.java new file mode 100644 index 00000000..1478134b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/position/domain/entity/PositionRelationEntity.java @@ -0,0 +1,26 @@ +package com.gangquan360.smartadmin.module.position.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * 岗位关联关系 + * + * @author zzr + */ +@Data +@TableName("t_position_relation") +public class PositionRelationEntity extends BaseEntity { + + /** + * 岗位ID + */ + private Long positionId; + + /** + * 员工ID + */ + private Long employeeId; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/constant/PrivilegeResponseCodeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/constant/PrivilegeResponseCodeConst.java new file mode 100644 index 00000000..dd5f09fc --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/constant/PrivilegeResponseCodeConst.java @@ -0,0 +1,24 @@ +package com.gangquan360.smartadmin.module.privilege.constant; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + + +/** + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +public class PrivilegeResponseCodeConst extends ResponseCodeConst { + + public static final PrivilegeResponseCodeConst PRIVILEGE_NOT_EXISTS = new PrivilegeResponseCodeConst(7001, "当前数据不存在,请联系你的管理员!"); + + public static final PrivilegeResponseCodeConst ROUTER_KEY_NO_REPEAT = new PrivilegeResponseCodeConst(7002, "模块和页面的“功能Key”值不能重复!"); + + public PrivilegeResponseCodeConst(int code, String msg) { + super(code, msg); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/constant/PrivilegeTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/constant/PrivilegeTypeEnum.java new file mode 100644 index 00000000..137d5f20 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/constant/PrivilegeTypeEnum.java @@ -0,0 +1,49 @@ +package com.gangquan360.smartadmin.module.privilege.constant; + + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +import java.util.Arrays; +import java.util.Optional; + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +public enum PrivilegeTypeEnum implements BaseEnum { + + + MENU(1,"菜单"), + + POINTS(2,"功能点"); + + private Integer value; + + private String desc; + + PrivilegeTypeEnum(Integer value,String desc){ + this.value = value; + this.desc = desc; + } + @Override + public Integer getValue() { + return this.value; + } + + @Override + public String getDesc() { + return this.desc; + } + + public static PrivilegeTypeEnum selectByValue(Integer value) { + Optional first = Arrays.stream(PrivilegeTypeEnum.values()).filter(e -> e.getValue().equals(value)).findFirst(); + return !first.isPresent() ? null : first.get(); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/controller/PrivilegeController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/controller/PrivilegeController.java new file mode 100644 index 00000000..f1126a3f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/controller/PrivilegeController.java @@ -0,0 +1,68 @@ +package com.gangquan360.smartadmin.module.privilege.controller; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.privilege.domain.dto.*; +import com.gangquan360.smartadmin.module.privilege.service.PrivilegeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * [ 与员工权限相关:角色权限关系、权限列表 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@OperateLog +@RestController +@Api(tags = {SwaggerTagConst.Admin.MANAGER_PRIVILEGE}) +public class PrivilegeController { + + @Autowired + private PrivilegeService privilegeService; + + @GetMapping("/privilege/getAllUrl") + @ApiOperation(value = "获取所有请求路径", notes = "获取所有请求路径") + public ResponseDTO> getAllUrl() { + return privilegeService.getPrivilegeUrlDTOList(); + } + + @ApiOperation(value = "菜单批量保存") + @PostMapping("/privilege/menu/batchSaveMenu") + public ResponseDTO menuBatchSave(@Valid @RequestBody List menuList) { + return privilegeService.menuBatchSave(menuList); +// return ResponseDTO.succ(); + } + + @ApiOperation(value = "查询所有菜单项") + @PostMapping("/privilege/menu/queryAll") + public ResponseDTO> queryAll() { + return privilegeService.menuQueryAll(); + } + + + @ApiOperation(value = "保存更新功能点") + @PostMapping("/privilege/function/saveOrUpdate") + public ResponseDTO functionSaveOrUpdate(@Valid @RequestBody PrivilegeFunctionDTO privilegeFunctionDTO) { + return privilegeService.functionSaveOrUpdate(privilegeFunctionDTO); +// return ResponseDTO.succ(); + } + + @ApiOperation(value = "查询菜单功能点", notes = "更新") + @PostMapping("/privilege/function/query/{menuKey}") + public ResponseDTO> functionQuery(@PathVariable String menuKey) { + return privilegeService.functionQuery(menuKey); + } + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/dao/PrivilegeDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/dao/PrivilegeDao.java new file mode 100644 index 00000000..aaa8d5cd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/dao/PrivilegeDao.java @@ -0,0 +1,87 @@ +package com.gangquan360.smartadmin.module.privilege.dao; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.gangquan360.smartadmin.module.privilege.domain.entity.PrivilegeEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Mapper +@Component +public interface PrivilegeDao extends BaseMapper { + + /** + * 根据权限key删除 + * @param keyList + */ + void delByKeyList(@Param("keyList") List keyList); + /** + * 根据权限parentkey删除 + * @param keyList + */ + void delByParentKeyList(@Param("keyList") List keyList); + + /** + * 批量保存 + * @param privilegeList + */ + void batchInsert(List privilegeList); + + /** + * 批量更新 + * @param privilegeList + */ + void batchUpdate(@Param("updateList") List privilegeList); + + /** + * 根据父节点key查询 + * @param parentKey + * @return + */ + List selectByParentKey(@Param("parentKey") String parentKey); + + /** + * 根据权限key查询 + * @param key + * @return + */ + PrivilegeEntity selectByKey(@Param("key") String key); + + /** + * 根据类型查询 + * @param type + * @return + */ + List selectByExcludeType(@Param("type") Integer type); + + /** + * 根据类型查询 + * @param type + * @return + */ + List selectByType(@Param("type") Integer type); + + /** + * 查询所有权限 + * @return + */ + List selectAll(); + + + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeFunctionDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeFunctionDTO.java new file mode 100644 index 00000000..8feca1be --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeFunctionDTO.java @@ -0,0 +1,41 @@ +package com.gangquan360.smartadmin.module.privilege.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/20 0020 下午 16:45 + * @since JDK1.8 + */ +@Data +public class PrivilegeFunctionDTO { + + @ApiModelProperty("功能点名称") + @NotBlank(message = "功能点名称不能为空") + private String functionName; + + @ApiModelProperty("所属菜单Key") + @NotBlank(message = "所属菜单Key不能为空") + private String menuKey; + + @ApiModelProperty("功能点Key") + @NotBlank(message = "功能点Key不能为空") + private String functionKey; + + @ApiModelProperty("url列表") + private String url; + + @ApiModelProperty("排序") + @NotNull(message = "请输入功能点顺序") + private Integer sort; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeFunctionVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeFunctionVO.java new file mode 100644 index 00000000..337317a3 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeFunctionVO.java @@ -0,0 +1,41 @@ +package com.gangquan360.smartadmin.module.privilege.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/20 0020 下午 16:45 + * @since JDK1.8 + */ +@Data +public class PrivilegeFunctionVO { + + @ApiModelProperty("功能点名称") + @NotBlank(message = "功能点名称不能为空") + private String functionName; + + @ApiModelProperty("所属菜单Key") + @NotBlank(message = "所属菜单Key不能为空") + private String menuKey; + + @ApiModelProperty("功能点Key") + @NotBlank(message = "功能点Key不能为空") + private String functionKey; + + @ApiModelProperty("url列表") + @NotEmpty(message = "url列表不能为空") + private String url; + + @ApiModelProperty("顺序") + private Integer sort; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeMenuDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeMenuDTO.java new file mode 100644 index 00000000..fc13811d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeMenuDTO.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.module.privilege.domain.dto; + +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.module.privilege.constant.PrivilegeTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/20 0020 下午 16:32 + * @since JDK1.8 + */ +@Data +public class PrivilegeMenuDTO { + + @ApiModelPropertyEnum(enumDesc = "菜单类型",value = PrivilegeTypeEnum.class) + @NotNull + private Integer type; + + @ApiModelProperty("菜单名") + @NotNull(message = "菜单名不能为空") + private String menuName; + + @ApiModelProperty("菜单Key") + @NotNull(message = "菜单Key不能为空") + private String menuKey; + + @ApiModelProperty("父级菜单Key,根节点不传") + private String parentKey; + + @ApiModelProperty("前端路由path") + @NotNull(message = "前端路由path不能为空") + private String url; + + @ApiModelProperty("排序字段") + @NotNull(message = "菜单项顺序不能为空") + private Integer sort; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeMenuListVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeMenuListVO.java new file mode 100644 index 00000000..62aec553 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeMenuListVO.java @@ -0,0 +1,37 @@ +package com.gangquan360.smartadmin.module.privilege.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/8/20 0020 下午 16:41 + * @since JDK1.8 + */ +@Data +public class PrivilegeMenuListVO { + + @ApiModelProperty("菜单名") + private String menuName; + + @ApiModelProperty("菜单Key") + private String menuKey; + + @ApiModelProperty("菜单父级Key") + private String parentKey; + + @ApiModelProperty("顺序") + private Integer sort; + + @ApiModelProperty("子菜单列表") + private List menuList; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeRequestUrlVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeRequestUrlVO.java new file mode 100644 index 00000000..87757aaa --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/dto/PrivilegeRequestUrlVO.java @@ -0,0 +1,27 @@ +package com.gangquan360.smartadmin.module.privilege.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/28 0028 上午 9:20 + * @since JDK1.8 + */ +@Data +public class PrivilegeRequestUrlVO { + + @ApiModelProperty("注释说明") + private String comment; + + @ApiModelProperty("controller.method") + private String name; + + @ApiModelProperty("url") + private String url; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/entity/PrivilegeEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/entity/PrivilegeEntity.java new file mode 100644 index 00000000..0eab5264 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/domain/entity/PrivilegeEntity.java @@ -0,0 +1,55 @@ +package com.gangquan360.smartadmin.module.privilege.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +import java.io.Serializable; + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +@TableName("t_privilege") +public class PrivilegeEntity extends BaseEntity implements Serializable { + private static final long serialVersionUID = 3848408566432915214L; + + /** + * 功能权限类型:1.模块 2.页面 3.功能点 4.子模块 + */ + private Integer type; + + /** + * 菜单名称 + */ + private String name; + + /** + * 路由name 英文关键字 + */ + private String key; + + + private String url; + + /** + * 排序 + */ + private Integer sort; + + + /** + * 父级key + */ + private String parentKey; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/service/PrivilegeEmployeeService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/service/PrivilegeEmployeeService.java new file mode 100644 index 00000000..e843ff1f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/service/PrivilegeEmployeeService.java @@ -0,0 +1,196 @@ +package com.gangquan360.smartadmin.module.privilege.service; + +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import com.gangquan360.smartadmin.common.exception.SmartBusinessException; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import com.gangquan360.smartadmin.module.privilege.constant.PrivilegeTypeEnum; +import com.gangquan360.smartadmin.module.privilege.dao.PrivilegeDao; +import com.gangquan360.smartadmin.module.privilege.domain.entity.PrivilegeEntity; +import com.gangquan360.smartadmin.module.role.roleemployee.RoleEmployeeDao; +import com.gangquan360.smartadmin.module.role.roleprivilege.RolePrivilegeDao; +import com.gangquan360.smartadmin.module.systemconfig.SystemConfigService; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigEnum; +import com.gangquan360.smartadmin.module.systemconfig.domain.dto.SystemConfigDTO; +import com.gangquan360.smartadmin.util.SmartStringUtil; +import com.google.common.collect.Lists; +import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; + +/** + * [ 后台员工权限缓存方法 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/28 0028 下午 14:07 + * @since JDK1.8 + */ +@Service +public class PrivilegeEmployeeService { + + /** + * 后台用户权限缓存 > + */ + private ConcurrentMap>> employeePrivileges = new ConcurrentLinkedHashMap.Builder>>().maximumWeightedCapacity(1000).build(); + private ConcurrentMap> employeePrivilegeListMap = new ConcurrentLinkedHashMap.Builder>().maximumWeightedCapacity(1000).build(); + + @Autowired + private SystemConfigService systemConfigService; + + @Autowired + private RoleEmployeeDao roleEmployeeDao; + + @Autowired + private RolePrivilegeDao rolePrivilegeDao; + + @Autowired + private PrivilegeDao privilegeDao; + + /** + * 移除某人缓存中的权限 + * + * @param employeeId + */ + public void removeCache(Long employeeId) { + this.employeePrivileges.remove(employeeId); + } + + /** + * 检查某人是否有访问某个方法的权限 + * + * @param requestTokenBO + * @param controllerName + * @param methodName + * @return + */ + public Boolean checkEmployeeHavePrivilege(RequestTokenBO requestTokenBO, String controllerName, String methodName) { + if (StringUtils.isEmpty(controllerName) || StringUtils.isEmpty(methodName)) { + return false; + } + Boolean isSuperman = requestTokenBO.getEmployeeBO().getIsSuperman(); + if (isSuperman) { + return true; + } + Map> privileges = this.getPrivileges(requestTokenBO.getRequestUserId()); + List urlList = privileges.get(controllerName.toLowerCase()); + if (CollectionUtils.isEmpty(urlList)) { + return false; + } + return urlList.contains(methodName); + } + + public List getEmployeeAllPrivilege(Long employeeId){ + return employeePrivilegeListMap.get(employeeId); + } + + /** + * 判断是否为超级管理员 + * + * @param employeeId + * @return + */ + public Boolean isSuperman(Long employeeId) { + SystemConfigDTO systemConfig = systemConfigService.getCacheByKey(SystemConfigEnum.Key.EMPLOYEE_SUPERMAN); + if (systemConfig == null) { + throw new SmartBusinessException("缺少系统配置项[" + SystemConfigEnum.Key.EMPLOYEE_SUPERMAN.name() + "]"); + } + + List superManIdsList = SmartStringUtil.splitConverToLongList(systemConfig.getConfigValue(), ","); + return superManIdsList.contains(employeeId); + } + + /** + * 根据员工ID 获取 权限信息 + * + * @param employeeId + * @return + */ + public List getPrivilegesByEmployeeId(Long employeeId) { + // 如果是超管的话 + Boolean isSuperman = this.isSuperman(employeeId); + if (isSuperman) { + List privilegeEntities = privilegeDao.selectAll(); + if (privilegeEntities == null) { + return Lists.newArrayList(); + } + return privilegeEntities; + } + List privilegeEntities = loadPrivilegeFromDb(employeeId); + this.updateCachePrivilege(employeeId, privilegeEntities); + return privilegeEntities; + } + + /** + * 获取某人所能访问的方法 + * + * @param employeeId + * @return + */ + private Map> getPrivileges(Long employeeId) { + Map> privileges = employeePrivileges.get(employeeId); + if (privileges != null) { + return privileges; + } + List privilegeEntities = this.loadPrivilegeFromDb(employeeId); + return updateCachePrivilege(employeeId, privilegeEntities); + } + + private List loadPrivilegeFromDb(Long employeeId) { + List roleIdList = roleEmployeeDao.selectRoleIdByEmployeeId(employeeId); + if (CollectionUtils.isEmpty(roleIdList)) { + return Lists.newArrayList(); + } + List privilegeEntities = rolePrivilegeDao.listByRoleIds(roleIdList, JudgeEnum.YES.getValue()); + if (privilegeEntities != null) { + return privilegeEntities; + } + return Collections.emptyList(); + } + + public Map> updateCachePrivilege(Long employeeId, List privilegeEntities) { + employeePrivilegeListMap.put(employeeId,privilegeEntities); + List privilegeList = new ArrayList<>(); + Map> privilegeMap = new HashMap<>(16); + if (CollectionUtils.isNotEmpty(privilegeEntities)) { + List> setList = + privilegeEntities.stream().filter(e -> e.getType().equals(PrivilegeTypeEnum.POINTS.getValue())).map(PrivilegeEntity :: getUrl).collect(Collectors.toList()).stream().map(e -> SmartStringUtil.splitConvertToList(e, ",")).collect(Collectors.toList()); + setList.forEach(privilegeList :: addAll); + } + privilegeList.forEach(item -> { + List path = SmartStringUtil.splitConvertToList(item, "\\."); + String controllerName = path.get(0).toLowerCase(); + String methodName = path.get(1); + List methodNameList = privilegeMap.get(controllerName); + if (null == methodNameList) { + methodNameList = new ArrayList(); + } + if (! methodNameList.contains(methodName)) { + methodNameList.add(methodName); + } + privilegeMap.put(controllerName, methodNameList); + }); + + employeePrivileges.put(employeeId, privilegeMap); + return privilegeMap; + } + + public void updateOnlineEmployeePrivilegeByRoleId(Long roleId) { + List roleEmployeeList = roleEmployeeDao.selectEmployeeByRoleId(roleId); + List employeeIdList = roleEmployeeList.stream().map(e -> e.getId()).collect(Collectors.toList()); + + for (Long empId : employeePrivileges.keySet()) { + if (employeeIdList.contains(empId)) { + getPrivilegesByEmployeeId(empId); + } + } + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/service/PrivilegeRequestUrlService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/service/PrivilegeRequestUrlService.java new file mode 100644 index 00000000..3be2af57 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/service/PrivilegeRequestUrlService.java @@ -0,0 +1,117 @@ +package com.gangquan360.smartadmin.module.privilege.service; + +import com.gangquan360.smartadmin.constant.CommonConst; +import com.gangquan360.smartadmin.module.privilege.domain.dto.PrivilegeRequestUrlVO; +import com.gangquan360.smartadmin.util.SmartStringUtil; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import javax.annotation.PostConstruct; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * [ 初始化 分离前后台权限URL ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/28 0028 上午 9:13 + * @since JDK1.8 + */ +@Service +public class PrivilegeRequestUrlService { + + /** + * 系统所有requestUrl + */ + private CopyOnWriteArrayList privilegeUrlDTOList = Lists.newCopyOnWriteArrayList(); + + @Autowired + private WebApplicationContext applicationContext; + + @PostConstruct + public void initAllUrl() { + this.privilegeUrlDTOList.clear(); + + RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); + //获取url与类和方法的对应信息 + Map map = mapping.getHandlerMethods(); + map.forEach((info, handlerMethod) -> { + //只对Rest 服务进行权限验证 + RestController restAnnotation = AnnotationUtils.findAnnotation(handlerMethod.getMethod().getDeclaringClass(), RestController.class); + if (restAnnotation == null) { + ResponseBody responseBody = handlerMethod.getMethod().getAnnotation(ResponseBody.class); + if (responseBody == null) { + return; + } + } + //获取url的Set集合,一个方法可能对应多个url + Set patterns = info.getPatternsCondition().getPatterns(); + if (CollectionUtils.isEmpty(patterns)) { + return; + } + String className = (String) handlerMethod.getBean(); + String methodName = handlerMethod.getMethod().getName(); + List list = SmartStringUtil.splitConvertToList(className, "\\."); + String controllerName = list.get(list.size() - 1); + String name = controllerName + "." + methodName; + + ApiOperation apiOperation = handlerMethod.getMethod().getAnnotation(ApiOperation.class); + String methodComment = null; + if (apiOperation != null) { + methodComment = apiOperation.value(); + } else { + ApiModelProperty apiModelProperty = handlerMethod.getMethod().getAnnotation(ApiModelProperty.class); + if (apiModelProperty != null) { + methodComment = apiModelProperty.value(); + } else { + methodComment = handlerMethod.getMethod().getName(); + } + } + Set urlSet = this.getUrlSet(patterns); + for (String url : urlSet) { + PrivilegeRequestUrlVO privilegeUrlDTO = new PrivilegeRequestUrlVO(); + privilegeUrlDTO.setUrl(url); + privilegeUrlDTO.setName(name); + privilegeUrlDTO.setComment(methodComment); + this.privilegeUrlDTOList.add(privilegeUrlDTO); + } + + }); + } + + private Set getUrlSet(Set patterns) { + Set urlSet = Sets.newHashSet(); + for (String url : patterns) { + for (String ignoreUrl : CommonConst.CommonCollection.IGNORE_URL_MAPPING) { + if (url.startsWith(ignoreUrl)) { + urlSet.add(url.substring(ignoreUrl.length() - 1)); + } else { + urlSet.add(url); + } + } + } + return urlSet; + } + + public List getPrivilegeList() { + return this.privilegeUrlDTOList; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/service/PrivilegeService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/service/PrivilegeService.java new file mode 100644 index 00000000..94b0ac9e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/privilege/service/PrivilegeService.java @@ -0,0 +1,217 @@ +package com.gangquan360.smartadmin.module.privilege.service; + +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.privilege.constant.PrivilegeTypeEnum; +import com.gangquan360.smartadmin.module.privilege.dao.PrivilegeDao; +import com.gangquan360.smartadmin.module.privilege.domain.dto.*; +import com.gangquan360.smartadmin.module.privilege.domain.entity.PrivilegeEntity; +import com.gangquan360.smartadmin.module.role.roleprivilege.RolePrivilegeDao; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * [ 后台员工权限 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Service +public class PrivilegeService { + + @Autowired + private PrivilegeRequestUrlService privilegeRequestUrlService; + + @Autowired + private PrivilegeDao privilegeDao; + + @Autowired + private RolePrivilegeDao rolePrivilegeDao; + + /** + * 获取系统所有请求路径 + * + * @return + */ + public ResponseDTO> getPrivilegeUrlDTOList() { + List privilegeUrlList = privilegeRequestUrlService.getPrivilegeList(); + return ResponseDTO.succData(privilegeUrlList); + } + + /** + * 批量保存权限菜单项 + * + * @param menuList + * @return + */ + @Transactional(rollbackFor = Throwable.class) + public ResponseDTO menuBatchSave(List menuList) { + if (CollectionUtils.isEmpty(menuList)) { + return ResponseDTO.succ(); + } + List privilegeList = privilegeDao.selectByExcludeType(PrivilegeTypeEnum.POINTS.getValue()); + //若数据库无数据 直接全部保存 + if (CollectionUtils.isEmpty(privilegeList)) { + List menuSaveEntity = this.buildPrivilegeMenuEntity(menuList); + privilegeDao.batchInsert(menuSaveEntity); + return ResponseDTO.succ(); + } + //处理需更新的菜单项 + Map storageMap = menuList.stream().collect(Collectors.toMap(PrivilegeMenuDTO::getMenuKey, e -> e)); + Set menuKeyList = storageMap.keySet(); + List updatePrivilegeList = privilegeList.stream().filter(e -> menuKeyList.contains(e.getKey())).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(updatePrivilegeList)) { + this.rebuildPrivilegeMenuEntity(storageMap, updatePrivilegeList); + privilegeDao.batchUpdate(updatePrivilegeList); + } + //处理需删除的菜单项 + List delKeyList = privilegeList.stream().filter(e -> !menuKeyList.contains(e.getKey())).map(PrivilegeEntity::getKey).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(delKeyList)) { + privilegeDao.delByKeyList(delKeyList); + //处理需删除的功能点 + privilegeDao.delByParentKeyList(delKeyList); + rolePrivilegeDao.deleteByPrivilegeKey(delKeyList); + } + + //处理需新增的菜单项 + List dbKeyList = privilegeList.stream().map(PrivilegeEntity::getKey).collect(Collectors.toList()); + List addPrivilegeList = menuList.stream().filter(e -> !dbKeyList.contains(e.getMenuKey())).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(addPrivilegeList)) { + List menuAddEntity = this.buildPrivilegeMenuEntity(addPrivilegeList); + privilegeDao.batchInsert(menuAddEntity); + } + return ResponseDTO.succ(); + } + + /** + * 构建权限菜单项类别 + * + * @param menuList + * @return + */ + private List buildPrivilegeMenuEntity(List menuList) { + List privilegeList = Lists.newArrayList(); + PrivilegeEntity privilegeEntity; + for (PrivilegeMenuDTO menuDTO : menuList) { + privilegeEntity = new PrivilegeEntity(); + privilegeEntity.setKey(menuDTO.getMenuKey()); + privilegeEntity.setName(menuDTO.getMenuName()); + privilegeEntity.setParentKey(menuDTO.getParentKey()); + privilegeEntity.setType(menuDTO.getType()); + privilegeEntity.setSort(menuDTO.getSort()); + privilegeEntity.setUrl(menuDTO.getUrl()); + privilegeList.add(privilegeEntity); + } + return privilegeList; + } + + /** + * 更新权限菜单项 + * + * @param menuMap + * @param menuEntityList + */ + private void rebuildPrivilegeMenuEntity(Map menuMap, List menuEntityList) { + for (PrivilegeEntity menuEntity : menuEntityList) { + PrivilegeMenuDTO menuDTO = menuMap.get(menuEntity.getKey()); + menuEntity.setName(menuDTO.getMenuName()); + menuEntity.setParentKey(menuDTO.getParentKey()); + menuEntity.setType(menuDTO.getType()); + menuEntity.setSort(menuDTO.getSort()); + } + + } + + /** + * 查询所有的权限菜单 + * + * @return + */ + public ResponseDTO> menuQueryAll() { + List privilegeEntityList = privilegeDao.selectByType(PrivilegeTypeEnum.MENU.getValue()); + if (CollectionUtils.isEmpty(privilegeEntityList)) { + return ResponseDTO.succData(Lists.newArrayList()); + } + + List voList = privilegeEntityList.stream().map( e-> { + PrivilegeMenuListVO vo = new PrivilegeMenuListVO(); + vo.setMenuKey(e.getKey()); + vo.setMenuName(e.getName()); + vo.setParentKey(e.getParentKey()); + vo.setSort(e.getSort()); + return vo; + }).collect(Collectors.toList()); + + return ResponseDTO.succData(voList); + } + + + /** + * 保存更新功能点 + * + * @param privilegeFunctionDTO + * @return + */ + public ResponseDTO functionSaveOrUpdate(PrivilegeFunctionDTO privilegeFunctionDTO) { + String functionKey = privilegeFunctionDTO.getFunctionKey(); + PrivilegeEntity functionEntity = privilegeDao.selectByKey(functionKey); + if (functionEntity == null) { + functionEntity = new PrivilegeEntity(); + functionEntity.setName(privilegeFunctionDTO.getFunctionName()); + functionEntity.setParentKey(privilegeFunctionDTO.getMenuKey()); + functionEntity.setType(PrivilegeTypeEnum.POINTS.getValue()); + functionEntity.setUrl(privilegeFunctionDTO.getUrl()); + functionEntity.setKey(privilegeFunctionDTO.getFunctionKey()); + functionEntity.setSort(privilegeFunctionDTO.getSort()); + functionEntity.setCreateTime(new Date()); + functionEntity.setUpdateTime(new Date()); + privilegeDao.insert(functionEntity); + } else { + functionEntity.setUrl(privilegeFunctionDTO.getUrl()); + functionEntity.setName(privilegeFunctionDTO.getFunctionName()); + functionEntity.setParentKey(privilegeFunctionDTO.getMenuKey()); + functionEntity.setSort(privilegeFunctionDTO.getSort()); + privilegeDao.updateById(functionEntity); + } + return ResponseDTO.succ(); + } + + /** + * 查询功能点 + * + * @param menuKey + * @return + */ + public ResponseDTO> functionQuery(String menuKey) { + List functionPrivilegeList = privilegeDao.selectByParentKey(menuKey); + if (CollectionUtils.isEmpty(functionPrivilegeList)) { + return ResponseDTO.succData(Lists.newArrayList()); + } + List functionList = Lists.newArrayList(); + PrivilegeFunctionVO functionDTO; + for (PrivilegeEntity functionEntity : functionPrivilegeList) { + functionDTO = new PrivilegeFunctionVO(); + functionDTO.setFunctionKey(functionEntity.getKey()); + functionDTO.setFunctionName(functionEntity.getName()); + functionDTO.setMenuKey(functionEntity.getParentKey()); + functionDTO.setUrl(functionEntity.getUrl()); + functionDTO.setSort(functionEntity.getSort()); + functionList.add(functionDTO); + } + return ResponseDTO.succData(functionList); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/constant/QuartzConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/constant/QuartzConst.java new file mode 100644 index 00000000..de28155d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/constant/QuartzConst.java @@ -0,0 +1,17 @@ +package com.gangquan360.smartadmin.module.quartz.constant; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 15:21 + * @since JDK1.8 + */ +public class QuartzConst { + public static final String QUARTZ_PARAMS_KEY="TASK_PARAMS"; + public static final String JOB_KEY_PREFIX="TASK_"; + public static final String TRIGGER_KEY_PREFIX="TRIGGER_"; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/constant/TaskResultEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/constant/TaskResultEnum.java new file mode 100644 index 00000000..72e95146 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/constant/TaskResultEnum.java @@ -0,0 +1,47 @@ +package com.gangquan360.smartadmin.module.quartz.constant; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 14:19 + * @since JDK1.8 + */ +public enum TaskResultEnum { + + SUCCESS(0,"成功"), + /** + * + */ + FAIL(1,"失败"); + + public static final String INFO="0:成功,1:失败"; + + private Integer status; + + private String desc; + + TaskResultEnum(Integer status , String desc) { + this.status = status; + this.desc = desc; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/constant/TaskStatusEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/constant/TaskStatusEnum.java new file mode 100644 index 00000000..19e24a87 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/constant/TaskStatusEnum.java @@ -0,0 +1,47 @@ +package com.gangquan360.smartadmin.module.quartz.constant; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 14:19 + * @since JDK1.8 + */ +public enum TaskStatusEnum { + + NORMAL(0,"正常"), + /** + * + */ + PAUSE(1,"暂停"); + + public static final String INFO="0:正常,1:暂停"; + + private Integer status; + + private String desc; + + TaskStatusEnum(Integer status ,String desc) { + this.status = status; + this.desc = desc; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/controller/QuartzController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/controller/QuartzController.java new file mode 100644 index 00000000..2b76fd16 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/controller/QuartzController.java @@ -0,0 +1,81 @@ +package com.gangquan360.smartadmin.module.quartz.controller; + +import com.gangquan360.smartadmin.common.anno.NoValidPrivilege; +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.quartz.domain.dto.*; +import com.gangquan360.smartadmin.module.quartz.service.QuartzTaskService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@OperateLog +@RestController +@Api(tags = {SwaggerTagConst.Admin.MANAGER_TASK_SCHEDULER}) +public class QuartzController { + + @Autowired + private QuartzTaskService quartzTaskService; + + + @PostMapping("/quartz/task/query") + @ApiOperation(value = "查询任务") + @NoValidPrivilege + public ResponseDTO> query(@RequestBody @Valid QuartzQueryDTO queryDTO){ + return quartzTaskService.query(queryDTO); + } + + + @PostMapping("/quartz/task/queryLog") + @ApiOperation(value = "查询任务运行日志") + @NoValidPrivilege + public ResponseDTO> queryLog(@RequestBody @Valid QuartzLogQueryDTO queryDTO){ + return quartzTaskService.queryLog(queryDTO); + } + + @PostMapping("/quartz/task/saveOrUpdate") + @ApiOperation(value = "新建更新任务") + public ResponseDTO saveOrUpdateTask(@RequestBody @Valid QuartzTaskDTO quartzTaskDTO)throws Exception{ + return quartzTaskService.saveOrUpdateTask(quartzTaskDTO); + } + + @GetMapping("/quartz/task/run/{taskId}") + @ApiOperation(value = "立即运行某个任务") + public ResponseDTO runTask(@PathVariable("taskId") Long taskId)throws Exception{ + return quartzTaskService.runTask(taskId); + } + + @GetMapping("/quartz/task/pause/{taskId}") + @ApiOperation(value = "暂停某个任务") + public ResponseDTO pauseTask(@PathVariable("taskId")Long taskId)throws Exception{ + return quartzTaskService.pauseTask(taskId); + } + + @GetMapping("/quartz/task/resume/{taskId}") + @ApiOperation(value = "恢复某个任务") + public ResponseDTO resumeTask(@PathVariable("taskId")Long taskId)throws Exception{ + return quartzTaskService.resumeTask(taskId); + } + + @GetMapping("/quartz/task/delete/{taskId}") + @ApiOperation(value = "删除某个任务") + public ResponseDTO deleteTask(@PathVariable("taskId")Long taskId)throws Exception{ + return quartzTaskService.deleteTask(taskId); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/dao/QuartzTaskDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/dao/QuartzTaskDao.java new file mode 100644 index 00000000..9813aa71 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/dao/QuartzTaskDao.java @@ -0,0 +1,42 @@ +package com.gangquan360.smartadmin.module.quartz.dao; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.module.quartz.domain.dto.QuartzQueryDTO; +import com.gangquan360.smartadmin.module.quartz.domain.dto.QuartzTaskVO; +import com.gangquan360.smartadmin.module.quartz.domain.entity.QuartzTaskEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 14:35 + * @since JDK1.8 + */ +@Mapper +@Component +public interface QuartzTaskDao extends BaseMapper { + + /** + * 更新任务状态 + * @param taskId + * @param taskStatus + */ + void updateStatus(@Param("taskId") Integer taskId,@Param("taskStatus") Integer taskStatus); + + /** + * 查询列表 + * @param queryDTO + * @return + */ + List queryList(Page page, @Param("queryDTO")QuartzQueryDTO queryDTO); + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/dao/QuartzTaskLogDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/dao/QuartzTaskLogDao.java new file mode 100644 index 00000000..0202e663 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/dao/QuartzTaskLogDao.java @@ -0,0 +1,35 @@ +package com.gangquan360.smartadmin.module.quartz.dao; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.module.quartz.domain.dto.QuartzLogQueryDTO; +import com.gangquan360.smartadmin.module.quartz.domain.dto.QuartzTaskLogVO; +import com.gangquan360.smartadmin.module.quartz.domain.entity.QuartzTaskLogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 14:35 + * @since JDK1.8 + */ +@Mapper +@Component +public interface QuartzTaskLogDao extends BaseMapper{ + + + /** + * 查询列表 + * @param queryDTO + * @return + */ + List queryList(Page page, @Param("queryDTO")QuartzLogQueryDTO queryDTO); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzLogQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzLogQueryDTO.java new file mode 100644 index 00000000..40450853 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzLogQueryDTO.java @@ -0,0 +1,25 @@ +package com.gangquan360.smartadmin.module.quartz.domain.dto; + +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/15 0015 上午 11:29 + * @since JDK1.8 + */ +@Data +public class QuartzLogQueryDTO extends PageParamDTO { + + @ApiModelProperty(value = "任务Id(不能为空)") + @NotNull(message = "任务Id不能为空") + private Integer taskId; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzQueryDTO.java new file mode 100644 index 00000000..1257291b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzQueryDTO.java @@ -0,0 +1,16 @@ +package com.gangquan360.smartadmin.module.quartz.domain.dto; + +import com.gangquan360.smartadmin.common.domain.PageParamDTO; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/15 0015 上午 11:29 + * @since JDK1.8 + */ +public class QuartzQueryDTO extends PageParamDTO { +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzTaskDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzTaskDTO.java new file mode 100644 index 00000000..001a7a27 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzTaskDTO.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.module.quartz.domain.dto; + +import com.gangquan360.smartadmin.module.quartz.constant.TaskStatusEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 15:42 + * @since JDK1.8 + */ +@Data +public class QuartzTaskDTO { + + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("任务名称") + @NotNull(message = "任务名称不能为空") + private String taskName; + + @ApiModelProperty("任务Bean") + @NotNull(message = "任务Bean不能为空") + private String taskBean; + + @ApiModelProperty("任务参数") + private String taskParams; + + @ApiModelProperty("cron") + @NotNull(message = "cron表达式不能为空") + private String taskCron; + + @ApiModelProperty("任务状态:"+ TaskStatusEnum.INFO) + private Integer taskStatus; + + @ApiModelProperty("任务备注") + private String remark; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzTaskLogVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzTaskLogVO.java new file mode 100644 index 00000000..c5015d62 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzTaskLogVO.java @@ -0,0 +1,49 @@ +package com.gangquan360.smartadmin.module.quartz.domain.dto; + +import com.gangquan360.smartadmin.module.quartz.constant.TaskResultEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 15:42 + * @since JDK1.8 + */ +@Data +public class QuartzTaskLogVO { + + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("任务id") + private Long taskId; + + @ApiModelProperty("任务名称") + private String taskName; + + @ApiModelProperty("任务参数") + private String taskParams; + + @ApiModelProperty("任务处理状态:"+ TaskResultEnum.INFO) + private Integer processStatus; + + @ApiModelProperty("任务时长ms") + private Long processDuration; + + @ApiModelProperty("处理日志") + private String processLog; + + @ApiModelProperty("创建时间") + private Date createTime; + + + @ApiModelProperty("主机ip") + private String ipAddress; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzTaskVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzTaskVO.java new file mode 100644 index 00000000..20c2c38f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/dto/QuartzTaskVO.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.module.quartz.domain.dto; + +import com.gangquan360.smartadmin.module.quartz.constant.TaskStatusEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 15:42 + * @since JDK1.8 + */ +@Data +public class QuartzTaskVO { + + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("任务名称") + @NotNull(message = "任务名称不能为空") + private String taskName; + + @ApiModelProperty("任务Bean") + @NotNull(message = "任务Bean不能为空") + private String taskBean; + + @ApiModelProperty("任务参数") + private String taskParams; + + @ApiModelProperty("cron") + @NotNull(message = "cron表达式不能为空") + private String taskCron; + + @ApiModelProperty("任务状态:"+ TaskStatusEnum.INFO) + private Integer taskStatus; + + @ApiModelProperty("任务备注") + private String remark; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/entity/QuartzTaskEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/entity/QuartzTaskEntity.java new file mode 100644 index 00000000..a25b58dd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/entity/QuartzTaskEntity.java @@ -0,0 +1,49 @@ +package com.gangquan360.smartadmin.module.quartz.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 13:45 + * @since JDK1.8 + */ +@Data +@TableName("t_quartz_task") +public class QuartzTaskEntity extends BaseEntity{ + /** + * 任务名称参数 + */ + private String taskName; + /** + * 任务类 + */ + private String taskBean; + + /** + * 任务参数 + */ + private String taskParams; + + /** + * cron + */ + private String taskCron; + + /** + * 任务状态 + */ + private Integer taskStatus; + + /** + * 备注 + */ + private String remark; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/entity/QuartzTaskLogEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/entity/QuartzTaskLogEntity.java new file mode 100644 index 00000000..cd3c6dc0 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/domain/entity/QuartzTaskLogEntity.java @@ -0,0 +1,50 @@ +package com.gangquan360.smartadmin.module.quartz.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 13:45 + * @since JDK1.8 + */ +@Data +@TableName("t_quartz_task_log") +public class QuartzTaskLogEntity extends BaseEntity{ + /** + * 任务名称参数 + */ + private Long taskId; + /** + * 任务名称 + */ + private String taskName; + /** + * 任务参数 + */ + private String taskParams; + /** + * 任务处理状态 + */ + private Integer processStatus; + + /** + * 任务时长ms + */ + private Long processDuration; + + /** + * 处理日志 + */ + private String processLog; + + + private String ipAddress; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/service/QuartzTask.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/service/QuartzTask.java new file mode 100644 index 00000000..010ab318 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/service/QuartzTask.java @@ -0,0 +1,78 @@ +package com.gangquan360.smartadmin.module.quartz.service; + +import com.gangquan360.smartadmin.module.quartz.constant.QuartzConst; +import com.gangquan360.smartadmin.module.quartz.constant.TaskResultEnum; +import com.gangquan360.smartadmin.module.quartz.domain.entity.QuartzTaskEntity; +import com.gangquan360.smartadmin.module.quartz.domain.entity.QuartzTaskLogEntity; +import com.gangquan360.smartadmin.module.quartz.task.ITask; +import com.gangquan360.smartadmin.third.SmartApplicationContext; +import com.gangquan360.smartadmin.util.SmartIPUtil; +import com.gangquan360.smartadmin.util.SmartQuartzUtil; +import org.quartz.JobDetail; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.JobKey; +import org.springframework.scheduling.quartz.QuartzJobBean; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +public class QuartzTask extends QuartzJobBean { + + @Override + protected void executeInternal(JobExecutionContext context) throws JobExecutionException { + JobDetail jobDetail = context.getJobDetail(); + Object params = jobDetail.getJobDataMap().get(QuartzConst.QUARTZ_PARAMS_KEY); + JobKey jobKey = jobDetail.getKey(); + + Long taskId = SmartQuartzUtil.getTaskIdByJobKey(jobKey); + QuartzTaskService quartzTaskService = (QuartzTaskService) SmartApplicationContext.getBean("quartzTaskService"); + QuartzTaskEntity quartzTaskEntity = quartzTaskService.getByTaskId(taskId); + + QuartzTaskLogService quartzTaskLogService = (QuartzTaskLogService) SmartApplicationContext.getBean("quartzTaskLogService"); + + QuartzTaskLogEntity taskLogEntity = new QuartzTaskLogEntity(); + taskLogEntity.setTaskId(taskId); + taskLogEntity.setIpAddress(SmartIPUtil.getLocalHostIP()); + taskLogEntity.setTaskName(quartzTaskEntity.getTaskName()); + String paramsStr = null; + if (params != null) { + paramsStr = params.toString(); + taskLogEntity.setTaskParams(paramsStr); + } + taskLogEntity.setUpdateTime(new Date()); + taskLogEntity.setCreateTime(new Date()); + //任务开始时间 + long startTime = System.currentTimeMillis(); + try { + ITask taskClass = (ITask) SmartApplicationContext.getBean(quartzTaskEntity.getTaskBean()); + taskClass.execute(paramsStr); + taskLogEntity.setProcessStatus(TaskResultEnum.SUCCESS.getStatus()); + } catch (Exception e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw, true); + e.printStackTrace(pw); + pw.flush(); + sw.flush(); + taskLogEntity.setProcessStatus(TaskResultEnum.FAIL.getStatus()); + taskLogEntity.setProcessLog(sw.toString()); + } finally { + long times = System.currentTimeMillis() - startTime; + taskLogEntity.setProcessDuration(times); + quartzTaskLogService.save(taskLogEntity); + } + + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/service/QuartzTaskLogService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/service/QuartzTaskLogService.java new file mode 100644 index 00000000..8a396991 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/service/QuartzTaskLogService.java @@ -0,0 +1,28 @@ +package com.gangquan360.smartadmin.module.quartz.service; + +import com.gangquan360.smartadmin.module.quartz.dao.QuartzTaskLogDao; +import com.gangquan360.smartadmin.module.quartz.domain.entity.QuartzTaskLogEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 14:50 + * @since JDK1.8 + */ +@Service +public class QuartzTaskLogService { + + @Autowired + private QuartzTaskLogDao quartzTaskLogDao; + + + public void save(QuartzTaskLogEntity logEntity){ + quartzTaskLogDao.insert(logEntity); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/service/QuartzTaskService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/service/QuartzTaskService.java new file mode 100644 index 00000000..75c2f914 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/service/QuartzTaskService.java @@ -0,0 +1,316 @@ +package com.gangquan360.smartadmin.module.quartz.service; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.quartz.constant.QuartzConst; +import com.gangquan360.smartadmin.module.quartz.constant.TaskStatusEnum; +import com.gangquan360.smartadmin.module.quartz.dao.QuartzTaskDao; +import com.gangquan360.smartadmin.module.quartz.dao.QuartzTaskLogDao; +import com.gangquan360.smartadmin.module.quartz.domain.dto.*; +import com.gangquan360.smartadmin.module.quartz.domain.entity.QuartzTaskEntity; +import com.gangquan360.smartadmin.third.SmartApplicationContext; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import com.gangquan360.smartadmin.util.SmartQuartzUtil; +import lombok.extern.slf4j.Slf4j; +import org.quartz.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 14:50 + * @since JDK1.8 + */ +@Slf4j +@Service +public class QuartzTaskService { + + @Autowired + private QuartzTaskDao quartzTaskDao; + + @Autowired + private QuartzTaskLogDao quartzTaskLogDao; + + @Autowired + private Scheduler scheduler; + + /** + * 查询列表 + * + * @param queryDTO + * @return + */ + public ResponseDTO> query(QuartzQueryDTO queryDTO) { + Page pageParam = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List taskList = quartzTaskDao.queryList(pageParam, queryDTO); + pageParam.setRecords(taskList); + return ResponseDTO.succData(SmartPaginationUtil.convert2PageInfoDTO(pageParam)); + } + + /** + * 查询运行日志 + * + * @param queryDTO + * @return + */ + public ResponseDTO> queryLog(QuartzLogQueryDTO queryDTO) { + Page pageParam = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List taskList = quartzTaskLogDao.queryList(pageParam, queryDTO); + pageParam.setRecords(taskList); + return ResponseDTO.succData(SmartPaginationUtil.convert2PageInfoDTO(pageParam)); + } + + /** + * 保存或更新 + * + * @param quartzTaskDTO + * @return + * @throws Exception + */ + @Transactional(rollbackFor = Throwable.class) + public ResponseDTO saveOrUpdateTask(QuartzTaskDTO quartzTaskDTO) throws Exception { + ResponseDTO baseValid = this.baseValid(quartzTaskDTO); + if (! baseValid.isSuccess()) { + return baseValid; + } + Long taskId = quartzTaskDTO.getId(); + if (taskId == null) { + return this.saveTask(quartzTaskDTO); + } else { + return this.updateTask(quartzTaskDTO); + } + } + + private ResponseDTO baseValid(QuartzTaskDTO quartzTaskDTO) { + Object taskBean = null; + try { + taskBean = SmartApplicationContext.getBean(quartzTaskDTO.getTaskBean()); + } catch (Exception e) { + log.error("taskBean 不存在{}", e); + } + if (taskBean == null) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "taskBean 不存在"); + } + if (! CronExpression.isValidExpression(quartzTaskDTO.getTaskCron())) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "请传入正确的正则表达式"); + } + return ResponseDTO.succ(); + } + + private ResponseDTO saveTask(QuartzTaskDTO quartzTaskDTO) throws Exception { + QuartzTaskEntity taskEntity = SmartBeanUtil.copy(quartzTaskDTO, QuartzTaskEntity.class); + taskEntity.setTaskStatus(TaskStatusEnum.NORMAL.getStatus()); + taskEntity.setUpdateTime(new Date()); + taskEntity.setCreateTime(new Date()); + quartzTaskDao.insert(taskEntity); + this.createQuartzTask(scheduler, taskEntity); + return ResponseDTO.succ(); + } + + private ResponseDTO updateTask(QuartzTaskDTO quartzTaskDTO) throws Exception { + QuartzTaskEntity updateEntity = quartzTaskDao.selectById(quartzTaskDTO.getId()); + if (updateEntity == null) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "task不存在"); + } + QuartzTaskEntity taskEntity = SmartBeanUtil.copy(quartzTaskDTO, QuartzTaskEntity.class); + //任务状态不能更新 + taskEntity.setTaskStatus(updateEntity.getTaskStatus()); + taskEntity.setUpdateTime(new Date()); + quartzTaskDao.updateById(taskEntity); + this.updateQuartzTask(scheduler, taskEntity); + return ResponseDTO.succ(); + } + + /** + * 立即运行 + * + * @param taskId + * @return + * @throws Exception + */ + public ResponseDTO runTask(Long taskId) throws Exception { + QuartzTaskEntity quartzTaskEntity = quartzTaskDao.selectById(taskId); + if (quartzTaskEntity == null) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "task不存在"); + } + this.runQuartzTask(scheduler, quartzTaskEntity); + return ResponseDTO.succ(); + } + + /** + * 暂停运行 + * + * @param taskId + * @return + * @throws Exception + */ + @Transactional(rollbackFor = Throwable.class) + public ResponseDTO pauseTask(Long taskId) throws Exception { + QuartzTaskEntity quartzTaskEntity = quartzTaskDao.selectById(taskId); + if (quartzTaskEntity == null) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "task不存在"); + } + quartzTaskEntity.setTaskStatus(TaskStatusEnum.PAUSE.getStatus()); + quartzTaskDao.updateById(quartzTaskEntity); + this.pauseQuartzTask(scheduler, taskId); + return ResponseDTO.succ(); + } + + /** + * 恢复任务 + * + * @param taskId + * @return + * @throws Exception + */ + @Transactional(rollbackFor = Throwable.class) + public ResponseDTO resumeTask(Long taskId) throws Exception { + QuartzTaskEntity quartzTaskEntity = quartzTaskDao.selectById(taskId); + if (quartzTaskEntity == null) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "task不存在"); + } + quartzTaskEntity.setTaskStatus(TaskStatusEnum.NORMAL.getStatus()); + quartzTaskDao.updateById(quartzTaskEntity); + this.resumeQuartzTask(scheduler, taskId); + return ResponseDTO.succ(); + } + + /** + * 删除任务 + * + * @param taskId + * @return + * @throws Exception + */ + public ResponseDTO deleteTask(Long taskId) throws Exception { + QuartzTaskEntity quartzTaskEntity = quartzTaskDao.selectById(taskId); + if (quartzTaskEntity == null) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "task不存在"); + } + quartzTaskDao.deleteById(taskId); + this.deleteQuartzTask(scheduler, taskId); + return ResponseDTO.succ(); + } + + /** + * 通过任务Id 获取任务实体 + * + * @param taskId + * @return + */ + public QuartzTaskEntity getByTaskId(Long taskId) { + return quartzTaskDao.selectById(taskId); + } + + /** + * 创建任务 + * + * @param scheduler + * @param taskEntity + * @throws Exception + */ + public void createQuartzTask(Scheduler scheduler, QuartzTaskEntity taskEntity) throws Exception { + JobKey jobKey = SmartQuartzUtil.getJobKey(taskEntity.getId()); + JobDetail jobDetail = JobBuilder.newJob(QuartzTask.class).withIdentity(jobKey).build(); + + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(taskEntity.getTaskCron()).withMisfireHandlingInstructionDoNothing(); + + TriggerKey triggerKey = SmartQuartzUtil.getTriggerKey(Long.valueOf(taskEntity.getId())); + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); + + jobDetail.getJobDataMap().put(QuartzConst.QUARTZ_PARAMS_KEY, taskEntity.getTaskParams()); + scheduler.scheduleJob(jobDetail, trigger); + } + + /** + * 更新任务 + * + * @param scheduler + * @param taskEntity + * @throws Exception + */ + private void updateQuartzTask(Scheduler scheduler, QuartzTaskEntity taskEntity) throws Exception { + TriggerKey triggerKey = SmartQuartzUtil.getTriggerKey(Long.valueOf(taskEntity.getId())); + + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(taskEntity.getTaskCron()).withMisfireHandlingInstructionDoNothing(); + + CronTrigger trigger = this.getCronTrigger(scheduler, Long.valueOf(taskEntity.getId())); + + trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); + + trigger.getJobDataMap().put(QuartzConst.QUARTZ_PARAMS_KEY, taskEntity.getTaskParams()); + + scheduler.rescheduleJob(triggerKey, trigger); + //如果更新之前任务是暂停状态,此时再次暂停任务 + if (TaskStatusEnum.PAUSE.getStatus().equals(taskEntity.getTaskStatus())) { + this.pauseQuartzTask(scheduler, Long.valueOf(taskEntity.getId())); + } + } + + private CronTrigger getCronTrigger(Scheduler scheduler, Long taskId) throws Exception { + TriggerKey triggerKey = SmartQuartzUtil.getTriggerKey(taskId); + return (CronTrigger) scheduler.getTrigger(triggerKey); + } + + /** + * 立即运行 + * + * @param scheduler + * @param taskEntity + * @throws Exception + */ + private void runQuartzTask(Scheduler scheduler, QuartzTaskEntity taskEntity) throws Exception { + JobDataMap dataMap = new JobDataMap(); + dataMap.put(QuartzConst.QUARTZ_PARAMS_KEY, taskEntity.getTaskParams()); + JobKey jobKey = SmartQuartzUtil.getJobKey(taskEntity.getId()); + scheduler.triggerJob(jobKey, dataMap); + } + + /** + * 暂停任务 + * + * @param scheduler + * @param taskId + * @throws Exception + */ + private void pauseQuartzTask(Scheduler scheduler, Long taskId) throws Exception { + JobKey jobKey = SmartQuartzUtil.getJobKey(taskId); + scheduler.pauseJob(jobKey); + } + + /** + * 恢复任务 + * + * @param scheduler + * @param taskId + * @throws Exception + */ + private void resumeQuartzTask(Scheduler scheduler, Long taskId) throws Exception { + JobKey jobKey = SmartQuartzUtil.getJobKey(taskId); + scheduler.resumeJob(jobKey); + } + + /** + * 删除任务 + * + * @param scheduler + * @param taskId + * @throws Exception + */ + private void deleteQuartzTask(Scheduler scheduler, Long taskId) throws Exception { + JobKey jobKey = SmartQuartzUtil.getJobKey(taskId); + scheduler.deleteJob(jobKey); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/task/ITask.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/task/ITask.java new file mode 100644 index 00000000..cfdd3067 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/task/ITask.java @@ -0,0 +1,16 @@ +package com.gangquan360.smartadmin.module.quartz.task; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 14:23 + * @since JDK1.8 + */ +public interface ITask { + + void execute(String paramJson) throws Exception; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/task/test/Example.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/task/test/Example.java new file mode 100644 index 00000000..a4c4b43f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/quartz/task/test/Example.java @@ -0,0 +1,26 @@ +package com.gangquan360.smartadmin.module.quartz.task.test; + +import com.gangquan360.smartadmin.module.quartz.task.ITask; +import com.gangquan360.smartadmin.util.SmartDateUtil; +import org.springframework.stereotype.Component; + +import java.util.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 14:26 + * @since JDK1.8 + */ +@Component("exampleTask") +public class Example implements ITask { + + @Override + public void execute(String paramJson) throws Exception { + System.out.println(SmartDateUtil.formatYMDHMS(new Date()) + ",今天搬了" + System.currentTimeMillis() + "块砖,paramJson:" + paramJson); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleController.java new file mode 100644 index 00000000..88ff9ab5 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleController.java @@ -0,0 +1,60 @@ +package com.gangquan360.smartadmin.module.role.basic; +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleAddDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleUpdateDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 角色管理路由 + * + * @author listen + * @date 2017/12/28 10:10 + */ +@Api(tags = {SwaggerTagConst.Admin.MANAGER_ROLE}) +@OperateLog +@RestController +public class RoleController { + + @Autowired + private RoleService roleService; + + @ApiOperation(value = "添加角色", notes = "添加角色") + @PostMapping("/role/add") + public ResponseDTO addRole(@Valid @RequestBody RoleAddDTO roleAddDTO) { + return roleService.addRole(roleAddDTO); + } + + @ApiOperation(value = "删除角色", notes = "根据id删除角色") + @GetMapping("/role/delete/{roleId}") + public ResponseDTO deleteRole(@PathVariable("roleId") Long roleId) { + return roleService.deleteRole(roleId); + } + + @ApiOperation(value = "更新角色", notes = "更新角色") + @PostMapping("/role/update") + public ResponseDTO updateRole(@Valid @RequestBody RoleUpdateDTO roleUpdateDTO) { + return roleService.updateRole(roleUpdateDTO); + } + + @ApiOperation(value = "获取角色数据", notes = "根据id获取角色数据") + @GetMapping("/role/get/{roleId}") + public ResponseDTO getRole(@PathVariable("roleId") Long roleId) { + return roleService.getRoleById(roleId); + } + + @ApiOperation(value = "获取所有角色", notes = "获取所有角色数据") + @GetMapping("/role/getAll") + public ResponseDTO> getAllRole() { + return roleService.getAllRole(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleDao.java new file mode 100644 index 00000000..22c6c1e2 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleDao.java @@ -0,0 +1,26 @@ +package com.gangquan360.smartadmin.module.role.basic; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.gangquan360.smartadmin.module.role.basic.domain.entity.RoleEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 13:00 + * @since JDK1.8 + */ +@Mapper +@Component +public interface RoleDao extends BaseMapper { + + + RoleEntity getByRoleName(@Param("roleName") String name); + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleResponseCodeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleResponseCodeConst.java new file mode 100644 index 00000000..62bb0573 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleResponseCodeConst.java @@ -0,0 +1,24 @@ +package com.gangquan360.smartadmin.module.role.basic; +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + +/** + * + * @author yandanyang + * 角色业务状态码 6001 - 6999 + */ +public class RoleResponseCodeConst extends ResponseCodeConst { + + /** + * 10501 角色名称已存在 + */ + public static final RoleResponseCodeConst ROLE_NAME_EXISTS = new RoleResponseCodeConst(6001, "角色名称已存在"); + + /** + * 10502 角色不存在 + */ + public static final RoleResponseCodeConst ROLE_NOT_EXISTS = new RoleResponseCodeConst(6002, "角色不存在"); + + public RoleResponseCodeConst(int code, String msg) { + super(code, msg); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleService.java new file mode 100644 index 00000000..9f90c3ae --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/RoleService.java @@ -0,0 +1,115 @@ +package com.gangquan360.smartadmin.module.role.basic; + +import com.baomidou.mybatisplus.mapper.EntityWrapper; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleAddDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleUpdateDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleVO; +import com.gangquan360.smartadmin.module.role.basic.domain.entity.RoleEntity; +import com.gangquan360.smartadmin.module.role.roleemployee.RoleEmployeeDao; +import com.gangquan360.smartadmin.module.role.roleprivilege.RolePrivilegeDao; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 角色管理业务 + * + * @author listen + * @date 2017/12/28 09:37 + */ +@Service +public class RoleService { + + @Autowired + private RoleDao roleDao; + + @Autowired + private RolePrivilegeDao rolePrivilegeDao; + + @Autowired + private RoleEmployeeDao roleEmployeeDao; + + /** + * 新增添加角色 + * + * @param roleAddDTO + * @return ResponseDTO + */ + public ResponseDTO addRole(RoleAddDTO roleAddDTO) { + RoleEntity employeeRoleEntity = roleDao.getByRoleName(roleAddDTO.getRoleName()); + if (null != employeeRoleEntity) { + return ResponseDTO.wrap(RoleResponseCodeConst.ROLE_NAME_EXISTS); + } + RoleEntity roleEntity = SmartBeanUtil.copy(roleAddDTO, RoleEntity.class); + roleDao.insert(roleEntity); + return ResponseDTO.succ(); + } + + /** + * 根据角色id 删除 + * + * @param roleId + * @return ResponseDTO + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO deleteRole(Long roleId) { + RoleEntity roleEntity = roleDao.selectById(roleId); + if (null == roleEntity) { + return ResponseDTO.wrap(RoleResponseCodeConst.ROLE_NOT_EXISTS); + } + roleDao.deleteById(roleId); + rolePrivilegeDao.deleteByRoleId(roleId); + roleEmployeeDao.deleteByRoleId(roleId); + return ResponseDTO.succ(); + } + + /** + * 更新角色 + * + * @param roleUpdateDTO + * @return ResponseDTO + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateRole(RoleUpdateDTO roleUpdateDTO) { + if (null == roleDao.selectById(roleUpdateDTO.getId())) { + return ResponseDTO.wrap(RoleResponseCodeConst.ROLE_NOT_EXISTS); + } + RoleEntity employeeRoleEntity = roleDao.getByRoleName(roleUpdateDTO.getRoleName()); + if (null != employeeRoleEntity && ! employeeRoleEntity.getId().equals(roleUpdateDTO.getId())) { + return ResponseDTO.wrap(RoleResponseCodeConst.ROLE_NAME_EXISTS); + } + RoleEntity roleEntity = SmartBeanUtil.copy(roleUpdateDTO, RoleEntity.class); + roleDao.updateById(roleEntity); + return ResponseDTO.succ(); + } + + /** + * 根据id获取角色数据 + * + * @param roleId + * @return ResponseDTO + */ + public ResponseDTO getRoleById(Long roleId) { + RoleEntity roleEntity = roleDao.selectById(roleId); + if (null == roleEntity) { + return ResponseDTO.wrap(RoleResponseCodeConst.ROLE_NOT_EXISTS); + } + RoleVO role = SmartBeanUtil.copy(roleEntity, RoleVO.class); + return ResponseDTO.succData(role); + } + + /** + * 获取所有角色列表 + * + * @return ResponseDTO + */ + public ResponseDTO> getAllRole() { + List roleEntityList = roleDao.selectList(new EntityWrapper()); + List roleList = SmartBeanUtil.copyList(roleEntityList, RoleVO.class); + return ResponseDTO.succData(roleList); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleAddDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleAddDTO.java new file mode 100644 index 00000000..f0f5af9a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleAddDTO.java @@ -0,0 +1,33 @@ +package com.gangquan360.smartadmin.module.role.basic.domain.dto; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; + +/** + * 角色添加DTO + * + * @author listen + * @date 2017/12/28 09:40 + */ +@Data +public class RoleAddDTO { + + /** + * 角色名称 + */ + @ApiModelProperty("角色名称") + @NotNull(message = "角色名称不能为空") + @Length(min = 1, max = 20, message = "角色名称(1-20)个字符") + private String roleName; + + /** + * 角色描述 + */ + @ApiModelProperty("角色描述") + @Length(max = 255, message = "角色描述最多255个字符") + private String remark; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleBatchDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleBatchDTO.java new file mode 100644 index 00000000..487675ca --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleBatchDTO.java @@ -0,0 +1,30 @@ +package com.gangquan360.smartadmin.module.role.basic.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 批量添加角色员工DTO + * + * @author listen + * @date 2017/12/29 15:38 + */ +@Data +public class RoleBatchDTO { + + @ApiModelProperty("角色id") + @NotNull(message = "角色id不能为空") + protected Long roleId; + + /** + * 员工id集合 + */ + @ApiModelProperty(value = "员工id集合") + @NotEmpty(message = "员工id不能为空") + protected List employeeIds; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleQueryDTO.java new file mode 100644 index 00000000..b46eda46 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleQueryDTO.java @@ -0,0 +1,25 @@ +package com.gangquan360.smartadmin.module.role.basic.domain.dto; +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +public class RoleQueryDTO extends PageParamDTO { + + @ApiModelProperty("角色名称") + private String roleName; + + @ApiModelProperty("角色id") + private String roleId; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleSelectedVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleSelectedVO.java new file mode 100644 index 00000000..b16854f6 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleSelectedVO.java @@ -0,0 +1,21 @@ +package com.gangquan360.smartadmin.module.role.basic.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 15:27 + * @since JDK1.8 + */ +@Data +public class RoleSelectedVO extends RoleVO { + + @ApiModelProperty("角色名称") + private Boolean selected; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleUpdateDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleUpdateDTO.java new file mode 100644 index 00000000..27f6a773 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleUpdateDTO.java @@ -0,0 +1,24 @@ +package com.gangquan360.smartadmin.module.role.basic.domain.dto; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 角色更新修改DTO + * + * @author listen + * @date 2017/12/28 09:40 + */ +@Data +public class RoleUpdateDTO extends RoleAddDTO { + + /** + * 角色id + */ + @ApiModelProperty("角色id") + @NotNull(message = "角色id不能为空") + protected Long id; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleVO.java new file mode 100644 index 00000000..f8bdbbdd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/dto/RoleVO.java @@ -0,0 +1,27 @@ +package com.gangquan360.smartadmin.module.role.basic.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 15:27 + * @since JDK1.8 + */ +@Data +public class RoleVO { + + @ApiModelProperty("角色ID") + private Long id; + + @ApiModelProperty("角色名称") + private String roleName; + + @ApiModelProperty("角色备注") + private String remark; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/entity/RoleEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/entity/RoleEntity.java new file mode 100644 index 00000000..ab28dca9 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/basic/domain/entity/RoleEntity.java @@ -0,0 +1,25 @@ +package com.gangquan360.smartadmin.module.role.basic.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * [ 角色 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 13:01 + * @since JDK1.8 + */ +@Data +@TableName("t_role") +public class RoleEntity extends BaseEntity { + + + private String roleName; + + private String remark; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/RoleEmployeeController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/RoleEmployeeController.java new file mode 100644 index 00000000..12045d46 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/RoleEmployeeController.java @@ -0,0 +1,73 @@ +package com.gangquan360.smartadmin.module.role.roleemployee; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.employee.domain.vo.EmployeeVO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleBatchDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleQueryDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleSelectedVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 用户角色管理路由 + * + * @author listen + * @date 2017/12/28 10:10 + */ +@Api(tags = {SwaggerTagConst.Admin.MANAGER_ROLE_USER}) +@OperateLog +@RestController +public class RoleEmployeeController { + + @Autowired + private RoleEmployeeService roleEmployeeService; + + @ApiOperation(value = "获取角色成员-员工列表", notes = "获取角色成员-员工列表(分页)") + @PostMapping("/role/listEmployee") + public ResponseDTO> listEmployeeByName(@Valid @RequestBody RoleQueryDTO queryDTO) { + return roleEmployeeService.listEmployeeByName(queryDTO); + } + + @ApiOperation(value = "根据角色id获取角色员工列表(无分页)", notes = "根据角色id获取角色成员-员工列表") + @GetMapping("/role/listAllEmployee/{roleId}") + public ResponseDTO> listAllEmployeeRoleId(@PathVariable Long roleId) { + return roleEmployeeService.getAllEmployeeByRoleId(roleId); + } + + @ApiOperation(value = "从角色成员列表中移除员工", notes = "从角色成员列表中移除员工") + @ApiImplicitParams({@ApiImplicitParam(name = "employeeId", value = "员工id", paramType = "query", required = true), @ApiImplicitParam(name = "roleId", value = "角色id", paramType = "query", + required = true)}) + @GetMapping("/role/removeEmployee") + public ResponseDTO removeEmployee(Long employeeId, Long roleId) { + return roleEmployeeService.removeEmployeeRole(employeeId, roleId); + } + + @ApiOperation(value = "从角色成员列表中批量移除员工", notes = "从角色成员列表中批量移除员工") + @PostMapping("/role/removeEmployeeList") + public ResponseDTO removeEmployeeList(@Valid @RequestBody RoleBatchDTO removeDTO) { + return roleEmployeeService.batchRemoveEmployeeRole(removeDTO); + } + + @ApiOperation(value = "角色成员列表中批量添加员工", notes = "角色成员列表中批量添加员工") + @PostMapping("/role/addEmployeeList") + public ResponseDTO addEmployeeList(@Valid @RequestBody RoleBatchDTO addDTO) { + return roleEmployeeService.batchAddEmployeeRole(addDTO); + } + + @ApiOperation(value = "通过员工id获取所有角色以及员工具有的角色", notes = "通过员工id获取所有角色以及员工具有的角色") + @GetMapping("/role/getRoles/{employeeId}") + @ApiImplicitParams({@ApiImplicitParam(name = "employeeId", value = "员工id", paramType = "path", required = true)}) + public ResponseDTO> getRoleByEmployeeId(@PathVariable Long employeeId) { + return roleEmployeeService.getRolesByEmployeeId(employeeId); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/RoleEmployeeDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/RoleEmployeeDao.java new file mode 100644 index 00000000..5f09bd37 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/RoleEmployeeDao.java @@ -0,0 +1,80 @@ +package com.gangquan360.smartadmin.module.role.roleemployee; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleQueryDTO; +import com.gangquan360.smartadmin.module.role.roleemployee.domain.RoleEmployeeEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 13:00 + * @since JDK1.8 + */ +@Mapper +@Component +public interface RoleEmployeeDao extends BaseMapper { + + /** + * 根据员工id 查询所有的角色 + * @param employeeId + * @return + */ + List selectRoleIdByEmployeeId(@Param("employeeId") Long employeeId); + + /** + * + * @param page + * @param queryDTO + * @return + */ + List selectEmployeeByNamePage(Page page,@Param("queryDTO") RoleQueryDTO queryDTO); + + /** + * + * @param roleId + * @return + */ + List selectEmployeeByRoleId(@Param("roleId") Long roleId); + /** + * 根据员工信息删除 + * @param employeeId + */ + void deleteByEmployeeId(@Param("employeeId") Long employeeId); + + /** + * 删除某个角色的所有关系 + * @param roleId + */ + void deleteByRoleId(@Param("roleId")Long roleId); + + /** + * 根据员工和 角色删除关系 + * @param employeeId + * @param roleId + */ + void deleteByEmployeeIdRoleId(@Param("employeeId") Long employeeId,@Param("roleId")Long roleId); + + /** + * 批量删除某个角色下的某批用户的关联关系 + * @param roleId + * @param employeeIds + */ + void batchDeleteEmployeeRole(@Param("roleId") Long roleId,@Param("employeeIds")List employeeIds); + + /** + * 批量新增 + * @param roleRelationList + */ + void batchInsert(List roleRelationList); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/RoleEmployeeService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/RoleEmployeeService.java new file mode 100644 index 00000000..e49ad43a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/RoleEmployeeService.java @@ -0,0 +1,133 @@ +package com.gangquan360.smartadmin.module.role.roleemployee; + +import com.baomidou.mybatisplus.mapper.EntityWrapper; +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.department.DepartmentDao; +import com.gangquan360.smartadmin.module.department.domain.entity.DepartmentEntity; +import com.gangquan360.smartadmin.module.employee.domain.dto.EmployeeDTO; +import com.gangquan360.smartadmin.module.employee.domain.vo.EmployeeVO; +import com.gangquan360.smartadmin.module.role.basic.RoleDao; +import com.gangquan360.smartadmin.module.role.basic.RoleResponseCodeConst; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleBatchDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleQueryDTO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleSelectedVO; +import com.gangquan360.smartadmin.module.role.basic.domain.dto.RoleVO; +import com.gangquan360.smartadmin.module.role.roleemployee.domain.RoleEmployeeEntity; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import com.google.common.collect.Lists; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 角色管理业务 + * + * @author zzr + * @date 2019/4/3 + */ +@Service +public class RoleEmployeeService { + + @Autowired + private RoleEmployeeDao roleEmployeeDao; + + @Autowired + private RoleDao roleDao; + + @Autowired + private DepartmentDao departmentDao; + + /** + * 通过角色id,分页获取成员员工列表 + * + * @param queryDTO + * @return + */ + public ResponseDTO> listEmployeeByName(RoleQueryDTO queryDTO) { + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List employeeDTOS = roleEmployeeDao.selectEmployeeByNamePage(page, queryDTO); + employeeDTOS.stream().filter(e -> e.getDepartmentId() != null).forEach(employeeDTO -> { + DepartmentEntity departmentEntity = departmentDao.selectById(employeeDTO.getDepartmentId()); + employeeDTO.setDepartmentName(departmentEntity.getName()); + }); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page, employeeDTOS, EmployeeVO.class); + return ResponseDTO.succData(pageResultDTO); + } + + public ResponseDTO> getAllEmployeeByRoleId(Long roleId) { + List employeeDTOS = roleEmployeeDao.selectEmployeeByRoleId(roleId); + List list = SmartBeanUtil.copyList(employeeDTOS, EmployeeVO.class); + return ResponseDTO.succData(list); + } + + /** + * 移除员工角色 + * + * @param employeeId + * @param roleId + * @return ResponseDTO + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO removeEmployeeRole(Long employeeId, Long roleId) { + if (null == employeeId || null == roleId) { + return ResponseDTO.wrap(RoleResponseCodeConst.ERROR_PARAM); + } + roleEmployeeDao.deleteByEmployeeIdRoleId(employeeId, roleId); + return ResponseDTO.succ(); + } + + /** + * 批量删除角色的成员员工 + * + * @param removeDTO + * @return ResponseDTO + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO batchRemoveEmployeeRole(RoleBatchDTO removeDTO) { + List employeeIdList = removeDTO.getEmployeeIds(); + roleEmployeeDao.batchDeleteEmployeeRole(removeDTO.getRoleId(), employeeIdList); + return ResponseDTO.succ(); + } + + /** + * 批量添加角色的成员员工 + * + * @param addDTO + * @return ResponseDTO + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO batchAddEmployeeRole(RoleBatchDTO addDTO) { + Long roleId = addDTO.getRoleId(); + List employeeIdList = addDTO.getEmployeeIds(); + roleEmployeeDao.deleteByRoleId(roleId); + List roleRelationEntities = Lists.newArrayList(); + RoleEmployeeEntity employeeRoleRelationEntity; + for (Long employeeId : employeeIdList) { + employeeRoleRelationEntity = new RoleEmployeeEntity(); + employeeRoleRelationEntity.setRoleId(roleId); + employeeRoleRelationEntity.setEmployeeId(employeeId); + roleRelationEntities.add(employeeRoleRelationEntity); + } + roleEmployeeDao.batchInsert(roleRelationEntities); + return ResponseDTO.succ(); + } + + /** + * 通过员工id获取员工角色 + * + * @param employeeId + * @return + */ + public ResponseDTO> getRolesByEmployeeId(Long employeeId) { + List roleIds = roleEmployeeDao.selectRoleIdByEmployeeId(employeeId); + List roleList = roleDao.selectList(new EntityWrapper()); + List result = SmartBeanUtil.copyList(roleList, RoleSelectedVO.class); + result.stream().forEach(item -> item.setSelected(roleIds.contains(item.getId()))); + return ResponseDTO.succData(result); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/domain/RoleEmployeeDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/domain/RoleEmployeeDTO.java new file mode 100644 index 00000000..1578bdbc --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/domain/RoleEmployeeDTO.java @@ -0,0 +1,21 @@ +package com.gangquan360.smartadmin.module.role.roleemployee.domain; + +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 15:27 + * @since JDK1.8 + */ +@Data +public class RoleEmployeeDTO { + + private Long roleId; + + private Long employeeId; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/domain/RoleEmployeeEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/domain/RoleEmployeeEntity.java new file mode 100644 index 00000000..75337357 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleemployee/domain/RoleEmployeeEntity.java @@ -0,0 +1,24 @@ +package com.gangquan360.smartadmin.module.role.roleemployee.domain; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * [ 角色 员工关系] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/27 0027 下午 13:01 + * @since JDK1.8 + */ +@Data +@TableName("t_role_employee") +public class RoleEmployeeEntity extends BaseEntity{ + + private Long roleId; + + private Long employeeId; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/RolePrivilegeController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/RolePrivilegeController.java new file mode 100644 index 00000000..63fa38fa --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/RolePrivilegeController.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.module.role.roleprivilege; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.role.roleprivilege.domain.dto.RolePrivilegeDTO; +import com.gangquan360.smartadmin.module.role.roleprivilege.domain.dto.RolePrivilegeTreeVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * [ 与员工权限相关:角色权限关系、权限列表 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@OperateLog +@RestController +@Api(tags = {SwaggerTagConst.Admin.MANAGER_ROLE_PRIVILEGE}) +public class RolePrivilegeController { + + @Autowired + private RolePrivilegeService rolePrivilegeService; + + @ApiOperation(value = "更新角色权限", notes = "更新角色权限") + @PostMapping("/privilege/updateRolePrivilege") + public ResponseDTO updateRolePrivilege(@Valid @RequestBody RolePrivilegeDTO updateDTO) { + return rolePrivilegeService.updateRolePrivilege(updateDTO); + } + + @ApiOperation(value = "获取角色可选的功能权限", notes = "获取角色可选的功能权限") + @GetMapping("/privilege/listPrivilegeByRoleId/{roleId}") + public ResponseDTO listPrivilegeByRoleId(@PathVariable("roleId") Long roleId) { + return rolePrivilegeService.listPrivilegeByRoleId(roleId); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/RolePrivilegeDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/RolePrivilegeDao.java new file mode 100644 index 00000000..2c2bff6b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/RolePrivilegeDao.java @@ -0,0 +1,58 @@ +package com.gangquan360.smartadmin.module.role.roleprivilege; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.gangquan360.smartadmin.module.privilege.domain.entity.PrivilegeEntity; +import com.gangquan360.smartadmin.module.role.roleprivilege.domain.entity.RolePrivilegeEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/28 0028 下午 12:23 + * @since JDK1.8 + */ +@Mapper +@Component +public interface RolePrivilegeDao extends BaseMapper { + + /** + * 根据角色id删除 + * @param roleId + */ + void deleteByRoleId(@Param("roleId")Long roleId); + + /** + * 删除权限所关联的角色信息 + * @param privilegeKeyList + */ + void deleteByPrivilegeKey(@Param("privilegeKeyList")List privilegeKeyList); + + + /** + * 批量添加 + * @param rolePrivilegeList + */ + void batchInsert(List rolePrivilegeList); + + /** + * 查询某批角色的权限 + * @param roleIds + * @return + */ + List listByRoleIds(@Param("roleIds")List roleIds,@Param("normalStatus")Integer normalStatus); + + /** + * 查询某个角色的权限 + * @param roleId + * @return + */ + List listByRoleId(@Param("roleId")Long roleId); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/RolePrivilegeService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/RolePrivilegeService.java new file mode 100644 index 00000000..28017fcf --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/RolePrivilegeService.java @@ -0,0 +1,129 @@ +package com.gangquan360.smartadmin.module.role.roleprivilege; + +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.module.privilege.dao.PrivilegeDao; +import com.gangquan360.smartadmin.module.privilege.domain.entity.PrivilegeEntity; +import com.gangquan360.smartadmin.module.privilege.service.PrivilegeEmployeeService; +import com.gangquan360.smartadmin.module.role.basic.RoleDao; +import com.gangquan360.smartadmin.module.role.basic.RoleResponseCodeConst; +import com.gangquan360.smartadmin.module.role.basic.domain.entity.RoleEntity; +import com.gangquan360.smartadmin.module.role.roleprivilege.domain.dto.RolePrivilegeDTO; +import com.gangquan360.smartadmin.module.role.roleprivilege.domain.dto.RolePrivilegeSimpleDTO; +import com.gangquan360.smartadmin.module.role.roleprivilege.domain.dto.RolePrivilegeTreeVO; +import com.gangquan360.smartadmin.module.role.roleprivilege.domain.entity.RolePrivilegeEntity; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * [ 后台员工权限 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Service +public class RolePrivilegeService { + + @Autowired + private PrivilegeDao privilegeDao; + + @Autowired + private RoleDao roleDao; + + @Autowired + private RolePrivilegeDao rolePrivilegeDao; + + @Autowired + private PrivilegeEmployeeService privilegeEmployeeService; + + /** + * 更新角色权限 + * + * @param updateDTO + * @return ResponseDTO + */ + public ResponseDTO updateRolePrivilege(RolePrivilegeDTO updateDTO) { + Long roleId = updateDTO.getRoleId(); + RoleEntity roleEntity = roleDao.selectById(roleId); + if (null == roleEntity) { + return ResponseDTO.wrap(RoleResponseCodeConst.ROLE_NOT_EXISTS); + } + rolePrivilegeDao.deleteByRoleId(roleId); + List rolePrivilegeList = Lists.newArrayList(); + RolePrivilegeEntity rolePrivilegeEntity; + for (String privilegeKey : updateDTO.getPrivilegeKeyList()) { + rolePrivilegeEntity = new RolePrivilegeEntity(); + rolePrivilegeEntity.setRoleId(roleId); + rolePrivilegeEntity.setPrivilegeKey(privilegeKey); + rolePrivilegeList.add(rolePrivilegeEntity); + } + rolePrivilegeDao.batchInsert(rolePrivilegeList); + privilegeEmployeeService.updateOnlineEmployeePrivilegeByRoleId(roleId); + return ResponseDTO.succ(); + } + + public ResponseDTO listPrivilegeByRoleId(Long roleId) { + RolePrivilegeTreeVO rolePrivilegeTreeDTO = new RolePrivilegeTreeVO(); + rolePrivilegeTreeDTO.setRoleId(roleId); + + List privilegeDTOList = privilegeDao.selectAll(); + if (CollectionUtils.isEmpty(privilegeDTOList)) { + rolePrivilegeTreeDTO.setPrivilege(Lists.newArrayList()); + rolePrivilegeTreeDTO.setSelectedKey(Lists.newArrayList()); + return ResponseDTO.succData(rolePrivilegeTreeDTO); + } + //构造权限树 + List privilegeList = this.buildPrivilegeTree(privilegeDTOList); + //设置选中状态 + List rolePrivilegeEntityList = rolePrivilegeDao.listByRoleId(roleId); + List privilegeKeyList = rolePrivilegeEntityList.stream().map(e -> e.getKey()).collect(Collectors.toList()); + rolePrivilegeTreeDTO.setPrivilege(privilegeList); + rolePrivilegeTreeDTO.setSelectedKey(privilegeKeyList); + return ResponseDTO.succData(rolePrivilegeTreeDTO); + } + + private List buildPrivilegeTree(List privilegeEntityList) { + List privilegeTree = Lists.newArrayList(); + List rootPrivilege = privilegeEntityList.stream().filter(e -> e.getParentKey() == null).collect(Collectors.toList()); + rootPrivilege.sort(Comparator.comparing(PrivilegeEntity::getSort)); + if (CollectionUtils.isEmpty(rootPrivilege)) { + return privilegeTree; + } + privilegeTree = SmartBeanUtil.copyList(rootPrivilege, RolePrivilegeSimpleDTO.class); + privilegeTree.forEach(e -> e.setChildren(Lists.newArrayList())); + this.buildChildPrivilegeList(privilegeEntityList, privilegeTree); + return privilegeTree; + } + + private void buildChildPrivilegeList(List privilegeEntityList, List parentMenuList) { + List parentKeyList = parentMenuList.stream().map(RolePrivilegeSimpleDTO :: getKey).collect(Collectors.toList()); + List childEntityList = privilegeEntityList.stream().filter(e -> parentKeyList.contains(e.getParentKey())).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(childEntityList)) { + return; + } + Map> listMap = childEntityList.stream().collect(Collectors.groupingBy(PrivilegeEntity :: getParentKey)); + for (RolePrivilegeSimpleDTO rolePrivilegeSimpleDTO : parentMenuList) { + String key = rolePrivilegeSimpleDTO.getKey(); + List privilegeEntities = listMap.get(key); + if (CollectionUtils.isEmpty(privilegeEntities)) { + continue; + } + privilegeEntities.sort(Comparator.comparing(PrivilegeEntity::getSort)); + List privilegeList = SmartBeanUtil.copyList(privilegeEntities, RolePrivilegeSimpleDTO.class); + privilegeList.forEach(e -> e.setChildren(Lists.newArrayList())); + rolePrivilegeSimpleDTO.setChildren(privilegeList); + this.buildChildPrivilegeList(privilegeEntityList, privilegeList); + } + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/dto/RolePrivilegeDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/dto/RolePrivilegeDTO.java new file mode 100644 index 00000000..5b09bf58 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/dto/RolePrivilegeDTO.java @@ -0,0 +1,35 @@ +package com.gangquan360.smartadmin.module.role.roleprivilege.domain.dto; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +public class RolePrivilegeDTO { + + /** + * 角色id + */ + @ApiModelProperty("角色id") + @NotNull(message = "角色id不能为空") + private Long roleId; + + /** + * 功能权限id 集合 + */ + @ApiModelProperty("功能权限Key集合") + @NotNull(message = "功能权限集合不能为空") + private List privilegeKeyList; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/dto/RolePrivilegeSimpleDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/dto/RolePrivilegeSimpleDTO.java new file mode 100644 index 00000000..c44dc937 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/dto/RolePrivilegeSimpleDTO.java @@ -0,0 +1,43 @@ +package com.gangquan360.smartadmin.module.role.roleprivilege.domain.dto; + +import com.gangquan360.smartadmin.common.anno.ApiModelPropertyEnum; +import com.gangquan360.smartadmin.module.privilege.constant.PrivilegeTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 角色功能权限 + * + * @author listen + * @date 2018/01/03 08:48 + */ +@Data +public class RolePrivilegeSimpleDTO { + + @ApiModelProperty("父级Key") + private String parentKey; + /** + * 功能名称 + */ + @ApiModelProperty("名称") + private String name; + + @ApiModelPropertyEnum(enumDesc = "类型",value = PrivilegeTypeEnum.class) + private Integer type; + + @ApiModelProperty("key") + private String key; + + @ApiModelProperty("url") + private String url; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("子级列表") + private List children; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/dto/RolePrivilegeTreeVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/dto/RolePrivilegeTreeVO.java new file mode 100644 index 00000000..7b7893c2 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/dto/RolePrivilegeTreeVO.java @@ -0,0 +1,19 @@ +package com.gangquan360.smartadmin.module.role.roleprivilege.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class RolePrivilegeTreeVO { + + @ApiModelProperty("角色ID") + private Long roleId; + + @ApiModelProperty("权限列表") + private List privilege; + + @ApiModelProperty("选中的权限") + private List selectedKey; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/entity/RolePrivilegeEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/entity/RolePrivilegeEntity.java new file mode 100644 index 00000000..f30b7a3e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/role/roleprivilege/domain/entity/RolePrivilegeEntity.java @@ -0,0 +1,32 @@ +package com.gangquan360.smartadmin.module.role.roleprivilege.domain.entity; +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +/** + * + * [ 角色 权限关系 ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +@TableName("t_role_privilege") +public class RolePrivilegeEntity extends BaseEntity { + + /** + * 角色 id + */ + private Long roleId; + + /** + * 功能权限 id + */ + private String privilegeKey; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/SmartReloadCommand.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/SmartReloadCommand.java new file mode 100644 index 00000000..5922a7c0 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/SmartReloadCommand.java @@ -0,0 +1,52 @@ +package com.gangquan360.smartadmin.module.smartreload; + +import com.gangquan360.smartadmin.common.reload.abstracts.AbstractSmartReloadCommand4Spring; +import com.gangquan360.smartadmin.common.reload.domain.entity.ReloadItem; +import com.gangquan360.smartadmin.common.reload.domain.entity.SmartReloadResult; +import com.gangquan360.smartadmin.module.smartreload.dao.ReloadItemDao; +import com.gangquan360.smartadmin.module.smartreload.dao.ReloadResultDao; +import com.gangquan360.smartadmin.module.smartreload.domain.entity.ReloadItemEntity; +import com.gangquan360.smartadmin.module.smartreload.domain.entity.ReloadResultEntity; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * Smart Reload 业务 + * + * @author listen + * @date 2018/02/10 09:18 + */ +@Component +public class SmartReloadCommand extends AbstractSmartReloadCommand4Spring { + + @Autowired + private ReloadItemDao reloadItemDao; + + @Autowired + private ReloadResultDao reloadResultDao; + + /** + * 读取数据库中SmartReload项 + * + * @return List + */ + @Override + public List readReloadItem() { + List reloadItemEntityList = reloadItemDao.selectList(null); + return SmartBeanUtil.copyList(reloadItemEntityList, ReloadItem.class); + } + + /** + * 保存reload结果 + * + * @param smartReloadResult + */ + @Override + public void handleReloadResult(SmartReloadResult smartReloadResult) { + ReloadResultEntity reloadResultEntity = SmartBeanUtil.copy(smartReloadResult, ReloadResultEntity.class); + reloadResultDao.insert(reloadResultEntity); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/SmartReloadController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/SmartReloadController.java new file mode 100644 index 00000000..97e71b23 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/SmartReloadController.java @@ -0,0 +1,52 @@ +package com.gangquan360.smartadmin.module.smartreload; + +import com.gangquan360.smartadmin.common.anno.NoValidPrivilege; +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.smartreload.domain.dto.ReloadItemUpdateDTO; +import com.gangquan360.smartadmin.module.smartreload.domain.dto.ReloadItemVO; +import com.gangquan360.smartadmin.module.smartreload.domain.dto.ReloadResultVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * Smart Reload 路由 + * + * @author listen + * @date 2018/02/10 09:18 + */ +@Api(tags = {SwaggerTagConst.Admin.MANAGER_SMART_RELOAD}) +@OperateLog +@RestController +public class SmartReloadController { + + @Autowired + private SmartReloadService smartReloadService; + + @ApiOperation(value = "获取全部Smart-reload项", notes = "获取全部Smart-reload项") + @GetMapping("/smartReload/all") + @NoValidPrivilege + public ResponseDTO> listAllReloadItem() { + return smartReloadService.listAllReloadItem(); + } + + @ApiOperation(value = "获取reload result", notes = "获取reload result") + @GetMapping("/smartReload/result/{tag}") + @NoValidPrivilege + public ResponseDTO> queryReloadResult(@PathVariable("tag") String tag) { + return smartReloadService.listReloadItemResult(tag); + } + + @ApiOperation("通过tag更新标识") + @PostMapping("/smartReload/update") + @NoValidPrivilege + public ResponseDTO updateByTag(@RequestBody @Valid ReloadItemUpdateDTO updateDTO) { + return smartReloadService.updateByTag(updateDTO); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/SmartReloadService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/SmartReloadService.java new file mode 100644 index 00000000..49ad7180 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/SmartReloadService.java @@ -0,0 +1,103 @@ +package com.gangquan360.smartadmin.module.smartreload; + +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.common.reload.SmartReloadManager; +import com.gangquan360.smartadmin.module.smartreload.dao.ReloadItemDao; +import com.gangquan360.smartadmin.module.smartreload.dao.ReloadResultDao; +import com.gangquan360.smartadmin.module.smartreload.domain.dto.ReloadItemUpdateDTO; +import com.gangquan360.smartadmin.module.smartreload.domain.dto.ReloadItemVO; +import com.gangquan360.smartadmin.module.smartreload.domain.dto.ReloadResultVO; +import com.gangquan360.smartadmin.module.smartreload.domain.entity.ReloadItemEntity; +import com.gangquan360.smartadmin.module.smartreload.domain.entity.ReloadResultEntity; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.sql.Timestamp; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * Smart initDefines 业务 + * + * @author listen + * @date 2018/02/10 13:49 + */ +@Service +public class SmartReloadService { + + @Autowired + private SmartReloadManager smartReloadManager; + + @Autowired + private SmartReloadCommand smartReloadCommand; + + @Autowired + private ReloadItemDao reloadItemDao; + + @Autowired + private ReloadResultDao reloadResultDao; + + @Value("${smart-reload.time-interval}") + private Long timeInterval; + + @PostConstruct + public void init() { + smartReloadManager.addCommand(smartReloadCommand, 10, timeInterval, TimeUnit.SECONDS); + } + + /** + * 注册到SmartReload里 + */ + public void register(Object reload) { + smartReloadManager.register(reload); + } + + /** + * 获取所有 initDefines 项 + * + * @return + */ + public ResponseDTO> listAllReloadItem() { + List reloadItemEntityList = reloadItemDao.selectList(null); + List reloadItemDTOList = SmartBeanUtil.copyList(reloadItemEntityList, ReloadItemVO.class); + return ResponseDTO.succData(reloadItemDTOList); + } + + /** + * 根据 tag + * 获取所有 initDefines 运行结果 + * + * @return ResponseDTO + */ + public ResponseDTO> listReloadItemResult(String tag) { + ReloadResultEntity query = new ReloadResultEntity(); + query.setTag(tag); + List reloadResultEntityList = reloadResultDao.query(tag); + List reloadResultDTOList = SmartBeanUtil.copyList(reloadResultEntityList, ReloadResultVO.class); + return ResponseDTO.succData(reloadResultDTOList); + } + + /** + * 通过标签更新标识符 + * + * @param updateDTO + * @return + */ + public ResponseDTO updateByTag(ReloadItemUpdateDTO updateDTO) { + ReloadItemEntity entity = new ReloadItemEntity(); + entity.setTag(updateDTO.getTag()); + ReloadItemEntity reloadItemEntity = reloadItemDao.selectById(entity.getTag()); + if (null == reloadItemEntity) { + return ResponseDTO.wrap(ResponseCodeConst.NOT_EXISTS); + } + reloadItemEntity.setIdentification(updateDTO.getIdentification()); + reloadItemEntity.setUpdateTime(new Timestamp(System.currentTimeMillis())); + reloadItemEntity.setArgs(updateDTO.getArgs()); + reloadItemDao.updateById(reloadItemEntity); + return ResponseDTO.succ(); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/dao/ReloadItemDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/dao/ReloadItemDao.java new file mode 100644 index 00000000..e5b56605 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/dao/ReloadItemDao.java @@ -0,0 +1,15 @@ +package com.gangquan360.smartadmin.module.smartreload.dao; +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.gangquan360.smartadmin.module.smartreload.domain.entity.ReloadItemEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +/** + * t_reload_item 数据表dao + * + * @author listen + * @date 2018/02/10 09:23 + */ +@Component +@Mapper +public interface ReloadItemDao extends BaseMapper {} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/dao/ReloadResultDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/dao/ReloadResultDao.java new file mode 100644 index 00000000..b78244c2 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/dao/ReloadResultDao.java @@ -0,0 +1,23 @@ +package com.gangquan360.smartadmin.module.smartreload.dao; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.gangquan360.smartadmin.module.smartreload.domain.entity.ReloadResultEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * t_reload_result 数据表dao + * + * @author listen + * @date 2018/02/10 09:23 + */ +@Component +@Mapper +public interface ReloadResultDao extends BaseMapper { + + + List query(@Param("tag") String tag); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/dto/ReloadItemUpdateDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/dto/ReloadItemUpdateDTO.java new file mode 100644 index 00000000..15e8e860 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/dto/ReloadItemUpdateDTO.java @@ -0,0 +1,29 @@ +package com.gangquan360.smartadmin.module.smartreload.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +/** + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Data +public class ReloadItemUpdateDTO { + + @ApiModelProperty("标签") + @NotBlank(message = "标签不能为空") + private String tag; + + @ApiModelProperty("状态标识") + @NotBlank(message = "状态标识不能为空") + private String identification; + + @ApiModelProperty("reload时传入的参数,可以为空") + private String args; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/dto/ReloadItemVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/dto/ReloadItemVO.java new file mode 100644 index 00000000..571dd599 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/dto/ReloadItemVO.java @@ -0,0 +1,46 @@ +package com.gangquan360.smartadmin.module.smartreload.domain.dto; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * initDefines 项 DTO 类 + * + * @author listen + * @date 2018/02/10 09:29 + */ +@Data +public class ReloadItemVO { + + /** + * 加载项标签 + */ + @ApiModelProperty("加载项标签") + private String tag; + + /** + * 参数 + */ + @ApiModelProperty("参数") + private String args; + + /** + * 状态标识 + */ + @ApiModelProperty("状态标识") + private String identification; + + /** + * 更新时间 + */ + @ApiModelProperty("最后更新时间") + private Date updateTime; + + /** + * 创建时间 + */ + @ApiModelProperty("创建时间") + private Date createTime; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/dto/ReloadResultVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/dto/ReloadResultVO.java new file mode 100644 index 00000000..0db01ee7 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/dto/ReloadResultVO.java @@ -0,0 +1,47 @@ +package com.gangquan360.smartadmin.module.smartreload.domain.dto; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.util.Date; + +/** + * reload_result DTO 类 + * + * @author listen + * @date 2018/02/10 09:29 + */ +@Data +public class ReloadResultVO { + + /** + * 加载项标签 + */ + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 状态标识 + */ + private String identification; + + /** + * 运行结果 + */ + private Boolean result; + + /** + * 异常 + */ + private String exception; + + /** + * 创建时间 + */ + private Date createTime; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/entity/ReloadItemEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/entity/ReloadItemEntity.java new file mode 100644 index 00000000..c5be854a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/entity/ReloadItemEntity.java @@ -0,0 +1,46 @@ +package com.gangquan360.smartadmin.module.smartreload.domain.entity; +import com.baomidou.mybatisplus.annotations.TableId; +import com.baomidou.mybatisplus.annotations.TableName; +import com.baomidou.mybatisplus.enums.IdType; +import lombok.Data; + +import java.util.Date; + +/** + * t_reload_item 数据表 实体类 + * + * @author listen + * @date 2018/02/10 09:29 + */ +@Data +@TableName("t_reload_item") +public class ReloadItemEntity { + + /** + * 加载项标签 + */ + @TableId(type = IdType.INPUT) + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 运行标识 + */ + private String identification; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 创建时间 + */ + private Date createTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/entity/ReloadResultEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/entity/ReloadResultEntity.java new file mode 100644 index 00000000..e04f197d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/smartreload/domain/entity/ReloadResultEntity.java @@ -0,0 +1,48 @@ +package com.gangquan360.smartadmin.module.smartreload.domain.entity; +import com.baomidou.mybatisplus.annotations.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * t_reload_result 数据表 实体类 + * + * @author listen + * @date 2018/02/10 09:29 + */ +@Data +@TableName("t_reload_result") +public class ReloadResultEntity { + + /** + * 加载项标签 + */ + private String tag; + + /** + * 运行标识 + */ + private String identification; + + /** + * 参数 + */ + private String args; + + /** + * 运行结果 + */ + private Boolean result; + + /** + * 异常 + */ + private String exception; + + /** + * 创建时间 + */ + private Date createTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/SystemConfigController.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/SystemConfigController.java new file mode 100644 index 00000000..da12c4ff --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/SystemConfigController.java @@ -0,0 +1,70 @@ +package com.gangquan360.smartadmin.module.systemconfig; + +import com.gangquan360.smartadmin.common.anno.OperateLog; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.constant.SwaggerTagConst; +import com.gangquan360.smartadmin.module.systemconfig.domain.dto.SystemConfigAddDTO; +import com.gangquan360.smartadmin.module.systemconfig.domain.dto.SystemConfigQueryDTO; +import com.gangquan360.smartadmin.module.systemconfig.domain.dto.SystemConfigUpdateDTO; +import com.gangquan360.smartadmin.module.systemconfig.domain.dto.SystemConfigVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.List; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Api(tags = {SwaggerTagConst.Admin.MANAGER_SYSTEM_CONFIG}) +@OperateLog +@RestController +public class SystemConfigController { + + @Autowired + private SystemConfigService systemConfigService; + + @ApiOperation(value = "分页查询所有系统配置", notes = "分页查询所有系统配置") + @PostMapping("systemConfig/getListPage") + public ResponseDTO> getSystemConfigPage(@RequestBody @Valid SystemConfigQueryDTO queryDTO) { + return systemConfigService.getSystemConfigPage(queryDTO); + } + + @ApiOperation(value = "添加配置参数", notes = "添加配置参数") + @PostMapping("systemConfig/add") + public ResponseDTO addSystemConfig(@RequestBody @Valid SystemConfigAddDTO configAddDTO) { + return systemConfigService.addSystemConfig(configAddDTO); + } + + @ApiOperation(value = "修改配置参数", notes = "修改配置参数") + @PostMapping("systemConfig/update") + public ResponseDTO updateSystemConfig(@RequestBody @Valid SystemConfigUpdateDTO updateDTO) { + return systemConfigService.updateSystemConfig(updateDTO); + } + + @ApiOperation(value = "根据分组查询所有系统配置", notes = "根据分组查询所有系统配置") + @GetMapping("systemConfig/getListByGroup") + public ResponseDTO> getListByGroup(String group) { + return systemConfigService.getListByGroup(group); + } + + @ApiOperation(value = "通过key获取对应的信息", notes = "通过key获取对应的信息") + @GetMapping("systemConfig/selectByKey") + public ResponseDTO selectByKey(String configKey) { + return systemConfigService.selectByKey(configKey); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/SystemConfigDao.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/SystemConfigDao.java new file mode 100644 index 00000000..53654d97 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/SystemConfigDao.java @@ -0,0 +1,62 @@ +package com.gangquan360.smartadmin.module.systemconfig; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.pagination.Pagination; +import com.gangquan360.smartadmin.module.systemconfig.domain.dto.SystemConfigQueryDTO; +import com.gangquan360.smartadmin.module.systemconfig.domain.entity.SystemConfigEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 系统参数配置 t_system_config Dao层 + * + * @author GHQ + * @date 2017-12-23 14:25 + */ +@Component +@Mapper +public interface SystemConfigDao extends BaseMapper { + + /** + * 查询所有系统配置(分页) + * + * @param page + * @return + */ + List selectSystemSettingList(Pagination page, SystemConfigQueryDTO queryDTO); + + /** + * 根据key查询获取数据 + * + * @param key + * @return + */ + SystemConfigEntity getByKey(@Param("key") String key); + + /** + * 根据key查询获取数据 排除掉某個id的数据 + * @param key + * @param excludeId + * @return + */ + SystemConfigEntity getByKeyExcludeId(@Param("key") String key,@Param("excludeId") Long excludeId); + /** + * 查询所有系统配置 + * + * @return + */ + List selectSystemSettingList(); + + /** + * 根据分组查询所有系统配置 + * @param group + * @return + */ + List getListByGroup(String group); + + + SystemConfigEntity selectByKeyAndGroup(@Param("configKey") String configKey, @Param("group") String group); +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/SystemConfigService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/SystemConfigService.java new file mode 100644 index 00000000..9a691071 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/SystemConfigService.java @@ -0,0 +1,250 @@ +package com.gangquan360.smartadmin.module.systemconfig; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.constant.JudgeEnum; +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import com.gangquan360.smartadmin.common.domain.ResponseDTO; +import com.gangquan360.smartadmin.common.exception.SmartBusinessException; +import com.gangquan360.smartadmin.common.reload.annotation.SmartReload; +import com.gangquan360.smartadmin.constant.SmartReloadTagConst; +import com.gangquan360.smartadmin.module.smartreload.SmartReloadService; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigDataType; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigEnum; +import com.gangquan360.smartadmin.module.systemconfig.constant.SystemConfigResponseCodeConst; +import com.gangquan360.smartadmin.module.systemconfig.domain.dto.*; +import com.gangquan360.smartadmin.module.systemconfig.domain.entity.SystemConfigEntity; +import com.gangquan360.smartadmin.util.SmartBeanUtil; +import com.gangquan360.smartadmin.util.SmartPaginationUtil; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; + +/** + * 系统配置业务类 + * + * @author GHQ + * @date 2017-12-23 15:09 + */ +@Slf4j +@Service +public class SystemConfigService { + + /** + * 系统配置缓存 + */ + private ConcurrentHashMap systemConfigMap = new ConcurrentHashMap<>(); + + @Autowired + private SystemConfigDao systemConfigDao; + + @Autowired + private SmartReloadService smartReloadService; + + /** + * 初始化系统设置缓存 + */ + @PostConstruct + private void initSystemConfigCache() { + List entityList = systemConfigDao.selectSystemSettingList(); + if (CollectionUtils.isEmpty(entityList)) { + return; + } + + systemConfigMap.clear(); + entityList.forEach(entity -> this.systemConfigMap.put(entity.getConfigKey().toLowerCase(), entity)); + log.info("系统设置缓存初始化完毕:{}", systemConfigMap.size()); + + smartReloadService.register(this); + } + + @SmartReload(SmartReloadTagConst.SYSTEM_CONFIG) + public boolean reload(String args) { + this.initSystemConfigCache(); + log.warn("<> <<{}>> , args {} reload success ", SmartReloadTagConst.SYSTEM_CONFIG, args); + return true; + } + + /** + * 分页获取系统配置 + * + * @param queryDTO + * @return + */ + public ResponseDTO> getSystemConfigPage(SystemConfigQueryDTO queryDTO) { + Page page = SmartPaginationUtil.convert2PageQueryInfo(queryDTO); + List entityList = systemConfigDao.selectSystemSettingList(page, queryDTO); + PageResultDTO pageResultDTO = SmartPaginationUtil.convert2PageInfoDTO(page, entityList, SystemConfigVO.class); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * 根据参数key获得一条数据(数据库) + * + * @param configKey + * @return + */ + public ResponseDTO selectByKey(String configKey) { + SystemConfigEntity entity = systemConfigDao.getByKey(configKey); + if (entity == null) { + return ResponseDTO.wrap(SystemConfigResponseCodeConst.NOT_EXIST); + } + SystemConfigVO configDTO = SmartBeanUtil.copy(entity, SystemConfigVO.class); + return ResponseDTO.succData(configDTO); + } + + /** + * 根据参数key获得一条数据 并转换为 对象 + * + * @param configKey + * @param clazz + * @param + * @return + */ + public T selectByKey2Obj(String configKey, Class clazz) { + SystemConfigEntity entity = systemConfigDao.getByKey(configKey); + if (entity == null) { + return null; + } + SystemConfigDTO configDTO = SmartBeanUtil.copy(entity, SystemConfigDTO.class); + String configValue = configDTO.getConfigValue(); + if (StringUtils.isEmpty(configValue)) { + return null; + } + T obj = JSON.parseObject(configValue, clazz); + return obj; + } + + public SystemConfigDTO getCacheByKey(SystemConfigEnum.Key key) { + SystemConfigEntity entity = this.systemConfigMap.get(key.name().toLowerCase()); + if (entity == null) { + throw new SmartBusinessException("缺少系统配置[" + key.name() + "]"); + } + return SmartBeanUtil.copy(entity, SystemConfigDTO.class); + } + + /** + * 添加系统配置 + * + * @param configAddDTO + * @return + */ + public ResponseDTO addSystemConfig(SystemConfigAddDTO configAddDTO) { + SystemConfigEntity entity = systemConfigDao.getByKey(configAddDTO.getConfigKey()); + if (entity != null) { + return ResponseDTO.wrap(SystemConfigResponseCodeConst.ALREADY_EXIST); + } + ResponseDTO valueValid = this.configValueValid(configAddDTO.getConfigKey(),configAddDTO.getConfigValue()); + if(!valueValid.isSuccess()){ + return valueValid; + } + SystemConfigEntity addEntity = SmartBeanUtil.copy(configAddDTO, SystemConfigEntity.class); + addEntity.setIsUsing(JudgeEnum.YES.getValue()); + systemConfigDao.insert(addEntity); + //刷新缓存 + this.initSystemConfigCache(); + return ResponseDTO.succ(); + } + + /** + * 更新系统配置 + * + * @param updateDTO + * @return + */ + public ResponseDTO updateSystemConfig(SystemConfigUpdateDTO updateDTO) { + SystemConfigEntity entity = systemConfigDao.selectById(updateDTO.getId()); + //系统配置不存在 + if (entity == null) { + return ResponseDTO.wrap(SystemConfigResponseCodeConst.NOT_EXIST); + } + SystemConfigEntity alreadyEntity = systemConfigDao.getByKeyExcludeId(updateDTO.getConfigKey(), updateDTO.getId()); + if (alreadyEntity != null) { + return ResponseDTO.wrap(SystemConfigResponseCodeConst.ALREADY_EXIST); + } + ResponseDTO valueValid = this.configValueValid(updateDTO.getConfigKey(),updateDTO.getConfigValue()); + if(!valueValid.isSuccess()){ + return valueValid; + } + entity = SmartBeanUtil.copy(updateDTO, SystemConfigEntity.class); + systemConfigDao.updateById(entity); + + //刷新缓存 + this.initSystemConfigCache(); + return ResponseDTO.succ(); + } + + + private ResponseDTO configValueValid(String configKey , String configValue){ + SystemConfigEnum.Key configKeyEnum = SystemConfigEnum.Key.selectByKey(configKey); + if(configKeyEnum == null){ + return ResponseDTO.succ(); + } + SystemConfigDataType dataType = configKeyEnum.getDataType(); + if(dataType == null){ + return ResponseDTO.succ(); + } + if(dataType.name().equals(SystemConfigDataType.TEXT.name())){ + return ResponseDTO.succ(); + } + if(dataType.name().equals(SystemConfigDataType.JSON.name())){ + try { + JSONObject jsonStr = JSONObject.parseObject(configValue); + return ResponseDTO.succ(); + } catch (Exception e) { + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM,"数据格式不是JSON,请修改后提交。"); + } + } + if(StringUtils.isNotEmpty(dataType.getValid())){ + Boolean valid = Pattern.matches(dataType.getValid(), configValue); + if(valid){ + return ResponseDTO.succ(); + } + return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM,"数据格式不是"+dataType.name().toLowerCase()+",请修改后提交。"); + } + + return ResponseDTO.succ(); + } + + /** + * 根据分组名称 获取获取系统设置 + * + * @param group + * @return + */ + public ResponseDTO> getListByGroup(String group) { + + List entityList = systemConfigDao.getListByGroup(group); + if (CollectionUtils.isEmpty(entityList)) { + return ResponseDTO.succData(Lists.newArrayList()); + } + List systemConfigList = SmartBeanUtil.copyList(entityList, SystemConfigVO.class); + return ResponseDTO.succData(systemConfigList); + } + + /** + * 根据分组名称 获取获取系统设置 + * + * @param group + * @return + */ + public List getListByGroup(SystemConfigEnum.Group group) { + List entityList = systemConfigDao.getListByGroup(group.name()); + if (CollectionUtils.isEmpty(entityList)) { + return Lists.newArrayList(); + } + List systemConfigList = SmartBeanUtil.copyList(entityList, SystemConfigDTO.class); + return systemConfigList; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/constant/SystemConfigDataType.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/constant/SystemConfigDataType.java new file mode 100644 index 00000000..e02da00e --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/constant/SystemConfigDataType.java @@ -0,0 +1,67 @@ +package com.gangquan360.smartadmin.module.systemconfig.constant; + +import com.gangquan360.smartadmin.util.SmartVerificationUtil; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/9/4 0004 上午 11:43 + * @since JDK1.8 + */ +public enum SystemConfigDataType { + /** + * 整数 + */ + INTEGER(SmartVerificationUtil.INTEGER), + /** + * 文本 + */ + TEXT(null), + /** + * url地址 + */ + URL(SmartVerificationUtil.URL), + /** + * 邮箱 + */ + EMAIL(SmartVerificationUtil.EMAIL), + /** + * JSON 字符串 + */ + JSON(null), + /** + * 2019-08 + */ + YEAR_MONTH(SmartVerificationUtil.YEAR_MONTH), + /** + * 2019-08-01 + */ + DATE(SmartVerificationUtil.DATE), + /** + * 2019-08-01 10:23 + */ + DATE_TIME(SmartVerificationUtil.DATE_TIME), + /** + * 10:23-10:56 + */ + TIME_SECTION(SmartVerificationUtil.TIME_SECTION), + /** + * 10:23 + */ + TIME(SmartVerificationUtil.TIME); + + private String valid; + + + SystemConfigDataType(String valid){ + this.valid = valid; + } + + public String getValid() { + return valid; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/constant/SystemConfigEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/constant/SystemConfigEnum.java new file mode 100644 index 00000000..0007f44b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/constant/SystemConfigEnum.java @@ -0,0 +1,65 @@ +package com.gangquan360.smartadmin.module.systemconfig.constant; + + +import java.util.Arrays; +import java.util.Optional; + +/** + * [ 系统配置常量类 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +public class SystemConfigEnum { + + public enum Group { + BACK + } + + public enum Key { + + /** + * 超管id + */ + EMPLOYEE_SUPERMAN(SystemConfigDataType.TEXT), + /** + * 阿里云OSS配置项 + */ + ALI_OSS(SystemConfigDataType.JSON), + /** + * 七牛云OSS配置项 + */ + QI_NIU_OSS(SystemConfigDataType.JSON), + /** + * 本地文件上传url前缀 + */ + LOCAL_UPLOAD_URL_PREFIX(SystemConfigDataType.URL), + /** + * 邮件配置 + */ + EMAIL_CONFIG(SystemConfigDataType.JSON); + + + private SystemConfigDataType dataType; + + Key(SystemConfigDataType dataType){ + this.dataType = dataType; + } + + + public SystemConfigDataType getDataType() { + return dataType; + } + + public static Key selectByKey(String key) { + Key[] values = Key.values(); + Optional first = Arrays.stream(values).filter(e -> e.name().equalsIgnoreCase(key)).findFirst(); + return !first.isPresent() ? null : first.get(); + } + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/constant/SystemConfigResponseCodeConst.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/constant/SystemConfigResponseCodeConst.java new file mode 100644 index 00000000..b95700e4 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/constant/SystemConfigResponseCodeConst.java @@ -0,0 +1,29 @@ +package com.gangquan360.smartadmin.module.systemconfig.constant; +import com.gangquan360.smartadmin.common.constant.ResponseCodeConst; + +/** + * + * [ 5001-5999 ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +public class SystemConfigResponseCodeConst extends ResponseCodeConst { + + /** + * 配置参数已存在 10201 + */ + public static final SystemConfigResponseCodeConst ALREADY_EXIST = new SystemConfigResponseCodeConst(5001, "配置参数已存在"); + /** + * 配置参数不存在 10203 + */ + public static final SystemConfigResponseCodeConst NOT_EXIST = new SystemConfigResponseCodeConst(5002, "配置参数不存在"); + + public SystemConfigResponseCodeConst(int code, String msg) { + super(code, msg); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigAddDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigAddDTO.java new file mode 100644 index 00000000..fbae679f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigAddDTO.java @@ -0,0 +1,45 @@ +package com.gangquan360.smartadmin.module.systemconfig.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Data +public class SystemConfigAddDTO { + + @ApiModelProperty("参数key") + @NotBlank(message = "参数key不能为空") + @Length(max = 255, message = "参数key最多255个字符") + private String configKey; + + @ApiModelProperty("参数的值") + @NotBlank(message = "参数的值不能为空") + @Length(max = 65530, message = "参数的值最多65530个字符") + private String configValue; + + @ApiModelProperty("参数名称") + @NotBlank(message = "参数名称不能为空") + @Length(max = 255, message = "参数名称最多255个字符") + private String configName; + + @ApiModelProperty("参数类别") + @NotBlank(message = "参数类别不能为空") + @Length(max = 255, message = "参数类别最多255个字符") + private String configGroup; + + @ApiModelProperty("备注") + @Length(max = 255, message = "备注最多255个字符") + private String remark; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigDTO.java new file mode 100644 index 00000000..d17f91e1 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigDTO.java @@ -0,0 +1,50 @@ +package com.gangquan360.smartadmin.module.systemconfig.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +public class SystemConfigDTO { + + @ApiModelProperty("主键") + private Long id; + + @ApiModelProperty("参数key") + private String configKey; + + @ApiModelProperty("参数的值") + private String configValue; + + @ApiModelProperty("参数名称") + private String configName; + + @ApiModelProperty("参数类别") + private String configGroup; + + @ApiModelProperty("是否使用0 是 1否") + private Integer isUsing; + + @ApiModelProperty("备注") + private String remark; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("上次修改时间") + private Date updateTime; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigQueryDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigQueryDTO.java new file mode 100644 index 00000000..08030ba8 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigQueryDTO.java @@ -0,0 +1,29 @@ +package com.gangquan360.smartadmin.module.systemconfig.domain.dto; + + +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +public class SystemConfigQueryDTO extends PageParamDTO { + + @ApiModelProperty("参数KEY") + private String key; + + @ApiModelProperty("参数类别") + private String configGroup; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigUpdateDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigUpdateDTO.java new file mode 100644 index 00000000..1c59b8e3 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigUpdateDTO.java @@ -0,0 +1,25 @@ +package com.gangquan360.smartadmin.module.systemconfig.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * + * [ ] + * + * @version 1.0 + * @since JDK1.8 + * @author yandanyang + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + */ +@Data +public class SystemConfigUpdateDTO extends SystemConfigAddDTO{ + + @ApiModelProperty("id") + @NotNull(message = "id不能为空") + private Long id; +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigVO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigVO.java new file mode 100644 index 00000000..246e4950 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/dto/SystemConfigVO.java @@ -0,0 +1,48 @@ +package com.gangquan360.smartadmin.module.systemconfig.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +@Data +public class SystemConfigVO { + + @ApiModelProperty("主键") + private Long id; + + @ApiModelProperty("参数key") + private String configKey; + + @ApiModelProperty("参数的值") + private String configValue; + + @ApiModelProperty("参数名称") + private String configName; + + @ApiModelProperty("参数类别") + private String configGroup; + + @ApiModelProperty("是否使用0 是 1否") + private Integer isUsing; + + @ApiModelProperty("备注") + private String remark; + + @ApiModelProperty("创建时间") + private Date createTime; + + @ApiModelProperty("上次修改时间") + private Date updateTime; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/entity/SystemConfigEntity.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/entity/SystemConfigEntity.java new file mode 100644 index 00000000..56345b64 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/systemconfig/domain/entity/SystemConfigEntity.java @@ -0,0 +1,51 @@ +package com.gangquan360.smartadmin.module.systemconfig.domain.entity; + +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +import lombok.Data; + +import java.io.Serializable; + +/** + * 系统配置参数 实体类 + * + * @author GHQ + * @date 2017-12-23 13:41 + */ +@Data +@TableName(value = "t_system_config") +public class SystemConfigEntity extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 257284726400352502L; + + /** + * 参数key + */ + private String configKey; + + /** + * 参数的值 + */ + private String configValue; + + /** + * 参数名称 + */ + private String configName; + + /** + * 参数类别 + */ + private String configGroup; + + /** + * 是否使用0 是 1否 + */ + private Integer isUsing; + + /** + * 备注 + */ + private String remark; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/MessageTypeEnum.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/MessageTypeEnum.java new file mode 100644 index 00000000..d2512306 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/MessageTypeEnum.java @@ -0,0 +1,44 @@ +package com.gangquan360.smartadmin.module.websocket; + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/10 0010 下午 19:11 + * @since JDK1.8 + */ +public enum MessageTypeEnum implements BaseEnum{ + + SYS_NOTICE(1,"系统通知"), + + PRIVATE_LETTER(2,"私信"), + + HEART_BEAT(3,"心跳"); + + + private Integer value; + + private String desc; + + + MessageTypeEnum(Integer value,String desc){ + this.value = value; + this.desc = desc; + } + + + @Override + public Integer getValue() { + return this.value; + } + + @Override + public String getDesc() { + return this.desc; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/WebSocketServer.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/WebSocketServer.java new file mode 100644 index 00000000..5474e03c --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/WebSocketServer.java @@ -0,0 +1,199 @@ +package com.gangquan360.smartadmin.module.websocket; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.gangquan360.smartadmin.module.websocket.domain.MessageCommonDTO; +import com.gangquan360.smartadmin.module.websocket.domain.MessageDTO; +import com.gangquan360.smartadmin.module.websocket.domain.WebSocketHeartBeatDTO; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/10 0010 下午 16:09 + * @since JDK1.8 + */ +@Slf4j +@ServerEndpoint("/webSocket/{employeeId}") +@Component +public class WebSocketServer { + + /** + * 当前在线用户 employee,expireTime + */ + private static ConcurrentHashMap onLineUser = new ConcurrentHashMap<>(); + + /** + * 当前在线用户所对应的 socket session信息 + */ + private static ConcurrentHashMap webSocketSession = new ConcurrentHashMap<>(); + + @OnOpen + public void onOpen(Session session, @PathParam("employeeId") Long employeeId) { + if (employeeId == null) { + return; + } + webSocketSession.put(employeeId, session); + log.info("连接打开"); + } + + /** + * 不做处理如果 前台可以监听到浏览器关闭 此处处理在线人数也可 + * + * @param session + */ + @OnClose + public void onClose(Session session) { + + log.info("连接关闭"); + } + + @OnError + public void onError(Session session, Throwable error) { + log.error("socket error,{}", error); + error.printStackTrace(); + } + + /** + * 此方法接收 前台信息 + * + * @param message + * @param session + */ + @OnMessage + public void onMessage(String message, Session session) { + if (StringUtils.isEmpty(message)) { + return; + } + MessageCommonDTO messageCommonDTO = JSON.parseObject(message, new TypeReference() {}); + if (MessageTypeEnum.HEART_BEAT.getValue().equals(messageCommonDTO.getMessageType())) { + this.heartBeatHandle(messageCommonDTO.getJsonStr()); + } + } + + /** + * 更新用户过期时间 + * + * @param json + */ + private void heartBeatHandle(String json) { + Long currentDate = System.currentTimeMillis(); + Long expireTime = currentDate + 5 * 1000; + WebSocketHeartBeatDTO heartBeatDTO = JSON.parseObject(json, new TypeReference() {}); + Long employeeId = heartBeatDTO.getEmployeeId(); + onLineUser.put(employeeId, expireTime); + } + + /** + * 移除过期用户,如果用户超过5s未获取到心跳列表则清除在线用户信息 + */ + @Scheduled(cron = "0/5 * * * * ?") + private void removeOnLineUser() { + Long currentDate = System.currentTimeMillis(); + Iterator> it = onLineUser.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + Long key = entry.getKey(); + Long value = entry.getValue(); + Long userExpireTime = value + 5 * 1000; + if (currentDate > userExpireTime) { + onLineUser.remove(key); + webSocketSession.remove(key); + } + } + } + + /** + * 此方法用户后台发送消息 + * + * @param messageDTO + */ + public static void sendMessage(MessageDTO messageDTO) { + //系统通知 + if (MessageTypeEnum.SYS_NOTICE.getValue().equals(messageDTO.getMessageType())) { + sendAllOnLineUser(messageDTO.getMessage(), messageDTO.getFromUserId()); + } + //站内信 + if (MessageTypeEnum.PRIVATE_LETTER.getValue().equals(messageDTO.getMessageType())) { + sendOneOnLineUser(messageDTO.getMessage(), messageDTO.getToUserId()); + } + } + + /** + * 通知所有在线用户 + * + * @param message + */ + public static void sendAllOnLineUser(String message, Long fromUserId) { + for (Entry entry : webSocketSession.entrySet()) { + Session session = entry.getValue(); + Long userId = entry.getKey(); + try { + //不想消息创建人推送消息 + if (! userId.equals(fromUserId)) { + session.getBasicRemote().sendText(message); + } + } catch (IOException e) { + log.error("推送消息到{},发送错误{}", userId, e); + log.error("", e); + } + + } + } + + /** + * 通知某人 + * + * @param message + * @param toUserId + */ + public static void sendOneOnLineUser(String message, Long toUserId) { + Session session = webSocketSession.get(toUserId); + if (session == null) { + log.error("推送消息到{},用户不在线", toUserId); + } + try { + session.getBasicRemote().sendText(message); + } catch (IOException e) { + log.error("推送消息到{},发送错误{}", toUserId, e); + log.error("", e); + } + } + + /** + * 获取所有在线用户id + * + * @return + */ + public static List getOnLineUserList() { + return Lists.newArrayList(onLineUser.keySet()); + } + + /** + * 获取当前在线用户数 + * + * @return + */ + public static Integer getOnLineUserCount() { + return onLineUser.entrySet().size(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/domain/MessageCommonDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/domain/MessageCommonDTO.java new file mode 100644 index 00000000..fb9611c0 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/domain/MessageCommonDTO.java @@ -0,0 +1,29 @@ +package com.gangquan360.smartadmin.module.websocket.domain; + +import com.gangquan360.smartadmin.module.websocket.MessageTypeEnum; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/13 0013 下午 14:37 + * @since JDK1.8 + */ +@Data +public class MessageCommonDTO { + /** + * 消息类型 {@link MessageTypeEnum} + */ + private Integer messageType; + + /** + * 具体消息内容 + */ + private String jsonStr; + + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/domain/MessageDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/domain/MessageDTO.java new file mode 100644 index 00000000..ca1ec32d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/domain/MessageDTO.java @@ -0,0 +1,41 @@ +package com.gangquan360.smartadmin.module.websocket.domain; + +import com.gangquan360.smartadmin.module.websocket.MessageTypeEnum; +import lombok.Builder; +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/10 0010 下午 18:50 + * @since JDK1.8 + */ +@Data +@Builder +public class MessageDTO { + + /** + * 消息类型 {@link MessageTypeEnum} + */ + private Integer messageType; + + /** + * 消息体 + */ + private String message; + + /** + * 发送者 + */ + private Long fromUserId; + + /** + * 接收者,系统通知可为null + */ + private Long toUserId; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/domain/WebSocketHeartBeatDTO.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/domain/WebSocketHeartBeatDTO.java new file mode 100644 index 00000000..bef2fd9f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/module/websocket/domain/WebSocketHeartBeatDTO.java @@ -0,0 +1,23 @@ +package com.gangquan360.smartadmin.module.websocket.domain; + +import lombok.Data; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/7/13 0013 下午 14:39 + * @since JDK1.8 + */ +@Data +public class WebSocketHeartBeatDTO { + + /** + * 当前登录人id + */ + private Long employeeId; + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/third/SmartApplicationContext.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/third/SmartApplicationContext.java new file mode 100644 index 00000000..a14759d8 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/third/SmartApplicationContext.java @@ -0,0 +1,80 @@ +package com.gangquan360.smartadmin.third; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * [ApplicationContextHelper] + * + * @author yandanyang + * @version 1.0 + * @since JDK1.8 + */ +@Component +public class SmartApplicationContext implements ApplicationContextAware { + /** + * 上下文对象实例 + */ + private static ApplicationContext applicationContext = null; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if(SmartApplicationContext.applicationContext == null){ + + SmartApplicationContext.applicationContext = applicationContext; + + } + } + + /** + * 获取applicationContext + * @return + */ + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + /** + * 通过name获取 Bean. + * @param name + * @return + */ + public static Object getBean(String name){ + ApplicationContext applicationContext = getApplicationContext(); + if(applicationContext == null){ + return null; + } + return applicationContext.getBean(name); + } + + /** + * 通过class获取Bean. + * @param clazz + * @param + * @return + */ + public static T getBean(Class clazz){ + ApplicationContext applicationContext = getApplicationContext(); + if(applicationContext == null){ + return null; + } + return applicationContext.getBean(clazz); + } + + /** + * 通过name,以及Clazz返回指定的Bean + * @param name + * @param clazz + * @param + * @return + */ + public static T getBean(String name,Class clazz){ + ApplicationContext applicationContext = getApplicationContext(); + if(applicationContext == null){ + return null; + } + return applicationContext.getBean(name, clazz); + } +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/third/SmartRedisService.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/third/SmartRedisService.java new file mode 100644 index 00000000..78aa5c32 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/third/SmartRedisService.java @@ -0,0 +1,622 @@ +package com.gangquan360.smartadmin.third; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.*; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * [ redis 一顿操作 ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/3/26 0026 下午 18:12 + * @since JDK1.8 + */ +@Slf4j +@Component +public class SmartRedisService { + + @Autowired + private RedisTemplate redisTemplate; + + @Autowired + private ValueOperations redisValueOperations; + + @Autowired + private HashOperations redisHashOperations; + + @Autowired + private ListOperations redisListOperations; + + @Autowired + private SetOperations redisSetOperations; + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 根据key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete(CollectionUtils.arrayToList(key)); + } + } + } + + //============================String============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public String get(String key) { + return key == null ? null : redisValueOperations.get(key); + } + + public T getObject(String key, Class clazz) { + Object json = this.get(key); + if (json == null) { + return null; + } + T obj = JSON.parseObject(json.toString(), clazz); + return obj; + } + + public List getList(String key, Class clz) { + Object json = this.get(key); + if (json == null) { + return Lists.newArrayList(); + } + List list = JSONObject.parseArray(json.toString(), clz); + return list; + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, String value) { + try { + redisValueOperations.set(key, value); + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, String value, long time) { + try { + if (time > 0) { + redisValueOperations.set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 递增 + * + * @param key 键 + * @param delta 要增加几(大于0) + * @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisValueOperations.increment(key, delta); + } + + /** + * 递减 + * + * @param key 键 + * @param delta 要减少几(小于0) + * @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisValueOperations.increment(key, - delta); + } + + //================================Map================================= + + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisHashOperations.get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisHashOperations.entries(key); + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisHashOperations.putAll(key, map); + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisHashOperations.putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisHashOperations.put(key, item, value); + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisHashOperations.put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisHashOperations.delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisHashOperations.hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisHashOperations.increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisHashOperations.increment(key, item, - by); + } + + //============================set============================= + + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisSetOperations.members(key); + } catch (Exception e) { + log.error("", e); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisSetOperations.isMember(key, value); + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisSetOperations.add(key, values); + } catch (Exception e) { + log.error("", e); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisSetOperations.add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + log.error("", e); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisSetOperations.size(key); + } catch (Exception e) { + log.error("", e); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisSetOperations.remove(key, values); + return count; + } catch (Exception e) { + log.error("", e); + return 0; + } + } + //===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisListOperations.range(key, start, end); + } catch (Exception e) { + log.error("", e); + return null; + } + } + + /** + * 获取list缓存的所有内容 + * + * @param key + * @return + */ + public List lGetAll(String key) { + return lGet(key, 0, - 1); + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisListOperations.size(key); + } catch (Exception e) { + log.error("", e); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisListOperations.index(key, index); + } catch (Exception e) { + log.error("", e); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisListOperations.rightPush(key, value); + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisListOperations.rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + try { + redisListOperations.rightPushAll(key, value); + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisListOperations.rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisListOperations.set(key, index, value); + return true; + } catch (Exception e) { + log.error("", e); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisListOperations.remove(key, count, value); + return remove; + } catch (Exception e) { + log.error("", e); + return 0; + } + } +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartBaseEnumUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartBaseEnumUtil.java new file mode 100644 index 00000000..cfed468f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartBaseEnumUtil.java @@ -0,0 +1,85 @@ +package com.gangquan360.smartadmin.util; + +import com.gangquan360.smartadmin.common.domain.BaseEnum; + +/** + * 枚举工具类 + * + * @author listen + * @date 2017/10/10 18:17 + */ +public class SmartBaseEnumUtil { + + /** + * 校验int类型的参数与枚举类比较是否合法 + * + * @param value 参数 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return boolean + * @Author listen + */ + public static boolean checkEnum(Integer value, Class enumClass) { + if (null == value) { + return false; + } + BaseEnum[] enums = enumClass.getEnumConstants(); + for (BaseEnum baseEnum : enums) { + if (baseEnum.equalsValue(value)) { + return true; + } + } + return false; + } + + /** + * 获取枚举类的说明 value : info 的形式 + * + * @param enumClass + * @return String + */ + public static String getEnumDesc(Class enumClass) { + BaseEnum[] enums = enumClass.getEnumConstants(); + // value : info 的形式 + StringBuilder sb = new StringBuilder(); + for (BaseEnum baseEnum : enums) { + sb.append(baseEnum.getValue() + ":" + baseEnum.getDesc() + ","); + } + return sb.toString(); + } + + /** + * 获取与int Code相匹配的枚举类的info + * + * @param value 参数 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return String 如无匹配枚举则返回null + */ + public static String getEnumDescByValue(Integer value, Class enumClass) { + BaseEnum[] enums = enumClass.getEnumConstants(); + for (BaseEnum baseEnum : enums) { + if (baseEnum.equalsValue(value)) { + return baseEnum.getDesc(); + } + } + return null; + } + + /** + * 根据int类型的参数与获取枚举类的实例 + * + * @param value 参数 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return BaseEnum 无匹配值返回null + * @Author listen + */ + public static T getEnumByValue(Object value, Class enumClass) { + T[] enums = enumClass.getEnumConstants(); + for (T baseEnum : enums) { + if (baseEnum.equalsValue(value)) { + return baseEnum; + } + } + return null; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartBeanUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartBeanUtil.java new file mode 100644 index 00000000..2c2d3701 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartBeanUtil.java @@ -0,0 +1,56 @@ +package com.gangquan360.smartadmin.util; + +import org.springframework.beans.BeanUtils; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class SmartBeanUtil { + + /** + * 复制bean的属性 + * + * @param source 源 要复制的对象 + * @param target 目标 复制到此对象 + */ + public static void copyProperties(Object source, Object target) { + BeanUtils.copyProperties(source, target); + } + + /** + * 复制对象 + * + * @param source 源 要复制的对象 + * @param target 目标 复制到此对象 + * @param + * @return + */ + public static T copy(Object source, Class target) { + try { + T newInstance = target.newInstance(); + BeanUtils.copyProperties(source, newInstance); + return newInstance; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 复制list + * + * @param source + * @param target + * @param + * @param + * @return + */ + public static List copyList(List source, Class target) { + + if (null == source || source.isEmpty()) { + return Collections.emptyList(); + } + return source.stream().map(e -> copy(e, target)).collect(Collectors.toList()); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartBigDecimalUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartBigDecimalUtil.java new file mode 100644 index 00000000..0672dc9d --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartBigDecimalUtil.java @@ -0,0 +1,303 @@ +package com.gangquan360.smartadmin.util; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.NumberFormat; + +/** + * 全局 BigDecimal 工具类 + * + * @author listen + * @date 2018/01/17 13:54 + */ +public class SmartBigDecimalUtil { + + /** + * 价格类型 保留小数点 2 + */ + public static final int PRICE_DECIMAL_POINT = 2; + + /** + * 价格类型 保留小数点 6 + */ + public static final int SIX_PRICE_DECIMAL_POINT = 6; + + /** + * 重量类型保留小数点 3 + */ + public static final int WEIGHT_DECIMAL_POINT = 3; + + /** + * 金额相关计算方法:四舍五入 保留2位小数点 + */ + public static class Amount { + + public static BigDecimal add(BigDecimal num1, BigDecimal num2) { + return setScale(num1.add(num2), PRICE_DECIMAL_POINT); + } + public static BigDecimal multiply(BigDecimal num1, BigDecimal num2) { + return setScale(num1.multiply(num2), PRICE_DECIMAL_POINT); + } + public static BigDecimal subtract(BigDecimal num1, BigDecimal num2) { + return setScale(num1.subtract(num2), PRICE_DECIMAL_POINT); + } + public static BigDecimal divide(BigDecimal num1, BigDecimal num2) { + return setScale(num1.divide(num2, RoundingMode.HALF_UP), PRICE_DECIMAL_POINT); + } + } + + /** + * 金额相关计算方法:四舍五入 保留2位小数点 + */ + public static class AmountSix { + + public static BigDecimal add(BigDecimal num1, BigDecimal num2) { + return setScale(num1.add(num2), SIX_PRICE_DECIMAL_POINT); + } + public static BigDecimal multiply(BigDecimal num1, BigDecimal num2) { + return setScale(num1.multiply(num2), SIX_PRICE_DECIMAL_POINT); + } + public static BigDecimal subtract(BigDecimal num1, BigDecimal num2) { + return setScale(num1.subtract(num2), SIX_PRICE_DECIMAL_POINT); + } + public static BigDecimal divide(BigDecimal num1, BigDecimal num2) { + return num1.divide(num2, PRICE_DECIMAL_POINT, RoundingMode.HALF_UP); + } + } + + /** + * 重量相关计算方法:四舍五入 保留3位小数点 + */ + public static class Weight { + + public static BigDecimal add(BigDecimal num1, BigDecimal num2) { + return setScale(num1.add(num2), WEIGHT_DECIMAL_POINT); + } + public static BigDecimal multiply(BigDecimal num1, BigDecimal num2) { + return setScale(num1.multiply(num2), WEIGHT_DECIMAL_POINT); + } + public static BigDecimal subtract(BigDecimal num1, BigDecimal num2) { + return setScale(num1.subtract(num2), WEIGHT_DECIMAL_POINT); + } + public static BigDecimal divide(BigDecimal num1, BigDecimal num2) { + return num1.divide(num2, WEIGHT_DECIMAL_POINT, RoundingMode.HALF_UP); + } + } + + /** + * BigDecimal 加法 num1 + num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal add(BigDecimal num1, BigDecimal num2, int point) { + return setScale(num1.add(num2), point); + } + + /** + * BigDecimal 乘法 num1 x num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal multiply(BigDecimal num1, BigDecimal num2, int point) { + return setScale(num1.multiply(num2), point); + } + + /** + * BigDecimal 减法 num1 - num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal subtract(BigDecimal num1, BigDecimal num2, int point) { + return setScale(num1.subtract(num2), point); + } + + /** + * BigDecimal 除法 num1/num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal divide(BigDecimal num1, BigDecimal num2, int point) { + return num1.divide(num2, point, RoundingMode.HALF_UP); + } + + /** + * 设置小数点类型为 四舍五入 + * + * @param num + * @param point + * @return BigDecimal + */ + public static BigDecimal setScale(BigDecimal num, int point) { + return num.setScale(point, RoundingMode.HALF_UP); + } + + /** + * 比较 num1 是否大于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isGreaterThan(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) == 1; + } + + /** + * 比较 num1 是否大于等于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isGreaterOrEqual(BigDecimal num1, BigDecimal num2) { + return isGreaterThan(num1, num2) || equals(num1, num2); + } + + /** + * 比较 num1 是否小于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isLessThan(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) == - 1; + } + + /** + * 比较 num1 是否小于等于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isLessOrEqual(BigDecimal num1, BigDecimal num2) { + return isLessThan(num1, num2) || equals(num1, num2); + } + + /** + * 比较 num1 是否等于 num2 + * + * @param num1 + * @param num2 + * @return + */ + public static boolean equals(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) == 0; + } + + /** + * 计算 num1 / num2 的百分比 + * + * @param num1 + * @param num2 + * @return String + */ + public static String getPercentage(BigDecimal num1, BigDecimal num2) { + BigDecimal result = num1.divide(num2, 4, RoundingMode.HALF_UP); + NumberFormat percent = NumberFormat.getPercentInstance(); + percent.setMaximumFractionDigits(2); + return percent.format(result.doubleValue()); + } + + /** + * 计算 num1 / num2 的百分比 + * + * @param num1 + * @param num2 + * @param point 保留几位小数 + * @return String + */ + public static BigDecimal bigDecimalPercent(Integer num1, Integer num2, int point) { + if (num1 == null || num2 == null) { + return BigDecimal.ZERO; + } + if (num2.equals(Integer.valueOf(0))) { + return BigDecimal.ZERO; + } + BigDecimal bigDecimalNum1 = new BigDecimal(num1); + BigDecimal bigDecimalNum2 = new BigDecimal(num2); + return bigDecimalPercent(bigDecimalNum1, bigDecimalNum2, point); + } + + /** + * 计算 num1 / num2 的百分比 + * + * @param num1 + * @param num2 + * @param point 保留几位小数 + * @return String + */ + public static BigDecimal bigDecimalPercent(BigDecimal num1, BigDecimal num2, int point) { + if (num1 == null || num2 == null) { + return BigDecimal.ZERO; + } + if (equals(BigDecimal.ZERO, num2)) { + return BigDecimal.ZERO; + } + BigDecimal percent = num1.divide(num2, point + 2, RoundingMode.HALF_UP); + BigDecimal percent100 = percent.multiply(new BigDecimal(100)).setScale(point); + return percent100; + } + + /** + * 判断num是否为空 或者 零 + * + * @param num + * @return String + */ + public static Boolean isEmpty(BigDecimal num) { + return null == num || equals(BigDecimal.ZERO, num); + } + + /** + * 判断num是否 不等于null 并且不等于零 + * + * @param num + * @return String + */ + public static Boolean isNotEmpty(BigDecimal num) { + return ! isEmpty(num); + } + + /** + * 转换为万 + * + * @param num + * @param point + * @return + */ + public static BigDecimal convertTenThousand(BigDecimal num, int point) { + BigDecimal decimal = num.divide(new BigDecimal(10000), point, RoundingMode.HALF_UP); + return decimal; + } + + /** + * 转换为负数 + * + * @param num + * @return + */ + public static BigDecimal convertToMinusNumber(BigDecimal num) { + if (isLessOrEqual(num, BigDecimal.ZERO)) { + return num; + } + return BigDecimal.ZERO.subtract(num); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartDateUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartDateUtil.java new file mode 100644 index 00000000..28a602b4 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartDateUtil.java @@ -0,0 +1,521 @@ +package com.gangquan360.smartadmin.util; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateUtils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 线程安全的date工具类 + * + * @author jiaozi + */ +public class SmartDateUtil extends DateUtils { + + private static final ThreadLocal dateFormats = new ThreadLocal() { + @Override + protected DateFormats initialValue() { + return new DateFormats(); + } + }; + + public static final int HOUR_MIN = 60; + + public static final int DAY_MI_SECOND = 24 * 60 * 60 * 1000; + + public static String formatYMD(Date date) { + return dateFormats.get().ymd.format(date); + } + + public static String formatYMDDigital(Date date) { + return dateFormats.get().ymdDigital.format(date); + } + + public static String formatYMDHMSDigital(Date date) { + return dateFormats.get().ymdhmsDigital.format(date); + } + + public static String formatYM(Date date) { + return dateFormats.get().ym.format(date); + } + + public static String formatHMS(Date date) { + return dateFormats.get().hms.format(date); + } + + public static String formatHM(Date date) { + return dateFormats.get().hm.format(date); + } + + public static String formatYMDHM(Date date) { + return dateFormats.get().ymdhm.format(date); + } + + public static String formatYMDHMS(Date date) { + return dateFormats.get().ymdhms.format(date); + } + + public static String formatYMDChinese(Date date) { + return dateFormats.get().ymdChinese.format(date); + } + + public static String formatYMDSlash(Date date) { + return dateFormats.get().ymdSlash.format(date); + } + + public static Date parseYMD(String dateStr) { + return parse(dateFormats.get().ymd, dateStr); + } + + public static Date parseYMDDigital(String dateStr) { + return parse(dateFormats.get().ymdDigital, dateStr); + } + + public static Date parseYMDHMSDigital(String dateStr) { + return parse(dateFormats.get().ymdhmsDigital, dateStr); + } + + public static Date parseformatYMDChinese(String dateStr) { + return parse(dateFormats.get().ymdChinese, dateStr); + } + + public static Date parseYM(String dateStr) { + return parse(dateFormats.get().ym, dateStr); + } + + public static Date parseYMDHMS(String dateStr) { + + return parse(dateFormats.get().ymdhms, dateStr); + } + + public static Date parseYMDHM(String dateStr) { + return parse(dateFormats.get().ymdhm, dateStr); + } + + public static Date parseTodayHMS(String dateStr) { + String today = formatYMD(new Date()); + String todayDateStr = String.format("%s %s", today, dateStr); + return parse(dateFormats.get().ymdhms, todayDateStr); + } + + /** + * 判断当前时间是否在某段时间内 参数不区分先后顺序 + */ + public static boolean isDuringTwoDate(Date date, Date another) { + long dateTime = date.getTime(); + long anotherTime = another.getTime(); + long currentTime = System.currentTimeMillis(); + + if (currentTime > dateTime && currentTime < anotherTime) { + return true; + } else if (currentTime > anotherTime && currentTime < dateTime) { + return true; + } else { + return false; + } + } + + public static Date parse(SimpleDateFormat format, String dateStr) { + try { + Date d = format.parse(dateStr); + Calendar c = Calendar.getInstance(); + c.setTime(d); + int year = c.get(Calendar.YEAR); + if (year >= 1000 && year <= 9999) { + return d; + } else { + return null; + } + } catch (Exception ex) { + return null; + } + } + + public static long daysOffset(Date date1, Date date2) { + date1 = parseYMD(formatYMD(date1)); + date2 = parseYMD(formatYMD(date2)); + return (date1.getTime() - date2.getTime()) / DAY_MI_SECOND; + } + + /** + * 今天是星期几 , 7表示星期日 + * + * @return + */ + public static int getTodayDayOfWeek() { + Calendar now = Calendar.getInstance(); + int dayOfweek = now.get(Calendar.DAY_OF_WEEK); + dayOfweek--; + if (dayOfweek == 0) { + dayOfweek = 7; + } + return dayOfweek; + } + + public static boolean isTodaytDay(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + Calendar todayCalendar = Calendar.getInstance(); + if (calendar.get(Calendar.YEAR) != todayCalendar.get(Calendar.YEAR)) { + return false; + } else if (calendar.get(Calendar.MONTH) != todayCalendar.get(Calendar.MONTH)) { + return false; + } else if (calendar.get(Calendar.DAY_OF_MONTH) != todayCalendar.get(Calendar.DAY_OF_MONTH)) { + return false; + } + return true; + } + + /** + * 设置Calendar的小时、分钟、秒、毫秒 + * + * @param calendar 日历 + * @param hour 小时 + * @param minute 分钟 + * @param second 秒 + * @param milliSecond 毫秒 + */ + public static void setCalender(Calendar calendar, int hour, int minute, int second, int milliSecond) { + calendar.set(Calendar.HOUR_OF_DAY, hour); + calendar.set(Calendar.MINUTE, minute); + calendar.set(Calendar.SECOND, second); + calendar.set(Calendar.MILLISECOND, milliSecond); + } + + /** + * 获取指定天开始时间 + * + * @param date 日期 + * @return 获得该日期的开始 + */ + public static Date getDayBegin(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + setCalender(calendar, 0, 0, 0, 0); + return calendar.getTime(); + } + + /** + * 获取指定天结束时间 + * + * @param date 日期 + * @return 获得该日期的结束 + */ + public static Date getDayEnd(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + setCalender(calendar, 23, 59, 59, 999); + return calendar.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(); + } + + /** + * 获取该日期当月最后一天getAgeByBirthday + * + * @param date + * @return + */ + public static Date getMonthEnd(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(getDayEnd(date)); + calendar.add(Calendar.MONTH, 1); + calendar.set(Calendar.DAY_OF_MONTH, 1); + calendar.add(Calendar.DAY_OF_MONTH, - 1); + return calendar.getTime(); + } + + public static String timeDifference(Date endDate) { + Date nowDate = new Date(); + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // 获得两个时间的毫秒时间差异 + long diff = nowDate.getTime() - endDate.getTime(); + // 计算差多少天 + long day = diff / nd; + if (day > 0) { + return day + "天前"; + } + // 计算差多少小时 + long hour = diff % nd / nh; + if (hour > 0) { + return hour + "小时前"; + } + // 计算差多少分钟 + long min = diff % nd % nh / nm; + if (min > 0) { + return "1小时内"; + } + return "1小时内"; + } + + /** + * 计算所用时长 + * + * @param startDate + * @param endDate + * @return + */ + public static BigDecimal timeDifferenceMin(Date startDate, Date endDate) { + long nm = 1000 * 60; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - startDate.getTime(); + BigDecimal min = BigDecimal.valueOf(diff).divide(BigDecimal.valueOf(nm), RoundingMode.HALF_UP); + return min; + } + + /** + * 功能描述: 是否为当天 + * + * @param dateStr yyyy-mm-dd + * @return + * @auther yandanyang + * @date 2018/10/16 0016 下午 17:43 + */ + public static boolean isCurrentDayYMD(String dateStr) { + if (StringUtils.isEmpty(dateStr)) { + return true; + } + String current = SmartDateUtil.formatYMD(new Date()); + if (current.equals(dateStr)) { + return true; + } + return false; + } + + /** + * 功能描述: 是否为当月 + * + * @param dateStr yyyy-mm-dd + * @return + * @auther yandanyang + * @date 2018/10/16 0016 下午 17:43 + */ + public static boolean isCurrentMonthYMD(String dateStr) { + if (StringUtils.isEmpty(dateStr)) { + return true; + } + String queryDate = SmartDateUtil.formatYM(SmartDateUtil.parseYMD(dateStr)); + String current = SmartDateUtil.formatYM(new Date()); + if (current.equals(queryDate)) { + return true; + } + return false; + } + + public static boolean isCurrentMonthYM(String dateStr) { + if (StringUtils.isEmpty(dateStr)) { + return true; + } + String current = SmartDateUtil.formatYM(new Date()); + if (current.equals(dateStr)) { + return true; + } + return false; + } + + /** + * 获取本周的开始时间 + * + * @return + */ + public static Date getBeginDayOfWeek() { + Date date = new Date(); + if (date == null) { + return null; + } + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int dayofweek = cal.get(Calendar.DAY_OF_WEEK); + if (dayofweek == 1) { + dayofweek += 7; + } + cal.add(Calendar.DATE, 2 - dayofweek); + return getDayBegin(cal.getTime()); + } + + /** + * 获取本周的结束时间 + * + * @return + */ + public static Date getEndDayOfWeek() { + Calendar cal = Calendar.getInstance(); + cal.setTime(getBeginDayOfWeek()); + cal.add(Calendar.DAY_OF_WEEK, 6); + Date weekEndSta = cal.getTime(); + return getDayEnd(weekEndSta); + } + + /** + * 获取两个日期区间的日期(包括这两个日期) + */ + public static List getiIntervalDate(String dateBegin, String dateEnd) { + List dateList = new ArrayList<>(); + Date startDate = SmartDateUtil.parseYMD(dateBegin); + Date endDate = SmartDateUtil.parseYMD(dateEnd); + Calendar cal = Calendar.getInstance(); + cal.setTime(startDate); + dateList.add(dateBegin); + while (cal.getTime().compareTo(endDate) < 0) { + cal.add(Calendar.DAY_OF_MONTH, 1); + dateList.add(SmartDateUtil.formatYMD(cal.getTime())); + } + return dateList; + } + + /** + * 返回某个日期后几天的日期 + * + * @param date + * @param i + * @return + */ + public static Date getNextDay(Date date, int i) { + Calendar cal = new GregorianCalendar(); + cal.setTime(date); + cal.set(Calendar.DATE, cal.get(Calendar.DATE) + i); + return cal.getTime(); + } + + /** + * 返回某个日期前几天的日期 + * + * @param date + * @param i + * @return + */ + public static Date getFrontDay(Date date, int i) { + Calendar cal = new GregorianCalendar(); + cal.setTime(date); + cal.set(Calendar.DATE, cal.get(Calendar.DATE) - i); + return cal.getTime(); + } + + /** + * 获取昨天的开始时间 + * + * @return + */ + public static Date getBeginDayOfYesterday() { + Calendar cal = new GregorianCalendar(); + cal.setTime(getDayBegin(new Date())); + cal.add(Calendar.DAY_OF_MONTH, - 1); + return cal.getTime(); + } + + /** + * 获取昨天的结束时间 + * + * @return + */ + public static Date getEndDayOfYesterDay() { + Calendar cal = new GregorianCalendar(); + cal.setTime(getDayEnd(new Date())); + cal.add(Calendar.DAY_OF_MONTH, - 1); + return cal.getTime(); + } + + public static Integer getDayNumOfMonth(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + Integer num = c.getActualMaximum(Calendar.DAY_OF_MONTH); + return num; + } + + /** + * 转换日期(格式:年-月-日 时:分--分自定义) + */ + public static String formatYMDH(Date date, String minute) { + String ymdhm = dateFormats.get().ymdh + ":" + minute; + SimpleDateFormat format = new SimpleDateFormat(ymdhm); + return format.format(date); + } + + /** + * 获取几个月后的日期 + */ + public static Date getAfterMonth(Date inputDate, int number) { + Calendar c = Calendar.getInstance();//获得一个日历的实例 + c.setTime(inputDate);//设置日历时间 + c.add(Calendar.MONTH, number);//在日历的月份上增加月 + return c.getTime(); + } + + /** + * 计算当前月有多少天 + */ + public static int getDays(int year, int month) { + int days = 0; + if (month != 2) { + switch (month) { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + days = 31; + break; + case 4: + case 6: + case 9: + case 11: + days = 30; + + } + } else { + // 闰年 + if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { + days = 29; + } else { + days = 28; + } + } + System.out.println("当月有" + days + "天!"); + return days; + } + +} + +class DateFormats { + + public final SimpleDateFormat hms = new SimpleDateFormat("HH:mm:ss"); + + public final SimpleDateFormat hm = new SimpleDateFormat("HH:mm"); + + public final SimpleDateFormat ymdhm = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + + public final SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd"); + + public final SimpleDateFormat ym = new SimpleDateFormat("yyyy-MM"); + + public final SimpleDateFormat ymdhms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public final SimpleDateFormat ymdChinese = new SimpleDateFormat("yyyy年MM月dd日"); + + public final SimpleDateFormat ymdSlash = new SimpleDateFormat("yyyy/MM/dd"); + + public final SimpleDateFormat ymdDigital = new SimpleDateFormat("yyyyMMdd"); + + public final SimpleDateFormat ymdhmsDigital = new SimpleDateFormat("yyyyMMddHHmmss"); + + public static final String ymdh = "yyyy-MM-dd HH"; +} + diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartDigestUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartDigestUtil.java new file mode 100644 index 00000000..c36f2a2f --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartDigestUtil.java @@ -0,0 +1,17 @@ +package com.gangquan360.smartadmin.util; + +import org.apache.commons.codec.digest.DigestUtils; + +public class SmartDigestUtil extends DigestUtils { + + /** + * md5加盐加密 + * + * @param salt + * @param password + * @return + */ + public static String encryptPassword(String salt, String password) { + return SmartDigestUtil.md5Hex(String.format(salt, password)); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartHttpUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartHttpUtil.java new file mode 100644 index 00000000..27d62cd0 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartHttpUtil.java @@ -0,0 +1,151 @@ +package com.gangquan360.smartadmin.util; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * [ HttpUtils ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +public class SmartHttpUtil { + + public static String sendGet(String url, Map params, Map header) throws Exception { + HttpGet httpGet = null; + String body = ""; + try { + CloseableHttpClient httpClient = HttpClients.createDefault(); + List mapList = new ArrayList<>(); + if (params != null) { + for (Entry entry : params.entrySet()) { + mapList.add(entry.getKey() + "=" + entry.getValue()); + } + } + if (CollectionUtils.isNotEmpty(mapList)) { + url = url + "?"; + String paramsStr = StringUtils.join(mapList, "&"); + url = url + paramsStr; + } + httpGet = new HttpGet(url); + httpGet.setHeader("Content-type", "application/json; charset=utf-8"); + httpGet.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + if (header != null) { + for (Entry entry : header.entrySet()) { + httpGet.setHeader(entry.getKey(), entry.getValue()); + } + } + HttpResponse response = httpClient.execute(httpGet); + + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + throw new RuntimeException("请求失败"); + } else { + body = EntityUtils.toString(response.getEntity(), "UTF-8"); + } + } catch (Exception e) { + throw e; + } finally { + if (httpGet != null) { + httpGet.releaseConnection(); + } + } + return body; + } + + public static String sendPostJson(String url, String json, Map header) throws Exception { + HttpPost httpPost = null; + String body = ""; + try { + CloseableHttpClient httpClient = HttpClients.createDefault(); + httpPost = new HttpPost(url); + httpPost.setHeader("Content-type", "application/json; charset=utf-8"); + httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + if (header != null) { + for (Entry entry : header.entrySet()) { + httpPost.setHeader(entry.getKey(), entry.getValue()); + } + } + StringEntity entity = new StringEntity(json, Charset.forName("UTF-8")); + entity.setContentEncoding("UTF-8"); + entity.setContentType("application/json"); + httpPost.setEntity(entity); + HttpResponse response = httpClient.execute(httpPost); + + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + throw new RuntimeException("请求失败"); + } else { + body = EntityUtils.toString(response.getEntity(), "UTF-8"); + } + } catch (Exception e) { + throw e; + } finally { + if (httpPost != null) { + httpPost.releaseConnection(); + } + } + return body; + } + + public static String sendPostForm(String url, Map params, Map header) throws Exception { + HttpPost httpPost = null; + String body = ""; + try { + CloseableHttpClient httpClient = HttpClients.createDefault(); + httpPost = new HttpPost(url); + httpPost.setHeader("Content-type", "application/x-www-form-urlencoded"); + httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + if (header != null) { + for (Entry entry : header.entrySet()) { + httpPost.setHeader(entry.getKey(), entry.getValue()); + } + } + List nvps = new ArrayList<>(); + if (params != null) { + for (Entry entry : params.entrySet()) { + nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); + } + } + //设置参数到请求对象中 + httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); + HttpResponse response = httpClient.execute(httpPost); + + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + throw new RuntimeException("请求失败"); + } else { + body = EntityUtils.toString(response.getEntity(), "UTF-8"); + } + } catch (Exception e) { + throw e; + } finally { + if (httpPost != null) { + httpPost.releaseConnection(); + } + } + return body; + } + +} \ No newline at end of file diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartIPUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartIPUtil.java new file mode 100644 index 00000000..f85116b2 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartIPUtil.java @@ -0,0 +1,159 @@ +package com.gangquan360.smartadmin.util; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/5/5 0005 下午 15:34 + * @since JDK1.8 + */ +public class SmartIPUtil { + + public static final String IP_URL = "http://ip.taobao.com/service/getIpInfo.php"; + + public static String getLocalHostIP() { + // 本地IP,如果没有配置外网IP则返回它 + String localIp = null; + // 外网IP + String netIp = null; + try { + Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces(); + InetAddress ip = null; + // 是否找到外网IP + boolean finded = false; + while (netInterfaces.hasMoreElements() && ! finded) { + NetworkInterface ni = netInterfaces.nextElement(); + Enumeration address = ni.getInetAddresses(); + while (address.hasMoreElements()) { + ip = address.nextElement(); + // 外网IP + if (! ip.isSiteLocalAddress() && ! ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == - 1) { + netIp = ip.getHostAddress(); + finded = true; + break; + } else if (ip.isSiteLocalAddress() && ! ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == - 1) { + // 内网IP + localIp = ip.getHostAddress(); + } + } + } + } catch (SocketException e) { + e.getMessage(); + } + if (netIp != null && ! "".equals(netIp)) { + return netIp; + } else { + return localIp; + } + } + + public static String getRemoteIp(HttpServletRequest request) { + // 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 + + String ip = getXForwardedForIp(request); + if (ipValid(ip)) { + return realIp(ip); + } + ip = request.getHeader("Proxy-Client-IP"); + if (ipValid(ip)) { + return realIp(ip); + } + ip = request.getHeader("HTTP_CLIENT_IP"); + if (ipValid(ip)) { + return realIp(ip); + } + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + if (ipValid(ip)) { + return realIp(ip); + } + + ip = request.getRemoteAddr(); + return realIp(ip); + } + + private static String getXForwardedForIp(HttpServletRequest request) { + String ip = request.getHeader("x-forwarded-for"); + //ip 无效直接返回 + if (! ipValid(ip)) { + return ""; + } + if (ip.length() > 15) { + String[] ips = ip.split(","); + for (String strIp : ips) { + if (! ("unknown".equalsIgnoreCase(strIp))) { + ip = strIp; + break; + } + } + return ip; + } + return ip; + } + + private static Boolean ipValid(String ip) { + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + return false; + } + return true; + } + + private static String realIp(String ip) { + if (StringUtils.isEmpty(ip)) { + return ""; + } + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; + } + + public static String getRemoteLocation(HttpServletRequest request) { + String ip = getRemoteIp(request); + return getIpLocation(ip); + } + + public static String getIpLocation(String ip) { + String location = "未知"; + if (StringUtils.isEmpty(ip)) { + return location; + } + Map param = new HashMap<>(); + param.put("ip", ip); + + try { + String rspStr = SmartHttpUtil.sendGet(IP_URL, param, null); + if (StringUtils.isEmpty(rspStr)) { + return location; + } + JSONObject jsonObject = JSON.parseObject(rspStr); + String data = jsonObject.getString("data"); + JSONObject jsonData = JSON.parseObject(data); + String region = jsonData.getString("region"); + String city = jsonData.getString("city"); + location = region + " " + city; + if (location.contains("内网IP")) { + location = "内网(" + ip + ")"; + } + } catch (Exception e) { + + } + return location; + } + + public static void main(String[] args) { + System.out.printf(getIpLocation("172.16.0.221")); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartPaginationUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartPaginationUtil.java new file mode 100644 index 00000000..6aeed4b0 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartPaginationUtil.java @@ -0,0 +1,86 @@ +package com.gangquan360.smartadmin.util; + +import com.baomidou.mybatisplus.plugins.Page; +import com.gangquan360.smartadmin.common.domain.PageParamDTO; +import com.gangquan360.smartadmin.common.domain.PageResultDTO; +import org.apache.poi.ss.formula.functions.T; + +import java.util.List; + +/** + * 分页工具类 + * + * @author GHQ + * @date 2017-12-23 16:40 + */ + +public class SmartPaginationUtil { + + public static PageResultDTO convert2PageInfoDTO(Page page) { + PageResultDTO result = new PageResultDTO<>(); + result.setPageNum(page.getCurrent()); + result.setPageSize(page.getSize()); + result.setTotal(Long.valueOf(page.getTotal())); + result.setPages(page.getPages()); + result.setList(page.getRecords()); + return result; + } + + public static Page convert2PageQueryInfo(PageParamDTO baseDTO) { + Page page = new Page<>(); + Boolean sort = baseDTO.getSort(); + if (null != sort && SmartStringUtil.isNoneBlank(baseDTO.getOrderByField())) { + page.setAsc(sort); + page.setOrderByField(baseDTO.getOrderByField()); + } + page.setCurrent(baseDTO.getPageNum()); + page.setSize(baseDTO.getPageSize()); + if (null != baseDTO.getSearchCount()) { + page.setSearchCount(baseDTO.getSearchCount()); + } + return page; + } + + /** + * 转换为 PageResultDTO 对象 + * + * @param page + * @param sourceList 原list + * @param targetClazz 目标类 + * @return + * @author yandanyang + * @date 2018年5月16日 下午6:05:28 + */ + public static PageResultDTO convert2PageInfoDTO(Page page, List sourceList, Class targetClazz) { + PageResultDTO pageResultDTO = setPage(page); + List records = SmartBeanUtil.copyList(sourceList, targetClazz); + page.setRecords(records); + pageResultDTO.setList(records); + return pageResultDTO; + } + + /** + * 转换为 PageResultDTO 对象 + * + * @param page + * @param sourceList list + * @return + * @author yandanyang + * @date 2018年5月16日 下午6:05:28 + */ + public static PageResultDTO convert2PageInfoDTO(Page page, List sourceList) { + PageResultDTO pageResultDTO = setPage(page); + page.setRecords(sourceList); + pageResultDTO.setList(sourceList); + return pageResultDTO; + } + + private static PageResultDTO setPage(Page page) { + PageResultDTO pageResultDTO = new PageResultDTO(); + pageResultDTO.setPageNum(page.getCurrent()); + pageResultDTO.setPageSize(page.getSize()); + pageResultDTO.setTotal(Long.valueOf(page.getTotal())); + pageResultDTO.setPages(page.getPages()); + return pageResultDTO; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartQuartzUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartQuartzUtil.java new file mode 100644 index 00000000..7b1506bd --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartQuartzUtil.java @@ -0,0 +1,43 @@ +package com.gangquan360.smartadmin.util; + +import com.gangquan360.smartadmin.module.quartz.constant.QuartzConst; +import org.apache.commons.lang3.StringUtils; +import org.quartz.JobKey; +import org.quartz.TriggerKey; + +/** + * [ ] + * + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2018 1024lab.netInc. All rights reserved. + * @date 2019/4/13 0013 下午 15:16 + * @since JDK1.8 + */ +public class SmartQuartzUtil { + + public static Long getTaskIdByJobKey(JobKey jobKey) { + String name = jobKey.getName(); + return Long.valueOf(StringUtils.replace(name, QuartzConst.JOB_KEY_PREFIX, "")); + } + + public static Integer getTaskIdByTriggerKey(TriggerKey triggerKey) { + String name = triggerKey.getName(); + return Integer.valueOf(StringUtils.replace(name, QuartzConst.TRIGGER_KEY_PREFIX, "")); + } + + /** + * 获取触发器key + */ + public static TriggerKey getTriggerKey(Long taskId) { + return TriggerKey.triggerKey(QuartzConst.TRIGGER_KEY_PREFIX + taskId); + } + + /** + * 获取jobKey + */ + public static JobKey getJobKey(Long taskId) { + return JobKey.jobKey(QuartzConst.JOB_KEY_PREFIX + taskId); + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartRequestTokenUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartRequestTokenUtil.java new file mode 100644 index 00000000..b8f3f39a --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartRequestTokenUtil.java @@ -0,0 +1,51 @@ +package com.gangquan360.smartadmin.util; + +import com.gangquan360.smartadmin.module.login.domain.RequestTokenBO; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +/** + * @author yandanyang + * @version 1.0 + * @company 1024lab.net + * @copyright (c) 2019 1024lab.netInc. All rights reserved. + * @date + * @since JDK1.8 + */ +public class SmartRequestTokenUtil { + + private static final String USER_KEY = "smart_admin_user"; + + private static ThreadLocal RequestUserThreadLocal = new ThreadLocal(); + + public static void setUser(HttpServletRequest request, RequestTokenBO requestToken) { + request.setAttribute(USER_KEY, requestToken); + RequestUserThreadLocal.set(requestToken); + } + + public static RequestTokenBO getThreadLocalUser() { + return RequestUserThreadLocal.get(); + } + + public static RequestTokenBO getRequestUser() { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + if (requestAttributes != null) { + HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); + if (request != null) { + return (RequestTokenBO) request.getAttribute(USER_KEY); + } + } + return null; + } + + public static Long getRequestUserId() { + RequestTokenBO requestUser = getRequestUser(); + if (null == requestUser) { + return null; + } + return requestUser.getRequestUserId(); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartSendMailUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartSendMailUtil.java new file mode 100644 index 00000000..8ff2ed6b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartSendMailUtil.java @@ -0,0 +1,243 @@ +package com.gangquan360.smartadmin.util; + +import lombok.extern.slf4j.Slf4j; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.mail.Authenticator; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.*; +import javax.mail.util.ByteArrayDataSource; +import java.io.InputStream; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import java.util.regex.Pattern; + +@Slf4j +public class SmartSendMailUtil { + + /** + * 邮箱正则表达式 + */ + static final Pattern pattern = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$"); + + public static void main(String[] args) throws Exception { + // 发件人的 邮箱 和 密码(替换为自己的邮箱和密码) + // PS: 某些邮箱服务器为了增加邮箱本身密码的安全性,给 SMTP 客户端设置了独立密码(有的邮箱称为“授权码”), + // 对于开启了独立密码的邮箱, 这里的邮箱密码必需使用这个独立密码(授权码)。 + String myEmailAccount = "xxxxx@163.com"; + String myEmailPassword = "xxxxxx"; + // 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般(只是一般, 绝非绝对)格式为: smtp.xxx.com + // 网易163邮箱的 SMTP 服务器地址为: smtp.163.com + String myEmailSMTPHost = "smtp.163.com"; + // 收件人邮箱(替换为自己知道的有效邮箱) + String[] toMailAccountList = new String[]{"421316927@qq.com"}; + SmartSendMailUtil.sendMail(myEmailAccount, myEmailPassword, "", toMailAccountList, "", myEmailSMTPHost, "测试发送邮件", "测试发送邮件"); + + } + + /** + * 发送文本邮件 + * + * @param sendMail 发件人邮箱 + * @param sendMailPwd 发件人密码 + * @param sendMailName 发件人昵称(可选) + * @param receiveMail 收件人邮箱 + * @param receiveMailName 收件人昵称(可选) + * @param sendSMTPHost 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般(只是一般, 绝非绝对)格式为: smtp.xxx.com + * @param title 邮件主题 + * @param content 邮件正文 + * @author Administrator + * @date 2017年12月13日 下午1:51:38 + */ + public static void sendMail(String sendMail, String sendMailPwd, String sendMailName, String[] receiveMail, String receiveMailName, String sendSMTPHost, String title, String content) { + + Session session = createSession(sendSMTPHost); + // 3. 创建一封邮件 + MimeMessage message; + try { + message = createMimeMessage(session, sendMail, sendMailName, receiveMail, receiveMailName, title, content); + // 4. 根据 Session 获取邮件传输对象 + Transport transport = session.getTransport(); + + // 5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错 + // + // PS_01: 成败的判断关键在此一句, 如果连接服务器失败, 都会在控制台输出相应失败原因的 log, + // 仔细查看失败原因, 有些邮箱服务器会返回错误码或查看错误类型的链接, 根据给出的错误 + // 类型到对应邮件服务器的帮助网站上查看具体失败原因。 + // + // PS_02: 连接失败的原因通常为以下几点, 仔细检查代码: + // (1) 邮箱没有开启 SMTP 服务; + // (2) 邮箱密码错误, 例如某些邮箱开启了独立密码; + // (3) 邮箱服务器要求必须要使用 SSL 安全连接; + // (4) 请求过于频繁或其他原因, 被邮件服务器拒绝服务; + // (5) 如果以上几点都确定无误, 到邮件服务器网站查找帮助。 + // + // PS_03: 仔细看log, 认真看log, 看懂log, 错误原因都在log已说明。 + transport.connect(sendMail, sendMailPwd); + // 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人 + transport.sendMessage(message, message.getAllRecipients()); + // 7. 关闭连接 + transport.close(); + } catch (Exception e) { + log.error("", e); + } + + } + + /** + * 发送带附件的邮件 + * + * @param sendMail 发件人邮箱 + * @param sendMailPwd 发件人密码 + * @param sendMailName 发件人昵称(可选) + * @param receiveMail 收件人邮箱 + * @param receiveMailName 收件人昵称(可选) + * @param sendSMTPHost 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般(只是一般, 绝非绝对)格式为: smtp.xxx.com + * @param title 邮件主题 + * @param content 邮件正文 + * @author Administrator + * @date 2017年12月13日 下午1:51:38 + */ + public static void sendFileMail(String sendMail, String sendMailPwd, String sendMailName, String[] receiveMail, String receiveMailName, String sendSMTPHost, String title, String content, + InputStream is, String fileName, String port) { + + Session session = createSSLSession(sendSMTPHost, port, sendMailName, sendMailPwd); + // 3. 创建一封邮件 + MimeMessage message; + try { + message = createMimeMessage(session, sendMail, sendMailName, receiveMail, receiveMailName, title, content); + // 5. Content: 邮件正文(可以使用html标签)(内容有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改发送内容) + MimeMultipart mm = new MimeMultipart(); + MimeBodyPart text = new MimeBodyPart(); + text.setContent(content, "text/html;charset=UTF-8"); + mm.addBodyPart(text); + if (null != is && is.available() > 0) { + MimeBodyPart attachment = new MimeBodyPart(); + DataSource source = new ByteArrayDataSource(is, "application/msexcel"); + // 将附件数据添加到"节点" + attachment.setDataHandler(new DataHandler(source)); + // 设置附件的文件名(需要编码) + attachment.setFileName(MimeUtility.encodeText(fileName)); + // 10. 设置文本和 附件 的关系(合成一个大的混合"节点" / Multipart ) + // 如果有多个附件,可以创建多个多次添加 + mm.addBodyPart(attachment); + } + message.setContent(mm); + message.saveChanges(); + // 4. 根据 Session 获取邮件传输对象 + Transport transport = session.getTransport("smtp"); + transport.connect(sendSMTPHost, sendMail, sendMailPwd); + // // 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人 + transport.sendMessage(message, message.getAllRecipients()); + // 7. 关闭连接 + } catch (Exception e) { + log.error("", e); + } + + } + + /** + * 创建session + * + * @author lidoudou + * @date 2019/2/16 14:59 + */ + private static Session createSSLSession(String sendSMTPHost, String port, String userName, String pwd) { + // 1. 创建参数配置, 用于连接邮件服务器的参数配置 + Properties props = new Properties(); // 参数配置 + + props.setProperty("mail.smtp.user", userName); + props.setProperty("mail.smtp.password", pwd); + props.setProperty("mail.smtp.host", sendSMTPHost); + props.setProperty("mail.smtp.port", port); + props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + props.setProperty("mail.smtp.socketFactory.fallback", "false"); + props.setProperty("mail.smtp.socketFactory.port", port); + props.put("mail.smtp.auth", "true"); + + // 2. 根据配置创建会话对象, 用于和邮件服务器交互 + Session session = Session.getDefaultInstance(props, new Authenticator() { + //身份认证 + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(userName, pwd); + } + }); + session.setDebug(true); // 设置为debug模式, 可以查看详细的发送 log + return session; + } + + /** + * 创建session + * + * @author lidoudou + * @date 2019/2/16 14:59 + */ + private static Session createSession(String sendSMTPHost) { + // 1. 创建参数配置, 用于连接邮件服务器的参数配置 + Properties props = new Properties(); // 参数配置 + props.setProperty("mail.transport.protocol", "smtp"); // 使用的协议(JavaMail规范要求) + props.setProperty("mail.smtp.host", sendSMTPHost); // 发件人的邮箱的 SMTP 服务器地址 + props.setProperty("mail.smtp.auth", "true"); // 需要请求认证 + // PS: 某些邮箱服务器要求 SMTP 连接需要使用 SSL 安全认证 (为了提高安全性, 邮箱支持SSL连接, 也可以自己开启), + // 如果无法连接邮件服务器, 仔细查看控制台打印的 log, 如果有有类似 “连接失败, 要求 SSL 安全连接” 等错误, + // 打开下面 /* ... */ 之间的注释代码, 开启 SSL 安全连接。 + /* + * // SMTP 服务器的端口 (非 SSL 连接的端口一般默认为 25, 可以不添加, 如果开启了 SSL 连接, // 需要改为对应邮箱的 SMTP 服务器的端口, + * 具体可查看对应邮箱服务的帮助, // QQ邮箱的SMTP(SLL)端口为465或587, 其他邮箱自行去查看) final String smtpPort = "465"; + * props.setProperty("mail.smtp.port", smtpPort); + * props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + * props.setProperty("mail.smtp.socketFactory.fallback", "false"); + * props.setProperty("mail.smtp.socketFactory.port", smtpPort); + */ + // 2. 根据配置创建会话对象, 用于和邮件服务器交互 + Session session = Session.getInstance(props); + session.setDebug(true); // 设置为debug模式, 可以查看详细的发送 log + return session; + } + + /** + * 创建一封只包含文本的简单邮件 + * + * @param session 和服务器交互的会话 + * @param sendMail 发件人邮箱 + * @param sendMailName 发件人昵称 + * @param receiveMail 收件人邮箱 + * @param receiveMailName 收件人昵称 + * @param title 邮件主题 + * @param content 邮件正文 + * @return + * @throws Exception + * @author Administrator + * @date 2017年12月13日 下午1:55:45 + */ + public static MimeMessage createMimeMessage(Session session, String sendMail, String sendMailName, String[] receiveMail, String receiveMailName, String title, String content) throws Exception { + // 1. 创建一封邮件 + MimeMessage message = new MimeMessage(session); + // 2. From: 发件人(昵称有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改昵称) + message.setFrom(new InternetAddress(sendMail, sendMailName, "UTF-8")); + // 3. To: 收件人(可以增加多个收件人、抄送、密送) + List to = new LinkedList<>(); + for (String s : receiveMail) { + if (pattern.matcher(s).matches()) { + to.add(new InternetAddress(s)); + } + } + //Address[] addresses = new Address[]{new InternetAddress(receiveMail),new InternetAddress(receiveMail)}; + message.addRecipients(MimeMessage.RecipientType.TO, to.toArray((new InternetAddress[to.size()]))); + // 4. Subject: 邮件主题(标题有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改标题) + message.setSubject(title, "UTF-8"); + // 5. Content: 邮件正文(可以使用html标签)(内容有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改发送内容) + message.setContent(content, "text/html;charset=UTF-8"); + // 6. 设置发件时间 + message.setSentDate(new Date()); + // 7. 保存设置 + message.saveChanges(); + return message; + } +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartStringUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartStringUtil.java new file mode 100644 index 00000000..b3d82d0b --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartStringUtil.java @@ -0,0 +1,311 @@ +package com.gangquan360.smartadmin.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 字符串操作类,包括分割,转换,大写首字母 + * + * @author jiaozi + */ +public class SmartStringUtil extends StringUtils { + + // ===============split ======================= + + public static Set splitConvertToSet(String str, String split) { + if (isEmpty(str)) { + return new HashSet(); + } + String[] splitArr = str.split(split); + HashSet set = new HashSet(splitArr.length); + for (String string : splitArr) { + set.add(string); + } + return set; + } + + public static List splitConvertToList(String str, String split) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] splitArr = str.split(split); + ArrayList list = new ArrayList(splitArr.length); + for (String string : splitArr) { + list.add(string); + } + return list; + } + + // ===============split Integer======================= + + public static List splitConverToIntList(String str, String split, int defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + int parseInt = Integer.parseInt(strArr[i]); + list.add(parseInt); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static Set splitConverToIntSet(String str, String split, int defaultVal) { + if (isEmpty(str)) { + return new HashSet(); + } + String[] strArr = str.split(split); + HashSet set = new HashSet(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + int parseInt = Integer.parseInt(strArr[i]); + set.add(parseInt); + } catch (NumberFormatException e) { + set.add(defaultVal); + continue; + } + } + return set; + } + + public static Set splitConverToIntSet(String str, String split) { + return splitConverToIntSet(str, split, 0); + } + + public static List splitConverToIntList(String str, String split) { + return splitConverToIntList(str, split, 0); + } + + public static int[] splitConvertToIntArray(String str, String split, int defaultVal) { + if (isEmpty(str)) { + return new int[0]; + } + String[] strArr = str.split(split); + int[] result = new int[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Integer.parseInt(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static int[] splitConvertToIntArray(String str, String split) { + return splitConvertToIntArray(str, split, 0); + } + + // ===============split 2 Long======================= + + public static List splitConverToLongList(String str, String split, long defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + long parseLong = Long.parseLong(strArr[i]); + list.add(parseLong); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConverToLongList(String str, String split) { + return splitConverToLongList(str, split, 0L); + } + + public static long[] splitConvertToLongArray(String str, String split, long defaultVal) { + if (isEmpty(str)) { + return new long[0]; + } + String[] strArr = str.split(split); + long[] result = new long[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Long.parseLong(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static long[] splitConvertToLongArray(String str, String split) { + return splitConvertToLongArray(str, split, 0L); + } + + // ===============split convert byte======================= + + public static List splitConverToByteList(String str, String split, byte defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + byte parseByte = Byte.parseByte(strArr[i]); + list.add(parseByte); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConverToByteList(String str, String split) { + return splitConverToByteList(str, split, (byte) 0); + } + + public static byte[] splitConvertToByteArray(String str, String split, byte defaultVal) { + if (isEmpty(str)) { + return new byte[0]; + } + String[] strArr = str.split(split); + byte[] result = new byte[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Byte.parseByte(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static byte[] splitConvertToByteArray(String str, String split) { + return splitConvertToByteArray(str, split, (byte) 0); + } + + // ===============split convert double======================= + + public static List splitConverToDoubleList(String str, String split, double defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + double parseByte = Double.parseDouble(strArr[i]); + list.add(parseByte); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConverToDoubleList(String str, String split) { + return splitConverToDoubleList(str, split, 0); + } + + public static double[] splitConvertToDoubleArray(String str, String split, double defaultVal) { + if (isEmpty(str)) { + return new double[0]; + } + String[] strArr = str.split(split); + double[] result = new double[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Double.parseDouble(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static double[] splitConvertToDoubleArray(String str, String split) { + return splitConvertToDoubleArray(str, split, 0); + } + + // ===============solit convert float======================= + + public static List splitConverToFloatList(String str, String split, float defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + float parseByte = Float.parseFloat(strArr[i]); + list.add(parseByte); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConverToFloatList(String str, String split) { + return splitConverToFloatList(str, split, 0f); + } + + public static float[] splitConvertToFloatArray(String str, String split, float defaultVal) { + if (isEmpty(str)) { + return new float[0]; + } + String[] strArr = str.split(split); + float[] result = new float[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Float.parseFloat(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static float[] splitConvertToFloatArray(String str, String split) { + return splitConvertToFloatArray(str, split, 0f); + } + + // ===============upperCase======================= + + /** + * 将首字母大写 + * + * @param str + * @return + */ + public static String upperCaseFirstChar(String str) { + if (str == null || str.isEmpty()) { + return str; + } + char firstChar = str.charAt(0); + if (Character.isUpperCase(firstChar)) { + return str; + } + char[] values = str.toCharArray(); + values[0] = Character.toUpperCase(firstChar); + return new String(values); + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartThreadFactory.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartThreadFactory.java new file mode 100644 index 00000000..a6b34c25 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartThreadFactory.java @@ -0,0 +1,44 @@ +package com.gangquan360.smartadmin.util; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 拥有自己的thread facotry是为了jstack时候能看到是哪个线程 + * + * @author jiaozi + */ +public class SmartThreadFactory implements ThreadFactory { + + public static SmartThreadFactory create(String namePrefix) { + return new SmartThreadFactory(namePrefix); + } + + private final AtomicInteger poolNumber = new AtomicInteger(1); + + private final ThreadGroup group; + + private final AtomicInteger threadNumber = new AtomicInteger(1); + + private final String namePrefix; + + private SmartThreadFactory(String namePrefix) { + SecurityManager s = System.getSecurityManager(); + group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); + this.namePrefix = namePrefix + " pool " + poolNumber.getAndIncrement() + "-thread-"; + } + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); + if (t.isDaemon()) { + t.setDaemon(false); + } + + if (t.getPriority() != Thread.NORM_PRIORITY) { + t.setPriority(Thread.NORM_PRIORITY); + } + return t; + } + +} diff --git a/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartVerificationUtil.java b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartVerificationUtil.java new file mode 100644 index 00000000..76b6f879 --- /dev/null +++ b/java/smart-admin-api/src/main/java/com/gangquan360/smartadmin/util/SmartVerificationUtil.java @@ -0,0 +1,95 @@ +package com.gangquan360.smartadmin.util; + +import java.util.regex.Pattern; +/** + * 验证工具类 + * + * @author listen + * @date 2017/11/06 10:54 + */ +public class SmartVerificationUtil { + + + + /** + * 手机号码验证规则 + */ + public static final String PHONE_REGEXP = "^1[0-9]{10}"; + + /** + * 固定号码验证规则 + */ + public static final String FIXED_PHONE_REGEXP = "^0\\d{2,3}-[1-9]\\d{6,7}$"; + + /** + * 密码正则校验 + */ + public static final String PWD_REGEXP = "^[A-Za-z0-9.]{6,15}$"; + + /** + * 车牌号 + */ + public static final String CAR_NUMBER = + "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|" + "([A-HJ-Z" + "]{1}[A-D0-9]{1}[0-9]{3}警)))|" + + "([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|" + "([VKHBSLJNGCE]{1}[A-DJ-PR" + "-TVY]{1}[0-9]{5})"; + + /** + * 日期年月日校验 yyyy-MM-dd HH:mm:ss + */ + public static final String DATE_TIME = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9" + + "]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"; + + /** + * 日期校验 yyyy-MM-dd + */ + public static final String DATE = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))" + + "|(02-(0[1-9]|[1][0-9]|2[0-8])))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)" + "([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9" + + "][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|(" + "(([0-9]{2})(0[48]|[2468][048]|[13579][26])|(" + "(0[48" + "]|[2468][048]|[3579][26])00))-02-29)"; + + /** + * 年月校验 例: 2019-10 + */ + public static final String YEAR_MONTH = "^\\d{4}-((0([1-9]))|(1(0|1|2)))$"; + + + /** + * 时间区间验证 10:23-19:00 + */ + public static final String TIME_SECTION= "^(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])-(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])$"; + + /** + * 时间验证 10:23 + */ + public static final String TIME = "^(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])$"; + + /** + * 身份证号 + */ + public static final String ID_CARD = "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)"; + + /** + * URL + */ + public static final String URL = "[a-zA-z]+://[^\\s]*"; + + /** + * 邮箱 + */ + public static final String EMAIL = "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?"; + + /** + * 整数 + */ + public static final String INTEGER = "^-?[1-9]\\d*$"; + + /** + * 小数 + */ + public static final String DOUBLE = "^-?[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$"; + + + public static void main(String[] args) { + boolean matches = Pattern.matches(INTEGER, "1"); + System.out.println(matches); + } +} diff --git a/java/smart-admin-api/src/main/resources/banner.txt b/java/smart-admin-api/src/main/resources/banner.txt new file mode 100644 index 00000000..cd18d69c --- /dev/null +++ b/java/smart-admin-api/src/main/resources/banner.txt @@ -0,0 +1,8 @@ + / ____| | | /\ | | (_) +| (___ _ __ ___ __ _ _ __| |_ / \ __| |_ __ ___ _ _ __ + \___ \| '_ ` _ \ / _` | '__| __| / /\ \ / _` | '_ ` _ \| | '_ \ + ____) | | | | | | (_| | | | |_ / ____ \ (_| | | | | | | | | | | +|_____/|_| |_| |_|\__,_|_| \__/_/ \_\__,_|_| |_| |_|_|_| |_| + +SmartAdmin v1.0.0 + diff --git a/java/smart-admin-api/src/main/resources/dev/application.properties b/java/smart-admin-api/src/main/resources/dev/application.properties new file mode 100644 index 00000000..ad34ca04 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/dev/application.properties @@ -0,0 +1,122 @@ +######################### server ################### +server.servlet.context-path=/smart-admin-api +server.port=10086 +spring.profiles.active=dev + +######################### tomcat ################### +server.tomcat.basedir=/home/logs/smartadmin/tomcat-logs +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.pattern=%t %{X-Forwarded-For}i %a "%r" %s %D (%D ms) + +######################### jackson ######################### +spring.jackson.serialization.write-enums-using-to-string=true +spring.jackson.deserialization.read-enums-using-to-string=true +spring.jackson.deserialization.fail-on-unknown-properties=false +spring.jackson.default-property-inclusion=always +spring.jackson.date-format=yyyy-MM-dd HH:mm:ss +spring.jackson.time-zone=GMT+8 +spring.jackson.serialization.write-dates-as-timestamps=false + +######################### http file ######################### +spring.servlet.multipart.max-file-size=30MB +spring.servlet.multipart.max-request-size=30MB +file-upload-service.path=/home/upload/ +file-upload-service.geturl=http://172.16.0.145/smartAdmin/file/ + +######################### database ######################### +spring.datasource.url=jdbc:mysql://127.0.0.1:3306/smart-admin-dev?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC +spring.datasource.username=erp +spring.datasource.password=listen1015 +spring.datasource.initial-size=2 +spring.datasource.min-idle=1 +spring.datasource.max-active=10 +spring.datasource.max-wait=60000 +spring.datasource.time-between-eviction-runs-millis=60000 +spring.datasource.min-evictable-edle-time-millis=300000 +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.filters=stat +spring.datasource.druid.username=druid +spring.datasource.druid.password=Gq123456 +spring.datasource.druid.login.enabled=false + +######################### redis ####################################### +spring.redis.database=13 +spring.redis.host=172.16.0.145 +spring.redis.jedis.pool.max-active=100 +spring.redis.jedis.pool.min-idle=5 +spring.redis.jedis.pool.max-idle=10 +spring.redis.jedis.pool.max-wait=30000ms +spring.redis.port=50000 +spring.redis.timeout=10000ms +spring.redis.password= + +########################## rest http pool ######################### +#\u6700\u5927\u8FDE\u63A5\u6570 +http.pool.max-total=100 +#\u5355\u8DEF\u7531\u6700\u5927\u8FDE\u63A5\u6570 +http.pool.default-max-per-route=25 +#\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E(response)\u7684\u65F6\u95F4 +http.pool.socket-timeout=8000 +#\u8FDE\u63A5\u4E0A\u670D\u52A1\u5668(\u63E1\u624B\u6210\u529F)\u7684\u65F6\u95F4 +http.pool.connect-timeout=8000 +#\u4ECE\u8FDE\u63A5\u6C60\u4E2D\u83B7\u53D6\u8FDE\u63A5\u7684\u8D85\u65F6\u65F6\u95F4 +http.pool.connection-request-timeout=8000 + +######################### mybatis\u914D\u7F6E ######################### +mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl +# mybatis-plus \u5B57\u6BB5\u9A7C\u5CF0\u81EA\u52A8\u8F6C\u6362 +mybatis-plus.configuration.map-underscore-to-camel-case=true +mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml,/mapper/*/*Mapper.xml +mybatis-plus.typeAliasesPackage=com.gangquan360.smartadmin.*.*.domain.entity +mybatis-plus.global-config.refresh-mapper=true +mybatis-plus.global-config.db-column-underline=true + +######################### swagger ######################### +swagger.apiGroupName=smartAdmin +swagger.title=smartAdmin +swagger.description=smartAdmin +swagger.version=1.0 +swagger.serviceUrl=http://localhost:10086/smart-admin-api +swagger.packAge=com.gangquan360.smartadmin.module + +######################### jwt ######################### +jwt.key=smart-admin-jwt-key + +########################## smart reload ######################### +smart-reload.thread-count=1 +smart-reload.time-interval=5 + +######################### cros ######################### +access-control-allow-origin=* + +######################### heart beat ######################### +heart-beat.delayHandlerTime=60000 +heart-beat.intervalTime=180000 + +######################### quartz ############################# +#\u8C03\u5EA6\u6807\u8BC6\u540D \u96C6\u7FA4\u4E2D\u6BCF\u4E00\u4E2A\u5B9E\u4F8B\u90FD\u5FC5\u987B\u4F7F\u7528\u76F8\u540C\u7684\u540D\u79F0 +spring.quartz.properties.org.quartz.scheduler.instanceName=devClusteredScheduler +spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO +#\u8FDC\u7A0B\u7BA1\u7406\u76F8\u5173\u7684\u914D\u7F6E,\u5168\u90E8\u5173\u95ED +spring.quartz.properties.org.quartz.scheduler.rmi.export=false +spring.quartz.properties.org.quartz.scheduler.rmi.proxy=false +#\u8DF3\u8FC7quartz\u7248\u672C\u68C0\u67E5 +spring.quartz.properties.org.quartz.scheduler.skipUpdateCheck=true +#\u6570\u636E\u4FDD\u5B58\u65B9\u5F0F\u4E3A\u6301\u4E45\u5316 +spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate +spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_ +spring.quartz.properties.org.quartz.jobStore.isClustered=true +#\u8C03\u5EA6\u5B9E\u4F8B\u5931\u6548\u7684\u68C0\u67E5\u65F6\u95F4\u95F4\u9694 +spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=10000 +spring.quartz.properties.org.quartz.jobStore.useProperties=false +#\u8C03\u5EA6\u7EBF\u7A0B +spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool +spring.quartz.properties.org.quartz.threadPool.threadCount=2 +spring.quartz.properties.org.quartz.threadPool.threadPriority=5 +spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true +spring.quartz.properties.org.quartz.threadPool.threadNamePrefix=quartz +spring.quartz.job-store-type=jdbc +#ALWAYS,EMBEDDED,NEVER +spring.quartz.jdbc.initialize-schema=NEVER +spring.quartz.jdbc.schema=classpath:sql/quartz_mysql_2.3.0.sql diff --git a/java/smart-admin-api/src/main/resources/dev/log4j2.xml b/java/smart-admin-api/src/main/resources/dev/log4j2.xml new file mode 100644 index 00000000..86c514a3 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/dev/log4j2.xml @@ -0,0 +1,97 @@ + + + + + /home/logs/smart-admin/dev/logs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/codegenerator/TableMapper.xml b/java/smart-admin-api/src/main/resources/mapper/codegenerator/TableMapper.xml new file mode 100644 index 00000000..13be97b7 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/codegenerator/TableMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/datascope/DataScopeRoleMapper.xml b/java/smart-admin-api/src/main/resources/mapper/datascope/DataScopeRoleMapper.xml new file mode 100644 index 00000000..84d4d0b1 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/datascope/DataScopeRoleMapper.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + DELETE FROM t_role_data_scope + WHERE role_id = #{roleId} + + + + INSERT INTO t_role_data_scope (data_scope_type,view_type,role_id,update_time,create_time) VALUES + + ( + #{item.dataScopeType}, + #{item.viewType}, + #{item.roleId}, + now(), + now() + ) + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/department/DepartmentMapper.xml b/java/smart-admin-api/src/main/resources/mapper/department/DepartmentMapper.xml new file mode 100644 index 00000000..19904e31 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/department/DepartmentMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + d.id, + d.name, + d.short_name, + d.manager_id, + d.parent_id, + d.sort, + d.update_time, + d.create_time + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/email/EmailMapper.xml b/java/smart-admin-api/src/main/resources/mapper/email/EmailMapper.xml new file mode 100644 index 00000000..fcfb0813 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/email/EmailMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + delete from t_email where id = #{id} + + + + delete from t_email where id in + + #{item} + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/employee/EmployeeMapper.xml b/java/smart-admin-api/src/main/resources/mapper/employee/EmployeeMapper.xml new file mode 100644 index 00000000..79f48c02 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/employee/EmployeeMapper.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + e.id, + e.login_name, + e.login_pwd, + e.actual_name, + e.nick_name, + e.phone, + e.id_card, + e.birthday, + e.email, + e.department_id, + e.is_leave, + e.is_disabled, + e.remark, + e.is_delete, + e.update_time, + e.create_time + + + + + + + UPDATE t_employee e + set e.is_disabled = #{isDisabled} + WHERE id in + + #{item} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE t_employee + SET login_pwd = #{password} + WHERE id = #{employeeId} + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/file/FileMapper.xml b/java/smart-admin-api/src/main/resources/mapper/file/FileMapper.xml new file mode 100644 index 00000000..9b4a32ef --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/file/FileMapper.xml @@ -0,0 +1,100 @@ + + + + + + + + + + INSERT INTO t_file ( + module_id, + module_type, + file_name, + file_size, + file_type, + file_path, + creater_user, + file_location_type + ) + VALUES + + (#{item.moduleId},#{item.moduleType},#{item.fileName},#{item.fileSize},#{item.fileType},#{item.filePath},#{item.createrUser},#{item.createrUserType},#{item.fileLocationType}) + + + + + INSERT INTO t_file ( + module_id, + module_type, + file_name, + file_size, + file_type, + file_path, + creater_user, + file_location_type + ) + VALUES + + (#{item.moduleId},#{item.moduleType},#{item.fileName},#{item.fileSize},#{item.fileType},#{item.filePath},#{item.createrUser},#{item.createrUserType},#{item.fileLocationType}) + + + + + DELETE FROM t_file WHERE module_id =#{moduleId} + + + + DELETE FROM t_file WHERE module_id =#{moduleId} and module_type=#{moduleType} + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/heartbeat/HeartBeatRecordMapper.xml b/java/smart-admin-api/src/main/resources/mapper/heartbeat/HeartBeatRecordMapper.xml new file mode 100644 index 00000000..97b8521d --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/heartbeat/HeartBeatRecordMapper.xml @@ -0,0 +1,41 @@ + + + + + + + INSERT INTO t_heart_beat_record ( + project_path, + server_ip, + process_no, + process_start_time, + heart_beat_time + ) + VALUES + (#{projectPath}, + #{serverIp}, + #{processNo}, + #{processStartTime}, + #{heartBeatTime}) + + + + update t_heart_beat_record + set heart_beat_time = #{heartBeatTime} + + id = #{id} + + + + + + + diff --git a/java/smart-admin-api/src/main/resources/mapper/idgenerator/IdGeneratorMapper.xml b/java/smart-admin-api/src/main/resources/mapper/idgenerator/IdGeneratorMapper.xml new file mode 100644 index 00000000..55ad8557 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/idgenerator/IdGeneratorMapper.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + update t_id_generator set last_number = #{lastNumber}, update_time = now() where id = #{generatorId} + + + + replace into `t_id_generator_record` (`generator_id`, `year`, `month`, `day`, `last_number`) values (#{generatorId}, #{year}, #{month}, #{day}, #{lastNumber}) + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/log/OrderOperateLogMapper.xml b/java/smart-admin-api/src/main/resources/mapper/log/OrderOperateLogMapper.xml new file mode 100644 index 00000000..3ed401bb --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/log/OrderOperateLogMapper.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + INSERT INTO t_order_operate_log (order_id,order_type, operate_type, operate_content, operate_remark, employee_id, employee_name,ext_data,update_time,create_time) VALUES + + (#{item.orderId}, + #{item.orderType}, + #{item.operateType}, + #{item.operateContent}, + #{item.operateRemark}, + #{item.employeeId}, + #{item.employeeName}, + #{item.extData}, + #{item.updateTime} + #{item.createTime} + ) + + + + + diff --git a/java/smart-admin-api/src/main/resources/mapper/log/UserLoginLogMapper.xml b/java/smart-admin-api/src/main/resources/mapper/log/UserLoginLogMapper.xml new file mode 100644 index 00000000..f97f4853 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/log/UserLoginLogMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + delete from t_user_login_log where id = #{id} + + + + delete from t_user_login_log where id in + + #{item} + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/log/UserOperateLogMapper.xml b/java/smart-admin-api/src/main/resources/mapper/log/UserOperateLogMapper.xml new file mode 100644 index 00000000..c84d3a5a --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/log/UserOperateLogMapper.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + delete from t_user_operate_log where id = #{id} + + + + delete from t_user_operate_log where id in + + #{item} + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/notice/NoticeMapper.xml b/java/smart-admin-api/src/main/resources/mapper/notice/NoticeMapper.xml new file mode 100644 index 00000000..dd9e50e8 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/notice/NoticeMapper.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE t_notice + set deleted = #{deletedFlag} + WHERE id =#{id} + + + + + UPDATE t_notice set deleted = #{deletedFlag} where id in + + #{item} + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/notice/NoticeReceiveRecordMapper.xml b/java/smart-admin-api/src/main/resources/mapper/notice/NoticeReceiveRecordMapper.xml new file mode 100644 index 00000000..cee64902 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/notice/NoticeReceiveRecordMapper.xml @@ -0,0 +1,39 @@ + + + + + + + + + delete from t_notice_receive_record where notice_id = #{noticeId} + + + + INSERT INTO t_notice_receive_record (notice_id, employee_id, update_time, create_time) VALUES + + ( + #{item.noticeId}, + #{item.employeeId}, + now(), + now() + ) + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/position/PositionMapper.xml b/java/smart-admin-api/src/main/resources/mapper/position/PositionMapper.xml new file mode 100644 index 00000000..cfb7792d --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/position/PositionMapper.xml @@ -0,0 +1,59 @@ + + + + + + + id, + position_name, + remark, + update_time, + create_time + + + + + + + + INSERT INTO t_position_relation (position_id,employee_id) VALUES + + (#{item},#{batchDTO.employeeId}) + + + + + + DELETE FROM t_position_relation WHERE employee_id = #{employeeId} + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/privilege/PrivilegeMapper.xml b/java/smart-admin-api/src/main/resources/mapper/privilege/PrivilegeMapper.xml new file mode 100644 index 00000000..896e1282 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/privilege/PrivilegeMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + p.id, + p.type, + p.name, + p.key, + p.url, + p.sort, + p.parent_key, + p.update_time, + p.create_time + + + + + + + + + + DELETE FROM t_privilege + WHERE `key` IN + + #{item} + + + + + DELETE FROM t_privilege + WHERE parent_key IN + + #{item} + + + + + INSERT INTO t_privilege (`type`, `name`, `key`,url,sort,parent_key,create_time,update_time) VALUES + + ( + #{item.type}, + #{item.name}, + #{item.key}, + #{item.url}, + #{item.sort}, + #{item.parentKey}, + now(), + now() + ) + + + + + + UPDATE t_privilege + SET `type`=#{item.type},`name`=#{item.name},url=#{item.url},sort=#{item.sort},parent_key=#{item.parentKey},update_time=now() + WHERE `key` = #{item.key} + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/quartz/QuartzTaskLogMapper.xml b/java/smart-admin-api/src/main/resources/mapper/quartz/QuartzTaskLogMapper.xml new file mode 100644 index 00000000..570a8053 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/quartz/QuartzTaskLogMapper.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + tl.id, + tl.task_id, + tl.task_name, + tl.task_params, + tl.process_status, + tl.process_duration, + tl.process_log, + tl.ip_address, + tl.update_time, + tl.create_time + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/quartz/QuartzTaskMapper.xml b/java/smart-admin-api/src/main/resources/mapper/quartz/QuartzTaskMapper.xml new file mode 100644 index 00000000..8701f6d5 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/quartz/QuartzTaskMapper.xml @@ -0,0 +1,36 @@ + + + + + + + + t.id, + t.task_name, + t.task_bean, + t.task_params, + t.task_cron, + t.task_status, + t.remark, + t.update_time, + t.create_time + + + + + + + + UPDATE t_quartz_task t + set t.task_status = #{taskStatus} + WHERE t.id = #{taskId} + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/role/RoleEmployeeMapper.xml b/java/smart-admin-api/src/main/resources/mapper/role/RoleEmployeeMapper.xml new file mode 100644 index 00000000..7d60225a --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/role/RoleEmployeeMapper.xml @@ -0,0 +1,124 @@ + + + + + + + + + + er.id, + er.role_id, + er.employee_id, + er.update_time, + er.create_time + + + + + + + + + + + + + DELETE FROM t_role_employee + WHERE employee_id = #{employeeId} + + + + + DELETE FROM t_role_employee + WHERE role_id = #{roleId} + + + + DELETE FROM t_role_employee + WHERE role_id = #{roleId} and employee_id = #{employeeId} + + + + + DELETE FROM t_role_employee + WHERE role_id = #{roleId} and employee_id in + + #{item} + + + + + INSERT INTO t_role_employee (role_id, employee_id, update_time, create_time) VALUES + + ( + #{item.roleId}, + #{item.employeeId}, + now(), + now() + ) + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/role/RoleMapper.xml b/java/smart-admin-api/src/main/resources/mapper/role/RoleMapper.xml new file mode 100644 index 00000000..7c791e2f --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/role/RoleMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + r.id, + r.role_name, + r.remark, + r.update_time, + r.create_time + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/role/RolePrivilegeMapper.xml b/java/smart-admin-api/src/main/resources/mapper/role/RolePrivilegeMapper.xml new file mode 100644 index 00000000..b9f2cb83 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/role/RolePrivilegeMapper.xml @@ -0,0 +1,72 @@ + + + + + + + + + + rp.id, + rp.role_id, + rp.privilege_key, + rp.update_time, + rp.create_time + + + + + DELETE FROM t_role_privilege + WHERE role_id = #{roleId} + + + + DELETE FROM t_role_privilege + WHERE privilege_key in + + #{item} + + + + + + INSERT INTO t_role_privilege (role_id, privilege_key, update_time, create_time) VALUES + + ( + #{item.roleId}, + #{item.privilegeKey}, + now(), + now() + ) + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/smartreload/ReloadItemMapper.xml b/java/smart-admin-api/src/main/resources/mapper/smartreload/ReloadItemMapper.xml new file mode 100644 index 00000000..f9106a5b --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/smartreload/ReloadItemMapper.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/smartreload/ReloadResultMapper.xml b/java/smart-admin-api/src/main/resources/mapper/smartreload/ReloadResultMapper.xml new file mode 100644 index 00000000..864d93ad --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/smartreload/ReloadResultMapper.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/mapper/systemconfig/SystemConfigMapper.xml b/java/smart-admin-api/src/main/resources/mapper/systemconfig/SystemConfigMapper.xml new file mode 100644 index 00000000..6604274c --- /dev/null +++ b/java/smart-admin-api/src/main/resources/mapper/systemconfig/SystemConfigMapper.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/pre/application.properties b/java/smart-admin-api/src/main/resources/pre/application.properties new file mode 100644 index 00000000..ad34ca04 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/pre/application.properties @@ -0,0 +1,122 @@ +######################### server ################### +server.servlet.context-path=/smart-admin-api +server.port=10086 +spring.profiles.active=dev + +######################### tomcat ################### +server.tomcat.basedir=/home/logs/smartadmin/tomcat-logs +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.pattern=%t %{X-Forwarded-For}i %a "%r" %s %D (%D ms) + +######################### jackson ######################### +spring.jackson.serialization.write-enums-using-to-string=true +spring.jackson.deserialization.read-enums-using-to-string=true +spring.jackson.deserialization.fail-on-unknown-properties=false +spring.jackson.default-property-inclusion=always +spring.jackson.date-format=yyyy-MM-dd HH:mm:ss +spring.jackson.time-zone=GMT+8 +spring.jackson.serialization.write-dates-as-timestamps=false + +######################### http file ######################### +spring.servlet.multipart.max-file-size=30MB +spring.servlet.multipart.max-request-size=30MB +file-upload-service.path=/home/upload/ +file-upload-service.geturl=http://172.16.0.145/smartAdmin/file/ + +######################### database ######################### +spring.datasource.url=jdbc:mysql://127.0.0.1:3306/smart-admin-dev?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC +spring.datasource.username=erp +spring.datasource.password=listen1015 +spring.datasource.initial-size=2 +spring.datasource.min-idle=1 +spring.datasource.max-active=10 +spring.datasource.max-wait=60000 +spring.datasource.time-between-eviction-runs-millis=60000 +spring.datasource.min-evictable-edle-time-millis=300000 +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.filters=stat +spring.datasource.druid.username=druid +spring.datasource.druid.password=Gq123456 +spring.datasource.druid.login.enabled=false + +######################### redis ####################################### +spring.redis.database=13 +spring.redis.host=172.16.0.145 +spring.redis.jedis.pool.max-active=100 +spring.redis.jedis.pool.min-idle=5 +spring.redis.jedis.pool.max-idle=10 +spring.redis.jedis.pool.max-wait=30000ms +spring.redis.port=50000 +spring.redis.timeout=10000ms +spring.redis.password= + +########################## rest http pool ######################### +#\u6700\u5927\u8FDE\u63A5\u6570 +http.pool.max-total=100 +#\u5355\u8DEF\u7531\u6700\u5927\u8FDE\u63A5\u6570 +http.pool.default-max-per-route=25 +#\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E(response)\u7684\u65F6\u95F4 +http.pool.socket-timeout=8000 +#\u8FDE\u63A5\u4E0A\u670D\u52A1\u5668(\u63E1\u624B\u6210\u529F)\u7684\u65F6\u95F4 +http.pool.connect-timeout=8000 +#\u4ECE\u8FDE\u63A5\u6C60\u4E2D\u83B7\u53D6\u8FDE\u63A5\u7684\u8D85\u65F6\u65F6\u95F4 +http.pool.connection-request-timeout=8000 + +######################### mybatis\u914D\u7F6E ######################### +mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl +# mybatis-plus \u5B57\u6BB5\u9A7C\u5CF0\u81EA\u52A8\u8F6C\u6362 +mybatis-plus.configuration.map-underscore-to-camel-case=true +mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml,/mapper/*/*Mapper.xml +mybatis-plus.typeAliasesPackage=com.gangquan360.smartadmin.*.*.domain.entity +mybatis-plus.global-config.refresh-mapper=true +mybatis-plus.global-config.db-column-underline=true + +######################### swagger ######################### +swagger.apiGroupName=smartAdmin +swagger.title=smartAdmin +swagger.description=smartAdmin +swagger.version=1.0 +swagger.serviceUrl=http://localhost:10086/smart-admin-api +swagger.packAge=com.gangquan360.smartadmin.module + +######################### jwt ######################### +jwt.key=smart-admin-jwt-key + +########################## smart reload ######################### +smart-reload.thread-count=1 +smart-reload.time-interval=5 + +######################### cros ######################### +access-control-allow-origin=* + +######################### heart beat ######################### +heart-beat.delayHandlerTime=60000 +heart-beat.intervalTime=180000 + +######################### quartz ############################# +#\u8C03\u5EA6\u6807\u8BC6\u540D \u96C6\u7FA4\u4E2D\u6BCF\u4E00\u4E2A\u5B9E\u4F8B\u90FD\u5FC5\u987B\u4F7F\u7528\u76F8\u540C\u7684\u540D\u79F0 +spring.quartz.properties.org.quartz.scheduler.instanceName=devClusteredScheduler +spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO +#\u8FDC\u7A0B\u7BA1\u7406\u76F8\u5173\u7684\u914D\u7F6E,\u5168\u90E8\u5173\u95ED +spring.quartz.properties.org.quartz.scheduler.rmi.export=false +spring.quartz.properties.org.quartz.scheduler.rmi.proxy=false +#\u8DF3\u8FC7quartz\u7248\u672C\u68C0\u67E5 +spring.quartz.properties.org.quartz.scheduler.skipUpdateCheck=true +#\u6570\u636E\u4FDD\u5B58\u65B9\u5F0F\u4E3A\u6301\u4E45\u5316 +spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate +spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_ +spring.quartz.properties.org.quartz.jobStore.isClustered=true +#\u8C03\u5EA6\u5B9E\u4F8B\u5931\u6548\u7684\u68C0\u67E5\u65F6\u95F4\u95F4\u9694 +spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=10000 +spring.quartz.properties.org.quartz.jobStore.useProperties=false +#\u8C03\u5EA6\u7EBF\u7A0B +spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool +spring.quartz.properties.org.quartz.threadPool.threadCount=2 +spring.quartz.properties.org.quartz.threadPool.threadPriority=5 +spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true +spring.quartz.properties.org.quartz.threadPool.threadNamePrefix=quartz +spring.quartz.job-store-type=jdbc +#ALWAYS,EMBEDDED,NEVER +spring.quartz.jdbc.initialize-schema=NEVER +spring.quartz.jdbc.schema=classpath:sql/quartz_mysql_2.3.0.sql diff --git a/java/smart-admin-api/src/main/resources/pre/log4j2.xml b/java/smart-admin-api/src/main/resources/pre/log4j2.xml new file mode 100644 index 00000000..f1942baf --- /dev/null +++ b/java/smart-admin-api/src/main/resources/pre/log4j2.xml @@ -0,0 +1,97 @@ + + + + + /home/logs/smart-admin/dev/logs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/prod/application.properties b/java/smart-admin-api/src/main/resources/prod/application.properties new file mode 100644 index 00000000..e42e3f94 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/prod/application.properties @@ -0,0 +1,122 @@ +######################### server ################### +server.servlet.context-path=/smart-admin-api +server.port=10088 +spring.profiles.active=@profiles.active@ + +######################### tomcat ################### +server.tomcat.basedir=/home/logs/smart-admin/tomcat-logs +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.pattern=%t %{X-Forwarded-For}i %a "%r" %s %D (%D ms) + +######################### jackson ######################### +spring.jackson.serialization.write-enums-using-to-string=true +spring.jackson.deserialization.read-enums-using-to-string=true +spring.jackson.deserialization.fail-on-unknown-properties=false + +spring.jackson.default-property-inclusion=always +spring.jackson.date-format=yyyy-MM-dd HH:mm:ss +spring.jackson.time-zone=GMT+8 +spring.jackson.serialization.write-dates-as-timestamps=false + +######################### http file ######################### +spring.servlet.multipart.max-file-size=30MB +spring.servlet.multipart.max-request-size=30MB +file-upload-service.path=/home/upload/smart-admin-file +file-upload-service.geturl=http://smartadmin.gangquan360.com/demoAdmin/file/ + +######################### database ######################### +spring.datasource.url=jdbc:mysql://172.16.0.201:3306/smart-admin-prod?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true +spring.datasource.username=smart-admin +spring.datasource.password=Admin@123457 +spring.datasource.initial-size=2 +spring.datasource.min-idle=1 +spring.datasource.max-active=10 +spring.datasource.max-wait=60000 +spring.datasource.time-between-eviction-runs-millis=60000 +spring.datasource.min-evictable-edle-time-millis=300000 +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.filters=stat +spring.datasource.druid.username=druid +spring.datasource.druid.password=Gq123456 +spring.datasource.druid.login.enabled=false + +######################### redis ####################################### +spring.redis.database=13 +spring.redis.host=127.0.0.1 +spring.redis.jedis.pool.max-active=100 +spring.redis.jedis.pool.min-idle=5 +spring.redis.jedis.pool.max-idle=10 +spring.redis.jedis.pool.max-wait=30000ms +spring.redis.port=6379 +spring.redis.timeout=10000ms +spring.redis.password=Gq123456@ + +########################## rest http pool ######################### +#\u6700\u5927\u8FDE\u63A5\u6570 +http.pool.max-total=100 +#\u5355\u8DEF\u7531\u6700\u5927\u8FDE\u63A5\u6570 +http.pool.default-max-per-route=25 +#\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E(response)\u7684\u65F6\u95F4 +http.pool.socket-timeout=8000 +#\u8FDE\u63A5\u4E0A\u670D\u52A1\u5668(\u63E1\u624B\u6210\u529F)\u7684\u65F6\u95F4 +http.pool.connect-timeout=8000 +#\u4ECE\u8FDE\u63A5\u6C60\u4E2D\u83B7\u53D6\u8FDE\u63A5\u7684\u8D85\u65F6\u65F6\u95F4 +http.pool.connection-request-timeout=8000 + +######################### mybatis\u914D\u7F6E ######################### +mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl +# mybatis-plus \u5B57\u6BB5\u9A7C\u5CF0\u81EA\u52A8\u8F6C\u6362 +mybatis-plus.configuration.map-underscore-to-camel-case=true +mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml,/mapper/*/*Mapper.xml +mybatis-plus.typeAliasesPackage=com.gangquan360.smartadmin.*.*.domain.entity +mybatis-plus.global-config.refresh-mapper=true +mybatis-plus.global-config.db-column-underline=true + +######################### swagger ######################### +swagger.apiGroupName=smartAdmin +swagger.title=smartAdmin +swagger.description=smartAdmin +swagger.version=1.0 +swagger.serviceUrl=http://localhost:10086/smart-admin-api +swagger.packAge=com.gangquan360.smartadmin.module + +######################### jwt ######################### +jwt.key=smart-admin-jwt-key + +########################## smart reload ######################### +smart-reload.thread-count=2 +smart-reload.time-interval=20 +######################### cros ######################### +access-control-allow-origin=preview.smartadmin.1024lab.net +######################### heart beat ######################### +heart-beat.delayHandlerTime=60000 +heart-beat.intervalTime=180000 + +######################### quartz ############################# +#\u8C03\u5EA6\u6807\u8BC6\u540D \u96C6\u7FA4\u4E2D\u6BCF\u4E00\u4E2A\u5B9E\u4F8B\u90FD\u5FC5\u987B\u4F7F\u7528\u76F8\u540C\u7684\u540D\u79F0 +spring.quartz.properties.org.quartz.scheduler.instanceName=prodClusteredScheduler +spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO +#\u8FDC\u7A0B\u7BA1\u7406\u76F8\u5173\u7684\u914D\u7F6E,\u5168\u90E8\u5173\u95ED +spring.quartz.properties.org.quartz.scheduler.rmi.export=false +spring.quartz.properties.org.quartz.scheduler.rmi.proxy=false +#\u8DF3\u8FC7quartz\u7248\u672C\u68C0\u67E5 +spring.quartz.properties.org.quartz.scheduler.skipUpdateCheck=true +#\u6570\u636E\u4FDD\u5B58\u65B9\u5F0F\u4E3A\u6301\u4E45\u5316 +spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate +spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_ +spring.quartz.properties.org.quartz.jobStore.isClustered=true +#\u8C03\u5EA6\u5B9E\u4F8B\u5931\u6548\u7684\u68C0\u67E5\u65F6\u95F4\u95F4\u9694 +spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=10000 +spring.quartz.properties.org.quartz.jobStore.useProperties=false +#\u8C03\u5EA6\u7EBF\u7A0B +spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool +spring.quartz.properties.org.quartz.threadPool.threadCount=2 +spring.quartz.properties.org.quartz.threadPool.threadPriority=5 +spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true +spring.quartz.properties.org.quartz.threadPool.threadNamePrefix=quartz + +spring.quartz.job-store-type=jdbc +#ALWAYS,EMBEDDED,NEVER +spring.quartz.jdbc.initialize-schema=NEVER +spring.quartz.jdbc.schema=classpath:sql/quartz_mysql_2.3.0.sql diff --git a/java/smart-admin-api/src/main/resources/prod/log4j2.xml b/java/smart-admin-api/src/main/resources/prod/log4j2.xml new file mode 100644 index 00000000..4991f76e --- /dev/null +++ b/java/smart-admin-api/src/main/resources/prod/log4j2.xml @@ -0,0 +1,97 @@ + + + + + /home/logs/smart-admin + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/sit/application.properties b/java/smart-admin-api/src/main/resources/sit/application.properties new file mode 100644 index 00000000..ad34ca04 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/sit/application.properties @@ -0,0 +1,122 @@ +######################### server ################### +server.servlet.context-path=/smart-admin-api +server.port=10086 +spring.profiles.active=dev + +######################### tomcat ################### +server.tomcat.basedir=/home/logs/smartadmin/tomcat-logs +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.pattern=%t %{X-Forwarded-For}i %a "%r" %s %D (%D ms) + +######################### jackson ######################### +spring.jackson.serialization.write-enums-using-to-string=true +spring.jackson.deserialization.read-enums-using-to-string=true +spring.jackson.deserialization.fail-on-unknown-properties=false +spring.jackson.default-property-inclusion=always +spring.jackson.date-format=yyyy-MM-dd HH:mm:ss +spring.jackson.time-zone=GMT+8 +spring.jackson.serialization.write-dates-as-timestamps=false + +######################### http file ######################### +spring.servlet.multipart.max-file-size=30MB +spring.servlet.multipart.max-request-size=30MB +file-upload-service.path=/home/upload/ +file-upload-service.geturl=http://172.16.0.145/smartAdmin/file/ + +######################### database ######################### +spring.datasource.url=jdbc:mysql://127.0.0.1:3306/smart-admin-dev?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC +spring.datasource.username=erp +spring.datasource.password=listen1015 +spring.datasource.initial-size=2 +spring.datasource.min-idle=1 +spring.datasource.max-active=10 +spring.datasource.max-wait=60000 +spring.datasource.time-between-eviction-runs-millis=60000 +spring.datasource.min-evictable-edle-time-millis=300000 +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.filters=stat +spring.datasource.druid.username=druid +spring.datasource.druid.password=Gq123456 +spring.datasource.druid.login.enabled=false + +######################### redis ####################################### +spring.redis.database=13 +spring.redis.host=172.16.0.145 +spring.redis.jedis.pool.max-active=100 +spring.redis.jedis.pool.min-idle=5 +spring.redis.jedis.pool.max-idle=10 +spring.redis.jedis.pool.max-wait=30000ms +spring.redis.port=50000 +spring.redis.timeout=10000ms +spring.redis.password= + +########################## rest http pool ######################### +#\u6700\u5927\u8FDE\u63A5\u6570 +http.pool.max-total=100 +#\u5355\u8DEF\u7531\u6700\u5927\u8FDE\u63A5\u6570 +http.pool.default-max-per-route=25 +#\u670D\u52A1\u5668\u8FD4\u56DE\u6570\u636E(response)\u7684\u65F6\u95F4 +http.pool.socket-timeout=8000 +#\u8FDE\u63A5\u4E0A\u670D\u52A1\u5668(\u63E1\u624B\u6210\u529F)\u7684\u65F6\u95F4 +http.pool.connect-timeout=8000 +#\u4ECE\u8FDE\u63A5\u6C60\u4E2D\u83B7\u53D6\u8FDE\u63A5\u7684\u8D85\u65F6\u65F6\u95F4 +http.pool.connection-request-timeout=8000 + +######################### mybatis\u914D\u7F6E ######################### +mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl +# mybatis-plus \u5B57\u6BB5\u9A7C\u5CF0\u81EA\u52A8\u8F6C\u6362 +mybatis-plus.configuration.map-underscore-to-camel-case=true +mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml,/mapper/*/*Mapper.xml +mybatis-plus.typeAliasesPackage=com.gangquan360.smartadmin.*.*.domain.entity +mybatis-plus.global-config.refresh-mapper=true +mybatis-plus.global-config.db-column-underline=true + +######################### swagger ######################### +swagger.apiGroupName=smartAdmin +swagger.title=smartAdmin +swagger.description=smartAdmin +swagger.version=1.0 +swagger.serviceUrl=http://localhost:10086/smart-admin-api +swagger.packAge=com.gangquan360.smartadmin.module + +######################### jwt ######################### +jwt.key=smart-admin-jwt-key + +########################## smart reload ######################### +smart-reload.thread-count=1 +smart-reload.time-interval=5 + +######################### cros ######################### +access-control-allow-origin=* + +######################### heart beat ######################### +heart-beat.delayHandlerTime=60000 +heart-beat.intervalTime=180000 + +######################### quartz ############################# +#\u8C03\u5EA6\u6807\u8BC6\u540D \u96C6\u7FA4\u4E2D\u6BCF\u4E00\u4E2A\u5B9E\u4F8B\u90FD\u5FC5\u987B\u4F7F\u7528\u76F8\u540C\u7684\u540D\u79F0 +spring.quartz.properties.org.quartz.scheduler.instanceName=devClusteredScheduler +spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO +#\u8FDC\u7A0B\u7BA1\u7406\u76F8\u5173\u7684\u914D\u7F6E,\u5168\u90E8\u5173\u95ED +spring.quartz.properties.org.quartz.scheduler.rmi.export=false +spring.quartz.properties.org.quartz.scheduler.rmi.proxy=false +#\u8DF3\u8FC7quartz\u7248\u672C\u68C0\u67E5 +spring.quartz.properties.org.quartz.scheduler.skipUpdateCheck=true +#\u6570\u636E\u4FDD\u5B58\u65B9\u5F0F\u4E3A\u6301\u4E45\u5316 +spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate +spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_ +spring.quartz.properties.org.quartz.jobStore.isClustered=true +#\u8C03\u5EA6\u5B9E\u4F8B\u5931\u6548\u7684\u68C0\u67E5\u65F6\u95F4\u95F4\u9694 +spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=10000 +spring.quartz.properties.org.quartz.jobStore.useProperties=false +#\u8C03\u5EA6\u7EBF\u7A0B +spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool +spring.quartz.properties.org.quartz.threadPool.threadCount=2 +spring.quartz.properties.org.quartz.threadPool.threadPriority=5 +spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true +spring.quartz.properties.org.quartz.threadPool.threadNamePrefix=quartz +spring.quartz.job-store-type=jdbc +#ALWAYS,EMBEDDED,NEVER +spring.quartz.jdbc.initialize-schema=NEVER +spring.quartz.jdbc.schema=classpath:sql/quartz_mysql_2.3.0.sql diff --git a/java/smart-admin-api/src/main/resources/sit/log4j2.xml b/java/smart-admin-api/src/main/resources/sit/log4j2.xml new file mode 100644 index 00000000..ac533c99 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/sit/log4j2.xml @@ -0,0 +1,97 @@ + + + + + /home/logs/smart-admin/dev/logs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/sql/quartz_mysql_2.3.0.sql b/java/smart-admin-api/src/main/resources/sql/quartz_mysql_2.3.0.sql new file mode 100644 index 00000000..8968c23f --- /dev/null +++ b/java/smart-admin-api/src/main/resources/sql/quartz_mysql_2.3.0.sql @@ -0,0 +1,179 @@ +# +# In your Quartz properties file, you'll need to set +# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate +# +# +# By: Ron Cordell - roncordell +# I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM. + +DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; +DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; +DROP TABLE IF EXISTS QRTZ_LOCKS; +DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; +DROP TABLE IF EXISTS QRTZ_CALENDARS; + +CREATE TABLE QRTZ_JOB_DETAILS( +SCHED_NAME VARCHAR(120) NOT NULL, +JOB_NAME VARCHAR(190) NOT NULL, +JOB_GROUP VARCHAR(190) NOT NULL, +DESCRIPTION VARCHAR(250) NULL, +JOB_CLASS_NAME VARCHAR(250) NOT NULL, +IS_DURABLE VARCHAR(1) NOT NULL, +IS_NONCONCURRENT VARCHAR(1) NOT NULL, +IS_UPDATE_DATA VARCHAR(1) NOT NULL, +REQUESTS_RECOVERY VARCHAR(1) NOT NULL, +JOB_DATA BLOB NULL, +PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_TRIGGERS ( +SCHED_NAME VARCHAR(120) NOT NULL, +TRIGGER_NAME VARCHAR(190) NOT NULL, +TRIGGER_GROUP VARCHAR(190) NOT NULL, +JOB_NAME VARCHAR(190) NOT NULL, +JOB_GROUP VARCHAR(190) NOT NULL, +DESCRIPTION VARCHAR(250) NULL, +NEXT_FIRE_TIME BIGINT(13) NULL, +PREV_FIRE_TIME BIGINT(13) NULL, +PRIORITY INTEGER NULL, +TRIGGER_STATE VARCHAR(16) NOT NULL, +TRIGGER_TYPE VARCHAR(8) NOT NULL, +START_TIME BIGINT(13) NOT NULL, +END_TIME BIGINT(13) NULL, +CALENDAR_NAME VARCHAR(190) NULL, +MISFIRE_INSTR SMALLINT(2) NULL, +JOB_DATA BLOB NULL, +PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), +FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) +REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_SIMPLE_TRIGGERS ( +SCHED_NAME VARCHAR(120) NOT NULL, +TRIGGER_NAME VARCHAR(190) NOT NULL, +TRIGGER_GROUP VARCHAR(190) NOT NULL, +REPEAT_COUNT BIGINT(7) NOT NULL, +REPEAT_INTERVAL BIGINT(12) NOT NULL, +TIMES_TRIGGERED BIGINT(10) NOT NULL, +PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), +FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_CRON_TRIGGERS ( +SCHED_NAME VARCHAR(120) NOT NULL, +TRIGGER_NAME VARCHAR(190) NOT NULL, +TRIGGER_GROUP VARCHAR(190) NOT NULL, +CRON_EXPRESSION VARCHAR(120) NOT NULL, +TIME_ZONE_ID VARCHAR(80), +PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), +FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_SIMPROP_TRIGGERS + ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(190) NOT NULL, + TRIGGER_GROUP VARCHAR(190) NOT NULL, + STR_PROP_1 VARCHAR(512) NULL, + STR_PROP_2 VARCHAR(512) NULL, + STR_PROP_3 VARCHAR(512) NULL, + INT_PROP_1 INT NULL, + INT_PROP_2 INT NULL, + LONG_PROP_1 BIGINT NULL, + LONG_PROP_2 BIGINT NULL, + DEC_PROP_1 NUMERIC(13,4) NULL, + DEC_PROP_2 NUMERIC(13,4) NULL, + BOOL_PROP_1 VARCHAR(1) NULL, + BOOL_PROP_2 VARCHAR(1) NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_BLOB_TRIGGERS ( +SCHED_NAME VARCHAR(120) NOT NULL, +TRIGGER_NAME VARCHAR(190) NOT NULL, +TRIGGER_GROUP VARCHAR(190) NOT NULL, +BLOB_DATA BLOB NULL, +PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), +INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP), +FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_CALENDARS ( +SCHED_NAME VARCHAR(120) NOT NULL, +CALENDAR_NAME VARCHAR(190) NOT NULL, +CALENDAR BLOB NOT NULL, +PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS ( +SCHED_NAME VARCHAR(120) NOT NULL, +TRIGGER_GROUP VARCHAR(190) NOT NULL, +PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_FIRED_TRIGGERS ( +SCHED_NAME VARCHAR(120) NOT NULL, +ENTRY_ID VARCHAR(95) NOT NULL, +TRIGGER_NAME VARCHAR(190) NOT NULL, +TRIGGER_GROUP VARCHAR(190) NOT NULL, +INSTANCE_NAME VARCHAR(190) NOT NULL, +FIRED_TIME BIGINT(13) NOT NULL, +SCHED_TIME BIGINT(13) NOT NULL, +PRIORITY INTEGER NOT NULL, +STATE VARCHAR(16) NOT NULL, +JOB_NAME VARCHAR(190) NULL, +JOB_GROUP VARCHAR(190) NULL, +IS_NONCONCURRENT VARCHAR(1) NULL, +REQUESTS_RECOVERY VARCHAR(1) NULL, +PRIMARY KEY (SCHED_NAME,ENTRY_ID)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_SCHEDULER_STATE ( +SCHED_NAME VARCHAR(120) NOT NULL, +INSTANCE_NAME VARCHAR(190) NOT NULL, +LAST_CHECKIN_TIME BIGINT(13) NOT NULL, +CHECKIN_INTERVAL BIGINT(13) NOT NULL, +PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)) +ENGINE=InnoDB; + +CREATE TABLE QRTZ_LOCKS ( +SCHED_NAME VARCHAR(120) NOT NULL, +LOCK_NAME VARCHAR(40) NOT NULL, +PRIMARY KEY (SCHED_NAME,LOCK_NAME)) +ENGINE=InnoDB; + +CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY); +CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP); + +CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); +CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP); +CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME); +CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); +CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); + +CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME); +CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); +CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); +CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP); +CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); +CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); + +commit; diff --git a/java/smart-admin-api/src/main/resources/sql/smart-admin.sql b/java/smart-admin-api/src/main/resources/sql/smart-admin.sql new file mode 100644 index 00000000..664c3bea --- /dev/null +++ b/java/smart-admin-api/src/main/resources/sql/smart-admin.sql @@ -0,0 +1,1497 @@ +-- -------------------------------------------------------- +-- 主机: 127.0.0.1 +-- 服务器版本: 5.7.20-log - MySQL Community Server (GPL) +-- 服务器操作系统: Win64 +-- HeidiSQL 版本: 10.2.0.5670 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8 */; +/*!50503 SET NAMES utf8mb4 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + + +-- 导出 smart-admin-dev 的数据库结构 +DROP DATABASE IF EXISTS `smart-admin-dev`; +CREATE DATABASE IF NOT EXISTS `smart-admin-dev` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */; +USE `smart-admin-dev`; + +-- 导出 表 smart-admin-dev.t_department 结构 +DROP TABLE IF EXISTS `t_department`; +CREATE TABLE IF NOT EXISTS `t_department` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '部门主键id', + `name` varchar(50) NOT NULL COMMENT '部门名称', + `short_name` varchar(50) DEFAULT NULL COMMENT '部门简称', + `manager_id` int(10) unsigned DEFAULT NULL COMMENT '部门负责人id', + `parent_id` int(10) unsigned DEFAULT NULL COMMENT '部门的父级id', + `sort` int(10) NOT NULL COMMENT '部门排序', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `parent_id` (`parent_id`) +) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COMMENT='部门表'; + +-- 正在导出表 smart-admin-dev.t_department 的数据:~20 rows (大约) +DELETE FROM `t_department`; +/*!40000 ALTER TABLE `t_department` DISABLE KEYS */; +INSERT INTO `t_department` (`id`, `name`, `short_name`, `manager_id`, `parent_id`, `sort`, `update_time`, `create_time`) VALUES + (1, '1024创新实验室', 'ZWGWL', 16, 0, 1, '2019-04-03 10:41:25', '2019-04-03 10:41:25'), + (2, '二级部门-2', NULL, 15, 1, 17, '2019-04-15 16:45:10', '2019-04-15 16:45:10'), + (4, '二级部门-1', '管理', 14, 1, 20, '2019-04-17 16:14:55', '2019-04-17 16:14:55'), + (8, '三级部门-1', NULL, NULL, 4, 8, '2019-04-25 12:25:52', '2019-04-25 12:25:52'), + (9, '四级部门-1', NULL, NULL, 8, 9, '2019-04-25 12:26:36', '2019-04-25 12:26:36'), + (10, '五级部门-1', NULL, NULL, 9, 10, '2019-04-25 12:26:49', '2019-04-25 12:26:49'), + (11, '六级部门-1', NULL, NULL, 10, 11, '2019-04-25 12:26:59', '2019-04-25 12:26:59'), + (12, '七级部门-1', NULL, NULL, 11, 12, '2019-04-25 12:27:18', '2019-04-25 12:27:18'), + (13, '八级部门-1', NULL, NULL, 12, 13, '2019-04-25 12:27:34', '2019-04-25 12:27:34'), + (14, '九级部门-1', NULL, NULL, 13, 14, '2019-04-25 12:27:47', '2019-04-25 12:27:47'), + (15, '十级部门-1', NULL, NULL, 14, 15, '2019-04-25 12:28:16', '2019-04-25 12:28:16'), + (16, '十一级部门部门部部门门嘻嘻哈哈-1', NULL, 13, 15, 16, '2019-04-25 14:56:40', '2019-04-25 14:56:40'), + (17, '信息中心', NULL, 16, 1, 4, '2019-04-26 11:53:50', '2019-04-26 11:53:50'), + (18, '测试部门', NULL, 16, 17, 18, '2019-04-26 11:54:06', '2019-04-26 11:54:06'), + (19, '张娇测试', NULL, NULL, 2, 22, '2019-04-26 14:36:18', '2019-04-26 14:36:18'), + (20, '子部门', NULL, NULL, 2, 23, '2019-04-26 14:36:28', '2019-04-26 14:36:28'), + (22, '张静如', NULL, 16, 1, 2, '2019-04-28 14:21:44', '2019-04-28 14:21:44'), + (23, '张静如2', NULL, 22, 4, 19, '2019-04-28 14:22:48', '2019-04-28 14:22:48'), + (24, '测试', NULL, 18, 23, 24, '2019-04-29 10:12:42', '2019-04-29 10:12:42'), + (25, '测试', NULL, 18, 23, 25, '2019-04-29 10:12:42', '2019-04-29 10:12:42'); +/*!40000 ALTER TABLE `t_department` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_email 结构 +DROP TABLE IF EXISTS `t_email`; +CREATE TABLE IF NOT EXISTS `t_email` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `title` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '标题', + `to_emails` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收件人', + `send_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '发送状态 0未发送 1已发送', + `content` longtext COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '邮件内容', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=87 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 正在导出表 smart-admin-dev.t_email 的数据:~56 rows (大约) +DELETE FROM `t_email`; +/*!40000 ALTER TABLE `t_email` DISABLE KEYS */; +INSERT INTO `t_email` (`id`, `title`, `to_emails`, `send_status`, `content`, `create_time`, `update_time`) VALUES + (20, '新增测试12345', '新增测试@11.com', 1, '

这是内容

', '2019-08-30 15:35:12', '2019-08-30 15:35:12'), + (21, 'b', 'asdf@33.com', 1, '

c

', '2019-09-06 14:25:33', '2019-09-06 14:25:33'), + (23, 'string', 'string', 0, 'string', '2019-09-06 06:55:01', '2019-09-06 06:55:01'), + (24, 'string', 'string', 0, 'string', '2019-09-06 06:55:01', '2019-09-06 06:55:01'), + (26, 'string', 'string', 0, 'string', '2019-09-06 07:01:32', '2019-09-06 07:01:32'), + (27, 'string', 'string', 0, 'string', '2019-09-06 07:01:32', '2019-09-06 07:01:32'), + (37, 'ewqwe', '适者生存@22.cc', 1, '

qweqwe

', '2019-11-09 10:00:46', '2019-11-09 10:00:46'), + (38, 'ewqwe', '适者生存@22.cc', 1, '

qweqwe

', '2019-11-09 10:00:49', '2019-11-09 10:00:49'), + (39, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:04:54', '2019-11-09 10:04:54'), + (40, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:04:57', '2019-11-09 10:04:57'), + (41, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:04:57', '2019-11-09 10:04:57'), + (42, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:04:58', '2019-11-09 10:04:58'), + (43, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:04:59', '2019-11-09 10:04:59'), + (44, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:04:59', '2019-11-09 10:04:59'), + (45, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:05:16', '2019-11-09 10:05:16'), + (46, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:06:29', '2019-11-09 10:06:29'), + (47, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:07:02', '2019-11-09 10:07:02'), + (48, 'dsfds', 'dsfsd@qq.ccc', 1, '

fsdfs

', '2019-11-09 10:07:16', '2019-11-09 10:07:16'), + (49, '2342', '11@ss.cc', 1, '

234234

', '2019-11-09 10:08:13', '2019-11-09 10:08:13'), + (50, '2342', '11@ss.cc', 1, '

234234

', '2019-11-09 10:08:30', '2019-11-09 10:08:30'), + (51, '2342', '11@ss.cc', 1, '

234234

', '2019-11-09 10:08:50', '2019-11-09 10:08:50'), + (52, '2342', '11@ss.cc', 1, '

234234

', '2019-11-09 10:09:09', '2019-11-09 10:09:09'), + (53, '2342', '11@ss.cc', 1, '

234234

', '2019-11-09 10:09:31', '2019-11-09 10:09:31'), + (54, '2342', '11@ss.cc', 1, '

234234

', '2019-11-09 10:12:24', '2019-11-09 10:12:24'), + (55, '2342', '11@ss.cc', 1, '

234234

', '2019-11-09 10:13:13', '2019-11-09 10:13:13'), + (56, 'asdasd', '3423@aqq.cc', 0, '

asdasd

', '2019-11-09 10:20:42', '2019-11-09 10:20:42'), + (57, 'asdasd', '3423@aqq.cc', 0, '

asdasd

', '2019-11-09 10:20:52', '2019-11-09 10:20:52'), + (58, 'asdasd', '3423@aqq.cc', 0, '

asdasd

', '2019-11-09 10:21:16', '2019-11-09 10:21:16'), + (59, 'asdasd', '3423@aqq.cc', 0, '

asdasd

', '2019-11-09 10:21:24', '2019-11-09 10:21:24'), + (60, 'asdasd', '3423@aqq.cc', 0, '

asdasd

', '2019-11-09 10:21:30', '2019-11-09 10:21:30'), + (61, 'asdasd', '3423@aqq.cc', 0, '

asdasd

', '2019-11-09 10:21:53', '2019-11-09 10:21:53'), + (62, 'a21312', '23423@qq.cc', 0, '

asdasdas

', '2019-11-09 10:23:40', '2019-11-09 10:23:40'), + (63, '11', '1234@qq.com', 0, '

23

', '2019-11-15 15:35:12', '2019-11-15 15:35:12'), + (64, '11', '1234@qq.com', 0, '

23

', '2019-11-15 15:35:15', '2019-11-15 15:35:15'), + (65, '11', '1234@qq.com', 0, '

23

', '2019-11-15 15:35:16', '2019-11-15 15:35:16'), + (66, 'eeee', '1234@qq.com', 0, '

    eee2233

', '2019-11-15 17:00:00', '2019-11-15 17:00:00'), + (67, 'eeee', '1234@qq.com', 0, '

    eee2233

', '2019-11-15 17:00:03', '2019-11-15 17:00:03'), + (68, 'eeee', '1234@qq.com', 0, '

    eee2233

', '2019-11-15 17:00:04', '2019-11-15 17:00:04'), + (69, '22223', '1017146812@qq.com', 0, '

    e34233

', '2019-11-15 17:00:33', '2019-11-15 17:00:33'), + (70, '22223', '1017146812@qq.com', 0, '

    e34233

', '2019-11-15 17:00:34', '2019-11-15 17:00:34'), + (71, '22223', '1017146812@qq.com', 0, '

    e34233

', '2019-11-15 17:00:34', '2019-11-15 17:00:34'), + (72, '22223', '12232', 0, '

    e34233

', '2019-11-15 17:00:49', '2019-11-15 17:00:49'), + (73, '22223', '12232@qq.com', 0, '

    e34233

', '2019-11-15 17:00:56', '2019-11-15 17:00:56'), + (74, 'dsasdasd', 'asdas@qq.com', 0, '

asdasd

', '2019-11-16 08:51:44', '2019-11-16 08:51:44'), + (75, 'dsasdasd', 'asdas@qq.com', 0, '

asdasd

', '2019-11-16 09:05:10', '2019-11-16 09:05:10'), + (76, 'dsasdasd', 'asdas@qq.com', 0, '

asdasd

', '2019-11-16 09:05:14', '2019-11-16 09:05:14'), + (77, 'dsasdasd', 'asdas@qq.com', 0, '

asdasd

', '2019-11-16 09:06:34', '2019-11-16 09:06:34'), + (78, 'dsasdasd', 'asdas@qq.com', 0, '

asdasd

', '2019-11-16 09:07:09', '2019-11-16 09:07:09'), + (79, 'dsasdasd', 'asdas@qq.com', 0, '

asdasd

', '2019-11-16 09:07:30', '2019-11-16 09:07:30'), + (80, 'dsasdasd', 'asdas@qq.com', 0, '

asdasd

', '2019-11-16 09:07:32', '2019-11-16 09:07:32'), + (81, 'dsasdasd', 'asdas@qq.com', 0, '

asdasd

', '2019-11-16 09:08:29', '2019-11-16 09:08:29'), + (82, 'sdfs', 'ss@ss.cc', 0, '

dsdsf

', '2019-11-16 09:08:46', '2019-11-16 09:08:46'), + (83, 'asdasd', 'asd@qq.vv', 0, '

asdas

', '2019-11-16 09:09:18', '2019-11-16 09:09:18'), + (84, 'asdasd', 'asd@qq.vv', 0, '

asdas

', '2019-11-16 09:09:42', '2019-11-16 09:09:42'), + (85, 'asdasd', 'asd@qq.vv', 0, '

asdas

', '2019-11-16 09:09:46', '2019-11-16 09:09:46'), + (86, 'dasdad', 'dasda@ss.cc', 1, '

dasasdas

', '2019-11-16 09:10:05', '2019-11-16 09:10:05'); +/*!40000 ALTER TABLE `t_email` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_employee 结构 +DROP TABLE IF EXISTS `t_employee`; +CREATE TABLE IF NOT EXISTS `t_employee` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', + `login_name` varchar(30) CHARACTER SET utf8 NOT NULL COMMENT '登录帐号', + `login_pwd` varchar(50) CHARACTER SET utf8 NOT NULL COMMENT '登录密码', + `actual_name` varchar(30) CHARACTER SET utf8 NOT NULL COMMENT '员工名称', + `nick_name` varchar(30) DEFAULT '' COMMENT '别名', + `phone` varchar(15) CHARACTER SET utf8 DEFAULT NULL COMMENT '手机号码', + `id_card` varchar(18) CHARACTER SET utf8 DEFAULT NULL COMMENT '身份证', + `birthday` date DEFAULT NULL COMMENT '出生日期', + `email` varchar(50) DEFAULT NULL COMMENT '邮箱', + `department_id` int(10) unsigned NOT NULL COMMENT '部门id', + `is_leave` int(10) NOT NULL DEFAULT '0' COMMENT '是否离职1是', + `is_disabled` int(10) NOT NULL DEFAULT '0' COMMENT '是否被禁用 0否1是', + `remark` varchar(200) DEFAULT NULL COMMENT '备注', + `create_user` int(10) unsigned NOT NULL COMMENT '创建者id', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `is_delete` int(10) NOT NULL DEFAULT '0' COMMENT '是否删除0否 1是', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8mb4 COMMENT='员工表'; + +-- 正在导出表 smart-admin-dev.t_employee 的数据:~28 rows (大约) +DELETE FROM `t_employee`; +/*!40000 ALTER TABLE `t_employee` DISABLE KEYS */; +INSERT INTO `t_employee` (`id`, `login_name`, `login_pwd`, `actual_name`, `nick_name`, `phone`, `id_card`, `birthday`, `email`, `department_id`, `is_leave`, `is_disabled`, `remark`, `create_user`, `update_time`, `create_time`, `is_delete`) VALUES + (1, 'sa', 'c655798e4648c540812a1b8f48759af7', '管理员', '15515515515', '13112312131', '410306199202020020', '1992-02-02', NULL, 1, 0, 0, NULL, 0, '2019-04-27 09:56:17', '2018-05-11 09:38:54', 0), + (11, 'role1', 'c655798e4648c540812a1b8f48759af7', '角色测试1', '', '18123245230', '', '1970-01-01', '', 4, 0, 0, NULL, 1, '2019-04-27 09:56:17', '2019-04-25 12:30:22', 0), + (12, 'role2', 'c655798e4648c540812a1b8f48759af7', '角色测试2', '', '18121451241', '', NULL, '', 4, 0, 0, NULL, 1, '2019-08-01 10:04:38', '2019-04-25 12:31:11', 0), + (13, 'lihaifan', 'c655798e4648c540812a1b8f48759af7', 'lihaifan', '', '18399485774', '', NULL, '', 1, 0, 0, NULL, 1, '2019-04-27 09:56:17', '2019-04-25 13:50:44', 0), + (14, 'lipeng', 'c655798e4648c540812a1b8f48759af7', '李鹏1', '', '13937988294', '', NULL, '', 2, 0, 0, NULL, 1, '2019-04-27 09:56:17', '2019-04-25 14:34:47', 0), + (15, 'huangwenli', 'c655798e4648c540812a1b8f48759af7', '黄文丽', '', '15515515515', '', NULL, '', 16, 0, 0, NULL, 1, '2019-04-27 09:56:17', '2019-04-26 10:05:05', 0), + (16, 'huangwenli1', 'c655798e4648c540812a1b8f48759af7', '黄文丽', '', '15515515515', '', NULL, '', 15, 0, 0, NULL, 1, '2019-04-27 14:04:19', '2019-04-26 10:25:04', 0), + (17, 'zhangjiao', 'c655798e4648c540812a1b8f48759af7', '张娇', '阿娇', '15670390391', '410305199102020020', '1991-02-02', '86484@qq.com', 19, 0, 0, NULL, 1, '2019-08-05 16:33:57', '2019-04-26 14:37:23', 0), + (18, 'zhangjiao1', 'c655798e4648c540812a1b8f48759af7', '张娇1', '', '15670390391', '', '2019-04-18', '6666@qq.com', 20, 0, 0, NULL, 1, '2019-08-05 16:33:57', '2019-04-26 14:45:55', 0), + (19, 'zhenxiaocang', 'c655798e4648c540812a1b8f48759af7', '珍小藏', '', '15670390391', '', NULL, '', 19, 0, 1, NULL, 1, '2019-09-09 08:34:35', '2019-04-26 14:46:57', 0), + (20, 'matengfei', 'c655798e4648c540812a1b8f48759af7', '马腾飞', '', '15670390393', '', NULL, '', 19, 0, 0, NULL, 1, '2019-08-05 16:33:57', '2019-04-26 14:47:24', 0), + (21, 'ceshi123', 'c655798e4648c540812a1b8f48759af7', '测试人员', '', '18829938477', '', NULL, '', 1, 0, 1, NULL, 13, '2019-04-27 09:56:17', '2019-04-27 09:38:07', 1), + (22, 'zhangjingru', 'c655798e4648c540812a1b8f48759af7', '张静如', '', '15600000000', '', NULL, '', 1, 0, 0, NULL, 1, '2019-09-04 09:06:47', '2019-04-28 14:05:03', 0), + (23, 'sdfsdfdsfsdfdsfdsf', 'c655798e4648c540812a1b8f48759af7', 'werewr', '', '15698585858', '', NULL, '', 19, 0, 0, NULL, 1, '2019-09-05 16:13:03', '2019-04-28 16:26:27', 0), + (25, 'shq2019', 'c655798e4648c540812a1b8f48759af7', 'shq', 'shq', '18798801298', '410281199309024040', '1993-09-02', '', 17, 0, 0, NULL, 1, '2019-08-05 16:33:57', '2019-05-05 09:13:41', 0), + (26, 'zhangjiao666', 'c655798e4648c540812a1b8f48759af7', 'tom我是五个字12', '', '15612345678', '', NULL, '', 18, 0, 0, NULL, 1, '2019-08-05 16:33:57', '2019-05-05 15:34:10', 0), + (28, 'dfsfgds', 'c655798e4648c540812a1b8f48759af7', 'fds', '', '15854127845', '', NULL, '', 22, 0, 1, NULL, 1, '2019-09-06 08:58:40', '2019-05-06 10:36:57', 0), + (29, 'abcabc', 'c655798e4648c540812a1b8f48759af7', 'abccba', 'aaabac', '13311112222', '', NULL, '', 17, 0, 0, NULL, 1, '2019-08-05 16:33:57', '2019-07-10 17:00:58', 0), + (30, 'gengweigang', 'c655798e4648c540812a1b8f48759af7', '耿为刚', 'geng', '15038588418', '', NULL, '', 17, 0, 0, NULL, 1, '2019-08-08 14:35:51', '2019-08-08 14:35:51', 0), + (31, 'gengweigang1', 'c655798e4648c540812a1b8f48759af7', '耿为刚1', '这是别名', '15038588418', '410322193312123232', '1933-12-12', '32@qq.com', 18, 0, 0, NULL, 30, '2019-08-23 09:27:22', '2019-08-23 09:25:50', 0), + (32, 'ceshi123', 'c655798e4648c540812a1b8f48759af7', '测试', '测试', '15670702651', '', NULL, '', 17, 0, 0, NULL, 1, '2019-09-04 09:05:48', '2019-09-03 11:48:04', 0), + (33, 'ceshi321', 'c655798e4648c540812a1b8f48759af7', '测试', '测试', '15670702651', '', NULL, '', 17, 0, 1, NULL, 1, '2019-09-03 15:51:16', '2019-09-03 11:49:17', 0), + (34, 'ceshi123321', 'c655798e4648c540812a1b8f48759af7', '123', '', '15600000000', '', NULL, '', 22, 0, 1, NULL, 1, '2019-09-06 08:58:37', '2019-09-04 09:13:54', 0), + (35, 'guoqingfeng', 'c655798e4648c540812a1b8f48759af7', '郭青枫', '', '15670702651', '', NULL, '', 18, 0, 0, NULL, 1, '2019-09-04 15:09:00', '2019-09-04 15:09:00', 0), + (36, 'li327263458', 'c655798e4648c540812a1b8f48759af7', 'lipeng', '', '13937988294', '', NULL, '', 17, 0, 0, NULL, 1, '2019-09-09 17:01:39', '2019-09-09 17:01:39', 0), + (37, 'test123', 'c655798e4648c540812a1b8f48759af7', 'test', '', '13211110201', '', NULL, '', 18, 0, 1, NULL, 1, '2019-11-14 16:08:08', '2019-11-08 09:32:39', 0), + (38, 'tiantian', 'c655798e4648c540812a1b8f48759af7', '天天管理员', '', '13574502368', '', NULL, '', 17, 0, 0, NULL, 1, '2019-11-14 02:08:08', '2019-11-08 11:09:46', 0), + (39, 'wang13211111', 'c655798e4648c540812a1b8f48759af7', 'ceshi111', 'dddd', '13244553212', '', NULL, '', 25, 0, 0, NULL, 38, '2019-11-15 17:14:34', '2019-11-15 17:03:04', 0); +/*!40000 ALTER TABLE `t_employee` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_file 结构 +DROP TABLE IF EXISTS `t_file`; +CREATE TABLE IF NOT EXISTS `t_file` ( + `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `module_id` varchar(50) NOT NULL COMMENT '相关业务id', + `module_type` varchar(50) NOT NULL COMMENT '相关业务类型', + `file_name` varchar(255) DEFAULT NULL COMMENT '文件名称', + `file_size` varchar(255) DEFAULT NULL COMMENT '文件大小', + `file_type` varchar(50) DEFAULT NULL COMMENT '文件类型,程序中枚举控制,文件类型:如身份证正面,三证合一等等', + `file_path` varchar(255) NOT NULL COMMENT '文件key,用于文件下载', + `file_location_type` int(10) NOT NULL COMMENT '文件位置类型', + `creater_user` int(10) NOT NULL COMMENT '创建人,即上传人', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '上次更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `module_id_module_type` (`module_id`,`module_type`) USING BTREE, + KEY `module_type` (`module_type`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + +-- 正在导出表 smart-admin-dev.t_file 的数据:~23 rows (大约) +DELETE FROM `t_file`; +/*!40000 ALTER TABLE `t_file` DISABLE KEYS */; +INSERT INTO `t_file` (`id`, `module_id`, `module_type`, `file_name`, `file_size`, `file_type`, `file_path`, `file_location_type`, `creater_user`, `update_time`, `create_time`) VALUES + (1, '1', '1', '阿里云1.jpg', NULL, NULL, 'backUser/config/d1788b717be24f14ba526f25397b936f', 2, 1, NULL, '2019-07-05 10:38:15'), + (2, '2', '1', '1.jpg', NULL, NULL, 'backUser/config/8895ec770c4e4e558c6d9b54eb00dffc', 2, 1, '2019-07-18 09:20:59', '2019-07-18 09:20:25'), + (3, '3', '1', '随笔.txt', NULL, NULL, 'backUser/config/f5cbc4c9a56f4fa7ad0ba58b0aa5d169', 2, 1, NULL, '2019-07-18 09:22:47'), + (4, '3', '1', '1.jpg', NULL, NULL, 'backUser/config/2019071809245603e0a4e449a4bf3aa28ee731c309040.jpg', 1, 1, NULL, '2019-07-18 09:24:51'), + (6, '4', '1', '1.jpg', NULL, NULL, 'backUser/config/ddcb8214ba274dec9bb2c33e0e246391', 3, 1, NULL, '2019-07-19 16:19:43'), + (7, '5', '1', 'sql.txt', NULL, NULL, 'backUser/config/cfbdf9562c894405b5b6f64f71fa812a', 3, 1, NULL, '2019-07-19 17:41:55'), + (9, '1', '1', '20190912023241a6132f5713b54e1fb490f4ea88115747.md', NULL, NULL, 'backUser/config/20190912023241a6132f5713b54e1fb490f4ea88115747.md', 1, 1, '2019-09-12 15:25:35', '2019-09-12 14:32:42'), + (10, '1', '1', '201909120232499804998573f643ff8e58189d23485629.mjs', NULL, NULL, 'backUser/config/201909120232499804998573f643ff8e58189d23485629.mjs', 1, 1, '2019-09-12 15:25:19', '2019-09-12 14:32:50'), + (11, '1', '1', '201909120326564cdc8df7b8cc49cfb273926877f047f5.json', NULL, NULL, 'backUser/config/201909120326564cdc8df7b8cc49cfb273926877f047f5.json', 1, 1, NULL, '2019-09-12 15:26:56'), + (12, '1', '1', '201909120343357104b7f1cc684f5797ada35c06aba770.json', NULL, NULL, 'backUser/config/201909120343357104b7f1cc684f5797ada35c06aba770.json', 1, 1, NULL, '2019-09-12 15:43:36'), + (13, '1', '1', '201909120343427e408141a0ea467ea2e012f7086a6265.json', NULL, NULL, 'backUser/config/201909120343427e408141a0ea467ea2e012f7086a6265.json', 1, 1, NULL, '2019-09-12 15:43:42'), + (14, '1', '1', '20190912034543b4d3a061fb2e416c899fe2ff6b9327e0.ts', NULL, NULL, 'backUser/config/20190912034543b4d3a061fb2e416c899fe2ff6b9327e0.ts', 1, 1, NULL, '2019-09-12 15:45:43'), + (15, '1', '1', '20190912034550a5dc04ce79b14a1cb2bb76545c909aa8.md', NULL, NULL, 'backUser/config/20190912034550a5dc04ce79b14a1cb2bb76545c909aa8.md', 1, 1, NULL, '2019-09-12 15:45:51'), + (16, '1', '1', 'LICENCE', NULL, NULL, 'backUser/config/cc02b99c0ec548f1a2231b70b7d569b8', 2, 1, NULL, '2019-09-12 15:47:22'), + (17, '1', '1', 'bignumber.min.js', NULL, NULL, 'backUser/config/bda49e8ad6d242fe8735b2023dfbf125', 2, 1, NULL, '2019-09-12 15:47:29'), + (18, '1', '1', '20190912034880a881fa8fbc841bfb7194ff312bd1058.json', NULL, NULL, 'backUser/config/20190912034880a881fa8fbc841bfb7194ff312bd1058.json', 1, 1, NULL, '2019-09-12 15:48:08'), + (19, '1', '1', '20190912034816ece14084acf345a79396a0f4347c4e44.md', NULL, NULL, 'backUser/config/20190912034816ece14084acf345a79396a0f4347c4e44.md', 1, 1, NULL, '2019-09-12 15:48:16'), + (20, '1', '1', '20191024054412fac4b4e04c574c6eab71f91e13a8a0b6.jpg', NULL, NULL, 'backUser/config/20191024054412fac4b4e04c574c6eab71f91e13a8a0b6.jpg', 1, 1, NULL, '2019-10-24 17:44:13'), + (21, '1', '1', '20191106042073f7ef01bde3046bd8e01928f397230bd.jpg', NULL, NULL, 'backUser/config/20191106042073f7ef01bde3046bd8e01928f397230bd.jpg', 1, 1, NULL, '2019-11-06 02:20:13'), + (22, '1', '1', '201911130802024b8a2ebf80543a98241bb464682650d.jpg', NULL, NULL, 'backUser/config/201911130802024b8a2ebf80543a98241bb464682650d.jpg', 1, 1, NULL, '2019-11-13 06:02:01'), + (23, '1', '1', '20191113080210d1d98eea46364d268b2a03fa03f7a446.jpg', NULL, NULL, 'backUser/config/20191113080210d1d98eea46364d268b2a03fa03f7a446.jpg', 1, 1, NULL, '2019-11-13 06:02:14'), + (24, '1', '1', '20191115043844e92b25e70fb140a1885614b978469ca9.jpg', NULL, NULL, 'backUser/config/20191115043844e92b25e70fb140a1885614b978469ca9.jpg', 1, 38, NULL, '2019-11-15 02:38:45'), + (25, '1', '1', '20191116060546d3a2c703cb5546b3851612907cc3786f.png', NULL, NULL, 'backUser/config/20191116060546d3a2c703cb5546b3851612907cc3786f.png', 1, 1, NULL, '2019-11-16 10:05:47'); +/*!40000 ALTER TABLE `t_file` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_heart_beat_record 结构 +DROP TABLE IF EXISTS `t_heart_beat_record`; +CREATE TABLE IF NOT EXISTS `t_heart_beat_record` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', + `project_path` varchar(100) DEFAULT NULL COMMENT '项目名称', + `server_ip` varchar(200) DEFAULT NULL COMMENT '服务器ip', + `process_no` int(10) DEFAULT NULL COMMENT '进程号', + `process_start_time` datetime DEFAULT NULL COMMENT '进程开启时间', + `heart_beat_time` datetime DEFAULT NULL COMMENT '心跳时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + +-- 正在导出表 smart-admin-dev.t_heart_beat_record 的数据:~2 rows (大约) +DELETE FROM `t_heart_beat_record`; +/*!40000 ALTER TABLE `t_heart_beat_record` DISABLE KEYS */; +INSERT INTO `t_heart_beat_record` (`id`, `project_path`, `server_ip`, `process_no`, `process_start_time`, `heart_beat_time`) VALUES + (1, '/home/server/smart-admin/dev', '192.168.122.1;172.16.0.145', 14843, '2019-11-16 03:11:50', '2019-11-16 03:58:01'), + (2, 'F:\\codespace\\idea\\gangquan360\\foundation', '172.16.1.188;192.168.56.1', 227992, '2019-11-16 10:02:39', '2019-11-16 10:06:50'); +/*!40000 ALTER TABLE `t_heart_beat_record` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_id_generator 结构 +DROP TABLE IF EXISTS `t_id_generator`; +CREATE TABLE IF NOT EXISTS `t_id_generator` ( + `id` int(11) DEFAULT NULL, + `key_name` varchar(50) NOT NULL COMMENT '英文key', + `rule_format` varchar(500) NOT NULL COMMENT '规则格式。no_cycle没有周期, year_cycle 年周期, month_cycle月周期, day_cycle 日周期', + `rule_type` varchar(50) NOT NULL COMMENT '格式[yyyy]表示年,[mm]标识月,[dd]表示日,[nnn]表示三位数字', + `init_number` int(11) NOT NULL DEFAULT '1' COMMENT '初始值', + `last_number` int(11) DEFAULT NULL COMMENT '上次产生的id, 默认为空', + `remark` varchar(1000) NOT NULL COMMENT '备注', + `update_time` datetime DEFAULT NULL, + `create_time` datetime NOT NULL, + UNIQUE KEY `key_name` (`key_name`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='id生成器定义表'; + +-- 正在导出表 smart-admin-dev.t_id_generator 的数据:~2 rows (大约) +DELETE FROM `t_id_generator`; +/*!40000 ALTER TABLE `t_id_generator` DISABLE KEYS */; +INSERT INTO `t_id_generator` (`id`, `key_name`, `rule_format`, `rule_type`, `init_number`, `last_number`, `remark`, `update_time`, `create_time`) VALUES + (2, 'goods_num', '[nnnnnnn]', 'NO_CYCLE', 1, NULL, '商品编号', '2019-04-09 09:48:04', '2019-03-29 14:14:12'), + (1, 'order', '[yyyy][mm][dd][nnnnn]', 'DAY_CYCLE', 1, 1, '订单编号', '2019-03-30 11:25:42', '2019-03-29 14:14:12'); +/*!40000 ALTER TABLE `t_id_generator` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_id_generator_record 结构 +DROP TABLE IF EXISTS `t_id_generator_record`; +CREATE TABLE IF NOT EXISTS `t_id_generator_record` ( + `generator_id` int(11) NOT NULL, + `year` int(11) NOT NULL, + `month` int(11) NOT NULL, + `day` int(11) NOT NULL, + `last_number` int(11) NOT NULL, + PRIMARY KEY (`generator_id`,`year`,`month`,`day`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='id_generator记录表'; + +-- 正在导出表 smart-admin-dev.t_id_generator_record 的数据:~5 rows (大约) +DELETE FROM `t_id_generator_record`; +/*!40000 ALTER TABLE `t_id_generator_record` DISABLE KEYS */; +INSERT INTO `t_id_generator_record` (`generator_id`, `year`, `month`, `day`, `last_number`) VALUES + (1, 2019, 3, 30, 1), + (2, 2019, 3, 30, 1), + (2, 2019, 4, 3, 2), + (2, 2019, 4, 8, 2), + (2, 2019, 4, 9, 1); +/*!40000 ALTER TABLE `t_id_generator_record` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_notice 结构 +DROP TABLE IF EXISTS `t_notice`; +CREATE TABLE IF NOT EXISTS `t_notice` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `title` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '消息标题', + `content` longtext COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '消息内容', + `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '删除状态:0未删除 0删除 ', + `send_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '发送状态 0未发送 1发送', + `create_user` bigint(20) NOT NULL COMMENT '消息创建人', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=108 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 正在导出表 smart-admin-dev.t_notice 的数据:~14 rows (大约) +DELETE FROM `t_notice`; +/*!40000 ALTER TABLE `t_notice` DISABLE KEYS */; +INSERT INTO `t_notice` (`id`, `title`, `content`, `deleted`, `send_status`, `create_user`, `create_time`, `update_time`) VALUES + (93, '大扫把', '晓冬吃大便', 1, 1, 1, '2019-07-13 17:54:13', '2019-07-13 17:54:21'), + (95, '4444444', '444444444444', 1, 1, 1, '2019-07-13 17:54:53', '2019-09-04 09:42:02'), + (96, '3434', '444444', 1, 1, 1, '2019-07-13 17:58:42', '2019-11-08 09:05:24'), + (97, '44444', '555555555555', 1, 1, 1, '2019-07-13 17:58:54', '2019-09-03 16:19:50'), + (98, '《青花瓷》', '素胚勾勒出青花笔锋浓转淡\n瓶身描绘的牡丹一如你初妆\n冉冉檀香透过窗心事我了然\n周杰伦 青花瓷\n周杰伦 青花瓷\n宣纸上走笔至此搁一半\n釉色渲染仕女图韵味被私藏\n而你嫣然的一笑如含苞待放\n你的美一缕飘散\n去到我去不了的地方\n天青色等烟雨 而我在等你\n炊烟袅袅升起 隔江千万里\n在瓶底书刻隶仿前朝的飘逸\n就当我为遇见你伏笔\n天青色等烟雨 而我在等你\n月色被打捞起 晕开了结局\n如传世的青花瓷自顾自美丽\n你眼带笑意\n色白花青的锦鲤跃然于碗底\n临摹宋体落款时却惦记着你\n你隐藏在窑烧里千年的秘密\n极细腻犹如绣花针落地\n篱外芭蕉惹骤雨门环惹铜绿\n而我路过那江南小镇惹了你\n在泼墨山水画里\n你从墨色深处被隐去\n天青色等烟雨 而我在等你\n炊烟袅袅升起 隔江千万里\n在瓶底书刻隶仿前朝的飘逸\n就当我为遇见你伏笔\n天青色等烟雨 而我在等你\n月色被打捞起 晕开了结局\n如传世的青花瓷自顾自美丽\n你眼带笑意\n天青色等烟雨 而我在等你\n炊烟袅袅升起 隔江千万里\n在瓶底书刻隶仿前朝的飘逸\n就当我为遇见你伏笔\n天青色等烟雨 而我在等你\n月色被打捞起 晕开了结局\n如传世的青花瓷自顾自美丽\n你眼带笑意 ', 1, 1, 1, '2019-08-05 16:36:44', '2019-09-02 17:53:12'), + (99, '1', '2', 1, 1, 30, '2019-08-08 14:53:58', '2019-08-08 14:54:07'), + (100, '呵呵', '呵呵', 1, 1, 1, '2019-08-20 16:52:53', '2019-09-02 17:46:59'), + (101, 'aa', 'bbcc', 1, 1, 30, '2019-08-23 09:51:01', '2019-08-23 09:51:28'), + (102, '1', '2', 0, 1, 1, '2019-09-05 14:28:10', '2019-09-05 14:28:10'), + (103, '12', '22', 0, 1, 1, '2019-09-05 14:29:30', '2019-09-05 14:29:30'), + (104, 'a', 'b', 1, 1, 30, '2019-09-06 14:21:18', '2019-09-06 14:24:07'), + (105, '22222222222', '1111', 0, 0, 1, '2019-11-07 19:05:56', '2019-11-07 19:05:56'), + (106, '423', '234', 0, 0, 37, '2019-11-08 21:48:19', '2019-11-08 21:48:19'), + (107, 'AAS', 's\'da\'ssdas', 1, 1, 1, '2019-11-13 19:06:55', '2019-11-14 09:07:06'); +/*!40000 ALTER TABLE `t_notice` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_notice_receive_record 结构 +DROP TABLE IF EXISTS `t_notice_receive_record`; +CREATE TABLE IF NOT EXISTS `t_notice_receive_record` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `notice_id` bigint(20) NOT NULL COMMENT '消息id', + `employee_id` bigint(20) NOT NULL COMMENT '用户id', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=141 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 正在导出表 smart-admin-dev.t_notice_receive_record 的数据:~27 rows (大约) +DELETE FROM `t_notice_receive_record`; +/*!40000 ALTER TABLE `t_notice_receive_record` DISABLE KEYS */; +INSERT INTO `t_notice_receive_record` (`id`, `notice_id`, `employee_id`, `create_time`, `update_time`) VALUES + (114, 93, 1, '2019-07-13 17:54:16', '2019-07-13 17:54:16'), + (115, 95, 1, '2019-07-13 17:54:55', '2019-07-13 17:54:55'), + (116, 95, 22, '2019-07-13 17:58:03', '2019-07-13 17:58:03'), + (117, 93, 22, '2019-07-13 17:58:05', '2019-07-13 17:58:05'), + (118, 96, 1, '2019-07-13 17:58:44', '2019-07-13 17:58:44'), + (119, 97, 1, '2019-07-13 17:58:58', '2019-07-13 17:58:58'), + (120, 98, 1, '2019-08-05 16:37:01', '2019-08-05 16:37:01'), + (121, 99, 30, '2019-08-08 14:54:05', '2019-08-08 14:54:05'), + (122, 99, 1, '2019-08-08 15:15:44', '2019-08-08 15:15:44'), + (123, 100, 1, '2019-08-20 16:53:29', '2019-08-20 16:53:29'), + (124, 101, 30, '2019-08-23 09:51:11', '2019-08-23 09:51:11'), + (125, 101, 1, '2019-08-23 12:46:27', '2019-08-23 12:46:27'), + (126, 102, 1, '2019-09-05 14:28:32', '2019-09-05 14:28:32'), + (127, 104, 30, '2019-09-06 14:23:58', '2019-09-06 14:23:58'), + (128, 104, 1, '2019-09-06 15:25:13', '2019-09-06 15:25:13'), + (129, 101, 14, '2019-11-02 21:46:13', '2019-11-02 21:46:13'), + (130, 102, 14, '2019-11-02 21:46:14', '2019-11-02 21:46:14'), + (131, 104, 14, '2019-11-02 21:46:15', '2019-11-02 21:46:15'), + (132, 98, 14, '2019-11-02 21:46:18', '2019-11-02 21:46:18'), + (133, 103, 37, '2019-11-07 19:58:06', '2019-11-07 19:58:06'), + (134, 103, 1, '2019-11-07 20:03:54', '2019-11-07 20:03:54'), + (135, 107, 1, '2019-11-13 19:07:02', '2019-11-13 19:07:02'), + (136, 107, 38, '2019-11-15 02:11:04', '2019-11-15 02:11:04'), + (137, 104, 38, '2019-11-15 02:11:17', '2019-11-15 02:11:17'), + (138, 101, 38, '2019-11-15 02:26:33', '2019-11-15 02:26:33'), + (139, 98, 38, '2019-11-15 02:29:32', '2019-11-15 02:29:32'), + (140, 100, 38, '2019-11-15 03:19:18', '2019-11-15 03:19:18'); +/*!40000 ALTER TABLE `t_notice_receive_record` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_order_operate_log 结构 +DROP TABLE IF EXISTS `t_order_operate_log`; +CREATE TABLE IF NOT EXISTS `t_order_operate_log` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `order_id` int(11) NOT NULL COMMENT '各种单据的id', + `order_type` int(11) NOT NULL COMMENT '单据类型', + `operate_type` int(11) NOT NULL COMMENT '操作类型', + `operate_content` text NOT NULL COMMENT '操作类型 对应的中文', + `operate_remark` text COMMENT '操作备注', + `employee_id` int(11) NOT NULL COMMENT '员工id', + `employee_name` varchar(1000) NOT NULL COMMENT '员工名称', + `ext_data` text COMMENT '额外信息', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `order_id_order_type` (`order_id`,`order_type`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='各种单据操作记录\r\n'; + +-- 正在导出表 smart-admin-dev.t_order_operate_log 的数据:~0 rows (大约) +DELETE FROM `t_order_operate_log`; +/*!40000 ALTER TABLE `t_order_operate_log` DISABLE KEYS */; +/*!40000 ALTER TABLE `t_order_operate_log` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_position 结构 +DROP TABLE IF EXISTS `t_position`; +CREATE TABLE IF NOT EXISTS `t_position` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `position_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '岗位名称', + `remark` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '岗位描述', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='岗位表'; + +-- 正在导出表 smart-admin-dev.t_position 的数据:~13 rows (大约) +DELETE FROM `t_position`; +/*!40000 ALTER TABLE `t_position` DISABLE KEYS */; +INSERT INTO `t_position` (`id`, `position_name`, `remark`, `update_time`, `create_time`) VALUES + (1, 'java develop', 'java develop is good job', '2019-07-03 15:18:45', '2019-07-03 15:18:45'), + (2, 'android develop', 'android develop is good job', '2019-07-04 16:11:11', '2019-07-04 16:11:00'), + (3, '测试岗位1', '这是内容11', '2019-09-02 16:39:33', '2019-07-10 14:03:50'), + (8, '测试岗位2', '测试岗位2.。', '2019-09-04 10:19:40', '2019-09-04 10:19:32'), + (9, '测试岗位3', '测试岗位3', '2019-09-05 14:39:43', '2019-09-05 14:39:43'), + (10, '测试岗位4', '测试岗位4', '2019-09-05 14:39:48', '2019-09-05 14:39:48'), + (11, '测试岗位5', '测试岗位5', '2019-09-05 14:39:53', '2019-09-05 14:39:53'), + (12, '测试岗位6', '测试岗位6', '2019-09-05 14:39:58', '2019-09-05 14:39:58'), + (13, '测试岗位7', '测试岗位7', '2019-09-05 14:40:03', '2019-09-05 14:40:03'), + (14, '测试岗位8', '测试岗位8', '2019-09-05 14:40:09', '2019-09-05 14:40:09'), + (15, '测试岗位9', '测试岗位9', '2019-09-05 14:40:19', '2019-09-05 14:40:19'), + (16, 'aaa22222', 'ddddddddddd', '2019-11-15 17:04:29', '2019-11-06 15:58:37'), + (17, 'ddd', 'fsdef', '2019-11-15 17:04:40', '2019-11-15 17:04:40'); +/*!40000 ALTER TABLE `t_position` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_position_relation 结构 +DROP TABLE IF EXISTS `t_position_relation`; +CREATE TABLE IF NOT EXISTS `t_position_relation` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `position_id` int(10) DEFAULT NULL COMMENT '岗位ID', + `employee_id` int(10) DEFAULT NULL COMMENT '员工ID', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `job_id` (`position_id`) USING BTREE, + KEY `employee_id` (`employee_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='岗位关联表'; + +-- 正在导出表 smart-admin-dev.t_position_relation 的数据:~27 rows (大约) +DELETE FROM `t_position_relation`; +/*!40000 ALTER TABLE `t_position_relation` DISABLE KEYS */; +INSERT INTO `t_position_relation` (`id`, `position_id`, `employee_id`, `update_time`, `create_time`) VALUES + (14, 1, 28, '2019-07-10 16:40:14', '2019-07-10 16:40:14'), + (18, 1, 29, '2019-07-11 10:18:22', '2019-07-11 10:18:22'), + (19, 3, 29, '2019-07-11 10:18:22', '2019-07-11 10:18:22'), + (20, 2, 29, '2019-07-11 10:18:22', '2019-07-11 10:18:22'), + (21, 1, 30, '2019-08-08 14:35:51', '2019-08-08 14:35:51'), + (22, 2, 30, '2019-08-08 14:35:51', '2019-08-08 14:35:51'), + (23, 3, 30, '2019-08-08 14:35:51', '2019-08-08 14:35:51'), + (26, 2, 31, '2019-08-23 09:26:44', '2019-08-23 09:26:44'), + (27, 3, 31, '2019-08-23 09:26:44', '2019-08-23 09:26:44'), + (28, 3, 32, '2019-09-04 09:05:47', '2019-09-04 09:05:47'), + (29, 2, 32, '2019-09-04 09:05:47', '2019-09-04 09:05:47'), + (30, 3, 22, '2019-09-04 09:06:46', '2019-09-04 09:06:46'), + (31, 2, 22, '2019-09-04 09:06:46', '2019-09-04 09:06:46'), + (35, 8, 35, '2019-09-04 15:09:00', '2019-09-04 15:09:00'), + (36, 3, 35, '2019-09-04 15:09:00', '2019-09-04 15:09:00'), + (37, 15, 23, '2019-09-05 16:13:02', '2019-09-05 16:13:02'), + (38, 14, 23, '2019-09-05 16:13:02', '2019-09-05 16:13:02'), + (39, 13, 23, '2019-09-05 16:13:02', '2019-09-05 16:13:02'), + (40, 3, 34, '2019-09-06 08:55:18', '2019-09-06 08:55:18'), + (41, 2, 34, '2019-09-06 08:55:18', '2019-09-06 08:55:18'), + (42, 1, 34, '2019-09-06 08:55:18', '2019-09-06 08:55:18'), + (43, 14, 36, '2019-09-09 17:01:39', '2019-09-09 17:01:39'), + (44, 3, 37, '2019-11-08 09:32:39', '2019-11-08 09:32:39'), + (46, 8, 38, '2019-11-14 16:08:05', '2019-11-14 16:08:05'), + (50, 16, 39, '2019-11-15 17:07:04', '2019-11-15 17:07:04'), + (51, 13, 39, '2019-11-15 17:07:04', '2019-11-15 17:07:04'), + (52, 14, 39, '2019-11-15 17:07:04', '2019-11-15 17:07:04'); +/*!40000 ALTER TABLE `t_position_relation` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_privilege 结构 +DROP TABLE IF EXISTS `t_privilege`; +CREATE TABLE IF NOT EXISTS `t_privilege` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '功能权限表主键id', + `type` tinyint(11) NOT NULL COMMENT '1.菜单 2.功能点', + `name` varchar(50) NOT NULL COMMENT '菜单名称', + `key` varchar(1000) NOT NULL COMMENT '路由name 英文关键字', + `url` text COMMENT '路由path/type=3为API接口', + `sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序', + `parent_key` varchar(1000) DEFAULT NULL COMMENT '父级key', + `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + UNIQUE KEY `key` (`key`) USING BTREE, + KEY `type` (`type`) USING BTREE, + KEY `parent_key` (`parent_key`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=106 DEFAULT CHARSET=utf8 COMMENT='权限功能表'; + +-- 正在导出表 smart-admin-dev.t_privilege 的数据:~103 rows (大约) +DELETE FROM `t_privilege`; +/*!40000 ALTER TABLE `t_privilege` DISABLE KEYS */; +INSERT INTO `t_privilege` (`id`, `type`, `name`, `key`, `url`, `sort`, `parent_key`, `update_time`, `create_time`) VALUES + (1, 1, '人员管理', 'Employee', '/employee', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (2, 1, '角色管理', 'RoleManage', '/employee/role', 0, 'Employee', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (3, 1, '岗位管理', 'PositionList', '/employee/position', 0, 'Employee', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (4, 1, '员工管理', 'RoleEmployeeManage', '/employee/role-employee-manage', 0, 'Employee', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (5, 1, '系统设置', 'SystemSetting', '/system-setting', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (6, 1, '系统参数', 'SystemConfig', '/system-setting/system-config', 0, 'SystemSetting', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (8, 1, '菜单管理', 'SystemPrivilege', '/system-setting/system-privilege', 0, 'SystemSetting', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (9, 1, '消息管理', 'Notice', '/notice', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (10, 1, '通知管理', 'NoticeList', '/notice/notice-list', 0, 'Notice', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (11, 1, '个人消息', 'PersonNotice', '/notice/person-notice', 0, 'Notice', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (12, 1, '邮件管理', 'Email', '/email', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (13, 1, '邮件管理', 'EmailList', '/email/email-list', 0, 'Email', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (14, 1, '发送邮件', 'SendMail', '/email/send-mail', 0, 'Email', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (15, 1, '用户日志', 'UserLog', '/user-log', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (16, 1, '用户操作日志', 'UserOperateLog', '/user-log/user-operate-log', 0, 'UserLog', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (17, 1, '用户登录日志', 'UserLoginLog', '/user-log/user-login-log', 0, 'UserLog', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (18, 1, '系统监控', 'Monitor', '/monitor', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (19, 1, '在线人数', 'OnlineUser', '/monitor/online-user', 0, 'Monitor', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (20, 1, 'SQL监控', 'Sql', '/monitor/sql', 0, 'Monitor', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (21, 1, '定时任务', 'Task', '/task', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (22, 1, '任务管理', 'TaskList', '/system-setting/task-list', 0, 'Task', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (23, 1, '动态加载', 'Reload', '/reload', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (24, 1, 'SmartReload', 'SmartReloadList', '/reload/smart-reload-list', 0, 'Reload', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (25, 1, '接口文档', 'ApiDoc', '/api-doc', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (26, 1, 'Swagger接口文档', 'Swagger', '/api-doc/swagger', 0, 'ApiDoc', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (27, 1, '三级路由', 'ThreeRouter', '/three-router', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (28, 1, '三级菜单', 'LevelTwo', '/three-router/level-two', 0, 'ThreeRouter', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (29, 1, '三级A', 'RoleOneTwo', '/three-router/level-two/level-three1', 0, 'LevelTwo', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (30, 1, '三级B', 'RoleTwoTwo', '/three-router/level-two/level-three2', 0, 'LevelTwo', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (31, 1, '二级菜单', 'RoleOneOne', '/three-router/level-two2', 0, 'ThreeRouter', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (32, 1, 'KeepAlive', 'KeepAlive', '/keep-alive', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (33, 1, 'KeepAlive列表', 'KeepAliveContentList', '/keep-alive/content-list', 0, 'KeepAlive', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (34, 1, 'KeepAlive表单', 'KeepAliveAddContent', '/keep-alive/add-content', 0, 'KeepAlive', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (35, 1, '心跳服务', 'HeartBeat', '/heart-beat', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (36, 1, '心跳服务', 'HeartBeatList', '/heart-beat/heart-beat-list', 0, 'HeartBeat', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (37, 1, '文件服务', 'File', '/file', 0, NULL, '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (38, 1, '文件列表', 'FileList', '/file/file-list', 0, 'File', '2019-11-14 14:05:10', '2019-11-01 11:28:07'), + (39, 2, '添加角色', 'add-role', 'roleController.addRole', 0, 'RoleManage', '2019-11-01 11:47:29', '2019-11-01 11:47:29'), + (40, 2, '删除角色', 'delete-role', 'roleController.deleteRole', 1, 'RoleManage', '2019-11-01 11:47:43', '2019-11-01 11:47:43'), + (41, 2, '编辑角色', 'update-role', 'roleController.updateRole', 2, 'RoleManage', '2019-11-01 11:47:55', '2019-11-01 11:47:55'), + (42, 2, '修改角色权限', 'update-role-privilege', 'rolePrivilegeController.updateRolePrivilege', 3, 'RoleManage', '2019-11-01 11:48:09', '2019-11-01 11:48:09'), + (43, 2, '添加成员', 'add-employee-role', 'roleEmployeeController.addEmployeeList', 4, 'RoleManage', '2019-11-05 10:38:11', '2019-11-05 10:38:11'), + (44, 2, '查询成员', 'search-employee-list', 'roleEmployeeController.listAllEmployeeRoleId,roleEmployeeController.listEmployeeByName,roleController.getAllRole,rolePrivilegeController.listPrivilegeByRoleId', 7, 'RoleManage', '2019-11-05 10:39:04', '2019-11-05 10:39:04'), + (45, 2, '移除成员', 'delete-employee-role', 'roleEmployeeController.removeEmployee', 5, 'RoleManage', '2019-11-05 10:40:09', '2019-11-05 10:40:09'), + (46, 2, '批量移除', 'delete-employee-role-batch', 'roleEmployeeController.removeEmployeeList', 6, 'RoleManage', '2019-11-05 10:40:27', '2019-11-05 10:40:27'), + (47, 2, '查询数据范围', 'query-data-scope', 'dataScopeController.dataScopeList,dataScopeController.dataScopeListByRole,rolePrivilegeController.listPrivilegeByRoleId,privilegeController.queryAll,privilegeController.getAllUrl', 8, 'RoleManage', '2019-11-05 10:40:57', '2019-11-05 10:40:57'), + (48, 2, '更新数据范围', 'update-data-scope', 'dataScopeController.dataScopeBatchSet', 9, 'RoleManage', '2019-11-05 10:41:03', '2019-11-05 10:41:03'), + (49, 2, '查询', 'search-position', 'positionController.queryJobById,positionController.getJobPage', 0, 'PositionList', '2019-11-05 10:41:30', '2019-11-05 10:41:30'), + (50, 2, '添加', 'add-position', 'positionController.addJob', 1, 'PositionList', '2019-11-05 10:41:40', '2019-11-05 10:41:40'), + (51, 2, '修改', 'update-position', 'positionController.updateJob', 2, 'PositionList', '2019-11-05 10:41:49', '2019-11-05 10:41:49'), + (52, 2, '删除', 'delete-position', 'positionController.removeJob', 3, 'PositionList', '2019-11-05 10:41:57', '2019-11-05 10:41:57'), + (53, 2, '添加部门', 'add-department', 'departmentController.addDepartment', 0, 'RoleEmployeeManage', '2019-11-05 11:11:18', '2019-11-05 11:11:18'), + (54, 2, '编辑部门', 'update-department', 'departmentController.updateDepartment', 1, 'RoleEmployeeManage', '2019-11-05 11:11:29', '2019-11-05 11:11:29'), + (55, 2, '删除部门', 'delete-department', 'departmentController.delDepartment', 2, 'RoleEmployeeManage', '2019-11-05 11:11:48', '2019-11-05 11:11:48'), + (56, 2, '查询', 'search-department', 'departmentController.listAll,departmentController.getDepartment,departmentController.listDepartmentEmployee,departmentController.listDepartment,employeeController.query', 3, 'RoleEmployeeManage', '2019-11-05 11:12:09', '2019-11-05 11:12:09'), + (57, 2, '添加成员', 'add-employee', 'employeeController.addEmployee', 4, 'RoleEmployeeManage', '2019-11-05 17:06:23', '2019-11-05 17:06:23'), + (58, 2, '编辑成员', 'update-employee', 'employeeController.updateEmployee', 5, 'RoleEmployeeManage', '2019-11-05 17:06:57', '2019-11-05 17:06:57'), + (59, 2, '禁用', 'disabled-employee', 'employeeController.updateStatus', 6, 'RoleEmployeeManage', '2019-11-05 17:14:35', '2019-11-05 17:14:35'), + (60, 2, '批量操作', 'disabled-employee-batch', 'employeeController.batchUpdateStatus', 7, 'RoleEmployeeManage', '2019-11-05 17:19:23', '2019-11-05 17:19:23'), + (61, 2, '员工角色编辑', 'update-employee-role', 'employeeController.updateRoles', 8, 'RoleEmployeeManage', '2019-11-05 17:21:15', '2019-11-05 17:21:15'), + (62, 2, '重置密码', 'reset-employee-password', 'employeeController.resetPasswd', 10, 'RoleEmployeeManage', '2019-11-05 17:22:13', '2019-11-05 17:22:13'), + (63, 2, '删除员工', 'delete-employee', 'employeeController.deleteEmployeeById', 9, 'RoleEmployeeManage', '2019-11-05 17:22:27', '2019-11-05 17:22:27'), + (64, 2, '查询系统参数', 'system-params-search', 'systemConfigController.selectByKey,systemConfigController.getListByGroup,systemConfigController.getSystemConfigPage', 0, 'SystemConfig', '2019-11-05 17:23:41', '2019-11-05 17:23:41'), + (65, 2, '添加系统参数', 'system-params-add', 'systemConfigController.addSystemConfig', 1, 'SystemConfig', '2019-11-05 17:26:00', '2019-11-05 17:26:00'), + (66, 2, '修改系统参数', 'system-config-update', 'systemConfigController.updateSystemConfig', 2, 'SystemConfig', '2019-11-05 17:26:07', '2019-11-05 17:26:07'), + (67, 2, '搜索系统参数', 'system-config-search', 'systemConfigController.selectByKey,systemConfigController.getListByGroup,systemConfigController.getSystemConfigPage', 3, 'SystemConfig', '2019-11-05 17:26:44', '2019-11-05 17:26:44'), + (69, 2, '编辑', 'privilege-main-update', 'privilegeController.menuBatchSave,privilegeController.functionSaveOrUpdate', 0, 'SystemPrivilege', '2019-11-05 17:27:28', '2019-11-05 17:27:28'), + (70, 2, '查询', 'privilege-main-search', 'privilegeController.queryAll,privilegeController.getAllUrl,privilegeController.functionQuery', 1, 'SystemPrivilege', '2019-11-05 17:28:45', '2019-11-05 17:28:45'), + (71, 2, '查询', 'notice-query', 'noticeController.queryReceiveByPage,noticeController.queryUnreadByPage,noticeController.queryByPage,noticeController.detail', 0, 'NoticeList', '2019-11-05 17:30:16', '2019-11-05 17:30:16'), + (72, 2, '添加', 'notice-add', 'noticeController.add', 1, 'NoticeList', '2019-11-05 17:30:28', '2019-11-05 17:30:28'), + (73, 2, '修改', 'notice-edit', 'noticeController.update', 2, 'NoticeList', '2019-11-05 17:31:24', '2019-11-05 17:31:24'), + (74, 2, '删除', 'notice-delete', 'noticeController.delete', 3, 'NoticeList', '2019-11-06 11:12:32', '2019-11-06 11:12:32'), + (75, 2, '详情', 'notice-detail', 'noticeController.detail', 4, 'NoticeList', '2019-11-06 11:12:44', '2019-11-06 11:12:44'), + (76, 2, '发送', 'notice-send', 'noticeController.send', 5, 'NoticeList', '2019-11-06 11:12:51', '2019-11-06 11:12:51'), + (77, 2, '查询', 'person-notice-query', 'noticeController.queryReceiveByPage,noticeController.queryUnreadByPage,noticeController.queryByPage', 0, 'PersonNotice', '2019-11-06 11:13:27', '2019-11-06 11:13:27'), + (78, 2, '详情', 'person-notice-detail', 'noticeController.detail', 1, 'PersonNotice', '2019-11-06 11:13:35', '2019-11-06 11:13:35'), + (79, 2, '查询', 'email-query', 'emailController.queryByPage,emailController.detail', 0, 'EmailList', '2019-11-06 11:13:49', '2019-11-06 11:13:49'), + (80, 2, '新增', 'email-add', 'emailController.add', 1, 'EmailList', '2019-11-06 11:14:02', '2019-11-06 11:14:02'), + (81, 2, '编辑', 'email-update', 'emailController.update', 2, 'EmailList', '2019-11-06 11:14:08', '2019-11-06 11:14:08'), + (82, 2, '删除', 'email-delete', 'emailController.delete', 3, 'EmailList', '2019-11-06 11:14:16', '2019-11-06 11:14:16'), + (83, 2, '发送', 'email-send', 'emailController.send', 0, 'SendMail', '2019-11-06 11:14:40', '2019-11-06 11:14:40'), + (84, 2, '查询', 'user-operate-log-search', 'userOperateLogController.queryByPage', 0, 'UserOperateLog', '2019-11-06 11:15:04', '2019-11-06 11:15:04'), + (85, 2, '详情', 'user-operate-log-detail', 'userOperateLogController.detail', 1, 'UserOperateLog', '2019-11-06 11:15:16', '2019-11-06 11:15:16'), + (86, 2, '删除', 'user-operate-log-delete', 'userOperateLogController.delete', 2, 'UserOperateLog', '2019-11-06 11:15:25', '2019-11-06 11:15:25'), + (87, 2, '查询', 'user-login-log-search', 'userLoginLogController.queryByPage', 0, 'UserLoginLog', '2019-11-06 11:15:43', '2019-11-06 11:15:43'), + (88, 2, '删除', 'user-login-log-delete', 'userLoginLogController.delete', 1, 'UserLoginLog', '2019-11-06 11:15:49', '2019-11-06 11:15:49'), + (89, 2, '查询', 'online-user-search', 'userLoginLogController.queryUserOnLine', 0, 'OnlineUser', '2019-11-06 11:16:05', '2019-11-06 11:16:05'), + (90, 2, '查询任务', 'task-search', 'quartzController.query', 0, 'TaskList', '2019-11-06 11:16:24', '2019-11-06 11:16:24'), + (91, 2, '刷新任务', 'task-refresh', 'quartzController.query', 1, 'TaskList', '2019-11-06 11:16:50', '2019-11-06 11:16:50'), + (92, 2, '添加任务', 'task-add', 'quartzController.saveOrUpdateTask', 2, 'TaskList', '2019-11-06 11:17:04', '2019-11-06 11:17:04'), + (93, 2, '编辑任务', 'task-update', 'quartzController.saveOrUpdateTask', 3, 'TaskList', '2019-11-06 11:17:17', '2019-11-06 11:17:17'), + (94, 2, '暂停任务', 'task-pause', 'quartzController.pauseTask', 4, 'TaskList', '2019-11-06 11:17:25', '2019-11-06 11:17:25'), + (95, 2, '恢复任务', 'task-resume', 'quartzController.resumeTask', 5, 'TaskList', '2019-11-06 11:17:31', '2019-11-06 11:17:31'), + (96, 2, '立即运行任务', 'task-run', 'quartzController.runTask', 6, 'TaskList', '2019-11-06 11:17:38', '2019-11-06 11:17:38'), + (97, 2, '查看任务日志', 'task-query-log', 'quartzController.queryLog', 7, 'TaskList', '2019-11-06 11:17:47', '2019-11-06 11:17:47'), + (98, 2, '删除任务', 'task-delete', 'quartzController.deleteTask', 8, 'TaskList', '2019-11-06 11:17:53', '2019-11-06 11:17:53'), + (99, 2, '查询', 'smart-reload-search', 'smartReloadController.listAllReloadItem', 0, 'SmartReloadList', '2019-11-06 11:18:06', '2019-11-06 11:18:06'), + (100, 2, '执行reload', 'smart-reload-update', 'smartReloadController.updateByTag', 1, 'SmartReloadList', '2019-11-06 11:18:14', '2019-11-06 11:18:14'), + (101, 2, '查看执行结果', 'smart-reload-result', 'smartReloadController.queryReloadResult', 2, 'SmartReloadList', '2019-11-06 11:18:19', '2019-11-06 11:18:19'), + (102, 2, '查询任务', 'heart-beat-query', 'heartBeatController.query', 0, 'HeartBeatList', '2019-11-06 11:18:38', '2019-11-06 11:18:38'), + (103, 2, '查询', 'file-filePage-query', 'fileController.queryListByPage,fileController.localGetFile,fileController.downLoadById', 0, 'FileList', '2019-11-06 11:19:06', '2019-11-06 11:19:06'), + (104, 2, '上传', 'file-filePage-upload', 'fileController.qiNiuUpload,fileController.localUpload,fileController.aliYunUpload,fileController.saveFile', 1, 'FileList', '2019-11-06 11:19:36', '2019-11-06 11:19:36'), + (105, 2, '下载', 'file-filePage-download', 'fileController.downLoadById', 2, 'FileList', '2019-11-16 10:05:02', '2019-11-16 10:05:02'); +/*!40000 ALTER TABLE `t_privilege` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_quartz_task 结构 +DROP TABLE IF EXISTS `t_quartz_task`; +CREATE TABLE IF NOT EXISTS `t_quartz_task` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `task_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '任务名称', + `task_bean` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'spring bean名称', + `task_params` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '任务参数', + `task_cron` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '运行cron表达式', + `task_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务状态0:正常,1:暂停', + `remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 正在导出表 smart-admin-dev.t_quartz_task 的数据:~5 rows (大约) +DELETE FROM `t_quartz_task`; +/*!40000 ALTER TABLE `t_quartz_task` DISABLE KEYS */; +INSERT INTO `t_quartz_task` (`id`, `task_name`, `task_bean`, `task_params`, `task_cron`, `task_status`, `remark`, `update_time`, `create_time`) VALUES + (9, '2312332', 'exampleTask', '21314', '*/5 * * * * ?', 1, NULL, '2019-09-06 14:41:55', '2019-04-19 15:24:26'), + (13, '567', 'exampleTask', 'ads', '*/5 * * * * ?', 1, NULL, '2019-09-04 16:37:25', '2019-04-23 15:32:17'), + (21, '11', 'exampleTask', '11', '*/5 * * * * ?', 1, NULL, '2019-09-04 16:37:30', '2019-04-26 17:29:21'), + (22, '33', 'exampleTask', '333', '*/5 * * * * ?', 1, NULL, '2019-04-26 17:29:36', '2019-04-26 17:29:36'), + (23, '1', 'exampleTask', '3', '*/5 * * * * ?', 0, NULL, '2019-09-05 17:21:12', '2019-04-26 17:29:50'); +/*!40000 ALTER TABLE `t_quartz_task` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_quartz_task_log 结构 +DROP TABLE IF EXISTS `t_quartz_task_log`; +CREATE TABLE IF NOT EXISTS `t_quartz_task_log` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `task_id` int(11) NOT NULL COMMENT '任务id', + `task_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '任务名称', + `task_params` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '任务参数', + `process_status` tinyint(4) NOT NULL COMMENT '任务处理状态0:成功,1:失败', + `process_duration` bigint(11) NOT NULL DEFAULT '0' COMMENT '运行时长', + `process_log` text COLLATE utf8mb4_unicode_ci COMMENT '日志', + `ip_address` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '运行主机ip', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=732881 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 正在导出表 smart-admin-dev.t_quartz_task_log 的数据:~11 rows (大约) +DELETE FROM `t_quartz_task_log`; +/*!40000 ALTER TABLE `t_quartz_task_log` DISABLE KEYS */; +INSERT INTO `t_quartz_task_log` (`id`, `task_id`, `task_name`, `task_params`, `process_status`, `process_duration`, `process_log`, `ip_address`, `update_time`, `create_time`) VALUES + (732870, 9, '231233', '2131', 0, 5, NULL, '127.0.0.1', '2019-05-05 15:28:01', '2019-05-05 15:28:01'), + (732871, 9, '231233', '2131', 0, 32, NULL, '172.16.0.145', '2019-05-05 15:54:40', '2019-05-05 15:54:40'), + (732872, 22, '33', '333', 0, 31, NULL, '172.16.0.145', '2019-05-07 16:20:31', '2019-05-07 16:20:31'), + (732873, 9, '231233', '2131', 0, 304, NULL, '172.16.0.145', '2019-08-02 09:29:36', '2019-08-02 09:29:36'), + (732874, 9, '231233', '2131', 0, 24, NULL, '172.16.0.145', '2019-08-08 16:48:49', '2019-08-08 16:48:49'), + (732875, 9, '231233', '2131', 0, 147, NULL, '172.16.0.145', '2019-08-23 09:41:08', '2019-08-23 09:41:08'), + (732876, 9, '231233', '2131', 0, 610, NULL, '172.16.0.145', '2019-08-26 16:16:34', '2019-08-26 16:16:34'), + (732877, 9, '2312332', '2131', 0, 27, NULL, '172.16.0.145', '2019-09-05 14:34:51', '2019-09-05 14:34:51'), + (732878, 9, '2312332', '2131', 0, 5, NULL, '172.16.0.145', '2019-09-05 17:18:17', '2019-09-05 17:18:17'), + (732879, 9, '2312332', '2131', 0, 1, NULL, '172.16.0.145', '2019-09-05 17:20:15', '2019-09-05 17:20:15'), + (732880, 9, '2312332', '2131', 0, 5, NULL, '172.16.0.145', '2019-09-06 14:42:04', '2019-09-06 14:42:04'); +/*!40000 ALTER TABLE `t_quartz_task_log` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_reload_item 结构 +DROP TABLE IF EXISTS `t_reload_item`; +CREATE TABLE IF NOT EXISTS `t_reload_item` ( + `tag` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT '项名称', + `args` varchar(255) DEFAULT NULL COMMENT '参数 可选', + `identification` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT '运行标识', + `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`tag`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- 正在导出表 smart-admin-dev.t_reload_item 的数据:~1 rows (大约) +DELETE FROM `t_reload_item`; +/*!40000 ALTER TABLE `t_reload_item` DISABLE KEYS */; +INSERT INTO `t_reload_item` (`tag`, `args`, `identification`, `update_time`, `create_time`) VALUES + ('system_config', '234', 'xxxx', '2019-11-14 16:46:21', '2019-04-18 11:48:27'); +/*!40000 ALTER TABLE `t_reload_item` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_reload_result 结构 +DROP TABLE IF EXISTS `t_reload_result`; +CREATE TABLE IF NOT EXISTS `t_reload_result` ( + `tag` varchar(255) NOT NULL, + `identification` varchar(255) NOT NULL COMMENT '运行标识', + `args` varchar(255) DEFAULT NULL, + `result` tinyint(3) unsigned NOT NULL COMMENT '是否成功 ', + `exception` text, + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- 正在导出表 smart-admin-dev.t_reload_result 的数据:~126 rows (大约) +DELETE FROM `t_reload_result`; +/*!40000 ALTER TABLE `t_reload_result` DISABLE KEYS */; +INSERT INTO `t_reload_result` (`tag`, `identification`, `args`, `result`, `exception`, `create_time`) VALUES + ('system_config', '23', '', 1, NULL, '2019-09-07 17:26:04'), + ('system_config', '23', '', 1, NULL, '2019-09-07 17:28:16'), + ('system_config', '23', '', 1, NULL, '2019-09-07 17:35:39'), + ('system_config', '23', '', 1, NULL, '2019-09-07 17:42:58'), + ('system_config', '23', '', 1, NULL, '2019-09-09 08:30:13'), + ('system_config', '23', '', 1, NULL, '2019-09-11 10:38:19'), + ('system_config', '23', '', 1, NULL, '2019-09-11 10:42:46'), + ('system_config', '23', '', 1, NULL, '2019-09-11 10:49:27'), + ('system_config', '23', '', 1, NULL, '2019-09-11 11:09:10'), + ('system_config', '23', '', 1, NULL, '2019-09-11 11:10:06'), + ('system_config', '23', '', 1, NULL, '2019-09-11 11:18:17'), + ('system_config', '23', '', 1, NULL, '2019-09-11 11:41:18'), + ('system_config', '23', '', 1, NULL, '2019-09-11 11:45:41'), + ('system_config', '23', '', 1, NULL, '2019-09-11 11:46:37'), + ('system_config', '23', '', 1, NULL, '2019-09-11 11:50:35'), + ('system_config', '23', '', 1, NULL, '2019-09-11 14:55:00'), + ('system_config', '23', '', 1, NULL, '2019-09-11 15:26:19'), + ('system_config', '23', '', 1, NULL, '2019-09-11 15:35:51'), + ('system_config', '23', '', 1, NULL, '2019-09-11 15:36:19'), + ('system_config', '23', '', 1, NULL, '2019-09-11 15:36:53'), + ('system_config', '23', '', 1, NULL, '2019-09-11 15:37:58'), + ('system_config', '23', '', 1, NULL, '2019-09-11 15:41:37'), + ('system_config', '23', '', 1, NULL, '2019-09-16 10:12:29'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:14:08'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:18:24'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:23:07'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:24:17'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:30:17'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:31:40'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:32:34'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:52:31'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:55:10'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:55:47'), + ('system_config', '23', '', 1, NULL, '2019-09-20 17:58:49'), + ('system_config', '23', '', 1, NULL, '2019-09-21 10:53:47'), + ('system_config', '23', '', 1, NULL, '2019-09-22 18:24:21'), + ('system_config', '23', '', 1, NULL, '2019-09-24 09:04:42'), + ('system_config', '23', '', 1, NULL, '2019-10-15 11:06:12'), + ('system_config', '23', '', 1, NULL, '2019-10-15 11:22:10'), + ('system_config', '23', '', 1, NULL, '2019-10-15 16:42:16'), + ('system_config', '23', '', 1, NULL, '2019-10-19 15:18:54'), + ('system_config', '23', '', 1, NULL, '2019-10-19 16:50:10'), + ('system_config', '23', '', 1, NULL, '2019-10-21 15:52:25'), + ('system_config', '23', '', 1, NULL, '2019-10-23 10:24:38'), + ('system_config', '23', '', 1, NULL, '2019-10-23 10:28:45'), + ('system_config', '23', '', 1, NULL, '2019-10-23 16:35:45'), + ('system_config', '23', '', 1, NULL, '2019-10-23 16:38:48'), + ('system_config', '23', '', 1, NULL, '2019-10-25 08:52:22'), + ('system_config', '23', '', 1, NULL, '2019-10-28 16:04:30'), + ('system_config', '23', '', 1, NULL, '2019-10-30 19:59:24'), + ('system_config', '23', '', 1, NULL, '2019-10-31 14:29:26'), + ('system_config', '23', '', 1, NULL, '2019-10-31 14:35:38'), + ('system_config', '23', '', 1, NULL, '2019-10-31 15:58:39'), + ('system_config', '23', '', 1, NULL, '2019-10-31 17:34:48'), + ('system_config', '23', '', 1, NULL, '2019-11-01 11:23:26'), + ('system_config', '23', '', 1, NULL, '2019-11-01 14:55:34'), + ('system_config', '23', '', 1, NULL, '2019-11-02 08:49:44'), + ('system_config', '23', '', 1, NULL, '2019-11-02 09:40:52'), + ('system_config', '23', '', 1, NULL, '2019-11-02 09:42:48'), + ('system_config', '23', '', 1, NULL, '2019-11-02 09:47:38'), + ('system_config', '23', '', 1, NULL, '2019-11-02 09:50:57'), + ('system_config', '23', '', 1, NULL, '2019-11-02 09:51:32'), + ('system_config', '23', '', 1, NULL, '2019-11-02 09:51:48'), + ('system_config', '23', '', 1, NULL, '2019-11-02 15:48:21'), + ('system_config', '23', '', 1, NULL, '2019-11-02 20:48:44'), + ('system_config', '23', '', 1, NULL, '2019-11-02 21:27:50'), + ('system_config', '23', '', 1, NULL, '2019-11-03 22:10:32'), + ('system_config', '23', '', 1, NULL, '2019-11-03 22:10:32'), + ('system_config', '23', '', 1, NULL, '2019-11-04 09:10:24'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-05 10:24:51'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 11:22:42'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 11:25:54'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 11:27:04'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 11:28:00'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 11:34:06'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 11:34:43'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 11:53:11'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 11:56:05'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 13:52:39'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 15:29:29'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 16:05:36'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 16:06:13'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 16:13:22'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 16:19:38'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 16:21:37'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-06 16:22:23'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-08 08:50:08'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-08 13:37:34'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 08:35:08'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 08:54:38'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 09:00:32'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 09:01:24'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 09:24:16'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 09:26:46'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 09:43:13'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 09:44:48'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 10:28:30'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-09 11:24:19'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-11 09:40:42'), + ('system_config', '23', '4234234', 1, NULL, '2019-11-13 17:25:42'), + ('system_config', '23343', '2423', 1, NULL, '2019-11-13 20:29:19'), + ('system_config', '23343', '2423', 1, NULL, '2019-11-13 20:29:23'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 11:43:57'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 11:50:18'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 11:51:13'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 11:52:03'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 11:53:02'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 13:49:11'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 13:51:05'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 13:53:53'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 13:55:57'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 16:15:44'), + ('system_config', '23343', '234', 1, NULL, '2019-11-14 16:39:36'), + ('system_config', '23343234234', '234', 1, NULL, '2019-11-14 16:41:05'), + ('system_config', '23343234234', '234', 1, NULL, '2019-11-14 16:41:05'), + ('system_config', 'aaaa', '234', 1, NULL, '2019-11-14 16:41:20'), + ('system_config', 'aaaa', '234', 1, NULL, '2019-11-14 16:41:25'), + ('system_config', '111', '234', 1, NULL, '2019-11-14 16:43:20'), + ('system_config', '111', '234', 1, NULL, '2019-11-14 16:44:13'), + ('system_config', 'xxxx', '234', 1, NULL, '2019-11-14 16:46:26'), + ('system_config', 'xxxx', '234', 1, NULL, '2019-11-14 16:46:39'), + ('system_config', 'xxxx', '234', 1, NULL, '2019-11-14 16:48:47'), + ('system_config', 'xxxx', '234', 1, NULL, '2019-11-15 14:39:55'), + ('system_config', 'xxxx', '234', 1, NULL, '2019-11-16 08:47:43'), + ('system_config', 'xxxx', '234', 1, NULL, '2019-11-16 17:12:10'), + ('system_config', 'xxxx', '234', 1, NULL, '2019-11-16 18:02:57'); +/*!40000 ALTER TABLE `t_reload_result` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_role 结构 +DROP TABLE IF EXISTS `t_role`; +CREATE TABLE IF NOT EXISTS `t_role` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', + `role_name` varchar(20) NOT NULL COMMENT '角色名称', + `remark` varchar(255) DEFAULT NULL COMMENT '角色描述', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8 COMMENT='角色表'; + +-- 正在导出表 smart-admin-dev.t_role 的数据:~14 rows (大约) +DELETE FROM `t_role`; +/*!40000 ALTER TABLE `t_role` DISABLE KEYS */; +INSERT INTO `t_role` (`id`, `role_name`, `remark`, `update_time`, `create_time`) VALUES + (1, '管理员', '', '2019-06-21 12:09:34', '2019-06-21 12:09:34'), + (34, '销售', '', '2019-08-30 09:30:50', '2019-08-30 09:30:50'), + (35, '总经理', '', '2019-08-30 09:31:05', '2019-08-30 09:31:05'), + (36, '董事长', '', '2019-08-30 09:31:11', '2019-08-30 09:31:11'), + (37, '财务', '', '2019-08-30 09:31:16', '2019-08-30 09:31:16'), + (38, '运营', '', '2019-08-30 09:31:22', '2019-08-30 09:31:22'), + (40, '测试角色1', '测试角色1', '2019-09-05 15:05:38', '2019-09-05 15:05:38'), + (41, '测试角色2', '测试角色2', '2019-09-05 15:05:43', '2019-09-05 15:05:43'), + (42, '测试角色3', '测试角色3', '2019-09-05 15:05:49', '2019-09-05 15:05:49'), + (43, '测试角色4', '测试角色4', '2019-09-05 15:05:56', '2019-09-05 15:05:56'), + (45, '测试角色6', '测试角色6', '2019-09-05 15:06:06', '2019-09-05 15:06:06'), + (46, '测试角色7', '测试角色7', '2019-09-05 15:06:18', '2019-09-05 15:06:18'), + (47, '测试角色8', '测试角色8', '2019-09-05 15:06:25', '2019-09-05 15:06:25'), + (48, '测试角色9', '测试角色9', '2019-11-15 17:06:11', '2019-09-05 15:06:30'); +/*!40000 ALTER TABLE `t_role` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_role_data_scope 结构 +DROP TABLE IF EXISTS `t_role_data_scope`; +CREATE TABLE IF NOT EXISTS `t_role_data_scope` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `data_scope_type` int(11) NOT NULL COMMENT '数据范围id', + `view_type` int(11) NOT NULL COMMENT '数据范围类型', + `role_id` int(11) NOT NULL COMMENT '角色id', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 正在导出表 smart-admin-dev.t_role_data_scope 的数据:~4 rows (大约) +DELETE FROM `t_role_data_scope`; +/*!40000 ALTER TABLE `t_role_data_scope` DISABLE KEYS */; +INSERT INTO `t_role_data_scope` (`id`, `data_scope_type`, `view_type`, `role_id`, `update_time`, `create_time`) VALUES + (5, 0, 2, 9, '2019-04-29 15:01:04', '2019-04-29 15:01:04'), + (14, 0, 2, 40, '2019-09-05 15:25:37', '2019-09-05 15:25:37'), + (15, 0, 0, 1, '2019-09-06 08:35:45', '2019-09-06 08:35:45'), + (16, 0, 3, 34, '2019-11-06 16:08:02', '2019-11-06 16:08:02'); +/*!40000 ALTER TABLE `t_role_data_scope` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_role_employee 结构 +DROP TABLE IF EXISTS `t_role_employee`; +CREATE TABLE IF NOT EXISTS `t_role_employee` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `role_id` int(11) NOT NULL COMMENT '角色id', + `employee_id` int(11) NOT NULL COMMENT '员工id', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=214 DEFAULT CHARSET=utf8mb4 COMMENT='角色员工功能表'; + +-- 正在导出表 smart-admin-dev.t_role_employee 的数据:~25 rows (大约) +DELETE FROM `t_role_employee`; +/*!40000 ALTER TABLE `t_role_employee` DISABLE KEYS */; +INSERT INTO `t_role_employee` (`id`, `role_id`, `employee_id`, `update_time`, `create_time`) VALUES + (121, 38, 22, '2019-09-04 09:23:09', '2019-09-04 09:23:09'), + (130, 1, 30, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (131, 1, 17, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (132, 1, 26, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (135, 1, 12, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (136, 1, 11, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (137, 1, 16, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (138, 1, 18, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (139, 1, 19, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (140, 1, 20, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (141, 1, 23, '2019-09-05 15:32:40', '2019-09-05 15:32:40'), + (147, 1, 35, '2019-09-06 09:00:27', '2019-09-06 09:00:27'), + (148, 40, 35, '2019-09-06 09:00:27', '2019-09-06 09:00:27'), + (165, 40, 32, '2019-11-08 10:39:35', '2019-11-08 10:39:35'), + (166, 34, 32, '2019-11-08 10:39:35', '2019-11-08 10:39:35'), + (167, 38, 32, '2019-11-08 10:39:35', '2019-11-08 10:39:35'), + (168, 38, 36, '2019-11-08 10:40:16', '2019-11-08 10:40:16'), + (169, 40, 36, '2019-11-08 10:40:16', '2019-11-08 10:40:16'), + (170, 37, 36, '2019-11-08 10:40:16', '2019-11-08 10:40:16'), + (174, 38, 37, '2019-11-08 11:05:39', '2019-11-08 11:05:39'), + (175, 42, 37, '2019-11-08 11:05:39', '2019-11-08 11:05:39'), + (188, 1, 1, '2019-11-15 16:05:33', '2019-11-15 16:05:33'), + (211, 40, 38, '2019-11-15 16:54:54', '2019-11-15 16:54:54'), + (212, 34, 29, '2019-11-16 18:04:04', '2019-11-16 18:04:04'), + (213, 45, 29, '2019-11-16 18:04:04', '2019-11-16 18:04:04'); +/*!40000 ALTER TABLE `t_role_employee` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_role_privilege 结构 +DROP TABLE IF EXISTS `t_role_privilege`; +CREATE TABLE IF NOT EXISTS `t_role_privilege` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `role_id` int(11) NOT NULL COMMENT '角色id', + `privilege_key` varchar(1000) NOT NULL COMMENT '权限key', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=10835 DEFAULT CHARSET=utf8mb4 COMMENT='角色权限功能表'; + +-- 正在导出表 smart-admin-dev.t_role_privilege 的数据:~322 rows (大约) +DELETE FROM `t_role_privilege`; +/*!40000 ALTER TABLE `t_role_privilege` DISABLE KEYS */; +INSERT INTO `t_role_privilege` (`id`, `role_id`, `privilege_key`, `update_time`, `create_time`) VALUES + (3506, 48, 'search-position', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3507, 48, 'add-position', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3508, 48, 'update-position', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3509, 48, 'delete-position', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3510, 48, 'add-role', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3511, 48, 'delete-role', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3512, 48, 'update-role', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3513, 48, 'update-role-privilege', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3514, 48, 'add-employee-role', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3515, 48, 'delete-employee-role', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3516, 48, 'delete-employee-role-batch', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3517, 48, 'search-employee-list', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3518, 48, 'query-data-scope', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3519, 48, 'update-data-scope', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3520, 48, 'add-department', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3521, 48, 'update-department', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3522, 48, 'delete-department', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3523, 48, 'search-department', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3524, 48, 'add-employee', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3525, 48, 'update-employee', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3526, 48, 'delete-employee', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3527, 48, 'disabled-employee', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3528, 48, 'reset-employee-password', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3529, 48, 'set-employee-role', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3530, 48, 'disabled-employee-batch', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3531, 48, 'update-employee-role', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3533, 48, 'system-params-search', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3534, 48, 'system-params-add', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3535, 48, 'system-config-update', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3536, 48, 'system-config-search', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3537, 48, 'privilegeMainSearch', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3538, 48, 'privilegeMainUpdate', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3539, 48, 'task-search', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3540, 48, 'task-refresh', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3541, 48, 'task-add', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3542, 48, 'task-update', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3543, 48, 'task-pause', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3544, 48, 'task-resume', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3545, 48, 'task-run', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3546, 48, 'task-query-log', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3547, 48, 'task-delete', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3548, 48, 'systemCodeVersionsQuery', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3552, 48, 'roleOneTwo-add', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3555, 48, 'apiDocument', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3557, 48, 'reload', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3559, 48, 'smart-reload-search', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3560, 48, 'smart-reload-update', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3561, 48, 'smart-reload-result', '2019-09-06 15:28:07', '2019-09-06 15:28:07'), + (3575, 45, 'task-search', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3576, 45, 'task-refresh', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3577, 45, 'task-add', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3578, 45, 'task-update', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3579, 45, 'task-pause', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3580, 45, 'task-resume', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3581, 45, 'task-run', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3582, 45, 'task-query-log', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3583, 45, 'task-delete', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3586, 45, 'add-role', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3587, 45, 'delete-role', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3588, 45, 'update-role', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3589, 45, 'update-role-privilege', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3590, 45, 'add-employee-role', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3591, 45, 'delete-employee-role', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3592, 45, 'delete-employee-role-batch', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3593, 45, 'search-employee-list', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3594, 45, 'query-data-scope', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3595, 45, 'update-data-scope', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3597, 45, 'search-position', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3598, 45, 'add-position', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3599, 45, 'update-position', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3600, 45, 'delete-position', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3602, 45, 'add-department', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3603, 45, 'set-employee-role', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3604, 45, 'update-department', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3605, 45, 'delete-department', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3606, 45, 'search-department', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3607, 45, 'add-employee', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3608, 45, 'update-employee', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3609, 45, 'disabled-employee', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3610, 45, 'disabled-employee-batch', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3611, 45, 'update-employee-role', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3612, 45, 'delete-employee', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (3613, 45, 'reset-employee-password', '2019-09-06 15:28:17', '2019-09-06 15:28:17'), + (8112, 41, 'SystemSetting', '2019-11-08 11:21:22', '2019-11-08 11:21:22'), + (8113, 41, 'SystemPrivilege', '2019-11-08 11:21:22', '2019-11-08 11:21:22'), + (8114, 41, 'privilege-main-update', '2019-11-08 11:21:22', '2019-11-08 11:21:22'), + (8115, 41, 'privilege-main-search', '2019-11-08 11:21:22', '2019-11-08 11:21:22'), + (8549, 35, 'SystemSetting', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8550, 35, 'SystemConfig', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8551, 35, 'SystemPrivilege', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8552, 35, 'Notice', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8553, 35, 'NoticeList', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8554, 35, 'PersonNotice', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8555, 35, 'Email', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8556, 35, 'EmailList', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8557, 35, 'UserLog', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8558, 35, 'UserOperateLog', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8559, 35, 'UserLoginLog', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8560, 35, 'system-config-search', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8561, 35, 'privilege-main-update', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8562, 35, 'privilege-main-search', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8563, 35, 'notice-query', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8564, 35, 'notice-add', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8565, 35, 'notice-edit', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8566, 35, 'notice-delete', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8567, 35, 'person-notice-query', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8568, 35, 'person-notice-detail', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8569, 35, 'email-query', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8570, 35, 'email-add', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8571, 35, 'email-update', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8572, 35, 'user-operate-log-search', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8573, 35, 'user-login-log-search', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (8574, 35, 'system-config-update', '2019-11-15 15:47:52', '2019-11-15 15:47:52'), + (9005, 37, 'SystemSetting', '2019-11-15 16:33:09', '2019-11-15 16:33:09'), + (9006, 37, 'SystemConfig', '2019-11-15 16:33:09', '2019-11-15 16:33:09'), + (9007, 37, 'system-params-search', '2019-11-15 16:33:09', '2019-11-15 16:33:09'), + (9008, 37, 'system-params-add', '2019-11-15 16:33:09', '2019-11-15 16:33:09'), + (9009, 37, 'system-config-update', '2019-11-15 16:33:09', '2019-11-15 16:33:09'), + (9368, 34, 'SystemSetting', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9369, 34, 'SystemConfig', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9370, 34, 'SystemPrivilege', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9371, 34, 'system-params-search', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9372, 34, 'system-params-add', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9373, 34, 'privilege-main-search', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9374, 34, 'Task', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9375, 34, 'TaskList', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9376, 34, 'task-search', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9377, 34, 'task-refresh', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9378, 34, 'task-add', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9379, 34, 'task-update', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9380, 34, 'task-pause', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9381, 34, 'task-resume', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9382, 34, 'task-run', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9383, 34, 'task-query-log', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9384, 34, 'task-delete', '2019-11-15 16:45:39', '2019-11-15 16:45:39'), + (9536, 42, 'Task', '2019-11-15 16:50:40', '2019-11-15 16:50:40'), + (9537, 42, 'TaskList', '2019-11-15 16:50:40', '2019-11-15 16:50:40'), + (9538, 42, 'task-search', '2019-11-15 16:50:40', '2019-11-15 16:50:40'), + (9539, 42, 'task-add', '2019-11-15 16:50:40', '2019-11-15 16:50:40'), + (9540, 42, 'task-update', '2019-11-15 16:50:40', '2019-11-15 16:50:40'), + (9541, 42, 'task-query-log', '2019-11-15 16:50:40', '2019-11-15 16:50:40'), + (9674, 38, 'Employee', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9675, 38, 'PositionList', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9676, 38, 'SystemSetting', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9677, 38, 'SystemConfig', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9678, 38, 'Notice', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9679, 38, 'PersonNotice', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9680, 38, 'Email', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9681, 38, 'EmailList', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9682, 38, 'SendMail', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9683, 38, 'Monitor', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9684, 38, 'OnlineUser', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9685, 38, 'Task', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9686, 38, 'TaskList', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9687, 38, 'KeepAlive', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9688, 38, 'KeepAliveContentList', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9689, 38, 'HeartBeat', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9690, 38, 'HeartBeatList', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9691, 38, 'File', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9692, 38, 'FileList', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9693, 38, 'search-position', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9694, 38, 'system-params-search', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9695, 38, 'system-config-update', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9696, 38, 'system-config-search', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9697, 38, 'person-notice-query', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9698, 38, 'person-notice-detail', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9699, 38, 'email-query', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9700, 38, 'email-send', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9701, 38, 'online-user-search', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9702, 38, 'task-search', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9703, 38, 'heart-beat-query', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9704, 38, 'file-filePage-query', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9705, 38, 'file-filePage-upload', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (9706, 38, 'task-refresh', '2019-11-15 16:53:47', '2019-11-15 16:53:47'), + (10585, 40, 'Employee', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10586, 40, 'RoleManage', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10587, 40, 'PositionList', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10588, 40, 'RoleEmployeeManage', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10589, 40, 'SystemSetting', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10590, 40, 'SystemConfig', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10591, 40, 'SystemPrivilege', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10592, 40, 'Notice', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10593, 40, 'NoticeList', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10594, 40, 'PersonNotice', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10595, 40, 'Email', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10596, 40, 'SendMail', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10597, 40, 'Task', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10598, 40, 'TaskList', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10599, 40, 'add-role', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10600, 40, 'delete-role', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10601, 40, 'update-role', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10602, 40, 'update-role-privilege', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10603, 40, 'add-employee-role', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10604, 40, 'search-employee-list', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10605, 40, 'delete-employee-role', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10606, 40, 'delete-employee-role-batch', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10607, 40, 'query-data-scope', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10608, 40, 'update-data-scope', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10609, 40, 'search-position', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10610, 40, 'add-position', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10611, 40, 'update-position', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10612, 40, 'search-department', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10613, 40, 'system-params-add', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10614, 40, 'system-config-search', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10615, 40, 'privilege-main-search', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10616, 40, 'notice-query', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10617, 40, 'notice-add', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10618, 40, 'notice-edit', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10619, 40, 'notice-delete', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10620, 40, 'notice-detail', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10621, 40, 'notice-send', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10622, 40, 'person-notice-query', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10623, 40, 'email-send', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10624, 40, 'task-search', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10625, 40, 'task-refresh', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10626, 40, 'task-add', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10627, 40, 'task-update', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10628, 40, 'task-query-log', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10629, 40, 'task-delete', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10630, 40, 'delete-department', '2019-11-15 17:19:42', '2019-11-15 17:19:42'), + (10733, 1, 'Employee', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10734, 1, 'RoleManage', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10735, 1, 'PositionList', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10736, 1, 'RoleEmployeeManage', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10737, 1, 'SystemSetting', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10738, 1, 'SystemConfig', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10739, 1, 'SystemPrivilege', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10740, 1, 'Notice', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10741, 1, 'NoticeList', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10742, 1, 'PersonNotice', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10743, 1, 'Email', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10744, 1, 'EmailList', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10745, 1, 'SendMail', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10746, 1, 'UserLog', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10747, 1, 'UserOperateLog', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10748, 1, 'UserLoginLog', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10749, 1, 'Monitor', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10750, 1, 'OnlineUser', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10751, 1, 'Sql', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10752, 1, 'Task', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10753, 1, 'TaskList', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10754, 1, 'Reload', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10755, 1, 'SmartReloadList', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10756, 1, 'ApiDoc', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10757, 1, 'Swagger', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10758, 1, 'ThreeRouter', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10759, 1, 'LevelTwo', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10760, 1, 'RoleOneTwo', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10761, 1, 'RoleTwoTwo', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10762, 1, 'RoleOneOne', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10763, 1, 'KeepAlive', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10764, 1, 'KeepAliveContentList', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10765, 1, 'KeepAliveAddContent', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10766, 1, 'HeartBeat', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10767, 1, 'HeartBeatList', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10768, 1, 'File', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10769, 1, 'FileList', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10770, 1, 'add-role', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10771, 1, 'delete-role', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10772, 1, 'update-role', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10773, 1, 'update-role-privilege', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10774, 1, 'add-employee-role', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10775, 1, 'search-employee-list', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10776, 1, 'delete-employee-role', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10777, 1, 'delete-employee-role-batch', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10778, 1, 'query-data-scope', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10779, 1, 'update-data-scope', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10780, 1, 'search-position', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10781, 1, 'add-position', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10782, 1, 'update-position', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10783, 1, 'delete-position', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10784, 1, 'add-department', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10785, 1, 'update-department', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10786, 1, 'delete-department', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10787, 1, 'search-department', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10788, 1, 'add-employee', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10789, 1, 'update-employee', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10790, 1, 'disabled-employee', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10791, 1, 'disabled-employee-batch', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10792, 1, 'update-employee-role', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10793, 1, 'reset-employee-password', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10794, 1, 'delete-employee', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10795, 1, 'system-params-search', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10796, 1, 'system-params-add', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10797, 1, 'system-config-update', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10798, 1, 'system-config-search', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10799, 1, 'privilege-main-update', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10800, 1, 'privilege-main-search', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10801, 1, 'notice-query', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10802, 1, 'notice-add', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10803, 1, 'notice-edit', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10804, 1, 'notice-delete', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10805, 1, 'notice-detail', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10806, 1, 'notice-send', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10807, 1, 'person-notice-query', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10808, 1, 'person-notice-detail', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10809, 1, 'email-query', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10810, 1, 'email-add', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10811, 1, 'email-update', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10812, 1, 'email-delete', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10813, 1, 'email-send', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10814, 1, 'user-operate-log-search', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10815, 1, 'user-operate-log-detail', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10816, 1, 'user-operate-log-delete', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10817, 1, 'user-login-log-search', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10818, 1, 'user-login-log-delete', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10819, 1, 'online-user-search', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10820, 1, 'task-search', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10821, 1, 'task-refresh', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10822, 1, 'task-add', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10823, 1, 'task-update', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10824, 1, 'task-pause', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10825, 1, 'task-resume', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10826, 1, 'task-run', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10827, 1, 'task-query-log', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10828, 1, 'task-delete', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10829, 1, 'smart-reload-search', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10830, 1, 'smart-reload-update', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10831, 1, 'smart-reload-result', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10832, 1, 'heart-beat-query', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10833, 1, 'file-filePage-query', '2019-11-16 18:04:10', '2019-11-16 18:04:10'), + (10834, 1, 'file-filePage-upload', '2019-11-16 18:04:10', '2019-11-16 18:04:10'); +/*!40000 ALTER TABLE `t_role_privilege` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_system_config 结构 +DROP TABLE IF EXISTS `t_system_config`; +CREATE TABLE IF NOT EXISTS `t_system_config` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', + `config_name` varchar(255) NOT NULL COMMENT '参数名字', + `config_key` varchar(255) NOT NULL COMMENT '参数key', + `config_value` text NOT NULL, + `config_group` varchar(255) NOT NULL COMMENT '参数类别', + `is_using` int(10) NOT NULL COMMENT '是否使用0 否 1 是', + `remark` varchar(255) DEFAULT NULL, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '上次修改时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; + +-- 正在导出表 smart-admin-dev.t_system_config 的数据:~8 rows (大约) +DELETE FROM `t_system_config`; +/*!40000 ALTER TABLE `t_system_config` DISABLE KEYS */; +INSERT INTO `t_system_config` (`id`, `config_name`, `config_key`, `config_value`, `config_group`, `is_using`, `remark`, `update_time`, `create_time`) VALUES + (1, '超级管理员', 'employee_superman', '12,13,1', 'employee', 1, '123r8566456', '2019-11-14 16:40:48', '2018-08-18 16:28:03'), + (13, '本地上传URL前缀', 'local_upload_url_prefix', 'http://172.16.0.145/smartAdmin/file/', 'upload', 1, '', '2019-09-04 16:23:49', '2019-04-26 17:06:53'), + (14, '阿里云上传配置', 'ali_oss', '{"accessKeyId":"","accessKeySecret":"","bucketName":"sit","endpoint":"http://oss-cn-beijing.aliyuncs.com"}', 'upload', 1, 'eefwfwfds', '2019-11-16 18:04:30', '2019-05-11 18:00:06'), + (15, '邮件发配置', 'email_config', '{"password":"wy656112","smtpHost":"smtp.163.com","username":"simajq@163.com"}', 'email', 1, NULL, '2019-09-04 16:42:17', '2019-05-13 16:57:48'), + (16, '七牛云上传配置', 'qi_niu_oss', '{"accessKeyId":"rX7HgY1ZLpUD25JrA-uwMM_jj-","accessKeySecret":"","bucketName":"sun-smart-admin","endpoint":"http://puvpyay08.bkt.clouddn.com"}', 'upload', 1, NULL, '2019-11-16 18:04:42', '2019-07-19 16:05:56'), + (17, 'test', 'ww_1', 'ewr', '3', 1, 'testoo', '2019-11-08 09:43:36', '2019-11-08 09:27:19'), + (18, '4234', '42342', '423423', '23423', 1, '423423111111111111111111111111111111111111423423111111111111111111111111111111111111423423111111111111111111111111111111111111423423111111111111111111111111111111111111423423111111111111111111111111111111111111', '2019-11-14 14:58:39', '2019-11-14 11:22:49'), + (19, 'test323@', 'test', '123456', '11_', 1, 'gggggg', '2019-11-15 16:24:52', '2019-11-15 16:24:52'); +/*!40000 ALTER TABLE `t_system_config` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_user_login_log 结构 +DROP TABLE IF EXISTS `t_user_login_log`; +CREATE TABLE IF NOT EXISTS `t_user_login_log` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` int(11) NOT NULL COMMENT '员工id', + `user_name` varchar(50) NOT NULL COMMENT '用户名', + `remote_ip` varchar(50) DEFAULT NULL COMMENT '用户ip', + `remote_port` int(11) DEFAULT NULL COMMENT '用户端口', + `remote_browser` varchar(100) DEFAULT NULL COMMENT '浏览器', + `remote_os` varchar(50) DEFAULT NULL COMMENT '操作系统', + `login_status` tinyint(4) NOT NULL COMMENT '登录状态 0 失败 1成功', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `customer_id` (`user_id`) USING BTREE, + KEY `auditor_id` (`remote_browser`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=1742 DEFAULT CHARSET=utf8mb4 COMMENT='用户登录日志'; + +-- 正在导出表 smart-admin-dev.t_user_login_log 的数据:~122 rows (大约) +DELETE FROM `t_user_login_log`; +/*!40000 ALTER TABLE `t_user_login_log` DISABLE KEYS */; +INSERT INTO `t_user_login_log` (`id`, `user_id`, `user_name`, `remote_ip`, `remote_port`, `remote_browser`, `remote_os`, `login_status`, `update_time`, `create_time`) VALUES + (1501, 30, '耿为刚', '172.16.1.234', 61406, 'Chrome', 'Windows 10', 1, '2019-09-06 14:19:47', '2019-09-06 14:19:47'), + (1502, 30, '耿为刚', '172.16.1.234', 61405, 'Chrome', 'Windows 10', 1, '2019-09-06 14:20:46', '2019-09-06 14:20:46'), + (1503, 30, '耿为刚', '172.16.1.234', 62213, 'Chrome', 'Windows 10', 1, '2019-09-06 14:28:50', '2019-09-06 14:28:50'), + (1505, 30, '耿为刚', '172.16.1.234', 62478, 'Chrome', 'Windows 10', 1, '2019-09-06 14:32:57', '2019-09-06 14:32:57'), + (1506, 1, '管理员', '127.0.0.1', 55613, 'Chrome', 'Windows 10', 1, '2019-09-06 14:35:48', '2019-09-06 14:35:48'), + (1507, 1, '管理员', '172.16.1.234', 63132, 'Chrome', 'Windows 10', 1, '2019-09-06 14:38:43', '2019-09-06 14:38:43'), + (1508, 30, '耿为刚', '172.16.1.234', 63132, 'Chrome', 'Windows 10', 1, '2019-09-06 14:41:36', '2019-09-06 14:41:36'), + (1509, 1, '管理员', '172.16.1.234', 63332, 'Chrome', 'Windows 10', 1, '2019-09-06 14:42:37', '2019-09-06 14:42:37'), + (1511, 1, '管理员', '172.16.1.166', 29923, 'Chrome', 'Windows 10', 1, '2019-09-06 15:09:22', '2019-09-06 15:09:22'), + (1512, 1, '管理员', '172.16.1.113', 58150, 'Chrome', 'Windows 7', 1, '2019-09-06 15:23:31', '2019-09-06 15:23:31'), + (1513, 1, '管理员', '172.16.1.166', 31226, 'Chrome', 'Windows 10', 1, '2019-09-06 15:24:51', '2019-09-06 15:24:51'), + (1514, 1, '管理员', '172.16.1.113', 58300, 'Chrome', 'Windows 7', 1, '2019-09-06 15:25:04', '2019-09-06 15:25:04'), + (1515, 1, '管理员', '172.16.1.113', 58300, 'Chrome', 'Windows 7', 1, '2019-09-06 15:25:26', '2019-09-06 15:25:26'), + (1516, 1, '管理员', '172.16.1.166', 31243, 'Chrome', 'Windows 10', 1, '2019-09-06 15:25:29', '2019-09-06 15:25:29'), + (1517, 1, '管理员', '172.16.1.221', 61458, 'Chrome', 'Windows 10', 1, '2019-09-06 15:27:07', '2019-09-06 15:27:07'), + (1518, 1, '管理员', '172.16.1.166', 31243, 'Chrome', 'Windows 10', 1, '2019-09-06 15:27:09', '2019-09-06 15:27:09'), + (1519, 1, '管理员', '172.16.1.113', 58300, 'Chrome', 'Windows 7', 1, '2019-09-06 15:27:10', '2019-09-06 15:27:10'), + (1520, 1, '管理员', '172.16.1.166', 31551, 'Chrome', 'Windows 10', 1, '2019-09-06 15:30:01', '2019-09-06 15:30:01'), + (1521, 1, '管理员', '172.16.4.160', 50527, 'Chrome', 'Windows 10', 1, '2019-09-06 15:50:20', '2019-09-06 15:50:20'), + (1522, 1, '管理员', '172.16.1.166', 36381, 'Chrome', 'Windows 10', 1, '2019-09-06 16:20:46', '2019-09-06 16:20:46'), + (1523, 1, '管理员', '172.16.1.166', 40039, 'Chrome', 'Windows 10', 1, '2019-09-06 17:02:33', '2019-09-06 17:02:33'), + (1524, 1, '管理员', '172.16.1.166', 41014, 'Chrome', 'Windows 10', 1, '2019-09-06 17:16:09', '2019-09-06 17:16:09'), + (1525, 1, '管理员', '172.16.1.188', 56577, 'Chrome', 'Windows 7', 1, '2019-09-07 08:36:31', '2019-09-07 08:36:31'), + (1526, 1, '管理员', '172.16.1.48', 60852, 'Chrome', 'Windows 10', 1, '2019-09-07 08:45:02', '2019-09-07 08:45:02'), + (1527, 1, '管理员', '172.16.4.85', 4818, 'Chrome', 'Windows 10', 1, '2019-09-07 09:04:44', '2019-09-07 09:04:44'), + (1528, 1, '管理员', '172.16.4.85', 5230, 'Chrome', 'Windows 10', 1, '2019-09-07 09:25:41', '2019-09-07 09:25:41'), + (1529, 1, '管理员', '172.16.1.166', 10251, 'Chrome', 'Windows 10', 1, '2019-09-07 10:15:20', '2019-09-07 10:15:20'), + (1530, 1, '管理员', '172.16.1.48', 63877, 'Chrome', 'Windows 10', 1, '2019-09-07 11:26:19', '2019-09-07 11:26:19'), + (1531, 1, '管理员', '172.16.1.166', 26667, 'Chrome', 'Windows 10', 1, '2019-09-07 14:08:15', '2019-09-07 14:08:15'), + (1532, 1, '管理员', '172.16.4.85', 10604, 'Chrome', 'Windows 10', 1, '2019-09-07 14:08:33', '2019-09-07 14:08:33'), + (1533, 1, '管理员', '172.16.4.85', 10604, 'Chrome', 'Windows 10', 1, '2019-09-07 14:08:50', '2019-09-07 14:08:50'), + (1534, 1, '管理员', '172.16.1.166', 26812, 'Chrome', 'Windows 10', 1, '2019-09-07 14:14:09', '2019-09-07 14:14:09'), + (1535, 1, '管理员', '172.16.1.188', 52924, 'Chrome', 'Windows 7', 1, '2019-09-07 14:37:16', '2019-09-07 14:37:16'), + (1536, 1, '管理员', '172.16.1.188', 56721, 'Chrome', 'Windows 7', 1, '2019-09-07 14:49:37', '2019-09-07 14:49:37'), + (1537, 1, '管理员', '172.16.1.188', 52839, 'Chrome', 'Windows 7', 1, '2019-09-07 15:33:04', '2019-09-07 15:33:04'), + (1538, 1, '管理员', '172.16.1.166', 32489, 'Chrome', 'Windows 10', 1, '2019-09-07 15:48:02', '2019-09-07 15:48:02'), + (1539, 1, '管理员', '172.16.1.166', 32847, 'Chrome', 'Windows 10', 1, '2019-09-07 15:52:25', '2019-09-07 15:52:25'), + (1540, 1, '管理员', '172.16.1.166', 33456, 'Chrome', 'Windows 10', 1, '2019-09-07 16:00:01', '2019-09-07 16:00:01'), + (1541, 1, '管理员', '172.16.1.188', 61015, 'Chrome', 'Windows 7', 1, '2019-09-07 17:05:49', '2019-09-07 17:05:49'), + (1542, 1, '管理员', '127.0.0.1', 51566, 'Chrome', 'Windows 7', 1, '2019-09-07 17:31:20', '2019-09-07 17:31:20'), + (1543, 1, '管理员', '127.0.0.1', 54228, 'Chrome', 'Windows 7', 1, '2019-09-07 17:41:12', '2019-09-07 17:41:12'), + (1544, 1, '管理员', '127.0.0.1', 54957, 'Chrome', 'Windows 7', 1, '2019-09-07 17:43:21', '2019-09-07 17:43:21'), + (1545, 1, '管理员', '172.16.4.85', 2336, 'Chrome', 'Windows 10', 1, '2019-09-07 18:25:51', '2019-09-07 18:25:51'), + (1546, 1, '管理员', '127.0.0.1', 52161, 'Chrome', 'Windows 7', 1, '2019-09-09 08:30:47', '2019-09-09 08:30:47'), + (1547, 1, '管理员', '172.16.4.85', 5903, 'Chrome', 'Windows 10', 1, '2019-09-09 08:47:47', '2019-09-09 08:47:47'), + (1548, 1, '管理员', '172.16.1.243', 55673, 'Chrome', 'Windows 10', 1, '2019-09-09 11:25:02', '2019-09-09 11:25:02'), + (1549, 1, '管理员', '172.16.4.85', 4672, 'Chrome', 'Windows 10', 1, '2019-09-09 11:25:34', '2019-09-09 11:25:34'), + (1550, 1, '管理员', '172.16.1.188', 61186, 'Chrome', 'Windows 7', 1, '2019-09-09 11:39:24', '2019-09-09 11:39:24'), + (1551, 1, '管理员', '172.16.4.85', 3032, 'Chrome', 'Windows 10', 1, '2019-09-09 14:17:53', '2019-09-09 14:17:53'), + (1552, 1, '管理员', '172.16.4.85', 5829, 'Chrome', 'Windows 10', 1, '2019-09-09 14:54:27', '2019-09-09 14:54:27'), + (1553, 1, '管理员', '172.16.1.166', 23398, 'Chrome', 'Windows 10', 1, '2019-09-09 15:06:50', '2019-09-09 15:06:50'), + (1554, 1, '管理员', '172.16.5.60', 61094, 'Chrome', 'Windows 10', 1, '2019-09-09 15:20:50', '2019-09-09 15:20:50'), + (1555, 1, '管理员', '172.16.4.85', 10566, 'Chrome', 'Windows 10', 1, '2019-09-09 15:51:22', '2019-09-09 15:51:22'), + (1556, 1, '管理员', '172.16.1.166', 32190, 'Chrome', 'Windows 10', 1, '2019-09-09 17:00:59', '2019-09-09 17:00:59'), + (1557, 1, '管理员', '172.16.5.60', 54502, 'Chrome', 'Windows 10', 1, '2019-09-10 09:10:48', '2019-09-10 09:10:48'), + (1558, 1, '管理员', '172.16.4.85', 10659, 'Chrome', 'Windows 10', 1, '2019-09-10 09:21:48', '2019-09-10 09:21:48'), + (1559, 1, '管理员', '172.16.4.85', 3363, 'Chrome', 'Windows 10', 1, '2019-09-10 10:56:23', '2019-09-10 10:56:23'), + (1560, 1, '管理员', '172.16.4.85', 4460, 'Chrome', 'Windows 10', 1, '2019-09-10 14:23:44', '2019-09-10 14:23:44'), + (1561, 1, '管理员', '172.16.4.85', 7344, 'Chrome', 'Windows 10', 1, '2019-09-10 14:59:52', '2019-09-10 14:59:52'), + (1562, 1, '管理员', '172.16.5.89', 49996, 'Chrome', 'Windows 10', 1, '2019-09-10 18:08:04', '2019-09-10 18:08:04'), + (1563, 1, '管理员', '172.16.1.38', 50152, 'Chrome', 'Windows 10', 1, '2019-09-11 10:19:27', '2019-09-11 10:19:27'), + (1564, 1, '管理员', '172.16.1.38', 50173, 'Chrome', 'Windows 10', 1, '2019-09-11 10:20:38', '2019-09-11 10:20:38'), + (1565, 1, '管理员', '172.16.4.141', 60881, 'Chrome', 'Windows 10', 1, '2019-09-11 14:52:02', '2019-09-11 14:52:02'), + (1566, 1, '管理员', '172.16.4.93', 52688, 'Chrome', 'Windows 10', 1, '2019-09-11 15:15:14', '2019-09-11 15:15:14'), + (1567, 1, '管理员', '172.16.5.127', 54993, 'Chrome', 'Windows 10', 1, '2019-09-12 14:29:58', '2019-09-12 14:29:58'), + (1568, 1, '管理员', '172.16.5.127', 57424, 'Chrome', 'Windows 10', 1, '2019-09-12 15:26:46', '2019-09-12 15:26:46'), + (1569, 1, '管理员', '172.16.5.127', 58073, 'Chrome', 'Windows 10', 1, '2019-09-12 15:41:54', '2019-09-12 15:41:54'), + (1570, 1, '管理员', '172.16.5.146', 63230, 'Chrome', 'Windows 10', 1, '2019-09-16 10:17:15', '2019-09-16 10:17:15'), + (1571, 1, '管理员', '172.16.5.146', 52857, 'Chrome', 'Windows 10', 1, '2019-09-16 11:17:18', '2019-09-16 11:17:18'), + (1572, 1, '管理员', '172.16.1.190', 64527, 'Chrome', 'Windows 10', 1, '2019-09-19 14:06:45', '2019-09-19 14:06:45'), + (1573, 1, '管理员', '127.0.0.1', 53267, 'Chrome', 'Windows 7', 1, '2019-09-20 17:24:33', '2019-09-20 17:24:33'), + (1574, 1, '管理员', '127.0.0.1', 53267, 'Chrome', 'Windows 7', 1, '2019-09-20 17:24:43', '2019-09-20 17:24:43'), + (1575, 1, '管理员', '127.0.0.1', 53267, 'Chrome', 'Windows 7', 1, '2019-09-20 17:24:59', '2019-09-20 17:24:59'), + (1576, 1, '管理员', '127.0.0.1', 53267, 'Chrome', 'Windows 7', 1, '2019-09-20 17:26:05', '2019-09-20 17:26:05'), + (1577, 1, '管理员', '127.0.0.1', 60612, 'Chrome', 'Windows 7', 1, '2019-09-20 17:56:06', '2019-09-20 17:56:06'), + (1578, 1, '管理员', '172.16.1.202', 58066, 'Chrome', 'Windows 7', 1, '2019-09-22 18:25:03', '2019-09-22 18:25:03'), + (1579, 1, '管理员', '172.16.1.48', 52290, 'Chrome', 'Windows 10', 1, '2019-09-23 16:01:16', '2019-09-23 16:01:16'), + (1580, 1, '管理员', '172.16.4.141', 60997, 'Chrome', 'Windows 10', 1, '2019-09-23 17:16:55', '2019-09-23 17:16:55'), + (1581, 1, '管理员', '172.16.5.146', 53246, 'Chrome', 'Windows 10', 1, '2019-09-23 17:54:14', '2019-09-23 17:54:14'), + (1582, 1, '管理员', '127.0.0.1', 51987, 'Chrome', 'Windows 7', 1, '2019-09-24 09:16:37', '2019-09-24 09:16:37'), + (1583, 1, '管理员', '172.16.1.202', 55724, 'Chrome', 'Windows 7', 1, '2019-09-24 12:57:39', '2019-09-24 12:57:39'), + (1584, 1, '管理员', '172.16.1.166', 51876, 'Chrome', 'Windows 10', 1, '2019-09-24 16:24:37', '2019-09-24 16:24:37'), + (1585, 1, '管理员', '172.16.1.202', 51648, 'Chrome', 'Windows 7', 1, '2019-09-24 19:26:39', '2019-09-24 19:26:39'), + (1586, 1, '管理员', '172.16.1.234', 60984, 'Chrome', 'Windows 10', 1, '2019-09-26 10:52:07', '2019-09-26 10:52:07'), + (1587, 1, '管理员', '172.16.1.234', 63440, 'Chrome', 'Windows 10', 1, '2019-09-26 11:30:54', '2019-09-26 11:30:54'), + (1588, 1, '管理员', '172.16.1.202', 51956, 'Chrome', 'Windows 7', 1, '2019-09-27 20:55:08', '2019-09-27 20:55:08'), + (1589, 1, '管理员', '172.16.1.48', 56166, 'Chrome', 'Windows 10', 1, '2019-09-30 08:59:13', '2019-09-30 08:59:13'), + (1590, 1, '管理员', '172.16.1.202', 51448, 'Chrome', 'Windows 7', 1, '2019-09-30 09:00:13', '2019-09-30 09:00:13'), + (1591, 1, '管理员', '172.16.1.188', 62679, 'Chrome', 'Windows 7', 1, '2019-10-15 11:25:26', '2019-10-15 11:25:26'), + (1592, 1, '管理员', '172.16.1.234', 54034, 'Chrome', 'Windows 10', 1, '2019-10-18 10:47:14', '2019-10-18 10:47:14'), + (1593, 1, '管理员', '172.16.1.234', 64515, 'Chrome', 'Windows 10', 1, '2019-10-18 13:32:10', '2019-10-18 13:32:10'), + (1594, 1, '管理员', '172.16.1.234', 50211, 'Chrome', 'Windows 10', 1, '2019-10-18 13:56:19', '2019-10-18 13:56:19'), + (1595, 1, '管理员', '172.16.1.234', 55469, 'Chrome', 'Windows 10', 1, '2019-10-18 14:56:24', '2019-10-18 14:56:24'), + (1596, 1, '管理员', '172.16.1.234', 56392, 'Chrome', 'Windows 10', 1, '2019-10-18 15:08:25', '2019-10-18 15:08:25'), + (1597, 1, '管理员', '172.16.1.234', 60896, 'Chrome', 'Windows 10', 1, '2019-10-18 16:14:15', '2019-10-18 16:14:15'), + (1598, 1, '管理员', '172.16.1.234', 50590, 'Chrome', 'Windows 10', 1, '2019-10-19 08:38:54', '2019-10-19 08:38:54'), + (1599, 1, '管理员', '172.16.1.166', 4879, 'Chrome', 'Windows 10', 1, '2019-10-19 09:19:08', '2019-10-19 09:19:08'), + (1600, 1, '管理员', '172.16.1.188', 62895, 'Chrome', 'Windows 7', 1, '2019-10-19 13:49:29', '2019-10-19 13:49:29'), + (1601, 1, '管理员', '172.16.1.234', 58144, 'Chrome', 'Windows 10', 1, '2019-10-19 14:55:50', '2019-10-19 14:55:50'), + (1602, 1, '管理员', '127.0.0.1', 61033, 'Chrome', 'Windows 7', 1, '2019-10-19 15:19:38', '2019-10-19 15:19:38'), + (1603, 1, '管理员', '172.16.1.188', 58944, 'Chrome', 'Windows 7', 1, '2019-10-19 16:48:49', '2019-10-19 16:48:49'), + (1604, 1, '管理员', '172.16.1.188', 63950, 'Chrome', 'Windows 7', 1, '2019-10-21 08:10:38', '2019-10-21 08:10:38'), + (1605, 1, '管理员', '172.16.1.188', 64899, 'Chrome', 'Windows 7', 1, '2019-10-21 08:17:40', '2019-10-21 08:17:40'), + (1606, 1, '管理员', '172.16.1.221', 53180, 'Chrome', 'Windows 10', 1, '2019-10-21 15:52:36', '2019-10-21 15:52:36'), + (1607, 1, '管理员', '172.16.1.221', 56067, 'Chrome', 'Windows 10', 1, '2019-10-23 10:19:39', '2019-10-23 10:19:39'), + (1608, 1, '管理员', '172.16.1.221', 57692, 'Chrome', 'Windows 10', 1, '2019-10-23 16:36:39', '2019-10-23 16:36:39'), + (1609, 1, '管理员', '172.16.1.188', 57180, 'Chrome', 'Windows 7', 1, '2019-10-24 08:26:21', '2019-10-24 08:26:21'), + (1610, 1, '管理员', '172.16.0.196', 61409, 'Chrome', 'Windows 10', 1, '2019-10-24 08:26:55', '2019-10-24 08:26:55'), + (1611, 1, '管理员', '172.16.1.234', 51906, 'Chrome', 'Windows 10', 1, '2019-10-24 15:56:50', '2019-10-24 15:56:50'), + (1612, 1, '管理员', '172.16.1.234', 56793, 'Chrome', 'Windows 10', 1, '2019-10-24 17:04:54', '2019-10-24 17:04:54'), + (1613, 30, '耿为刚', '172.16.1.234', 60368, 'Chrome', 'Windows 10', 1, '2019-10-24 17:51:13', '2019-10-24 17:51:13'), + (1614, 1, '管理员', '172.16.1.234', 60368, 'Chrome', 'Windows 10', 1, '2019-10-24 17:51:56', '2019-10-24 17:51:56'), + (1615, 30, '耿为刚', '172.16.1.234', 60589, 'Chrome 65', 'Windows 10', 1, '2019-10-24 17:52:52', '2019-10-24 17:52:52'), + (1616, 1, '管理员', '172.16.1.234', 52998, 'Chrome', 'Windows 10', 1, '2019-10-25 09:28:13', '2019-10-25 09:28:13'), + (1617, 1, '管理员', '172.16.1.234', 54948, 'Chrome', 'Windows 10', 1, '2019-10-25 10:01:34', '2019-10-25 10:01:34'), + (1618, 1, '管理员', '172.16.1.234', 56800, 'Chrome', 'Windows 10', 1, '2019-10-25 10:32:53', '2019-10-25 10:32:53'), + (1619, 1, '管理员', '127.0.0.1', 59071, 'Chrome', 'Windows 7', 1, '2019-10-28 16:05:21', '2019-10-28 16:05:21'), + (1620, 1, '管理员', '127.0.0.1', 60106, 'Chrome', 'Windows 7', 1, '2019-10-28 16:11:29', '2019-10-28 16:11:29'), + (1621, 1, '管理员', '127.0.0.1', 63479, 'Chrome', 'Windows 7', 1, '2019-10-28 16:28:59', '2019-10-28 16:28:59'), + (1622, 1, '管理员', '127.0.0.1', 63479, 'Chrome', 'Windows 7', 1, '2019-10-28 16:29:55', '2019-10-28 16:29:55'), + (1623, 1, '管理员', '127.0.0.1', 57588, 'Chrome', 'Windows 7', 1, '2019-10-29 15:37:03', '2019-10-29 15:37:03'), + (1741, 1, '管理员', '127.0.0.1', 54621, 'Chrome', 'Windows 7', 1, '2019-11-16 18:03:45', '2019-11-16 18:03:45'); +/*!40000 ALTER TABLE `t_user_login_log` ENABLE KEYS */; + +-- 导出 表 smart-admin-dev.t_user_operate_log 结构 +DROP TABLE IF EXISTS `t_user_operate_log`; +CREATE TABLE IF NOT EXISTS `t_user_operate_log` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` int(11) NOT NULL COMMENT '用户id', + `user_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名称', + `module` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '操作模块', + `content` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '操作内容', + `url` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '请求路径', + `method` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '请求方法', + `param` text COLLATE utf8mb4_unicode_ci COMMENT '请求参数', + `result` tinyint(4) DEFAULT NULL COMMENT '请求结果 0失败 1成功', + `fail_reason` longtext COLLATE utf8mb4_unicode_ci COMMENT '失败原因', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 正在导出表 smart-admin-dev.t_user_operate_log 的数据:~32 rows (大约) +DELETE FROM `t_user_operate_log`; +/*!40000 ALTER TABLE `t_user_operate_log` DISABLE KEYS */; +INSERT INTO `t_user_operate_log` (`id`, `user_id`, `user_name`, `module`, `content`, `url`, `method`, `param`, `result`, `fail_reason`, `update_time`, `create_time`) VALUES + (1, 1, '管理员', '管理端-角色权限', '获取角色可选的功能权限', '/smart-admin-api/privilege/listPrivilegeByRoleId/0', 'com.gangquan360.smartadmin.module.role.roleprivilege.RolePrivilegeController.listPrivilegeByRoleId', 'Long[0]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (2, 1, '管理员', '管理端-角色', '获取所有角色', '/smart-admin-api/role/getAll', 'com.gangquan360.smartadmin.module.role.basic.RoleController.getAllRole', '', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (3, 1, '管理员', '管理端-角色权限', '获取角色可选的功能权限', '/smart-admin-api/privilege/listPrivilegeByRoleId/1', 'com.gangquan360.smartadmin.module.role.roleprivilege.RolePrivilegeController.listPrivilegeByRoleId', 'Long[1]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (4, 1, '管理员', '管理端-岗位', '分页查询所有岗位', '/smart-admin-api/position/getListPage', 'com.gangquan360.smartadmin.module.position.PositionController.getJobPage', 'PositionQueryDTO[{"pageNum":1,"pageSize":10,"positionName":"","searchCount":true,"sort":false}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (5, 1, '管理员', '管理端-角色', '获取所有角色', '/smart-admin-api/role/getAll', 'com.gangquan360.smartadmin.module.role.basic.RoleController.getAllRole', '', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (6, 1, '管理员', '管理端-部门', '根据部门名称查询部门及员工列表', '/smart-admin-api/department/listEmployeeByDepartmentName', 'com.gangquan360.smartadmin.module.department.DepartmentController.listDepartmentEmployee', 'String[""]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (7, 1, '管理员', '管理端-部门', '查询部门及员工列表', '/smart-admin-api/department/listEmployee', 'com.gangquan360.smartadmin.module.department.DepartmentController.listDepartmentEmployee', '', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (8, 1, '管理员', '管理端-用户', '员工管理查询', '/smart-admin-api/employee/query', 'com.gangquan360.smartadmin.module.employee.EmployeeController.query', 'EmployeeQueryDTO[{"isDelete":0,"isDisabled":0,"keyword":"","pageNum":1,"pageSize":10}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (9, 1, '管理员', '管理端-用户', '员工重置密码', '/smart-admin-api/employee/resetPasswd/29', 'com.gangquan360.smartadmin.module.employee.EmployeeController.resetPasswd', 'Integer[29]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (10, 1, '管理员', '管理端-用户', '员工管理查询', '/smart-admin-api/employee/query', 'com.gangquan360.smartadmin.module.employee.EmployeeController.query', 'EmployeeQueryDTO[{"isDelete":0,"isDisabled":0,"keyword":"","pageNum":1,"pageSize":10}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (11, 1, '管理员', '管理端-角色用户', '通过员工id获取所有角色以及员工具有的角色', '/smart-admin-api/role/getRoles/29', 'com.gangquan360.smartadmin.module.role.roleemployee.RoleEmployeeController.getRoleByEmployeeId', 'Long[29]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (12, 1, '管理员', '管理端-用户', '单个员工角色授权', '/smart-admin-api/employee/updateRoles', 'com.gangquan360.smartadmin.module.employee.EmployeeController.updateRoles', 'EmployeeUpdateRolesDTO[{"employeeId":29,"roleIds":[34,45]}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (13, 1, '管理员', '管理端-用户', '员工管理查询', '/smart-admin-api/employee/query', 'com.gangquan360.smartadmin.module.employee.EmployeeController.query', 'EmployeeQueryDTO[{"isDelete":0,"isDisabled":0,"keyword":"","pageNum":1,"pageSize":10}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (14, 1, '管理员', '管理端-角色权限', '更新角色权限', '/smart-admin-api/privilege/updateRolePrivilege', 'com.gangquan360.smartadmin.module.role.roleprivilege.RolePrivilegeController.updateRolePrivilege', 'RolePrivilegeDTO[{"privilegeKeyList":["Employee","RoleManage","PositionList","RoleEmployeeManage","SystemSetting","SystemConfig","SystemPrivilege","Notice","NoticeList","PersonNotice","Email","EmailList","SendMail","UserLog","UserOperateLog","UserLoginLog","Monitor","OnlineUser","Sql","Task","TaskList","Reload","SmartReloadList","ApiDoc","Swagger","ThreeRouter","LevelTwo","RoleOneTwo","RoleTwoTwo","RoleOneOne","KeepAlive","KeepAliveContentList","KeepAliveAddContent","HeartBeat","HeartBeatList","File","FileList","add-role","delete-role","update-role","update-role-privilege","add-employee-role","search-employee-list","delete-employee-role","delete-employee-role-batch","query-data-scope","update-data-scope","search-position","add-position","update-position","delete-position","add-department","update-department","delete-department","search-department","add-employee","update-employee","disabled-employee","disabled-employee-batch","update-employee-role","reset-employee-password","delete-employee","system-params-search","system-params-add","system-config-update","system-config-search","privilege-main-update","privilege-main-search","notice-query","notice-add","notice-edit","notice-delete","notice-detail","notice-send","person-notice-query","person-notice-detail","email-query","email-add","email-update","email-delete","email-send","user-operate-log-search","user-operate-log-detail","user-operate-log-delete","user-login-log-search","user-login-log-delete","online-user-search","task-search","task-refresh","task-add","task-update","task-pause","task-resume","task-run","task-query-log","task-delete","smart-reload-search","smart-reload-update","smart-reload-result","heart-beat-query","file-filePage-query","file-filePage-upload"],"roleId":1}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (15, 1, '管理员', '管理端-角色权限', '获取角色可选的功能权限', '/smart-admin-api/privilege/listPrivilegeByRoleId/1', 'com.gangquan360.smartadmin.module.role.roleprivilege.RolePrivilegeController.listPrivilegeByRoleId', 'Long[1]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (16, 1, '管理员', '管理端-系统配置', '分页查询所有系统配置', '/smart-admin-api/systemConfig/getListPage', 'com.gangquan360.smartadmin.module.systemconfig.SystemConfigController.getSystemConfigPage', 'SystemConfigQueryDTO[{"key":"","pageNum":1,"pageSize":10}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (17, 1, '管理员', '管理端-系统配置', '修改配置参数', '/smart-admin-api/systemConfig/update', 'com.gangquan360.smartadmin.module.systemconfig.SystemConfigController.updateSystemConfig', 'SystemConfigUpdateDTO[{"configGroup":"upload","configKey":"ali_oss","configName":"阿里云上传配置","configValue":"{\\"accessKeyId\\":\\"\\",\\"accessKeySecret\\":\\"\\",\\"bucketName\\":\\"sit\\",\\"endpoint\\":\\"http://oss-cn-beijing.aliyuncs.com\\"}","id":14,"remark":"eefwfwfds"}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (18, 1, '管理员', '管理端-系统配置', '分页查询所有系统配置', '/smart-admin-api/systemConfig/getListPage', 'com.gangquan360.smartadmin.module.systemconfig.SystemConfigController.getSystemConfigPage', 'SystemConfigQueryDTO[{"key":"","pageNum":1,"pageSize":10}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (19, 1, '管理员', '管理端-系统配置', '修改配置参数', '/smart-admin-api/systemConfig/update', 'com.gangquan360.smartadmin.module.systemconfig.SystemConfigController.updateSystemConfig', 'SystemConfigUpdateDTO[{"configGroup":"upload","configKey":"qi_niu_oss","configName":"七牛云上传配置","configValue":"{\\"accessKeyId\\":\\"rX7HgY1ZLpUD25JrA-uwMM_jj-\\",\\"accessKeySecret\\":\\"\\",\\"bucketName\\":\\"sun-smart-admin\\",\\"endpoint\\":\\"http://puvpyay08.bkt.clouddn.com\\"}","id":16}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (20, 1, '管理员', '管理端-系统配置', '分页查询所有系统配置', '/smart-admin-api/systemConfig/getListPage', 'com.gangquan360.smartadmin.module.systemconfig.SystemConfigController.getSystemConfigPage', 'SystemConfigQueryDTO[{"key":"","pageNum":1,"pageSize":10}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (21, 1, '管理员', '通用-权限', '获取所有请求路径', '/smart-admin-api/privilege/getAllUrl', 'com.gangquan360.smartadmin.module.privilege.controller.PrivilegeController.getAllUrl', '', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (22, 1, '管理员', '通用-权限', '查询所有菜单项', '/smart-admin-api/privilege/menu/queryAll', 'com.gangquan360.smartadmin.module.privilege.controller.PrivilegeController.queryAll', '', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (23, 1, '管理员', '通用-权限', '查询菜单功能点', '/smart-admin-api/privilege/function/query/FileList', 'com.gangquan360.smartadmin.module.privilege.controller.PrivilegeController.functionQuery', 'String["FileList"]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (24, 1, '管理员', '通用-权限', '保存更新功能点', '/smart-admin-api/privilege/function/saveOrUpdate', 'com.gangquan360.smartadmin.module.privilege.controller.PrivilegeController.functionSaveOrUpdate', 'PrivilegeFunctionDTO[{"functionKey":"file-filePage-download","functionName":"下载","menuKey":"FileList","sort":2,"url":"fileController.downLoadById"}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (25, 1, '管理员', '通用-权限', '查询菜单功能点', '/smart-admin-api/privilege/function/query/FileList', 'com.gangquan360.smartadmin.module.privilege.controller.PrivilegeController.functionQuery', 'String["FileList"]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (26, 1, '管理员', '通用-邮件发送', '分页查询', '/smart-admin-api/email/page/query', 'com.gangquan360.smartadmin.module.email.EmailController.queryByPage', 'EmailQueryDTO[{"endDate":"","pageNum":1,"pageSize":10,"searchCount":true,"startDate":""}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (27, 1, '管理员', '管理端-用户操作日志', '分页查询', '/smart-admin-api/userOperateLog/page/query', 'com.gangquan360.smartadmin.module.log.useroperatelog.UserOperateLogController.queryByPage', 'UserOperateLogQueryDTO[{"endDate":"","pageNum":1,"pageSize":10,"searchCount":true,"sort":false,"startDate":"","userName":""}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (28, 1, '管理员', '管理端-用户登录日志', '分页查询用户登录日志', '/smart-admin-api/userLoginLog/page/query', 'com.gangquan360.smartadmin.module.log.userloginlog.UserLoginLogController.queryByPage', 'UserLoginLogQueryDTO[{"endDate":"","pageNum":1,"pageSize":10,"searchCount":true,"sort":false,"startDate":"","userName":""}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (29, 1, '管理员', '管理端-用户登录日志', '查询员工在线状态', '/smart-admin-api/userOnLine/query', 'com.gangquan360.smartadmin.module.log.userloginlog.UserLoginLogController.queryUserOnLine', 'EmployeeQueryDTO[{"actualName":"","employeeIds":[1],"isDelete":0,"pageNum":1,"pageSize":10}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (30, 1, '管理员', '管理端-任务调度', '查询任务', '/smart-admin-api/quartz/task/query', 'com.gangquan360.smartadmin.module.quartz.controller.QuartzController.query', 'QuartzQueryDTO[{"pageNum":1,"pageSize":10}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (31, 1, '管理员', '管理端-smart reload', '获取全部Smart-reload项', '/smart-admin-api/smartReload/all', 'com.gangquan360.smartadmin.module.smartreload.SmartReloadController.listAllReloadItem', '', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'), + (32, 1, '管理员', '通用-心跳服务', '查询心跳记录 @author zhuoda', '/smart-admin-api/heartBeat/query', 'com.gangquan360.smartadmin.module.heartbeat.HeartBeatController.query', 'PageParamDTO[{"pageNum":1,"pageSize":10}]', 1, NULL, '2019-11-01 00:00:00', '2019-11-01 00:00:00'); +/*!40000 ALTER TABLE `t_user_operate_log` ENABLE KEYS */; + +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/java/smart-admin-api/src/main/resources/templates/codegenerator/Controller.java.vm b/java/smart-admin-api/src/main/resources/templates/codegenerator/Controller.java.vm new file mode 100644 index 00000000..a04de01b --- /dev/null +++ b/java/smart-admin-api/src/main/resources/templates/codegenerator/Controller.java.vm @@ -0,0 +1,64 @@ +package ${basePackage}.module.${modulePackage}.controller; + +import ${basePackage}.common.constant.SwaggerTagConst; +import ${basePackage}.common.domain.PageInfoDTO; +import ${basePackage}.common.domain.ResponseDTO; +import ${basePackage}.module.${modulePackage}.domain.dto.${moduleClass}DTO; +import ${basePackage}.module.${modulePackage}.domain.dto.${moduleClass}QueryDTO; +import ${basePackage}.module.${modulePackage}.service.${moduleClass}Service; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * [ ${tableDesc} ] + * + * @author ${author} + * @version 1.0 + * @company ${company} + * @copyright (c) 2019 ${company}Inc. All rights reserved. + * @date ${date} + * @since JDK1.8 + */ +@RestController +@Api(tags = {"${tableDesc}"}) +public class ${moduleClass}Controller { + + @Autowired + private ${moduleClass}Service ${moduleVar}Service; + + @ApiOperation(value = "分页查询${tableDesc}",notes = "@author ${author}") + @PostMapping("/${moduleVar}/page/query") + public ResponseDTO> queryByPage(@RequestBody ${moduleClass}QueryDTO queryDTO) { + return ${moduleVar}Service.queryByPage(queryDTO); + } + + @ApiOperation(value = "添加${tableDesc}",notes = "@author ${author}") + @PostMapping("/${moduleVar}/add") + public ResponseDTO add(@RequestBody @Valid ${moduleClass}DTO addTO){ + return ${moduleVar}Service.add(addTO); + } + + @ApiOperation(value="修改${tableDesc}",notes = "@author ${author}") + @PostMapping("/${moduleVar}/update") + public ResponseDTO update(@RequestBody @Valid ${moduleClass}DTO updateDTO){ + return ${moduleVar}Service.update(updateDTO); + } + + + @ApiOperation(value="删除${tableDesc}",notes = "@author ${author}") + @GetMapping("/${moduleVar}/delete/{id}") + public ResponseDTO delete(@PathVariable("id") Long id){ + return ${moduleVar}Service.delete(id); + } + + + @ApiOperation(value="详情${tableDesc}",notes = "@author ${author}") + @GetMapping("/${moduleVar}/detail/{id}") + public ResponseDTO<${moduleClass}DTO> detail(@PathVariable("id") Long id){ + return ${moduleVar}Service.detail(id); + } +} diff --git a/java/smart-admin-api/src/main/resources/templates/codegenerator/DTO.java.vm b/java/smart-admin-api/src/main/resources/templates/codegenerator/DTO.java.vm new file mode 100644 index 00000000..fa4e8d18 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/templates/codegenerator/DTO.java.vm @@ -0,0 +1,34 @@ +package ${basePackage}.module.${modulePackage}.domain.dto; +import lombok.Data; +#foreach ($dtoImport in $dtoImports) +$dtoImport +#end +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; + +/** + * [ ${tableDesc} ] + * + * @author ${author} + * @version 1.0 + * @company ${company} + * @copyright (c) 2018 ${company}Inc. All rights reserved. + * @date 2019/3/27 0027 下午 12:27 + * @since JDK1.8 + */ +@Data +public class ${moduleClass}DTO { + +#foreach ($column in $columnList) +#if($column.fieldType == 'Date') + @ApiModelProperty("${column.columnDesc}") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private $column.fieldType $column.fieldName; +#else + @ApiModelProperty("${column.columnDesc}") + private $column.fieldType $column.fieldName; +#end + +#end + +} diff --git a/java/smart-admin-api/src/main/resources/templates/codegenerator/Dao.java.vm b/java/smart-admin-api/src/main/resources/templates/codegenerator/Dao.java.vm new file mode 100644 index 00000000..c491c70d --- /dev/null +++ b/java/smart-admin-api/src/main/resources/templates/codegenerator/Dao.java.vm @@ -0,0 +1,48 @@ +package ${basePackage}.module.${modulePackage}.dao; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.baomidou.mybatisplus.plugins.pagination.Pagination; +import ${basePackage}.module.${modulePackage}.domain.dto.${moduleClass}QueryDTO; +import ${basePackage}.module.${modulePackage}.domain.entity.${moduleClass}Entity; +import ${basePackage}.utils.PaginationUtil; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * [ ${tableDesc} ] + * + * @author ${author} + * @version 1.0 + * @company ${company} + * @copyright (c) 2018 ${company}Inc. All rights reserved. + * @date ${date} + * @since JDK1.8 + */ +@Mapper +@Component +public interface ${moduleClass}Dao extends BaseMapper<${moduleClass}Entity> { + + /** + * 分页查询 + * @param queryDTO + * @return ${moduleClass}Entity + */ + List<${moduleClass}Entity> queryByPage(Pagination page, @Param("queryDTO") ${moduleClass}QueryDTO queryDTO); + + /** + * 根据id删除 + * @param id + * @return + */ + void deleteById(@Param("id") Long id); + + /** + * 批量删除 + * @param idList + * @return + */ + void deleteByIds(@Param("idList") List idList); +} diff --git a/java/smart-admin-api/src/main/resources/templates/codegenerator/Dao.xml.vm b/java/smart-admin-api/src/main/resources/templates/codegenerator/Dao.xml.vm new file mode 100644 index 00000000..f41cff53 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/templates/codegenerator/Dao.xml.vm @@ -0,0 +1,77 @@ + + + + + + + + + + + delete from ${tableName} where id = #{id} + + + + delete from ${tableName} where id in + + #{item} + + + + \ No newline at end of file diff --git a/java/smart-admin-api/src/main/resources/templates/codegenerator/Entity.java.vm b/java/smart-admin-api/src/main/resources/templates/codegenerator/Entity.java.vm new file mode 100644 index 00000000..fc07de61 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/templates/codegenerator/Entity.java.vm @@ -0,0 +1,35 @@ +package ${basePackage}.module.${modulePackage}.domain.entity; +import com.baomidou.mybatisplus.annotations.TableName; +import com.gangquan360.smartadmin.common.domain.BaseEntity; +#foreach ($entityImport in $entityImports) +$entityImport +#end +import lombok.Data; + +import java.io.Serializable; + +/** + * [ ${tableDesc} ] + * + * @author ${author} + * @version 1.0 + * @company ${company} + * @copyright (c) 2018 ${company}Inc. All rights reserved. + * @date ${date} + * @since JDK1.8 + */ +@Data +@TableName("${tableName}") +public class ${moduleClass}Entity extends BaseEntity{ + +#foreach ($column in $columnList) + +#if($column.columnName != 'id' && $column.fieldName != 'updateTime' && $column.fieldName != 'createTime') + /** + * $column.columnDesc + */ + private $column.fieldType $column.fieldName; +#end +#end + +} diff --git a/java/smart-admin-api/src/main/resources/templates/codegenerator/QueryDTO.java.vm b/java/smart-admin-api/src/main/resources/templates/codegenerator/QueryDTO.java.vm new file mode 100644 index 00000000..8ebf55bf --- /dev/null +++ b/java/smart-admin-api/src/main/resources/templates/codegenerator/QueryDTO.java.vm @@ -0,0 +1,43 @@ +package ${basePackage}.module.${modulePackage}.domain.dto; + +import ${basePackage}.common.domain.PageBaseDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +#foreach ($queryImport in $queryImports) +$queryImport +#end + +/** + * [ ${tableDesc} ] + * + * @author ${author} + * @version 1.0 + * @company ${company} + * @copyright (c) 2019 ${company}Inc. All rights reserved. + * @date ${date} + * @since JDK1.8 + */ +@Data +public class ${moduleClass}QueryDTO extends PageBaseDTO { + +#foreach ($queryField in $queryFieldList) + +#if($queryField.sqlOperate == 'in') + @ApiModelProperty("${queryField.columnDesc}") + private List<${queryField.fieldType}> ${queryField.fieldName}List; +#elseif($queryField.sqlOperate == 'time_equals') + @ApiModelProperty("${queryField.columnDesc}") + private String ${queryField.fieldName}; +#elseif($queryField.sqlOperate == 'time_between') + @ApiModelProperty("开始日期") + private String startDate; + + @ApiModelProperty("结束日期") + private String endDate; +#else + @ApiModelProperty("${queryField.columnDesc}") + private ${queryField.fieldType} ${queryField.fieldName}; +#end + +#end +} diff --git a/java/smart-admin-api/src/main/resources/templates/codegenerator/Service.java.vm b/java/smart-admin-api/src/main/resources/templates/codegenerator/Service.java.vm new file mode 100644 index 00000000..88e418a7 --- /dev/null +++ b/java/smart-admin-api/src/main/resources/templates/codegenerator/Service.java.vm @@ -0,0 +1,95 @@ +package ${basePackage}.module.${modulePackage}.service; + +import com.baomidou.mybatisplus.plugins.Page; +import ${basePackage}.common.domain.PageInfoDTO; +import ${basePackage}.common.domain.ResponseDTO; +import ${basePackage}.module.${modulePackage}.dao.${moduleClass}Dao; +import ${basePackage}.module.${modulePackage}.domain.dto.${moduleClass}DTO; +import ${basePackage}.module.${modulePackage}.domain.dto.${moduleClass}QueryDTO; +import ${basePackage}.module.${modulePackage}.domain.entity.${moduleClass}Entity; +import ${basePackage}.utils.PaginationUtil; +import com.gangquan360.smartutil.bean.SmartBeanUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * [ ${tableDesc} ] + * + * @author ${author} + * @version 1.0 + * @company ${company} + * @copyright (c) 2019 ${company}Inc. All rights reserved. + * @date ${date} + * @since JDK1.8 + */ +@Service +public class ${moduleClass}Service { + + @Autowired + private ${moduleClass}Dao ${moduleVar}Dao; + + + /** + * @author ${author} + * @description 分页查询 + * @date ${date} + */ + public ResponseDTO> queryByPage(${moduleClass}QueryDTO queryDTO) { + Page page = PaginationUtil.convert2PageQueryInfo(queryDTO); + List<${moduleClass}Entity> entities = ${moduleVar}Dao.queryByPage(page, queryDTO); + List<${moduleClass}DTO> dtoList = SmartBeanUtil.copyList(entities, ${moduleClass}DTO.class); + page.setRecords(dtoList); + PageInfoDTO<${moduleClass}DTO> pageResultDTO = PaginationUtil.convert2PageInfoDTO(page); + return ResponseDTO.succData(pageResultDTO); + } + + /** + * @author ${author} + * @description 添加 + * @date ${date} + */ + public ResponseDTO add(${moduleClass}DTO addDTO) { + ${moduleClass}Entity entity = SmartBeanUtil.copy(addDTO, ${moduleClass}Entity.class); + ${moduleVar}Dao.insert(entity); + return ResponseDTO.succ(); + } + + + /** + * @author ${author} + * @description 编辑 + * @date ${date} + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO update(${moduleClass}DTO updateDTO) { + ${moduleClass}Entity entity = SmartBeanUtil.copy(updateDTO, ${moduleClass}Entity.class); + ${moduleVar}Dao.updateById(entity); + return ResponseDTO.succ(); + } + + + /** + * @author ${author} + * @description 删除 + * @date ${date} + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO delete(Long id) { + ${moduleVar}Dao.deleteById(id); + return ResponseDTO.succ(); + } + + /** + * @author ${author} + * @description 根据ID查询 + * @date ${date} + */ + public ResponseDTO<${moduleClass}DTO> detail(Long id){ + ${moduleClass}Entity entity = ${moduleVar}Dao.selectById(id); + ${moduleClass}DTO dto = SmartBeanUtil.copy(entity,${moduleClass}DTO.class); + return ResponseDTO.succData(dto); + } +} diff --git a/java/smart-admin-api/src/test/java/com/gangquan360/smartadmin/BaseTest.java b/java/smart-admin-api/src/test/java/com/gangquan360/smartadmin/BaseTest.java new file mode 100644 index 00000000..65606abe --- /dev/null +++ b/java/smart-admin-api/src/test/java/com/gangquan360/smartadmin/BaseTest.java @@ -0,0 +1,29 @@ +package com.gangquan360.smartadmin; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * 测试基类 + * + * @author lizongliang + * @date 2017/09/29 10:54 + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SmartAdminApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class BaseTest { + + @Before + public void before() { + System.out.println("测试开始------------------"); + } + + @After + public void after() { + System.out.println("测试结束------------------"); + } +} diff --git a/java/smart-admin-api/src/test/java/com/gangquan360/smartadmin/SmartAdminApplicationTests.java b/java/smart-admin-api/src/test/java/com/gangquan360/smartadmin/SmartAdminApplicationTests.java new file mode 100644 index 00000000..3113a8bb --- /dev/null +++ b/java/smart-admin-api/src/test/java/com/gangquan360/smartadmin/SmartAdminApplicationTests.java @@ -0,0 +1,11 @@ +package com.gangquan360.smartadmin; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SmartAdminApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class SmartAdminApplicationTests { + +} \ No newline at end of file diff --git a/java/smart-admin-api/src/test/java/com/gangquan360/smartadmin/module/codegenerator/CodeGeneratorServiceTest.java b/java/smart-admin-api/src/test/java/com/gangquan360/smartadmin/module/codegenerator/CodeGeneratorServiceTest.java new file mode 100644 index 00000000..b3a2ffde --- /dev/null +++ b/java/smart-admin-api/src/test/java/com/gangquan360/smartadmin/module/codegenerator/CodeGeneratorServiceTest.java @@ -0,0 +1,39 @@ +package com.gangquan360.smartadmin.module.codegenerator; + +import com.gangquan360.smartadmin.BaseTest; +import com.gangquan360.smartadmin.module.codegenerator.service.CodeGeneratorService; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * IdGeneratorService Tester. + * + * @author lizongliang + * @version 1.0 + */ +public class CodeGeneratorServiceTest extends BaseTest { + + @Autowired + private CodeGeneratorService codeGeneratorService; + + @Test + public void testGenerate() throws Exception { + // CodeGeneratorQueryColumnDTO createTimeBetween = CodeGeneratorQueryColumnDTO.builder() + // .columnName("create_time") + // .sqlOperate(SqlOperateTypeEnum.TIME_BETWEEN).build(); + // CodeGeneratorQueryColumnDTO like = CodeGeneratorQueryColumnDTO.builder() + // .columnName("title") + // .sqlOperate(SqlOperateTypeEnum.LIKE).build(); + // + // List queryColumnList = Lists.newArrayList(createTimeBetween,like); + // CodeGeneratorDTO codeGenerator = CodeGeneratorDTO.builder() + // .author("yandanyang") + // .company("钢圈") + // .tableName("t_notice") + // .tablePrefix("t_") + // .basePackage("com.gangquan360.smartadmin") + // .queryColumnList(queryColumnList).build(); + // codeGeneratorService.codeGenerator(codeGenerator); + } + +} diff --git a/java/smart-admin-parent/README.md b/java/smart-admin-parent/README.md new file mode 100644 index 00000000..28e28bed --- /dev/null +++ b/java/smart-admin-parent/README.md @@ -0,0 +1 @@ +admin的项目采用maven bom和maven module的形式 \ No newline at end of file diff --git a/java/smart-admin-parent/pom.xml b/java/smart-admin-parent/pom.xml new file mode 100644 index 00000000..10a279c9 --- /dev/null +++ b/java/smart-admin-parent/pom.xml @@ -0,0 +1,547 @@ + + + 4.0.0 + + com.gangquan360 + smart-admin-parent + 1.0.0 + pom + + + 1.8 + 3.3.0.ga + 2.10.0 + 2.1.9.RELEASE + Finchley.SR1 + 5.1.10.RELEASE + 2.0.5.RELEASE + 1.5.0 + 1.0.6 + 2.0.1 + 3.0.1.RELEASE + 3.0.2.RELEASE + 2.3.0 + 3.0.9.RELEASE + 1.7 + 2.7.0 + 1.3.0 + 6.3.2.jre8-preview + 1.2.9 + 8.18.0 + 23.1-jre + 1.2.3 + 2.7.0 + [7.2.0, 7.2.99] + 1.3.1 + 1.2.9 + 0.9.0 + 0.0.1-RC11 + 6.0.2.Final + 2.0.0.Final + 3.0.1-b08 + 1.0.29 + 3.3.2 + 2.1.6 + 1.0.4 + 1.4.2 + 2.0 + 1.0.0-SNAPSHOT + 2.0.2.RELEASE + 3.15 + 3.3.0 + 3.3.4 + 1.9.3 + 3.1.0 + 2.1.11.RELEASE + 2.1.11.RELEASE + 1.6.4 + 1.21 + 2.3.2 + 1.18.8 + 4.2.2 + + + + + + velocity + org.apache.velocity + ${velocity.version} + + + org.springframework + spring-framework-bom + ${spring-framework-bom.version} + pom + import + + + org.springframework.boot + spring-boot-dependencies + ${smartadmin.springboot.version} + pom + import + + + org.springframework.boot + spring-boot-starter-actuator + ${actuator.version} + + + org.springframework.boot + spring-boot-starter-quartz + 2.0.5.RELEASE + + + org.jolokia + jolokia-core + ${jolokia.version} + + + io.micrometer + micrometer-registry-influx + ${micrometer.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + + + com.alibaba + druid + ${druid.version} + + + + + com.github.binarywang + weixin-java-mp + ${weixin-sdk.version} + + + + org.springframework.kafka + spring-kafka + ${kafka.version} + + + org.springframework.kafka + spring-kafka-test + ${kafka.version} + + + + + org.springframework.cloud + spring-cloud-dependencies + ${smartadmin.springcloud.version} + pom + import + + + + + org.hibernate + hibernate-validator + ${hibernate-validator-version} + + + + javax.validation + validation-api + ${javax.validation-version} + + + + org.glassfish + javax.el + ${javax.el-version} + + + + + org.apache.logging.log4j + log4j-web + ${log4j.web.version} + + + + + com.github.mxab.thymeleaf.extras + thymeleaf-extras-data-attribute + ${thymeleaf-extras-data-attribute.version} + + + org.thymeleaf.extras + thymeleaf-extras-java8time + ${thymeleaf-extras-java8time.version} + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity4 + ${thymeleaf-extras-springsecurity4.version} + + + nz.net.ultraq.thymeleaf + thymeleaf-layout-dialect + ${thymeleaf-layout-dialect.version} + + + org.thymeleaf + thymeleaf + ${thymeleaf.version} + + + javassist + org.javassist + + + + + org.thymeleaf + thymeleaf-spring5 + ${thymeleaf.version} + + + + + + org.springframework.boot + spring-boot-starter-data-redis + ${smartadmin.springboot.version} + + + + org.springframework.boot + spring-boot-starter-test + ${smartadmin.springboot.version} + test + + + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + + io.springfox + springfox-swagger-ui + ${swagger.version} + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis-spring-boot.version} + + + + + com.microsoft.sqlserver + mssql-jdbc + ${sql-server.version} + + + + + com.alibaba + fastjson + ${fastjson.version} + + + + + com.netflix.feign + feign-gson + ${feign-gson-version} + + + com.google.code.gson + gson + 2.8.5 + + + + + org.springframework.boot + spring-boot-starter-cache + ${smartadmin.springboot.version} + + + + + com.google.guava + guava + ${guava-version} + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper-version} + + + + + com.aliyun.oss + aliyun-sdk-oss + ${oss.version} + + + com.qiniu + qiniu-java-sdk + ${qiniu.version} + + + commons-fileupload + commons-fileupload + ${fileupload.version} + + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + + + com.openhtmltopdf + openhtmltopdf-core + ${openhtml.version} + + + + + com.openhtmltopdf + openhtmltopdf-pdfbox + ${openhtml.version} + + + + + com.openhtmltopdf + openhtmltopdf-java2d + ${openhtml.version} + + + + + cn.afterturn + easypoi-base + ${easypoi-version} + + + + + cn.afterturn + easypoi-web + ${easypoi-version} + + + + cn.afterturn + easypoi-annotation + ${easypoi-version} + + + + org.apache.poi + poi + ${apache-poi-version} + + + + org.apache.poi + poi-ooxml-schemas + ${apache-poi-version} + + + + org.apache.poi + poi-ooxml + ${apache-poi-version} + + + + + cn.jpush.api + jpush-client + ${jpush-api-version} + + + commons-beanutils + commons-beanutils + ${commons-beanutils.version} + + + org.fusesource + sigar + ${sigar.version} + + + eu.bitwalker + UserAgentUtils + ${userAgent.version} + + + com.github.penggle + kaptcha + ${kaptcha.version} + + + + com.googlecode.concurrentlinkedhashmap + concurrentlinkedhashmap-lru + ${concurrentlinkedhashmap-version} + + + + org.apache.velocity + velocity-engine-core + ${velocity-engine-core.version} + test + + + + com.baomidou + mybatis-plus + ${mybatisplus.version} + + + + com.squareup.okhttp3 + okhttp + ${okhttp.version} + + + + + com.baomidou + mybatisplus-spring-boot-starter + + + spring-boot-starter-logging + org.springframework.boot + + + ${mybatisplus-spring-boot-starter.version} + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + + + + + src/main/java + + **/*.* + + + + false + src/main/resources + + dev/* + sit/* + pre/* + prod/* + + + + src/main/resources/${profiles.active} + true + + *.properties + + + + src/main/resources/${profiles.active} + false + + *.* + + + + + + + pl.project13.maven + git-commit-id-plugin + 2.2.4 + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + UTF-8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${smartadmin.springboot.version} + + ${main-class} + + + + + repackage + + + + + + + + + + + + dev + + dev + + + true + + + + sit + + sit + + + + pre + + pre + + + + prod + + prod + + + + \ No newline at end of file