diff --git a/PC/UI.WinIn.FasterZ.Job/package-lock.json b/PC/UI.WinIn.FasterZ.Job/package-lock.json index eaa1212..c397a94 100644 --- a/PC/UI.WinIn.FasterZ.Job/package-lock.json +++ b/PC/UI.WinIn.FasterZ.Job/package-lock.json @@ -27,6 +27,7 @@ "moment": "^2.29.1", "normalize.css": "7.0.0", "nprogress": "0.2.0", + "oidc-client": "^1.11.5", "path-to-regexp": "2.4.0", "qs": "^6.10.3", "screenfull": "4.2.0", @@ -7416,6 +7417,11 @@ "node": "*" } }, + "node_modules/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + }, "node_modules/css": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", @@ -16024,6 +16030,35 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, + "node_modules/oidc-client": { + "version": "1.11.5", + "resolved": "https://registry.npmmirror.com/oidc-client/-/oidc-client-1.11.5.tgz", + "integrity": "sha512-LcKrKC8Av0m/KD/4EFmo9Sg8fSQ+WFJWBrmtWd+tZkNn3WT/sQG3REmPANE9tzzhbjW6VkTNy4xhAXCfPApAOg==", + "dependencies": { + "acorn": "^7.4.1", + "base64-js": "^1.5.1", + "core-js": "^3.8.3", + "crypto-js": "^4.0.0", + "serialize-javascript": "^4.0.0" + } + }, + "node_modules/oidc-client/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/oidc-client/node_modules/core-js": { + "version": "3.32.2", + "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.32.2.tgz", + "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==", + "hasInstallScript": true + }, "node_modules/omelette": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/omelette/-/omelette-0.4.5.tgz", @@ -29520,6 +29555,11 @@ "randomfill": "^1.0.3" } }, + "crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + }, "css": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", @@ -36331,6 +36371,30 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, + "oidc-client": { + "version": "1.11.5", + "resolved": "https://registry.npmmirror.com/oidc-client/-/oidc-client-1.11.5.tgz", + "integrity": "sha512-LcKrKC8Av0m/KD/4EFmo9Sg8fSQ+WFJWBrmtWd+tZkNn3WT/sQG3REmPANE9tzzhbjW6VkTNy4xhAXCfPApAOg==", + "requires": { + "acorn": "^7.4.1", + "base64-js": "^1.5.1", + "core-js": "^3.8.3", + "crypto-js": "^4.0.0", + "serialize-javascript": "^4.0.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "core-js": { + "version": "3.32.2", + "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.32.2.tgz", + "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==" + } + } + }, "omelette": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/omelette/-/omelette-0.4.5.tgz", diff --git a/PC/UI.WinIn.FasterZ.Job/package.json b/PC/UI.WinIn.FasterZ.Job/package.json index 518f341..a74c05c 100644 --- a/PC/UI.WinIn.FasterZ.Job/package.json +++ b/PC/UI.WinIn.FasterZ.Job/package.json @@ -33,6 +33,7 @@ "moment": "^2.29.1", "normalize.css": "7.0.0", "nprogress": "0.2.0", + "oidc-client": "^1.11.5", "path-to-regexp": "2.4.0", "qs": "^6.10.3", "screenfull": "4.2.0", diff --git a/PC/UI.WinIn.FasterZ.Job/public/config.js b/PC/UI.WinIn.FasterZ.Job/public/config.js index 7d76160..b343a91 100644 --- a/PC/UI.WinIn.FasterZ.Job/public/config.js +++ b/PC/UI.WinIn.FasterZ.Job/public/config.js @@ -1,17 +1,28 @@ // dev_win -// window.SITE_CONFIG['baseApi'] = 'http://192.168.0.190:30002' -// window.SITE_CONFIG['authApi'] = 'http://192.168.0.190:30002' -// window.SITE_CONFIG['userApi'] = 'http://192.168.0.190:30000' -window.SITE_CONFIG['baseApi'] = 'http://dev.ccwin-in.com:60067' -window.SITE_CONFIG['authApi'] = 'http://dev.ccwin-in.com:60067' -window.SITE_CONFIG['userApi'] = 'http://dev.ccwin-in.com:60064' +window.SITE_CONFIG['baseApi'] = 'http://dev.ccwin-in.com:60023' +window.SITE_CONFIG['authApi'] = 'http://dev.ccwin-in.com:60020' +// window.SITE_CONFIG['baseApi'] = 'http://192.168.0.190:60078'//http://dev.ccwin-in.com:60022 +// window.SITE_CONFIG['authApi'] = 'http://192.168.0.190:60065'//http://dev.ccwin-in.com:60020 window.SITE_CONFIG['businessApi'] = 'http://dev.ccwin-in.com:10097' -window.SITE_CONFIG['columnsApiNamesZh'] = 'Job' -window.SITE_CONFIG['isAutoLogin'] = true +//是否登录配置信息【loginName】 +window.SITE_CONFIG['isConfigLogin'] = false +//如果【isConfigLogin】为true则使用【loginName】登录 +window.SITE_CONFIG['configLoginName'] = 'admin' +// 默认登录密码(isConfigLogin为true或者链接参数存在loginName使用) +window.SITE_CONFIG['configLoginPass'] = '1q2w3E*' +// 是否单页面(不显示菜单头部等部分) window.SITE_CONFIG['isSinglePage'] = false -window.SITE_CONFIG['userNameOrEmailAddress'] = 'admin' -window.SITE_CONFIG['client_secret'] = '1q2w3E*' -window.SITE_CONFIG['browserTitle'] = 'JOB-QAD&WMS' +// 项目配置 +window.SITE_CONFIG['appClientId'] = 'Z_App' +// 项目配置内部名称 +window.SITE_CONFIG['appClientScope'] = 'Job' +// 浏览器名称 +window.SITE_CONFIG['browserTitle'] = 'Job-QAD&WMS' +// 单点登录使用数据 +window.SITE_CONFIG['oidcLogin_url'] = 'http://dev.ccwin-in.com:60065', +window.SITE_CONFIG['oidcLogin_clientId'] = 'InterfaceDash_App' +window.SITE_CONFIG['oidcLogin_scopes'] = 'offline_access Z profile' +// 隐藏的页面 window.SITE_CONFIG['menuHiddenConfig'] = [ 'CheckJobDetail','CountJobDetail','DeliverJobDetail', 'InspectJobDetail','IssueJobDetail','JisDeliverJobDetail', diff --git a/PC/UI.WinIn.FasterZ.Job/src/App.vue b/PC/UI.WinIn.FasterZ.Job/src/App.vue index bdc6eaf..a19d843 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/App.vue +++ b/PC/UI.WinIn.FasterZ.Job/src/App.vue @@ -10,15 +10,25 @@ export default { } localStorage.setItem('baseApi',window.SITE_CONFIG['baseApi']) localStorage.setItem('authApi',window.SITE_CONFIG['authApi']) -localStorage.setItem('userApi',window.SITE_CONFIG['userApi']) +// localStorage.setItem('userApi',window.SITE_CONFIG['userApi']) localStorage.setItem('businessApi',window.SITE_CONFIG['businessApi']) -localStorage.setItem('columnsApiNamesZh',window.SITE_CONFIG['columnsApiNamesZh']) -localStorage.setItem('isAutoLogin',window.SITE_CONFIG['isAutoLogin']) +localStorage.setItem('isConfigLogin',window.SITE_CONFIG['isConfigLogin']) +localStorage.setItem('configLoginName',window.SITE_CONFIG['configLoginName']) +localStorage.setItem('configLoginPass',window.SITE_CONFIG['configLoginPass']) localStorage.setItem('isSinglePage',window.SITE_CONFIG['isSinglePage']) -localStorage.setItem('userNameOrEmailAddress',window.SITE_CONFIG['userNameOrEmailAddress']) -localStorage.setItem('client_secret',window.SITE_CONFIG['client_secret']) -localStorage.setItem('menuHiddenConfig',window.SITE_CONFIG['menuHiddenConfig']) +localStorage.setItem('appClientId',window.SITE_CONFIG['appClientId']) +localStorage.setItem('appClientScope',window.SITE_CONFIG['appClientScope']) localStorage.setItem('browserTitle',window.SITE_CONFIG['browserTitle']) +// 单点登录使用数据 +localStorage.setItem('oidcLogin_url',window.SITE_CONFIG['oidcLogin_url']) +localStorage.setItem('oidcLogin_clientId',window.SITE_CONFIG['oidcLogin_clientId']) +localStorage.setItem('oidcLogin_scopes',window.SITE_CONFIG['oidcLogin_scopes']) +// 隐藏菜单 +localStorage.setItem('menuHiddenConfig',window.SITE_CONFIG['menuHiddenConfig']) + +// localStorage.setItem('isAutoLogin',window.SITE_CONFIG['isAutoLogin']) +// localStorage.setItem('userNameOrEmailAddress',window.SITE_CONFIG['userNameOrEmailAddress']) +// localStorage.setItem('client_secret',window.SITE_CONFIG['client_secret']) // 获取浏览器语言 const language_brow = (navigator.language || navigator.browserLanguage) diff --git a/PC/UI.WinIn.FasterZ.Job/src/api/wms-auth.js b/PC/UI.WinIn.FasterZ.Job/src/api/wms-auth.js index b4d2730..8b96a19 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/api/wms-auth.js +++ b/PC/UI.WinIn.FasterZ.Job/src/api/wms-auth.js @@ -1,47 +1,60 @@ import request from '@/utils/request' -let authApi = localStorage.getItem('authApi') + '/api' -let userApi = localStorage.getItem('userApi') +let baseApi = localStorage.getItem('baseApi') + '/api' +let authUrl = localStorage.getItem('authApi') +let authApi = authUrl + '/api' +export function logout() { + return request({ + url: authApi + '/account/logout', + method: 'get' + }) +} + + +// faster-new +// 登录 export function login(data) { return request({ - url: authApi + '/account/login', + url: authUrl + '/CustAccount/login', method: 'post', data }) } +// 获取token export function token(data) { return request({ url: authApi + '/connect/token', method: 'post', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, data }) } -export function logout() { +// 通过token获取用户信息(单点登录) +export function getUsersByToken(token) { return request({ - url: authApi + '/account/logout', - method: 'get' + url: authUrl + '/connect/userinfo', + method: 'get', + Token:token }) } - -// faster-new // 通过用户名获取用户信息 export function getUsersByUserName(name) { - let _api = userApi == 'undefined' ? authApi : userApi + '/api' return request({ - url: _api + '/identity/users/by-username/'+name, + url: authApi + '/identity/users/by-username/'+name, method: 'get', }) } - // 获取表头zh转义数据 export function getInterfaceBoard() { return request({ method:'get', - url: authApi + '/abp/application-localization', + url: baseApi + '/abp/application-localization', params:{ CultureName:localStorage.getItem('browserLanguage'), OnlyDynamics:false @@ -54,7 +67,7 @@ export function getInterfaceBoard() { export function getDefinitionMenu(IncludeTypes) { return request({ method:'get', - url: authApi + '/abp/application-configuration', + url: baseApi + '/abp/application-configuration', params:{IncludeLocalizationResources:true} }) } @@ -63,7 +76,132 @@ export function getDefinitionMenu(IncludeTypes) { export async function getApiDefinition() { return request({ method:'get', - url: authApi + '/abp/api-definition', + url: baseApi + '/abp/api-definition', params:{IncludeTypes:true} }) } + +// *************权限Roles页面维护************* +//获取列表 +export function getPageListRoles(data) { + return request({ + url: authApi + '/identity/roles', + // url: 'http://192.168.0.190:44330/Identity/Roles', + method: 'get', + params: data + }) +} + +//获取权限模板 +export function getPermissionsRoles(data) { + return request({ + url: authApi +'/permission-management/permissions', + method: 'get', + params: data + }) +} + +// 创建角色 +export function postCreateRoles(data) { + return request({ + url: authApi + '/identity/roles', + method: 'post', + data + }) +} + +//编辑角色 +export function postUpdateRoles(data, id) { + return request({ + url: authApi+'/identity/roles/' + id, + method: 'put', + data + }) +} + +//删除角色 +export function postDeleteRoles(id) { + return request({ + url: authApi + '/identity/roles/' + id, + method: 'delete', + }) +} + +//保存权限模板 +export function savePermissionsRoles(URL, data) { + return request({ + url: authApi + URL, + method: 'put', + data + }) +} + +// 更新权限 +export function updatePermissionsGranted(pname,pkey) { + return request({ + url: authApi + `/permissions/get-isGranted?name=demox&providerName=${pname}&providerKey=${pkey}`, + method: 'post', + }) +} + +// *************用户Users页面维护************* + +//获取全部用户信息 +export function getPageListUsers(data) { + return request({ + url: authApi + '/identity/users', + method: 'get', + params: data + }) +} + +//新建用户 +export function postCreateUser(data) { + return request({ + url: authApi + '/identity/users', + method: 'post', + data + }) +} + +//编辑用户 +export function postUpdateUser(data, id) { + return request({ + url: authApi + '/identity/users/' + id, + method: 'put', + data + }) +} + +//删除用户 +export function postDeleteUser(id) { + return request({ + url: authApi + '/identity/users/' + id, + method: 'delete', + }) +} + +// 获取当前用户的角色 +export function usersroles() { + return request({ + url: authApi + '/identity/users/assignable-roles', + method: 'get' + }) +} + +//获取当前角色 +export function getusersID(data) { + return request({ + url: authApi + '/identity/users/' + data + '/roles', + method: 'get' + }) +} + +//修改登录用户的密码-强密码规则 +export function postLoginUserInfo(data, id) { + return request({ + url: authApi + '/identity/users/change-password/' + id, + method: 'post', + data + }) +} \ No newline at end of file diff --git a/PC/UI.WinIn.FasterZ.Job/src/components/currenButton/innerButton.vue b/PC/UI.WinIn.FasterZ.Job/src/components/currenButton/innerButton.vue index aed6679..6d7d293 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/components/currenButton/innerButton.vue +++ b/PC/UI.WinIn.FasterZ.Job/src/components/currenButton/innerButton.vue @@ -16,6 +16,7 @@ }" :class="item.class" @click="tableButtonClick(item.name,item)" + v-permission="item.permission" >{{ item.label }} diff --git a/PC/UI.WinIn.FasterZ.Job/src/components/tablePagination/index.vue b/PC/UI.WinIn.FasterZ.Job/src/components/tablePagination/index.vue index afc8d66..a081346 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/components/tablePagination/index.vue +++ b/PC/UI.WinIn.FasterZ.Job/src/components/tablePagination/index.vue @@ -97,7 +97,7 @@ export default { noUsePermissionBtn:{ type: Array, default: () => { - return ['refresh','field'] + return ['refresh','field','export','filter']//刷新,字段设置,导出,筛选 } }, rowMaxHeight:{ @@ -307,7 +307,8 @@ export default { _list.push(item) }else{ if(this.noUsePermissionBtn.indexOf(item.name) < 0){ - item.permission = [this.$route.name+'.'+item.name] + let _scope = item.clientScope || localStorage.getItem('appClientScope') + item.permission = [_scope + '.' +this.$route.name+'.'+item.name] }else{ item.permission = [] } diff --git a/PC/UI.WinIn.FasterZ.Job/src/components/umyTable/index.vue b/PC/UI.WinIn.FasterZ.Job/src/components/umyTable/index.vue index aaad8fc..ab57c35 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/components/umyTable/index.vue +++ b/PC/UI.WinIn.FasterZ.Job/src/components/umyTable/index.vue @@ -167,6 +167,7 @@ :key="indexButton" type="text" size="mini" + v-permission="itemButton.permission" :style="{color:itemButton.color || '#409EFF'}" @click="buttonOperationClick_right(scope.row, itemButton, indexButton)" >{{itemButton.label}} @@ -212,8 +213,10 @@ import { formatTimeStrToStr } from "@/utils/formatTime"; import _ from "lodash"; import { getMatchRegConformValue } from "@/utils/index" import showCopyJsonPop from "@/components/showCopyJsonPop" +import permission from "@/directive/permission/index" export default { name: "currenTable", + directives: { permission }, components:{ showCopyJsonPop }, filters: { formatDate(time) { diff --git a/PC/UI.WinIn.FasterZ.Job/src/layout/components/Navbar.vue b/PC/UI.WinIn.FasterZ.Job/src/layout/components/Navbar.vue index 8545743..02bbe72 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/layout/components/Navbar.vue +++ b/PC/UI.WinIn.FasterZ.Job/src/layout/components/Navbar.vue @@ -1,5 +1,5 @@ @@ -36,9 +36,9 @@ 系统首页 - + 退出登录 @@ -57,6 +57,10 @@ import Screenfull from "@/components/Screenfull"; import SizeSelect from "@/components/SizeSelect"; import Search from "@/components/HeaderSearch"; import getPageTitle from '@/utils/get-page-title' +import { mgr } from "@/oidc/oidc-client"; +import { + logout, +} from '@/api/wms-auth' export default { components: { @@ -69,6 +73,7 @@ export default { }, data(){ return{ + fullscreenLoading:false, pageTitle:getPageTitle() } }, @@ -80,13 +85,21 @@ export default { this.$store.dispatch("app/toggleSideBar"); }, async logout() { - await this.$store.dispatch("user/logout") - // this.$router.push(`/login?redirect=${this.$route.fullPath}`); - // this.$router.push(`/login?redirect=${this.$route.fullPath}&isAutoLogin=false`) - this.$router.push(`/login?isAutoLogin=false`) + this.fullscreenLoading = true + this.$store.dispatch("user/logout") + // 如果有单点登录方式使用下方配置 + // mgr.signoutRedirect() + // mgr.signoutRedirectCallback() + // .then(() => { + // this.$store.dispatch("user/logout") + // }) + // .catch(function(error){ + // this.$message.error("退出登录失败,请重试") + // this.fullscreenLoading = false + // }) }, - handleClick() { + showProfileuser() { this.$router.push({ name: 'Profileuser'}); }, }, diff --git a/PC/UI.WinIn.FasterZ.Job/src/mixins/TableHeaderMixins.js b/PC/UI.WinIn.FasterZ.Job/src/mixins/TableHeaderMixins.js index 7d28f28..f468695 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/mixins/TableHeaderMixins.js +++ b/PC/UI.WinIn.FasterZ.Job/src/mixins/TableHeaderMixins.js @@ -67,11 +67,11 @@ export const TableHeaderMixins = { this.paging() // this.$store.dispatch("app/appMainLoading", true) } - // 新增(原始前端写死配置方式) - else if (val == 'newly') { + // 新增(原始前端写死配置) + else if (val == 'Create') { this.formTitle = "新增" + this.$route.meta.title; this.formReveal = true - this.theEvent = "newly" + this.theEvent = "Create" this.displayDialog.newDialog = true; } // Api新增(参数配置从api获取) @@ -290,7 +290,7 @@ export const TableHeaderMixins = { * list_api: 表头来自api的列表 detail_api: 表头来自api列表的明细 detailPage_api表头来自api的明细页面列表 * list: 表头固定的列表 detail: 表头固定列表的明细 */ - rowDrop(data,type) { + rowDrop(data,type) { if(!type || type == 'list_api'){ this.apiColumns_Table = data } if(type && type == 'detail_api'){ this.apiColumns_DetailsTable = data } // if(type && type == 'detailPage_api'){ this.apiColumns_DetailsPage = data } diff --git a/PC/UI.WinIn.FasterZ.Job/src/mixins/TableMixins.js b/PC/UI.WinIn.FasterZ.Job/src/mixins/TableMixins.js index 32dbdd5..1fab8af 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/mixins/TableMixins.js +++ b/PC/UI.WinIn.FasterZ.Job/src/mixins/TableMixins.js @@ -51,15 +51,19 @@ export const tableMixins = { }, methods: { // 主表-右侧操作列基础按钮 - buttonOperationList_rightBase(){ + buttonOperationList_rightBase(op_e,op_d){ return [{ label:'编辑', name:'edit', - color:'#ff9000' + color:'#ff9000', + hide:op_e && op_e.hide ? op_e.hide : false, + permission:op_e && op_e.permission ? op_e.permission : [] },{ label:'删除', name:'delete', - color:'red' + color:'red', + hide:op_d && op_d.hide ? op_d.hide : false, + permission:op_d && op_d.permission ? op_d.permission : [] }] }, // 主表-右侧操作列基础按钮 diff --git a/PC/UI.WinIn.FasterZ.Job/src/oidc/oidc-client.js b/PC/UI.WinIn.FasterZ.Job/src/oidc/oidc-client.js new file mode 100644 index 0000000..90058c3 --- /dev/null +++ b/PC/UI.WinIn.FasterZ.Job/src/oidc/oidc-client.js @@ -0,0 +1,21 @@ +import Oidc from "oidc-client"; + +export const identityServerBase = localStorage.getItem('oidcLogin_url');//目标服务器登录地址 +export const vueBase = window.location.origin + +// 参考文档 https://github.com/IdentityModel/oidc-client-js/wiki +export const mgr = new Oidc.UserManager({ + authority: `${identityServerBase}`, // 认证服务器 + client_id: localStorage.getItem('oidcLogin_clientId'), // 表示客户端的ID,必选项 + redirect_uri: `${vueBase}/callback`,// 表示重定向URI,认证服务器回调的客户端页面。可选项 + response_type: `code`, + scope: localStorage.getItem('oidcLogin_scopes'), // 表示申请的权限范围,可选项 + post_logout_redirect_uri: `${vueBase}/home?action=logout`, + automaticSilentRenew: false, + + // accessTokenExpiringNotificationTime: 10, + // filterProtocolClaims: false, + // loadUserInfo: true, + // monitorSession: false, + // includeIdTokenInSilentRenew : false, +}); \ No newline at end of file diff --git a/PC/UI.WinIn.FasterZ.Job/src/permission.js b/PC/UI.WinIn.FasterZ.Job/src/permission.js index 3c989cc..188ca74 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/permission.js +++ b/PC/UI.WinIn.FasterZ.Job/src/permission.js @@ -3,124 +3,181 @@ import store from './store' import { Message } from 'element-ui' import NProgress from 'nprogress' // progress bar import 'nprogress/nprogress.css' // progress bar style -import { getToken } from '@/utils/auth' // get token from cookie +import { getToken,removeToken } from '@/utils/auth' // get token from cookie import getPageTitle from '@/utils/get-page-title' -import { asyncRoutes } from '@/router' +import { mgr } from "@/oidc/oidc-client"; NProgress.configure({ showSpinner: false }) // NProgress Configuration -router.beforeEach(async (to, from, next) => { - // start progress bar - NProgress.start() - // set page title - document.title = getPageTitle() +const whiteList = ['/login','/callback'] // no redirect whitelist +const loginErr = '登录失败,请重新登录 !' +const getErrMsg = '数据获取失败 !' + + +// 退出登录处理 +const logoutHandle = (msg) => { + if(msg){ + Message.error(msg) + } + setTimeout(()=>{ + store.dispatch("user/logout") + },0) +} + +// 跳转登录页 +const pageToLogin = (to, from, next) => { + if (whiteList.indexOf(to.path) >= 0 ) { + // in the free login whitelist, go directly + next() + NProgress.done() + } else { + // other pages that do not have permission to access are redirected to the login page. + // removeToken() + store.dispatch('user/resetToken') + next(`/login?redirect=${to.path}`) + NProgress.done() + } +} + +// 首次进入页面加载数据处理 +const toPageInit = async (to, from, next) => { + // const hasToken = getToken() + // // 获取用户信息 + // // let _userName = localStorage.getItem("isLoginTokenName")//使用用户名获取 + // // if(_userName && _userName != null && (!store.getters.currentUserInfo || store.getters.currentUserInfo.length <= 0)){ + // // await store.dispatch('user/getUserInfo',_userName)//使用用户名获取 + // let _user_access = hasToken.substring(hasToken.indexOf(" ") + 1,hasToken.length) + // if(hasToken && hasToken != null && (!store.getters.currentUserInfo || store.getters.currentUserInfo.length <= 0)){ + // await store.dispatch('user/getUserInfoByToken',_user_access) + // .then(()=>{ + // toNextHandle(to, from, next) + // }) + // .catch(()=>{ + // // toNextHandle(to, from, next) + // Message.error(loginErr) + // pageToLogin(to, from, next) + // }) + // return + // } + if(getToken()){ + toNextHandle(to, from, next) + }else{ + logoutHandle('暂无token,请重新登录') + } + +} + +// 获取数据失败处理 +const getErrHandle = (to, from, next) => { + let isAutoLogin = JSON.parse(localStorage.getItem('isConfigLogin')) || to.query.loginName + Message.error(getErrMsg) + if(!isAutoLogin){ + logoutHandle() + } + NProgress.done() +} + + +// 跳转处理 +const toNextHandle = async (to, from, next) => { + let isFresh = false // 获取表头转义 - if(!store.getters.columZHList || store.getters.columZHList.length <= 0){ - await store.dispatch('definition/getColumZHList',()=>{ - NProgress.done() + if(!store.getters.columZHList){ + await store.dispatch('definition/getColumZHList').catch(()=>{ + getErrHandle(to, from, next) }) } - // 获取菜单数据 - if(!store.getters.permission_routes || store.getters.permission_routes.length <= 0){ - const accessRoutes = await store.dispatch('permission/getApiColumnsNames') - router.addRoutes(accessRoutes) + // 获取菜单数据 permission_routes + if(!store.getters.hasApiToken){ + isFresh = true + await store.dispatch('permission/getAppConfig') + .then((res)=>{ + // 没有权限(token失效处理) + if(!res || !res.auth || !res.auth.grantedPolicies || JSON.stringify(res.auth.grantedPolicies) == '{}'){ + logoutHandle('用户无权限或者token失效,请配置权限或重新登录') + } + }) + .catch(()=>{ + getErrHandle(to, from, next) + }) } // 获取枚举数据 if(!store.getters.enumList || store.getters.enumList.length <= 0){ - await store.dispatch('definition/getDefinitionConfig') + await store.dispatch('definition/getDefinitionConfig').catch(()=>{ + getErrHandle(to, from, next) + }) } - // 是否已尝试过自动登录 - const alreadyTryLogin = localStorage.getItem('alreadyTryLogin') - // 是否有用户信息: - const userInfo = store.getters.currentUserInfo - // 判断是否自动登录 - let isAutoLogin = JSON.parse(localStorage.getItem('isAutoLogin')) - // 如果路径中有isAutoLogin参数则优先,否则读取配置文件中的isAutoLogin参数 - let _url_isAutoLogin = to.query.isAutoLogin - if( _url_isAutoLogin== 'false' || _url_isAutoLogin == 'true'){ - isAutoLogin = JSON.parse(_url_isAutoLogin) - } - if(to.path == '/login'){ - console.log('-------当前路由为登录页-------') - next() + if(isFresh){ + next({...to,replace:true}) }else{ - console.log('-------当前路由不是登录页-------') - if((userInfo && userInfo.id) || alreadyTryLogin == 'true'){ - if(userInfo && userInfo.id){ - console.log('-------当前有用户信息-------',userInfo) + next() + } + NProgress.done() +} + +router.beforeEach(async (to, from, next) => { + + // start progress bar + NProgress.start() + // set page title + document.title = getPageTitle() + + const hasToken = getToken() + + // 判断是否自动登录 + let isAutoLogin = JSON.parse(localStorage.getItem('isConfigLogin')) || to.query.loginName + + if(hasToken || to.path == '/callback'){ + if (to.path === '/login') { + console.log('有token,是登录页,将跳转至/') + // if is logged in, redirect to the home page + next({ + path: '/' + }) + NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939 + } else { + if(to.path == '/callback'){ + console.log('有token,是callback页,next') + next() }else{ - console.log('-------当前没有用户信息,但是已尝试过登录-------') + console.log('有token,不是登录页,不是callback页,toPageInit') + await toPageInit(to, from, next) } - next() - }else{ - console.log('-------当前没有用户信息-------') - if(isAutoLogin || to.query.loginName){ - let _username = to.query.loginName || localStorage.getItem("isLoginName") || localStorage.getItem("userNameOrEmailAddress") - console.log('-------要求自动登录-------',isAutoLogin,to.query.loginName,_username) - // let loginForm= { - // userNameOrEmailAddress:localStorage.getItem("userNameOrEmailAddress"), - // password:localStorage.getItem("client_secret"), - // // rememberMe:true, - // // grant_type: 'password', - // // client_id: 'Auth_App', - // } - // // store.dispatch('user/login', loginForm).then(() => { - // login(loginForm).then(()=>{ - await store.dispatch('user/getUserInfo',_username).then(()=>{ - console.log("-------用户信息获取成功-------") - localStorage.setItem('alreadyTryLogin',true) - next(to) - // next({ - // ...to, - // query:{ - // loginName:to.query.loginName, - // isAutoLogin:to.query.isAutoLogin, - // isSinglePage:to.query.isSinglePage - // }, - // replace: true - // }) - }).catch(()=>{ - localStorage.setItem('alreadyTryLogin',true) - next() - // next({ - // path:'/login', - // query:{ - // isAutoLogin:to.query.isAutoLogin, - // isSinglePage:to.query.isSinglePage - // }, - // replace: true - // }) - // next(`/login?loginName=${to.query.loginName}&isAutoLogin=${to.query.isAutoLogin}`) - // next(`/login`) - localStorage.setItem("isLoginName",_username) - // Message.error('获取用户信息失败,请重试!') + } + }else{ + if (to.path === '/login') { + console.log('没有token,是登录页,pageToLogin') + pageToLogin(to, from, next) + } else { + // 如果有单点登录方式使用下方配置 + // mgr.signinRedirect(); //执行重定向 + + if(isAutoLogin){ + let _username = localStorage.getItem("isConfigLogin") && localStorage.getItem("isConfigLogin") != 'false' ? localStorage.getItem("configLoginName") : to.query.loginName + await store.dispatch('user/login', { + username:_username, + password:localStorage.getItem("configLoginPass") }) - // }) - // .catch((error) => { - // console.log('登录失败') - // }) + .then(()=>{ + toPageInit(to, from, next) + }) + .catch(()=>{ + // toNextHandle(to, from, next) + Message.error(loginErr) + pageToLogin(to, from, next) + }) }else{ - console.log('-------不需要自动登录-------',isAutoLogin,to.query.loginName) - next({ - path:'/login', - query:{ - loginName:to.query.loginName, - isAutoLogin:to.query.isAutoLogin, - isSinglePage:to.query.isSinglePage - }, - replace: true - }) + console.log('没有token,不是登录页,不是自动登录,pageToLogin') + pageToLogin(to, from, next) } } } - - localStorage.setItem('alreadyTryLogin',false) }) router.afterEach(() => { diff --git a/PC/UI.WinIn.FasterZ.Job/src/router/index.js b/PC/UI.WinIn.FasterZ.Job/src/router/index.js index eb7bdc3..a1459f1 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/router/index.js +++ b/PC/UI.WinIn.FasterZ.Job/src/router/index.js @@ -60,25 +60,29 @@ export let constantRoutes = [ component: () => import('@/views/error-page/401'), hidden: true }, + { + path: '/callback', + component: () => import('@/views/callback/index'), + hidden: true + }, { path: '/', component: Layout, - redirect: '/dashboard', + redirect: '/home', // hidden: true, children: [{ - path: 'dashboard', + path: 'home', component: () => import('@/views/dashboard/index'), - name: 'Dashboard', + name: 'Home', meta: { keepAlive : true, - // title: localStorage.getItem('browserLanguage') == 'zh-Hans' ? '系统首页' : 'Dashboard', title: i18n.t('common.home'), icon: 'svg_dashboard', outerFirst:true // affix: true } }] - }, + }, { path: '/', component: Layout, @@ -96,7 +100,41 @@ export let constantRoutes = [ // affix: true } }] - }, + }, + { + path: '/', + component: Layout, + redirect: '/profileuser', + hidden: true, + children: [{ + path: 'profileuser', + component: () => import('@/views/profileuser/index'), + name: 'Profileuser', + meta: { + title: '个人中心', + icon: 'user', + noCache: true + } + }] + }, + // { + // path: '/', + // component: Layout, + // redirect: '/RoleManage', + // hidden: true, + // children: [{ + // path: 'RoleManage', + // component: () => import('@/views/systemManage/RoleManage'), + // name: 'RoleManage', + // meta: { + // keepAlive : true, + // title: 'RoleManage', + // icon: 'svg_dashboard', + // outerFirst:true + // // affix: true + // } + // }] + // }, ] /** @@ -107,22 +145,20 @@ export let constantRoutes = [ export let asyncRoutes = [ /** when your routing map is too long, you can split it into small modules **/ // 404 page must be placed at the end !!! - // { - // path: '*', - // redirect: '/404', - // hidden: true - // } + { + path: '*', + redirect: '/404', + hidden: true + } ] const createRouter = () => new Router({ - // mode: 'history', // require service support + mode: 'hash', // 单点登录需要使用history,但是history会使线上nginx刷新404(需要确认及处理) scrollBehavior: () => ({ y: 0 }), - // todo-new:有token后使用去掉下一行代码 - routes: constantRoutes.concat(asyncRoutes) - // todo-new:有token后使打开下方代码,并检查是否有效 - // routes: constantRoutes + // routes: constantRoutes.concat(asyncRoutes) + routes: constantRoutes }) const router = createRouter() diff --git a/PC/UI.WinIn.FasterZ.Job/src/store/getters.js b/PC/UI.WinIn.FasterZ.Job/src/store/getters.js index 3205c47..7014692 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/store/getters.js +++ b/PC/UI.WinIn.FasterZ.Job/src/store/getters.js @@ -5,11 +5,11 @@ const getters = { loading: state => state.app.loading, visitedViews: state => state.tagsView.visitedViews, cachedViews: state => state.tagsView.cachedViews, - token: state => state.user.token, introduction: state => state.user.introduction, - roles: state => state.user.roles, + roles: state => state.permission.roles,//当前用户权限 currentUserInfo: state => state.user.userInfo,//当前用户信息 - permission_routes: state => state.permission.routes,//接口获取的菜单 + permission_routes: state => state.permission.routes,//全部菜单 + hasApiToken:state => state.permission.configApiToken,//配置config接口是否有权限 tablesName:state => state.permission.tablesName,//接口获取所有的表名 errorLogs: state => state.errorLog.logs, enumList: state => state.definition.enumList,//接口获取的枚举 diff --git a/PC/UI.WinIn.FasterZ.Job/src/store/modules/definition.js b/PC/UI.WinIn.FasterZ.Job/src/store/modules/definition.js index a016ce9..64acf97 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/store/modules/definition.js +++ b/PC/UI.WinIn.FasterZ.Job/src/store/modules/definition.js @@ -161,7 +161,7 @@ const actions = { return new Promise((resolve,reject) => { getInterfaceBoard() .then(res=>{ - let _zh = res.resources[localStorage.getItem('columnsApiNamesZh')].texts; + let _zh = res.resources[localStorage.getItem('appClientScope')].texts; commit('SET_COLUMZH_LIST', _zh) resolve(res) }) @@ -170,6 +170,13 @@ const actions = { reject(err) }) }) + }, + // 重置配置信息 + resetDefinition({ commit }) { + commit('SET_ENUM_LIST', []) + commit('SET_COLUMZH_LIST', null) + commit('SET_DTOCOLUMN_TYPES', []) + commit('SET_API_ACTIONS', []) } } diff --git a/PC/UI.WinIn.FasterZ.Job/src/store/modules/permission.js b/PC/UI.WinIn.FasterZ.Job/src/store/modules/permission.js index 1cbd7af..a64a675 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/store/modules/permission.js +++ b/PC/UI.WinIn.FasterZ.Job/src/store/modules/permission.js @@ -5,74 +5,34 @@ import { import Layout from '@/layout' import { getDefinitionMenu } from '@/api/wms-auth' import store from '@/store' +import router from '@/router' -/** - * Use meta.role to determine if the current user has permission - * @param roles - * @param route - */ -function hasPermission(roles, route) { - if (route.meta && route.meta.roles) { - if (route.meta.roles == "skip") { - return true - } else { - return roles.some(role => route.meta.roles.includes(role)) - } - } else { - return false - } -} -const filterAccessedRoutes = (items,indexVal,childrenIndex) => { - const route = JSON.parse(JSON.stringify(items)) - route.forEach((val, index) => { - // debugger; - if(val.meta && val.meta.roles == "skip"){ - if (val.children && val.children.length != 0) { - filterAccessedRoutes(items[index-indexVal].children,childrenIndex) - } - if(items[index-indexVal].children && items[index-indexVal].children.length == 0){ - items.splice(index-indexVal, 1) - indexVal++ - } - } - }) - indexVal = 0 -} -/** - * Filter asynchronous routing tables by recursion - * @param routes asyncRoutes - * @param roles - */ -export function filterAsyncRoutes(routes, roles) { - const res = [] - routes.forEach(route => { - const tmp = { - ...route - } - if (hasPermission(roles, tmp)) { - if (tmp.children) { - tmp.children = filterAsyncRoutes(tmp.children, roles) - } - res.push(tmp) - } - }) - return res -} +// 身份权限的页面标识(角色等) +const AbpIdentity_mark = 'AbpIdentityMark' const state = { routes: [],//菜单 - addRoutes: [], + roles: [],//当前用户权限 + configApiToken:false,//配置config接口是否有权限 tablesName:null,//所有的表名 } const mutations = { SET_ROUTES: (state, routes) => { - state.addRoutes = routes state.routes = constantRoutes.concat(routes) + router.addRoutes(routes) + }, + // 配置config接口是否为空(即没有权限) + SET_CONFIG_TOKEN: (state, data) => { + state.configApiToken = data + }, + // 设置权限(v-permission) + SET_ROLES: (state, roles) => { + state.roles = roles }, SET_TABLESNAME: (state, data) => { state.tablesName = data - } + }, } /** * 静态路由懒加载 @@ -92,28 +52,27 @@ export function generaMenu(routes, data, first) { let _noShowMenus = localStorage.getItem('menuHiddenConfig').split(',') data.forEach(item => { let _item = { - path: '/'+item.name, + path: item.path, component: loadView(item.name), hidden: _noShowMenus.indexOf(item.name) >= 0, // 状态为0的隐藏 name: item.name, - // meta: item.meta - meta: { - title: item.title, - icon: item.icon || 'svg_default', - roles: item.permission, - outerFirst:first - }, + meta: item.meta } let menu = _item - if(first && item.component == '@/layout'){ + // if(first && item.component == '@/layout'){ + if(first){ menu = { path: '/', component: Layout, redirect: '/' + item.name, - children: [], + // redirect: 'noRedirect', + } + if(item.children && item.children.length > 0){ + menu.meta=item.meta + }else{ + menu.children = [] + menu.children.push(_item) } - menu.children = [] - menu.children.push(_item) } // 一级菜单 二级菜单 特定属性 // if (item.component == '@/layout' || item.component == 'index') { @@ -134,6 +93,7 @@ export function generaMenu(routes, data, first) { // menu.hasOpen = false // 是否打开过,默认false // } if (item.children && item.children.length > 0) { + if(!menu.children)menu.children = [] generaMenu(menu.children, item.children) } // if (item.permission == 'skip' && item.children.length == 0) { @@ -147,9 +107,25 @@ export function generaMenu(routes, data, first) { export function initTreeMenusHandle(tree, list,first) { let _res = [] tree.forEach(item=>{ - if(list.indexOf(item.name) >= 0){ - item.title = store.getters.columZHList[item.name] || item.name - if(first)item.component = '@/layout' + if(list.indexOf(item.name) >= 0 || item.name.indexOf(AbpIdentity_mark) >= 0){ + if(item.name.indexOf(AbpIdentity_mark) >= 0){ + if(item.name == AbpIdentity_mark){ + item.title = '系统设置管理' + }else{ + let _name = item.name.substring(AbpIdentity_mark.length,item.name.length) + item.title = store.getters.columZHList[_name] || _name + } + }else{ + item.title = store.getters.columZHList[item.name] || item.name + } + item.path = '/'+item.name + item.meta={ + title: item.title, + icon: item.icon || 'svg_default', + // roles: item.permission, + outerFirst:first + } + // if(first)item.component = '@/layout' if (item.children && item.children.length > 0) { item.children = initTreeMenusHandle(item.children,list) } @@ -159,55 +135,75 @@ export function initTreeMenusHandle(tree, list,first) { return _res } const actions = { - getApiColumnsNames({ + // 设置权限 + resetUserRoles({commit}){ + commit('SET_ROUTES',[]) + commit('SET_ROLES', []) + commit('SET_TABLESNAME', null) + }, + + // 获取菜单数据 + getAppConfig({ commit }, userId) { return new Promise(resolve => { - let accessedRoutes = asyncRoutes - // accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) - // let indexVal = 0 - // let childrenIndex = 0 - // filterAccessedRoutes(accessedRoutes,indexVal,childrenIndex) - // commit('SET_ROUTES', accessedRoutes) - // resolve(accessedRoutes) getDefinitionMenu(true).then(res => { + // 存储当前用户信息 + store.dispatch('user/setUserInfo',res.currentUser) + let roles_arr = [] + if(!res.auth.grantedPolicies || JSON.stringify(res.auth.grantedPolicies) == '{}'){ + commit('SET_CONFIG_TOKEN',false) + }else{ + commit('SET_CONFIG_TOKEN',true) + } + for(let r in res.auth.grantedPolicies){ + if(res.auth.grantedPolicies[r])roles_arr.push(r) + } + commit('SET_ROLES', roles_arr) + let _allConfig = res.auth.grantedPolicies;//所有配置 let _menuList = []//接口获取所有的菜单 + let _AbpIdentity = []//接口获取所有的身份配置信息数据 for(let item in _allConfig){ let point_number = item.split('.').length - 1 // 只选择配置项中的数据 - if(point_number == 1 && item.substring(0,item.indexOf('.')) == localStorage.getItem('columnsApiNamesZh')){ + if(point_number == 1 && item.substring(0,item.indexOf('.')) == localStorage.getItem('appClientScope')){ _menuList.push(item.substring(item.indexOf('.') + 1,item.length)) - } + } + // 身份配置信息数据(用户、角色) + if(point_number == 1 && item.substring(0,item.indexOf('.')) == 'AbpIdentity'){ + _AbpIdentity.push(AbpIdentity_mark + item.substring(item.indexOf('.') + 1,item.length)) + } } // 存储所有的表名 commit('SET_TABLESNAME', _menuList) - // 数据模拟,todo-new:接口获取 + // 数据模拟,todo-faster:接口获取 let _treeMenusAll = null//树形菜单 // _treeMenusAll = [ // {name:"aaaaaaa"}, - // {name:"ExportCustomUserSetting" - // // ,children:[ - // // {name:'OutgoingDataHistory',children:[ - // // {name:'IncomingData',children:[ - // // {name:'OutgoingDataHistory'}, - // // {name:'IncomingData'}, - // // {name:'333333'}, - // // ]}, - // // {name:'eee1111-bbb',children:[ - // // {name:'ExportCustomUserSetting'}, - // // {name:'MessageReceive'}, - // // ]}, - // // ]}, - // // {name:'eee222'}, - // // {name:'eee333'}, - // // {name:'eee444'}, - // // {name:'eee555'}, - // // ] + // { + // name:"ExportCustomUserSetting1", + // children:[ + // {name:'ExportCustomUserSetting'}, + // {name:'OutgoingDataHistory' + // ,children:[ + // {name:"OutgoingDataHistory"}, + // {name:'IncomingData',children:[ + // {name:'IncomingDataHistory'}, + // {name:'IncomingData'}, + // {name:'333333'}, + // ]}, + // {name:'eee1111-bbb',children:[ + // {name:'IncomingDataHistory'}, + // {name:'MessageReceive'}, + // ]}, + // ]}, + // {name:'eee222'}, + // {name:'eee333'}, + // {name:'eee444'}, + // {name:'eee555'}, + // ] // }, - // {name:"OutgoingDataHistory"}, - // {name:"IncomingData"}, - // {name:"IncomingDataHistory"}, // {name:"MesProductL7PartsNote"}, // {name:"MessageReceive"}, // {name:"OutgoingData"}, @@ -231,30 +227,38 @@ const actions = { // {name:"VendPart"}, // {name:"Vend"}, // ] - - let _initTreeMenus = [] + + let _menuAndAbpList = [..._menuList,..._AbpIdentity]// 包含配置项中的业务菜单+身份权限菜单(角色用户等) + let _initTreeMenus = []//转义为树状结构 if(_treeMenusAll && _treeMenusAll.length > 0){ - _initTreeMenus = initTreeMenusHandle(_treeMenusAll,_menuList,true) + _initTreeMenus = initTreeMenusHandle(_treeMenusAll,_menuAndAbpList,true) }else{ let _data = [] - for(let i in _menuList){ - _data.push({name:_menuList[i]}) + // 自定义系统设置管理分级 + if(_AbpIdentity && _AbpIdentity.length > 0){ + _data.push({name:AbpIdentity_mark,children:[]}) } - _initTreeMenus = initTreeMenusHandle(_data,_menuList,true) + for(let i in _menuAndAbpList){ + if(_menuAndAbpList[i].indexOf(AbpIdentity_mark) >= 0){ + _data[0].children.push({ name:_menuAndAbpList[i] }) + } + else{ + _data.push({name:_menuAndAbpList[i]}) + } + } + _initTreeMenus = initTreeMenusHandle(_data,_menuAndAbpList,true) } // 最后查重+层级查重后的菜单 let _initEndMenus = generaMenu(asyncRoutes, _initTreeMenus,true) let accessedRoutes = _initEndMenus - // let indexVal = 0 - // let childrenIndex = 0 - // filterAccessedRoutes(accessedRoutes,indexVal,childrenIndex) commit('SET_ROUTES', accessedRoutes) - resolve(accessedRoutes) + resolve(res) }).catch(err => { console.log(err) }) }) }, + } export default { diff --git a/PC/UI.WinIn.FasterZ.Job/src/store/modules/user.js b/PC/UI.WinIn.FasterZ.Job/src/store/modules/user.js index bfbd08b..d21325f 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/store/modules/user.js +++ b/PC/UI.WinIn.FasterZ.Job/src/store/modules/user.js @@ -1,6 +1,8 @@ import { token, + login, logout, + getUsersByToken, getUsersByUserName } from '@/api/wms-auth' import { @@ -11,85 +13,124 @@ import { import router, { resetRouter } from '@/router' -import qs from 'qs' +import store from '@/store' +import { mgr } from "@/oidc/oidc-client"; const state = { - token: getToken(), introduction: '', - roles: [], userInfo:null } const mutations = { - SET_TOKEN: (state, token) => { - state.token = token - }, SET_INTRODUCTION: (state, introduction) => { state.introduction = introduction }, - // 设置权限(v-permission) - SET_ROLES: (state, roles) => { - let _roles = [ - 'IncomingDataHistory.filter', - 'IncomingData.export', - 'MesProductL7PartsNote.filter', - 'MesProductL7PartsNote.export' - ] - state.roles = _roles - }, SET_USERINFO: (state, data) => { state.userInfo = data } } +// 登录(token)成功后处理 +const loginSuccess = (type,token,username,resolve,reject) => { + let _type = type ? type : 'Bearer' + setToken(_type + ' ' + token) + localStorage.setItem('isLoginTokenName',username) + resolve() + // store.dispatch('user/getUserInfoByToken',token).then(()=>{ + // resolve() + // }).catch(()=>{ + // reject() + // }) + + // store.dispatch('user/getUserInfo',username).then(()=>{ + // resolve() + // }).catch(()=>{ + // reject() + // }) +} + +// 单点登录(token)成功后处理 +const loginSuccessBySignin = (res,resolve, reject,commit) => { + let _token = res.token_type + ' ' + res.access_token + setToken(_token) + store.dispatch('user/getUserInfoByToken',res.access_token).then(()=>{ + resolve() + }).catch(()=>{ + reject() + }) +} + const actions = { - // user login + // 设置当前用户 + setUserInfo({commit},data){ + commit('SET_USERINFO',data) + }, + + // 登录,需要密码 login({ - commit + commit, }, userInfo) { const { password, username, - company, - warehouseCode } = userInfo - let loginData = { - userNameOrEmailAddress: username, - password: password, - rememberMe: true - } - let parseData = JSON.parse(JSON.stringify(userInfo)) - delete parseData.warehouseCode - delete parseData.company - parseData.client_secret = window.SITE_CONFIG['client_secret'] - let tokenData = qs.stringify(parseData) return new Promise((resolve, reject) => { - // login(loginData).then(response => { - let params = { - password: password, - userNameOrEmailAddress: username + // let params = qs.stringify({ + // password: password, + // username: username, + // client_id:localStorage.getItem('appClientId'), + // scopes:localStorage.getItem('appClientScope'), + // grant_type:'password' + // }); + let params= { + name:username, + password: password } - token(params).then(response => { - const { - accessToken, - tokenType - } = response - if (accessToken == null) { - reject() + login(params).then(response => { + if (response && response.token) { + loginSuccess(null,response.token,username,resolve,reject,commit) } else { - commit('SET_TOKEN', accessToken) - setToken(tokenType + ' ' + accessToken) - resolve() + reject() } }).catch(error => { reject(error) }) + // token(params).then(response => { + // if (response.access_token == null) { + // reject() + // } else { + // loginSuccess(response,username,resolve,reject,commit) + // } // }).catch(error => { // reject(error) // }) }) }, + // 单点登录 + loginBySignin({ + commit, + }) { + return new Promise((resolve, reject) => { + mgr.signinRedirectCallback() + .then(() => { + mgr.getUser() + .then((res_token) => { + if(res_token){ + loginSuccessBySignin(res_token,resolve, reject,commit) + }else{ + mgr.signinRedirect(); //执行重定向 + } + }) + }) + .catch(function(e) { + // console.log('catch') + mgr.signinRedirect(); //执行重定向 + console.error("CallBack 错误信息" + e); + }); + }) + }, + // user logout logout({ commit, @@ -97,18 +138,17 @@ const actions = { }) { return new Promise((resolve, reject) => { // logout().then(() => { - commit('SET_TOKEN', '') - // commit('SET_USERINFO', null) - // removeToken() - // resetRouter() + dispatch('permission/resetUserRoles',null,{root:true}) + dispatch('definition/resetDefinition',null,{root:true}) + dispatch('tagsView/delAllViews', null, {root: true}).then(()=>{ + removeToken() + resetRouter() + resolve() + }) // reset visited views and cached views // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485 - dispatch('tagsView/delAllViews', null, { - root: true - }) - resolve() - // 防止路由叠加 - // location.reload() + // 防止路由叠加(打开后单点登录的退出无效),如果有单点登录方式关闭下方location.reload() + location.reload() // }).catch(error => { // reject(error) // }) @@ -120,8 +160,8 @@ const actions = { commit }) { return new Promise(resolve => { - commit('SET_TOKEN', '') - commit('SET_ROLES', []) + // commit('SET_ROLES', []) + localStorage.setItem('isLoginTokenName',null) removeToken() resolve() }) @@ -134,8 +174,6 @@ const actions = { return new Promise((resolve, reject) => { getUsersByUserName(username).then(res=>{ if(res && JSON.stringify(res).length > 0){ - localStorage.setItem('isLoginName',username) - // commit('SET_ROLES', res) commit('SET_USERINFO', res) resolve(res) }else{ @@ -148,6 +186,29 @@ const actions = { }) }) }, + + // get userInfo + getUserInfoByToken({ + commit + },access_token) { + return new Promise((resolve, reject) => { + getUsersByToken(access_token) + .then(info=>{ + if(info){ + let _info = info + _info.name = info.preferred_username + _info.id = info.sub + commit('SET_USERINFO', _info) + resolve(_info) + }else{ + reject('用户信息获取失败') + } + }) + .catch(err=>{ + reject(err) + }) + }) + }, } export default { @@ -155,4 +216,4 @@ export default { state, mutations, actions -} +} \ No newline at end of file diff --git a/PC/UI.WinIn.FasterZ.Job/src/utils/auth.js b/PC/UI.WinIn.FasterZ.Job/src/utils/auth.js index 45b74fa..94ccbff 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/utils/auth.js +++ b/PC/UI.WinIn.FasterZ.Job/src/utils/auth.js @@ -2,8 +2,6 @@ import Cookies from 'js-cookie' import store from '@/store' const TokenKey = 'Admin-Token' -const CompanyKey = 'Admin-Company' -const WarehouseCodeKey = 'Admin-WarehouseCode' export function getToken() { return Cookies.get(TokenKey) @@ -19,5 +17,6 @@ export function removeToken() { // fast-new export function getLoginName() { - return (store.getters.currentUserInfo && store.getters.currentUserInfo.name) ? store.getters.currentUserInfo.name : localStorage.getItem('isLoginName') -} \ No newline at end of file + let _name = (store.getters.currentUserInfo && store.getters.currentUserInfo.name) ? store.getters.currentUserInfo.name : localStorage.getItem('isLoginTokenName') + return (!_name || _name == 'null') ? null : _name +} diff --git a/PC/UI.WinIn.FasterZ.Job/src/utils/defaultButtons.js b/PC/UI.WinIn.FasterZ.Job/src/utils/defaultButtons.js index bbe5032..8dcf1c8 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/utils/defaultButtons.js +++ b/PC/UI.WinIn.FasterZ.Job/src/utils/defaultButtons.js @@ -13,7 +13,7 @@ export function defaultAddBtn(option) { type: "primary", icon: "el-icon-plus", label: i18n.t('btns.add'), - name: "newly", + name: "Create", size: "mini", background:"#31bb99" }) @@ -123,5 +123,6 @@ function __defaultBtnOption(option,specific){ isDetailExport:option && option.isDetailExport ? option.isDetailExport : false, isRedundance:option && option.isRedundance ? option.isRedundance : false, permission:option && option.permission ? option.permission : null, + clientScope:option && option.clientScope ? option.clientScope : null, } } \ No newline at end of file diff --git a/PC/UI.WinIn.FasterZ.Job/src/utils/request.js b/PC/UI.WinIn.FasterZ.Job/src/utils/request.js index b2965e0..1e1a39e 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/utils/request.js +++ b/PC/UI.WinIn.FasterZ.Job/src/utils/request.js @@ -20,7 +20,8 @@ service.interceptors.request.use( config => { // do something before request is sent - if (store.getters.token) { + // if (store.getters.token) { + if (getToken() && getToken() != null) { // let each request carry token // ['X-Token'] is a custom headers key // please modify it according to the actual situation @@ -92,12 +93,12 @@ service.interceptors.response.use( }, error => { // if(!error.response || !error.response.data){ - // // Message({ - // // message: '访问出错,请重试', - // // type: 'error', - // // duration: 5 * 1000, - // // showClose:true - // // }) + // Message({ + // message: '访问出错,请重试', + // type: 'error', + // duration: 5 * 1000, + // showClose:true + // }) // return Promise.reject(error) // } let err = error.response.data.error // for debug diff --git a/PC/UI.WinIn.FasterZ.Job/src/views/callback/index.vue b/PC/UI.WinIn.FasterZ.Job/src/views/callback/index.vue new file mode 100644 index 0000000..3db1e22 --- /dev/null +++ b/PC/UI.WinIn.FasterZ.Job/src/views/callback/index.vue @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/PC/UI.WinIn.FasterZ.Job/src/views/dashboard/index.vue b/PC/UI.WinIn.FasterZ.Job/src/views/dashboard/index.vue index a099f66..82c17a6 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/views/dashboard/index.vue +++ b/PC/UI.WinIn.FasterZ.Job/src/views/dashboard/index.vue @@ -27,24 +27,31 @@ export default { ]) }, mounted(){ - this.initData(this.permission_routes) + let _menus = JSON.parse(JSON.stringify(this.permission_routes)) + let _showList = _menus.filter(item=>{ + return !item.hidden + }) + this.navList = this.initData(_showList,true) }, methods:{ - initData(data){ + initData(data,first){ + let _list = [] data.forEach(item => { - if(!item.hidden && item.path !== '/' && item.meta) { - let _item = { - title:item.meta.title, - name:item.name, - path:item.path, - children:item.children - } - this.navList.push(_item) + // 多层数据 + if(item.meta){ + item.title = item.meta.title + _list.push(item) } - if(!item.hidden && item.children){ - this.initData(item.children) + // 默认为单层 + else{ + if(item.children && item.children.length > 0)_list.push(item.children[0]) } + if(item.children && item.children.length > 0)item.children = this.initData(item.children) + }); + _list = _list.filter(item=>{ + return !item.hidden }) + return _list }, goPage(item){ this.$router.push({name: item.name}) diff --git a/PC/UI.WinIn.FasterZ.Job/src/views/error-page/401.vue b/PC/UI.WinIn.FasterZ.Job/src/views/error-page/401.vue index a52ed23..57d42d4 100644 --- a/PC/UI.WinIn.FasterZ.Job/src/views/error-page/401.vue +++ b/PC/UI.WinIn.FasterZ.Job/src/views/error-page/401.vue @@ -14,7 +14,7 @@