diff --git a/epmet-oper-web/.env.development b/epmet-oper-web/.env.development index aa72728..9a0e690 100644 --- a/epmet-oper-web/.env.development +++ b/epmet-oper-web/.env.development @@ -1,2 +1,3 @@ NODE_ENV=development +VUE_APP_API_SERVER = http://192.168.1.130:8080/api VUE_APP_NODE_ENV=dev \ No newline at end of file diff --git a/epmet-oper-web/.eslintignore b/epmet-oper-web/.eslintignore index 7b93168..89317ca 100644 --- a/epmet-oper-web/.eslintignore +++ b/epmet-oper-web/.eslintignore @@ -1 +1,3 @@ /src/icons/iconfont.js +/*.js +/*.vue \ No newline at end of file diff --git a/epmet-oper-web/.vscode/settings.json b/epmet-oper-web/.vscode/settings.json index fbbfd4c..ad2327f 100644 --- a/epmet-oper-web/.vscode/settings.json +++ b/epmet-oper-web/.vscode/settings.json @@ -8,18 +8,14 @@ // 重新设定tabsize "editor.tabSize": 2, // #每次保存的时候自动格式化 - "editor.formatOnSave": false, + "editor.formatOnSave": true, // #每次保存的时候将代码按eslint格式进行修复 "eslint.autoFixOnSave": true, // 添加 vue 支持 - "eslint.validate": [ - "javascript", - "javascriptreact", - { - "language": "vue", - "autoFix": true - } - ], + "eslint.validate": [], + "semi": true, //在代码尾部添加分号 + "singleQuote": true, //把双引号换成单引号 + "trailingComma": "es5", //在代码尾部添加逗号 // #去掉代码结尾的分号 "prettier.semi": false, // #使用带引号替代双引号 diff --git a/epmet-oper-web/epmet-oper.rar b/epmet-oper-web/epmet-oper.rar new file mode 100644 index 0000000..493dfe4 Binary files /dev/null and b/epmet-oper-web/epmet-oper.rar differ diff --git a/epmet-oper-web/gulpfile.js b/epmet-oper-web/gulpfile.js index 3384e7d..c13f6de 100644 --- a/epmet-oper-web/gulpfile.js +++ b/epmet-oper-web/gulpfile.js @@ -1,62 +1,72 @@ -var gulp = require('gulp') -var $ = require('gulp-load-plugins')() -var fs = require('fs') -var path = require('path') -var del = require('del') -//var colors = require('colors') +var gulp = require('gulp') +var $ = require('gulp-load-plugins')() +var fs = require('fs') +var path = require('path') +var del = require('del') +// var colors = require('colors') var child_process = require('child_process') -var theme = {} -var themeList = require('./src/element-ui/config.js').filter(item => !item.hasBuild) -var styleFileDir = './src/assets/scss' +var theme = {} +var themeList = require('./src/element-ui/config.js').filter( + (item) => !item.hasBuild +) +var styleFileDir = './src/assets/scss' var styleFileDirTemp = `${styleFileDir}-temp` -var themeFileDir = './public/element-theme' -var et = require('element-theme') -var etOptions = require('./package.json')['element-theme'] -var themeFileName = etOptions.config.replace(/.*\/(.+\.scss)/, '$1') - +var themeFileDir = './public/element-theme' +var et = require('element-theme') +var etOptions = require('./package.json')['element-theme'] +var themeFileName = etOptions.config.replace(/.*\/(.+\.scss)/, '$1') /** * 构建生成主题 */ gulp.task('themes', () => { - //console.log(colors.green('-------------------- 构建中,主题============= -------------------------')) - if (themeList.length <= 0) { return del(styleFileDirTemp) } + // console.log(colors.green('-------------------- 构建中,主题============= -------------------------')) + if (themeList.length <= 0) { + return del(styleFileDirTemp) + } // 删除临时文件,保证本次操作正常执行 - //del(styleFileDirTemp) + // del(styleFileDirTemp) // 拷贝一份scss样式文件夹,作为构建的临时处理文件夹 - //child_process.spawnSync('cp', ['-r', styleFileDir, styleFileDirTemp]) + // child_process.spawnSync('cp', ['-r', styleFileDir, styleFileDirTemp]) // 拷贝element组件scss变量样式文件至临时处理文件夹中,并修改相应配置信息 - //child_process.spawnSync('cp', ['-r', etOptions.config, styleFileDirTemp]) + // child_process.spawnSync('cp', ['-r', etOptions.config, styleFileDirTemp]) etOptions.config = `${styleFileDirTemp}/${themeFileName}` // 开始构建生成 fnCreate(themeList) - function fnCreate (themeList) { + function fnCreate(themeList) { if (themeList.length >= 1) { // 保存当前构建生成的主题对象 theme = themeList[0] console.log('\n') - //console.log(colors.green('-------------------- 待构建,主题 -------------------------')) + // console.log(colors.green('-------------------- 待构建,主题 -------------------------')) console.log(themeList) console.log('\n') - //console.log(colors.green('-------------------- 构建中,主题 -------------------------')) + // console.log(colors.green('-------------------- 构建中,主题 -------------------------')) console.log(theme) console.log('\n') // 修改.scss临时文件中的$--color-primary主题变量值 var data = fs.readFileSync(etOptions.config, 'utf8') - var result = data.replace(/\$--color-primary:(.*) !default;/, `$--color-primary:${theme.color} !default;`) + var result = data.replace( + /\$--color-primary:(.*) !default;/, + `$--color-primary:${theme.color} !default;` + ) fs.writeFileSync(path.resolve(etOptions.config), result) // 修改aui.scss临时文件中引入element组件主题变量文件路径 var data = fs.readFileSync(`${styleFileDirTemp}/aui.scss`, 'utf8') - var result = data.replace(new RegExp(`(@import \")(.*\/)(${themeFileName}\";)`), '$1./$3') + var result = data.replace( + // eslint-disable-next-line no-useless-escape + new RegExp(`(@import \")(.*\/)(${themeFileName}\";)`), + '$1./$3' + ) fs.writeFileSync(path.resolve(`${styleFileDirTemp}/aui.scss`), result) // 调用element-theme插件,生成element组件主题 @@ -73,7 +83,7 @@ gulp.task('themes', () => { // 删除临时文件 del(styleFileDirTemp) console.log('\n') - //console.log(colors.green('-------------------- 构建完毕,删除临时文件 -------------------------')) + // console.log(colors.green('-------------------- 构建完毕,删除临时文件 -------------------------')) console.log(styleFileDirTemp) console.log('\n') @@ -82,10 +92,10 @@ gulp.task('themes', () => { `${themeFileDir}/**/*.css`, `!${themeFileDir}/**/index.css`, `!${themeFileDir}/**/aui.css`, - `!${themeFileDir}/**/fonts` + `!${themeFileDir}/**/fonts`, ] del(files) - //console.log(colors.green('-------------------- 构建完毕,删除主题独立组件文件 -------------------------')) + // console.log(colors.green('-------------------- 构建完毕,删除主题独立组件文件 -------------------------')) console.log(files) console.log('\n') } @@ -93,12 +103,15 @@ gulp.task('themes', () => { }) gulp.task('styles', () => { - return gulp.src([`${styleFileDirTemp}/aui.scss`]) + return gulp + .src([`${styleFileDirTemp}/aui.scss`]) .pipe($.sass().on('error', $.sass.logError)) - .pipe($.autoprefixer({ - browsers: etOptions.browsers, - cascade: false - })) + .pipe( + $.autoprefixer({ + browsers: etOptions.browsers, + cascade: false, + }) + ) .pipe($.cleanCss()) .pipe($.rename('aui.css')) .pipe(gulp.dest(`${themeFileDir}/${theme.name}`)) diff --git a/epmet-oper-web/src/js/ajax.js b/epmet-oper-web/src/js/ajax.js new file mode 100644 index 0000000..5c20658 --- /dev/null +++ b/epmet-oper-web/src/js/ajax.js @@ -0,0 +1,585 @@ +/* eslint-disable */ +import axios from 'axios' +import Cookies from 'js-cookie' +import router from '@/router' +import qs from 'qs' +import { clearLoginInfo } from '@/utils' +import isPlainObject from 'lodash/isPlainObject' + +import Vue from 'vue' + +import { Loading } from 'element-ui' //引入Loading服务 + + + +// 默认超时时间60s +axios.defaults.timeout = 60000 + +let timer +let loading +//请求时间超过300ms 提示加载 +function startLoading () { + if (timer) return + + timer = setTimeout(() => { + loading = Loading.service({ + lock: true, //是否锁定 + text: '正在加载……', //加载中需要显示的文字 + background: 'rgba(0,0,0,.7)', //背景颜色 + }) + }, 300) +} + +//结束加载动画 +function endLoading () { + if (timer) { + clearTimeout(timer) + } + if (loading) { + loading.close() + } +} + +/** + * 请求拦截 + */ +axios.interceptors.request.use( + (config) => { + config.headers['Accept-Language'] = Cookies.get('language') || 'zh-CN' + config.headers['token'] = Cookies.get('token') || '' + config.headers['Authorization'] = Cookies.get('token') || '' + // 默认参数 + var defaults = {} + // 防止缓存,GET请求默认带_t参数 + if (config.method === 'get') { + config.params = { + ...config.params, + ...{ _t: new Date().getTime() }, + } + } + if (isPlainObject(config.params)) { + config.params = { + ...defaults, + ...config.params, + } + } + if (isPlainObject(config.data)) { + config.data = { + ...defaults, + ...config.data, + } + if ( + /^application\/x-www-form-urlencoded/.test( + config.headers['content-type'] + ) + ) { + config.data = qs.stringify(config.data) + } + } + return config + }, + (error) => { + return Promise.reject(error) + } +) + +/** + * 响应拦截 + */ +axios.interceptors.response.use( + (response) => { + if (response.data.code === 401 || response.data.code === 10001) { + clearLoginInfo() + router.replace({ name: 'login' }) + return Promise.reject(response.data.msg) + } + return response + }, + (error) => { + console.error(error) + return Promise.reject(error) + } +) + +/* + * 1、后台请求成功均返回(业务上的异常也属于请求成功) res.status=200的响应码 + * 2、res.data:后台自定义的响应体,包括: + * 1)res.data.sysresultcode:请求结果,success业务成功,fail业务失败 + * 2)res.data.rspMsg:返回消息,用于进行消息提示 + * 3)res.data.data:返回数据,用于获取请求的数据 + * 3、异步请求,以cb_su(data.data, data.rspMsg),返回业务层 + */ +export default { + // 并发请求 + all (gets, cb) { + if (gets && gets.length > 0) { + let functions = gets.map((get) => { + return axios.get(processUrl(get.url), { + params: get.params, + }) + }) + axios.all(functions).then( + axios.spread((..._results) => { + let results = _results.map((_result) => { + return _result.data.data + }) + cb(results) + }) + ) + } + }, + get (url, params, cb_su, cb_err, headers) { + var p = { + params: params, + } + if (headers && JSON.stringify(headers) != '{}') { + var h = { + headers: headers, + } + p = { + ...p, + ...h, + } + } + url = url + '?r=' + new Date().getTime() //时间戳作为随机码,防止IE从缓存获取数据 + axios + .get(processUrl(url), p) + .then((res) => { + if (res) { + if (res.status === 200) { + var data = res.data + if (data.sysresultcode === 'success') { + //业务成功 + if (typeof cb_su === 'function') { + cb_su(data.data, data.rspMsg) + } + } else if (data.sysresultcode === 'fail') { + //业务失败 + if (typeof cb_err === 'function') cb_err(data.rspMsg, data.data) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + }) + .catch((err) => { + if (typeof (cb_err === 'function')) { + cb_err(err) + } + }) + }, + put (url, data, cb_su, cb_err) { + axios + .put(processUrl(url), data) + .then((res) => { + if (res) { + if (res.status === 200) { + var data = res.data + if (data.sysresultcode === 'success') { + //业务成功 + if (typeof cb_su === 'function') { + cb_su(data.data, data.rspMsg) + } + } else if (data.sysresultcode === 'fail') { + //业务失败 + if (typeof cb_err === 'function') cb_err(data.rspMsg, data.data) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + }) + .catch((err) => { + if (typeof cb_err === 'function') { + cb_err(err) + } + }) + }, + post (url, data, cb_su, cb_err, headers) { + var h = {} + if (headers && JSON.stringify(headers) != '{}') { + h = { + headers, + } + } + //var data = qs.stringify(paramas); + axios + .post(processUrl(url), data, h) + .then((res) => { + + if (res) { + if (res.status === 200) { + + var data = res.data + if (data.code == 0) { + //业务成功 + if (typeof cb_su === 'function') { + cb_su(data.data, data.msg) + } + } else { + //业务失败 + if (typeof cb_err === 'function') cb_err(data.msg, data.data) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + }) + .catch((err) => { + if (typeof cb_err === 'function') { + cb_err(err) + } + }) + }, + post2 (url, data, cb_su, cb_err) { + //var data = qs.stringify(paramas); + axios + .post(processUrl(url), data) + .then((res) => { + if (res) { + if (res.status === 200) { + var data = res.data + if (data.sysresultcode === 'success') { + //业务成功 + if (typeof cb_su === 'function') { + cb_su(data.data, data.rspMsg) + } + } else if (data.sysresultcode === 'fail') { + //业务失败 + if (typeof cb_err === 'function') cb_err(data.rspMsg, data.data) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + }) + .catch((err) => { + if (typeof cb_err === 'function') { + cb_err(err) + } + }) + }, + delete (url, params, cb_su, cb_err) { + axios + .delete(processUrl(url), { + params: params, + }) + .then((res) => { + if (res) { + if (res.status === 200) { + var data = res.data + if (data.sysresultcode === 'success') { + //业务成功 + if (typeof cb_su === 'function') { + cb_su(data.data, data.rspMsg) + } + } else if (data.sysresultcode === 'fail') { + //业务失败 + if (typeof cb_err === 'function') cb_err(data.rspMsg, data.data) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + }) + .catch((err) => { + if (typeof cb_err === 'function') { + cb_err(err) + } + }) + }, + + //导出文件,包括excel,word等 + exportFile (url, params, cb_su, cb_err, headers) { + var h = {} + if (headers && JSON.stringify(headers) != '{}') { + h = headers + } + var errorMsg = '操作失败' + url = url + '?r=' + new Date().getTime() //时间戳作为随机码,防止IE从缓存获取数据 + axios({ + method: 'get', + url: processUrl(url), + params: params, + headers: h, //{ tenantCode: "GDYXB" }, + responseType: 'blob', + }) + .then((res) => { + if (res) { + if (res.status === 200) { + var data = res.data //直接返回blob + + if (data) { + //业务成功 + if (typeof cb_su === 'function') { + cb_su(data, '操作成功') + } + } else { + //业务失败 + if (typeof cb_err === 'function') cb_err(errorMsg) + } + } else { + if (typeof cb_err === 'function') cb_err(errorMsg) + } + } else { + if (typeof cb_err === 'function') cb_err(errorMsg) + } + }) + .catch((err) => { + if (typeof (cb_err === 'function')) { + cb_err(errorMsg) + } + }) + }, + + //导出文件,包括excel,word等 + exportFilePost (url, params, cb_su, cb_err) { + //var data = qs.stringify(paramas); + // axios + // .post(processUrl(url), data) + axios({ + method: 'post', + url: processUrl(url), + data: params, + responseType: 'blob', + }) + .then((res) => { + if (res) { + if (res.status === 200) { + var data = res.data //直接返回blob + + if (data) { + //业务成功 + if (typeof cb_su === 'function') { + cb_su(data, '操作成功') + } + } else { + //业务失败 + if (typeof cb_err === 'function') cb_err(errorMsg) + } + } else { + if (typeof cb_err === 'function') cb_err(errorMsg) + } + } else { + if (typeof cb_err === 'function') cb_err(errorMsg) + } + }) + .catch((err) => { + if (typeof cb_err === 'function') { + cb_err(err) + } + }) + }, + + //上传文件 + importFilePut (url, fileFormData, cb_su, cb_err) { + var errorMsg = '操作失败' + let requestConfig = { + headers: { + 'Content-Type': 'multipart/form-data', + // Authorization: auth.loadTokenType() + ' ' + auth.loadAccessToken(), + }, + } + Vue.http + .put(processUrl(url), fileFormData, requestConfig) + .then((res) => { + if (res && res.status === 200) { + var data = res.body //直接返回blob + + if (data.sysresultcode === 'fail') { + //业务失败 + if (typeof cb_err === 'function') cb_err(data.rspMsg) + } else if (data.sysresultcode === 'success') { + //业务成功 + if (typeof cb_su === 'function') { + cb_su(data, '操作成功') + } + } else { + if (typeof cb_err === 'function') cb_err(errorMsg) + } + } else { + if (typeof cb_err === 'function') cb_err(errorMsg) + } + }) + .catch((err) => { + if (typeof (cb_err === 'function')) { + cb_err(errorMsg) + } + }) + }, + + //上传文件 + importFilePost (url, fileFormData, cb_su, cb_err) { + var errorMsg = '操作失败' + let requestConfig = { + headers: { + 'Content-Type': 'multipart/form-data', + Authorization: auth.loadTokenType() + ' ' + auth.loadAccessToken(), + }, + } + + Vue.http + .post(processUrl(url), fileFormData, requestConfig) + .then((res) => { + if (res && res.status === 200) { + var data = res.body //直接返回blob + + if (data.sysresultcode === 'fail') { + //业务失败 + if (typeof cb_err === 'function') cb_err(data.rspMsg) + } else if (data.sysresultcode === 'success') { + //业务成功 + if (typeof cb_su === 'function') { + cb_su(data, '操作成功') + } + } else { + if (typeof cb_err === 'function') cb_err(errorMsg) + } + } else { + if (typeof cb_err === 'function') cb_err(errorMsg) + } + }) + .catch((err) => { + if (typeof (cb_err === 'function')) { + cb_err(errorMsg) + } + }) + }, + + //登录获取token/刷新token + tokenPost (url, paramas, cb_su, cb_err) { + var data = qs.stringify(paramas) + axios + .post(processUrl(url), data) + .then((res) => { + if (res) { + if (res.status === 200) { + var data = res.data + if (data) { + if (typeof cb_su === 'function') { + cb_su(data) + } + } else { + if (typeof cb_err === 'function') cb_err('登录验证失败') + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + } else { + if (typeof cb_err === 'function') cb_err(res) + } + }) + .catch((err) => { + var rspMsg = '登录失败,请重试!' + if ( + err && + err.response && + err.response.status === 401 && + err.response.data && + err.response.data.error === 'unauthorized' + ) { + // 用户名不存在时: 状态码401 + // Response Body: + // { + // "error": "unauthorized", + // "error_description": null + // } + rspMsg = err.response.data.error_description || '用户名不存在' + } else if ( + err && + err.response && + err.response.status === 400 && + err.response.data && + err.response.data.error === 'invalid_grant' + ) { + // 用户名存在,密码错误时:状态码400 + // { + // "error": "invalid_grant", + // "error_description": "Bad credentials" + // } + rspMsg = '用户名或密码输入错误' + } + if (typeof cb_err === 'function') { + cb_err(rspMsg) + } + }) + }, + + //通过接口传递的token进行验证登录 lyx 20191210 + async interfacetokenPost (url, paramas, cb_su, cb_err) { + var data = qs.stringify(paramas) + await axios + .post(processUrl(url), data) + .then((res) => { + if (res) { + if (res.status === 200) { + var data = res.data + if (data) { + if (typeof cb_su === 'function') { + cb_su(data) + return true + } + } else { + if (typeof cb_err === 'function') { + cb_err('接口验证失败') + return false + } + } + } else { + if (typeof cb_err === 'function') { + cb_err(res) + return false + } + } + } else { + if (typeof cb_err === 'function') { + cb_err(res) + return false + } + } + }) + .catch((err) => { + var rspMsg = '接口验证失败,请重试!' + if ( + err && + err.response && + err.response.status === 401 && + err.response.data && + err.response.data.error === 'unauthorized' + ) { + rspMsg = '用户名不存在' + } else if ( + err && + err.response && + err.response.status === 400 && + err.response.data && + err.response.data.error === 'invalid_grant' + ) { + rspMsg = '用户名或密码输入错误' + } + if (typeof cb_err === 'function') { + cb_err(rspMsg) + return false + } + }) + }, +} + +// 添加服务器端URL +function processUrl (url) { + + if (url.indexOf('http://') > -1) { + return url + } + return process.env.VUE_APP_API_SERVER + url +} diff --git a/epmet-oper-web/src/main.js b/epmet-oper-web/src/main.js index 0586576..94bc83b 100644 --- a/epmet-oper-web/src/main.js +++ b/epmet-oper-web/src/main.js @@ -19,6 +19,14 @@ import renRegionTree from '@/components/ren-region-tree' import { hasPermission, getDictLabel } from '@/utils' import cloneDeep from 'lodash/cloneDeep' +// axios封装 +import ajax from '@/js/ajax' + +window.app = Object.assign({}, { + ajax + +}) + Vue.config.productionTip = false Vue.use(renRadioGroup) @@ -47,5 +55,5 @@ new Vue({ i18n, router, store, - render: h => h(App) + render: (h) => h(App) }).$mount('#app') diff --git a/epmet-oper-web/src/views/modules/customer-manage/customer-info.vue b/epmet-oper-web/src/views/modules/customer-manage/customer-info.vue index c1cd3c7..4d2d72f 100644 --- a/epmet-oper-web/src/views/modules/customer-manage/customer-info.vue +++ b/epmet-oper-web/src/views/modules/customer-manage/customer-info.vue @@ -1,29 +1,41 @@ @@ -31,7 +43,7 @@ export default { props: { dataList: { - type: [ Object, Array ], + type: [Object, Array], default: function () { return { customerInfoDTO: {}, diff --git a/epmet-oper-web/src/views/modules/customer-manage/customer-manage.vue b/epmet-oper-web/src/views/modules/customer-manage/customer-manage.vue index aff0ca8..4a6e6c4 100644 --- a/epmet-oper-web/src/views/modules/customer-manage/customer-manage.vue +++ b/epmet-oper-web/src/views/modules/customer-manage/customer-manage.vue @@ -1,227 +1,218 @@ +