diff --git a/.env.development b/.env.development index 2e7835e..b41440c 100644 --- a/.env.development +++ b/.env.development @@ -21,3 +21,6 @@ VUE_APP_RANDOM_URL=http://172.22.80.156:8085/aicods_gz_old/login/sso_home.html #年报 VUE_APP_AICEPS_URL = 'http://10.201.62.87:6891/gz-aiceps-manage' + +VUE_APP_AICEPS_SERVICE_URL = 'http://localhost:9549' + diff --git a/.env.production b/.env.production index 500265a..ab3a2a0 100644 --- a/.env.production +++ b/.env.production @@ -14,3 +14,7 @@ VUE_APP_CAS_SERVER_UNITE = 'http://10.194.188.69/cas' #年报 VUE_APP_AICEPS_URL = 'http://10.201.62.87:6891/gz-aiceps-manage' + +# 年报服务地址 无需写/aiceps-service-web 如和aiccs同域名同端口部署则置空 +VUE_APP_AICEPS_SERVICE_URL = '' + diff --git a/build/genapi.js b/build/genapi.js new file mode 100644 index 0000000..0166fe5 --- /dev/null +++ b/build/genapi.js @@ -0,0 +1,140 @@ +const axios = require('axios').default +const fs = require('fs') +const Path = require('path') + +function mkdirsSync(dirname) { + if (fs.existsSync(dirname)) { + return true + } else { + if (mkdirsSync(Path.dirname(dirname))) { + fs.mkdirSync(dirname) + return true + } + } +} +const fileTemplate = `/** + * 该文件由插件根据doc.html在启动项目时自动生成,请勿修改(修改了也会被覆盖 + */ + +import request from '@/utils/request' +` +const functionCodeGener = function(meta) { + const functionParams = [] + if (Array.isArray(meta.params) && meta.params.length > 0) { + functionParams.push('params') + } + if (Array.isArray(meta.data) && meta.data.length > 0) { + functionParams.push('data') + } + if (Array.isArray(meta.formData) && meta.formData.length > 0) { + functionParams.push('formData') + } + return ` +/** + * ${meta.comment} + */ +export function ${meta.name}(${functionParams.join(', ')}) { + return request({ + method: '${meta.method}', + url: '${meta.url}'${meta.requestType ? ',\n requestType: \'' + meta.requestType + '\'' : ''}${functionParams.includes('params') ? ',\n params' : ''}${functionParams.includes('data') || functionParams.includes('formData') ? ',\n data' + (functionParams.includes('formData') ? ': formData' : '') : ''} + }) +} +` +} +module.exports = class Genapi { + constructor(apiUrl, output = 'build') { + this.apiUrl = apiUrl[apiUrl.length - 1] === '/' ? apiUrl.slice(0, apiUrl.length - 1) : apiUrl + this.output = output + } + apply(compiler) { + compiler.hooks.environment.tap('Genapi', async(compilation, callback) => { + const projectPath = Path.join(__dirname, '../') + const apiPath = Path.join(projectPath, 'src/api/', this.output) + axios({ + url: this.apiUrl + '/swagger-resources', + method: 'get' + }).then(({ data }) => { + const resultFile = {} + Promise.all(data.map((apiScope) => { + return axios({ + url: this.apiUrl + '/v2/api-docs', + params: { + group: apiScope.name + }, + method: 'get' + }).then(({ data }) => { + const { + basePath, + paths + } = data + for (const _path in paths) { + const path = _path.replace(new RegExp('^' + basePath, 'g'), '') + const pathSplit = path.split('/').slice('/') + const apiName = pathSplit[pathSplit.length - 1] + const fileName = pathSplit.length > 2 ? pathSplit[pathSplit.length - 2] : '' + const mkdirPath = pathSplit.slice(0, pathSplit.length - 2).join('/') || '/' + const fileApiSet = new Set() + const filePath = Path.join(mkdirPath, fileName) + if (!resultFile[filePath]) { + resultFile[filePath] = fileTemplate + } + for (const method in paths[_path]) { + const apiMeta = paths[_path][method] + const parameters = apiMeta.parameters || [] + const formData = parameters.filter((item) => { + return item.in === 'formData' + }) + const data = parameters.filter((item) => { + return item.in === 'body' + }) + const params = parameters.filter((item) => { + return item.in === 'query' + }) + resultFile[filePath] += functionCodeGener({ + name: (() => { + const filterApiName = apiName.replace(/\.do$/g, '') + let result = Object.keys(paths[_path]).length > 1 ? `${method}_${filterApiName}` : filterApiName + if (fileApiSet.has(result)) { + let i = 1 + while (fileApiSet.has(`${result}_${i}`)) { + i++ + } + result = `${result}_${i}` + } + return result + })(), + method, + url: path, + comment: apiMeta.summary, + data, + params, + formData, + requestType: (() => { + if (method !== 'get') { + if (formData.length > 0) { + return 'formdata' + } else { + return 'json' + } + } + })() + }) + } + } + }).catch((e) => { + console.warn(`无法读取api文档: ${apiScope.name}`) + console.warn(e.message) + }) + })).then(() => { + for (const path in resultFile) { + mkdirsSync(Path.join(apiPath, path)) + const filepath = Path.join(apiPath, path, 'index.js') + if (fs.existsSync(filepath) && fs.readFileSync(filepath).toString() !== resultFile[path]) { + fs.writeFileSync(filepath, resultFile[path]) + } + } + }) + }).catch((e) => { }) + }) + } +} diff --git a/build/increpack.js b/build/increpack.js new file mode 100644 index 0000000..902d0bd --- /dev/null +++ b/build/increpack.js @@ -0,0 +1,115 @@ +const path = require('path') +const fs = require('fs') +const compressing = require('compressing') +const axios = require('axios') +const child_process = require('child_process') +const packageJson = require('../package.json') +function parseTime(time, format = 'yyyy-MM-dd hh:mm:ss') { + const date = time instanceof Date ? time : new Date(time) + + const o = { + 'M+': date.getMonth() + 1, // 月份 + 'd+': date.getDate(), // 日 + 'h+': date.getHours(), // 小时 + 'm+': date.getMinutes(), // 分 + 's+': date.getSeconds(), // 秒 + 'q+': Math.floor((date.getMonth() + 3) / 3), // 季度 + 'S': date.getMilliseconds() // 毫秒 + } + if (/(y+)/.test(format)) { + format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)) + } + for (const k in o) { + if (new RegExp('(' + k + ')').test(format)) { + format = format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) + } + } + return format +} + +/** + * 打包插件 v2.0 + * youfool + */ +class IncrePack { + apply(compiler) { + if (process.env.VUE_APP_WEBPACK_CMD !== 'build') { + return + } + const date = new Date() + const projectPath = path.join(__dirname, '../') + const distPath = projectPath + 'dist' + const versionPath = `${projectPath}src/version.js` + let hash = '000000' + try { + hash = child_process.execSync('git rev-parse HEAD').slice(0, 6) + } catch (e) { + console.log('------------------读取版本Hash失败---------------') + console.warn(e) + } + const codeVersion = `${parseTime(date, 'yyyy-MM-dd hh:mm:ss')} ${hash} ${process.env.VUE_APP_ENVIRONMENT}` + compiler.hooks.beforeRun.tapAsync('SetVersion', async(compilation, callback) => { + const data = `/** 本文件由打包插件自动生成和修改 */\nexport default '${codeVersion}'\n` + fs.writeFileSync(versionPath, data) + callback() + }) + compiler.hooks.done.tap('SetVersion', async(compilation) => { + const data = `/** 本文件由打包插件自动生成和修改 */\nexport default ''\n` + fs.writeFileSync(versionPath, data) + }) + compiler.hooks.done.tap('IncrePack', async(compilation) => { + let versionJson = { + artifactId: packageJson.name, + version: packageJson.version, + appId: packageJson.appId, + codeId: packageJson.codeId, + codeVersion + } + if (packageJson.increApi) { + // 获取版本信息 + try { + console.log('------------------正在写入升级记录---------------') + const res = await axios.default({ + url: packageJson.increApi + '?appId=' + packageJson.appId + '&codeId=' + packageJson.codeId, + method: 'get', + timeout: 5000 + }) + const { code, data } = res.data + if (code === 0 && data) { + versionJson = { + ...versionJson, + artifactId: packageJson.name, + upgradeId: data.upgradeId, + version: data.version, + releaseTime: data.releaseTime, + fromCommit: data.fromCommit, + untilCommit: data.untilCommit, + newFeatures: data.newFeatures, + repair: data.repair, + other: data.other + } + console.log('------------------写入升级记录成功---------------') + } + } catch (e) { + console.log(e.message) + console.log('------------------提交升级记录到远端失败---------------') + } + } + fs.mkdirSync(distPath + '/increpack-config') + fs.writeFileSync(distPath + '/increpack-config/version.json', JSON.stringify(versionJson), 'utf8') + const increName = `${packageJson.name}-${process.env.VUE_APP_ENVIRONMENT}-${parseTime(date, 'yyyy-MM-dd')}-${hash}.zip` + // 打包压缩 + const tempFile = projectPath + '/' + increName + compressing.zip.compressDir(distPath, tempFile, { ignoreBase: true }) + .then(() => { + // 剪切回dist目录下 + fs.renameSync(tempFile, distPath + '/' + increName) + console.log('------------------打包成功------------------') + }) + .catch(err => { + console.error(err) + }) + }) + } +} +module.exports = IncrePack diff --git a/src/api/user.js b/src/api/user.js index 0e706d0..a2c0ccb 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -139,3 +139,10 @@ export function isHaveUser(phone) { data: params }) } + +export function oauth() { + return request({ + url: '/aiccs-api/oauth2/sm4/encrypted/data', + method: 'get' + }) +} diff --git a/src/layout/Empty.vue b/src/layout/Empty.vue new file mode 100644 index 0000000..db3c971 --- /dev/null +++ b/src/layout/Empty.vue @@ -0,0 +1,13 @@ + diff --git a/src/layout/components/Banner.vue b/src/layout/components/Banner.vue index 0ae5273..4b5c894 100644 --- a/src/layout/components/Banner.vue +++ b/src/layout/components/Banner.vue @@ -98,7 +98,9 @@ export default { align-items: center; justify-content: space-between; /* background: linear-gradient(66deg,#054dd3 0%, #3296fa 89%); */ - background: url('../../assets/images/banner.png') no-repeat; + background-image: url('../../assets/images/banner.png') ; + background-repeat: no-repeat; + background-size: cover; /* box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.16); */ font-family: 'Source Han Sans CN'; z-index: 2000; diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 826c44b..5ac136d 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -3,6 +3,7 @@ import { getUserMenus } from '@/api/router' import user from './user' import { Message } from 'element-ui' import Layout from '@/layout' +import Empty from '@/layout/Empty' /** * Use meta.role to determine if the current user has permission @@ -47,10 +48,18 @@ export function generaMenu(routes, data, curPath = '') { } else { iconName = 'default' } + let component = () => import('@/views/iframe/index') + if (item.children && item.children.length > 0) { + if (item.level === 1) { + component = Layout + } else { + component = Empty + } + } const menu = { path: (curPath === '/' ? '' : curPath) + item.path, - component: item.pid === '' ? Layout : () => import('@/views/iframe/index'), - redirect: item.pid === '' ? (curPath === '/' ? '' : curPath) + item.path + (item.children.length > 0 ? item.children[0].path : '') : '', + component, + redirect: !item.pid ? (curPath === '/' ? '' : curPath) + item.path + (item.children.length > 0 ? item.children[0].path : '') : '', children: [], name: item.path, meta: { title: item.title, id: item.sysMenuId, icon: iconName } @@ -125,6 +134,7 @@ const actions = { }) Object.assign(loadMenuData, data) generaMenu(asyncRoutes, loadMenuData) + console.log('动态路由', asyncRoutes) let accessedRoutes roles = ['admin'] if (roles.includes('admin')) { diff --git a/src/views/iframe/index.vue b/src/views/iframe/index.vue index 775dc0a..b3f0aa8 100644 --- a/src/views/iframe/index.vue +++ b/src/views/iframe/index.vue @@ -3,9 +3,11 @@