diff --git a/modules/vue/build/constant.ts b/modules/vue/build/constant.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b69b1a5ffc5726ba593b428b27060a1032a3adbb
--- /dev/null
+++ b/modules/vue/build/constant.ts
@@ -0,0 +1,6 @@
+/**
+ * The name of the configuration file entered in the production environment
+ */
+export const GLOB_CONFIG_FILE_NAME = '_app.config.js';
+
+export const OUTPUT_DIR = 'target/generated-resources/public';
diff --git a/modules/vue/java/src/main/java/com/jeesite/autoconfigure/vue/VueAutoConfiguration.java b/modules/vue/java/src/main/java/com/jeesite/autoconfigure/vue/VueAutoConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff8c8931950acd811520554731266e35e0802046
--- /dev/null
+++ b/modules/vue/java/src/main/java/com/jeesite/autoconfigure/vue/VueAutoConfiguration.java
@@ -0,0 +1,32 @@
+package com.jeesite.autoconfigure.vue;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author oliver foo
+ * @description
+ * @date 2022/4/14 17:54
+ */
+@Configuration(proxyBeanMethods = false)
+public class VueAutoConfiguration implements WebMvcConfigurer {
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/**").addResourceLocations("classpath:/public/");
+ registry.addResourceHandler("/_app.config.js").addResourceLocations("classpath:/static/");
+ registry.addResourceHandler("/favicon.png").addResourceLocations("classpath:/static/");
+ }
+
+ @Controller
+ public static class VueRedirect {
+ @RequestMapping(value = "/{path:^(?!a$)(?!f$)(?!assets$)(?!resource$)(?!static$)(?!_app.config.js$)(?!favicon.png$)[^\\.]*}/**")
+ public String redirect() {
+ return "forward:/index.html";
+ }
+ }
+
+}
diff --git a/modules/vue/java/src/main/resource/META-INF/spring.factories b/modules/vue/java/src/main/resource/META-INF/spring.factories
new file mode 100644
index 0000000000000000000000000000000000000000..727e9992a08113445f9a84335fb4432d05ef0e16
--- /dev/null
+++ b/modules/vue/java/src/main/resource/META-INF/spring.factories
@@ -0,0 +1,3 @@
+# Auto Configure
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+com.jeesite.autoconfigure.vue.VueAutoConfiguration
diff --git a/modules/vue/java/src/main/resource/static/_app.config.js b/modules/vue/java/src/main/resource/static/_app.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..f4c299aa460506f07d766c7bfdd802db52b577a5
--- /dev/null
+++ b/modules/vue/java/src/main/resource/static/_app.config.js
@@ -0,0 +1,14 @@
+window.__PRODUCTION__THINGSBOX__CONF__ = {
+ VITE_GLOB_APP_TITLE: 'Jeesite',
+ VITE_GLOB_APP_SHORT_NAME: 'Jeesite',
+ VITE_GLOB_API_URL: '',
+ VITE_GLOB_UPLOAD_URL: '/upload',
+ VITE_GLOB_WEBSOCKET_URL: '/a/ws/stomp',
+ VITE_GLOB_API_URL_PREFIX: '',
+ VITE_GLOB_ADMIN_PATH: '/a',
+};
+Object.freeze(window.__PRODUCTION__THINGSBOX__CONF__);
+Object.defineProperty(window, '__PRODUCTION__THINGSBOX__CONF__', {
+ configurable: false,
+ writable: false,
+});
diff --git a/modules/vue/package.json b/modules/vue/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..8c1e424d8f09b8eb7f99c4cbc907d1fb2b94763f
--- /dev/null
+++ b/modules/vue/package.json
@@ -0,0 +1,151 @@
+{
+ "name": "jeesite",
+ "version": "5.0.3",
+ "author": {
+ "name": "ThinkGem",
+ "email": "thinkgem@163.com",
+ "url": "https://gitee.com/thinkgem/jeesite-vue"
+ },
+ "scripts": {
+ "bootstrap": "yarn install",
+ "serve": "npm run dev",
+ "dev": "vite",
+ "build": "cross-env NODE_ENV=production vite build && esno ./build/script/postBuild.ts",
+ "build:test": "cross-env vite build --mode test && esno ./build/script/postBuild.ts",
+ "build:no-cache": "yarn clean:cache && npm run build",
+ "report": "cross-env REPORT=true npm run build",
+ "type:check": "vue-tsc --noEmit --skipLibCheck",
+ "preview": "npm run build && vite preview",
+ "preview:dist": "vite preview",
+ "log": "conventional-changelog -p angular -i CHANGELOG.md -s",
+ "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
+ "clean:lib": "rimraf node_modules",
+ "lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
+ "lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
+ "lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
+ "lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
+ "lint:pretty": "pretty-quick --staged",
+ "test:unit": "jest",
+ "test:unit-coverage": "jest --coverage",
+ "test:gzip": "http-server dist --cors --gzip -c-1",
+ "test:br": "http-server dist --cors --brotli -c-1",
+ "reinstall": "rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
+ "prepare": "husky install",
+ "gen:icon": "esno ./build/generate/icon/index.ts"
+ },
+ "dependencies": {
+ "@iconify/iconify": "^2.1.0",
+ "@vueuse/core": "^7.1.2",
+ "@vueuse/shared": "^7.1.2",
+ "@zxcvbn-ts/core": "^1.0.0",
+ "ant-design-vue": "2.2.8",
+ "axios": "^0.24.0",
+ "cropperjs": "^1.5.12",
+ "crypto-js": "^4.1.1",
+ "echarts": "^5.2.2",
+ "lodash-es": "^4.17.21",
+ "mockjs": "^1.1.0",
+ "nprogress": "^0.2.0",
+ "path-to-regexp": "^6.2.0",
+ "pinia": "2.0.4",
+ "qrcode": "^1.5.0",
+ "qs": "^6.10.1",
+ "resize-observer-polyfill": "^1.5.1",
+ "sortablejs": "^1.14.0",
+ "spark-md5": "^3.0.2",
+ "vue": "^3.2.23",
+ "vue-i18n": "^9.1.9",
+ "vue-router": "^4.0.12",
+ "vue-types": "^4.1.1"
+ },
+ "devDependencies": {
+ "@commitlint/cli": "^15.0.0",
+ "@commitlint/config-conventional": "^15.0.0",
+ "@iconify/json": "^2.0.3",
+ "@purge-icons/generated": "^0.7.0",
+ "@types/codemirror": "^5.60.5",
+ "@types/crypto-js": "^4.0.2",
+ "@types/fs-extra": "^9.0.13",
+ "@types/inquirer": "^8.1.3",
+ "@types/intro.js": "^3.0.2",
+ "@types/jest": "^27.0.3",
+ "@types/lodash-es": "^4.17.5",
+ "@types/mockjs": "^1.0.4",
+ "@types/node": "^16.11.10",
+ "@types/nprogress": "^0.2.0",
+ "@types/qrcode": "^1.4.1",
+ "@types/qs": "^6.9.7",
+ "@types/showdown": "^1.9.4",
+ "@types/sortablejs": "^1.10.7",
+ "@typescript-eslint/eslint-plugin": "^5.4.0",
+ "@typescript-eslint/parser": "^5.4.0",
+ "@vitejs/plugin-legacy": "^1.6.3",
+ "@vitejs/plugin-vue": "^1.10.1",
+ "@vitejs/plugin-vue-jsx": "^1.3.0",
+ "@vue/compiler-sfc": "3.2.23",
+ "@vue/test-utils": "^2.0.0-rc.17",
+ "autoprefixer": "^10.4.0",
+ "commitizen": "^4.2.4",
+ "conventional-changelog-cli": "^2.1.1",
+ "cross-env": "^7.0.3",
+ "dotenv": "^10.0.0",
+ "eslint": "^8.3.0",
+ "eslint-config-prettier": "^8.3.0",
+ "eslint-define-config": "^1.2.0",
+ "eslint-plugin-jest": "^25.3.0",
+ "eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-vue": "^8.1.1",
+ "esno": "^0.12.1",
+ "fs-extra": "^10.0.0",
+ "husky": "^7.0.4",
+ "inquirer": "^8.2.0",
+ "jest": "^27.4.0",
+ "less": "^4.1.2",
+ "lint-staged": "12.1.2",
+ "npm-run-all": "^4.1.5",
+ "postcss": "^8.4.4",
+ "postcss-html": "^1.3.0",
+ "postcss-less": "^5.0.0",
+ "prettier": "^2.5.0",
+ "rimraf": "^3.0.2",
+ "rollup-plugin-visualizer": "^5.5.2",
+ "stylelint": "^14.1.0",
+ "stylelint-config-html": "^1.0.0",
+ "stylelint-config-prettier": "^9.0.3",
+ "stylelint-config-recommended": "^6.0.0",
+ "stylelint-config-standard": "^24.0.0",
+ "stylelint-order": "^5.0.0",
+ "ts-jest": "^27.0.7",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.5.2",
+ "vite": "^2.7.0-beta.9",
+ "vite-plugin-compression": "^0.3.6",
+ "vite-plugin-html": "^2.1.1",
+ "vite-plugin-mock": "^2.9.6",
+ "vite-plugin-purge-icons": "^0.7.0",
+ "vite-plugin-pwa": "^0.11.8",
+ "vite-plugin-style-import": "^1.4.0",
+ "vite-plugin-svg-icons": "^1.0.5",
+ "vite-plugin-theme": "^0.8.1",
+ "vite-plugin-vue-setup-extend": "^0.1.0",
+ "vite-plugin-windicss": "^1.5.3",
+ "vue-eslint-parser": "^8.0.1",
+ "vue-tsc": "^0.29.7"
+ },
+ "resolutions": {
+ "bin-wrapper": "npm:bin-wrapper-china",
+ "rollup": "^2.56.3"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://gitee.com/thinkgem/jeesite-vue.git"
+ },
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://gitee.com/thinkgem/jeesite-vue/issues"
+ },
+ "homepage": "https://jeesite.com",
+ "engines": {
+ "node": "^12 || >=14"
+ }
+}
\ No newline at end of file
diff --git a/modules/vue/pom.xml b/modules/vue/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ec46b697ebae528973a3a9ad00797bd72470ed1b
--- /dev/null
+++ b/modules/vue/pom.xml
@@ -0,0 +1,121 @@
+
+
+ 4.0.0
+
+
+ com.jeesite
+ jeesite-parent
+ 5.0.1-SNAPSHOT
+ ../../parent/pom.xml
+
+
+ jeesite-module-vue
+
+ JeeSite Module Vue
+ http://vue.com
+
+
+ v16.13.2
+ v8.1.2
+ v1.22.17
+ UTF-8
+
+
+
+
+ com.jeesite
+ jeesite-framework
+ ${project.parent.version}
+
+
+
+
+ java/src/main/java
+
+
+ java/src/main/resources
+
+
+ ${project.build.directory}/generated-resources
+
+
+
+
+ com.github.eirslett
+ frontend-maven-plugin
+ 1.12.1
+
+ ${build.node.version}
+ ${build.yarn.version}
+
+
+
+
+
+
+
+ install node and yarn
+
+ install-node-and-yarn
+
+
+ generate-resources
+
+
+ yarn install
+
+ yarn
+
+
+ install
+
+
+
+ yarn build
+
+ yarn
+
+
+ build
+
+
+
+
+
+
+
+
+
+ oliver
+ oliver foo
+ 1069035666@qq.com
+
+ Project lead
+
+ +8
+
+
+
+
+
+ aliyun-repos
+ https://maven.aliyun.com/repository/public
+
+ true
+
+
+ false
+
+
+
+
+
+
+ aliyun-repos
+ https://maven.aliyun.com/repository/public
+
+
+
+
diff --git a/modules/vue/src/App.vue b/modules/vue/src/App.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b744e8c3ebd85c7417e9c05b8a4e2e6f9c582788
--- /dev/null
+++ b/modules/vue/src/App.vue
@@ -0,0 +1,35 @@
+
+
+
+
+ 暂无数据
+
+
+
+
+
+
+
+
diff --git a/root/pom.xml b/root/pom.xml
index 9bcc64b14fb6d0c608dc07db9baf288a2b5d2502..b9806197c299959106603768731d63491f2cee88 100644
--- a/root/pom.xml
+++ b/root/pom.xml
@@ -17,6 +17,7 @@
../common
../modules/core
../modules/cms
+ ../modules/vue
../web
../web-api
diff --git a/web-api/pom.xml b/web-api/pom.xml
index c8e6eee06f0b19ec68584e297a87678994746ca3..a57b85a8d6101d4602a73356b659f52da010e620 100644
--- a/web-api/pom.xml
+++ b/web-api/pom.xml
@@ -48,6 +48,13 @@
jeesite-module-swagger
${project.parent.version}
+
+