├── web └── vue-admin-pro │ ├── .eslintignore │ ├── .babelrc │ ├── cypress.json │ ├── src │ ├── components │ │ ├── tree-select │ │ │ ├── index.js │ │ │ ├── tree-select.vue │ │ │ └── tree-select-tree.vue │ │ ├── icons │ │ │ ├── index.js │ │ │ └── icons.vue │ │ ├── main │ │ │ ├── index.js │ │ │ ├── components │ │ │ │ ├── user │ │ │ │ │ ├── index.js │ │ │ │ │ ├── user.less │ │ │ │ │ └── user.vue │ │ │ │ ├── a-back-top │ │ │ │ │ ├── index.js │ │ │ │ │ └── index.vue │ │ │ │ ├── header-bar │ │ │ │ │ ├── index.js │ │ │ │ │ ├── sider-trigger │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── sider-trigger.less │ │ │ │ │ │ └── sider-trigger.vue │ │ │ │ │ ├── custom-bread-crumb │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── custom-bread-crumb.less │ │ │ │ │ │ └── custom-bread-crumb.vue │ │ │ │ │ ├── header-bar.less │ │ │ │ │ └── header-bar.vue │ │ │ │ ├── language │ │ │ │ │ ├── index.js │ │ │ │ │ └── language.vue │ │ │ │ ├── side-menu │ │ │ │ │ ├── index.js │ │ │ │ │ ├── item-mixin.js │ │ │ │ │ ├── mixin.js │ │ │ │ │ ├── side-menu.less │ │ │ │ │ ├── side-menu-item.vue │ │ │ │ │ ├── collapsed-menu.vue │ │ │ │ │ └── side-menu.vue │ │ │ │ ├── tags-nav │ │ │ │ │ ├── index.js │ │ │ │ │ └── tags-nav.less │ │ │ │ ├── error-store │ │ │ │ │ ├── index.js │ │ │ │ │ └── error-store.vue │ │ │ │ └── fullscreen │ │ │ │ │ ├── index.js │ │ │ │ │ └── fullscreen.vue │ │ │ └── main.less │ │ ├── editor │ │ │ ├── index.js │ │ │ └── editor.vue │ │ ├── split-pane │ │ │ ├── index.js │ │ │ ├── trigger.vue │ │ │ ├── index.less │ │ │ └── split.vue │ │ ├── tables │ │ │ ├── index.js │ │ │ ├── index.less │ │ │ ├── handle-btns.js │ │ │ └── edit.vue │ │ ├── count-to │ │ │ ├── index.js │ │ │ ├── index.less │ │ │ └── count-to.vue │ │ ├── cropper │ │ │ ├── index.js │ │ │ ├── index.less │ │ │ └── index.vue │ │ ├── drag-list │ │ │ ├── index.js │ │ │ └── drag-list.vue │ │ ├── info-card │ │ │ ├── index.js │ │ │ └── infor-card.vue │ │ ├── login-form │ │ │ ├── index.js │ │ │ └── login-form.vue │ │ ├── common-icon │ │ │ ├── index.js │ │ │ └── common-icon.vue │ │ ├── drag-drawer │ │ │ ├── index.js │ │ │ ├── mixin.js │ │ │ ├── drag-drawer-trigger.vue │ │ │ ├── index.less │ │ │ └── drag-drawer.vue │ │ ├── markdown │ │ │ ├── index.js │ │ │ └── markdown.vue │ │ ├── parent-view │ │ │ ├── index.js │ │ │ └── parent-view.vue │ │ ├── paste-editor │ │ │ ├── index.js │ │ │ ├── paste-editor.less │ │ │ ├── plugins │ │ │ │ └── placeholder.js │ │ │ └── paste-editor.vue │ │ ├── charts │ │ │ ├── index.js │ │ │ ├── bar.vue │ │ │ └── pie.vue │ │ └── common │ │ │ ├── util.js │ │ │ └── common.less │ ├── assets │ │ ├── images │ │ │ ├── logo.jpg │ │ │ ├── logo.png │ │ │ ├── yasuo.jpg │ │ │ ├── login-bg.jpg │ │ │ ├── login-bg2.jpg │ │ │ ├── login-bg3.jpg │ │ │ ├── logo-min.jpg │ │ │ ├── talkingdata.png │ │ │ ├── icon-qr-qq-wechat.png │ │ │ ├── icon-social-juejin.svg │ │ │ ├── icon-social-zhihu.svg │ │ │ └── icon-social-twitter.svg │ │ ├── icons │ │ │ ├── iconfont.eot │ │ │ ├── iconfont.ttf │ │ │ ├── iconfont.woff │ │ │ └── iconfont.css │ │ └── fonts │ │ │ └── menu │ │ │ ├── iconfont.eot │ │ │ ├── iconfont.ttf │ │ │ ├── iconfont.woff │ │ │ ├── iconfont.svg │ │ │ ├── iconfont.css │ │ │ └── iconfont.js │ ├── index.less │ ├── libs │ │ ├── render-dom.js │ │ ├── api.request.js │ │ ├── axios.js │ │ ├── request.js │ │ └── excel.js │ ├── directive │ │ ├── directives.js │ │ ├── index.js │ │ └── module │ │ │ ├── clipboard.js │ │ │ └── draggable.js │ ├── view │ │ ├── Table │ │ │ └── SimpleTable.vue │ │ └── Login │ │ │ ├── Login.vue │ │ │ └── Login.less │ ├── api │ │ ├── data-test.js │ │ ├── ApiData.js │ │ ├── data.js │ │ └── login.js │ ├── plugin │ │ ├── index.js │ │ └── error-store │ │ │ └── index.js │ ├── router │ │ ├── before-close.js │ │ ├── routers.js │ │ └── index.js │ ├── store │ │ ├── index.js │ │ └── module │ │ │ ├── login.js │ │ │ └── app.js │ ├── App.vue │ ├── mock │ │ ├── login.js │ │ ├── data │ │ │ ├── org-data.js │ │ │ └── tree-select.js │ │ ├── data.js │ │ ├── index.js │ │ └── user.js │ ├── locale │ │ ├── index.js │ │ └── lang │ │ │ ├── zh-CN.js │ │ │ ├── zh-TW.js │ │ │ └── en-US.js │ ├── config │ │ └── index.js │ └── main.js │ ├── .postcssrc.js │ ├── .travis.yml │ ├── images │ ├── login.png │ └── login-2020.png │ ├── public │ ├── favicon.png │ └── index.html │ ├── tests │ ├── unit │ │ ├── .eslintrc.js │ │ └── HelloWorld.spec.js │ └── e2e │ │ ├── .eslintrc │ │ ├── specs │ │ └── test.js │ │ ├── plugins │ │ └── index.js │ │ └── support │ │ ├── index.js │ │ └── commands.js │ ├── .editorconfig │ ├── .gitignore │ ├── .eslintrc.js │ ├── LICENSE │ ├── vue.config.js │ └── package.json ├── settings.gradle ├── images ├── 1.png ├── 2.png ├── 3.png ├── 4.png └── 5.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── src ├── main │ ├── resources │ │ └── application.properties │ └── java │ │ └── com │ │ └── fengwenyi │ │ └── spring_boot_elasticsearch_sample │ │ ├── service │ │ ├── DataService.java │ │ └── SearchService.java │ │ ├── vo │ │ ├── request │ │ │ ├── FullSearchRequestVo.java │ │ │ └── AdvancedSearchRequestVo.java │ │ └── response │ │ │ └── PhoneSearchResultResponseVo.java │ │ ├── SpringBootElasticsearchSampleApplication.java │ │ ├── config │ │ └── Swagger2Config.java │ │ ├── repository │ │ └── PhoneRepository.java │ │ ├── constant │ │ └── Constants.java │ │ ├── util │ │ ├── HttpUtils.java │ │ └── JsonUtils.java │ │ ├── entity │ │ └── PhoneEntity.java │ │ └── controller │ │ ├── DataController.java │ │ └── SearchController.java └── test │ └── java │ └── com │ └── fengwenyi │ └── spring_boot_elasticsearch_sample │ ├── SpringBootElasticsearchSampleApplicationTests.java │ └── repository │ └── PhoneRepositoryTests.java ├── ApiTest.http ├── README.md ├── .gitignore ├── LICENSE ├── gradlew.bat └── gradlew /web/vue-admin-pro/.eslintignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-elasticsearch-sample' 2 | -------------------------------------------------------------------------------- /web/vue-admin-pro/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@vue/app" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /web/vue-admin-pro/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginsFile": "tests/e2e/plugins/index.js" 3 | } 4 | -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/images/1.png -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/images/2.png -------------------------------------------------------------------------------- /images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/images/3.png -------------------------------------------------------------------------------- /images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/images/4.png -------------------------------------------------------------------------------- /images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/images/5.png -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/tree-select/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './tree-select.vue' 2 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/icons/index.js: -------------------------------------------------------------------------------- 1 | import Icons from './icons.vue' 2 | export default Icons 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/index.js: -------------------------------------------------------------------------------- 1 | import Main from './main.vue' 2 | export default Main 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/.postcssrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/editor/index.js: -------------------------------------------------------------------------------- 1 | import Editor from './editor.vue' 2 | export default Editor 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/split-pane/index.js: -------------------------------------------------------------------------------- 1 | import Split from './split.vue' 2 | export default Split 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/tables/index.js: -------------------------------------------------------------------------------- 1 | import Tables from './tables.vue' 2 | export default Tables 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/count-to/index.js: -------------------------------------------------------------------------------- 1 | import countTo from './count-to.vue' 2 | export default countTo 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/cropper/index.js: -------------------------------------------------------------------------------- 1 | import Cropper from './index.vue' 2 | export default Cropper 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/drag-list/index.js: -------------------------------------------------------------------------------- 1 | import DragList from './drag-list.vue' 2 | export default DragList 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/user/index.js: -------------------------------------------------------------------------------- 1 | import User from './user.vue' 2 | export default User 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/info-card/index.js: -------------------------------------------------------------------------------- 1 | import InforCard from './infor-card.vue' 2 | export default InforCard 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/login-form/index.js: -------------------------------------------------------------------------------- 1 | import LoginForm from './login-form.vue' 2 | export default LoginForm 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/common-icon/index.js: -------------------------------------------------------------------------------- 1 | import CommonIcon from './common-icon.vue' 2 | export default CommonIcon 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/drag-drawer/index.js: -------------------------------------------------------------------------------- 1 | import DragDrawer from './drag-drawer.vue' 2 | export default DragDrawer 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/markdown/index.js: -------------------------------------------------------------------------------- 1 | import MarkdownEditor from './markdown.vue' 2 | export default MarkdownEditor 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/parent-view/index.js: -------------------------------------------------------------------------------- 1 | import ParentView from './parent-view.vue' 2 | export default ParentView 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: stable 3 | script: npm run lint 4 | notifications: 5 | email: false 6 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/a-back-top/index.js: -------------------------------------------------------------------------------- 1 | import ABackTop from './index.vue' 2 | export default ABackTop 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/header-bar/index.js: -------------------------------------------------------------------------------- 1 | import HeaderBar from './header-bar' 2 | export default HeaderBar 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/language/index.js: -------------------------------------------------------------------------------- 1 | import Language from './language.vue' 2 | export default Language 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/side-menu/index.js: -------------------------------------------------------------------------------- 1 | import SideMenu from './side-menu.vue' 2 | export default SideMenu 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/tags-nav/index.js: -------------------------------------------------------------------------------- 1 | import TagsNav from './tags-nav.vue' 2 | export default TagsNav 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/paste-editor/index.js: -------------------------------------------------------------------------------- 1 | import PasteEditor from './paste-editor.vue' 2 | export default PasteEditor 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /web/vue-admin-pro/images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/images/login.png -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/error-store/index.js: -------------------------------------------------------------------------------- 1 | import ErrorStore from './error-store.vue' 2 | export default ErrorStore 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/fullscreen/index.js: -------------------------------------------------------------------------------- 1 | import Fullscreen from './fullscreen.vue' 2 | export default Fullscreen 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/public/favicon.png -------------------------------------------------------------------------------- /web/vue-admin-pro/images/login-2020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/images/login-2020.png -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/charts/index.js: -------------------------------------------------------------------------------- 1 | import ChartPie from './pie.vue' 2 | import ChartBar from './bar.vue' 3 | export { ChartPie, ChartBar } 4 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/drag-drawer/mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | data () { 3 | return { 4 | prefix: 'drag-drawer' 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/images/logo.jpg -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/images/logo.png -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/yasuo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/images/yasuo.jpg -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/header-bar/sider-trigger/index.js: -------------------------------------------------------------------------------- 1 | import siderTrigger from './sider-trigger.vue' 2 | export default siderTrigger 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/icons/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/icons/iconfont.eot -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/icons/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/icons/iconfont.ttf -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/icons/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/icons/iconfont.woff -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/login-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/images/login-bg.jpg -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/login-bg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/images/login-bg2.jpg -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/login-bg3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/images/login-bg3.jpg -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/logo-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/images/logo-min.jpg -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/fonts/menu/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/fonts/menu/iconfont.eot -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/fonts/menu/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/fonts/menu/iconfont.ttf -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/talkingdata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/images/talkingdata.png -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/header-bar/custom-bread-crumb/index.js: -------------------------------------------------------------------------------- 1 | import customBreadCrumb from './custom-bread-crumb.vue' 2 | export default customBreadCrumb 3 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/fonts/menu/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/fonts/menu/iconfont.woff -------------------------------------------------------------------------------- /web/vue-admin-pro/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | mocha: true 4 | }, 5 | rules: { 6 | 'import/no-extraneous-dependencies': 'off' 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/icon-qr-qq-wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fengwenyi/spring-boot-elasticsearch-sample/HEAD/web/vue-admin-pro/src/assets/images/icon-qr-qq-wechat.png -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less: -------------------------------------------------------------------------------- 1 | .custom-bread-crumb{ 2 | display: inline-block; 3 | vertical-align: top; 4 | } 5 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/index.less: -------------------------------------------------------------------------------- 1 | @import '~view-design/src/styles/index.less'; 2 | 3 | @menu-dark-title: #001529; 4 | @menu-dark-active-bg: #000c17; 5 | @layout-sider-background: #001529; 6 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/common/util.js: -------------------------------------------------------------------------------- 1 | export const showTitle = (item, vm) => { 2 | return vm.$config.useI18n ? vm.$t(item.name) : ((item.meta && item.meta.title) || item.name) 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # 服务端口 2 | server.port=9099 3 | # 应用名称 4 | spring.application.name=spring-boot-elasticsearch-sample 5 | # elasticsearch 连接地址 6 | spring.elasticsearch.rest.uris=http://localhost:9200 -------------------------------------------------------------------------------- /web/vue-admin-pro/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /web/vue-admin-pro/tests/e2e/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "cypress" 4 | ], 5 | "env": { 6 | "mocha": true, 7 | "cypress/globals": true 8 | }, 9 | "rules": { 10 | "strict": "off" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/libs/render-dom.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'RenderDom', 3 | functional: true, 4 | props: { 5 | render: Function 6 | }, 7 | render: (h, ctx) => { 8 | return ctx.props.render(h) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/directive/directives.js: -------------------------------------------------------------------------------- 1 | import draggable from './module/draggable' 2 | import clipboard from './module/clipboard' 3 | 4 | const directives = { 5 | draggable, 6 | clipboard 7 | } 8 | 9 | export default directives 10 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/common/common.less: -------------------------------------------------------------------------------- 1 | .no-select{ 2 | -webkit-touch-callout: none; 3 | -webkit-user-select: none; 4 | -khtml-user-select: none; 5 | -moz-user-select: none; 6 | -ms-user-select: none; 7 | user-select: none; 8 | } 9 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/count-to/index.less: -------------------------------------------------------------------------------- 1 | @prefix: ~"count-to"; 2 | 3 | .@{prefix}-wrapper{ 4 | .content-outer{ 5 | display: inline-block; 6 | .@{prefix}-unit-text{ 7 | font-style: normal; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/view/Table/SimpleTable.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /web/vue-admin-pro/tests/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | describe('My First Test', () => { 4 | it('Visits the app root url', () => { 5 | cy.visit('/') 6 | cy.contains('h1', 'Welcome to Your Vue.js App') 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/api/data-test.js: -------------------------------------------------------------------------------- 1 | import request from '@/libs/request' 2 | 3 | export function apiDataTest (data) { 4 | const param = JSON.stringify(data) 5 | return request({ 6 | url: '/data/test', 7 | method: 'post', 8 | data: param 9 | }) 10 | } 11 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/libs/api.request.js: -------------------------------------------------------------------------------- 1 | import HttpRequest from '@/libs/axios' 2 | import config from '@/config' 3 | const baseUrl = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro 4 | 5 | const axios = new HttpRequest(baseUrl) 6 | export default axios 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Jun 24 19:43:04 CST 2020 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/plugin/index.js: -------------------------------------------------------------------------------- 1 | import config from '@/config' 2 | const { plugin } = config 3 | 4 | export default (Vue) => { 5 | for (let name in plugin) { 6 | const value = plugin[name] 7 | Vue.use(require(`./${name}`).default, typeof value === 'object' ? value : undefined) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/service/DataService.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.service; 2 | 3 | /** 4 | * 数据服务 5 | * @author Erwin Feng 6 | * @since 2020/7/4 7 | */ 8 | public interface DataService { 9 | 10 | void jd(); 11 | 12 | void export(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/header-bar/header-bar.less: -------------------------------------------------------------------------------- 1 | .header-bar{ 2 | width: 100%; 3 | height: 100%; 4 | position: relative; 5 | .custom-content-con{ 6 | float: right; 7 | height: auto; 8 | padding-right: 20px; 9 | line-height: 64px; 10 | & > *{ 11 | float: right; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/tables/index.less: -------------------------------------------------------------------------------- 1 | .search-con{ 2 | padding: 10px 0; 3 | .search{ 4 | &-col{ 5 | display: inline-block; 6 | width: 200px; 7 | } 8 | &-input{ 9 | display: inline-block; 10 | width: 200px; 11 | margin-left: 2px; 12 | } 13 | &-btn{ 14 | margin-left: 2px; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/router/before-close.js: -------------------------------------------------------------------------------- 1 | import { Modal } from 'view-design' 2 | 3 | const beforeClose = { 4 | before_close_normal: (resolve) => { 5 | Modal.confirm({ 6 | title: '确定要关闭这一页吗', 7 | onOk: () => { 8 | resolve(true) 9 | }, 10 | onCancel: () => { 11 | resolve(false) 12 | } 13 | }) 14 | } 15 | } 16 | 17 | export default beforeClose 18 | -------------------------------------------------------------------------------- /web/vue-admin-pro/tests/e2e/plugins/index.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/guides/guides/plugins-guide.html 2 | 3 | module.exports = (on, config) => Object.assign({}, config, { 4 | fixturesFolder: 'tests/e2e/fixtures', 5 | integrationFolder: 'tests/e2e/specs', 6 | screenshotsFolder: 'tests/e2e/screenshots', 7 | videosFolder: 'tests/e2e/videos', 8 | supportFile: 'tests/e2e/support/index.js' 9 | }) 10 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | import login from './module/login' 5 | import app from './module/app' 6 | 7 | Vue.use(Vuex) 8 | 9 | export default new Vuex.Store({ 10 | state: { 11 | // 12 | }, 13 | mutations: { 14 | // 15 | }, 16 | actions: { 17 | // 18 | }, 19 | modules: { 20 | app, 21 | login 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 28 | -------------------------------------------------------------------------------- /src/test/java/com/fengwenyi/spring_boot_elasticsearch_sample/SpringBootElasticsearchSampleApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringBootElasticsearchSampleApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /web/vue-admin-pro/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | package-lock.json 6 | 7 | /tests/e2e/videos/ 8 | /tests/e2e/screenshots/ 9 | 10 | # local env files 11 | .env.local 12 | .env.*.local 13 | 14 | # Log files 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | 19 | # Editor directories and files 20 | .idea 21 | .vscode 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw* 27 | 28 | build/env.js 29 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/api/ApiData.js: -------------------------------------------------------------------------------- 1 | import request from '@/libs/request' 2 | 3 | // 全文搜索 4 | export const apiFullSearch = ( data ) => { 5 | return request({ 6 | url: '/api/search/full', 7 | method: 'post', 8 | data: data 9 | }) 10 | } 11 | 12 | // 高级搜索 13 | export const apiAdvancedSearch = ( data ) => { 14 | return request({ 15 | url: '/api/search/advanced', 16 | method: 'post', 17 | data: data 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/drag-drawer/drag-drawer-trigger.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | 17 | 19 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/user/user.less: -------------------------------------------------------------------------------- 1 | .user{ 2 | &-avatar-dropdown{ 3 | cursor: pointer; 4 | display: inline-block; 5 | // height: 64px; 6 | vertical-align: middle; 7 | // line-height: 64px; 8 | .ivu-badge-dot{ 9 | top: 16px; 10 | } 11 | .user-name { 12 | margin-left: 8px; 13 | margin-right: 2px; 14 | font-size: 16px; 15 | color: #333; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /web/vue-admin-pro/tests/unit/HelloWorld.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import { shallow } from '@vue/test-utils' 3 | import HelloWorld from '@/components/HelloWorld.vue' 4 | 5 | describe('HelloWorld.vue', () => { 6 | it('renders props.msg when passed', () => { 7 | const msg = 'new message' 8 | const wrapper = shallow(HelloWorld, { 9 | propsData: { msg } 10 | }) 11 | expect(wrapper.text()).to.include(msg) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/vo/request/FullSearchRequestVo.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.vo.request; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 全文搜索请求VO 7 | * @author Erwin Feng 8 | * @since 2020/7/11 9 | */ 10 | @Data 11 | public class FullSearchRequestVo { 12 | 13 | /** 当前页 */ 14 | private Integer currentPage; 15 | 16 | /** 关键字 */ 17 | private String keyword; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/header-bar/sider-trigger/sider-trigger.less: -------------------------------------------------------------------------------- 1 | .trans{ 2 | transition: transform .2s ease; 3 | } 4 | @size: 40px; 5 | .sider-trigger-a{ 6 | padding: 6px; 7 | width: @size; 8 | height: @size; 9 | display: inline-block; 10 | text-align: center; 11 | color: #5c6b77; 12 | margin-top: 12px; 13 | i{ 14 | .trans; 15 | vertical-align: top; 16 | font-size: 26px; 17 | } 18 | &.collapsed i{ 19 | //transform: rotateZ(90deg); 20 | .trans; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/side-menu/item-mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | props: { 3 | parentItem: { 4 | type: Object, 5 | default: () => {} 6 | }, 7 | theme: String, 8 | iconSize: Number 9 | }, 10 | computed: { 11 | parentName () { 12 | return this.parentItem.name 13 | }, 14 | children () { 15 | return this.parentItem.children 16 | }, 17 | textColor () { 18 | return this.theme === 'dark' ? '#fff' : '#495060' 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/plugin/error-store/index.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | export default { 3 | install (Vue, options) { 4 | if (options.developmentOff && process.env.NODE_ENV === 'development') return 5 | Vue.config.errorHandler = (error, vm, mes) => { 6 | let info = { 7 | type: 'script', 8 | code: 0, 9 | mes: error.message, 10 | url: window.location.href 11 | } 12 | Vue.nextTick(() => { 13 | store.dispatch('addErrorLog', info) 14 | }) 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ApiTest.http: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### 4 | 5 | # 测试抓取手机信息 6 | GET http://localhost:9099/api/data/grab 7 | Content-Type: application/json 8 | 9 | ### 10 | 11 | 12 | # 查询所有手机信息 13 | GET http://localhost:9099/api/data/all 14 | Content-Type: application/json 15 | 16 | ### 17 | 18 | # 导出所有手机信息 19 | GET http://localhost:9099/api/data/export 20 | Content-Type: application/json 21 | 22 | ### 23 | 24 | # 全文搜索 25 | POST http://localhost:9099/api/search/full 26 | Content-Type: application/json 27 | 28 | { 29 | "currentPage": 1, 30 | "keyword": "华为" 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/SpringBootElasticsearchSampleApplication.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringBootElasticsearchSampleApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringBootElasticsearchSampleApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/config/Swagger2Config.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.config; 2 | 3 | import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; 4 | import org.springframework.context.annotation.Configuration; 5 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 6 | 7 | /** 8 | * Swagger2API文档的配置 9 | * @author Erwin Feng 10 | * @since 2020/7/22 11 | */ 12 | @Configuration 13 | @EnableSwagger2 14 | @EnableKnife4j 15 | public class Swagger2Config { 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/repository/PhoneRepository.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.repository; 2 | 3 | import com.fengwenyi.spring_boot_elasticsearch_sample.entity.PhoneEntity; 4 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author Erwin Feng 9 | * @since 2020/7/4 10 | */ 11 | @Repository 12 | public interface PhoneRepository extends ElasticsearchRepository { 13 | } 14 | -------------------------------------------------------------------------------- /web/vue-admin-pro/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 'extends': [ 4 | 'plugin:vue/essential', 5 | '@vue/standard' 6 | ], 7 | rules: { 8 | // allow async-await 9 | 'generator-star-spacing': 'off', 10 | // allow debugger during development 11 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'vue/no-parsing-error': [2, { 13 | 'x-invalid-end-tag': false 14 | }], 15 | 'no-undef': 'off', 16 | 'camelcase': 'off' 17 | }, 18 | parserOptions: { 19 | parser: 'babel-eslint' 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/paste-editor/paste-editor.less: -------------------------------------------------------------------------------- 1 | .paste-editor-wrapper{ 2 | width: 100%; 3 | height: 100%; 4 | border: 1px dashed gainsboro; 5 | textarea.textarea-el{ 6 | width: 100%; 7 | height: 100%; 8 | } 9 | .CodeMirror{ 10 | height: 100%; 11 | padding: 0; 12 | .CodeMirror-code div .CodeMirror-line > span > span.cm-tab{ 13 | &::after{ 14 | content: '→'; 15 | color: #BFBFBF; 16 | } 17 | } 18 | } 19 | .first-row{ 20 | font-weight: 700; 21 | font-size: 14px; 22 | } 23 | .incorrect-row{ 24 | background: #F5CBD1; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot 整合 Elasticsearch 2 | 3 | 2.3.1.RELEASE 4 | 5 | ## 测试数据下载地址 6 | 7 | [phone-info.json](https://download.csdn.net/download/qq_28336351/12595861) 8 | 9 | ## 当前状态 10 | 11 | * [x] 搭建项目(2020-06-25) 12 | * [x] 设计测试模型(2020-07-04) 13 | * [x] 抓取数据(2020-07-08) 14 | * [x] 数据处理(2020-07-09) 15 | * [x] 全文搜索接口(2020-07-11) 16 | * [x] 高级搜索接口(2020-07-22) 17 | * [x] 前端页面(2020-07-23) 18 | * [x] 前端调用接口,实现搜索功能(2020-07-23) 19 | 20 | ## 效果截图 21 | 22 | ![](./images/1.png) 23 | 24 | ![](./images/2.png) 25 | 26 | ![](./images/3.png) 27 | 28 | ![](./images/4.png) 29 | 30 | ![](./images/5.png) 31 | 32 | ## 其他 33 | 34 | 还有一些问题,待优化! -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/side-menu/mixin.js: -------------------------------------------------------------------------------- 1 | import CommonIcon from '_c/common-icon' 2 | import { showTitle } from '@/libs/util' 3 | export default { 4 | components: { 5 | CommonIcon 6 | }, 7 | methods: { 8 | showTitle (item) { 9 | return showTitle(item, this) 10 | }, 11 | showChildren (item) { 12 | return item.children && (item.children.length > 1 || (item.meta && item.meta.showAlways)) 13 | }, 14 | getNameOrHref (item, children0) { 15 | return item.href ? `isTurnByHref_${item.href}` : (children0 ? item.children[0].name : item.name) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /web/vue-admin-pro/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/icons/icons.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 32 | 33 | 36 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/directive/index.js: -------------------------------------------------------------------------------- 1 | import directive from './directives' 2 | 3 | const importDirective = Vue => { 4 | /** 5 | * 拖拽指令 v-draggable="options" 6 | * options = { 7 | * trigger: /这里传入作为拖拽触发器的CSS选择器/, 8 | * body: /这里传入需要移动容器的CSS选择器/, 9 | * recover: /拖动结束之后是否恢复到原来的位置/ 10 | * } 11 | */ 12 | Vue.directive('draggable', directive.draggable) 13 | /** 14 | * clipboard指令 v-draggable="options" 15 | * options = { 16 | * value: /在输入框中使用v-model绑定的值/, 17 | * success: /复制成功后的回调/, 18 | * error: /复制失败后的回调/ 19 | * } 20 | */ 21 | Vue.directive('clipboard', directive.clipboard) 22 | } 23 | 24 | export default importDirective 25 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/parent-view/parent-view.vue: -------------------------------------------------------------------------------- 1 | 6 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/constant/Constants.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.constant; 2 | 3 | /** 4 | * @author Erwin Feng 5 | * @since 2020/7/4 6 | */ 7 | public final class Constants { 8 | 9 | /* 响应默认成功信息 */ 10 | public static final String RESPONSE_DEFAULT_SUCCESS_MESSAGE = "Success"; 11 | 12 | /* 响应默认错误信息 */ 13 | public static final String RESPONSE_DEFAULT_ERROR_MESSAGE = "Error"; 14 | 15 | /* 抓取华为手机信息的URL */ 16 | public static final String URL_PHONE_HUAWEI = "https://consumer.huawei.com/cn/phones/?ic_medium=hwdc&ic_source=corp_header_consumer"; 17 | 18 | /* 抓取华为手机信息的URL */ 19 | public static final String URL_PHONE_JD = "https://list.jd.com/list.html?cat=9987,653,655"; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /web/vue-admin-pro/tests/e2e/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/tables/handle-btns.js: -------------------------------------------------------------------------------- 1 | const btns = { 2 | delete: (h, params, vm) => { 3 | return h('Poptip', { 4 | props: { 5 | confirm: true, 6 | title: '你确定要删除吗?' 7 | }, 8 | on: { 9 | 'on-ok': () => { 10 | vm.$emit('on-delete', params) 11 | vm.$emit('input', params.tableData.filter((item, index) => index !== params.row.initRowIndex)) 12 | } 13 | } 14 | }, [ 15 | h('Button', { 16 | props: { 17 | type: 'text', 18 | ghost: true 19 | } 20 | }, [ 21 | h('Icon', { 22 | props: { 23 | type: 'md-trash', 24 | size: 18, 25 | color: '#000000' 26 | } 27 | }) 28 | ]) 29 | ]) 30 | } 31 | } 32 | 33 | export default btns 34 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/mock/login.js: -------------------------------------------------------------------------------- 1 | import { getParams } from '@/libs/util' 2 | import { Message } from 'view-design' 3 | 4 | const USER_MAP = { 5 | jsdz: { 6 | name: 'super_admin', 7 | user_id: '1', 8 | access: ['super_admin', 'admin'], 9 | token: 'jsdz', 10 | avatar: 'http://localhost:8108/header.jpg' 11 | } 12 | } 13 | 14 | export const login = req => { 15 | req = JSON.parse(req.body) 16 | console.log(JSON.stringify(req)) 17 | let password = req.password 18 | if (password === 'jsdz1234') { 19 | return { token: USER_MAP[req.userName].token } 20 | } else { 21 | Message.error('登录失败,原因:密码不正确') 22 | } 23 | } 24 | 25 | export const getUserInfo = req => { 26 | const params = getParams(req.url) 27 | return USER_MAP[params.token] 28 | } 29 | 30 | export const logout = req => { 31 | return null 32 | } 33 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/header-bar/sider-trigger/sider-trigger.vue: -------------------------------------------------------------------------------- 1 | 7 | 28 | 31 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/mock/data/org-data.js: -------------------------------------------------------------------------------- 1 | export default { 2 | id: 0, 3 | label: 'XXX科技有限公司', 4 | children: [ 5 | { 6 | id: 2, 7 | label: '产品研发部', 8 | children: [ 9 | { 10 | id: 5, 11 | label: '研发-前端' 12 | }, { 13 | id: 6, 14 | label: '研发-后端' 15 | }, { 16 | id: 9, 17 | label: 'UI设计' 18 | }, { 19 | id: 10, 20 | label: '产品经理' 21 | } 22 | ] 23 | }, 24 | { 25 | id: 3, 26 | label: '销售部', 27 | children: [ 28 | { 29 | id: 7, 30 | label: '销售一部' 31 | }, { 32 | id: 8, 33 | label: '销售二部' 34 | } 35 | ] 36 | }, 37 | { 38 | id: 4, 39 | label: '财务部' 40 | }, { 41 | id: 11, 42 | label: 'HR人事' 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | 34 | .DS_Store 35 | node_modules 36 | /dist 37 | 38 | package-lock.json 39 | 40 | /tests/e2e/videos/ 41 | /tests/e2e/screenshots/ 42 | 43 | # local env files 44 | .env.local 45 | .env.*.local 46 | 47 | # Log files 48 | npm-debug.log* 49 | yarn-debug.log* 50 | yarn-error.log* 51 | 52 | # Editor directories and files 53 | .idea 54 | .vscode 55 | *.suo 56 | *.ntvs* 57 | *.njsproj 58 | *.sln 59 | *.sw* 60 | 61 | build/env.js -------------------------------------------------------------------------------- /web/vue-admin-pro/src/api/data.js: -------------------------------------------------------------------------------- 1 | import axios from '@/libs/api.request' 2 | import { getToken } from '@/libs/util' 3 | 4 | /** 5 | * 获取数据 6 | * @param d1 参数1 7 | * @param d2 参数2 8 | */ 9 | export const data = (d1, d2) => { 10 | const data = { 11 | d1, 12 | d2 13 | } 14 | return axios.request({ 15 | url: 'auth/login', 16 | method: 'post', 17 | dataType: 'json', 18 | headers: { 19 | 'Content-Type': 'application/json; charset=UTF-8', 20 | 'token': getToken() 21 | }, 22 | data: data 23 | }) 24 | } 25 | 26 | /** 27 | * 获取数据 28 | * @param param 参数 29 | */ 30 | export const data2 = (param) => { 31 | return axios.request({ 32 | url: 'auth/login', 33 | method: 'post', 34 | dataType: 'json', 35 | headers: { 36 | 'Content-Type': 'application/json; charset=UTF-8', 37 | 'token': getToken() 38 | }, 39 | data: param 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/side-menu/side-menu.less: -------------------------------------------------------------------------------- 1 | .side-menu-wrapper{ 2 | user-select: none; 3 | 4 | .menu-collapsed{ 5 | padding-top: 10px; 6 | 7 | .ivu-dropdown{ 8 | width: 100%; 9 | .ivu-dropdown-rel a{ 10 | width: 100%; 11 | } 12 | } 13 | .ivu-tooltip{ 14 | width: 100%; 15 | .ivu-tooltip-rel{ 16 | width: 100%; 17 | } 18 | .ivu-tooltip-popper .ivu-tooltip-content{ 19 | .ivu-tooltip-arrow{ 20 | border-right-color: #fff; 21 | } 22 | .ivu-tooltip-inner{ 23 | background: #fff; 24 | color: #495060; 25 | } 26 | } 27 | } 28 | 29 | 30 | } 31 | a.drop-menu-a{ 32 | display: inline-block; 33 | padding: 6px 15px; 34 | width: 100%; 35 | text-align: center; 36 | color: #495060; 37 | } 38 | } 39 | .menu-title{ 40 | padding-left: 6px; 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/vo/request/AdvancedSearchRequestVo.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.vo.request; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | 7 | /** 8 | * 高级搜索 请求VO 9 | * @author Erwin Feng 10 | * @since 2020/7/22 11 | */ 12 | @Data 13 | public class AdvancedSearchRequestVo { 14 | 15 | /* 名称 */ 16 | private String name; 17 | 18 | /* 推广广告 */ 19 | private String ad; 20 | 21 | /* 售价:最低 */ 22 | private BigDecimal priceMin; 23 | 24 | /* 售价:最高 */ 25 | private BigDecimal priceMax; 26 | 27 | /* 内存 */ 28 | private String memory; 29 | 30 | /* 存储 */ 31 | private String storage; 32 | 33 | /* 屏幕 */ 34 | private String screen; 35 | 36 | /* 开始时间字符串 */ 37 | private Long startTimeStamp; 38 | 39 | /* 结束时间字符串 */ 40 | private Long endTimeStamp; 41 | 42 | /** 当前页 */ 43 | private Integer currentPage; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/icon-social-juejin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/vue-admin-pro/tests/e2e/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This is will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/mock/data.js: -------------------------------------------------------------------------------- 1 | import Mock from 'mockjs' 2 | import { doCustomTimes } from '@/libs/util' 3 | import orgData from './data/org-data' 4 | import { treeData } from './data/tree-select' 5 | const Random = Mock.Random 6 | 7 | export const getTableData = req => { 8 | let tableData = [] 9 | doCustomTimes(5, () => { 10 | tableData.push(Mock.mock({ 11 | name: '@name', 12 | email: '@email', 13 | createTime: '@date' 14 | })) 15 | }) 16 | return tableData 17 | } 18 | 19 | export const getDragList = req => { 20 | let dragList = [] 21 | doCustomTimes(5, () => { 22 | dragList.push(Mock.mock({ 23 | name: Random.csentence(10, 13), 24 | id: Random.increment(10) 25 | })) 26 | }) 27 | return dragList 28 | } 29 | 30 | export const uploadImage = req => { 31 | return Promise.resolve() 32 | } 33 | 34 | export const getOrgData = req => { 35 | return orgData 36 | } 37 | 38 | export const getTreeSelectData = req => { 39 | return treeData 40 | } 41 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/split-pane/trigger.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/service/SearchService.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.service; 2 | 3 | import com.fengwenyi.api.result.CommonResponse; 4 | import com.fengwenyi.spring_boot_elasticsearch_sample.vo.request.AdvancedSearchRequestVo; 5 | import com.fengwenyi.spring_boot_elasticsearch_sample.vo.request.FullSearchRequestVo; 6 | import com.fengwenyi.spring_boot_elasticsearch_sample.vo.response.PhoneSearchResultResponseVo; 7 | 8 | /** 9 | * 搜索服务接口 10 | * @author Erwin Feng 11 | * @since 2020/7/11 12 | */ 13 | public interface SearchService { 14 | 15 | /** 16 | * 全文搜索 17 | * @param requestVo {@link FullSearchRequestVo} 18 | * @return 19 | */ 20 | CommonResponse fullSearch(FullSearchRequestVo requestVo); 21 | 22 | /** 23 | * 高级搜索 24 | * @param requestVo 搜索条件 25 | * @return 返回搜索结果 26 | */ 27 | CommonResponse advancedSearch(AdvancedSearchRequestVo requestVo); 28 | } 29 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/common-icon/common-icon.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 39 | 40 | 43 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/cropper/index.less: -------------------------------------------------------------------------------- 1 | .bg{ 2 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC") 3 | } 4 | .cropper-wrapper{ 5 | width: 600px; 6 | height: 340px; 7 | .img-box{ 8 | height: 340px; 9 | width: 430px; 10 | border: 1px solid #ebebeb; 11 | display: inline-block; 12 | .bg; 13 | img{ 14 | max-width: 100%; 15 | display: block; 16 | } 17 | } 18 | .right-con{ 19 | display: inline-block; 20 | width: 170px; 21 | vertical-align: top; 22 | box-sizing: border-box; 23 | padding: 0 10px; 24 | .preview-box{ 25 | height: 150px !important; 26 | width: 100% !important; 27 | overflow: hidden; 28 | border: 1px solid #ebebeb; 29 | .bg; 30 | } 31 | .button-box{ 32 | padding: 10px 0 0; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/directive/module/clipboard.js: -------------------------------------------------------------------------------- 1 | import Clipboard from 'clipboard' 2 | export default { 3 | bind: (el, binding) => { 4 | const clipboard = new Clipboard(el, { 5 | text: () => binding.value.value 6 | }) 7 | el.__success_callback__ = binding.value.success 8 | el.__error_callback__ = binding.value.error 9 | clipboard.on('success', e => { 10 | const callback = el.__success_callback__ 11 | callback && callback(e) 12 | }) 13 | clipboard.on('error', e => { 14 | const callback = el.__error_callback__ 15 | callback && callback(e) 16 | }) 17 | el.__clipboard__ = clipboard 18 | }, 19 | update: (el, binding) => { 20 | el.__clipboard__.text = () => binding.value.value 21 | el.__success_callback__ = binding.value.success 22 | el.__error_callback__ = binding.value.error 23 | }, 24 | unbind: (el, binding) => { 25 | delete el.__success_callback__ 26 | delete el.__error_callback__ 27 | el.__clipboard__.destroy() 28 | delete el.__clipboard__ 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/util/HttpUtils.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.util; 2 | 3 | import okhttp3.OkHttpClient; 4 | import okhttp3.Request; 5 | import okhttp3.Response; 6 | 7 | import java.io.IOException; 8 | import java.util.Objects; 9 | 10 | /** 11 | * Http工具类 12 | * @author Erwin Feng 13 | * @since 2020/7/5 14 | */ 15 | public class HttpUtils { 16 | 17 | /** 18 | * http get请求 19 | * @param url 20 | * @return 21 | */ 22 | public static String get(String url) { 23 | OkHttpClient client = new OkHttpClient(); 24 | Request request = new Request.Builder() 25 | .url(url) 26 | .build(); 27 | 28 | try { 29 | try (Response response = client.newCall(request).execute()) { 30 | return Objects.requireNonNull(response.body()).string(); 31 | } 32 | } catch (IOException e) { 33 | e.printStackTrace(); 34 | } 35 | return null; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/error-store/error-store.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 38 | 39 | 50 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/api/login.js: -------------------------------------------------------------------------------- 1 | // import axios from '@/libs/api.request' 2 | import request from '@/libs/request' 3 | 4 | /** 5 | * 登录 6 | * @param account 7 | * @param password 8 | * @returns {http.ClientRequest | ClientHttp2Stream | * | never | AxiosPromise} 9 | */ 10 | // export const login = (account, password) => { 11 | // const data = { 12 | // account, 13 | // password 14 | // } 15 | // return axios.request({ 16 | // url: 'auth/login', 17 | // method: 'post', 18 | // dataType: 'json', 19 | // headers: { 20 | // 'Content-Type': 'application/json; charset=UTF-8' 21 | // }, 22 | // data: data 23 | // }) 24 | // } 25 | export const login = (account, password) => { 26 | const data = { 27 | account, 28 | password 29 | } 30 | return request({ 31 | url: 'auth/login', 32 | method: 'post', 33 | data: data 34 | }) 35 | } 36 | 37 | /** 38 | * 退出登录 39 | * @param token 40 | */ 41 | export const logout = (token) => { 42 | const data = {} 43 | return request({ 44 | url: 'auth/logout', 45 | method: 'get', 46 | data: data 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Erwin Feng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/header-bar/header-bar.vue: -------------------------------------------------------------------------------- 1 | 11 | 37 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/vo/response/PhoneSearchResultResponseVo.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.vo.response; 2 | 3 | import com.fengwenyi.api.result.CommonPage; 4 | import com.fengwenyi.spring_boot_elasticsearch_sample.entity.PhoneEntity; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author Erwin Feng 10 | * @since 2020/8/24 11 | */ 12 | public class PhoneSearchResultResponseVo extends CommonPage> { 13 | 14 | /** 执行耗时 */ 15 | private String execSpendTime; 16 | 17 | public PhoneSearchResultResponseVo() { 18 | } 19 | 20 | public PhoneSearchResultResponseVo(Long currentPage, Integer pageSize, Long totalElements, Long totalPages, List content, String execSpendTime) { 21 | super(currentPage, pageSize, totalElements, totalPages, content); 22 | this.execSpendTime = execSpendTime; 23 | } 24 | 25 | public String getExecSpendTime() { 26 | return execSpendTime; 27 | } 28 | 29 | public void setExecSpendTime(String execSpendTime) { 30 | this.execSpendTime = execSpendTime; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /web/vue-admin-pro/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Vue Admin Pro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/mock/index.js: -------------------------------------------------------------------------------- 1 | import Mock from 'mockjs' 2 | import { login, logout, getUserInfo } from './login' 3 | import { getTableData, getDragList, uploadImage, getOrgData, getTreeSelectData } from './data' 4 | import { getMessageInit, getContentByMsgId, hasRead, removeReaded, restoreTrash, messageCount } from './user' 5 | 6 | // 配置Ajax请求延时,可用来测试网络延迟大时项目中一些效果 7 | Mock.setup({ 8 | timeout: 1000 9 | }) 10 | 11 | // 登录相关和获取用户信息 12 | // Mock.mock(/\/login/, login) 13 | // Mock.mock(/\/get_info/, getUserInfo) 14 | // Mock.mock(/\/logout/, logout) 15 | // Mock.mock(/\/get_table_data/, getTableData) 16 | // Mock.mock(/\/get_drag_list/, getDragList) 17 | // Mock.mock(/\/save_error_logger/, 'success') 18 | // Mock.mock(/\/image\/upload/, uploadImage) 19 | // Mock.mock(/\/message\/init/, getMessageInit) 20 | // Mock.mock(/\/message\/content/, getContentByMsgId) 21 | // Mock.mock(/\/message\/has_read/, hasRead) 22 | // Mock.mock(/\/message\/remove_readed/, removeReaded) 23 | // Mock.mock(/\/message\/restore/, restoreTrash) 24 | // Mock.mock(/\/message\/count/, messageCount) 25 | // Mock.mock(/\/get_org_data/, getOrgData) 26 | // Mock.mock(/\/get_tree_select_data/, getTreeSelectData) 27 | 28 | export default Mock 29 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/language/language.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 52 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/locale/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import { localRead } from '@/libs/util' 4 | import customZhCn from './lang/zh-CN' 5 | import customZhTw from './lang/zh-TW' 6 | import customEnUs from './lang/en-US' 7 | import zhCnLocale from 'view-design/src/locale/lang/zh-CN' 8 | import enUsLocale from 'view-design/src/locale/lang/en-US' 9 | import zhTwLocale from 'view-design/src/locale/lang/zh-TW' 10 | 11 | Vue.use(VueI18n) 12 | 13 | // 自动根据浏览器系统语言设置语言 14 | const navLang = navigator.language 15 | const localLang = (navLang === 'zh-CN' || navLang === 'en-US') ? navLang : false 16 | let lang = localLang || localRead('local') || 'zh-CN' 17 | 18 | Vue.config.lang = lang 19 | 20 | // vue-i18n 6.x+写法 21 | Vue.locale = () => {} 22 | const messages = { 23 | 'zh-CN': Object.assign(zhCnLocale, customZhCn), 24 | 'zh-TW': Object.assign(zhTwLocale, customZhTw), 25 | 'en-US': Object.assign(enUsLocale, customEnUs) 26 | } 27 | const i18n = new VueI18n({ 28 | locale: lang, 29 | messages 30 | }) 31 | 32 | export default i18n 33 | 34 | // vue-i18n 5.x写法 35 | // Vue.locale('zh-CN', Object.assign(zhCnLocale, customZhCn)) 36 | // Vue.locale('en-US', Object.assign(zhTwLocale, customZhTw)) 37 | // Vue.locale('zh-TW', Object.assign(enUsLocale, customEnUs)) 38 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue: -------------------------------------------------------------------------------- 1 | 11 | 47 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/side-menu/side-menu-item.vue: -------------------------------------------------------------------------------- 1 | 19 | 27 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/locale/lang/zh-CN.js: -------------------------------------------------------------------------------- 1 | export default { 2 | home: '首页', 3 | login: '登录', 4 | components: '组件', 5 | count_to_page: '数字渐变', 6 | tables_page: '多功能表格', 7 | split_pane_page: '分割窗口', 8 | markdown_page: 'Markdown编辑器', 9 | editor_page: '富文本编辑器', 10 | icons_page: '自定义图标', 11 | img_cropper_page: '图片编辑器', 12 | update: '上传数据', 13 | join_page: 'QQ群', 14 | doc: '文档', 15 | update_table_page: '上传CSV文件', 16 | update_paste_page: '粘贴表格数据', 17 | multilevel: '多级菜单', 18 | directive_page: '指令', 19 | level_1: 'Level-1', 20 | level_2: 'Level-2', 21 | level_2_1: 'Level-2-1', 22 | level_2_3: 'Level-2-3', 23 | level_2_2: 'Level-2-2', 24 | level_2_2_1: 'Level-2-2-1', 25 | level_2_2_2: 'Level-2-2-2', 26 | excel: 'Excel', 27 | 'upload-excel': '上传excel', 28 | 'export-excel': '导出excel', 29 | tools_methods_page: '工具函数', 30 | drag_list_page: '拖拽列表', 31 | i18n_page: '多语言', 32 | modalTitle: '模态框题目', 33 | content: '这是模态框内容', 34 | buttonText: '显示模态框', 35 | 'i18n-tip': '注:仅此页做了多语言,其他页面没有在多语言包中添加语言内容', 36 | error_store_page: '错误收集', 37 | error_logger_page: '错误日志', 38 | query: '带参路由', 39 | params: '动态路由', 40 | cropper_page: '图片裁剪', 41 | message_page: '消息中心', 42 | tree_table_page: '树状表格', 43 | org_tree_page: '组织结构树', 44 | drag_drawer_page: '可拖动抽屉', 45 | tree_select_page: '树状下拉选择器', 46 | list_page: '认证列表' 47 | } 48 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/locale/lang/zh-TW.js: -------------------------------------------------------------------------------- 1 | export default { 2 | home: '首頁', 3 | login: '登錄', 4 | components: '组件', 5 | count_to_page: '数字渐变', 6 | tables_page: '多功能表格', 7 | split_pane_page: '分割窗口', 8 | markdown_page: 'Markdown編輯器', 9 | editor_page: '富文本編輯器', 10 | icons_page: '自定義圖標', 11 | img_cropper_page: '圖片編輯器', 12 | update: '上傳數據', 13 | join_page: 'QQ群', 14 | doc: '文檔', 15 | update_table_page: '上傳CSV文件', 16 | update_paste_page: '粘貼表格數據', 17 | multilevel: '多级菜单', 18 | directive_page: '指令', 19 | level_1: 'Level-1', 20 | level_2: 'Level-2', 21 | level_2_1: 'Level-2-1', 22 | level_2_3: 'Level-2-3', 23 | level_2_2: 'Level-2-2', 24 | level_2_2_1: 'Level-2-2-1', 25 | level_2_2_2: 'Level-2-2-2', 26 | excel: 'Excel', 27 | 'upload-excel': '上傳excel', 28 | 'export-excel': '導出excel', 29 | tools_methods_page: '工具函數', 30 | drag_list_page: '拖拽列表', 31 | i18n_page: '多語言', 32 | modalTitle: '模態框題目', 33 | content: '這是模態框內容', 34 | buttonText: '顯示模態框', 35 | 'i18n-tip': '注:僅此頁做了多語言,其他頁面沒有在多語言包中添加語言內容', 36 | error_store_page: '錯誤收集', 37 | error_logger_page: '錯誤日誌', 38 | query: '帶參路由', 39 | params: '動態路由', 40 | cropper_page: '圖片裁剪', 41 | message_page: '消息中心', 42 | tree_table_page: '樹狀表格', 43 | org_tree_page: '組織結構樹', 44 | drag_drawer_page: '可拖動抽屜', 45 | tree_select_page: '樹狀下拉選擇器', 46 | list_page: '認證列表' 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/util/JsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.util; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | 6 | import java.util.Collection; 7 | 8 | /** 9 | * @author Erwin Feng 10 | * @since 2020/7/4 11 | */ 12 | public class JsonUtils { 13 | 14 | private static ObjectMapper objectMapper = new ObjectMapper(); 15 | 16 | public static T coverObject(String json, Class clazz) { 17 | try { 18 | return objectMapper.readValue(json, clazz); 19 | } catch (JsonProcessingException e) { 20 | e.printStackTrace(); 21 | } 22 | return null; 23 | } 24 | 25 | public static String coverObject(Object json) { 26 | try { 27 | return objectMapper.writeValueAsString(json); 28 | } catch (JsonProcessingException e) { 29 | e.printStackTrace(); 30 | } 31 | return null; 32 | } 33 | 34 | public static Collection coverCollection(String json, Class> collectionClass) { 35 | try { 36 | return objectMapper.readValue(json, collectionClass); 37 | } catch (JsonProcessingException e) { 38 | e.printStackTrace(); 39 | } 40 | return null; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/config/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | /** 3 | * @description 配置显示在浏览器标签的title 4 | */ 5 | title: 'Vue Admin Pro', 6 | /** 7 | * @description 副标题 8 | */ 9 | subtitle: '始终在追求极简', 10 | /** 11 | * @description token在Cookie中存储的天数,默认1天 12 | */ 13 | cookieExpires: 1, 14 | /** 15 | * @description 是否使用国际化,默认为false 16 | * 如果不使用,则需要在路由中给需要在菜单中展示的路由设置meta: {title: 'xxx'} 17 | * 用来在菜单中显示文字 18 | */ 19 | useI18n: false, 20 | /** 21 | * @description api请求基础路径 22 | */ 23 | baseUrl: { 24 | // dev: 'https://www.easy-mock.com/mock/5add9213ce4d0e69998a6f51/iview-admin/', 25 | dev: 'http://localhost:9099', 26 | pro: 'https://produce.com' 27 | }, 28 | /** 29 | * @description 默认打开的首页的路由name值,默认为home 30 | */ 31 | homeName: 'home', 32 | /** 33 | * @description 需要加载的插件 34 | */ 35 | plugin: { 36 | 'error-store': { 37 | showInHeader: true, // 设为false后不会在顶部显示错误日志徽标 38 | developmentOff: true // 设为true后在开发环境不会收集错误信息,方便开发中排查错误 39 | } 40 | }, 41 | /** 42 | * 接口请求配置 43 | */ 44 | api: { 45 | /** 46 | * header配置 47 | */ 48 | header: { 49 | /** 50 | * 是否携带token(当token存在时) 51 | */ 52 | token: true, 53 | /** 54 | * 自定义token key 55 | */ 56 | tokenKey: 'token', 57 | /** 58 | * 是否采用JSON方式提交 59 | */ 60 | json: true 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/charts/bar.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 59 | -------------------------------------------------------------------------------- /web/vue-admin-pro/vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | const resolve = dir => { 4 | return path.join(__dirname, dir) 5 | } 6 | 7 | // 项目部署基础 8 | // 默认情况下,我们假设你的应用将被部署在域的根目录下, 9 | // 例如:https://www.my-app.com/ 10 | // 默认:'/' 11 | // 如果您的应用程序部署在子路径中,则需要在这指定子路径 12 | // 例如:https://www.foobar.com/my-app/ 13 | // 需要将它改为'/my-app/' 14 | // iview-admin线上演示打包路径: https://file.iviewui.com/admin-dist/ 15 | const BASE_URL = process.env.NODE_ENV === 'production' 16 | ? '/' 17 | : '/' 18 | 19 | module.exports = { 20 | // Project deployment base 21 | // By default we assume your app will be deployed at the root of a domain, 22 | // e.g. https://www.my-app.com/ 23 | // If your app is deployed at a sub-path, you will need to specify that 24 | // sub-path here. For example, if your app is deployed at 25 | // https://www.foobar.com/my-app/ 26 | // then change this to '/my-app/' 27 | publicPath: BASE_URL, 28 | // tweak internal webpack configuration. 29 | // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md 30 | // 如果你不需要使用eslint,把lintOnSave设为false即可 31 | lintOnSave: true, 32 | chainWebpack: config => { 33 | config.resolve.alias 34 | .set('@', resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components')) 35 | .set('_c', resolve('src/components')) 36 | }, 37 | // 设为false打包时不生成.map文件 38 | productionSourceMap: false 39 | // 这里写你调用接口的基础路径,来解决跨域,如果设置了代理,那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串 40 | // devServer: { 41 | // proxy: 'localhost:3000' 42 | // } 43 | } 44 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import store from './store' 7 | import ViewUI from 'view-design' 8 | import i18n from '@/locale' 9 | import config from '@/config' 10 | import importDirective from '@/directive' 11 | import { directive as clickOutside } from 'v-click-outside-x' 12 | import installPlugin from '@/plugin' 13 | import './index.less' 14 | import '@/assets/icons/iconfont.css' 15 | import '@/assets/fonts/menu/iconfont.css' 16 | import '@/assets/fonts/menu/iconfont.js' 17 | import TreeTable from 'tree-table-vue' 18 | import VOrgTree from 'v-org-tree' 19 | import 'v-org-tree/dist/v-org-tree.css' 20 | 21 | // 实际打包时应该不引入mock 22 | /* eslint-disable */ 23 | if (process.env.NODE_ENV !== 'production') require('@/mock') 24 | 25 | Vue.use(ViewUI, { 26 | i18n: (key, value) => i18n.t(key, value) 27 | }) 28 | Vue.use(TreeTable) 29 | Vue.use(VOrgTree) 30 | /** 31 | * @description 注册admin内置插件 32 | */ 33 | installPlugin(Vue) 34 | /** 35 | * @description 生产环境关掉提示 36 | */ 37 | Vue.config.productionTip = false 38 | /** 39 | * @description 全局注册应用配置 40 | */ 41 | Vue.prototype.$config = config 42 | /** 43 | * 注册指令 44 | */ 45 | importDirective(Vue) 46 | Vue.directive('clickOutside', clickOutside) 47 | 48 | /* eslint-disable no-new */ 49 | new Vue({ 50 | el: '#app', 51 | router, 52 | i18n, 53 | store, 54 | render: h => h(App) 55 | }) 56 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/router/routers.js: -------------------------------------------------------------------------------- 1 | import Main from '@/components/main' 2 | import parentView from '@/components/parent-view' 3 | 4 | /** 5 | * iview-admin中meta除了原生参数外可配置的参数: 6 | * meta: { 7 | * title: { String|Number|Function } 8 | * 显示在侧边栏、面包屑和标签栏的文字 9 | * 使用'{{ 多语言字段 }}'形式结合多语言使用,例子看多语言的路由配置; 10 | * 可以传入一个回调函数,参数是当前路由对象,例子看动态路由和带参路由 11 | * hideInBread: (false) 设为true后此级路由将不会出现在面包屑中,示例看QQ群路由配置 12 | * hideInMenu: (false) 设为true后在左侧菜单不会显示该页面选项 13 | * notCache: (false) 设为true后页面在切换标签后不会缓存,如果需要缓存,无需设置这个字段,而且需要设置页面组件name属性和路由配置的name一致 14 | * access: (null) 可访问该页面的权限数组,当前路由设置的权限会影响子路由 15 | * icon: (-) 该页面在左侧菜单、面包屑和标签导航处显示的图标,如果是自定义图标,需要在图标名称前加下划线'_' 16 | * beforeCloseName: (-) 设置该字段,则在关闭当前tab页时会去'@/router/before-close.js'里寻找该字段名对应的方法,作为关闭前的钩子函数 17 | * } 18 | */ 19 | 20 | export default [ 21 | { 22 | path: '/login', 23 | name: 'login', 24 | meta: { 25 | title: 'Login - 登录', 26 | hideInMenu: true 27 | }, 28 | component: () => import('@/view/Login/Login') 29 | }, 30 | { 31 | path: '/', 32 | name: '_home', 33 | redirect: '/home', 34 | component: Main, 35 | meta: { 36 | hideInMenu: true, 37 | notCache: true 38 | }, 39 | children: [ 40 | { 41 | path: '/home', 42 | name: 'home', 43 | meta: { 44 | hideInMenu: true, 45 | title: '首页', 46 | notCache: true, 47 | icon: 'md-home' 48 | }, 49 | component: () => import('@/view/Home/Home') 50 | } 51 | ] 52 | } 53 | ] 54 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/directive/module/draggable.js: -------------------------------------------------------------------------------- 1 | import { on } from '@/libs/tools' 2 | export default { 3 | inserted: (el, binding, vnode) => { 4 | let triggerDom = document.querySelector(binding.value.trigger) 5 | triggerDom.style.cursor = 'move' 6 | let bodyDom = document.querySelector(binding.value.body) 7 | let pageX = 0 8 | let pageY = 0 9 | let transformX = 0 10 | let transformY = 0 11 | let canMove = false 12 | const handleMousedown = e => { 13 | let transform = /\(.*\)/.exec(bodyDom.style.transform) 14 | if (transform) { 15 | transform = transform[0].slice(1, transform[0].length - 1) 16 | let splitxy = transform.split('px, ') 17 | transformX = parseFloat(splitxy[0]) 18 | transformY = parseFloat(splitxy[1].split('px')[0]) 19 | } 20 | pageX = e.pageX 21 | pageY = e.pageY 22 | canMove = true 23 | } 24 | const handleMousemove = e => { 25 | let xOffset = e.pageX - pageX + transformX 26 | let yOffset = e.pageY - pageY + transformY 27 | if (canMove) bodyDom.style.transform = `translate(${xOffset}px, ${yOffset}px)` 28 | } 29 | const handleMouseup = e => { 30 | canMove = false 31 | } 32 | on(triggerDom, 'mousedown', handleMousedown) 33 | on(document, 'mousemove', handleMousemove) 34 | on(document, 'mouseup', handleMouseup) 35 | }, 36 | update: (el, binding, vnode) => { 37 | if (!binding.value.recover) return 38 | let bodyDom = document.querySelector(binding.value.body) 39 | bodyDom.style.transform = '' 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import routes from './routers' 4 | // import store from '@/store' 5 | import ViewUI from 'view-design' 6 | // import { setToken, getToken, canTurnTo, setTitle } from '@/libs/util' 7 | import { getToken, canTurnTo, setTitle } from '@/libs/util' 8 | import config from '@/config' 9 | const { homeName } = config 10 | 11 | Vue.use(Router) 12 | const router = new Router({ 13 | routes, 14 | mode: 'history' 15 | }) 16 | const LOGIN_PAGE_NAME = 'login' 17 | 18 | const turnTo = (to, access, next) => { 19 | if (canTurnTo(to.name, access, routes)) next() // 有权限,可访问 20 | else next({ replace: true, name: 'error_401' }) // 无权限,重定向到401页面 21 | } 22 | 23 | router.beforeEach((to, from, next) => { 24 | ViewUI.LoadingBar.start() 25 | next() 26 | }) 27 | 28 | // router.beforeEach((to, from, next) => { 29 | // ViewUI.LoadingBar.start() 30 | // const token = getToken() 31 | // if (!token && to.name !== LOGIN_PAGE_NAME) { 32 | // // 未登录且要跳转的页面不是登录页 33 | // next({ 34 | // name: LOGIN_PAGE_NAME // 跳转到登录页 35 | // }) 36 | // } else if (!token && to.name === LOGIN_PAGE_NAME) { 37 | // // 未登陆且要跳转的页面是登录页 38 | // next() // 跳转 39 | // } else if (token && to.name === LOGIN_PAGE_NAME) { 40 | // // 已登录且要跳转的页面是登录页 41 | // next({ 42 | // name: homeName // 跳转到homeName页 43 | // }) 44 | // } else { 45 | // turnTo(to, ['admin'], next) 46 | // } 47 | // }) 48 | 49 | router.afterEach(to => { 50 | setTitle(to, router.app) 51 | ViewUI.LoadingBar.finish() 52 | window.scrollTo(0, 0) 53 | }) 54 | 55 | export default router 56 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/user/user.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 66 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/locale/lang/en-US.js: -------------------------------------------------------------------------------- 1 | export default { 2 | home: 'Home', 3 | login: 'Login', 4 | components: 'Components', 5 | count_to_page: 'Count-to', 6 | tables_page: 'Table', 7 | split_pane_page: 'Split-pane', 8 | markdown_page: 'Markdown-editor', 9 | editor_page: 'Rich-Text-Editor', 10 | icons_page: 'Custom-icon', 11 | img_cropper_page: 'Image-editor', 12 | update: 'Update', 13 | doc: 'Document', 14 | join_page: 'QQ Group', 15 | update_table_page: 'Update .CSV', 16 | update_paste_page: 'Paste Table Data', 17 | multilevel: 'multilevel', 18 | directive_page: 'Directive', 19 | level_1: 'Level-1', 20 | level_2: 'Level-2', 21 | level_2_1: 'Level-2-1', 22 | level_2_3: 'Level-2-3', 23 | level_2_2: 'Level-2-2', 24 | level_2_2_1: 'Level-2-2-1', 25 | level_2_2_2: 'Level-2-2-2', 26 | excel: 'Excel', 27 | 'upload-excel': 'Upload Excel', 28 | 'export-excel': 'Export Excel', 29 | tools_methods_page: 'Tools Methods', 30 | drag_list_page: 'Drag-list', 31 | i18n_page: 'Internationalization', 32 | modalTitle: 'Modal Title', 33 | content: 'This is the modal box content.', 34 | buttonText: 'Show Modal', 35 | 'i18n-tip': 'Note: Only this page is multi-language, other pages do not add language content to the multi-language package.', 36 | error_store_page: 'Error Collection', 37 | error_logger_page: 'Error Logger', 38 | query: 'Query', 39 | params: 'Params', 40 | cropper_page: 'Cropper', 41 | message_page: 'Message Center', 42 | tree_table_page: 'Tree Table', 43 | org_tree_page: 'Org Tree', 44 | drag_drawer_page: 'Draggable Drawer', 45 | tree_select_page: 'Tree Selector', 46 | list_page: 'Auth List' 47 | } 48 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/icon-social-zhihu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/tree-select/tree-select.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/mock/data/tree-select.js: -------------------------------------------------------------------------------- 1 | export const treeData = [ 2 | { 3 | id: 1, 4 | title: '1', 5 | children: [ 6 | { 7 | id: 11, 8 | title: '1-1', 9 | loading: false, 10 | children: [ 11 | // { 12 | // id: 111, 13 | // title: '1-1-1' 14 | // }, 15 | // { 16 | // id: 112, 17 | // title: '1-1-2' 18 | // }, 19 | // { 20 | // id: 113, 21 | // title: '1-1-3' 22 | // }, 23 | // { 24 | // id: 114, 25 | // title: '1-1-4' 26 | // } 27 | ] 28 | }, 29 | { 30 | id: 12, 31 | title: '1-2', 32 | children: [ 33 | { 34 | id: 121, 35 | title: '1-2-1' 36 | } 37 | ] 38 | } 39 | ] 40 | } 41 | ] 42 | 43 | export const newTreeData = [ 44 | { 45 | id: 'a', 46 | title: 'a', 47 | children: [ 48 | { 49 | id: 'a1', 50 | title: 'a-1', 51 | children: [ 52 | { 53 | id: 112, 54 | title: '1-1-2' 55 | }, 56 | { 57 | id: 'a12', 58 | title: 'a-1-2' 59 | }, 60 | { 61 | id: 'a13', 62 | title: 'a-1-3' 63 | }, 64 | { 65 | id: 'a14', 66 | title: 'a-1-4' 67 | } 68 | ] 69 | }, 70 | { 71 | id: 'a2', 72 | title: 'a-2', 73 | children: [ 74 | { 75 | id: 'a21', 76 | title: 'b-2-1' 77 | } 78 | ] 79 | } 80 | ] 81 | } 82 | ] 83 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/entity/PhoneEntity.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.entity; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | import lombok.experimental.Accessors; 7 | import org.springframework.data.annotation.Id; 8 | import org.springframework.data.elasticsearch.annotations.Document; 9 | 10 | import java.io.Serializable; 11 | import java.math.BigDecimal; 12 | 13 | /** 14 | * 手机实体类 15 | * @author Erwin Feng 16 | * @since 2020/7/4 17 | */ 18 | //@ApiModel("手机实体类") 19 | @Data 20 | @Accessors(chain = true) 21 | @Document(indexName = "spring-boot-elasticsearch-sample-phone") 22 | public class PhoneEntity implements Serializable { 23 | 24 | /* ID */ 25 | @ApiModelProperty("ID") 26 | @Id 27 | private String id; 28 | 29 | /* 名称 */ 30 | @ApiModelProperty("名称") 31 | private String name; 32 | 33 | /* 推广广告 */ 34 | @ApiModelProperty("推广广告") 35 | private String ad; 36 | 37 | /* 售价 */ 38 | @ApiModelProperty("售价") 39 | private BigDecimal price; 40 | 41 | /* 图片URL */ 42 | @ApiModelProperty("图片URL") 43 | private String imgUrl; 44 | 45 | /* 内存 */ 46 | @ApiModelProperty("内存") 47 | private String memory; 48 | 49 | /* 存储 */ 50 | @ApiModelProperty("存储") 51 | private String storage; 52 | 53 | /* 屏幕 */ 54 | @ApiModelProperty("屏幕") 55 | private String screen; 56 | 57 | 58 | /* 创建时间,时间戳,毫秒 */ 59 | @ApiModelProperty("创建时间戳(毫秒)") 60 | private Long createTimeStamp; 61 | 62 | /* 创建时间,yyyy-MM-dd HH:mm:ss,SSS */ 63 | @ApiModelProperty("创建时间字符串") 64 | private String createTimeString; 65 | 66 | } 67 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/charts/pie.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 71 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/fonts/menu/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/drag-drawer/index.less: -------------------------------------------------------------------------------- 1 | @prefix: ~"drag-drawer"; 2 | @drag-drawer-trigger-height: 100px; 3 | @drag-drawer-trigger-width: 8px; 4 | 5 | .@{prefix}-wrapper{ 6 | &.no-select{ 7 | user-select: none; 8 | } 9 | &.pointer-events-none{ 10 | pointer-events: none; 11 | & .@{prefix}-trigger-wrapper{ 12 | pointer-events: all; 13 | } 14 | } 15 | .ivu-drawer{ 16 | &-header{ 17 | overflow: hidden !important; 18 | box-sizing: border-box; 19 | } 20 | &-body{ 21 | padding: 0; 22 | overflow: visible; 23 | position: static; 24 | display: flex; 25 | flex-direction: column; 26 | } 27 | } 28 | .@{prefix}-body-wrapper{ 29 | width: 100%; 30 | height: 100%; 31 | padding: 16px; 32 | overflow: auto; 33 | } 34 | .@{prefix}-trigger-wrapper{ 35 | top: 0; 36 | height: 100%; 37 | width: 0; 38 | .@{prefix}-move-trigger{ 39 | position: absolute; 40 | top: 50%; 41 | height: @drag-drawer-trigger-height; 42 | width: @drag-drawer-trigger-width; 43 | background: rgb(243, 243, 243); 44 | transform: translate(-50%, -50%); 45 | border-radius: ~"4px / 6px"; 46 | box-shadow: 0 0 1px 1px rgba(0, 0, 0, .2); 47 | line-height: @drag-drawer-trigger-height; 48 | cursor: col-resize; 49 | &-point{ 50 | display: inline-block; 51 | width: 50%; 52 | transform: translateX(50%); 53 | i{ 54 | display: block; 55 | border-bottom: 1px solid rgb(192, 192, 192); 56 | padding-bottom: 2px; 57 | } 58 | } 59 | } 60 | } 61 | .@{prefix}-footer{ 62 | flex-grow: 1; 63 | width: 100%; 64 | bottom: 0; 65 | left: 0; 66 | border-top: 1px solid #e8e8e8; 67 | padding: 10px 16px; 68 | background: #fff; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/mock/user.js: -------------------------------------------------------------------------------- 1 | import Mock from 'mockjs' 2 | import { doCustomTimes } from '@/libs/util' 3 | const Random = Mock.Random 4 | 5 | export const getMessageInit = () => { 6 | let unreadList = [] 7 | doCustomTimes(3, () => { 8 | unreadList.push(Mock.mock({ 9 | title: Random.cword(10, 15), 10 | create_time: '@date', 11 | msg_id: Random.increment(100) 12 | })) 13 | }) 14 | let readedList = [] 15 | doCustomTimes(4, () => { 16 | readedList.push(Mock.mock({ 17 | title: Random.cword(10, 15), 18 | create_time: '@date', 19 | msg_id: Random.increment(100) 20 | })) 21 | }) 22 | let trashList = [] 23 | doCustomTimes(2, () => { 24 | trashList.push(Mock.mock({ 25 | title: Random.cword(10, 15), 26 | create_time: '@date', 27 | msg_id: Random.increment(100) 28 | })) 29 | }) 30 | return { 31 | unread: unreadList, 32 | readed: readedList, 33 | trash: trashList 34 | } 35 | } 36 | 37 | export const getContentByMsgId = () => { 38 | return `
        这是消息内容,这个内容是使用富文本编辑器编辑的,所以你可以看到一些格式
  1. 你可以查看Mock返回的数据格式,和api请求的接口,来确定你的后端接口的开发
  2. 使用你的真实接口后,前端页面基本不需要修改即可满足基本需求
  3. 快来试试吧

${Random.csentence(100, 200)}

` 39 | } 40 | 41 | export const hasRead = () => { 42 | return true 43 | } 44 | 45 | export const removeReaded = () => { 46 | return true 47 | } 48 | 49 | export const restoreTrash = () => { 50 | return true 51 | } 52 | 53 | export const messageCount = () => { 54 | return 3 55 | } 56 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/fonts/menu/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('./iconfont.eot?t=1559802228430'); /* IE9 */ 3 | src: url('./iconfont.eot?t=1559802228430#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAMAAAsAAAAAB4QAAAK0AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCfgqCcIJAATYCJAMMCwgABCAFhG0HOhuCBhHVk1lkXxdvDJFe2IgRbLhXlPq87qes+LsXmYrShXKxrCuKKHs+H8TD9/v9b+1zzrv/fNOmlhiSiKRHaCQSQ6iuIeKJDH8608Ua3uh/YJ4TIlsR0tbmS/X1CWRzAHRDBLO0dji5qwcbcBBjIDQALdj+b+vES1pIWCSedu3I9hXGG+OkHzz4+vxx77RJYSDzAQWawlzLPnVRPCmgwPbEKJIFPMW4ZXjVpW7snThNoMuENbHv6nhAVdBJgTjragWg5jyKIsar0NSsLOI2VE1XUrgVPj/+2BQESSujM0+dscrArh99WhuttI/CHc8EcR0ZayhEu9ZySo4ja7IuPVLMsa5BwY/rRz5ntX94hEQ0aG4PWMLidEZcV+LUuPgCCWTQoOI8LmL8iLMoPVQ8Rm6vZ/Ks/ae59rT1iVJCZQDji0+u/S98cPp45Q8v1ru/a+05/8GeiamWX4WwfbgIxzdc3dqxVijN75jQ79f3TWaIpyZV6a7aJBjXb9jKJ7hTXH/4XJrHKPcYdMJ+A/Rn9JU2j/bJ79I65PXwF4Gg/Tj7P4d47S7ggyvSFHBZPW1r8Au4wKpi8Kk2F43jcixrtiXjksAsyW6DOoZ8ZZeNgnMJ1WgKSYdxyKo5dMGvQUu3zdCodkKXVQfXdxt2ThalEysuIAgDXkPS5y1kA96jC/4LtIz5B42BgKFLO5gduy2E6A4KVoot1H9wDffk6PUQ5d/RTLGSLD8kvVFG54c8yYrxG/YoY8wZP6ZQJSDhDq7oPIyRYRD22GhiVYcyTanuSknD3ewwMwQrxRbqP7iGe/Ib66H0+DuaKVbSgqjTv1FG1zvkSQZA3yQ9CHEtl4wfU6gSkHAHV2TCaEcYhvphHhtNLENoKFNSi6CSZH5Z93y7mM0OM7p8OU+Ro8A77Ccm2oTmfjYD') format('woff2'), 5 | url('./iconfont.woff?t=1559802228430') format('woff'), 6 | url('./iconfont.ttf?t=1559802228430') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('./iconfont.svg?t=1559802228430#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-menuoff:before { 19 | content: "\e77c"; 20 | } 21 | 22 | .icon-menuon:before { 23 | content: "\e77d"; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/editor/editor.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 70 | 71 | 76 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/login-form/login-form.vue: -------------------------------------------------------------------------------- 1 | 22 | 73 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/markdown/markdown.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 63 | 64 | 77 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/controller/DataController.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.controller; 2 | 3 | import com.fengwenyi.api.result.CommonResponse; 4 | import com.fengwenyi.spring_boot_elasticsearch_sample.entity.PhoneEntity; 5 | import com.fengwenyi.spring_boot_elasticsearch_sample.repository.PhoneRepository; 6 | import com.fengwenyi.spring_boot_elasticsearch_sample.service.DataService; 7 | import io.swagger.annotations.Api; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RestController; 13 | import reactor.core.publisher.Mono; 14 | 15 | /** 16 | * 数据接口 17 | * @author Erwin Feng 18 | * @since 2020/7/10 19 | */ 20 | @Api("搜索服务接口") 21 | @RestController 22 | @RequestMapping(value = "/api/data", 23 | produces = MediaType.APPLICATION_JSON_VALUE, 24 | consumes = MediaType.APPLICATION_JSON_VALUE) 25 | public class DataController { 26 | 27 | @Autowired 28 | private DataService dataService; 29 | 30 | @Autowired 31 | private PhoneRepository phoneRepository; 32 | 33 | // 抓取数据接口 34 | @GetMapping("/grab") 35 | public Mono> grab() { 36 | new Thread(() -> dataService.jd()).start(); 37 | return Mono.just(CommonResponse.ok()); 38 | } 39 | 40 | // 导出数据接口 41 | @GetMapping("/export") 42 | public Mono> export() { 43 | new Thread(() -> dataService.export()).start(); 44 | return Mono.just(CommonResponse.ok()); 45 | } 46 | 47 | @GetMapping("all") 48 | public Mono> getAll() { 49 | Iterable all = phoneRepository.findAll(); 50 | all.forEach(System.out::println); 51 | return Mono.just(CommonResponse.ok()); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/info-card/infor-card.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 55 | 56 | 95 | -------------------------------------------------------------------------------- /src/main/java/com/fengwenyi/spring_boot_elasticsearch_sample/controller/SearchController.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.controller; 2 | 3 | import com.fengwenyi.api.result.CommonResponse; 4 | import com.fengwenyi.spring_boot_elasticsearch_sample.service.SearchService; 5 | import com.fengwenyi.spring_boot_elasticsearch_sample.vo.request.AdvancedSearchRequestVo; 6 | import com.fengwenyi.spring_boot_elasticsearch_sample.vo.request.FullSearchRequestVo; 7 | import com.fengwenyi.spring_boot_elasticsearch_sample.vo.response.PhoneSearchResultResponseVo; 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiOperation; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.http.MediaType; 12 | import org.springframework.web.bind.annotation.*; 13 | import reactor.core.publisher.Mono; 14 | 15 | /** 16 | * 搜索接口 17 | * @author Erwin Feng 18 | * @since 2020/7/4 19 | */ 20 | @CrossOrigin 21 | @Api("搜索服务接口") 22 | @RestController 23 | @RequestMapping(value = "/api/search", 24 | produces = MediaType.APPLICATION_JSON_VALUE, 25 | consumes = MediaType.APPLICATION_JSON_VALUE) 26 | public class SearchController { 27 | 28 | @Autowired 29 | private SearchService searchService; 30 | 31 | // 全局搜索 32 | @ApiOperation("全局搜索接口") 33 | @PostMapping("/full") 34 | public Mono> fullSearch(@RequestBody FullSearchRequestVo requestVo) { 35 | CommonResponse responseEntity = searchService.fullSearch(requestVo); 36 | return Mono.just(responseEntity); 37 | } 38 | 39 | // 高级搜索 40 | @ApiOperation("高级搜索接口") 41 | @PostMapping("/advanced") 42 | public Mono> advancedSearch(@RequestBody AdvancedSearchRequestVo requestVo) { 43 | CommonResponse responseEntity = searchService.advancedSearch(requestVo); 44 | return Mono.just(responseEntity); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/tags-nav/tags-nav.less: -------------------------------------------------------------------------------- 1 | .no-select{ 2 | -webkit-touch-callout: none; 3 | -webkit-user-select: none; 4 | -khtml-user-select: none; 5 | -moz-user-select: none; 6 | -ms-user-select: none; 7 | user-select: none; 8 | } 9 | .size{ 10 | width: 100%; 11 | height: 100%; 12 | } 13 | .tags-nav{ 14 | position: relative; 15 | border-top: 1px solid #F0F0F0; 16 | border-bottom: 1px solid #F0F0F0; 17 | .no-select; 18 | .size; 19 | .close-con{ 20 | position: absolute; 21 | right: 0; 22 | top: 0; 23 | height: 100%; 24 | width: 32px; 25 | background: #fff; 26 | text-align: center; 27 | z-index: 10; 28 | } 29 | .btn-con{ 30 | position: absolute; 31 | top: 0px; 32 | height: 100%; 33 | background: #fff; 34 | padding-top: 3px; 35 | z-index: 10; 36 | button{ 37 | padding: 6px 4px; 38 | line-height: 14px; 39 | text-align: center; 40 | } 41 | &.left-btn{ 42 | left: 0px; 43 | } 44 | &.right-btn{ 45 | right: 32px; 46 | border-right: 1px solid #F0F0F0; 47 | } 48 | } 49 | .scroll-outer{ 50 | position: absolute; 51 | left: 28px; 52 | right: 61px; 53 | top: 0; 54 | bottom: 0; 55 | box-shadow: 0px 0 3px 2px rgba(100,100,100,.1) inset; 56 | .scroll-body{ 57 | height: ~"calc(100% - 1px)"; 58 | display: inline-block; 59 | padding: 1px 4px 0; 60 | position: absolute; 61 | overflow: visible; 62 | white-space: nowrap; 63 | transition: left .3s ease; 64 | .ivu-tag-dot-inner{ 65 | transition: background .2s ease; 66 | } 67 | } 68 | } 69 | .contextmenu { 70 | position: absolute; 71 | margin: 0; 72 | padding: 5px 0; 73 | background: #fff; 74 | z-index: 1000; 75 | list-style-type: none; 76 | border-radius: 4px; 77 | box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .1); 78 | li { 79 | margin: 0; 80 | padding: 5px 15px; 81 | cursor: pointer; 82 | &:hover { 83 | background: #eee; 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/tables/edit.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 45 | 46 | 74 | -------------------------------------------------------------------------------- /web/vue-admin-pro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-admin-pro", 3 | "version": "1.0.2", 4 | "author": "Erwin.Feng", 5 | "private": false, 6 | "scripts": { 7 | "dev": "vue-cli-service serve --open --port 9292", 8 | "build": "vue-cli-service build", 9 | "lint": "vue-cli-service lint", 10 | "test:unit": "vue-cli-service test:unit", 11 | "test:e2e": "vue-cli-service test:e2e" 12 | }, 13 | "dependencies": { 14 | "axios": "^0.18.0", 15 | "clipboard": "^2.0.0", 16 | "codemirror": "^5.38.0", 17 | "countup": "^1.8.2", 18 | "cropperjs": "^1.2.2", 19 | "dayjs": "^1.7.7", 20 | "echarts": "^4.0.4", 21 | "html2canvas": "^1.0.0-alpha.12", 22 | "iview-area": "^1.5.17", 23 | "js-cookie": "^2.2.0", 24 | "simplemde": "^1.11.2", 25 | "sortablejs": "^1.7.0", 26 | "tree-table-vue": "^1.1.0", 27 | "v-org-tree": "^1.0.6", 28 | "view-design": "^4.0.2", 29 | "vue": "^2.5.10", 30 | "vue-i18n": "^7.8.0", 31 | "vue-router": "^3.0.1", 32 | "vuedraggable": "^2.16.0", 33 | "vuex": "^3.0.1", 34 | "wangeditor": "^3.1.1", 35 | "xlsx": "^0.13.3" 36 | }, 37 | "devDependencies": { 38 | "@vue/cli-plugin-babel": "^3.0.1", 39 | "@vue/cli-plugin-eslint": "^3.0.1", 40 | "@vue/cli-plugin-unit-mocha": "^3.0.1", 41 | "@vue/cli-service": "^3.0.1", 42 | "@vue/eslint-config-standard": "^3.0.0-beta.10", 43 | "@vue/test-utils": "^1.0.0-beta.10", 44 | "chai": "^4.1.2", 45 | "eslint-plugin-cypress": "^2.0.1", 46 | "less": "^2.7.3", 47 | "less-loader": "^4.0.5", 48 | "lint-staged": "^6.0.0", 49 | "mockjs": "^1.0.1-beta3", 50 | "stylus": "^0.54.7", 51 | "stylus-loader": "^3.0.2", 52 | "vue-template-compiler": "^2.5.13" 53 | }, 54 | "browserslist": [ 55 | "> 1%", 56 | "last 2 versions", 57 | "not ie <= 8" 58 | ], 59 | "gitHooks": { 60 | "pre-commit": "lint-staged" 61 | }, 62 | "lint-staged": { 63 | "*.js": [ 64 | "vue-cli-service lint", 65 | "git add" 66 | ], 67 | "*.vue": [ 68 | "vue-cli-service lint", 69 | "git add" 70 | ] 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/libs/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import store from '@/store' 3 | // import { Spin } from 'view-design' 4 | const addErrorLog = errorInfo => { 5 | const { statusText, status, request: { responseURL } } = errorInfo 6 | let info = { 7 | type: 'ajax', 8 | code: status, 9 | mes: statusText, 10 | url: responseURL 11 | } 12 | if (!responseURL.includes('save_error_logger')) store.dispatch('addErrorLog', info) 13 | } 14 | 15 | class HttpRequest { 16 | constructor (baseUrl = baseURL) { 17 | this.baseUrl = baseUrl 18 | this.queue = {} 19 | } 20 | getInsideConfig () { 21 | const config = { 22 | baseURL: this.baseUrl, 23 | headers: { 24 | // 25 | } 26 | } 27 | return config 28 | } 29 | destroy (url) { 30 | delete this.queue[url] 31 | if (!Object.keys(this.queue).length) { 32 | // Spin.hide() 33 | } 34 | } 35 | interceptors (instance, url) { 36 | // 请求拦截 37 | instance.interceptors.request.use(config => { 38 | // 添加全局的loading... 39 | if (!Object.keys(this.queue).length) { 40 | // Spin.show() // 不建议开启,因为界面不友好 41 | } 42 | this.queue[url] = true 43 | return config 44 | }, error => { 45 | return Promise.reject(error) 46 | }) 47 | // 响应拦截 48 | instance.interceptors.response.use(res => { 49 | this.destroy(url) 50 | const { data, status } = res 51 | return { data, status } 52 | }, error => { 53 | this.destroy(url) 54 | let errorInfo = error.response 55 | if (!errorInfo) { 56 | const { request: { statusText, status }, config } = JSON.parse(JSON.stringify(error)) 57 | errorInfo = { 58 | statusText, 59 | status, 60 | request: { responseURL: config.url } 61 | } 62 | } 63 | addErrorLog(errorInfo) 64 | return Promise.reject(error) 65 | }) 66 | } 67 | request (options) { 68 | const instance = axios.create() 69 | options = Object.assign(this.getInsideConfig(), options) 70 | this.interceptors(instance, options.url) 71 | return instance(options) 72 | } 73 | } 74 | export default HttpRequest 75 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/side-menu/collapsed-menu.vue: -------------------------------------------------------------------------------- 1 | 12 | 52 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/paste-editor/plugins/placeholder.js: -------------------------------------------------------------------------------- 1 | export default (codemirror) => { 2 | (function (mod) { 3 | mod(codemirror) 4 | })(function (CodeMirror) { 5 | CodeMirror.defineOption('placeholder', '', function (cm, val, old) { 6 | var prev = old && old !== CodeMirror.Init 7 | if (val && !prev) { 8 | cm.on('blur', onBlur) 9 | cm.on('change', onChange) 10 | cm.on('swapDoc', onChange) 11 | onChange(cm) 12 | } else if (!val && prev) { 13 | cm.off('blur', onBlur) 14 | cm.off('change', onChange) 15 | cm.off('swapDoc', onChange) 16 | clearPlaceholder(cm) 17 | var wrapper = cm.getWrapperElement() 18 | wrapper.className = wrapper.className.replace(' CodeMirror-empty', '') 19 | } 20 | 21 | if (val && !cm.hasFocus()) onBlur(cm) 22 | }) 23 | 24 | function clearPlaceholder (cm) { 25 | if (cm.state.placeholder) { 26 | cm.state.placeholder.parentNode.removeChild(cm.state.placeholder) 27 | cm.state.placeholder = null 28 | } 29 | } 30 | function setPlaceholder (cm) { 31 | clearPlaceholder(cm) 32 | var elt = cm.state.placeholder = document.createElement('pre') 33 | elt.style.cssText = 'height: 0; overflow: visible; color: #80848f;' 34 | elt.style.direction = cm.getOption('direction') 35 | elt.className = 'CodeMirror-placeholder' 36 | var placeHolder = cm.getOption('placeholder') 37 | if (typeof placeHolder === 'string') placeHolder = document.createTextNode(placeHolder) 38 | elt.appendChild(placeHolder) 39 | cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild) 40 | } 41 | 42 | function onBlur (cm) { 43 | if (isEmpty(cm)) setPlaceholder(cm) 44 | } 45 | function onChange (cm) { 46 | let wrapper = cm.getWrapperElement() 47 | let empty = isEmpty(cm) 48 | wrapper.className = wrapper.className.replace(' CodeMirror-empty', '') + (empty ? ' CodeMirror-empty' : '') 49 | 50 | if (empty) setPlaceholder(cm) 51 | else clearPlaceholder(cm) 52 | } 53 | 54 | function isEmpty (cm) { 55 | return (cm.lineCount() === 1) && (cm.getLine(0) === '') 56 | } 57 | }) 58 | } 59 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/libs/request.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import config from '@/config' 3 | import { Message } from 'view-design' 4 | import { setToken, getToken } from '@/libs/util' 5 | import Router from '@/router/index' 6 | 7 | const baseUrl = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro 8 | 9 | // create an axios instance 10 | const service = axios.create({ 11 | baseURL: baseUrl, // url = base url + request url 12 | // withCredentials: true, // send cookies when cross-domain requests 13 | timeout: 5000 // request timeout 14 | }) 15 | 16 | // request interceptor 17 | service.interceptors.request.use( 18 | requestConfig => { 19 | // do something before request is sent 20 | if (config.api.header.token && getToken()) { 21 | // let each request carry token 22 | // ['X-Token'] is a custom headers key 23 | // please modify it according to the actual situation 24 | requestConfig.headers[config.api.header.tokenKey] = getToken() 25 | } 26 | if (config.api.header.json) { 27 | requestConfig.headers['Content-Type'] = 'application/json; charset=UTF-8' 28 | } 29 | return requestConfig 30 | }, 31 | error => { 32 | // do something with request error 33 | console.log(error) // for debug 34 | return Promise.reject(error) 35 | } 36 | ) 37 | 38 | // response interceptor 39 | service.interceptors.response.use( 40 | /** 41 | * If you want to get http information such as headers or status 42 | * Please return response => response 43 | */ 44 | 45 | /** 46 | * Determine the request status by custom code 47 | * Here is just an example 48 | * You can also judge the status by HTTP Status Code 49 | */ 50 | response => { 51 | let httpStatus = response.status 52 | if (httpStatus === 200) { 53 | const res = response.data 54 | if (!res.success) { 55 | let message = res.message 56 | Message.error(message) 57 | if (message.indexOf('身份') > -1 || 58 | message.indexOf('token') > -1) { 59 | // 退出登录 60 | setToken('') 61 | Router.push('/login') 62 | } 63 | } 64 | return res 65 | } else { 66 | console.error(response) 67 | } 68 | } 69 | ) 70 | 71 | export default service 72 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/main.less: -------------------------------------------------------------------------------- 1 | .main{ 2 | .logo-con{ 3 | height: 64px; 4 | line-height: 64px; 5 | //padding: 10px; 6 | overflow: hidden; 7 | vertical-align: middle; 8 | margin-bottom: 20px; 9 | img{ 10 | height: 40px; 11 | width: auto; 12 | float: left; 13 | margin-top: 12px; 14 | margin-left: 10px; 15 | margin-right: 10px; 16 | } 17 | .maxAdminName { 18 | color: #fff; 19 | font-size: 24px; 20 | font-weight: bold; 21 | font-family: 'Avenir', Helvetica, Arial, sans-serif; 22 | -webkit-font-smoothing: antialiased; 23 | -moz-osx-font-smoothing: grayscale; 24 | } 25 | } 26 | .header-con{ 27 | background: #fff; 28 | padding: 0 20px; 29 | width: 100%; 30 | .userName { 31 | color: red; 32 | } 33 | } 34 | .main-layout-con{ 35 | height: 100%; 36 | overflow: hidden; 37 | } 38 | .main-content-con{ 39 | height: ~"calc(100% - 60px)"; 40 | overflow: hidden; 41 | } 42 | .tag-nav-wrapper{ 43 | padding: 0; 44 | height:40px; 45 | background:#F0F0F0; 46 | } 47 | .content-wrapper{ 48 | padding: 18px; 49 | height: ~"calc(100% - 80px)"; 50 | overflow: auto; 51 | } 52 | .left-sider{ 53 | z-index: 100; 54 | box-shadow: 2px 0 3px -1px #c3c3c3; 55 | .ivu-layout-sider-children{ 56 | overflow-y: scroll; 57 | margin-right: -18px; 58 | } 59 | } 60 | } 61 | .ivu-menu-item > i{ 62 | margin-right: 12px !important; 63 | font-size: 18px; 64 | } 65 | .ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i { 66 | margin-right: 8px !important; 67 | } 68 | .collased-menu-dropdown{ 69 | width: 100%; 70 | margin: 0; 71 | line-height: normal; 72 | padding: 7px 0 6px 16px; 73 | clear: both; 74 | font-size: 12px !important; 75 | white-space: nowrap; 76 | list-style: none; 77 | cursor: pointer; 78 | transition: background 0.2s ease-in-out; 79 | &:hover{ 80 | background: rgba(100, 100, 100, 0.1); 81 | } 82 | & * { 83 | color: #515a6e; 84 | } 85 | .ivu-menu-item > i{ 86 | margin-right: 12px !important; 87 | } 88 | .ivu-menu-submenu > .ivu-menu > .ivu-menu-item > i { 89 | margin-right: 8px !important; 90 | } 91 | } 92 | 93 | .ivu-select-dropdown.ivu-dropdown-transfer{ 94 | max-height: 400px; 95 | } 96 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/fonts/menu/iconfont.js: -------------------------------------------------------------------------------- 1 | !function(l){var t,n='',e=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss");if(e&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}!function(t){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(t,0);else{var e=function(){document.removeEventListener("DOMContentLoaded",e,!1),t()};document.addEventListener("DOMContentLoaded",e,!1)}else document.attachEvent&&(o=t,c=l.document,i=!1,(a=function(){try{c.documentElement.doScroll("left")}catch(t){return void setTimeout(a,50)}n()})(),c.onreadystatechange=function(){"complete"==c.readyState&&(c.onreadystatechange=null,n())});function n(){i||(i=!0,o())}var o,c,i,a}(function(){var t,e;(t=document.createElement("div")).innerHTML=n,n=null,(e=t.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",function(t,e){e.firstChild?function(t,e){e.parentNode.insertBefore(t,e)}(t,e.firstChild):e.appendChild(t)}(e,document.body))})}(window); -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/a-back-top/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 91 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/fullscreen/fullscreen.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 75 | 76 | 85 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/drag-list/drag-list.vue: -------------------------------------------------------------------------------- 1 | 21 | 84 | 93 | -------------------------------------------------------------------------------- /src/test/java/com/fengwenyi/spring_boot_elasticsearch_sample/repository/PhoneRepositoryTests.java: -------------------------------------------------------------------------------- 1 | package com.fengwenyi.spring_boot_elasticsearch_sample.repository; 2 | 3 | import com.fengwenyi.javalib.util.DateTimeUtils; 4 | import com.fengwenyi.spring_boot_elasticsearch_sample.entity.PhoneEntity; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.util.Assert; 9 | 10 | import java.time.LocalDateTime; 11 | import java.util.Optional; 12 | 13 | /** 14 | * @author Erwin Feng 15 | * @since 2020/7/4 16 | */ 17 | @SpringBootTest 18 | public class PhoneRepositoryTests { 19 | 20 | @Autowired 21 | private PhoneRepository phoneRepository; 22 | 23 | @Test 24 | public void test() { 25 | // 测试添加 26 | PhoneEntity phoneEntity = testAdd(); 27 | Assert.notNull(phoneEntity, "保存失败"); 28 | 29 | // 测试查询 30 | PhoneEntity findEntity = testGet(phoneEntity.getId()); 31 | Assert.notNull(findEntity, "查询失败"); 32 | Assert.isTrue(findEntity.getName().equals(phoneEntity.getName()), "保存对象不相等"); 33 | 34 | // 测试修改 35 | PhoneEntity updateEntity = testUpdate(phoneEntity.setName("华为")); 36 | Assert.isTrue(updateEntity.getName().equals(phoneEntity.getName()), "修改对象不相等"); 37 | 38 | // 测试删除 39 | testDelete(phoneEntity.getId()); 40 | PhoneEntity findDeleteEntity = testGet(phoneEntity.getId()); 41 | Assert.isNull(findDeleteEntity, "删除失败"); 42 | 43 | } 44 | 45 | /** 46 | * 测试添加数据 47 | * @return {@link PhoneEntity} 48 | */ 49 | private PhoneEntity testAdd() { 50 | LocalDateTime localDateTime = LocalDateTime.now(); 51 | PhoneEntity phoneEntity = new PhoneEntity() 52 | .setName("小米") 53 | .setCreateTimeStamp(DateTimeUtils.toMillisecond(localDateTime)) 54 | .setCreateTimeString(DateTimeUtils.format(localDateTime, "yyyy-MM-dd HH:mm:ss")) 55 | ; 56 | return phoneRepository.save(phoneEntity); 57 | 58 | } 59 | 60 | /** 61 | * 测试查询数据 62 | * @param id ID 63 | * @return {@link PhoneEntity} 64 | */ 65 | private PhoneEntity testGet(String id) { 66 | Optional optionalPhoneEntity = phoneRepository.findById(id); 67 | return optionalPhoneEntity.orElse(null); 68 | } 69 | 70 | /** 71 | * 测试修改时间 72 | * @param entity {@link PhoneEntity} 73 | * @return {@link PhoneEntity} 74 | */ 75 | private PhoneEntity testUpdate(PhoneEntity entity) { 76 | return phoneRepository.save(entity); 77 | } 78 | 79 | /** 80 | * 测试删除数据 81 | * @param id ID 82 | */ 83 | private void testDelete(String id) { 84 | phoneRepository.deleteById(id); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/view/Login/Login.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 93 | 94 | 97 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/store/module/login.js: -------------------------------------------------------------------------------- 1 | import { 2 | login, 3 | logout 4 | } from '@/api/login' 5 | import { setToken, getToken } from '@/libs/util' 6 | 7 | export default { 8 | state: { 9 | account: '', 10 | userName: '', 11 | userId: '', 12 | avatarImgPath: '', 13 | token: getToken(), 14 | access: '', 15 | hasGetInfo: false, 16 | unreadCount: 0, 17 | messageUnreadList: [], 18 | messageReadedList: [], 19 | messageTrashList: [], 20 | messageContentStore: {} 21 | }, 22 | mutations: { 23 | setAccount (state, account) { 24 | state.account = account 25 | }, 26 | setAvatar (state, avatarPath) { 27 | state.avatarImgPath = avatarPath 28 | }, 29 | setUserId (state, id) { 30 | state.userId = id 31 | }, 32 | setUserName (state, name) { 33 | state.userName = name 34 | }, 35 | setAccess (state, access) { 36 | state.access = access 37 | }, 38 | setToken (state, token) { 39 | state.token = token 40 | setToken(token) 41 | }, 42 | setHasGetInfo (state, status) { 43 | state.hasGetInfo = status 44 | }, 45 | setMessageCount (state, count) { 46 | state.unreadCount = count 47 | }, 48 | setMessageUnreadList (state, list) { 49 | state.messageUnreadList = list 50 | }, 51 | setMessageReadedList (state, list) { 52 | state.messageReadedList = list 53 | }, 54 | setMessageTrashList (state, list) { 55 | state.messageTrashList = list 56 | }, 57 | updateMessageContentStore (state, { msg_id, content }) { 58 | state.messageContentStore[msg_id] = content 59 | }, 60 | moveMsg (state, { from, to, msg_id }) { 61 | const index = state[from].findIndex(_ => _.msg_id === msg_id) 62 | const msgItem = state[from].splice(index, 1)[0] 63 | msgItem.loading = false 64 | state[to].unshift(msgItem) 65 | } 66 | }, 67 | getters: { 68 | messageUnreadCount: state => state.messageUnreadList.length, 69 | messageReadedCount: state => state.messageReadedList.length, 70 | messageTrashCount: state => state.messageTrashList.length 71 | }, 72 | actions: { 73 | // 登录 74 | login ({ commit }, user) { 75 | const username = user.username 76 | const password = user.password 77 | return new Promise((resolve, reject) => { 78 | login( 79 | username, 80 | password 81 | ).then(res => { 82 | if (res.success) { 83 | const token = res.data.token 84 | // this.Cookies.set('Token', token) 85 | commit('setToken', token) 86 | resolve() 87 | } 88 | }) 89 | }) 90 | }, 91 | // 退出登录 92 | logout2 ({ state, commit }) { 93 | return new Promise((resolve, reject) => { 94 | logout(state.token).then(() => { 95 | commit('setToken', '') 96 | commit('setAccess', []) 97 | resolve() 98 | }).catch(err => { 99 | reject(err) 100 | }) 101 | }) 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/images/icon-social-twitter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/split-pane/index.less: -------------------------------------------------------------------------------- 1 | @split-prefix-cls: ~"ivu-split"; 2 | @box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.4); 3 | @trigger-bar-background: rgba(23, 35, 61, 0.25); 4 | @trigger-background: #F8F8F9; 5 | @trigger-width: 6px; 6 | @trigger-bar-width: 4px; 7 | @trigger-bar-offset: (@trigger-width - @trigger-bar-width) / 2; 8 | @trigger-bar-interval: 3px; 9 | @trigger-bar-weight: 1px; 10 | @trigger-bar-con-height: (@trigger-bar-weight + @trigger-bar-interval) * 8; 11 | 12 | .@{split-prefix-cls}{ 13 | &-wrapper{ 14 | position: relative; 15 | width: 100%; 16 | height: 100%; 17 | } 18 | &-pane{ 19 | position: absolute; 20 | &.left-pane, &.right-pane{ 21 | top: 0px; 22 | bottom: 0px; 23 | } 24 | &.left-pane{ 25 | left: 0px; 26 | } 27 | &.right-pane{ 28 | right: 0px; 29 | } 30 | &.top-pane, &.bottom-pane{ 31 | left: 0px; 32 | right: 0px; 33 | } 34 | &.top-pane{ 35 | top: 0px; 36 | } 37 | &.bottom-pane{ 38 | bottom: 0px; 39 | } 40 | } 41 | &-trigger{ 42 | &-con{ 43 | position: absolute; 44 | transform: translate(-50%, -50%); 45 | z-index: 10; 46 | } 47 | &-bar-con{ 48 | position: absolute; 49 | overflow: hidden; 50 | &.vertical{ 51 | left: @trigger-bar-offset; 52 | top: 50%; 53 | height: @trigger-bar-con-height; 54 | transform: translate(0, -50%); 55 | } 56 | &.horizontal{ 57 | left: 50%; 58 | top: @trigger-bar-offset; 59 | width: @trigger-bar-con-height; 60 | transform: translate(-50%, 0); 61 | } 62 | } 63 | &-vertical{ 64 | width: @trigger-width; 65 | height: 100%; 66 | background: @trigger-background; 67 | box-shadow: @box-shadow; 68 | cursor: col-resize; 69 | .@{split-prefix-cls}-trigger-bar{ 70 | width: @trigger-bar-width; 71 | height: 1px; 72 | background: @trigger-bar-background; 73 | float: left; 74 | margin-top: @trigger-bar-interval; 75 | } 76 | } 77 | &-horizontal{ 78 | height: @trigger-width; 79 | width: 100%; 80 | background: @trigger-background; 81 | box-shadow: @box-shadow; 82 | cursor: row-resize; 83 | .@{split-prefix-cls}-trigger-bar{ 84 | height: @trigger-bar-width; 85 | width: 1px; 86 | background: @trigger-bar-background; 87 | float: left; 88 | margin-right: @trigger-bar-interval; 89 | } 90 | } 91 | } 92 | &-horizontal{ 93 | .@{split-prefix-cls}-trigger-con{ 94 | top: 50%; 95 | height: 100%; 96 | width: 0; 97 | } 98 | } 99 | &-vertical{ 100 | .@{split-prefix-cls}-trigger-con{ 101 | left: 50%; 102 | height: 0; 103 | width: 100%; 104 | } 105 | } 106 | .no-select{ 107 | -webkit-touch-callout: none; 108 | -webkit-user-select: none; 109 | -khtml-user-select: none; 110 | -moz-user-select: none; 111 | -ms-user-select: none; 112 | user-select: none; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/paste-editor/paste-editor.vue: -------------------------------------------------------------------------------- 1 | 6 | 113 | 116 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto init 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto init 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :init 68 | @rem Get command-line arguments, handling Windows variants 69 | 70 | if not "%OS%" == "Windows_NT" goto win9xME_args 71 | 72 | :win9xME_args 73 | @rem Slurp the command line arguments. 74 | set CMD_LINE_ARGS= 75 | set _SKIP=2 76 | 77 | :win9xME_args_slurp 78 | if "x%~1" == "x" goto execute 79 | 80 | set CMD_LINE_ARGS=%* 81 | 82 | :execute 83 | @rem Setup the command line 84 | 85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 86 | 87 | 88 | @rem Execute Gradle 89 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 90 | 91 | :end 92 | @rem End local scope for the variables with windows NT shell 93 | if "%ERRORLEVEL%"=="0" goto mainEnd 94 | 95 | :fail 96 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 97 | rem the _cmd.exe /c_ return code! 98 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 99 | exit /b 1 100 | 101 | :mainEnd 102 | if "%OS%"=="Windows_NT" endlocal 103 | 104 | :omega 105 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/store/module/app.js: -------------------------------------------------------------------------------- 1 | import { 2 | getBreadCrumbList, 3 | setTagNavListInLocalstorage, 4 | getMenuByRouter, 5 | getTagNavListFromLocalstorage, 6 | getHomeRoute, 7 | getNextRoute, 8 | routeHasExist, 9 | routeEqual, 10 | getRouteTitleHandled, 11 | localSave, 12 | localRead 13 | } from '@/libs/util' 14 | // import { saveErrorLogger } from '@/api/data' 15 | import router from '@/router' 16 | import routers from '@/router/routers' 17 | import config from '@/config' 18 | const { homeName } = config 19 | 20 | const closePage = (state, route) => { 21 | const nextRoute = getNextRoute(state.tagNavList, route) 22 | state.tagNavList = state.tagNavList.filter(item => { 23 | return !routeEqual(item, route) 24 | }) 25 | router.push(nextRoute) 26 | } 27 | 28 | export default { 29 | state: { 30 | breadCrumbList: [], 31 | tagNavList: [], 32 | homeRoute: {}, 33 | local: localRead('local'), 34 | errorList: [], 35 | hasReadErrorPage: false 36 | }, 37 | getters: { 38 | menuList: (state, getters, rootState) => getMenuByRouter(routers, ['admin']), 39 | errorCount: state => state.errorList.length 40 | }, 41 | mutations: { 42 | setBreadCrumb (state, route) { 43 | state.breadCrumbList = getBreadCrumbList(route, state.homeRoute) 44 | }, 45 | setHomeRoute (state, routes) { 46 | state.homeRoute = getHomeRoute(routes, homeName) 47 | }, 48 | setTagNavList (state, list) { 49 | let tagList = [] 50 | if (list) { 51 | tagList = [...list] 52 | } else tagList = getTagNavListFromLocalstorage() || [] 53 | if (tagList[0] && tagList[0].name !== homeName) tagList.shift() 54 | let homeTagIndex = tagList.findIndex(item => item.name === homeName) 55 | if (homeTagIndex > 0) { 56 | let homeTag = tagList.splice(homeTagIndex, 1)[0] 57 | tagList.unshift(homeTag) 58 | } 59 | state.tagNavList = tagList 60 | setTagNavListInLocalstorage([...tagList]) 61 | }, 62 | closeTag (state, route) { 63 | let tag = state.tagNavList.filter(item => routeEqual(item, route)) 64 | route = tag[0] ? tag[0] : null 65 | if (!route) return 66 | closePage(state, route) 67 | }, 68 | addTag (state, { route, type = 'unshift' }) { 69 | let router = getRouteTitleHandled(route) 70 | if (!routeHasExist(state.tagNavList, router)) { 71 | if (type === 'push') state.tagNavList.push(router) 72 | else { 73 | if (router.name === homeName) state.tagNavList.unshift(router) 74 | else state.tagNavList.splice(1, 0, router) 75 | } 76 | setTagNavListInLocalstorage([...state.tagNavList]) 77 | } 78 | }, 79 | setLocal (state, lang) { 80 | localSave('local', lang) 81 | state.local = lang 82 | }, 83 | addError (state, error) { 84 | state.errorList.push(error) 85 | }, 86 | setHasReadErrorLoggerStatus (state, status = true) { 87 | state.hasReadErrorPage = status 88 | } 89 | }, 90 | actions: { 91 | addErrorLog ({ commit, rootState }, info) { 92 | if (!window.location.href.includes('error_logger_page')) commit('setHasReadErrorLoggerStatus', false) 93 | const { user: { token, userId, userName } } = rootState 94 | let data = { 95 | ...info, 96 | time: Date.parse(new Date()), 97 | token, 98 | userId, 99 | userName 100 | } 101 | /*saveErrorLogger(info).then(() => { 102 | commit('addError', data) 103 | })*/ 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/view/Login/Login.less: -------------------------------------------------------------------------------- 1 | body { 2 | background-image: url('../../assets/images/login-bg3.jpg'); 3 | //background-image: url('https://passport.baidu.com/static/passpc-account/img/reg_bg_min.jpg'); 4 | background-size: cover; 5 | background-position: center; 6 | font-family: 'Avenir', Helvetica, Arial, sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | width: 100%; 10 | height: 100%; 11 | } 12 | 13 | .container { 14 | width: 100%; 15 | height: 100%; 16 | position: relative; 17 | 18 | .bg { 19 | width: 100%; 20 | height: 100%; 21 | //background-color: #f3f3f3; 22 | position: absolute; 23 | z-index: 1; 24 | //opacity: .9; 25 | } 26 | 27 | .content { 28 | width: 430px; 29 | height: 465px; 30 | position: absolute; 31 | top: 0; 32 | bottom: 0; 33 | left: 0; 34 | right: 0; 35 | margin: auto; 36 | z-index: 3; 37 | background: rgba(255, 255, 255, .7); 38 | box-shadow: 0 0 10px #999; 39 | border-radius: 5px; 40 | padding: 50px 50px 10px; 41 | @media screen and (max-width: 800px) { 42 | 43 | width: calc(100% - 10px); 44 | padding: 30px 30px 10px; 45 | 46 | } 47 | 48 | .box-logo { 49 | text-align: center; 50 | 51 | .image-logo { 52 | height: 50px; 53 | width: auto; 54 | vertical-align: middle; 55 | } 56 | } 57 | 58 | .title { 59 | width: 100%; 60 | text-align: center; 61 | vertical-align: middle; 62 | 63 | img { 64 | height: 50px; 65 | width: auto; 66 | vertical-align: middle; 67 | } 68 | 69 | span { 70 | font-size: 35px; 71 | vertical-align: middle; 72 | display: inline-block; 73 | margin-left: 20px; 74 | font-weight: bold; 75 | } 76 | } 77 | 78 | .description { 79 | text-align: center; 80 | color: #666; 81 | } 82 | 83 | .box-login { 84 | .login-form { 85 | margin-top: 30px; 86 | 87 | .login-form-input { 88 | width: 100%; 89 | display: block; 90 | margin-top: 5px; 91 | } 92 | 93 | .login-form-btn-submit { 94 | width: 100%; 95 | height: 45px; 96 | display: block; 97 | margin-top: 10px; 98 | font-size: 16px; 99 | } 100 | } 101 | } 102 | 103 | .box-third-login { 104 | width: 100%; 105 | height: 36px; 106 | margin-top: 50px; 107 | display: flex; 108 | justify-content: center; 109 | 110 | .box-item-content { 111 | width: 200px; 112 | display: flex; 113 | justify-content: space-around; 114 | 115 | .item { 116 | width: 36px; 117 | height: 36px; 118 | border-radius: 36px; 119 | display: flex; 120 | align-items: center; 121 | justify-content: center; 122 | cursor: pointer; 123 | font-size: 28px; 124 | background-color: #000; 125 | color: #fff; 126 | } 127 | } 128 | } 129 | 130 | .box-login-way-select { 131 | width: 100%; 132 | height: 45px; 133 | margin-top: 20px; 134 | display: flex; 135 | justify-content: center; 136 | align-items: center; 137 | 138 | .item { 139 | color: #2d8cf0; 140 | cursor: pointer; 141 | 142 | .split { 143 | color: #aaa; 144 | margin-left: 10px; 145 | margin-right: 10px; 146 | } 147 | } 148 | } 149 | 150 | .footer { 151 | margin-top: 10px; 152 | display: flex; 153 | justify-content: center; 154 | } 155 | 156 | 157 | } 158 | 159 | .footer { 160 | .company { 161 | margin-left: 10px; 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/tree-select/tree-select-tree.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/assets/icons/iconfont.css: -------------------------------------------------------------------------------- 1 | 2 | @font-face {font-family: "iconfont"; 3 | src: url('iconfont.eot?t=1541579316141'); /* IE9*/ 4 | src: url('iconfont.eot?t=1541579316141#iefix') format('embedded-opentype'), /* IE6-IE8 */ 5 | url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAiEAAsAAAAADmgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY8eUnXY21hcAAAAYAAAACjAAACLi+YJuBnbHlmAAACJAAABAgAAAcg4dRWHmhlYWQAAAYsAAAAMQAAADYTL8piaGhlYQAABmAAAAAgAAAAJAfdA4xobXR4AAAGgAAAABQAAAAsLAD//2xvY2EAAAaUAAAAGAAAABgImgpGbWF4cAAABqwAAAAfAAAAIAEcAG5uYW1lAAAGzAAAAUUAAAJtPlT+fXBvc3QAAAgUAAAAbgAAAI54roygeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMTx/ytzwv4EhhrmBoRkozAiSAwDuUwzMeJzlkUEKwkAMRd/YabXFhQvxFF6qPYPrUujGY7jyIr1JoZNjtMnEhag3MOEN5MMk8D9QAoVyVSKEJwGrh6oh6wVN1iM3nc+cVImJVKdOehlklElmWdYVstp+ql8VdIv15a1NLW0zFXsO7Kjz3erH/3+rY37vr6kxnx1LKNWOJZlaxxJNnWOpSu+ot8jgqMvI6KjfyOSo88jsaAbI4tBsig89rQB4nLVUTWwbRRSeNzO767i2g7N/FP9s7MRrE5ON4/V6rSZyU0PiINSSNImES4IUoapWz6hEiqiMBDQqEojkAkiFStyKRC+9VSoFCeUEyqESVUAqEkcu3OAQb3hrJxAXwSGI3X0/szPz5vvm2x0i7O/vf8IJe5VkSJnUyUtklRBQJE1VIjRtUafkmk6pSu2ipleh4+xikkKxSksWTUeo8m8NoagpYtoslTmxrLl37z64e33esuJjU8P5Wd262LxoPVnPZ06Pxfe+C0YjkhSJygPhQCA8ABPOykwuN7NyuRvgUnAgLEnhATkaCQQiUe/7XKUyV6nQz+t2o7l66+rs7NVbq82GXTdrdjxjRGU5amTids2bUDMFtzCsqsMYMqr3IDY6OT05GjsI8Exv/6CSkOWEQigh+y3clxY5QVTcEZFIGtHLxDUJs6WsHR1y9SFKdr1HggCp3V1ICYL36OOpVmvKN9bC1u6R3vZ0qwWtVovgJfqOfUvfIYxIWL+fyETHNVJqSkIT1JTjW8ZWh3yDJDz0ctvsyt51etvrg9/QHhqGlzMM+vbmizPnDWPLMNbW19e7tffvsBzL99aWEfBRY46t+tbe3PypXv/IMDYN43WsQBe9HL2NC33RuxABrPsG+xH3o4bVRE2KgCRqulbWNf8W/UYVHM129aKra24VshZkq+CWD/Oy6Xt8cGYEthgHVlVliCfynAlqjo6oysTKlYUAD4docMI5/1ZioN+GwZNBcTwWUmTdBUqhTwX29QebXzF4An4JJMzwfMl+WQ01+IlQZVR4yhie53ycA16pOI/ODiYNGK4MChdCgXNnX5gIJXPCSYnf2OF850aQ+zJIyOs+u8+mMO8jQdwtg1TIWVRjKAnFcslMi8KfGUPoSUCergUyUk77dMyS69Ms6tijKZKYwUGKbpfdzu+iYeZYAHMFiOVi+MD7h9mb99qC0L7X8c+XatMfTj97KZ5IxJt/pd43tYYQKEjAnXMOB6kQEBrwg+LPjindAPOHNdC3q3ait0I3/ZIunZEARLNYNEUA6czSP3N/7j9wz6ZESdX0VNl1zGNS/szbQaQSIGk4DtVPcZf8AgXpf9A2OyTit5s2syZmand46bhEe2WtodLHkvaoqtTXuXN2/c42WADP9HGfbUcUW7JgqHss4xHtlMys679FqUomdP9VJBQBdnlPABBubpuNwqnmQj6/0HwNQzKxDUJFgKiXurBG6dqFjmeBzsvtRPJgGIZThYa5fdOvsReOticPh6JHHXxsv7ItJpOniYPYsmZ/x0QD/o5P105DeQwF6MH33ogoLi+KQp7zpY3HQV5bFMURzheXeds7gpP+jKNXljjHuYvXHke7cdCxLLZf6YX7B63UcCV4nGNgZGBgAOKAN2ZR8fw2Xxm4WRhA4AbHYRMY/f///1oWBuYGIJeDgQkkCgAvWgs2AAAAeJxjYGRgYG7438AQw8Lw/z8DAwsDA1AEBXADAHXiBHJ4nGNhYGBgYfj/nwVM48cATwECKwAAAAAAjAC6AOgBFAGAAf4CbgLqAzgDkHicY2BkYGDgZkhiYGcAASYg5gJCBob/YD4DABOmAYsAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicbYhdDoIwEAb3a6k/YIIX8VArWewmdJFWJOnpJTG+OQ+TzJCjLy39p4ODR4OAA4444YwWHS7U3IVzn6Voldtb8ksHnvohrlqjjmw1rmzXsvdT7fEbblnCmOfNfJIYStJJfGIL27yb6AOCGR89AAA=') format('woff'), 6 | url('iconfont.ttf?t=1541579316141') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ 7 | url('iconfont.svg?t=1541579316141#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family:"iconfont" !important; 12 | font-size:16px; 13 | font-style:normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-bear:before { content: "\e600"; } 19 | 20 | .icon-resize-vertical:before { content: "\e7c3"; } 21 | 22 | .icon-chuizhifanzhuan:before { content: "\e661"; } 23 | 24 | .icon-shuipingfanzhuan:before { content: "\e662"; } 25 | 26 | .icon-qq:before { content: "\e609"; } 27 | 28 | .icon-frown:before { content: "\e77e"; } 29 | 30 | .icon-meh:before { content: "\e780"; } 31 | 32 | .icon-smile:before { content: "\e783"; } 33 | 34 | .icon-man:before { content: "\e7e2"; } 35 | 36 | .icon-woman:before { content: "\e7e5"; } 37 | 38 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/libs/excel.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import XLSX from 'xlsx'; 3 | 4 | function auto_width(ws, data){ 5 | /*set worksheet max width per col*/ 6 | const colWidth = data.map(row => row.map(val => { 7 | /*if null/undefined*/ 8 | if (val == null) { 9 | return {'wch': 10}; 10 | } 11 | /*if chinese*/ 12 | else if (val.toString().charCodeAt(0) > 255) { 13 | return {'wch': val.toString().length * 2}; 14 | } else { 15 | return {'wch': val.toString().length}; 16 | } 17 | })) 18 | /*start in the first row*/ 19 | let result = colWidth[0]; 20 | for (let i = 1; i < colWidth.length; i++) { 21 | for (let j = 0; j < colWidth[i].length; j++) { 22 | if (result[j]['wch'] < colWidth[i][j]['wch']) { 23 | result[j]['wch'] = colWidth[i][j]['wch']; 24 | } 25 | } 26 | } 27 | ws['!cols'] = result; 28 | } 29 | 30 | function json_to_array(key, jsonData){ 31 | return jsonData.map(v => key.map(j => { return v[j] })); 32 | } 33 | 34 | // fix data,return string 35 | function fixdata(data) { 36 | let o = '' 37 | let l = 0 38 | const w = 10240 39 | for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w))) 40 | o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w))) 41 | return o 42 | } 43 | 44 | // get head from excel file,return array 45 | function get_header_row(sheet) { 46 | const headers = [] 47 | const range = XLSX.utils.decode_range(sheet['!ref']) 48 | let C 49 | const R = range.s.r /* start in the first row */ 50 | for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */ 51 | var cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] /* find the cell in the first row */ 52 | var hdr = 'UNKNOWN ' + C // <-- replace with your desired default 53 | if (cell && cell.t) hdr = XLSX.utils.format_cell(cell) 54 | headers.push(hdr) 55 | } 56 | return headers 57 | } 58 | 59 | export const export_table_to_excel= (id, filename) => { 60 | const table = document.getElementById(id); 61 | const wb = XLSX.utils.table_to_book(table); 62 | XLSX.writeFile(wb, filename); 63 | 64 | /* the second way */ 65 | // const table = document.getElementById(id); 66 | // const wb = XLSX.utils.book_new(); 67 | // const ws = XLSX.utils.table_to_sheet(table); 68 | // XLSX.utils.book_append_sheet(wb, ws, filename); 69 | // XLSX.writeFile(wb, filename); 70 | } 71 | 72 | export const export_json_to_excel = ({data, key, title, filename, autoWidth}) => { 73 | const wb = XLSX.utils.book_new(); 74 | data.unshift(title); 75 | const ws = XLSX.utils.json_to_sheet(data, {header: key, skipHeader: true}); 76 | if(autoWidth){ 77 | const arr = json_to_array(key, data); 78 | auto_width(ws, arr); 79 | } 80 | XLSX.utils.book_append_sheet(wb, ws, filename); 81 | XLSX.writeFile(wb, filename + '.xlsx'); 82 | } 83 | 84 | export const export_array_to_excel = ({key, data, title, filename, autoWidth}) => { 85 | const wb = XLSX.utils.book_new(); 86 | const arr = json_to_array(key, data); 87 | arr.unshift(title); 88 | const ws = XLSX.utils.aoa_to_sheet(arr); 89 | if(autoWidth){ 90 | auto_width(ws, arr); 91 | } 92 | XLSX.utils.book_append_sheet(wb, ws, filename); 93 | XLSX.writeFile(wb, filename + '.xlsx'); 94 | } 95 | 96 | export const read = (data, type) => { 97 | /* if type == 'base64' must fix data first */ 98 | // const fixedData = fixdata(data) 99 | // const workbook = XLSX.read(btoa(fixedData), { type: 'base64' }) 100 | const workbook = XLSX.read(data, { type: type }); 101 | const firstSheetName = workbook.SheetNames[0]; 102 | const worksheet = workbook.Sheets[firstSheetName]; 103 | const header = get_header_row(worksheet); 104 | const results = XLSX.utils.sheet_to_json(worksheet); 105 | return {header, results}; 106 | } 107 | 108 | export default { 109 | export_table_to_excel, 110 | export_array_to_excel, 111 | export_json_to_excel, 112 | read 113 | } 114 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/cropper/index.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 140 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/main/components/side-menu/side-menu.vue: -------------------------------------------------------------------------------- 1 | 26 | 112 | 115 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/count-to/count-to.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 175 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/drag-drawer/drag-drawer.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 157 | -------------------------------------------------------------------------------- /web/vue-admin-pro/src/components/split-pane/split.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 155 | 156 | 159 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ]; do 30 | ls=$(ls -ld "$PRG") 31 | link=$(expr "$ls" : '.*-> \(.*\)$') 32 | if expr "$link" : '/.*' >/dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=$(dirname "$PRG")"/$link" 36 | fi 37 | done 38 | SAVED="$(pwd)" 39 | cd "$(dirname \"$PRG\")/" >/dev/null 40 | APP_HOME="$(pwd -P)" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=$(basename "$0") 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn() { 53 | echo "$*" 54 | } 55 | 56 | die() { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "$(uname)" in 69 | CYGWIN*) 70 | cygwin=true 71 | ;; 72 | Darwin*) 73 | darwin=true 74 | ;; 75 | MINGW*) 76 | msys=true 77 | ;; 78 | NONSTOP*) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ]; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ]; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then 109 | MAX_FD_LIMIT=$(ulimit -H -n) 110 | if [ $? -eq 0 ]; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ]; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ]; then 130 | APP_HOME=$(cygpath --path --mixed "$APP_HOME") 131 | CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") 132 | 133 | JAVACMD=$(cygpath --unix "$JAVACMD") 134 | 135 | # We build the pattern for arguments to be converted via cygpath 136 | ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) 137 | SEP="" 138 | for dir in $ROOTDIRSRAW; do 139 | ROOTDIRS="$ROOTDIRS$SEP$dir" 140 | SEP="|" 141 | done 142 | OURCYGPATTERN="(^($ROOTDIRS))" 143 | # Add a user-defined pattern to the cygpath arguments 144 | if [ "$GRADLE_CYGPATTERN" != "" ]; then 145 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 146 | fi 147 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 148 | i=0 149 | for arg in "$@"; do 150 | CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) 151 | CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option 152 | 153 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition 154 | eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") 155 | else 156 | eval $(echo args$i)="\"$arg\"" 157 | fi 158 | i=$(expr $i + 1) 159 | done 160 | case $i in 161 | 0) set -- ;; 162 | 1) set -- "$args0" ;; 163 | 2) set -- "$args0" "$args1" ;; 164 | 3) set -- "$args0" "$args1" "$args2" ;; 165 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 166 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 167 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 168 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 169 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 170 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 171 | esac 172 | fi 173 | 174 | # Escape application args 175 | save() { 176 | for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done 177 | echo " " 178 | } 179 | APP_ARGS=$(save "$@") 180 | 181 | # Collect all arguments for the java command, following the shell quoting and substitution rules 182 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 183 | 184 | exec "$JAVACMD" "$@" 185 | --------------------------------------------------------------------------------