diff --git a/package.json b/package.json index 2ad5230..b61c829 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "compression-webpack-plugin": "^6.1.2", "core-js": "^3.8.3", "css-loader": "^7.1.2", + "dayjs": "^1.11.11", "element-ui": "^2.15.14", "js-cookie": "^3.0.5", "js-md5": "^0.8.3", diff --git a/src/api/systemData/commonFields.js b/src/api/systemData/commonFields.js new file mode 100644 index 0000000..18066e5 --- /dev/null +++ b/src/api/systemData/commonFields.js @@ -0,0 +1,40 @@ +import request from '@/utils/request' + +// 获取字段列表 +export function getList(data) { + return request({ + url: '/api/system/CommonFields', + method: 'get', + data + }) +} +// 获取字段信息 +export function getInfo(id) { + return request({ + url: `/api/system/CommonFields/${id}`, + method: 'get' + }) +} +// 删除字段 +export function Delete(id) { + return request({ + url: `/api/system/CommonFields/${id}`, + method: 'DELETE' + }) +} +// 修改字段 +export function Update(data) { + return request({ + url: `/api/system/CommonFields/${data.id}`, + method: 'PUT', + data + }) +} +// 新建字段 +export function Create(data) { + return request({ + url: '/api/system/CommonFields', + method: 'post', + data + }) +} diff --git a/src/api/systemData/dataBackup.js b/src/api/systemData/dataBackup.js new file mode 100644 index 0000000..63d8ba0 --- /dev/null +++ b/src/api/systemData/dataBackup.js @@ -0,0 +1,26 @@ +import request from '@/utils/request' + +// 获取数据备份列表(带分页) +export function getDataBackupList(data) { + return request({ + url: '/api/system/DataBackup', + method: 'GET', + data + }) +} + +// 添加数据备份 +export function createDataBackup() { + return request({ + url: '/api/system/DataBackup', + method: 'POST' + }) +} + +// 删除数据备份 +export function delDataBackup(id) { + return request({ + url: `/api/system/DataBackup/${id}`, + method: 'DELETE' + }) +} \ No newline at end of file diff --git a/src/api/systemData/dataInterface.js b/src/api/systemData/dataInterface.js new file mode 100644 index 0000000..ee8a7e2 --- /dev/null +++ b/src/api/systemData/dataInterface.js @@ -0,0 +1,93 @@ +import request from '@/utils/request' + +// 获取接口列表(分页) +export function getDataInterfaceList(data) { + return request({ + url: '/api/system/DataInterface', + method: 'GET', + data + }) +} + +// 获取接口列表下拉框 +export function getDataInterfaceSelector() { + return request({ + url: '/api/system/DataInterface/Selector', + method: 'GET' + }) +} + +// 添加接口 +export function createDataInterface(data) { + return request({ + url: '/api/system/DataInterface', + method: 'POST', + data + }) +} + +// 修改接口 +export function updateDataInterface(data) { + return request({ + url: `/api/system/DataInterface/${data.id}`, + method: 'PUT', + data + }) +} + +// 获取接口数据 +export function getDataInterfaceInfo(id) { + return request({ + url: `/api/system/DataInterface/${id}`, + method: 'GET' + }) +} + +// 删除接口数据 +export function delDataInterface(id) { + return request({ + url: `/api/system/DataInterface/${id}`, + method: 'DELETE' + }) +} + +// 更新接口状态 +export function updateDataInterfaceState(id) { + return request({ + url: `/api/system/DataInterface/${id}/Actions/State`, + method: 'PUT' + }) +} + +// 获取接口分类 +export function getDataInterfaceTypeSelector() { + return request({ + url: '/api/system/DictionaryData/9c43287481364d348c0ea0d0f64b38be/Data/Selector', + method: 'GET' + }) +} + +// 获取接口数据 +export function previewDataInterface(id) { + return request({ + url: `/api/system/DataInterface/${id}/Actions/Response`, + method: 'GET' + }) +} + +// 导出数据接口数据 +export function exportData(id) { + return request({ + url: `/api/system/DataInterface/${id}/Action/Export`, + method: 'GET' + }) +} + +// 获取数据接口调用日志列表 +export function getDataInterfaceLog(id, data) { + return request({ + url: `/api/system/DataInterfaceLog/${id}`, + method: 'GET', + data + }) +} \ No newline at end of file diff --git a/src/api/systemData/dataModel.js b/src/api/systemData/dataModel.js new file mode 100644 index 0000000..9b29b01 --- /dev/null +++ b/src/api/systemData/dataModel.js @@ -0,0 +1,62 @@ +import request from '@/utils/request' + +// 获取数据库表列表 +export function DataModelList(id, data) { + return request({ + url: `/api/system/DataModel/${id}/Tables`, + method: 'get', + data + }) +} +// 添加数据表 +export function DataModelCreate(linkId, data) { + return request({ + url: `/api/system/DataModel/${linkId}/Table`, + method: 'post', + data + }) +} +// 预览数据库表 +export function DataModelData(linkId, table, data) { + return request({ + url: `/api/system/DataModel/${linkId}/Table/${table}/Preview`, + method: 'get', + data + }) +} +// 删除数据表 +export function DataModelDelete(linkId, id) { + return request({ + url: `/api/system/DataModel/${linkId}/Table/${id}`, + method: 'delete', + }) +} +// 获取数据库表字段列表 +export function DataModelFieldList(linkId, table, type) { + return request({ + url: `/api/system/DataModel/${linkId}/Tables/${table}/Fields?type=${type}`, + method: 'get' + }) +} +// 获取数据表 +export function DataModelInfo(linkId, id) { + return request({ + url: `/api/system/DataModel/${linkId}/Table/${id}`, + method: 'get', + }) +} +// 修改数据表 +export function DataModelUpdate(linkId, data) { + return request({ + url: `/api/system/DataModel/${linkId}/Table`, + method: 'put', + data + }) +} +// 导出 +export function exportTpl(linkId, id) { + return request({ + url: `/api/system/DataModel/${linkId}/Table/${id}/Action/Export`, + method: 'get' + }) +} \ No newline at end of file diff --git a/src/api/systemData/dataSource.js b/src/api/systemData/dataSource.js new file mode 100644 index 0000000..2b49f03 --- /dev/null +++ b/src/api/systemData/dataSource.js @@ -0,0 +1,62 @@ +import request from '@/utils/request' + +export function getDataSourceList(data) { + return request({ + url: '/api/system/DataSource', + method: 'get', + data + }) +} +export function DataSourceCreate(data) { + return request({ + url: '/api/system/DataSource', + method: 'post', + data + }) +} +export function DataSourceDelete(id) { + return request({ + url: `/api/system/DataSource/${id}`, + method: 'delete', + }) +} +export function DataSourceInfo(id) { + return request({ + url: `/api/system/DataSource/${id}`, + method: 'get', + }) +} +export function DataSourceUpdate(data) { + return request({ + url: `/api/system/DataSource/${data.id}`, + method: 'put', + data + }) +} +export function TestDbConnection(data) { + return request({ + url: `/api/system/DataSource/Actions/Test`, + method: 'post', + data + }) +} +export function getDataSourceListAll() { + return request({ + url: '/api/system/DataSource/Selector', + method: 'get', + }) +} +export function Execute(data) { + return request({ + url: `/api/system/DataSync/Actions/Execute`, + method: 'post', + data + }) +} +export function DataSync(data) { + return request({ + url: `api/system/DataSync`, + method: 'post', + data + }) +} \ No newline at end of file diff --git a/src/api/systemData/dictionary.js b/src/api/systemData/dictionary.js new file mode 100644 index 0000000..6045255 --- /dev/null +++ b/src/api/systemData/dictionary.js @@ -0,0 +1,135 @@ +import request from '@/utils/request' + +// 获取数据字典分类 +export function getDictionaryType() { + return request({ + url: '/api/system/DictionaryType', + method: 'GET' + }) +} + +// 获取字典分类下拉框列表 +export function getDictionaryTypeSelector(id) { + return request({ + url: '/api/system/DictionaryType/Selector/' + (!!id ? id : 0), + method: 'GET' + }) +} + +// 添加数据字典分类 +export function createDictionaryType(data) { + return request({ + url: `/api/system/DictionaryType`, + method: 'POST', + data + }) +} + +// 修改数据字典分类 +export function updateDictionaryType(data) { + return request({ + url: `/api/system/DictionaryType/${data.id}`, + method: 'PUT', + data + }) +} + +// 获取数据字典分类信息 +export function getDictionaryTypeInfo(id) { + return request({ + url: `/api/system/DictionaryType/${id}`, + method: 'GET' + }) +} + +// 删除数据字典分类 +export function delDictionaryType(id) { + return request({ + url: `/api/system/DictionaryType/${id}`, + method: 'DELETE' + }) +} + +// 获取数据字典列表 +export function getDictionaryDataList(typeId, data) { + return request({ + url: `/api/system/DictionaryData/${typeId}`, + method: 'GET', + data + }) +} + +// 获取数据字典列表(分类+内容) +export function getDictionaryAll() { + return request({ + url: `/api/system/DictionaryData/All`, + method: 'GET' + }) +} + +// 获取字典分类下拉框(项目上级) +export function getDictionaryDataTypeSelector(dictionaryTypeId, isTree, id) { + return request({ + url: `/api/system/DictionaryData/${dictionaryTypeId}/Selector/` + (!!id ? id : 0), + method: 'GET', + data: { isTree } + }) +} + +// 获取字典数据下拉框列表 +export function getDictionaryDataSelector(dictionaryTypeId) { + return request({ + url: `/api/system/DictionaryData/${dictionaryTypeId}/Data/Selector`, + method: 'GET' + }) +} + +// 添加数据字典 +export function createDictionaryData(data) { + return request({ + url: '/api/system/DictionaryData', + method: 'POST', + data + }) +} + +// 修改数据字典 +export function updateDictionaryData(data) { + return request({ + url: `/api/system/DictionaryData/${data.id}`, + method: 'PUT', + data + }) +} + +// 获取数据字典信息 +export function getDictionaryDataInfo(id) { + return request({ + url: `/api/system/DictionaryData/${id}/Info`, + method: 'GET' + }) +} + +// 删除数据字典信息 +export function delDictionaryData(id) { + return request({ + url: `/api/system/DictionaryData/${id}`, + method: 'DELETE' + }) +} + +// 更新字典状态 +export function updateDictionaryState(id) { + return request({ + url: `/api/system/DictionaryData/${id}/Actions/State`, + method: 'PUT' + }) +} + +// 导出数据字典数据 +export function exportData(id) { + return request({ + url: `/api/system/DictionaryData/${id}/Action/Export`, + method: 'GET' + }) +} \ No newline at end of file diff --git a/src/assets/images/404.png b/src/assets/images/404.png new file mode 100644 index 0000000..2fa73a0 --- /dev/null +++ b/src/assets/images/404.png diff --git a/src/permission.js b/src/permission.js index 4d52e94..222dd7a 100644 --- a/src/permission.js +++ b/src/permission.js @@ -23,14 +23,21 @@ router.beforeEach((to, from, next) => { isRelogin.show = true // 判断当前用户是否已拉取完user_info信息 - store.dispatch('GetInfo').then(() => { + store.dispatch('GetInfo').then((res) => { isRelogin.show = false - next({ ...to, replace: true }) - // store.dispatch('GenerateRoutes').then(accessRoutes => { - // // 根据roles权限生成可访问的路由表 - // router.addRoutes(accessRoutes) // 动态添加可访问路由表 - // next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 - // }) + store.dispatch('generateRoutes', res).then(accessRoutes => { + console.log(accessRoutes); + // 根据roles权限生成可访问的路由表 + // router.addRoutes(accessRoutes) // 动态添加可访问路由表 + console.log(router.addRoutes); + router.addRoutes([{ + path: '/404', + component: (resolve) => require(['@/views/error-page/404'], resolve), + hidden: true + }]) // 动态添加可访问路由表 + console.log(router); + next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + }) }).catch(err => { store.dispatch('LogOut').then(() => { Message.error(err) diff --git a/src/router/index.js b/src/router/index.js index bc2e124..1fa3d82 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -2,45 +2,58 @@ import Vue from "vue"; import VueRouter from "vue-router"; import Layout from '@/views/homePage/HomePage.vue' - +import baseRouter from './modules/base' Vue.use(VueRouter); -const router = new VueRouter({ - mode: 'hash', // 使用 hash 模式 - routes: [ - { - path: '', - component: Layout, - name: 'homePage', - children: [ - { - path: '/homePage', - name: 'homePage', - component: () => import('@/views/overView/Overview.vue'), - meta: { title: '首页', icon: 'dashboard', affix: true } - }, - ] - }, - { - path: '', - component: Layout, - name: 'infoList', - children: [ - { - path: '/infoList', - name: 'infoList', - component: () => import('@/views/systemPage/InfoList.vue'), - meta: { title: '系统', icon: 'dashboard', affix: true } - }, - ] - }, - { - path: '/login', - name: 'login', - component: () => import('@/views/Login.vue'), - }, - ] -}); +export const constantRoutes = [ + { + path: '/404', + name: '404', + component: (resolve) => require(['@/views/error-page/404.vue'], resolve), + hidden: true + }, + { + path: '/login', + component: (resolve) => require(['@/views/Login.vue'], resolve), + hidden: true + }, + { + path: '', + name: 'homePage', + component: Layout, + children: [ + { + path: '/homePage', + name: 'homePage', + component: (resolve) => require(['@/views/overView/Overview.vue'], resolve), + meta: { title: '首页', icon: 'dashboard', affix: true }, + }, + ], + hidden: true + }, + ...baseRouter +] + +const createRouter = () => { + return new VueRouter({ + mode: 'hash', // 使用 hash 模式 + routes: constantRoutes + }); +} + +const originalPush = VueRouter.prototype.push +VueRouter.prototype.push = function push(location) { + return originalPush.call(this, location).catch(err => { + if (err && err.name != 'NavigationDuplicated') this.replace('/404') + }) +} + +const router = createRouter(); + +export function resetRouter() { + const newRouter = createRouter() + router.matcher = newRouter.matcher // reset router +} export default router; \ No newline at end of file diff --git a/src/router/modules/base.js b/src/router/modules/base.js new file mode 100644 index 0000000..1c8afe6 --- /dev/null +++ b/src/router/modules/base.js @@ -0,0 +1,27 @@ +// 基础路由 +import Layout from '@/views/homePage/HomePage.vue' + +const baseRouter = [ + { + path: '', + meta: { title: '基础信息库', icon: 'dashboard', affix: true }, + component: Layout, + children: [ + { + path: '/infoList', + name: 'infoList', + component: (resolve) => require(['@/views/systemPage/InfoList.vue'], resolve), + meta: { title: '应用信息', icon: 'dashboard', affix: true }, + id: 3, + }, + { + path: '/baseComapnyInfo', + name: 'baseComapnyInfo', + component: (resolve) => require(['@/views/baseComapnyInfo/index.vue'], resolve), + meta: { title: '公司信息', icon: 'dashboard', affix: true }, + id: 4, + } + ] + }, +] +export default baseRouter \ No newline at end of file diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 5eaa708..a64931e 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -1,52 +1,50 @@ // import auth from '@/plugins/auth' -import router, { constantRoutes, dynamicRoutes } from '@/router' +import { constantRoutes } from '@/router' +import VueRouter from "vue-router"; // import { getRouters } from '@/api/menu' import Layout from '@/views/homePage/HomePage.vue' -import ParentView from '@/components/ParentView' +import baseRouters from '@/router/modules/base' const permission = { state: { routes: [], - addRoutes: [], - defaultRoutes: [], - topbarRouters: [], - sidebarRouters: [] + addRoutes: [] }, mutations: { SET_ROUTES: (state, routes) => { state.addRoutes = routes state.routes = constantRoutes.concat(routes) - }, - SET_DEFAULT_ROUTES: (state, routes) => { - state.defaultRoutes = constantRoutes.concat(routes) - }, - SET_TOPBAR_ROUTES: (state, routes) => { - state.topbarRouters = routes - }, - SET_SIDEBAR_ROUTERS: (state, routes) => { - state.sidebarRouters = routes - }, + } }, actions: { - // 生成路由 - GenerateRoutes({ commit }) { + generateRoutes({ commit }, route) { return new Promise(resolve => { - // 向后端请求路由数据 - // getRouters().then(res => { - // let data = res.data.filter(v => !(v.name && v.name == 'System')); - // const sdata = JSON.parse(JSON.stringify(data)) - // const rdata = JSON.parse(JSON.stringify(data)) - // const sidebarRoutes = filterAsyncRouter(sdata) - // const rewriteRoutes = filterAsyncRouter(rdata, false, true) - // const asyncRoutes = filterDynamicRoutes(dynamicRoutes); - // rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) - // router.addRoutes(asyncRoutes); - // commit('SET_ROUTES', rewriteRoutes) - // commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes)) - // commit('SET_DEFAULT_ROUTES', sidebarRoutes) - // commit('SET_TOPBAR_ROUTES', sidebarRoutes) - // resolve(rewriteRoutes) - // }) + let accessedRoutes + let dtRoutes = { + path: '/', + component: Layout, + redirect: '/homePage', + children: [ + ...baseRouters, + ...route, + { + path: '/404', + component: (resolve) => require(['@/views/error-page/404'], resolve), + hidden: true + }, + ] + }; + accessedRoutes = [ + dtRoutes, + { + path: '*', + redirect: '/404', + hidden: true + } + ] + console.log(accessedRoutes, baseRouters); + commit('SET_ROUTES', accessedRoutes) + resolve(accessedRoutes) }) } } diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 3231305..942bff8 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -1,6 +1,10 @@ import { login, getInfo, logout } from '@/api/index' import { getToken, setToken, removeToken } from '@/utils/auth' +import { resetRouter } from '@/router' import md5 from "js-md5"; // 密码加密 +const define = require('@/utils/define') +import qs from 'qs' + const user = { state: { @@ -10,6 +14,9 @@ const user = { avatar: '', roles: [], address: '', + loginLoading: '', + userInfo: {}, + menuList: [], }, mutations: { @@ -30,6 +37,15 @@ const user = { }, SET_ADDRESS: (state, address) => { state.address = address + }, + SET_LOGIN_LOADING: (state, loginLoading) => { + state.loginLoading = loginLoading + }, + SET_USERINFO: (state, userInfo) => { + state.userInfo = userInfo + }, + SET_MENULIST: (state, menuList) => { + state.menuList = menuList } }, @@ -53,19 +69,121 @@ const user = { GetInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo().then((res) => { - let { data } = res; - const user = data.userInfo - const avatar = (user.headIcon == "" || user.headIcon == null) || require("@/assets/images/user.jpg"); - if (user.roleIds && user.roleIds.length > 0) { // 验证返回的roles是否是一个非空数组 - commit('SET_ROLES', user.roleIds) + let { menuList, userInfo, permissionList } = res.data + const avatar = (userInfo.headIcon == "" || userInfo.headIcon == null) || require("@/assets/images/user.jpg"); + if (!menuList.length) { + reject('您的权限不足,请联系管理员') + return false; + } + let routerList = [] + + function setData(list) { + for (let i = 0; i < list.length; i++) { + const e = list[i] + let name = e.enCode.replace(/\./g, '-') + e.vueName = name + if (e.type == 1) { + e.path = '/' + e.enCode + if (e.hasChildren && e.children.length) { + setData(e.children) + } + } + if (e.type == 2) { + let path = e.urlAddress + if (path.indexOf("?") > -1) path = path.split("?")[0] + e.path = '/' + e.urlAddress + let newObj = { + path: '/' + path, + component: (resolve) => require([`@/views/${path}`], resolve), + name: name, + meta: { + title: name, + icon: e.icon, + zhTitle: e.fullName, + modelId: e.id + } + } + routerList.push(newObj) + } + // 功能、字典、报表、门户 + if ([3, 4, 5, 8].indexOf(e.type) > -1) { + let propertyJson = e.propertyJson ? JSON.parse(e.propertyJson) : null, + relationId = '', + isTree = 0, + componentUrl = '' + if (propertyJson) { + relationId = propertyJson.moduleId || '' + isTree = propertyJson.isTree || 0 + } + if (e.type == 3) { + componentUrl = 'dynamicModel' + } else if (e.type == 4) { + componentUrl = 'dynamicDictionary' + } else if (e.type == 5) { + componentUrl = 'dynamicDataReport' + } else { + componentUrl = 'dynamicPortal' + } + e.path = '/' + e.urlAddress + let newObj = { + path: '/' + e.urlAddress, + component: (resolve) => require([`@/views/basic/${componentUrl}`], resolve), + name: e.enCode, + meta: { + title: name, + icon: e.icon, + zhTitle: e.fullName, + modelId: e.id, + relationId, + isTree + } + } + routerList.push(newObj) + } + // 大屏 + if (e.type == 6) { + let propertyJson = e.propertyJson ? JSON.parse(e.propertyJson) : null, + moduleId = ''; + if (propertyJson) moduleId = propertyJson.moduleId || '' + e.path = `${define.dataV}/view/${moduleId}?token=${getToken()}` + } + // 外链 + if (e.type == 7) { + if (e.linkTarget === "_self") { + e.path = '/' + e.enCode + let newObj = { + path: '/' + e.enCode, + component: (resolve) => require([`@/views/basic/externalLink`], resolve), + name: e.enCode, + meta: { + title: name, + icon: e.icon, + zhTitle: e.fullName, + modelId: e.id, + urlAddress: e.urlAddress + } + } + routerList.push(newObj) + } else { + const path = e.urlAddress.replace(/\${dataV}/g, define.dataV).replace(/\${nccToken}/g, getToken()) + e.path = path + } + } + } + } + setData(menuList); + if (userInfo.roleIds && userInfo.roleIds.length > 0) { // 验证返回的roles是否是一个非空数组 + commit('SET_ROLES', userInfo.roleIds) } else { commit('SET_ROLES', ['ROLE_DEFAULT']) } - commit('SET_ID', user.userId) - commit('SET_NAME', user.userName) + commit('SET_ID', userInfo.userId) + commit('SET_NAME', userInfo.userName) commit('SET_AVATAR', avatar) - commit('SET_ADDRESS', user.loginIPAddressName) - resolve(res) + commit('SET_ADDRESS', userInfo.loginIPAddressName) + commit('SET_USERINFO', userInfo) + commit('SET_MENULIST', menuList) + resolve(routerList) }).catch(error => { reject(error) }) diff --git a/src/utils/define.js b/src/utils/define.js new file mode 100644 index 0000000..63c75ae --- /dev/null +++ b/src/utils/define.js @@ -0,0 +1,23 @@ +// 开发环境接口配置 +// JAVA Boot版本对应后端接口地址 +// JAVA Cloud对应网关地址 +const APIURl = 'http://localhost:8061' + +module.exports = { + APIURl: APIURl, + timeout: process.env.NODE_ENV === 'development' ? 10000 : 1000000, + WebSocketUrl: process.env.NODE_ENV === 'development' ? APIURl.replace('http', 'ws') + '/api/message/websocket' : process.env.VUE_APP_BASE_WSS, + comUploadUrl: process.env.VUE_APP_BASE_API + '/api/file/Uploader', + comUrl: process.env.VUE_APP_BASE_API, + // 本地文件预览 + filePreviewServer: process.env.NODE_ENV === 'development' ? 'http://localhost:30090' : process.env.VUE_APP_BASE_API + '/FileServer', + // 大屏应用前端路径 + dataV: process.env.NODE_ENV === 'development' ? 'http://localhost:8100/DataV' : process.env.VUE_APP_BASE_API + '/DataV', + // 数据报表接口-java boot + reportServer: process.env.NODE_ENV === 'development' ? 'http://localhost:30007' : process.env.VUE_APP_BASE_API + '/ReportServer', + // 数据报表接口-java cloud + // reportServer: process.env.NODE_ENV === 'development' ? 'http://localhost:30000' : process.env.VUE_APP_BASE_API, + // 报表前端 + report: process.env.NODE_ENV === 'development' ? 'http://localhost:8200' : process.env.VUE_APP_BASE_API + '/Report', + version: '3.2' +} \ No newline at end of file diff --git a/src/utils/ncc.js b/src/utils/ncc.js new file mode 100644 index 0000000..d3cfd3f --- /dev/null +++ b/src/utils/ncc.js @@ -0,0 +1,327 @@ +import store from '@/store' +import dayjs from 'dayjs' +import context from '@/main' +const STORAGEPREFIX = 'ncc_' +const STORAGETYPE = window.localStorage + +const ncc = { + toDateText(dateTimeStamp) { + let result = '' + let minute = 1000 * 60; //把分,时,天,周,半个月,一个月用毫秒表示 + let hour = minute * 60; + let day = hour * 24; + let week = day * 7; + let halfamonth = day * 15; + let month = day * 30; + let now = new Date().getTime(); //获取当前时间毫秒 + let diffValue = now - dateTimeStamp; //时间差 + if (diffValue < 0) return "刚刚" + let minC = diffValue / minute; //计算时间差的分,时,天,周,月 + let hourC = diffValue / hour; + let dayC = diffValue / day; + let weekC = diffValue / week; + let monthC = diffValue / month; + if (monthC >= 1 && monthC <= 3) { + result = " " + parseInt(monthC) + "月前" + } else if (weekC >= 1 && weekC <= 3) { + result = " " + parseInt(weekC) + "周前" + } else if (dayC >= 1 && dayC <= 6) { + result = " " + parseInt(dayC) + "天前" + } else if (hourC >= 1 && hourC <= 23) { + result = " " + parseInt(hourC) + "小时前" + } else if (minC >= 1 && minC <= 59) { + result = " " + parseInt(minC) + "分钟前" + } else if (diffValue >= 0 && diffValue <= minute) { + result = "刚刚" + } else { + let datetime = new Date(); + datetime.setTime(dateTimeStamp); + let Nyear = datetime.getFullYear(); + let Nmonth = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1; + let Ndate = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate(); + let Nhour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours(); + let Nminute = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes(); + let Nsecond = datetime.getSeconds() < 10 ? "0" + datetime.getSeconds() : datetime.getSeconds(); + result = Nyear + "-" + Nmonth + "-" + Ndate + } + return result; + }, + getDate(format, strInterval, number) { + var myDate = new Date(); + var dtTmp = new Date(); + if (!!strInterval) { + switch (strInterval) { + case 's': + myDate = new Date(Date.parse(dtTmp) + (1000 * number)); // 秒 + break; + case 'n': + myDate = new Date(Date.parse(dtTmp) + (60000 * number)); // 分 + break; + case 'h': + myDate = new Date(Date.parse(dtTmp) + (3600000 * number)); // 小时 + break; + case 'd': + myDate = new Date(Date.parse(dtTmp) + (86400000 * number)); // 天 + break; + case 'w': + myDate = new Date(Date.parse(dtTmp) + ((86400000 * 7) * number)); // 星期 + break; + case 'q': + myDate = new Date(dtTmp.getFullYear(), (dtTmp.getMonth()) + number * 3, dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds()); // 季度 + break; + case 'm': + myDate = new Date(dtTmp.getFullYear(), (dtTmp.getMonth()) + number, dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds()); // 月 + break; + case 'y': + myDate = new Date((dtTmp.getFullYear() + number), dtTmp.getMonth(), dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds()); // 年 + break; + default: + } + } + return ncc.toDate(myDate, format); + }, + toDate(v, format) { + format = format ? format : "yyyy-MM-dd HH:mm" + if (!v) return ""; + var d = v; + if (typeof v === 'string') { + if (v.indexOf("/Date(") > -1) + d = new Date(parseInt(v.replace("/Date(", "").replace(")/", ""), 10)); + else + d = new Date(Date.parse(v.replace(/-/g, "/").replace("T", " ").split(".")[0])); + } else { + d = new Date(v) + } + var o = { + "M+": d.getMonth() + 1, + "d+": d.getDate(), + "h+": d.getHours(), + "H+": d.getHours(), + "m+": d.getMinutes(), + "s+": d.getSeconds(), + "q+": Math.floor((d.getMonth() + 3) / 3), + "S": d.getMilliseconds() + }; + if (/(y+)/.test(format)) { + format = format.replace(RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length)); + } + for (var 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; + }, + getThatDay(space) { + if (space == undefined) { + space = 0 + } + + let date = new Date() + date.setTime(date.getTime() + 86400000 * space) + return this.assemblyDay({ + year: date.getFullYear(), + month: date.getMonth(), + date: date.getDate() + }) + }, + assemblyDay(data) { + let year = data.year.toString() + data.month = Number(data.month + 1) + let month = this.complement(data.month) + let date = this.complement(data.date) + return year + '-' + month + '-' + date + }, + complement(value, digit) { + digit = digit ? digit : 2 + value = Number(value) + if (value < Math.pow(10, digit - 1)) { + let text = '' + for (let i = 0; i < digit - value.toString().length; i++) { + text = text + '0' + } + return text + value + } else { + return value.toString() + } + }, + toTreeViewJson(data, id, parentIdText, idText) { + parentIdText = parentIdText ? parentIdText : 'parentId' + idText = idText ? idText : 'id' + id = id ? id : 0 + let treeJson = []; + let childNode = data.filter(v => v[parentIdText] == id); + if (childNode.length > 0) { + for (let i = 0; i < childNode.length; i++) { + let treeModel = { + ...childNode[i], + hasChildren: !!data.filter(v => v[parentIdText] == childNode[i][idText]).length, + ChildNodes: ncc.toTreeViewJson(data, childNode[i][idText], parentIdText, idText), + isexpand: childNode[i].isexpand == undefined ? true : childNode[i].isexpand, + complete: true, + } + treeJson.push(treeModel); + } + } + return treeJson; + }, + toFileSize(size) { + if (size == null || size == "") { + return ""; + } + if (size < 1024.00) + return ncc.toDecimal(size) + " 字节"; + else if (size >= 1024.00 && size < 1048576) + return ncc.toDecimal(size / 1024.00) + " KB"; + else if (size >= 1048576 && size < 1073741824) + return ncc.toDecimal(size / 1024.00 / 1024.00) + " MB"; + else if (size >= 1073741824) + return ncc.toDecimal(size / 1024.00 / 1024.00 / 1024.00) + " GB"; + }, + toDecimal(num) { + if (num == null) { + num = "0"; + } + num = num.toString().replace(/\$|\,/g, ''); + if (isNaN(num)) + num = "0"; + var sign = (num == (num = Math.abs(num))); + num = Math.floor(num * 100 + 0.50000000001); + var cents = num % 100; + num = Math.floor(num / 100).toString(); + if (cents < 10) + cents = "0" + cents; + for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) + num = num.substring(0, num.length - (4 * i + 3)) + '' + + num.substring(num.length - (4 * i + 3)); + return (((sign) ? '' : '-') + num + '.' + cents); + }, + toUrl(url) { + return process.env.VUE_APP_BASE_API + url; + }, + getAuth() { + return store.getters.token; + }, + // 基于dayjs日期格式化,时间戳(毫秒)转日期 + dateFormat(date, format) { + format = format || 'YYYY-MM-DD HH:mm' + if (!date) return '' + return dayjs(date).format(format) + }, + // 基于dayjs日期格式化,日期转时间戳(毫秒) + timestamp(val) { + return dayjs(val).valueOf() + }, + // 基于dayjs日期格式化, 表格专用 + tableDateFormat(row, column, cellValue) { + let format = 'YYYY-MM-DD HH:mm' + if (!cellValue) return '' + return dayjs(cellValue).format(format) + }, + storageSet(obj) { + for (let i in obj) { + cacheItem(i, obj[i]) + } + + function cacheItem(key, val) { + key = STORAGEPREFIX + key + let valType = typeof(val) + if (val !== null) { + var valConstructor = val.constructor + } + if (valType === 'string' || valType === 'number' || valType === 'boolean') { + if (valConstructor === String) { + val = val + '|String' + } else if (valConstructor === Number) { + val = val + '|Number' + } else if (valConstructor === Boolean) { + val = val + '|Boolean' + } + STORAGETYPE.setItem(key, val) + } else if (valType === 'object') { + if (val === null) { + val = JSON.stringify(val) + '|Null' + STORAGETYPE.setItem(key, val) + } else { + if (valConstructor === Array) { + val = JSON.stringify(val) + '|Array' + } else if (valConstructor === Object) { + val = JSON.stringify(val) + '|Object' + } + STORAGETYPE.setItem(key, val) + } + } + } + }, + storageGet(key) { + key = STORAGEPREFIX + key + let keyName = STORAGETYPE.getItem(key) + if (keyName === null) { + return null + } + let valArr = keyName.split('|') + let getDataType = valArr[valArr.length - 1] + valArr.splice(valArr.length - 1, 1) + let val = valArr.join('') + if (getDataType === 'Number') { + val = parseInt(val) + } else if (getDataType === 'Boolean') { + if (val === 'true') { + val = true + } else { + val = false + } + } else if (getDataType === 'Array' || getDataType === 'Object' || getDataType === 'Null') { + val = JSON.parse(val) + } + return val + }, + storageRemove(key) { + STORAGETYPE.removeItem(STORAGEPREFIX + key) + }, + storageClear() { + for (let i in STORAGETYPE) { + if (i.indexOf(STORAGEPREFIX) !== -1) { + STORAGETYPE.removeItem(i) + } + } + }, + hasP(enCode) { + const permissionList = store.getters && store.getters.permissionList + const modelId = context.$route.meta.modelId || '' + if (!modelId) return false + const list = permissionList.filter(o => o.modelId === modelId) + if (!list.length) return false + const columnList = list[0] && list[0].column ? list[0].column : [] + if (!columnList.length) return false + const hasPermission = columnList.some(column => column.enCode === enCode) + if (hasPermission) return true + return false + }, + hasFormP(enCode) { + return true; + const permissionList = store.getters && store.getters.permissionList + const modelId = context.$route.meta.modelId || '' + if (!modelId) return false + const list = permissionList.filter(o => o.modelId === modelId) + if (!list.length) return false + const formList = list[0] && list[0].form ? list[0].form : [] + if (!formList.length) return false + const hasPermission = formList.some(form => form.enCode === enCode) + if (hasPermission) return true + return false + }, + hasBtnP(enCode) { + const permissionList = store.getters && store.getters.permissionList + const modelId = context.$route.meta.modelId || '' + if (!modelId) return false + const list = permissionList.filter(o => o.modelId === modelId) + if (!list.length) return false + const btnList = list[0] && list[0].button ? list[0].button : [] + if (!btnList.length) return false + const hasPermission = btnList.some(btn => btn.enCode === enCode) + if (hasPermission) return true + return false + } +} +export default ncc \ No newline at end of file diff --git a/src/views/Login.vue b/src/views/Login.vue index bb351ae..7aaad23 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -33,7 +33,9 @@ -
+ @@ -45,7 +47,11 @@ import { login } from "@/api/index"; import { setToken } from "@/utils/auth"; export default { name: "Login", - components: {}, + components: { + loginLoading() { + return this.$store.state.user.loginLoading; + }, + }, data() { return { form: { @@ -56,17 +62,32 @@ export default { account: { required: true, message: "用户名不能为空", trigger: "blur" }, password: { required: true, message: "密码不能为空", trigger: "blur" }, }, + loading: false, }; }, + watch: { + loginLoading(val) { + if (!val) this.loading = false; + }, + }, created() {}, mounted() {}, methods: { toHome() { + if (this.loading) return; + this.$refs["form"].validate((valid) => { if (valid) { - this.$store.dispatch("Login", this.form).then(() => { - this.$router.push({ path: "/homePage" }); - }); + this.loading = true; + this.$store.commit("SET_LOGIN_LOADING", true); + this.$store + .dispatch("Login", this.form) + .then(() => { + this.$router.push({ path: "/homePage" }); + }) + .catch(() => { + this.$store.commit("SET_LOGIN_LOADING", false); + }); } }); }, diff --git a/src/views/baseComapnyInfo/ExportBox.vue b/src/views/baseComapnyInfo/ExportBox.vue new file mode 100644 index 0000000..4fc5c07 --- /dev/null +++ b/src/views/baseComapnyInfo/ExportBox.vue @@ -0,0 +1,66 @@ + +
+