diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..438e12d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +.vscode/ +.idea/ +node_modules/ +dist/ +**/*.log +LICENSE +README.md diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..f456860 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,41 @@ +--- +kind: pipeline +type: docker +name: default + +steps: +- name: build + image: docker:dind + volumes: + - name: dockersock + path: /var/run/docker.sock + - name: dockerconfig + path: /root/.docker + commands: + - docker build -t harbor.picaiba.com/mes/mes-cigs-ui ./ && docker push harbor.picaiba.com/mes/mes-cigs-ui + +- name: deploy + image: harbor.picaiba.com/tools/kubectl:1.19.8 + commands: + - echo "172.27.0.20 lb.kubesphere.local" >> /etc/hosts + #- echo "52.74.223.119 github.com" >> /etc/hosts + - sleep 1 + - kubectl scale --replicas=0 deployment/mes-ui -n mes-cigs + - sleep 3 + - kubectl scale --replicas=1 deployment/mes-ui -n mes-cigs + depends_on: + - build + +volumes: +- name: dockersock + host: + path: /var/run/docker.sock +- name: dockerconfig + host: + path: /root/.docker + +trigger: + branch: + - develop + event: + - push diff --git a/.env.development b/.env.development index de583d0..55d9fb2 100644 --- a/.env.development +++ b/.env.development @@ -2,4 +2,16 @@ ENV = 'development' # base api -VUE_APP_BASE_API = '/dev-api' +# 这里修改成api服务器地址 +VUE_APP_BASE_API = '/api' + +# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, +# to control whether the babel-plugin-dynamic-import-node plugin is enabled. +# It only does one thing by converting all import() to require(). +# This configuration can significantly increase the speed of hot updates, +# when you have a large number of pages. +# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js + +VUE_CLI_BABEL_TRANSPILE_MODULES = true +VUE_APP_REPORT_DESIGN_URL = 'http://127.0.0.1:8080/ureport/designer' +VUE_APP_REPORT_VIEW_URL = 'http://127.0.0.1:8080/ureport/preview' diff --git a/.env.production b/.env.production index 80c8103..aec3a79 100644 --- a/.env.production +++ b/.env.production @@ -2,5 +2,6 @@ ENV = 'production' # base api -VUE_APP_BASE_API = '/prod-api' - +VUE_APP_BASE_API = '/api' +VUE_APP_REPORT_DESIGN_URL = '/ureport/designer' +VUE_APP_REPORT_VIEW_URL = '/ureport/preview' \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index d540802..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,4 +0,0 @@ -# These are supported funding model platforms - -patreon: panjiachen -custom: https://panjiachen.github.io/vue-element-admin-site/donate diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 1a114bc..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Bug report(报告问题) -about: Create a report to help us improve ---- - - - -## Bug report(问题描述) - -#### Steps to reproduce(问题复现步骤) - - -#### Screenshot or Gif(截图或动态图) - - -#### Link to minimal reproduction(最小可在线还原demo) - - - -#### Other relevant information(格外信息) -- Your OS: -- Node.js version: -- vue-element-admin version: diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index c33d10d..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: Feature Request(新功能建议) -about: Suggest an idea for this project ---- - -## Feature request(新功能建议) - diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index 7608354..0000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Question(提问) -about: Asking questions about use ---- - -## Question(提问) - - - -#### Steps to reproduce(问题复现步骤) - - -#### Screenshot or Gif(截图或动态图) - - -#### Link to minimal reproduction(最小可在线还原demo) - - - -#### Other relevant information(格外信息) -- Your OS: -- Node.js version: -- vue-element-admin version: diff --git a/.gitignore b/.gitignore index 78a752d..7dd5617 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ selenium-debug.log package-lock.json yarn.lock +/.env.development +/vue.config.js diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d6f19f4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM node:12 AS builder +WORKDIR /app +ADD package.json /app/ +RUN npm install \ + --registry=https://registry.npm.taobao.org \ + --disturl=https://npm.taobao.org/dist +ADD . /app +RUN npm run build:prod + +FROM busybox +LABEL maintainer thomas.hairong@gmail.com +COPY --from=builder /app/dist /html \ No newline at end of file diff --git a/QR.png b/QR.png new file mode 100644 index 0000000..cd55834 Binary files /dev/null and b/QR.png differ diff --git a/README.md b/README.md index ca7bf26..f45f259 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,50 @@ + # Readme -页面原型地址: http://rp.picaiba.com/qj/2021-9-22 + +页面原型地址: http://rp.picaiba.com/mes/2020-12-29 element 表单生成工具: https://mrhj.gitee.io/form-generator/#/ +*** + +* 顶栏右上角设置的配置在 @/layout/components/Navbar.vue 中 +* 富文本编辑器中 右上角上传图片的目标地址需要修改,在@/components/Tinymce/components/EditorImage.vue 中 + + ##### echarts封装 * 考虑使用mixin加入部分功能 * option配置分离,再复用 * 定义统一输入的数据格式(通过props?) + +##### 国际化注意事项 +* 所有methodbtn的tableBtn配置中的btnName写成下种形式,具体配置项在@/lang/i18n.js 中,若无想要的自行添加 +``` + btnName: 'btn.edit' +``` +* 所有hidden不为true的路由的mate中的title,写成下种形式,位置同上 +``` + meta: { title: routerTitle.dashboard.dashboard?.[language] || routerTitle.dashboard.dashboard.en, icon: 'dashboard', affix: true } +``` +* 所有table页引入国际化组件,表格配置项中label写成下种形式,具体配置需自行到@/lang/en.js 和@/lang/zh.js 中添加 +``` + import i18n from '@/lang' + const tableProps = [{ + ... + label: i18n.t('userManage.userId'), + ... + }] +``` + +##### 切换主题色 +* 主题样式文件应使用本地文件,不应使用element云上的(目前尝试使用本地可能因为缓存策略导致切换主题色仅第一次生效,目前仍保留使用element云上的样式文件) + +##### 备注 +* 废品报废添加时间隐藏,质量检测计划检测速率、检测内容隐藏 +test \ No newline at end of file diff --git a/babel.config.js b/babel.config.js index fb82b27..6604e8d 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,14 +1,26 @@ +/* + * @Date: 2020-12-14 09:07:03 + * @LastEditors: guo + * @LastEditTime: 2020-12-29 21:34:11 + * @FilePath: \basic-admin\babel.config.js + * @Description: 修改babel配置 + * preset-env用于适配浏览器(最新4个版本) + * transform-runtime 用于识别一些比较新的js语法 + */ module.exports = { presets: [ - // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app - '@vue/cli-plugin-babel/preset' + ['@babel/preset-env', { + 'useBuiltIns': 'usage', + 'debug': true, + 'targets': [ + 'last 4 versions' + ] + }], + '@vue/app' ], - 'env': { - 'development': { - // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). - // This plugin can significantly increase the speed of hot updates, when you have a large number of pages. - // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html - 'plugins': ['dynamic-import-node'] - } - } + plugins: [ + ['@babel/plugin-transform-runtime', { + 'corejs': 3 + }] + ] } diff --git a/default.conf b/default.conf new file mode 100644 index 0000000..52f7bbf --- /dev/null +++ b/default.conf @@ -0,0 +1,50 @@ +server { + listen 80 default_server; + listen [::]:80 default_server; + + root /usr/share/nginx/html; + index index.html index.htm; + + location / { + try_files $uri $uri/ @rewrites; + } + + location /spc/ { + proxy_pass http://58.210.206.230:8000/; + } + + location /api { + access_log off; + add_header Access-Control-Allow-Origin * always; + add_header Access-Control-Allow-Methods GET,OPTIONS,POST,GET,PUT,DELETE always; + add_header Access-Control-Allow-Headers $http_access_control_request_headers; + add_header Access-Control-Allow-Credentials true; + add_header Access-Control-Max-Age 1800; + + if ($request_method = OPTIONS){ + add_header Access-Control-Allow-Origin * always; + add_header Access-Control-Allow-Methods GET,OPTIONS,POST,GET,PUT,DELETE always; + add_header Access-Control-Allow-Headers $http_access_control_request_headers; + add_header Access-Control-Allow-Credentials true; + add_header Access-Control-Max-Age 1800; + return 204; + } + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_buffering off; + proxy_pass http://mes:9090/api; + proxy_http_version 1.1; + } + + location @rewrites { + rewrite ^(.+)$ /index.html last; + } + + location ~* \.(?:ico|css|js|gif|jpe?g|png)$ { + expires max; + add_header Pragma public; + add_header Cache-Control "public, must-revalidate, proxy-revalidate"; + } +} diff --git a/mock/article.js b/mock/article.js index 23d8ba5..50218ae 100644 --- a/mock/article.js +++ b/mock/article.js @@ -1,4 +1,4 @@ -const Mock = require('mockjs') +import Mock from 'mockjs' const List = [] const count = 100 @@ -27,7 +27,7 @@ for (let i = 0; i < count; i++) { })) } -module.exports = [ +export default [ { url: '/vue-element-admin/article/list', type: 'get', diff --git a/mock/index.js b/mock/index.js index 2eed65d..196e292 100644 --- a/mock/index.js +++ b/mock/index.js @@ -1,10 +1,10 @@ -const Mock = require('mockjs') -const { param2Obj } = require('./utils') +import Mock from 'mockjs' +import { param2Obj } from '../src/utils' -const user = require('./user') -const role = require('./role') -const article = require('./article') -const search = require('./remote-search') +import user from './user' +import role from './role' +import article from './article' +import search from './remote-search' const mocks = [ ...user, @@ -16,7 +16,7 @@ const mocks = [ // for front mock // please use it cautiously, it will redefine XMLHttpRequest, // which will cause many of your third-party libraries to be invalidated(like progress event). -function mockXHR() { +export function mockXHR() { // mock patch // https://github.com/nuysoft/Mock/issues/300 Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send @@ -54,7 +54,4 @@ function mockXHR() { } } -module.exports = { - mocks, - mockXHR -} +export default mocks diff --git a/mock/mock-server.js b/mock/mock-server.js index 8941ec0..806fdac 100644 --- a/mock/mock-server.js +++ b/mock/mock-server.js @@ -8,7 +8,7 @@ const mockDir = path.join(process.cwd(), 'mock') function registerRoutes(app) { let mockLastIndex - const { mocks } = require('./index.js') + const { default: mocks } = require('./index.js') const mocksForServer = mocks.map(route => { return responseFake(route.url, route.type, route.response) }) @@ -44,6 +44,9 @@ const responseFake = (url, type, respond) => { } module.exports = app => { + // es6 polyfill + require('@babel/register') + // parse app.body // https://expressjs.com/en/4x/api.html#req.body app.use(bodyParser.json()) diff --git a/mock/remote-search.js b/mock/remote-search.js index 8fc4926..60809cb 100644 --- a/mock/remote-search.js +++ b/mock/remote-search.js @@ -1,4 +1,4 @@ -const Mock = require('mockjs') +import Mock from 'mockjs' const NameList = [] const count = 100 @@ -10,7 +10,7 @@ for (let i = 0; i < count; i++) { } NameList.push({ name: 'mock-Pan' }) -module.exports = [ +export default [ // username search { url: '/vue-element-admin/search/user', diff --git a/mock/role/index.js b/mock/role/index.js index 4643f00..d957493 100644 --- a/mock/role/index.js +++ b/mock/role/index.js @@ -1,6 +1,6 @@ -const Mock = require('mockjs') -const { deepClone } = require('../utils') -const { asyncRoutes, constantRoutes } = require('./routes.js') +import Mock from 'mockjs' +import { deepClone } from '../../src/utils/index.js' +import { asyncRoutes, constantRoutes } from './routes.js' const routes = deepClone([...constantRoutes, ...asyncRoutes]) @@ -35,7 +35,7 @@ const roles = [ } ] -module.exports = [ +export default [ // mock get all routes form server { url: '/vue-element-admin/routes', diff --git a/mock/role/routes.js b/mock/role/routes.js index d33f162..d718919 100644 --- a/mock/role/routes.js +++ b/mock/role/routes.js @@ -1,6 +1,6 @@ // Just a mock data -const constantRoutes = [ +export const constantRoutes = [ { path: '/redirect', component: 'layout/Layout', @@ -72,7 +72,7 @@ const constantRoutes = [ } ] -const asyncRoutes = [ +export const asyncRoutes = [ { path: '/permission', component: 'layout/Layout', @@ -523,8 +523,3 @@ const asyncRoutes = [ { path: '*', redirect: '/404', hidden: true } ] - -module.exports = { - constantRoutes, - asyncRoutes -} diff --git a/mock/user.js b/mock/user.js index d82e079..859bd6f 100644 --- a/mock/user.js +++ b/mock/user.js @@ -23,7 +23,7 @@ const users = { } } -module.exports = [ +export default [ // user login { url: '/vue-element-admin/user/login', diff --git a/mock/utils.js b/mock/utils.js deleted file mode 100644 index f909a29..0000000 --- a/mock/utils.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @param {string} url - * @returns {Object} - */ -function param2Obj(url) { - const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') - if (!search) { - return {} - } - const obj = {} - const searchArr = search.split('&') - searchArr.forEach(v => { - const index = v.indexOf('=') - if (index !== -1) { - const name = v.substring(0, index) - const val = v.substring(index + 1, v.length) - obj[name] = val - } - }) - return obj -} - -/** - * This is just a simple version of deep copy - * Has a lot of edge cases bug - * If you want to use a perfect deep copy, use lodash's _.cloneDeep - * @param {Object} source - * @returns {Object} - */ -function deepClone(source) { - if (!source && typeof source !== 'object') { - throw new Error('error arguments', 'deepClone') - } - const targetObj = source.constructor === Array ? [] : {} - Object.keys(source).forEach(keys => { - if (source[keys] && typeof source[keys] === 'object') { - targetObj[keys] = deepClone(source[keys]) - } else { - targetObj[keys] = source[keys] - } - }) - return targetObj -} - -module.exports = { - param2Obj, - deepClone -} diff --git a/package.json b/package.json index 02f68e2..2f2edfc 100644 --- a/package.json +++ b/package.json @@ -1,87 +1,30 @@ { "name": "vue-element-admin", - "version": "4.4.0", + "version": "4.2.1", "description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features", "author": "Pan ", + "license": "MIT", "scripts": { "dev": "vue-cli-service serve", - "lint": "eslint --ext .js,.vue src", "build:prod": "vue-cli-service build", "build:stage": "vue-cli-service build --mode staging", "preview": "node build/index.js --preview", - "new": "plop", - "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", + "lint": "eslint --ext .js,.vue src", "test:unit": "jest --clearCache && vue-cli-service test:unit", - "test:ci": "npm run lint && npm run test:unit" + "test:ci": "npm run lint && npm run test:unit", + "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", + "new": "plop" }, - "dependencies": { - "axios": "0.18.1", - "clipboard": "2.0.4", - "codemirror": "5.45.0", - "core-js": "3.6.5", - "driver.js": "0.9.5", - "dropzone": "5.5.1", - "echarts": "4.2.1", - "element-ui": "2.13.2", - "file-saver": "2.0.1", - "fuse.js": "3.4.4", - "js-cookie": "2.2.0", - "jsonlint": "1.6.3", - "jszip": "3.2.1", - "normalize.css": "7.0.0", - "nprogress": "0.2.0", - "path-to-regexp": "2.4.0", - "screenfull": "4.2.0", - "script-loader": "0.7.2", - "sortablejs": "1.8.4", - "tui-editor": "1.3.3", - "vue": "2.6.10", - "vue-count-to": "1.0.13", - "vue-router": "3.0.2", - "vue-splitpane": "1.0.4", - "vuedraggable": "2.20.0", - "vuex": "3.1.0", - "xlsx": "0.14.1" + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } }, - "devDependencies": { - "@vue/cli-plugin-babel": "4.4.4", - "@vue/cli-plugin-eslint": "4.4.4", - "@vue/cli-plugin-unit-jest": "4.4.4", - "@vue/cli-service": "4.4.4", - "@vue/test-utils": "1.0.0-beta.29", - "autoprefixer": "9.5.1", - "babel-eslint": "10.1.0", - "babel-jest": "23.6.0", - "babel-plugin-dynamic-import-node": "2.3.3", - "chalk": "2.4.2", - "chokidar": "2.1.5", - "connect": "3.6.6", - "eslint": "6.7.2", - "eslint-plugin-vue": "6.2.2", - "html-webpack-plugin": "3.2.0", - "husky": "1.3.1", - "lint-staged": "8.1.5", - "mockjs": "1.0.1-beta3", - "plop": "2.3.0", - "runjs": "4.3.2", - "sass": "1.26.2", - "sass-loader": "8.0.2", - "script-ext-html-webpack-plugin": "2.1.3", - "serve-static": "1.13.2", - "svg-sprite-loader": "4.1.3", - "svgo": "1.2.0", - "vue-template-compiler": "2.6.10" - }, - "browserslist": [ - "> 1%", - "last 2 versions" - ], - "bugs": { - "url": "https://github.com/PanJiaChen/vue-element-admin/issues" - }, - "engines": { - "node": ">=8.9", - "npm": ">= 3.0.0" + "lint-staged": { + "src/**/*.{js,vue}": [ + "eslint --fix", + "git add" + ] }, "keywords": [ "vue", @@ -92,20 +35,94 @@ "admin-template", "management-system" ], - "license": "MIT", - "lint-staged": { - "src/**/*.{js,vue}": [ - "eslint --fix", - "git add" - ] - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, "repository": { "type": "git", "url": "git+https://github.com/PanJiaChen/vue-element-admin.git" - } + }, + "bugs": { + "url": "https://github.com/PanJiaChen/vue-element-admin/issues" + }, + "dependencies": { + "axios": "0.18.1", + "clipboard": "2.0.4", + "codemirror": "5.45.0", + "desandro-matches-selector": "^2.0.2", + "driver.js": "0.9.5", + "dropzone": "5.5.1", + "echarts": "4.2.1", + "element-ui": "2.13.0", + "ev-emitter": "^2.1.0", + "file-saver": "2.0.1", + "fizzy-ui-utils": "^3.0.0", + "fuse.js": "3.4.4", + "get-size": "^2.0.3", + "js-cookie": "2.2.0", + "jsonlint": "1.6.3", + "jszip": "3.2.1", + "lodash": "^4.17.15", + "masonry-layout": "^4.2.2", + "moment": "^2.27.0", + "normalize.css": "7.0.0", + "nprogress": "0.2.0", + "outlayer": "^2.1.1", + "path-to-regexp": "2.4.0", + "screenfull": "4.2.0", + "script-loader": "0.7.2", + "showdown": "1.9.0", + "sortablejs": "1.8.4", + "tui-editor": "1.4.10", + "viewerjs": "^1.6.1", + "vue": "2.6.10", + "vue-bus": "^1.2.1", + "vue-count-to": "1.0.13", + "vue-i18n": "^8.22.2", + "vue-perfect-scrollbar": "^0.2.1", + "vue-router": "3.0.2", + "vue-splitpane": "1.0.4", + "vuedraggable": "2.20.0", + "vuex": "3.1.0", + "xlsx": "0.14.1" + }, + "devDependencies": { + "@babel/core": "7.0.0", + "@babel/plugin-transform-runtime": "^7.12.10", + "@babel/preset-env": "^7.12.11", + "@babel/register": "7.0.0", + "@babel/runtime-corejs3": "^7.12.5", + "@vue/cli-plugin-babel": "3.5.3", + "@vue/cli-plugin-eslint": "^3.9.1", + "@vue/cli-plugin-unit-jest": "3.5.3", + "@vue/cli-service": "3.5.3", + "@vue/test-utils": "1.0.0-beta.29", + "autoprefixer": "^9.5.1", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "10.0.1", + "babel-jest": "23.6.0", + "chalk": "2.4.2", + "chokidar": "2.1.5", + "connect": "3.6.6", + "eslint": "5.15.3", + "eslint-plugin-vue": "5.2.2", + "html-webpack-plugin": "3.2.0", + "husky": "1.3.1", + "lint-staged": "8.1.5", + "mockjs": "1.0.1-beta3", + "plop": "2.3.0", + "runjs": "^4.3.2", + "sass": "^1.26.10", + "sass-loader": "^7.1.0", + "script-ext-html-webpack-plugin": "2.1.3", + "serve-static": "^1.13.2", + "svg-sprite-loader": "4.1.3", + "svgo": "1.2.0", + "vue-template-compiler": "2.6.10" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions" + ] } diff --git a/plop-templates/table/index.hbs b/plop-templates/table/index.hbs new file mode 100644 index 0000000..5851db4 --- /dev/null +++ b/plop-templates/table/index.hbs @@ -0,0 +1,89 @@ +{{#if template}} + +{{/if}} + +{{#if script}} + +{{/if}} + +{{#if style}} + +{{/if}} diff --git a/plop-templates/table/prompt.js b/plop-templates/table/prompt.js new file mode 100644 index 0000000..3408edf --- /dev/null +++ b/plop-templates/table/prompt.js @@ -0,0 +1,55 @@ +const { notEmpty } = require('../utils.js') + +module.exports = { + description: 'generate a table-view', + prompts: [{ + type: 'input', + name: 'name', + message: 'input table name please', + validate: notEmpty('name') + }, + { + type: 'checkbox', + name: 'blocks', + message: 'Blocks:', + choices: [{ + name: '