├── Vue_Adaptive_Table ├── .eslintignore ├── babel.config.js ├── .env.production ├── public │ ├── favicon.ico │ └── index.html ├── .env.staging ├── .env.development ├── jsconfig.json ├── .gitignore ├── .editorconfig ├── src │ ├── settings.js │ ├── directive │ │ └── el-table │ │ │ ├── index.js │ │ │ └── adaptive.js │ ├── main.js │ └── App.vue ├── build │ └── index.js ├── package.json ├── vue.config.js └── .eslintrc.js ├── SpringBoot_Axios_Cors ├── demo-front │ ├── .eslintignore │ ├── babel.config.js │ ├── .env.production │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ ├── .env.staging │ ├── src │ │ ├── assets │ │ │ └── 404_images │ │ │ │ ├── 404.png │ │ │ │ └── 404_cloud.png │ │ ├── views │ │ │ ├── nested │ │ │ │ ├── menu2 │ │ │ │ │ └── index.vue │ │ │ │ └── menu1 │ │ │ │ │ ├── menu1-3 │ │ │ │ │ └── index.vue │ │ │ │ │ ├── index.vue │ │ │ │ │ ├── menu1-2 │ │ │ │ │ ├── menu1-2-1 │ │ │ │ │ │ └── index.vue │ │ │ │ │ ├── menu1-2-2 │ │ │ │ │ │ └── index.vue │ │ │ │ │ └── index.vue │ │ │ │ │ └── menu1-1 │ │ │ │ │ └── index.vue │ │ │ ├── dashboard │ │ │ │ └── index.vue │ │ │ ├── tree │ │ │ │ └── index.vue │ │ │ ├── form │ │ │ │ └── index.vue │ │ │ ├── 404.vue │ │ │ └── login │ │ │ │ └── index.vue │ │ ├── layout │ │ │ ├── components │ │ │ │ ├── index.js │ │ │ │ ├── Sidebar │ │ │ │ │ ├── Item.vue │ │ │ │ │ ├── Link.vue │ │ │ │ │ ├── FixiOSBug.js │ │ │ │ │ ├── index.vue │ │ │ │ │ ├── Logo.vue │ │ │ │ │ └── SidebarItem.vue │ │ │ │ ├── AppMain.vue │ │ │ │ └── Navbar.vue │ │ │ ├── mixin │ │ │ │ └── ResizeHandler.js │ │ │ └── index.vue │ │ ├── App.vue │ │ ├── api │ │ │ └── user.js │ │ ├── store │ │ │ ├── getters.js │ │ │ ├── index.js │ │ │ └── modules │ │ │ │ ├── settings.js │ │ │ │ ├── user.js │ │ │ │ └── app.js │ │ ├── icons │ │ │ ├── svg │ │ │ │ ├── link.svg │ │ │ │ ├── user.svg │ │ │ │ ├── example.svg │ │ │ │ ├── table.svg │ │ │ │ ├── password.svg │ │ │ │ ├── nested.svg │ │ │ │ ├── eye.svg │ │ │ │ ├── eye-open.svg │ │ │ │ ├── tree.svg │ │ │ │ ├── dashboard.svg │ │ │ │ └── form.svg │ │ │ ├── index.js │ │ │ └── svgo.yml │ │ ├── utils │ │ │ ├── get-page-title.js │ │ │ ├── auth.js │ │ │ ├── validate.js │ │ │ ├── request.js │ │ │ └── index.js │ │ ├── settings.js │ │ ├── styles │ │ │ ├── mixin.scss │ │ │ ├── variables.scss │ │ │ ├── element-ui.scss │ │ │ ├── transition.scss │ │ │ ├── index.scss │ │ │ └── sidebar.scss │ │ ├── main.js │ │ ├── components │ │ │ ├── Hamburger │ │ │ │ └── index.vue │ │ │ ├── SvgIcon │ │ │ │ └── index.vue │ │ │ └── Breadcrumb │ │ │ │ └── index.vue │ │ ├── permission.js │ │ └── router │ │ │ └── index.js │ ├── .env.development │ ├── jsconfig.json │ ├── .gitignore │ ├── .editorconfig │ ├── build │ │ └── index.js │ ├── package.json │ ├── vue.config.js │ └── .eslintrc.js ├── demo-back │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ └── application.yml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── demo │ │ │ │ ├── DemoApplication.java │ │ │ │ ├── model │ │ │ │ └── User.java │ │ │ │ ├── conf │ │ │ │ └── WebMvcConfig.java │ │ │ │ └── controller │ │ │ │ └── LoginController.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ └── DemoApplicationTests.java │ ├── .gitignore │ └── pom.xml └── README.md ├── README.md ├── PageHelper_Demo ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.yml │ │ │ ├── sql │ │ │ │ └── pagehelper.sql │ │ │ └── mapper │ │ │ │ └── UserMapper.xml │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── mapper │ │ │ └── UserMapper.java │ │ │ ├── model │ │ │ └── User.java │ │ │ ├── base │ │ │ └── BaseMapper.java │ │ │ ├── DemoApplication.java │ │ │ └── service │ │ │ └── UserService.java │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── demo │ │ └── DemoApplicationTests.java ├── .gitignore └── pom.xml ├── Merge_Table ├── index.vue ├── README.md └── components │ └── MergeTable.vue └── Element_CheckBox └── demo.vue /Vue_Adaptive_Table/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | src/assets 3 | public 4 | dist 5 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | src/assets 3 | public 4 | dist 5 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 博客代码例子 2 | 3 | ## [查看博客戳这里 👆]() 4 | 5 | ## [掘金戳这里 👆](https://juejin.im/user/5b096c886fb9a07ab83e7af4) 6 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/.env.production: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'production' 3 | 4 | # base api 5 | VUE_APP_BASE_API = '/prod-api' 6 | 7 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superZhouDaLu/BlogExample/HEAD/Vue_Adaptive_Table/public/favicon.ico -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-back/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9090 3 | servlet: 4 | context-path: /CorsExample -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/.env.production: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'production' 3 | 4 | # base api 5 | VUE_APP_BASE_API = '/prod-api' 6 | 7 | -------------------------------------------------------------------------------- /PageHelper_Demo/src/main/resources/application.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superZhouDaLu/BlogExample/HEAD/PageHelper_Demo/src/main/resources/application.yml -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superZhouDaLu/BlogExample/HEAD/SpringBoot_Axios_Cors/demo-front/public/favicon.ico -------------------------------------------------------------------------------- /Vue_Adaptive_Table/.env.staging: -------------------------------------------------------------------------------- 1 | NODE_ENV = production 2 | 3 | # just a flag 4 | ENV = 'staging' 5 | 6 | # base api 7 | VUE_APP_BASE_API = '/stage-api' 8 | 9 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/.env.staging: -------------------------------------------------------------------------------- 1 | NODE_ENV = production 2 | 3 | # just a flag 4 | ENV = 'staging' 5 | 6 | # base api 7 | VUE_APP_BASE_API = '/stage-api' 8 | 9 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/assets/404_images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superZhouDaLu/BlogExample/HEAD/SpringBoot_Axios_Cors/demo-front/src/assets/404_images/404.png -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/assets/404_images/404_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superZhouDaLu/BlogExample/HEAD/SpringBoot_Axios_Cors/demo-front/src/assets/404_images/404_cloud.png -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/nested/menu2/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/.env.development: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'development' 3 | 4 | # base api 5 | VUE_APP_BASE_API = 'http://127.0.0.1:9090/CorsExample/' 6 | 7 | VUE_CLI_BABEL_TRANSPILE_MODULES = true 8 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Navbar } from './Navbar' 2 | export { default as Sidebar } from './Sidebar' 3 | export { default as AppMain } from './AppMain' 4 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | }, 8 | "exclude": ["node_modules", "dist"] 9 | } 10 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/.env.development: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'development' 3 | 4 | # base api 5 | VUE_APP_BASE_API = 'http://127.0.0.1:9090/CorsExample/' 6 | 7 | VUE_CLI_BABEL_TRANSPILE_MODULES = true 8 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | }, 8 | "exclude": ["node_modules", "dist"] 9 | } 10 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/nested/menu1/menu1-3/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/api/user.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function login(data) { 4 | return request({ 5 | url: '/login', 6 | method: 'post', 7 | data 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/nested/menu1/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/nested/menu1/menu1-2/menu1-2-1/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/nested/menu1/menu1-2/menu1-2-2/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/nested/menu1/menu1-1/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/nested/menu1/menu1-2/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | package-lock.json 8 | tests/**/coverage/ 9 | 10 | # Editor directories and files 11 | .idea 12 | .vscode 13 | *.suo 14 | *.ntvs* 15 | *.njsproj 16 | *.sln 17 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | sidebar: state => state.app.sidebar, 3 | device: state => state.app.device, 4 | token: state => state.user.token, 5 | avatar: state => state.user.avatar, 6 | name: state => state.user.name 7 | } 8 | export default getters 9 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | package-lock.json 8 | tests/**/coverage/ 9 | 10 | # Editor directories and files 11 | .idea 12 | .vscode 13 | *.suo 14 | *.ntvs* 15 | *.njsproj 16 | *.sln 17 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/utils/get-page-title.js: -------------------------------------------------------------------------------- 1 | import defaultSettings from '@/settings' 2 | 3 | const title = defaultSettings.title || 'Vue Admin Template' 4 | 5 | export default function getPageTitle(pageTitle) { 6 | if (pageTitle) { 7 | return `${pageTitle} - ${title}` 8 | } 9 | return `${title}` 10 | } 11 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | insert_final_newline = false 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /PageHelper_Demo/src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class DemoApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | insert_final_newline = false 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-back/src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class DemoApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import SvgIcon from '@/components/SvgIcon'// svg component 3 | 4 | // register globally 5 | Vue.component('svg-icon', SvgIcon) 6 | 7 | const req = require.context('./svg', false, /\.svg$/) 8 | const requireAll = requireContext => requireContext.keys().map(requireContext) 9 | requireAll(req) 10 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/src/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 3 | title: '自适应高度表格', 4 | 5 | /** 6 | * @type {boolean} true | false 7 | * @description Whether fix the header 8 | */ 9 | fixedHeader: false, 10 | 11 | /** 12 | * @type {boolean} true | false 13 | * @description Whether show the logo in sidebar 14 | */ 15 | sidebarLogo: false 16 | } 17 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/src/directive/el-table/index.js: -------------------------------------------------------------------------------- 1 | import adaptive from './adaptive' 2 | 3 | const install = function(Vue) { 4 | Vue.directive('adaptive', adaptive) 5 | } 6 | 7 | if (window.Vue) { 8 | window['adaptive'] = adaptive 9 | // eslint-disable-next-line no-undef 10 | Vue.use(install) 11 | } 12 | 13 | adaptive.install = install 14 | export default adaptive 15 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svgo.yml: -------------------------------------------------------------------------------- 1 | # replace default config 2 | 3 | # multipass: true 4 | # full: true 5 | 6 | plugins: 7 | 8 | # - name 9 | # 10 | # or: 11 | # - name: false 12 | # - name: true 13 | # 14 | # or: 15 | # - name: 16 | # param1: 1 17 | # param2: 2 18 | 19 | - removeAttrs: 20 | attrs: 21 | - 'fill' 22 | - 'fill-rule' 23 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 3 | title: 'Vue Admin Template', 4 | 5 | /** 6 | * @type {boolean} true | false 7 | * @description Whether fix the header 8 | */ 9 | fixedHeader: false, 10 | 11 | /** 12 | * @type {boolean} true | false 13 | * @description Whether show the logo in sidebar 14 | */ 15 | sidebarLogo: false 16 | } 17 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/utils/auth.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const TokenKey = 'vue_admin_template_token' 4 | 5 | export function getToken() { 6 | return Cookies.get(TokenKey) 7 | } 8 | 9 | export function setToken(token) { 10 | return Cookies.set(TokenKey, token) 11 | } 12 | 13 | export function removeToken() { 14 | return Cookies.remove(TokenKey) 15 | } 16 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-back/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !**/src/main/** 3 | !**/src/test/** 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /nbdist/ 24 | /.nb-gradle/ 25 | build/ 26 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-back/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import getters from './getters' 4 | import app from './modules/app' 5 | import settings from './modules/settings' 6 | import user from './modules/user' 7 | 8 | Vue.use(Vuex) 9 | 10 | const store = new Vuex.Store({ 11 | modules: { 12 | app, 13 | settings, 14 | user 15 | }, 16 | getters 17 | }) 18 | 19 | export default store 20 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets 4 | 5 | import ElementUI from 'element-ui' 6 | import 'element-ui/lib/theme-chalk/index.css' 7 | import locale from 'element-ui/lib/locale/lang/zh-CN' // lang i18n 8 | 9 | import App from './App' 10 | 11 | Vue.use(ElementUI, { locale }) 12 | 13 | Vue.config.productionTip = false 14 | 15 | new Vue({ 16 | el: '#app', 17 | render: h => h(App) 18 | }) 19 | -------------------------------------------------------------------------------- /PageHelper_Demo/src/main/java/com/example/demo/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.mapper; 2 | 3 | 4 | import com.example.demo.base.BaseMapper; 5 | import com.example.demo.model.User; 6 | 7 | /** 8 | * @author SuperZhouDaLu 9 | */ 10 | public interface UserMapper extends BaseMapper { 11 | 12 | /** 13 | * 根据用户昵称查询用户主键 14 | * 15 | * @param nickname 用户昵称 16 | * @return 用户主键 17 | */ 18 | Integer getUserIdByNickname(String nickname); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/utils/validate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PanJiaChen on 16/11/18. 3 | */ 4 | 5 | /** 6 | * @param {string} path 7 | * @returns {Boolean} 8 | */ 9 | export function isExternal(path) { 10 | return /^(https?:|mailto:|tel:)/.test(path) 11 | } 12 | 13 | /** 14 | * @param {string} str 15 | * @returns {Boolean} 16 | */ 17 | export function validUsername(str) { 18 | const valid_map = ['admin', 'editor'] 19 | return valid_map.indexOf(str.trim()) >= 0 20 | } 21 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/example.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/styles/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &:after { 3 | content: ""; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | 9 | @mixin scrollBar { 10 | &::-webkit-scrollbar-track-piece { 11 | background: #d3dce6; 12 | } 13 | 14 | &::-webkit-scrollbar { 15 | width: 6px; 16 | } 17 | 18 | &::-webkit-scrollbar-thumb { 19 | background: #99a9bf; 20 | border-radius: 20px; 21 | } 22 | } 23 | 24 | @mixin relative { 25 | position: relative; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /PageHelper_Demo/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | name: {{ name }} 4 | 5 | 6 | 7 | 19 | 20 | 31 | -------------------------------------------------------------------------------- /PageHelper_Demo/src/main/java/com/example/demo/model/User.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.GenerationType; 7 | import javax.persistence.Id; 8 | import javax.persistence.Table; 9 | 10 | /** 11 | * @author SuperZhouDaLu 12 | * @date 2020-07-18 13 | */ 14 | @Data 15 | @Table(name = "sys_user") 16 | public class User { 17 | 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | private Integer id; 21 | 22 | private String nickname; 23 | 24 | private String username; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/password.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/components/Sidebar/Item.vue: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-back/src/main/java/com/example/demo/model/User.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | /** 4 | * 用户实体 5 | * 6 | * @author SuperZhouDaLu 7 | * @since 2019-12-28 8 | */ 9 | public class User { 10 | 11 | /** 12 | * 账户名称 13 | */ 14 | private String username; 15 | 16 | /** 17 | * 密码 18 | */ 19 | private String password; 20 | 21 | public User(String username, String password) { 22 | this.username = username; 23 | this.password = password; 24 | } 25 | 26 | public String getUsername() { 27 | return username; 28 | } 29 | 30 | public String getPassword() { 31 | return password; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/store/modules/settings.js: -------------------------------------------------------------------------------- 1 | import defaultSettings from '@/settings' 2 | 3 | const { showSettings, fixedHeader, sidebarLogo } = defaultSettings 4 | 5 | const state = { 6 | showSettings: showSettings, 7 | fixedHeader: fixedHeader, 8 | sidebarLogo: sidebarLogo 9 | } 10 | 11 | const mutations = { 12 | CHANGE_SETTING: (state, { key, value }) => { 13 | if (state.hasOwnProperty(key)) { 14 | state[key] = value 15 | } 16 | } 17 | } 18 | 19 | const actions = { 20 | changeSetting({ commit }, data) { 21 | commit('CHANGE_SETTING', data) 22 | } 23 | } 24 | 25 | export default { 26 | namespaced: true, 27 | state, 28 | mutations, 29 | actions 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= webpackConfig.name %> 9 | 10 | 11 | 12 | We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue. 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /PageHelper_Demo/src/main/java/com/example/demo/base/BaseMapper.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base; 2 | 3 | import org.springframework.stereotype.Repository; 4 | import tk.mybatis.mapper.common.Mapper; 5 | import tk.mybatis.mapper.common.MySqlMapper; 6 | import tk.mybatis.mapper.common.condition.SelectByConditionMapper; 7 | import tk.mybatis.mapper.common.condition.UpdateByConditionMapper; 8 | import tk.mybatis.mapper.common.ids.DeleteByIdsMapper; 9 | 10 | /** 11 | * 公用Mapper接口 12 | * 13 | * @author SuperZhouDaLu 14 | */ 15 | @Repository 16 | public interface BaseMapper extends Mapper, SelectByConditionMapper, UpdateByConditionMapper, DeleteByIdsMapper, MySqlMapper { 17 | // FIXME 特别注意,该接口不能被扫描到,否则会出错 18 | } 19 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= webpackConfig.name %> 9 | 10 | 11 | 12 | We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue. 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /PageHelper_Demo/src/main/resources/sql/pagehelper.sql: -------------------------------------------------------------------------------- 1 | SET FOREIGN_KEY_CHECKS=0; 2 | -- ---------------------------- 3 | -- Table structure for `sys_user` 4 | -- ---------------------------- 5 | DROP TABLE IF EXISTS `sys_user`; 6 | CREATE TABLE `sys_user` ( 7 | `id` int(11) NOT NULL AUTO_INCREMENT, 8 | `username` varchar(20) DEFAULT NULL, 9 | `nickname` varchar(20) DEFAULT NULL, 10 | PRIMARY KEY (`id`) 11 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4; 12 | 13 | -- ---------------------------- 14 | -- Records of sys_user 15 | -- ---------------------------- 16 | INSERT INTO `sys_user` VALUES ('1', 'zhangsan', '张三'); 17 | INSERT INTO `sys_user` VALUES ('2', 'lisi', '李四'); 18 | INSERT INTO `sys_user` VALUES ('3', 'wangwu', '王五'); 19 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | // sidebar 2 | $menuText:#bfcbd9; 3 | $menuActiveText:#409EFF; 4 | $subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951 5 | 6 | $menuBg:#304156; 7 | $menuHover:#263445; 8 | 9 | $subMenuBg:#1f2d3d; 10 | $subMenuHover:#001528; 11 | 12 | $sideBarWidth: 210px; 13 | 14 | // the :export directive is the magic sauce for webpack 15 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 16 | :export { 17 | menuText: $menuText; 18 | menuActiveText: $menuActiveText; 19 | subMenuActiveText: $subMenuActiveText; 20 | menuBg: $menuBg; 21 | menuHover: $menuHover; 22 | subMenuBg: $subMenuBg; 23 | subMenuHover: $subMenuHover; 24 | sideBarWidth: $sideBarWidth; 25 | } 26 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/components/Sidebar/Link.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 37 | -------------------------------------------------------------------------------- /PageHelper_Demo/src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | select u.id 14 | from sys_user u 15 | where u.nickname = '${nickname}' 16 | 17 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/components/Sidebar/FixiOSBug.js: -------------------------------------------------------------------------------- 1 | export default { 2 | computed: { 3 | device() { 4 | return this.$store.state.app.device 5 | } 6 | }, 7 | mounted() { 8 | // In order to fix the click on menu on the ios device will trigger the mouseleave bug 9 | // https://github.com/PanJiaChen/vue-element-admin/issues/1135 10 | this.fixBugIniOS() 11 | }, 12 | methods: { 13 | fixBugIniOS() { 14 | const $subMenu = this.$refs.subMenu 15 | if ($subMenu) { 16 | const handleMouseleave = $subMenu.handleMouseleave 17 | $subMenu.handleMouseleave = (e) => { 18 | if (this.device === 'mobile') { 19 | return 20 | } 21 | handleMouseleave(e) 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets 4 | 5 | import ElementUI from 'element-ui' 6 | import 'element-ui/lib/theme-chalk/index.css' 7 | import locale from 'element-ui/lib/locale/lang/en' // lang i18n 8 | 9 | import '@/styles/index.scss' // global css 10 | 11 | import App from './App' 12 | import store from './store' 13 | import router from './router' 14 | 15 | import '@/icons' // icon 16 | import '@/permission' // permission control 17 | 18 | // set ElementUI lang to EN 19 | Vue.use(ElementUI, { locale }) 20 | // 如果想要中文版 element-ui,按如下方式声明 21 | // Vue.use(ElementUI) 22 | 23 | Vue.config.productionTip = false 24 | 25 | new Vue({ 26 | el: '#app', 27 | router, 28 | store, 29 | render: h => h(App) 30 | }) 31 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/nested.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/components/AppMain.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 19 | 20 | 32 | 33 | 41 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/store/modules/user.js: -------------------------------------------------------------------------------- 1 | import { login } from '@/api/user' 2 | import { getToken, setToken } from '@/utils/auth' 3 | 4 | const state = { 5 | token: getToken(), 6 | name: '', 7 | avatar: '' 8 | } 9 | 10 | const mutations = { 11 | SET_TOKEN: (state, token) => { 12 | state.token = token 13 | } 14 | } 15 | 16 | const actions = { 17 | login({ commit }, userInfo) { 18 | const { username, password } = userInfo 19 | return new Promise((resolve, reject) => { 20 | login({ username: username.trim(), password: password }).then(() => { 21 | commit('SET_TOKEN', true) 22 | setToken(true) 23 | resolve() 24 | }).catch(error => { 25 | reject(error) 26 | }) 27 | }) 28 | } 29 | } 30 | 31 | export default { 32 | namespaced: true, 33 | state, 34 | mutations, 35 | actions 36 | } 37 | 38 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-back/src/main/java/com/example/demo/conf/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.conf; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.http.HttpHeaders; 5 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 7 | 8 | @Configuration 9 | public class WebMvcConfig implements WebMvcConfigurer { 10 | 11 | /** 12 | * 允许跨域访问 13 | */ 14 | @Override 15 | public void addCorsMappings(CorsRegistry registry) { 16 | registry.addMapping("/**") 17 | .allowedHeaders("*") 18 | .allowedMethods("*") 19 | .allowedOrigins("*") 20 | .allowCredentials(true) 21 | .exposedHeaders(HttpHeaders.SET_COOKIE); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-back/src/main/java/com/example/demo/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controller; 2 | 3 | import com.example.demo.model.User; 4 | import org.springframework.web.bind.annotation.PostMapping; 5 | import org.springframework.web.bind.annotation.RequestBody; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | /** 10 | * 用户登录接口 11 | * 12 | * @author SuperZhouDaLu 13 | * @since 2019-12-28 14 | */ 15 | @RestController 16 | @RequestMapping("/login") 17 | public class LoginController { 18 | 19 | /** 20 | * 登录接口 21 | * 22 | * @param user 用户登录信息 23 | */ 24 | @PostMapping 25 | public void login(@RequestBody User user) { 26 | System.out.println("登录账户:" + user.getUsername() + "-----登录密码:" + user.getPassword()); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/styles/element-ui.scss: -------------------------------------------------------------------------------- 1 | // cover some element-ui styles 2 | 3 | .el-breadcrumb__inner, 4 | .el-breadcrumb__inner a { 5 | font-weight: 400 !important; 6 | } 7 | 8 | .el-upload { 9 | input[type="file"] { 10 | display: none !important; 11 | } 12 | } 13 | 14 | .el-upload__input { 15 | display: none; 16 | } 17 | 18 | 19 | // to fixed https://github.com/ElemeFE/element/issues/2461 20 | .el-dialog { 21 | transform: none; 22 | left: 0; 23 | position: relative; 24 | margin: 0 auto; 25 | } 26 | 27 | // refine element ui upload 28 | .upload-container { 29 | .el-upload { 30 | width: 100%; 31 | 32 | .el-upload-dragger { 33 | width: 100%; 34 | height: 200px; 35 | } 36 | } 37 | } 38 | 39 | // dropdown 40 | .el-dropdown-menu { 41 | a { 42 | display: block 43 | } 44 | } 45 | 46 | // to fix el-date-picker css style 47 | .el-range-separator { 48 | box-sizing: content-box; 49 | } 50 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /PageHelper_Demo/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import com.example.demo.service.UserService; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 8 | import tk.mybatis.spring.annotation.MapperScan; 9 | 10 | import javax.annotation.Resource; 11 | 12 | @SpringBootApplication 13 | @MapperScan(basePackages = "com.example.demo.mapper") 14 | public class DemoApplication implements CommandLineRunner { 15 | 16 | @Resource 17 | private UserService userService; 18 | 19 | public static void main(String[] args) { 20 | SpringApplication.run(DemoApplication.class, args); 21 | } 22 | 23 | @Override 24 | public void run(String... args) { 25 | userService.queryDemo(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/styles/transition.scss: -------------------------------------------------------------------------------- 1 | // global transition css 2 | 3 | /* fade */ 4 | .fade-enter-active, 5 | .fade-leave-active { 6 | transition: opacity 0.28s; 7 | } 8 | 9 | .fade-enter, 10 | .fade-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | /* fade-transform */ 15 | .fade-transform-leave-active, 16 | .fade-transform-enter-active { 17 | transition: all .5s; 18 | } 19 | 20 | .fade-transform-enter { 21 | opacity: 0; 22 | transform: translateX(-30px); 23 | } 24 | 25 | .fade-transform-leave-to { 26 | opacity: 0; 27 | transform: translateX(30px); 28 | } 29 | 30 | /* breadcrumb transition */ 31 | .breadcrumb-enter-active, 32 | .breadcrumb-leave-active { 33 | transition: all .5s; 34 | } 35 | 36 | .breadcrumb-enter, 37 | .breadcrumb-leave-active { 38 | opacity: 0; 39 | transform: translateX(20px); 40 | } 41 | 42 | .breadcrumb-move { 43 | transition: all .5s; 44 | } 45 | 46 | .breadcrumb-leave-active { 47 | position: absolute; 48 | } 49 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/build/index.js: -------------------------------------------------------------------------------- 1 | const { run } = require('runjs') 2 | const chalk = require('chalk') 3 | const config = require('../vue.config.js') 4 | const rawArgv = process.argv.slice(2) 5 | const args = rawArgv.join(' ') 6 | 7 | if (process.env.npm_config_preview || rawArgv.includes('--preview')) { 8 | const report = rawArgv.includes('--report') 9 | 10 | run(`vue-cli-service build ${args}`) 11 | 12 | const port = 9526 13 | const publicPath = config.publicPath 14 | 15 | var connect = require('connect') 16 | var serveStatic = require('serve-static') 17 | const app = connect() 18 | 19 | app.use( 20 | publicPath, 21 | serveStatic('./dist', { 22 | index: ['index.html', '/'] 23 | }) 24 | ) 25 | 26 | app.listen(port, function () { 27 | console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) 28 | if (report) { 29 | console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) 30 | } 31 | 32 | }) 33 | } else { 34 | run(`vue-cli-service build ${args}`) 35 | } 36 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/build/index.js: -------------------------------------------------------------------------------- 1 | const { run } = require('runjs') 2 | const chalk = require('chalk') 3 | const config = require('../vue.config.js') 4 | const rawArgv = process.argv.slice(2) 5 | const args = rawArgv.join(' ') 6 | 7 | if (process.env.npm_config_preview || rawArgv.includes('--preview')) { 8 | const report = rawArgv.includes('--report') 9 | 10 | run(`vue-cli-service build ${args}`) 11 | 12 | const port = 9526 13 | const publicPath = config.publicPath 14 | 15 | var connect = require('connect') 16 | var serveStatic = require('serve-static') 17 | const app = connect() 18 | 19 | app.use( 20 | publicPath, 21 | serveStatic('./dist', { 22 | index: ['index.html', '/'] 23 | }) 24 | ) 25 | 26 | app.listen(port, function () { 27 | console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) 28 | if (report) { 29 | console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) 30 | } 31 | 32 | }) 33 | } else { 34 | run(`vue-cli-service build ${args}`) 35 | } 36 | -------------------------------------------------------------------------------- /PageHelper_Demo/src/main/java/com/example/demo/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | import com.example.demo.mapper.UserMapper; 4 | import com.example.demo.model.User; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.stereotype.Service; 7 | import tk.mybatis.mapper.entity.Example; 8 | import tk.mybatis.mapper.weekend.WeekendSqls; 9 | 10 | /** 11 | * @author SuperZhouDaLu 12 | * @date 2020-07-18 13 | */ 14 | @RequiredArgsConstructor 15 | @Service 16 | public class UserService { 17 | 18 | private final UserMapper userMapper; 19 | 20 | public void queryDemo() { 21 | // 第一种方式 Example Builder 模式 22 | Integer builderUserId = userMapper.selectOneByExample(new Example.Builder(User.class) 23 | .where(WeekendSqls.custom().andEqualTo(User::getNickname, "张三")).build()).getId(); 24 | // 第二种方式 Xml 自定义 Sql 模式 25 | Integer customSqlUserId = userMapper.getUserIdByNickname("李四"); 26 | System.out.println("queryDemo 执行结果: builderUserId: " + builderUserId + ", customSqlUserId: " + customSqlUserId); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/src/directive/el-table/adaptive.js: -------------------------------------------------------------------------------- 1 | import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event' 2 | 3 | const doResize = async(el, binding, vnode) => { 4 | const { componentInstance: $table } = await vnode 5 | 6 | const { value } = binding 7 | 8 | if (!$table.height) { 9 | throw new Error(`el-$table must set the height. Such as height='100px'`) 10 | } 11 | const bottomOffset = (value && value.bottomOffset) || 30 12 | 13 | if (!$table) return 14 | 15 | const height = window.innerHeight - el.getBoundingClientRect().top - bottomOffset 16 | $table.layout.setHeight(height) 17 | $table.doLayout() 18 | } 19 | 20 | export default { 21 | bind(el, binding, vnode) { 22 | el.resizeListener = async() => { 23 | await doResize(el, binding, vnode) 24 | } 25 | addResizeListener(el, el.resizeListener) 26 | addResizeListener(window.document.body, el.resizeListener) 27 | }, 28 | async inserted(el, binding, vnode) { 29 | await doResize(el, binding, vnode) 30 | }, 31 | async componentUpdated(el, binding, vnode) { 32 | await doResize(el, binding, vnode) 33 | }, 34 | unbind(el) { 35 | removeResizeListener(el, el.resizeListener) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/styles/index.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | @import './mixin.scss'; 3 | @import './transition.scss'; 4 | @import './element-ui.scss'; 5 | @import './sidebar.scss'; 6 | 7 | body { 8 | height: 100%; 9 | -moz-osx-font-smoothing: grayscale; 10 | -webkit-font-smoothing: antialiased; 11 | text-rendering: optimizeLegibility; 12 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; 13 | } 14 | 15 | label { 16 | font-weight: 700; 17 | } 18 | 19 | html { 20 | height: 100%; 21 | box-sizing: border-box; 22 | } 23 | 24 | #app { 25 | height: 100%; 26 | } 27 | 28 | *, 29 | *:before, 30 | *:after { 31 | box-sizing: inherit; 32 | } 33 | 34 | a:focus, 35 | a:active { 36 | outline: none; 37 | } 38 | 39 | a, 40 | a:focus, 41 | a:hover { 42 | cursor: pointer; 43 | color: inherit; 44 | text-decoration: none; 45 | } 46 | 47 | div:focus { 48 | outline: none; 49 | } 50 | 51 | .clearfix { 52 | &:after { 53 | visibility: hidden; 54 | display: block; 55 | font-size: 0; 56 | content: " "; 57 | clear: both; 58 | height: 0; 59 | } 60 | } 61 | 62 | // main-container global css 63 | .app-container { 64 | padding: 20px; 65 | } 66 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/eye-open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/store/modules/app.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const state = { 4 | sidebar: { 5 | opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, 6 | withoutAnimation: false 7 | }, 8 | device: 'desktop' 9 | } 10 | 11 | const mutations = { 12 | TOGGLE_SIDEBAR: state => { 13 | state.sidebar.opened = !state.sidebar.opened 14 | state.sidebar.withoutAnimation = false 15 | if (state.sidebar.opened) { 16 | Cookies.set('sidebarStatus', 1) 17 | } else { 18 | Cookies.set('sidebarStatus', 0) 19 | } 20 | }, 21 | CLOSE_SIDEBAR: (state, withoutAnimation) => { 22 | Cookies.set('sidebarStatus', 0) 23 | state.sidebar.opened = false 24 | state.sidebar.withoutAnimation = withoutAnimation 25 | }, 26 | TOGGLE_DEVICE: (state, device) => { 27 | state.device = device 28 | } 29 | } 30 | 31 | const actions = { 32 | toggleSideBar({ commit }) { 33 | commit('TOGGLE_SIDEBAR') 34 | }, 35 | closeSideBar({ commit }, { withoutAnimation }) { 36 | commit('CLOSE_SIDEBAR', withoutAnimation) 37 | }, 38 | toggleDevice({ commit }, device) { 39 | commit('TOGGLE_DEVICE', device) 40 | } 41 | } 42 | 43 | export default { 44 | namespaced: true, 45 | state, 46 | mutations, 47 | actions 48 | } 49 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/components/Hamburger/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 32 | 33 | 45 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/mixin/ResizeHandler.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | const { body } = document 4 | const WIDTH = 992 // refer to Bootstrap's responsive design 5 | 6 | export default { 7 | watch: { 8 | $route(route) { 9 | if (this.device === 'mobile' && this.sidebar.opened) { 10 | store.dispatch('app/closeSideBar', { withoutAnimation: false }) 11 | } 12 | } 13 | }, 14 | beforeMount() { 15 | window.addEventListener('resize', this.$_resizeHandler) 16 | }, 17 | beforeDestroy() { 18 | window.removeEventListener('resize', this.$_resizeHandler) 19 | }, 20 | mounted() { 21 | const isMobile = this.$_isMobile() 22 | if (isMobile) { 23 | store.dispatch('app/toggleDevice', 'mobile') 24 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) 25 | } 26 | }, 27 | methods: { 28 | // use $_ for mixins properties 29 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential 30 | $_isMobile() { 31 | const rect = body.getBoundingClientRect() 32 | return rect.width - 1 < WIDTH 33 | }, 34 | $_resizeHandler() { 35 | if (!document.hidden) { 36 | const isMobile = this.$_isMobile() 37 | store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') 38 | 39 | if (isMobile) { 40 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 47 | 48 | 63 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-front", 3 | "version": "0.0.1", 4 | "author": "SuperZhouDaLu", 5 | "scripts": { 6 | "dev": "vue-cli-service serve", 7 | "build:prod": "vue-cli-service build", 8 | "build:stage": "vue-cli-service build --mode staging", 9 | "preview": "node build/index.js --preview", 10 | "lint": "eslint --ext .js,.vue src", 11 | "test:unit": "jest --clearCache && vue-cli-service test:unit", 12 | "test:ci": "npm run lint && npm run test:unit", 13 | "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" 14 | }, 15 | "dependencies": { 16 | "element-ui": "2.13.1", 17 | "normalize.css": "7.0.0", 18 | "vue": "2.6.11" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "7.0.0", 22 | "@babel/register": "7.0.0", 23 | "@vue/cli-plugin-babel": "3.6.0", 24 | "@vue/cli-plugin-eslint": "^3.9.1", 25 | "@vue/cli-plugin-unit-jest": "3.6.3", 26 | "@vue/cli-service": "3.6.0", 27 | "@vue/test-utils": "1.0.0-beta.29", 28 | "babel-core": "7.0.0-bridge.0", 29 | "babel-eslint": "10.0.1", 30 | "babel-jest": "23.6.0", 31 | "chalk": "2.4.2", 32 | "connect": "3.6.6", 33 | "eslint": "5.15.3", 34 | "eslint-plugin-vue": "5.2.2", 35 | "html-webpack-plugin": "3.2.0", 36 | "runjs": "^4.3.2", 37 | "script-ext-html-webpack-plugin": "2.1.3", 38 | "serve-static": "^1.13.2", 39 | "svgo": "1.2.2", 40 | "vue-template-compiler": "2.6.11" 41 | }, 42 | "engines": { 43 | "node": ">=8.9", 44 | "npm": ">= 3.0.0" 45 | }, 46 | "browserslist": [ 47 | "> 1%", 48 | "last 2 versions" 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/utils/request.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { Message } from 'element-ui' 3 | import store from '@/store' 4 | import { getToken } from '@/utils/auth' 5 | 6 | // create an axios instance 7 | const service = axios.create({ 8 | baseURL: process.env.VUE_APP_BASE_API, 9 | withCredentials: true, 10 | timeout: 5000 11 | }) 12 | 13 | // request interceptor 14 | service.interceptors.request.use( 15 | config => { 16 | // do something before request is sent 17 | 18 | if (store.getters.token) { 19 | // let each request carry token 20 | // ['X-Token'] is a custom headers key 21 | // please modify it according to the actual situation 22 | config.headers['X-Token'] = getToken() 23 | } 24 | return config 25 | }, 26 | error => { 27 | // do something with request error 28 | console.log(error) // for debug 29 | return Promise.reject(error) 30 | } 31 | ) 32 | 33 | // response interceptor 34 | service.interceptors.response.use( 35 | /** 36 | * If you want to get http information such as headers or status 37 | * Please return response => response 38 | */ 39 | 40 | /** 41 | * Determine the request status by custom code 42 | * Here is just an example 43 | * You can also judge the status by HTTP Status Code 44 | */ 45 | response => { 46 | return response.data 47 | }, 48 | error => { 49 | console.log('err' + error) // for debug 50 | Message({ 51 | message: error.message, 52 | type: 'error', 53 | duration: 5 * 1000 54 | }) 55 | return Promise.reject(error) 56 | } 57 | ) 58 | 59 | export default service 60 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/components/Sidebar/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 57 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/README.md: -------------------------------------------------------------------------------- 1 | ### 前言 2 | 3 | 前后台分离越来越来成为主流,刚接触这种开发模式时,我们必定会遇到一个问题: **跨域**。 4 | 5 | ### 跨域 6 | 7 | 产生跨域问题的罪魁祸首是[浏览器同源策略](https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy),当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域,不同域之间的网络请求就会触发跨域问题。跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。 8 | 9 |  10 | 11 | ### 解决方法 12 | 13 | 前后台分离模式目前主流解决方案有三种: 14 | 15 | * webpack proxy:仅开发模式有效,打包后会失效。 16 | * cors:开发和生产环境都可以用。 17 | * nginx: 仅生产环境可用。 18 | 19 | 本文主要讲的是 cors 方式,需要前后台进行配合。 20 | 21 | #### 前台 22 | 23 | 前台使用 [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template) 脚手架,网络请求使用 Axios。Axios 是一个基于 promise 的 HTTP 客户端,可以发送 get、post 请求。 24 | 25 | >找到项目中 Axios 封装的文件,在 Axios 创建时增加属性 **withCredentials: true** : 26 | 27 | ``` 28 | const service = axios.create({ 29 | baseURL: process.env.VUE_APP_BASE_API, 30 | withCredentials: true, 31 | timeout: 5000 32 | }) 33 | ``` 34 | 35 | #### 后台 36 | 37 | >后台新建 `WebMvcConfig` 类,继承 `WebMvcConfigurer`,统一配置全局跨域请求。 38 | 39 | ``` 40 | @Configuration 41 | public class WebMvcConfig implements WebMvcConfigurer { 42 | 43 | /** 44 | * 允许跨域访问 45 | */ 46 | @Override 47 | public void addCorsMappings(CorsRegistry registry) { 48 | registry.addMapping("/**") // 可限制哪个请求可以通过跨域 49 | .allowedHeaders("*") // 可限制固定请求头可以通过跨域 50 | .allowedMethods("*") // 可限制固定methods可以通过跨域 51 | .allowedOrigins("*") // 可限制访问ip可以通过跨域 52 | .allowCredentials(true) // 是否允许发送cookie 53 | .exposedHeaders(HttpHeaders.SET_COOKIE); 54 | } 55 | 56 | } 57 | ``` -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/tree.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/tree/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 78 | 79 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-back/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.2.2.RELEASE 9 | 10 | 11 | com.example 12 | demo 13 | 0.0.1-SNAPSHOT 14 | demo 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | org.junit.vintage 34 | junit-vintage-engine 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/permission.js: -------------------------------------------------------------------------------- 1 | import router from './router' 2 | import store from './store' 3 | import { Message } from 'element-ui' 4 | import NProgress from 'nprogress' // progress bar 5 | import 'nprogress/nprogress.css' // progress bar style 6 | import { getToken } from '@/utils/auth' // get token from cookie 7 | import getPageTitle from '@/utils/get-page-title' 8 | 9 | NProgress.configure({ showSpinner: false }) // NProgress Configuration 10 | 11 | const whiteList = ['/login'] // no redirect whitelist 12 | 13 | router.beforeEach(async(to, from, next) => { 14 | // start progress bar 15 | NProgress.start() 16 | 17 | // set page title 18 | document.title = getPageTitle(to.meta.title) 19 | 20 | // determine whether the user has logged in 21 | const hasToken = getToken() 22 | 23 | if (hasToken) { 24 | if (to.path === '/login') { 25 | // if is logged in, redirect to the home page 26 | next({ path: '/' }) 27 | NProgress.done() 28 | } else { 29 | const hasGetUserInfo = store.getters.name 30 | if (hasGetUserInfo) { 31 | next() 32 | } else { 33 | try { 34 | next() 35 | } catch (error) { 36 | // remove token and go to login page to re-login 37 | await store.dispatch('user/resetToken') 38 | Message.error(error || 'Has Error') 39 | next(`/login?redirect=${to.path}`) 40 | NProgress.done() 41 | } 42 | } 43 | } 44 | } else { 45 | /* has no token*/ 46 | 47 | if (whiteList.indexOf(to.path) !== -1) { 48 | // in the free login whitelist, go directly 49 | next() 50 | } else { 51 | // other pages that do not have permission to access are redirected to the login page. 52 | next(`/login?redirect=${to.path}`) 53 | NProgress.done() 54 | } 55 | } 56 | }) 57 | 58 | router.afterEach(() => { 59 | // finish progress bar 60 | NProgress.done() 61 | }) 62 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-front", 3 | "version": "0.0.1", 4 | "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint", 5 | "author": "SuperZhouDaLu", 6 | "scripts": { 7 | "dev": "vue-cli-service serve", 8 | "build:prod": "vue-cli-service build", 9 | "build:stage": "vue-cli-service build --mode staging", 10 | "preview": "node build/index.js --preview", 11 | "lint": "eslint --ext .js,.vue src", 12 | "test:unit": "jest --clearCache && vue-cli-service test:unit", 13 | "test:ci": "npm run lint && npm run test:unit", 14 | "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" 15 | }, 16 | "dependencies": { 17 | "axios": "^0.21.1", 18 | "element-ui": "2.7.2", 19 | "js-cookie": "2.2.0", 20 | "normalize.css": "7.0.0", 21 | "nprogress": "0.2.0", 22 | "path-to-regexp": "2.4.0", 23 | "vue": "2.6.10", 24 | "vue-router": "3.0.6", 25 | "vuex": "3.1.0" 26 | }, 27 | "devDependencies": { 28 | "@babel/core": "7.0.0", 29 | "@babel/register": "7.0.0", 30 | "@vue/cli-plugin-babel": "3.6.0", 31 | "@vue/cli-plugin-eslint": "^3.9.1", 32 | "@vue/cli-plugin-unit-jest": "3.6.3", 33 | "@vue/cli-service": "3.6.0", 34 | "@vue/test-utils": "1.0.0-beta.29", 35 | "autoprefixer": "^9.5.1", 36 | "babel-core": "7.0.0-bridge.0", 37 | "babel-eslint": "10.0.1", 38 | "babel-jest": "23.6.0", 39 | "chalk": "2.4.2", 40 | "connect": "3.6.6", 41 | "eslint": "5.15.3", 42 | "eslint-plugin-vue": "5.2.2", 43 | "html-webpack-plugin": "3.2.0", 44 | "node-sass": "^4.9.0", 45 | "runjs": "^4.3.2", 46 | "sass-loader": "^7.1.0", 47 | "script-ext-html-webpack-plugin": "2.1.3", 48 | "script-loader": "0.7.2", 49 | "serve-static": "^1.13.2", 50 | "svg-sprite-loader": "4.1.3", 51 | "svgo": "1.2.2", 52 | "vue-template-compiler": "2.6.10" 53 | }, 54 | "engines": { 55 | "node": ">=8.9", 56 | "npm": ">= 3.0.0" 57 | }, 58 | "browserslist": [ 59 | "> 1%", 60 | "last 2 versions" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/components/Sidebar/Logo.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ title }} 7 | 8 | 9 | 10 | {{ title }} 11 | 12 | 13 | 14 | 15 | 16 | 33 | 34 | 83 | -------------------------------------------------------------------------------- /Merge_Table/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 60 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/dashboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 52 | 53 | 94 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/components/Breadcrumb/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ item.meta.title }} 6 | {{ item.meta.title }} 7 | 8 | 9 | 10 | 11 | 12 | 65 | 66 | 79 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/icons/svg/form.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /PageHelper_Demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.1.RELEASE 9 | 10 | 11 | com.example 12 | demo 13 | 0.0.1-SNAPSHOT 14 | demo 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 2.1.5 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter 26 | 27 | 28 | 29 | org.projectlombok 30 | lombok 31 | true 32 | 33 | 34 | 35 | mysql 36 | mysql-connector-java 37 | 8.0.28 38 | 39 | 40 | 41 | org.mybatis.spring.boot 42 | mybatis-spring-boot-starter 43 | 2.1.2 44 | 45 | 46 | tk.mybatis 47 | mapper-spring-boot-starter 48 | ${mapper.starter.version} 49 | 50 | 51 | 52 | com.alibaba 53 | druid-spring-boot-starter 54 | 1.1.21 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-starter-test 59 | test 60 | 61 | 62 | org.junit.vintage 63 | junit-vintage-engine 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | org.springframework.boot 73 | spring-boot-maven-plugin 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/form/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | - 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Create 44 | Cancel 45 | 46 | 47 | 48 | 49 | 50 | 79 | 80 | 85 | 86 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/utils/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PanJiaChen on 16/11/18. 3 | */ 4 | 5 | /** 6 | * Parse the time to string 7 | * @param {(Object|string|number)} time 8 | * @param {string} cFormat 9 | * @returns {string | null} 10 | */ 11 | export function parseTime(time, cFormat) { 12 | if (arguments.length === 0) { 13 | return null 14 | } 15 | const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' 16 | let date 17 | if (typeof time === 'object') { 18 | date = time 19 | } else { 20 | if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { 21 | time = parseInt(time) 22 | } 23 | if ((typeof time === 'number') && (time.toString().length === 10)) { 24 | time = time * 1000 25 | } 26 | date = new Date(time) 27 | } 28 | const formatObj = { 29 | y: date.getFullYear(), 30 | m: date.getMonth() + 1, 31 | d: date.getDate(), 32 | h: date.getHours(), 33 | i: date.getMinutes(), 34 | s: date.getSeconds(), 35 | a: date.getDay() 36 | } 37 | const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { 38 | const value = formatObj[key] 39 | // Note: getDay() returns 0 on Sunday 40 | if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] } 41 | return value.toString().padStart(2, '0') 42 | }) 43 | return time_str 44 | } 45 | 46 | /** 47 | * @param {number} time 48 | * @param {string} option 49 | * @returns {string} 50 | */ 51 | export function formatTime(time, option) { 52 | if (('' + time).length === 10) { 53 | time = parseInt(time) * 1000 54 | } else { 55 | time = +time 56 | } 57 | const d = new Date(time) 58 | const now = Date.now() 59 | 60 | const diff = (now - d) / 1000 61 | 62 | if (diff < 30) { 63 | return '刚刚' 64 | } else if (diff < 3600) { 65 | // less 1 hour 66 | return Math.ceil(diff / 60) + '分钟前' 67 | } else if (diff < 3600 * 24) { 68 | return Math.ceil(diff / 3600) + '小时前' 69 | } else if (diff < 3600 * 24 * 2) { 70 | return '1天前' 71 | } 72 | if (option) { 73 | return parseTime(time, option) 74 | } else { 75 | return ( 76 | d.getMonth() + 77 | 1 + 78 | '月' + 79 | d.getDate() + 80 | '日' + 81 | d.getHours() + 82 | '时' + 83 | d.getMinutes() + 84 | '分' 85 | ) 86 | } 87 | } 88 | 89 | /** 90 | * @param {string} url 91 | * @returns {Object} 92 | */ 93 | export function param2Obj(url) { 94 | const search = url.split('?')[1] 95 | if (!search) { 96 | return {} 97 | } 98 | return JSON.parse( 99 | '{"' + 100 | decodeURIComponent(search) 101 | .replace(/"/g, '\\"') 102 | .replace(/&/g, '","') 103 | .replace(/=/g, '":"') 104 | .replace(/\+/g, ' ') + 105 | '"}' 106 | ) 107 | } 108 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/components/Sidebar/SidebarItem.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 96 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/layout/components/Navbar.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Home 17 | 18 | 19 | 20 | Github 21 | 22 | 23 | Log Out 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 57 | 58 | 136 | -------------------------------------------------------------------------------- /Merge_Table/README.md: -------------------------------------------------------------------------------- 1 | ### 前言 2 | 3 | > 示例版本为 Element-UI 2.13.2 + Vue 2.6.11 4 | 5 | 由于项目业务需求,最近写了一个可以自动合并行、列的表格组件,**对数据格式有一定的要求性**。 6 | 7 |  8 | 9 | [Element-UI]( 10 | https://codepen.io/pen/?&editable=true=https%3A%2F%2Felement.eleme.cn%2F) 提供了表格内容可以合并的示例,但是复杂一些的功能还是需要自己完成,在写组件之前查找了相关资料,并没有发现相关的示例,故分享一下。 11 | 12 | ### 预设数据 13 | 14 | 组件在定义之前需要提前预设几个属性: 15 | 16 | * tableData:表格中的数据 17 | * colConfigs:表格列的内容信息 18 | * mergeColumns:要合并的列信息 19 | 20 | #### tableData 21 | 示例中的数据格式: 22 | 23 | ``` 24 | [ 25 | { time: '2020-08-10', grade: '三年二班', name: '小明', subjects: '语文' }, 26 | { time: '2020-08-10', grade: '三年二班', name: '小明', subjects: '数学' }, 27 | { time: '2020-08-10', grade: '总成绩', name: '总成绩', subjects: '总成绩' }, 28 | { time: '2020-08-10', grade: '三年一班', name: '小雷', subjects: '语文' }, 29 | { time: '2020-08-10', grade: '三年一班', name: '小雷', subjects: '数学' }, 30 | { time: '2020-08-10', grade: '总成绩', name: '总成绩', subjects: '总成绩' }, 31 | { time: '2020-08-11', grade: '三年三班', name: '小花', subjects: '语文' }, 32 | { time: '2020-08-11', grade: '三年三班', name: '小花', subjects: '数学' }, 33 | { time: '2020-08-11', grade: '总成绩', name: '总成绩', subjects: '总成绩' } 34 | ] 35 | ``` 36 | #### colConfigs 37 | 38 | 表格列的内容信息: 39 | 40 | ``` 41 | [ 42 | { 43 | label: '考试信息', 44 | align: 'center', 45 | type: 'label', 46 | children: [ 47 | { prop: 'time', label: '考试时间', align: 'center' }, 48 | { prop: 'grade', label: '所在班级', align: 'center' }, 49 | { prop: 'name', label: '考生姓名', align: 'center' }, 50 | { prop: 'subjects', label: '考试科目', align: 'center' } 51 | ] 52 | }, 53 | { prop: 'results', label: '考试成绩', align: 'center', type: 'input' }, 54 | { prop: 'remark', label: '备注', align: 'center', type: 'input' } 55 | ] 56 | ``` 57 | 58 | | 参数 | 说明 | 59 | | --- | --- | 60 | | label | 显示的标题(element-ui原始属性) | 61 | | align | 对齐方式(element-ui原始属性) | 62 | | width | 对应列的宽度(element-ui原始属性) | 63 | | prop | 对应列内容的字段名(element-ui原始属性) | 64 | | formatter | 用来格式化内容(element-ui原始属性) | 65 | | type | 自定义属性,暂分为‘label’和其它,label为不可编辑的列,其它属性可按需自定义| 66 | | children | 自定义属性,存在合并列的情况 | 67 | 68 | #### mergeColumns 69 | 70 | 71 | 要合并的列信息数据格式: 72 | 73 | ``` 74 | [ 75 | { index: 2, name: 'time' }, 76 | { index: 3, name: 'grade' }, 77 | { index: 4, name: 'name' }, 78 | { index: 5, name: 'subjects' } 79 | ] 80 | ``` 81 | 82 | | 参数 | 说明 | 83 | | --- | --- | 84 | | index | 所在表格中的列下标 | 85 | | name | 要合并的字段名称 | 86 | 87 | 88 | ### 定义组件 89 | 90 | 将上面预设好的数据以 `props` 的方式传递到定义好的组件内。`el-table`组件内的内容在不进行合并的时候坐标信息为 `[1,1]`,如果中间出现了 `0`,例如:`[0,1]`, 就会隐藏掉相关的单元格,反之如果为 `[1,2]` 就会把相邻的单元格合并。表格合并思路为:在组件加载时根据 `tableData` 和`mergeColumns` 生成新的坐标信息,并调用`Element`提供的 `span-method` 生成。 91 | 92 | #### 生成坐标数组信息 93 | 94 |  95 | 96 | ``` 97 | // 遍历表格中需要合并的所有单元格 98 | for (let i = 0; i < this.tableData.length; i++) { 99 | for (let j = 0; j < this.mergeColumns.length; j++) { 100 | // 初始化行、列坐标信息 101 | let rowIndex = 1 102 | let columnIndex = 1 103 | // 比较横坐标左方的第一个元素 104 | if (j > 0 && this.tableData[i][this.mergeColumns[j]['name']] === this.tableData[i][this.mergeColumns[j - 1]['name']]) { 105 | columnIndex = 0 106 | } 107 | // 比较纵坐标上方的第一个元素 108 | if (i > 0 && this.tableData[i][this.mergeColumns[j]['name']] === this.tableData[i - 1][this.mergeColumns[j]['name']]) { 109 | rowIndex = 0 110 | } 111 | // 比较横坐标右方元素 112 | if (columnIndex > 0) { 113 | columnIndex = this.calculateColumnIndex(this.tableData[i], j, j + 1, 1, this.mergeColumns.length) 114 | } 115 | // 比较纵坐标下方元素 116 | if (rowIndex > 0) { 117 | rowIndex = this.calculateRowIndex(this.tableData, i, i + 1, 1, this.mergeColumns[j]['name']) 118 | } 119 | const key = this.mergeColumns[j]['index'] + '_' + i 120 | this.tableMergeData[key] = [rowIndex, columnIndex] 121 | } 122 | } 123 | ``` 124 | 125 | **遍历要合并的每一个单元格数据,以单个单元格为节点对周围的单元格的内容进行比对,然后用当前坐标为key存放新的坐标值,然后调用`Element`提供的 `span-method`方法生成合并后的数据结果。** 126 | 127 | ``` 128 | mergeCols({ rowIndex, columnIndex }) { 129 | const key = columnIndex + '_' + rowIndex 130 | if (this.tableMergeData[key]) { 131 | return this.tableMergeData[key] 132 | } 133 | } 134 | ``` 135 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 查询 5 | 添加 6 | 删除 7 | 12 | 17 | 22 | 27 | 31 | 32 | 40 | 41 | 42 | 43 | 156 | 161 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/styles/sidebar.scss: -------------------------------------------------------------------------------- 1 | #app { 2 | 3 | .main-container { 4 | min-height: 100%; 5 | transition: margin-left .28s; 6 | margin-left: $sideBarWidth; 7 | position: relative; 8 | } 9 | 10 | .sidebar-container { 11 | transition: width 0.28s; 12 | width: $sideBarWidth !important; 13 | background-color: $menuBg; 14 | height: 100%; 15 | position: fixed; 16 | font-size: 0px; 17 | top: 0; 18 | bottom: 0; 19 | left: 0; 20 | z-index: 1001; 21 | overflow: hidden; 22 | 23 | // reset element-ui css 24 | .horizontal-collapse-transition { 25 | transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; 26 | } 27 | 28 | .scrollbar-wrapper { 29 | overflow-x: hidden !important; 30 | } 31 | 32 | .el-scrollbar__bar.is-vertical { 33 | right: 0px; 34 | } 35 | 36 | .el-scrollbar { 37 | height: 100%; 38 | } 39 | 40 | &.has-logo { 41 | .el-scrollbar { 42 | height: calc(100% - 50px); 43 | } 44 | } 45 | 46 | .is-horizontal { 47 | display: none; 48 | } 49 | 50 | a { 51 | display: inline-block; 52 | width: 100%; 53 | overflow: hidden; 54 | } 55 | 56 | .svg-icon { 57 | margin-right: 16px; 58 | } 59 | 60 | .el-menu { 61 | border: none; 62 | height: 100%; 63 | width: 100% !important; 64 | } 65 | 66 | // menu hover 67 | .submenu-title-noDropdown, 68 | .el-submenu__title { 69 | &:hover { 70 | background-color: $menuHover !important; 71 | } 72 | } 73 | 74 | .is-active>.el-submenu__title { 75 | color: $subMenuActiveText !important; 76 | } 77 | 78 | & .nest-menu .el-submenu>.el-submenu__title, 79 | & .el-submenu .el-menu-item { 80 | min-width: $sideBarWidth !important; 81 | background-color: $subMenuBg !important; 82 | 83 | &:hover { 84 | background-color: $subMenuHover !important; 85 | } 86 | } 87 | } 88 | 89 | .hideSidebar { 90 | .sidebar-container { 91 | width: 54px !important; 92 | } 93 | 94 | .main-container { 95 | margin-left: 54px; 96 | } 97 | 98 | .submenu-title-noDropdown { 99 | padding: 0 !important; 100 | position: relative; 101 | 102 | .el-tooltip { 103 | padding: 0 !important; 104 | 105 | .svg-icon { 106 | margin-left: 20px; 107 | } 108 | } 109 | } 110 | 111 | .el-submenu { 112 | overflow: hidden; 113 | 114 | &>.el-submenu__title { 115 | padding: 0 !important; 116 | 117 | .svg-icon { 118 | margin-left: 20px; 119 | } 120 | 121 | .el-submenu__icon-arrow { 122 | display: none; 123 | } 124 | } 125 | } 126 | 127 | .el-menu--collapse { 128 | .el-submenu { 129 | &>.el-submenu__title { 130 | &>span { 131 | height: 0; 132 | width: 0; 133 | overflow: hidden; 134 | visibility: hidden; 135 | display: inline-block; 136 | } 137 | } 138 | } 139 | } 140 | } 141 | 142 | .el-menu--collapse .el-menu .el-submenu { 143 | min-width: $sideBarWidth !important; 144 | } 145 | 146 | // mobile responsive 147 | .mobile { 148 | .main-container { 149 | margin-left: 0px; 150 | } 151 | 152 | .sidebar-container { 153 | transition: transform .28s; 154 | width: $sideBarWidth !important; 155 | } 156 | 157 | &.hideSidebar { 158 | .sidebar-container { 159 | pointer-events: none; 160 | transition-duration: 0.3s; 161 | transform: translate3d(-$sideBarWidth, 0, 0); 162 | } 163 | } 164 | } 165 | 166 | .withoutAnimation { 167 | 168 | .main-container, 169 | .sidebar-container { 170 | transition: none; 171 | } 172 | } 173 | } 174 | 175 | // when menu collapsed 176 | .el-menu--vertical { 177 | &>.el-menu { 178 | .svg-icon { 179 | margin-right: 16px; 180 | } 181 | } 182 | 183 | .nest-menu .el-submenu>.el-submenu__title, 184 | .el-menu-item { 185 | &:hover { 186 | // you can use $subMenuHover 187 | background-color: $menuHover !important; 188 | } 189 | } 190 | 191 | // the scroll bar appears when the subMenu is too long 192 | >.el-menu--popup { 193 | max-height: 100vh; 194 | overflow-y: auto; 195 | 196 | &::-webkit-scrollbar-track-piece { 197 | background: #d3dce6; 198 | } 199 | 200 | &::-webkit-scrollbar { 201 | width: 6px; 202 | } 203 | 204 | &::-webkit-scrollbar-thumb { 205 | background: #99a9bf; 206 | border-radius: 20px; 207 | } 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/vue.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const defaultSettings = require('./src/settings.js') 4 | 5 | function resolve(dir) { 6 | return path.join(__dirname, dir) 7 | } 8 | 9 | const name = defaultSettings.title || 'vue Admin Template' // page title 10 | 11 | // If your port is set to 80, 12 | // use administrator privileges to execute the command line. 13 | // For example, Mac: sudo npm run 14 | // You can change the port by the following methods: 15 | // port = 9528 npm run dev OR npm run dev --port = 9528 16 | const port = process.env.port || process.env.npm_config_port || 9528 // dev port 17 | 18 | // All configuration item explanations can be find in https://cli.vuejs.org/config/ 19 | module.exports = { 20 | /** 21 | * You will need to set publicPath if you plan to deploy your site under a sub path, 22 | * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, 23 | * then publicPath should be set to "/bar/". 24 | * In most cases please use '/' !!! 25 | * Detail: https://cli.vuejs.org/config/#publicpath 26 | */ 27 | publicPath: '/', 28 | outputDir: 'dist', 29 | assetsDir: 'static', 30 | lintOnSave: process.env.NODE_ENV === 'development', 31 | productionSourceMap: false, 32 | devServer: { 33 | port: port, 34 | open: true, 35 | overlay: { 36 | warnings: false, 37 | errors: true 38 | }, 39 | proxy: { 40 | [process.env.VUE_APP_BASE_API]: { 41 | target: `http://127.0.0.1:${port}/mock`, 42 | changeOrigin: true, 43 | pathRewrite: { 44 | ['^' + process.env.VUE_APP_BASE_API]: '' 45 | } 46 | } 47 | } 48 | }, 49 | configureWebpack: { 50 | // provide the app's title in webpack's name field, so that 51 | // it can be accessed in index.html to inject the correct title. 52 | name: name, 53 | resolve: { 54 | alias: { 55 | '@': resolve('src') 56 | } 57 | } 58 | }, 59 | chainWebpack(config) { 60 | config.plugins.delete('preload') // TODO: need test 61 | config.plugins.delete('prefetch') // TODO: need test 62 | 63 | // set svg-sprite-loader 64 | config.module 65 | .rule('svg') 66 | .exclude.add(resolve('src/icons')) 67 | .end() 68 | config.module 69 | .rule('icons') 70 | .test(/\.svg$/) 71 | .include.add(resolve('src/icons')) 72 | .end() 73 | .use('svg-sprite-loader') 74 | .loader('svg-sprite-loader') 75 | .options({ 76 | symbolId: 'icon-[name]' 77 | }) 78 | .end() 79 | 80 | // set preserveWhitespace 81 | config.module 82 | .rule('vue') 83 | .use('vue-loader') 84 | .loader('vue-loader') 85 | .tap(options => { 86 | options.compilerOptions.preserveWhitespace = true 87 | return options 88 | }) 89 | .end() 90 | 91 | config 92 | // https://webpack.js.org/configuration/devtool/#development 93 | .when(process.env.NODE_ENV === 'development', 94 | config => config.devtool('cheap-source-map') 95 | ) 96 | 97 | config 98 | .when(process.env.NODE_ENV !== 'development', 99 | config => { 100 | config 101 | .plugin('ScriptExtHtmlWebpackPlugin') 102 | .after('html') 103 | .use('script-ext-html-webpack-plugin', [{ 104 | // `runtime` must same as runtimeChunk name. default is `runtime` 105 | inline: /runtime\..*\.js$/ 106 | }]) 107 | .end() 108 | config 109 | .optimization.splitChunks({ 110 | chunks: 'all', 111 | cacheGroups: { 112 | libs: { 113 | name: 'chunk-libs', 114 | test: /[\\/]node_modules[\\/]/, 115 | priority: 10, 116 | chunks: 'initial' // only package third parties that are initially dependent 117 | }, 118 | elementUI: { 119 | name: 'chunk-elementUI', // split elementUI into a single package 120 | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app 121 | test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm 122 | }, 123 | commons: { 124 | name: 'chunk-commons', 125 | test: resolve('src/components'), // can customize your rules 126 | minChunks: 3, // minimum common number 127 | priority: 5, 128 | reuseExistingChunk: true 129 | } 130 | } 131 | }) 132 | config.optimization.runtimeChunk('single') 133 | } 134 | ) 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/vue.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const defaultSettings = require('./src/settings.js') 4 | 5 | function resolve(dir) { 6 | return path.join(__dirname, dir) 7 | } 8 | 9 | const name = defaultSettings.title || 'vue Admin Template' // page title 10 | 11 | // If your port is set to 80, 12 | // use administrator privileges to execute the command line. 13 | // For example, Mac: sudo npm run 14 | // You can change the port by the following methods: 15 | // port = 9528 npm run dev OR npm run dev --port = 9528 16 | const port = process.env.port || process.env.npm_config_port || 9528 // dev port 17 | 18 | // All configuration item explanations can be find in https://cli.vuejs.org/config/ 19 | module.exports = { 20 | /** 21 | * You will need to set publicPath if you plan to deploy your site under a sub path, 22 | * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, 23 | * then publicPath should be set to "/bar/". 24 | * In most cases please use '/' !!! 25 | * Detail: https://cli.vuejs.org/config/#publicpath 26 | */ 27 | publicPath: '/', 28 | outputDir: 'dist', 29 | assetsDir: 'static', 30 | lintOnSave: process.env.NODE_ENV === 'development', 31 | productionSourceMap: false, 32 | devServer: { 33 | port: port, 34 | open: true, 35 | overlay: { 36 | warnings: false, 37 | errors: true 38 | }, 39 | proxy: { 40 | [process.env.VUE_APP_BASE_API]: { 41 | target: `http://127.0.0.1:${port}/mock`, 42 | changeOrigin: true, 43 | pathRewrite: { 44 | ['^' + process.env.VUE_APP_BASE_API]: '' 45 | } 46 | } 47 | } 48 | }, 49 | configureWebpack: { 50 | // provide the app's title in webpack's name field, so that 51 | // it can be accessed in index.html to inject the correct title. 52 | name: name, 53 | resolve: { 54 | alias: { 55 | '@': resolve('src') 56 | } 57 | } 58 | }, 59 | chainWebpack(config) { 60 | config.plugins.delete('preload') // TODO: need test 61 | config.plugins.delete('prefetch') // TODO: need test 62 | 63 | // set svg-sprite-loader 64 | config.module 65 | .rule('svg') 66 | .exclude.add(resolve('src/icons')) 67 | .end() 68 | config.module 69 | .rule('icons') 70 | .test(/\.svg$/) 71 | .include.add(resolve('src/icons')) 72 | .end() 73 | .use('svg-sprite-loader') 74 | .loader('svg-sprite-loader') 75 | .options({ 76 | symbolId: 'icon-[name]' 77 | }) 78 | .end() 79 | 80 | // set preserveWhitespace 81 | config.module 82 | .rule('vue') 83 | .use('vue-loader') 84 | .loader('vue-loader') 85 | .tap(options => { 86 | options.compilerOptions.preserveWhitespace = true 87 | return options 88 | }) 89 | .end() 90 | 91 | config 92 | // https://webpack.js.org/configuration/devtool/#development 93 | .when(process.env.NODE_ENV === 'development', 94 | config => config.devtool('cheap-source-map') 95 | ) 96 | 97 | config 98 | .when(process.env.NODE_ENV !== 'development', 99 | config => { 100 | config 101 | .plugin('ScriptExtHtmlWebpackPlugin') 102 | .after('html') 103 | .use('script-ext-html-webpack-plugin', [{ 104 | // `runtime` must same as runtimeChunk name. default is `runtime` 105 | inline: /runtime\..*\.js$/ 106 | }]) 107 | .end() 108 | config 109 | .optimization.splitChunks({ 110 | chunks: 'all', 111 | cacheGroups: { 112 | libs: { 113 | name: 'chunk-libs', 114 | test: /[\\/]node_modules[\\/]/, 115 | priority: 10, 116 | chunks: 'initial' // only package third parties that are initially dependent 117 | }, 118 | elementUI: { 119 | name: 'chunk-elementUI', // split elementUI into a single package 120 | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app 121 | test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm 122 | }, 123 | commons: { 124 | name: 'chunk-commons', 125 | test: resolve('src/components'), // can customize your rules 126 | minChunks: 3, // minimum common number 127 | priority: 5, 128 | reuseExistingChunk: true 129 | } 130 | } 131 | }) 132 | config.optimization.runtimeChunk('single') 133 | } 134 | ) 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | Vue.use(Router) 5 | 6 | /* Layout */ 7 | import Layout from '@/layout' 8 | 9 | /** 10 | * Note: sub-menu only appear when route children.length >= 1 11 | * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html 12 | * 13 | * hidden: true if set true, item will not show in the sidebar(default is false) 14 | * alwaysShow: true if set true, will always show the root menu 15 | * if not set alwaysShow, when item has more than one children route, 16 | * it will becomes nested mode, otherwise not show the root menu 17 | * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb 18 | * name:'router-name' the name is used by (must set!!!) 19 | * meta : { 20 | roles: ['admin','editor'] control the page roles (you can set multiple roles) 21 | title: 'title' the name show in sidebar and breadcrumb (recommend set) 22 | icon: 'svg-name' the icon show in the sidebar 23 | breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) 24 | activeMenu: '/example/list' if set path, the sidebar will highlight the path you set 25 | } 26 | */ 27 | 28 | /** 29 | * constantRoutes 30 | * a base page that does not have permission requirements 31 | * all roles can be accessed 32 | */ 33 | export const constantRoutes = [ 34 | { 35 | path: '/login', 36 | component: () => import('@/views/login/index'), 37 | hidden: true 38 | }, 39 | 40 | { 41 | path: '/404', 42 | component: () => import('@/views/404'), 43 | hidden: true 44 | }, 45 | 46 | { 47 | path: '/', 48 | component: Layout, 49 | redirect: '/dashboard', 50 | children: [{ 51 | path: 'dashboard', 52 | name: 'Dashboard', 53 | component: () => import('@/views/dashboard/index'), 54 | meta: { title: 'Dashboard', icon: 'dashboard' } 55 | }] 56 | }, 57 | 58 | { 59 | path: '/example', 60 | component: Layout, 61 | redirect: '/example/table', 62 | name: 'Example', 63 | meta: { title: 'Example', icon: 'example' }, 64 | children: [ 65 | { 66 | path: 'tree', 67 | name: 'Tree', 68 | component: () => import('@/views/tree/index'), 69 | meta: { title: 'Tree', icon: 'tree' } 70 | } 71 | ] 72 | }, 73 | 74 | { 75 | path: '/form', 76 | component: Layout, 77 | children: [ 78 | { 79 | path: 'index', 80 | name: 'Form', 81 | component: () => import('@/views/form/index'), 82 | meta: { title: 'Form', icon: 'form' } 83 | } 84 | ] 85 | }, 86 | 87 | { 88 | path: '/nested', 89 | component: Layout, 90 | redirect: '/nested/menu1', 91 | name: 'Nested', 92 | meta: { 93 | title: 'Nested', 94 | icon: 'nested' 95 | }, 96 | children: [ 97 | { 98 | path: 'menu1', 99 | component: () => import('@/views/nested/menu1/index'), // Parent router-view 100 | name: 'Menu1', 101 | meta: { title: 'Menu1' }, 102 | children: [ 103 | { 104 | path: 'menu1-1', 105 | component: () => import('@/views/nested/menu1/menu1-1'), 106 | name: 'Menu1-1', 107 | meta: { title: 'Menu1-1' } 108 | }, 109 | { 110 | path: 'menu1-2', 111 | component: () => import('@/views/nested/menu1/menu1-2'), 112 | name: 'Menu1-2', 113 | meta: { title: 'Menu1-2' }, 114 | children: [ 115 | { 116 | path: 'menu1-2-1', 117 | component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'), 118 | name: 'Menu1-2-1', 119 | meta: { title: 'Menu1-2-1' } 120 | }, 121 | { 122 | path: 'menu1-2-2', 123 | component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'), 124 | name: 'Menu1-2-2', 125 | meta: { title: 'Menu1-2-2' } 126 | } 127 | ] 128 | }, 129 | { 130 | path: 'menu1-3', 131 | component: () => import('@/views/nested/menu1/menu1-3'), 132 | name: 'Menu1-3', 133 | meta: { title: 'Menu1-3' } 134 | } 135 | ] 136 | }, 137 | { 138 | path: 'menu2', 139 | component: () => import('@/views/nested/menu2/index'), 140 | meta: { title: 'menu2' } 141 | } 142 | ] 143 | }, 144 | 145 | { 146 | path: 'external-link', 147 | component: Layout, 148 | children: [ 149 | { 150 | path: 'https://github.com/superZhouDaLu', 151 | meta: { title: 'External Link', icon: 'link' } 152 | } 153 | ] 154 | }, 155 | 156 | // 404 page must be placed at the end !!! 157 | { path: '*', redirect: '/404', hidden: true } 158 | ] 159 | 160 | const createRouter = () => new Router({ 161 | // mode: 'history', // require service support 162 | scrollBehavior: () => ({ y: 0 }), 163 | routes: constantRoutes 164 | }) 165 | 166 | const router = createRouter() 167 | 168 | // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465 169 | export function resetRouter() { 170 | const newRouter = createRouter() 171 | router.matcher = newRouter.matcher // reset router 172 | } 173 | 174 | export default router 175 | -------------------------------------------------------------------------------- /Vue_Adaptive_Table/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | parser: 'babel-eslint', 5 | sourceType: 'module' 6 | }, 7 | env: { 8 | browser: true, 9 | node: true, 10 | es6: true, 11 | }, 12 | extends: ['plugin:vue/recommended', 'eslint:recommended'], 13 | 14 | // add your custom rules here 15 | //it is base on https://github.com/vuejs/eslint-config-vue 16 | rules: { 17 | "vue/max-attributes-per-line": [2, { 18 | "singleline": 10, 19 | "multiline": { 20 | "max": 1, 21 | "allowFirstLine": false 22 | } 23 | }], 24 | "vue/singleline-html-element-content-newline": "off", 25 | "vue/multiline-html-element-content-newline":"off", 26 | "vue/name-property-casing": ["error", "PascalCase"], 27 | "vue/no-v-html": "off", 28 | 'accessor-pairs': 2, 29 | 'arrow-spacing': [2, { 30 | 'before': true, 31 | 'after': true 32 | }], 33 | 'block-spacing': [2, 'always'], 34 | 'brace-style': [2, '1tbs', { 35 | 'allowSingleLine': true 36 | }], 37 | 'camelcase': [0, { 38 | 'properties': 'always' 39 | }], 40 | 'comma-dangle': [2, 'never'], 41 | 'comma-spacing': [2, { 42 | 'before': false, 43 | 'after': true 44 | }], 45 | 'comma-style': [2, 'last'], 46 | 'constructor-super': 2, 47 | 'curly': [2, 'multi-line'], 48 | 'dot-location': [2, 'property'], 49 | 'eol-last': 2, 50 | 'eqeqeq': ["error", "always", {"null": "ignore"}], 51 | 'generator-star-spacing': [2, { 52 | 'before': true, 53 | 'after': true 54 | }], 55 | 'handle-callback-err': [2, '^(err|error)$'], 56 | 'indent': [2, 2, { 57 | 'SwitchCase': 1 58 | }], 59 | 'jsx-quotes': [2, 'prefer-single'], 60 | 'key-spacing': [2, { 61 | 'beforeColon': false, 62 | 'afterColon': true 63 | }], 64 | 'keyword-spacing': [2, { 65 | 'before': true, 66 | 'after': true 67 | }], 68 | 'new-cap': [2, { 69 | 'newIsCap': true, 70 | 'capIsNew': false 71 | }], 72 | 'new-parens': 2, 73 | 'no-array-constructor': 2, 74 | 'no-caller': 2, 75 | 'no-console': 'off', 76 | 'no-class-assign': 2, 77 | 'no-cond-assign': 2, 78 | 'no-const-assign': 2, 79 | 'no-control-regex': 0, 80 | 'no-delete-var': 2, 81 | 'no-dupe-args': 2, 82 | 'no-dupe-class-members': 2, 83 | 'no-dupe-keys': 2, 84 | 'no-duplicate-case': 2, 85 | 'no-empty-character-class': 2, 86 | 'no-empty-pattern': 2, 87 | 'no-eval': 2, 88 | 'no-ex-assign': 2, 89 | 'no-extend-native': 2, 90 | 'no-extra-bind': 2, 91 | 'no-extra-boolean-cast': 2, 92 | 'no-extra-parens': [2, 'functions'], 93 | 'no-fallthrough': 2, 94 | 'no-floating-decimal': 2, 95 | 'no-func-assign': 2, 96 | 'no-implied-eval': 2, 97 | 'no-inner-declarations': [2, 'functions'], 98 | 'no-invalid-regexp': 2, 99 | 'no-irregular-whitespace': 2, 100 | 'no-iterator': 2, 101 | 'no-label-var': 2, 102 | 'no-labels': [2, { 103 | 'allowLoop': false, 104 | 'allowSwitch': false 105 | }], 106 | 'no-lone-blocks': 2, 107 | 'no-mixed-spaces-and-tabs': 2, 108 | 'no-multi-spaces': 2, 109 | 'no-multi-str': 2, 110 | 'no-multiple-empty-lines': [2, { 111 | 'max': 1 112 | }], 113 | 'no-native-reassign': 2, 114 | 'no-negated-in-lhs': 2, 115 | 'no-new-object': 2, 116 | 'no-new-require': 2, 117 | 'no-new-symbol': 2, 118 | 'no-new-wrappers': 2, 119 | 'no-obj-calls': 2, 120 | 'no-octal': 2, 121 | 'no-octal-escape': 2, 122 | 'no-path-concat': 2, 123 | 'no-proto': 2, 124 | 'no-redeclare': 2, 125 | 'no-regex-spaces': 2, 126 | 'no-return-assign': [2, 'except-parens'], 127 | 'no-self-assign': 2, 128 | 'no-self-compare': 2, 129 | 'no-sequences': 2, 130 | 'no-shadow-restricted-names': 2, 131 | 'no-spaced-func': 2, 132 | 'no-sparse-arrays': 2, 133 | 'no-this-before-super': 2, 134 | 'no-throw-literal': 2, 135 | 'no-trailing-spaces': 2, 136 | 'no-undef': 2, 137 | 'no-undef-init': 2, 138 | 'no-unexpected-multiline': 2, 139 | 'no-unmodified-loop-condition': 2, 140 | 'no-unneeded-ternary': [2, { 141 | 'defaultAssignment': false 142 | }], 143 | 'no-unreachable': 2, 144 | 'no-unsafe-finally': 2, 145 | 'no-unused-vars': [2, { 146 | 'vars': 'all', 147 | 'args': 'none' 148 | }], 149 | 'no-useless-call': 2, 150 | 'no-useless-computed-key': 2, 151 | 'no-useless-constructor': 2, 152 | 'no-useless-escape': 0, 153 | 'no-whitespace-before-property': 2, 154 | 'no-with': 2, 155 | 'one-var': [2, { 156 | 'initialized': 'never' 157 | }], 158 | 'operator-linebreak': [2, 'after', { 159 | 'overrides': { 160 | '?': 'before', 161 | ':': 'before' 162 | } 163 | }], 164 | 'padded-blocks': [2, 'never'], 165 | 'quotes': [2, 'single', { 166 | 'avoidEscape': true, 167 | 'allowTemplateLiterals': true 168 | }], 169 | 'semi': [2, 'never'], 170 | 'semi-spacing': [2, { 171 | 'before': false, 172 | 'after': true 173 | }], 174 | 'space-before-blocks': [2, 'always'], 175 | 'space-before-function-paren': [2, 'never'], 176 | 'space-in-parens': [2, 'never'], 177 | 'space-infix-ops': 2, 178 | 'space-unary-ops': [2, { 179 | 'words': true, 180 | 'nonwords': false 181 | }], 182 | 'spaced-comment': [2, 'always', { 183 | 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] 184 | }], 185 | 'template-curly-spacing': [2, 'never'], 186 | 'use-isnan': 2, 187 | 'valid-typeof': 2, 188 | 'wrap-iife': [2, 'any'], 189 | 'yield-star-spacing': [2, 'both'], 190 | 'yoda': [2, 'never'], 191 | 'prefer-const': 2, 192 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 193 | 'object-curly-spacing': [2, 'always', { 194 | objectsInObjects: false 195 | }], 196 | 'array-bracket-spacing': [2, 'never'] 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | parser: 'babel-eslint', 5 | sourceType: 'module' 6 | }, 7 | env: { 8 | browser: true, 9 | node: true, 10 | es6: true, 11 | }, 12 | extends: ['plugin:vue/recommended', 'eslint:recommended'], 13 | 14 | // add your custom rules here 15 | //it is base on https://github.com/vuejs/eslint-config-vue 16 | rules: { 17 | "vue/max-attributes-per-line": [2, { 18 | "singleline": 10, 19 | "multiline": { 20 | "max": 1, 21 | "allowFirstLine": false 22 | } 23 | }], 24 | "vue/singleline-html-element-content-newline": "off", 25 | "vue/multiline-html-element-content-newline":"off", 26 | "vue/name-property-casing": ["error", "PascalCase"], 27 | "vue/no-v-html": "off", 28 | 'accessor-pairs': 2, 29 | 'arrow-spacing': [2, { 30 | 'before': true, 31 | 'after': true 32 | }], 33 | 'block-spacing': [2, 'always'], 34 | 'brace-style': [2, '1tbs', { 35 | 'allowSingleLine': true 36 | }], 37 | 'camelcase': [0, { 38 | 'properties': 'always' 39 | }], 40 | 'comma-dangle': [2, 'never'], 41 | 'comma-spacing': [2, { 42 | 'before': false, 43 | 'after': true 44 | }], 45 | 'comma-style': [2, 'last'], 46 | 'constructor-super': 2, 47 | 'curly': [2, 'multi-line'], 48 | 'dot-location': [2, 'property'], 49 | 'eol-last': 2, 50 | 'eqeqeq': ["error", "always", {"null": "ignore"}], 51 | 'generator-star-spacing': [2, { 52 | 'before': true, 53 | 'after': true 54 | }], 55 | 'handle-callback-err': [2, '^(err|error)$'], 56 | 'indent': [2, 2, { 57 | 'SwitchCase': 1 58 | }], 59 | 'jsx-quotes': [2, 'prefer-single'], 60 | 'key-spacing': [2, { 61 | 'beforeColon': false, 62 | 'afterColon': true 63 | }], 64 | 'keyword-spacing': [2, { 65 | 'before': true, 66 | 'after': true 67 | }], 68 | 'new-cap': [2, { 69 | 'newIsCap': true, 70 | 'capIsNew': false 71 | }], 72 | 'new-parens': 2, 73 | 'no-array-constructor': 2, 74 | 'no-caller': 2, 75 | 'no-console': 'off', 76 | 'no-class-assign': 2, 77 | 'no-cond-assign': 2, 78 | 'no-const-assign': 2, 79 | 'no-control-regex': 0, 80 | 'no-delete-var': 2, 81 | 'no-dupe-args': 2, 82 | 'no-dupe-class-members': 2, 83 | 'no-dupe-keys': 2, 84 | 'no-duplicate-case': 2, 85 | 'no-empty-character-class': 2, 86 | 'no-empty-pattern': 2, 87 | 'no-eval': 2, 88 | 'no-ex-assign': 2, 89 | 'no-extend-native': 2, 90 | 'no-extra-bind': 2, 91 | 'no-extra-boolean-cast': 2, 92 | 'no-extra-parens': [2, 'functions'], 93 | 'no-fallthrough': 2, 94 | 'no-floating-decimal': 2, 95 | 'no-func-assign': 2, 96 | 'no-implied-eval': 2, 97 | 'no-inner-declarations': [2, 'functions'], 98 | 'no-invalid-regexp': 2, 99 | 'no-irregular-whitespace': 2, 100 | 'no-iterator': 2, 101 | 'no-label-var': 2, 102 | 'no-labels': [2, { 103 | 'allowLoop': false, 104 | 'allowSwitch': false 105 | }], 106 | 'no-lone-blocks': 2, 107 | 'no-mixed-spaces-and-tabs': 2, 108 | 'no-multi-spaces': 2, 109 | 'no-multi-str': 2, 110 | 'no-multiple-empty-lines': [2, { 111 | 'max': 1 112 | }], 113 | 'no-native-reassign': 2, 114 | 'no-negated-in-lhs': 2, 115 | 'no-new-object': 2, 116 | 'no-new-require': 2, 117 | 'no-new-symbol': 2, 118 | 'no-new-wrappers': 2, 119 | 'no-obj-calls': 2, 120 | 'no-octal': 2, 121 | 'no-octal-escape': 2, 122 | 'no-path-concat': 2, 123 | 'no-proto': 2, 124 | 'no-redeclare': 2, 125 | 'no-regex-spaces': 2, 126 | 'no-return-assign': [2, 'except-parens'], 127 | 'no-self-assign': 2, 128 | 'no-self-compare': 2, 129 | 'no-sequences': 2, 130 | 'no-shadow-restricted-names': 2, 131 | 'no-spaced-func': 2, 132 | 'no-sparse-arrays': 2, 133 | 'no-this-before-super': 2, 134 | 'no-throw-literal': 2, 135 | 'no-trailing-spaces': 2, 136 | 'no-undef': 2, 137 | 'no-undef-init': 2, 138 | 'no-unexpected-multiline': 2, 139 | 'no-unmodified-loop-condition': 2, 140 | 'no-unneeded-ternary': [2, { 141 | 'defaultAssignment': false 142 | }], 143 | 'no-unreachable': 2, 144 | 'no-unsafe-finally': 2, 145 | 'no-unused-vars': [2, { 146 | 'vars': 'all', 147 | 'args': 'none' 148 | }], 149 | 'no-useless-call': 2, 150 | 'no-useless-computed-key': 2, 151 | 'no-useless-constructor': 2, 152 | 'no-useless-escape': 0, 153 | 'no-whitespace-before-property': 2, 154 | 'no-with': 2, 155 | 'one-var': [2, { 156 | 'initialized': 'never' 157 | }], 158 | 'operator-linebreak': [2, 'after', { 159 | 'overrides': { 160 | '?': 'before', 161 | ':': 'before' 162 | } 163 | }], 164 | 'padded-blocks': [2, 'never'], 165 | 'quotes': [2, 'single', { 166 | 'avoidEscape': true, 167 | 'allowTemplateLiterals': true 168 | }], 169 | 'semi': [2, 'never'], 170 | 'semi-spacing': [2, { 171 | 'before': false, 172 | 'after': true 173 | }], 174 | 'space-before-blocks': [2, 'always'], 175 | 'space-before-function-paren': [2, 'never'], 176 | 'space-in-parens': [2, 'never'], 177 | 'space-infix-ops': 2, 178 | 'space-unary-ops': [2, { 179 | 'words': true, 180 | 'nonwords': false 181 | }], 182 | 'spaced-comment': [2, 'always', { 183 | 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] 184 | }], 185 | 'template-curly-spacing': [2, 'never'], 186 | 'use-isnan': 2, 187 | 'valid-typeof': 2, 188 | 'wrap-iife': [2, 'any'], 189 | 'yield-star-spacing': [2, 'both'], 190 | 'yoda': [2, 'never'], 191 | 'prefer-const': 2, 192 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 193 | 'object-curly-spacing': [2, 'always', { 194 | objectsInObjects: false 195 | }], 196 | 'array-bracket-spacing': [2, 'never'] 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /Merge_Table/components/MergeTable.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 26 | 27 | 34 | 35 | 43 | 44 | 45 | 46 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 192 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/404.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | OOPS! 12 | All rights reserved 13 | wallstreetcn 14 | 15 | {{ message }} 16 | Please check that the URL you entered is correct, or click the button below to return to the homepage. 17 | Back to home 18 | 19 | 20 | 21 | 22 | 23 | 34 | 35 | 229 | -------------------------------------------------------------------------------- /SpringBoot_Axios_Cors/demo-front/src/views/login/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 系统登录 7 | 8 | 9 | 10 | 11 | 12 | 13 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | 42 | 43 | 44 | 登 录 45 | 46 | 47 | username: any 48 | password: any 49 | 50 | 51 | 52 | 53 | 54 | 55 | 127 | 128 | 174 | 175 | 238 | -------------------------------------------------------------------------------- /Element_CheckBox/demo.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 新增 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 29 | 30 | 31 | 32 | {{ scope.row.menu.menuName }} 33 | 34 | 35 | 36 | 37 | 38 | 45 | 46 | 47 | 48 | 49 | 50 | 61 | 62 | 63 | 64 | 65 | 392 | --------------------------------------------------------------------------------