{"_id":"@chanxxxx/elpis","_rev":"5-dfdee63bc64d90e0907caf2c9a553bad","name":"@chanxxxx/elpis","dist-tags":{"latest":"1.1.1"},"versions":{"1.0.0":{"name":"@chanxxxx/elpis","version":"1.0.0","author":{"name":"chan"},"license":"ISC","_id":"@chanxxxx/elpis@1.0.0","maintainers":[{"name":"chanxxxx","email":"983286993@qq.com"}],"dist":{"shasum":"c015d5bad2d7a93ee589b7351012722524f51766","tarball":"https://registry.npmjs.org/@chanxxxx/elpis/-/elpis-1.0.0.tgz","fileCount":94,"integrity":"sha512-f/NQBuY+dwvq1REhP9UNNXZr+ZP+xpUWUTQrjtPIsxzDkDFnv/wX9svxfImL+VMBWOPXoiCkEj8zR3HzZsGW4Q==","signatures":[{"sig":"MEQCIAoMYopJBWybUZhQ+yvR8PgxJ+xjLCPkBeAk3g2VNDWVAiAsBKsMocU+BRwab4kwR1h0epDvgjbTAnNtw4mTAqOpLg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":457307},"main":"index.js","config":{"commitizen":{"path":"cz-conventional-changelog"},"validate-commit-msg":{"types":["build","chore","docs","feat","fix","perf","refactor","revert","style","test"],"extends":[],"warnOnly":false}},"gitHead":"7c24f99654d396c1f7513ce3c2ee08819021756b","scripts":{"lint":"eslint --quiet --ext js,vue .","test":"cross-env _ENV=local mocha 'test/**/*.js'","prepare":"husky","commitmsg":"validate-commit-msg"},"_npmUser":{"name":"chanxxxx","email":"983286993@qq.com"},"repository":{"url":"https://e.coding.net/g-qnky8719/elpis/elpis.git","type":"git"},"_npmVersion":"11.6.1","description":"一个基于 Vue 3 + Koa.js 的企业级全栈应用框架，支持 DSL 驱动的动态组件开发。","directories":{},"_nodeVersion":"24.11.0","dependencies":{"ajv":"^6.10.2","koa":"2.7.0","md5":"^2.2.1","vue":"^3.3.4","glob":"^7.1.4","knex":"^0.19.0","less":"^3.8.1","path":"^0.12.7","pnpm":"^10.30.3","vuex":"^4.1.0","axios":"^0.19.2","mysql":"^2.18.1","pinia":"^2.1.6","ghooks":"~1.0.3","lodash":"^4.17.21","log4js":"^6.9.1","moment":"^2.30.1","echarts":"^5.5.0","express":"^4.18.2","nodemon":"^1.19.2","webpack":"^5.88.1","consoler":"^0.2.0","cross-env":"^7.0.3","happypack":"^5.0.1","koa2-cors":"^2.0.6","css-loader":"^0.23.1","koa-router":"^7.4.0","koa-static":"^5.0.0","superagent":"^8.1.2","url-loader":"^4.1.1","vue-loader":"^17.2.2","vue-router":"^4.2.4","@babel/core":"^7.24.0","file-loader":"^6.2.0","less-loader":"^11.1.3","babel-loader":"^8.0.4","element-plus":"^2.9.3","jsonwebtoken":"^9.0.2","style-loader":"^0.14.1","koa-useragent":"2.0.0","node-schedule":"^2.1.1","thread-loader":"^4.0.4","webpack-merge":"^4.2.1","@babel/runtime":"^7.27.1","koa-bodyparser":"^4.2.1","koa-nunjucks-2":"^3.0.2","vue-json-viewer":"^3.0.4","vue-style-loader":"^4.1.2","@babel/preset-env":"^7.4.5","generate-password":"^1.7.1","vue-eslint-parser":"^10.4.0","html-webpack-plugin":"^5.5.3","clean-webpack-plugin":"^0.1.19","terser-webpack-plugin":"^5.3.6","webpack-dev-middleware":"^6.1.1","webpack-hot-middleware":"^2.25.4","@element-plus/icons-vue":"^2.3.1","mini-css-extract-plugin":"^2.9.2","css-minimizer-webpack-plugin":"^5.0.1","directory-named-webpack-plugin":"^4.0.1","@babel/plugin-transform-runtime":"^7.1.0","html-webpack-inject-attributes-plugin":"^1.0.1"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","mocha":"^6.1.4","assert":"^2.0.0","eslint":"^7.32.0","supertest":"^4.0.2","babel-eslint":"^10.0.2","eslint-plugin-vue":"^9.17.0","validate-commit-msg":"~2.14.0","eslint-plugin-import":"^2.28.1"},"_npmOperationalInternal":{"tmp":"tmp/elpis_1.0.0_1776531092807_0.8247818090544219","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@chanxxxx/elpis","version":"1.0.1","author":{"name":"chan"},"license":"ISC","_id":"@chanxxxx/elpis@1.0.1","maintainers":[{"name":"chanxxxx","email":"983286993@qq.com"}],"dist":{"shasum":"d566ac65867e4f5c88bc40939c977595d3c02621","tarball":"https://registry.npmjs.org/@chanxxxx/elpis/-/elpis-1.0.1.tgz","fileCount":97,"integrity":"sha512-7Pn0ssQ9qn1MlM6GyErqoIhzhF1G9dCpN1l0BjPlNMe2UXQLYcFwpQpyea8+3b1+uHx5/yq8j266vpG5DxQHvA==","signatures":[{"sig":"MEYCIQCFzHPzgQkA2kkV1qqohZrGl402nIWSt0qkyuWAq1vGggIhANZcSJWJnKFxz8j+1KC88TRMpHuFfPtTo303Peew4fpy","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":567584},"main":"index.js","config":{"commitizen":{"path":"cz-conventional-changelog"},"validate-commit-msg":{"types":["build","chore","docs","feat","fix","perf","refactor","revert","style","test"],"extends":[],"warnOnly":false}},"gitHead":"bb11207c73bb1b76cdffafc2df5d4e69516423c5","scripts":{"lint":"eslint --quiet --ext js,vue .","test":"cross-env _ENV=local mocha 'test/**/*.js'","prepare":"husky","commitmsg":"validate-commit-msg"},"_npmUser":{"name":"chanxxxx","email":"983286993@qq.com"},"repository":{"url":"https://e.coding.net/g-qnky8719/elpis/elpis.git","type":"git"},"_npmVersion":"11.6.1","description":"一个基于 Vue 3 + Koa.js 的企业级全栈应用框架，支持 DSL 驱动的动态组件开发。","directories":{},"_nodeVersion":"24.11.0","dependencies":{"ajv":"^6.10.2","koa":"2.7.0","md5":"^2.2.1","vue":"^3.3.4","glob":"^7.1.4","knex":"^0.19.0","less":"^3.8.1","path":"^0.12.7","pnpm":"^10.30.3","vuex":"^4.1.0","axios":"^0.19.2","mysql":"^2.18.1","pinia":"^2.1.6","ghooks":"~1.0.3","lodash":"^4.17.21","log4js":"^6.9.1","moment":"^2.30.1","mysql2":"^3.22.3","echarts":"^5.5.0","express":"^4.18.2","nodemon":"^1.19.2","webpack":"^5.88.1","consoler":"^0.2.0","cross-env":"^7.0.3","happypack":"^5.0.1","koa2-cors":"^2.0.6","css-loader":"^0.23.1","koa-router":"^7.4.0","koa-static":"^5.0.0","superagent":"^8.1.2","url-loader":"^4.1.1","vue-loader":"^17.2.2","vue-router":"^4.2.4","@babel/core":"^7.24.0","file-loader":"^6.2.0","less-loader":"^11.1.3","babel-loader":"^8.0.4","element-plus":"^2.9.3","jsonwebtoken":"^9.0.2","style-loader":"^0.14.1","koa-useragent":"2.0.0","node-schedule":"^2.1.1","thread-loader":"^4.0.4","webpack-merge":"^4.2.1","@babel/runtime":"^7.27.1","koa-bodyparser":"^4.2.1","koa-nunjucks-2":"^3.0.2","vue-json-viewer":"^3.0.4","vue-style-loader":"^4.1.2","@babel/preset-env":"^7.4.5","generate-password":"^1.7.1","vue-eslint-parser":"^10.4.0","html-webpack-plugin":"^5.5.3","clean-webpack-plugin":"^0.1.19","terser-webpack-plugin":"^5.3.6","webpack-dev-middleware":"^6.1.1","webpack-hot-middleware":"^2.25.4","@element-plus/icons-vue":"^2.3.1","mini-css-extract-plugin":"^2.9.2","css-minimizer-webpack-plugin":"^5.0.1","directory-named-webpack-plugin":"^4.0.1","@babel/plugin-transform-runtime":"^7.1.0","html-webpack-inject-attributes-plugin":"^1.0.1"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","mocha":"^6.1.4","assert":"^2.0.0","eslint":"^8.57.1","supertest":"^4.0.2","eslint-plugin-vue":"^9.17.0","validate-commit-msg":"~2.14.0","@babel/eslint-parser":"^7.29.7","eslint-plugin-import":"^2.28.1"},"_npmOperationalInternal":{"tmp":"tmp/elpis_1.0.1_1779959557906_0.9643878587805452","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@chanxxxx/elpis","version":"1.0.2","author":{"name":"chan"},"license":"ISC","_id":"@chanxxxx/elpis@1.0.2","maintainers":[{"name":"chanxxxx","email":"983286993@qq.com"}],"dist":{"shasum":"70fd7d0c4a3e7fc5b262e3445254d8c1ee695c9e","tarball":"https://registry.npmjs.org/@chanxxxx/elpis/-/elpis-1.0.2.tgz","fileCount":104,"integrity":"sha512-hBqwFVSqH2QVSHJab7T0acIyF6eeu0qdMswHGBOZE7EC9vJbIhueCBTKCSOFGEEN7cxFMSsbh7BqDd3n3R/oWw==","signatures":[{"sig":"MEUCIQCKirJLHW8aSW7FDaA+2imJjPCbn59zzS64Vv1xxLflDQIgS7NJCGS146ABJPoAkNlQMITiDizCbYtesOnMns82r+Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":671173},"main":"index.js","config":{"commitizen":{"path":"cz-conventional-changelog"},"validate-commit-msg":{"types":["build","chore","docs","feat","fix","perf","refactor","revert","style","test"],"extends":[],"warnOnly":false}},"gitHead":"cb05faa797770586d439a6faacd7a0bc1116cf3e","scripts":{"lint":"eslint --quiet --ext js,vue .","test":"cross-env _ENV=local mocha 'test/**/*.js'","prepare":"husky","commitmsg":"validate-commit-msg"},"_npmUser":{"name":"chanxxxx","email":"983286993@qq.com"},"repository":{"url":"https://e.coding.net/g-qnky8719/elpis/elpis.git","type":"git"},"_npmVersion":"11.6.1","description":"一个基于 Vue 3 + Koa.js 的企业级全栈应用框架，支持 DSL 驱动的动态组件开发。","directories":{},"_nodeVersion":"24.11.0","dependencies":{"ajv":"^6.10.2","koa":"2.7.0","md5":"^2.2.1","vue":"^3.3.4","glob":"^7.1.4","knex":"^0.19.0","less":"^3.8.1","path":"^0.12.7","pnpm":"^10.30.3","vuex":"^4.1.0","axios":"^0.19.2","mysql":"^2.18.1","pinia":"^2.1.6","ghooks":"~1.0.3","lodash":"^4.17.21","log4js":"^6.9.1","moment":"^2.30.1","mysql2":"^3.22.3","echarts":"^5.5.0","express":"^4.18.2","nodemon":"^1.19.2","webpack":"^5.88.1","consoler":"^0.2.0","cross-env":"^7.0.3","happypack":"^5.0.1","koa2-cors":"^2.0.6","css-loader":"^0.23.1","koa-router":"^7.4.0","koa-static":"^5.0.0","superagent":"^8.1.2","url-loader":"^4.1.1","vue-loader":"^17.2.2","vue-router":"^4.2.4","@babel/core":"^7.24.0","file-loader":"^6.2.0","less-loader":"^11.1.3","babel-loader":"^8.0.4","element-plus":"^2.9.3","jsonwebtoken":"^9.0.2","style-loader":"^0.14.1","koa-useragent":"2.0.0","node-schedule":"^2.1.1","thread-loader":"^4.0.4","webpack-merge":"^4.2.1","@babel/runtime":"^7.27.1","koa-bodyparser":"^4.2.1","koa-nunjucks-2":"^3.0.2","vue-json-viewer":"^3.0.4","vue-style-loader":"^4.1.2","@babel/preset-env":"^7.4.5","generate-password":"^1.7.1","vue-eslint-parser":"^10.4.0","html-webpack-plugin":"^5.5.3","clean-webpack-plugin":"^0.1.19","terser-webpack-plugin":"^5.3.6","webpack-dev-middleware":"^6.1.1","webpack-hot-middleware":"^2.25.4","@element-plus/icons-vue":"^2.3.1","mini-css-extract-plugin":"^2.9.2","css-minimizer-webpack-plugin":"^5.0.1","directory-named-webpack-plugin":"^4.0.1","@babel/plugin-transform-runtime":"^7.1.0","html-webpack-inject-attributes-plugin":"^1.0.1"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","mocha":"^6.1.4","assert":"^2.0.0","eslint":"^8.57.1","supertest":"^4.0.2","eslint-plugin-vue":"^9.17.0","validate-commit-msg":"~2.14.0","@babel/eslint-parser":"^7.29.7","eslint-plugin-import":"^2.28.1"},"_npmOperationalInternal":{"tmp":"tmp/elpis_1.0.2_1787111099483_0.02006827225158947","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@chanxxxx/elpis","version":"1.1.0","author":{"name":"chan"},"license":"ISC","_id":"@chanxxxx/elpis@1.1.0","maintainers":[{"name":"chanxxxx","email":"983286993@qq.com"}],"dist":{"shasum":"bc8031c75ab0edc87d33f76649433f3e3592db26","tarball":"https://registry.npmjs.org/@chanxxxx/elpis/-/elpis-1.1.0.tgz","fileCount":97,"integrity":"sha512-IIgllZgpj71qdBuyiBgjIRulKtHl9zgEy7rMrHdLF6LPEq2Qj5gtcgL6LfHtZy2RSdti6ywu+22LSpiNFw/1MQ==","signatures":[{"sig":"MEYCIQCRxcRJBHHurbO6rbD1N2ywh98grt/nQuZYMN2AziV4UwIhAKtlJnhyODxqggdG4urLdsnvYI0rRNM0KUGOJJc9TFtQ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":635680},"main":"index.js","config":{"commitizen":{"path":"cz-conventional-changelog"},"validate-commit-msg":{"types":["build","chore","docs","feat","fix","perf","refactor","revert","style","test"],"extends":[],"warnOnly":false}},"gitHead":"fdd8c41695c6ab2b869474fbe6bd27852fc6627a","scripts":{"lint":"eslint --quiet --ext js,vue .","test":"cross-env _ENV=local mocha 'test/**/*.js'","prepare":"husky","commitmsg":"validate-commit-msg"},"_npmUser":{"name":"chanxxxx","email":"983286993@qq.com"},"repository":{"url":"https://e.coding.net/g-qnky8719/elpis/elpis.git","type":"git"},"_npmVersion":"11.6.1","description":"一个基于 Vue 3 + Koa.js 的企业级全栈应用框架，支持 DSL 驱动的动态组件开发。","directories":{},"_nodeVersion":"24.11.0","dependencies":{"ajv":"^6.10.2","koa":"2.7.0","md5":"^2.2.1","vue":"^3.3.4","glob":"^7.1.4","knex":"^0.19.0","less":"^3.8.1","path":"^0.12.7","pnpm":"^10.30.3","vuex":"^4.1.0","axios":"^0.19.2","mysql":"^2.18.1","pinia":"^2.1.6","ghooks":"~1.0.3","lodash":"^4.17.21","log4js":"^6.9.1","moment":"^2.30.1","mysql2":"^3.22.3","echarts":"^5.5.0","express":"^4.18.2","nodemon":"^1.19.2","webpack":"^5.88.1","consoler":"^0.2.0","cross-env":"^7.0.3","happypack":"^5.0.1","koa2-cors":"^2.0.6","css-loader":"^0.23.1","koa-router":"^7.4.0","koa-static":"^5.0.0","superagent":"^8.1.2","url-loader":"^4.1.1","vue-loader":"^17.2.2","vue-router":"^4.2.4","@babel/core":"^7.24.0","file-loader":"^6.2.0","less-loader":"^11.1.3","babel-loader":"^8.0.4","element-plus":"^2.9.3","jsonwebtoken":"^9.0.2","style-loader":"^0.14.1","koa-useragent":"2.0.0","node-schedule":"^2.1.1","thread-loader":"^4.0.4","webpack-merge":"^4.2.1","@babel/runtime":"^7.27.1","koa-bodyparser":"^4.2.1","koa-nunjucks-2":"^3.0.2","vue-json-viewer":"^3.0.4","vue-style-loader":"^4.1.2","@babel/preset-env":"^7.4.5","generate-password":"^1.7.1","vue-eslint-parser":"^10.4.0","html-webpack-plugin":"^5.5.3","@babel/eslint-parser":"^7.29.7","clean-webpack-plugin":"^0.1.19","terser-webpack-plugin":"^5.3.6","webpack-dev-middleware":"^6.1.1","webpack-hot-middleware":"^2.25.4","@element-plus/icons-vue":"^2.3.1","mini-css-extract-plugin":"^2.9.2","css-minimizer-webpack-plugin":"^5.0.1","directory-named-webpack-plugin":"^4.0.1","@babel/plugin-transform-runtime":"^7.1.0","html-webpack-inject-attributes-plugin":"^1.0.1"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","mocha":"^6.1.4","assert":"^2.0.0","eslint":"^8.57.1","supertest":"^4.0.2","eslint-plugin-vue":"^9.17.0","validate-commit-msg":"~2.14.0","eslint-plugin-import":"^2.28.1"},"_npmOperationalInternal":{"tmp":"tmp/elpis_1.1.0_1788111274973_0.09911014661474904","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@chanxxxx/elpis","version":"1.1.1","description":"一个基于 Vue 3 + Koa.js 的企业级全栈应用框架，支持 DSL 驱动的动态组件开发。","main":"index.js","scripts":{"lint":"eslint --quiet --ext js,vue .","test":"cross-env _ENV=local mocha 'test/**/*.js'","prepare":"husky","commitmsg":"validate-commit-msg"},"repository":{"type":"git","url":"https://e.coding.net/g-qnky8719/elpis/elpis.git"},"author":{"name":"chan"},"license":"ISC","dependencies":{"@babel/core":"^7.24.0","@babel/plugin-transform-runtime":"^7.1.0","@babel/preset-env":"^7.4.5","@babel/runtime":"^7.27.1","@element-plus/icons-vue":"^2.3.1","@babel/eslint-parser":"^7.29.7","ajv":"^6.10.2","axios":"^0.19.2","babel-loader":"^8.0.4","clean-webpack-plugin":"^0.1.19","consoler":"^0.2.0","cross-env":"^7.0.3","css-loader":"^0.23.1","css-minimizer-webpack-plugin":"^5.0.1","directory-named-webpack-plugin":"^4.0.1","echarts":"^5.5.0","element-plus":"^2.9.3","express":"^4.18.2","file-loader":"^6.2.0","generate-password":"^1.7.1","ghooks":"~1.0.3","glob":"^7.1.4","happypack":"^5.0.1","html-webpack-inject-attributes-plugin":"^1.0.1","html-webpack-plugin":"^5.5.3","jsonwebtoken":"^9.0.2","knex":"^0.19.0","koa":"2.7.0","koa-bodyparser":"^4.2.1","koa-nunjucks-2":"^3.0.2","koa-router":"^7.4.0","koa-static":"^5.0.0","koa-useragent":"2.0.0","koa2-cors":"^2.0.6","less":"^3.8.1","less-loader":"^11.1.3","lodash":"^4.17.21","log4js":"^6.9.1","md5":"^2.2.1","mini-css-extract-plugin":"^2.9.2","moment":"^2.30.1","mysql":"^2.18.1","mysql2":"^3.22.3","node-schedule":"^2.1.1","nodemon":"^1.19.2","path":"^0.12.7","pinia":"^2.1.6","pnpm":"^10.30.3","style-loader":"^0.14.1","superagent":"^8.1.2","terser-webpack-plugin":"^5.3.6","thread-loader":"^4.0.4","url-loader":"^4.1.1","vue":"^3.3.4","vue-eslint-parser":"^10.4.0","vue-json-viewer":"^3.0.4","vue-loader":"^17.2.2","vue-router":"^4.2.4","vue-style-loader":"^4.1.2","vuex":"^4.1.0","webpack":"^5.88.1","webpack-dev-middleware":"^6.1.1","webpack-hot-middleware":"^2.25.4","webpack-merge":"^4.2.1"},"devDependencies":{"assert":"^2.0.0","eslint":"^8.57.1","eslint-plugin-import":"^2.28.1","eslint-plugin-vue":"^9.17.0","husky":"^9.1.7","mocha":"^6.1.4","supertest":"^4.0.2","validate-commit-msg":"~2.14.0"},"config":{"commitizen":{"path":"cz-conventional-changelog"},"validate-commit-msg":{"types":["build","chore","docs","feat","fix","perf","refactor","revert","style","test"],"warnOnly":false,"extends":[]}},"gitHead":"5dd898f73b8e6772d3c79aec44905b183e6ef5c1","_id":"@chanxxxx/elpis@1.1.1","_nodeVersion":"24.11.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-BHpvjnXETPfEQxasYO+G6flBslamC8XXjZVzsNqEWWhC4DL18lVM/MrGAYyDqFb2j/NO2ngm4KTaMHK/bxVnqg==","shasum":"cdc73ffa8c82f643cf985e4333d551e16ed63c22","tarball":"https://registry.npmjs.org/@chanxxxx/elpis/-/elpis-1.1.1.tgz","fileCount":97,"unpackedSize":638551,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDp0UJ5XxywshH14TF1WTF5CTd/B9QW4gGpLSo/jT3l3wIgPGMP84IhRmdj20ATgqndxzz1Dbt50rykwGs0PE+99is="}]},"_npmUser":{"name":"chanxxxx","email":"983286993@qq.com"},"directories":{},"maintainers":[{"name":"chanxxxx","email":"983286993@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elpis_1.1.1_1788112316218_0.1162002749384734"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-18T16:51:32.675Z","modified":"2026-08-30T17:51:56.536Z","1.0.0":"2026-04-18T16:51:33.005Z","1.0.1":"2026-05-28T09:12:38.126Z","1.0.2":"2026-08-19T03:44:59.640Z","1.1.0":"2026-08-30T17:34:35.161Z","1.1.1":"2026-08-30T17:51:56.383Z"},"author":{"name":"chan"},"license":"ISC","repository":{"type":"git","url":"https://e.coding.net/g-qnky8719/elpis/elpis.git"},"description":"一个基于 Vue 3 + Koa.js 的企业级全栈应用框架，支持 DSL 驱动的动态组件开发。","maintainers":[{"name":"chanxxxx","email":"983286993@qq.com"}],"readme":"# Elpis\r\n\r\n一个基于 Vue 3 + Koa.js 的企业级全栈应用框架，支持 DSL 驱动的动态组件开发。\r\n\r\n## 核心特性\r\n\r\n- **Schema 驱动开发** - 通过 JSON Schema 配置动态生成表单、表格、搜索栏等组件\r\n- **动态组件系统** - 支持 createForm、editForm、detailPanel 等动态组件\r\n- **模块化架构** - elpis-core 核心框架 + 业务层分离设计\r\n\r\n## 项目结构\r\n\r\n```\r\nelpis/\r\n├── elpis-core/          # 核心框架\r\n├── app/                 # 应用业务代码\r\n│   ├── controller/      # 控制器\r\n│   ├── service/         # 服务层\r\n│   ├── middleware/      # 中间件\r\n│   ├── router/          # 路由配置\r\n│   ├── router-schema/   # 路由 Schema 定义\r\n│   ├── pages/           # 前端页面\r\n│   ├── widgets/         # UI 组件\r\n│   └── webpack/         # 构建配置\r\n├── config/              # 环境配置\r\n├── model/               # 数据模型\r\n├── docs/                # 项目文档\r\n└── test/                # 测试文件\r\n```\r\n\r\n### model 配置\r\n\r\n```javascript\r\n  {\r\n  mode: \"dashboard\", // 模版类型，不同模版类型对应不一样的模版数据结构\r\n  name: \"\", // 名称\r\n  desc: \"\", // 描述\r\n  icon: \"\", // 图标\r\n  homePage: \"\", // 首页(项目配置)\r\n\r\n  // 头部菜单\r\n  menu: [\r\n    {\r\n      key: \"\", // 菜单唯一描述\r\n      name: \"\", // 菜单名称\r\n      menuType: \"\", // 枚举值，group /module\r\n\r\n      // 当 menuType === group 时，才可填写\r\n      subMenu: [\r\n        {\r\n          // 可递归 menuItem\r\n        },\r\n      ],\r\n\r\n      // 当 menuType === module 时,才可填写(点击之后可跳转)\r\n      moduleType: \"\", // 枚举值，iframe/custom/schema /sider\r\n\r\n      // 当 moduleType === sider 时，(侧边栏)\r\n      siderConfig: {\r\n        menu: [\r\n          {\r\n            //  可递归 menuItem(除 moduleType === sider)\r\n          },\r\n        ],\r\n      },\r\n\r\n      //   当 moduleType === iframe 时\r\n      iframeConfig: {\r\n        path: \"\", // iframe 路径\r\n      },\r\n\r\n      // 当 moduleType === custom 时\r\n      customConfig: {\r\n        path: \"\", // 自定义组件路径\r\n      },\r\n\r\n      // 当 moduleType === schema 时\r\n      schemaConfig: {\r\n        api: \"/api/user\", // 数据源api (遵循 RESTFUL 规范)\r\n        schema: {\r\n          // 板块数据结构\r\n          type: \"object\",\r\n\r\n          properties: {\r\n            key: {\r\n              ...schema, // 标准 schema 配置\r\n              label: \"\", // 字段的中文名\r\n              type: \"\", // 字段类型\r\n\r\n              // 字段在table中的相关配置\r\n              tableOption: {\r\n                ...elTableColumnConfig, // 标准 el-table-column 配置\r\n                toFixed: 0, // 保留小数点后几位（演示）\r\n                visible: true | false, // 默认为 true(false 时，表示不在表单中显示)\r\n              },\r\n\r\n              // 字段在 search-bar 中的相关配置\r\n              searchOption: {\r\n                ...elComponentConfig, // 标准 el-component-column 配置\r\n                comType: \"\", // 配置组件类型 input/select/...\r\n                default: \"\", // 默认值（例如默认搜索时间的值）\r\n\r\n                // 当 comType === select 时\r\n                enumList: [],\r\n\r\n                // 当 comType === dynamicSelect 时\r\n                api: \"\",\r\n              },\r\n              formOption: {},\r\n\r\n              // 字段在不同动态 component 中的相关配置，前缀对应 componentConfig 中的键值\r\n              // 如：componentConfig.createForm ，这里对应 createFormOption\r\n              // 字段在 createForm 中相关配置\r\n              createFormOption: {\r\n                ...elComponentConfig, // 标准 el-component-column 配置\r\n                comType: \"\", // 配置控件类型 input/select/...\r\n                visible: true, // 默认为 true(false 时，表示不在表单中显示)\r\n                disabled: false, // 是否禁用 （true/false）默认为 false\r\n                default: \"\", // 默认值\r\n\r\n                // 当 comType === select 时 生效\r\n                enumList: [], // 枚举列表\r\n              },\r\n\r\n              // 字段在 editForm 中的相关配置\r\n              editFormOption: {\r\n                ...elComponentConfig, // 标准 el-component-column 配置\r\n                comType: \"\", // 配置控件类型 input/select/...\r\n                visible: true, // 默认为 true(false 时，表示不在表单中显示)\r\n                disabled: false, // 是否禁用 （true/false）默认为 false\r\n                default: \"\", // 默认值\r\n\r\n                // 当 comType === select 时 生效\r\n                enumList: [], // 枚举列表\r\n              },\r\n              detailPanelOption: {\r\n                visible: true, // 默认为 true(false 时，表示不在表单中显示)\r\n                ...eleComponentConfig, // 标准 el-component-column 配置\r\n              },\r\n            },\r\n          }, // 字段属性，可递归\r\n\r\n          // 必填字段\r\n          required: [], // 标记那些字段是必填字段\r\n        },\r\n\r\n        // 表格配置\r\n        tableConfig: {\r\n          headerButtons: [\r\n            {\r\n              label: \"\", // 按钮中文名\r\n              eventKey: \"\", // 按钮事件名\r\n\r\n              // 按钮事件具体配置 例如：调起不同的动态组件等\r\n              eventOption: {\r\n                // 当 eventKey === 'showComponent' 时生效\r\n                comName: \"\", // 组件名称\r\n              },\r\n\r\n              ...elButtonConfig, // 标准 el-button 配置\r\n            },\r\n          ],\r\n          rowButtons: [\r\n            {\r\n              label: \"\", // 按钮中文名\r\n              eventKey: \"\", // 按钮事件名\r\n              eventOption: {\r\n                // 当 eventKey === 'showComponent' 时生效\r\n                comName: \"\", // 组件名称\r\n\r\n                // 当 eventKey === remove 时（举例）\r\n                params: {\r\n                  // paramKey = 参数的键值 （e.g. ueserId:rowValueKey)\r\n                  // rowValueKey = 参数值 （当格式为 schema::tableKey 的时候，到 table 中找到相应的字段）这里的动态的值\r\n                  // 例子：user_id: schema::user_id\r\n                  paramKey: rowValueKey,\r\n                },\r\n              }, // 按钮事件具体配置\r\n              ...elButtonConfig, // 标准 el-button 配置\r\n            },\r\n          ],\r\n        },\r\n\r\n        // search-bar搜索配置\r\n        searchConfig: {},\r\n\r\n        // 动态组件 相关配置\r\n        componentConfig: {\r\n          //  create-form 表单相关配置\r\n          createForm: {\r\n            title: \"\", // 表单标题\r\n            saveBtnText: \"\", // 保存按钮文字\r\n          },\r\n\r\n          // edit-form 表单相关配置\r\n          editForm: {\r\n            title: \"\", // 表单标题\r\n            saveBtnText: \"\", // 保存按钮文字\r\n            mainKey: \"\", // 表单主键, 用于唯一标识要修改的数据对象\r\n          },\r\n\r\n          // detail-panel 相关配置\r\n          detailPanel: {\r\n            mainKey: \"\",\r\n            title: \"\", // 表单标题\r\n          },\r\n\r\n          // ...支持用户动态拓展\r\n        },\r\n      },\r\n    },\r\n  ],\r\n}\r\n```\r\n\r\n### 服务端启动\r\n\r\n```\r\nconst {serverStart} = require(@chanxxxx/elpis);\r\n\r\n// 启动 elpis服务\r\nconst app = serverStart({})\r\n```\r\n\r\n### 自定义服务端\r\n\r\n- router-schema\r\n- router\r\n- controller\r\n- service\r\n- extend\r\n- config\r\n\r\n### 前端构建\r\n\r\n```javascript\r\nconst {frontendBuild} = require(@chanxxxx/elpis);\r\n\r\n// 编译构架按前端工程\r\nfrontendBuild(process.env._ENV)\r\n\r\n```\r\n\r\n### 自定义页面扩展\r\n\r\n- 在 `app/pages/` 目录下写入口 entry.xxx.js\r\n\r\n### dashboard / custom-view 自定义页面扩展\r\n\r\n- 在 `app/pages/dashboard/xxx` 下写页面\r\n\r\n### dashboard 头部扩展点（$businessHeaderView）\r\n\r\n在业务项目创建 `app/pages/dashboard/complex-view/header-view/header-view.vue` 即可整体覆盖\r\ndashboard 头部；**不创建该文件时自动使用框架原版 header-view**（区别于其他扩展点的 blank.js\r\n兜底，header 是必备区域不会缺失）。\r\n\r\n自定义 header-view 应基于框架版的插槽契约实现：`name-menu` / `setting-content` /\r\n`name-content` 插槽与 `menu-select` 事件，可直接复制框架版文件后修改。\r\n\r\n### header-container 用户区域扩展\r\n\r\ndashboard 顶栏的用户区域（头像 + 下拉菜单）支持以下扩展方式，均向后兼容：\r\n\r\n```html\r\n<header-container\r\n  :title=\"projName\"\r\n  :user-menus=\"userMenus\"\r\n  @user-command=\"onUserCommand\"\r\n>\r\n  <!-- 可选：整体替换内置用户区域 -->\r\n  <template #user-content>\r\n    <!-- 自定义头像、菜单等 -->\r\n  </template>\r\n</header-container>\r\n```\r\n\r\n```javascript\r\n// 自定义下拉菜单项；command === \"logout\" 保留框架内置行为\r\n// （先调 POST /api/auth/logout 吊销后端会话，再清 cookie 跳转首页）\r\nconst userMenus = [\r\n  { command: \"changePassword\", label: \"修改密码\" },\r\n  { command: \"logout\", label: \"退出登录\" },\r\n];\r\n\r\n// 所有菜单命令向上透传，自定义项在此处理\r\nconst onUserCommand = (command) => { /* ... */ };\r\n```\r\n\r\n- `userName` prop：传入时优先展示；不传时自动从 `userInfo` cookie 解析 `username`\r\n  （cookie 值为 `encodeURIComponent(JSON.stringify({ user_id, username, ... }))`），\r\n  解析失败回退 `admin`\r\n- `userMenus` prop：`[{ command, label }]`，不传时仅渲染「退出登录」\r\n- `user-command` 事件：所有菜单命令向上透传（header-view → dashboard.vue 全链路可用）\r\n- `#user-content` 插槽：提供时整体替换内置用户区域\r\n\r\n### dashboard / schema-view / components 动态子组件扩展\r\n\r\n1. 在 `app/pages/dashboard/complex-view/schema-view/components/` 下写组件\r\n2. 配置到 `app/pages/dashboard/complex-view/schema-view/components/component-config.js`\r\n\r\n### schema-form 控件扩展\r\n\r\n1. 在 `app/pages/widgets/schema-form/complex-view` 下写控件\r\n2. 配置到 `app/pages/widgets/schema-form/form-item-config.js`\r\n\r\n### schema-search-bar 控件扩展\r\n\r\n1. 在 `app/pages/widgets/schema-search-bar/complex-view` 下写控件\r\n2. 配置到 `app/pages/widgets/schema-search-bar/search-item-config.js`\r\n\r\n## 更新日志\r\n\r\n完整日志见 [CHANGELOG.md](./CHANGELOG.md)。\r\n\r\n### 1.1.1（2026-08-31）\r\n\r\n- README 补充 dashboard 头部扩展点（$businessHeaderView）与用户区域扩展的使用说明\r\n\r\n### 1.1.0（2026-08-31）\r\n\r\n- **新增** `$businessHeaderView` 扩展点：业务项目可整体覆盖 dashboard 头部，业务文件缺失时回退框架原版\r\n- **新增** header-container 用户区域扩展能力：`userName` / `userMenus` props、`user-command` 事件、`#user-content` 插槽；用户名从 `userInfo` cookie 自动解析\r\n- **修复** 退出登录：先调用 `POST /api/auth/logout` 吊销后端 refreshToken 会话（携带签名头、失败不阻塞），再清 cookie 跳转首页\r\n","readmeFilename":"README.md"}