Compare commits
	
		
			1 Commits 
		
	
	
		
			master
			...
			x-20250106
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								 | 
						a4d103790d | 
| 
						 | 
					@ -37,7 +37,7 @@ onMounted(() => {
 | 
				
			||||||
  }, 1000 * 2)
 | 
					  }, 1000 * 2)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
const showMainApp = computed(() => {
 | 
					const showMainApp = computed(() => {
 | 
				
			||||||
  return ['/login', '/sso', '/lockme', '/redirect', '/404', '/license'].includes(route.path)
 | 
					  return ['/login', '/caslogin', '/sso', '/lockme', '/redirect', '/404', '/license'].includes(route.path)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style lang="scss">
 | 
					<style lang="scss">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
@media screen and(-ms-high-contrast:active),
 | 
					@media screen and (-ms-high-contrast:active),
 | 
				
			||||||
(-ms-high-contrast:none) {
 | 
					(-ms-high-contrast:none) {
 | 
				
			||||||
    .el-table__header,
 | 
					    .el-table__header,
 | 
				
			||||||
    .el-table__body {
 | 
					    .el-table__body {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,169 +1,176 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <a-dropdown>
 | 
					  <a-dropdown>
 | 
				
			||||||
    <div class="user-content">
 | 
					    <div class="user-content">
 | 
				
			||||||
      <img :src="userData.portrait" class="head-portrait" />
 | 
					      <img :src="userData.portrait" class="head-portrait" />
 | 
				
			||||||
      <span class="user-name">{{ userData.name }}</span>
 | 
					      <span class="user-name">{{ userData.name }}</span>
 | 
				
			||||||
      <DownOutlined />
 | 
					      <DownOutlined />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <template #overlay>
 | 
					    <template #overlay>
 | 
				
			||||||
      <a-menu class="user-dropdown">
 | 
					      <a-menu class="user-dropdown">
 | 
				
			||||||
        <a-menu-item @click="openInfoDialog" class="menu-item"> <UserOutlined /> 个人信息 </a-menu-item>
 | 
					        <a-menu-item @click="openInfoDialog" class="menu-item"> <UserOutlined /> 个人信息 </a-menu-item>
 | 
				
			||||||
        <a-menu-item @click="openPwdDialog" class="menu-item"> <LockOutlined /> 修改密码 </a-menu-item>
 | 
					        <a-menu-item @click="openPwdDialog" class="menu-item"> <LockOutlined /> 修改密码 </a-menu-item>
 | 
				
			||||||
        <a-menu-item @click="logoutSystem()" class="menu-item"> <PoweroffOutlined /> 退出系统 </a-menu-item>
 | 
					        <a-menu-item @click="logoutSystem()" class="menu-item"> <PoweroffOutlined /> 退出系统 </a-menu-item>
 | 
				
			||||||
      </a-menu>
 | 
					      </a-menu>
 | 
				
			||||||
    </template>
 | 
					    </template>
 | 
				
			||||||
  </a-dropdown>
 | 
					  </a-dropdown>
 | 
				
			||||||
  <a-modal title="修改密码" :maskClosable="false" width="600px" v-if="pwdDialogVisible" v-model:visible="pwdDialogVisible" @ok="modifyPwdSubmit" :confirmLoading="loading">
 | 
					  <a-modal title="修改密码" :maskClosable="false" width="600px" v-if="pwdDialogVisible" v-model:visible="pwdDialogVisible" @ok="modifyPwdSubmit" :confirmLoading="loading">
 | 
				
			||||||
    <a-form :model="pwdData" ref="pwdRef" :colon="true" :labelCol="{ span: 4 }">
 | 
					    <a-form :model="pwdData" ref="pwdRef" :colon="true" :labelCol="{ span: 4 }">
 | 
				
			||||||
      <a-form-item label="原密码" name="oldPassword" :rules="[required]">
 | 
					      <a-form-item label="原密码" name="oldPassword" :rules="[required]">
 | 
				
			||||||
        <a-input-password v-model:value="pwdData.oldPassword" auto-complete="off"></a-input-password>
 | 
					        <a-input-password v-model:value="pwdData.oldPassword" auto-complete="off"></a-input-password>
 | 
				
			||||||
      </a-form-item>
 | 
					      </a-form-item>
 | 
				
			||||||
      <a-form-item label="新密码" name="newPassword" :rules="pwdRule">
 | 
					      <a-form-item label="新密码" name="newPassword" :rules="pwdRule">
 | 
				
			||||||
        <a-input-password v-model:value="pwdData.newPassword" auto-complete="off"></a-input-password>
 | 
					        <a-input-password v-model:value="pwdData.newPassword" auto-complete="off"></a-input-password>
 | 
				
			||||||
      </a-form-item>
 | 
					      </a-form-item>
 | 
				
			||||||
      <a-form-item label="确认密码" name="confirmPassword" :rules="pwdRule">
 | 
					      <a-form-item label="确认密码" name="confirmPassword" :rules="pwdRule">
 | 
				
			||||||
        <a-input-password v-model:value="pwdData.confirmPassword" auto-complete="off"></a-input-password>
 | 
					        <a-input-password v-model:value="pwdData.confirmPassword" auto-complete="off"></a-input-password>
 | 
				
			||||||
      </a-form-item>
 | 
					      </a-form-item>
 | 
				
			||||||
    </a-form>
 | 
					    </a-form>
 | 
				
			||||||
  </a-modal>
 | 
					  </a-modal>
 | 
				
			||||||
  <InfoDialog ref="infoRef" :data="userData"></InfoDialog>
 | 
					  <InfoDialog ref="infoRef" :data="userData"></InfoDialog>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import crypto from 'utils/crypto.js'
 | 
					import crypto from 'utils/crypto.js'
 | 
				
			||||||
import { changePassword } from '@/services/manager'
 | 
					import { changePassword } from '@/services/manager'
 | 
				
			||||||
import { logout } from 'services'
 | 
					import { logout } from 'services'
 | 
				
			||||||
import InfoDialog from './InfoDialog.vue'
 | 
					import { getCasConfig } from '@/store/utils'
 | 
				
			||||||
import { computed, defineComponent, ref, createVNode } from 'vue'
 | 
					import InfoDialog from './InfoDialog.vue'
 | 
				
			||||||
import { message, Modal } from 'ant-design-vue'
 | 
					import { computed, defineComponent, ref, createVNode } from 'vue'
 | 
				
			||||||
import { useStore } from 'vuex'
 | 
					import { message, Modal } from 'ant-design-vue'
 | 
				
			||||||
import { required, complexPassword } from '@/validate'
 | 
					import { useStore } from 'vuex'
 | 
				
			||||||
import { UserOutlined, PoweroffOutlined, LockOutlined, ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons-vue'
 | 
					import { required, complexPassword } from '@/validate'
 | 
				
			||||||
 | 
					import { UserOutlined, PoweroffOutlined, LockOutlined, ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons-vue'
 | 
				
			||||||
export default defineComponent({
 | 
					
 | 
				
			||||||
  components: { InfoDialog, UserOutlined, PoweroffOutlined, LockOutlined, DownOutlined },
 | 
					export default defineComponent({
 | 
				
			||||||
  setup() {
 | 
					  components: { InfoDialog, UserOutlined, PoweroffOutlined, LockOutlined, DownOutlined },
 | 
				
			||||||
    const store = useStore()
 | 
					  setup() {
 | 
				
			||||||
    // 密码修改
 | 
					    const store = useStore()
 | 
				
			||||||
    const pwdData = ref({
 | 
					    // 密码修改
 | 
				
			||||||
      oldPassword: '',
 | 
					    const pwdData = ref({
 | 
				
			||||||
      newPassword: '',
 | 
					      oldPassword: '',
 | 
				
			||||||
      confirmPassword: ''
 | 
					      newPassword: '',
 | 
				
			||||||
    })
 | 
					      confirmPassword: ''
 | 
				
			||||||
    const pwdDialogVisible = ref(false)
 | 
					    })
 | 
				
			||||||
    function openPwdDialog() {
 | 
					    const pwdDialogVisible = ref(false)
 | 
				
			||||||
      pwdDialogVisible.value = true
 | 
					    function openPwdDialog() {
 | 
				
			||||||
      pwdData.value = {
 | 
					      pwdDialogVisible.value = true
 | 
				
			||||||
        oldPassword: '',
 | 
					      pwdData.value = {
 | 
				
			||||||
        newPassword: '',
 | 
					        oldPassword: '',
 | 
				
			||||||
        confirmPassword: ''
 | 
					        newPassword: '',
 | 
				
			||||||
      }
 | 
					        confirmPassword: ''
 | 
				
			||||||
    }
 | 
					      }
 | 
				
			||||||
    function checkPassword() {
 | 
					    }
 | 
				
			||||||
      const { newPassword, oldPassword, confirmPassword } = pwdData.value
 | 
					    function checkPassword() {
 | 
				
			||||||
      if (newPassword === oldPassword) {
 | 
					      const { newPassword, oldPassword, confirmPassword } = pwdData.value
 | 
				
			||||||
        message.error('新密码不能与原密码相同')
 | 
					      if (newPassword === oldPassword) {
 | 
				
			||||||
        return false
 | 
					        message.error('新密码不能与原密码相同')
 | 
				
			||||||
      }
 | 
					        return false
 | 
				
			||||||
      if (confirmPassword !== newPassword) {
 | 
					      }
 | 
				
			||||||
        message.error('确认密码与新密码不一致')
 | 
					      if (confirmPassword !== newPassword) {
 | 
				
			||||||
        return false
 | 
					        message.error('确认密码与新密码不一致')
 | 
				
			||||||
      }
 | 
					        return false
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      return true
 | 
					
 | 
				
			||||||
    }
 | 
					      return true
 | 
				
			||||||
    const pwdRef = ref()
 | 
					    }
 | 
				
			||||||
    const loading = ref(false)
 | 
					    const pwdRef = ref()
 | 
				
			||||||
    async function modifyPwdSubmit() {
 | 
					    const loading = ref(false)
 | 
				
			||||||
      try {
 | 
					    async function modifyPwdSubmit() {
 | 
				
			||||||
        const values = await pwdRef.value.validate()
 | 
					      try {
 | 
				
			||||||
        if (!checkPassword()) return
 | 
					        const values = await pwdRef.value.validate()
 | 
				
			||||||
        loading.value = true
 | 
					        if (!checkPassword()) return
 | 
				
			||||||
        const res = await changePassword(userData.value.id, {
 | 
					        loading.value = true
 | 
				
			||||||
          password: crypto.encrypt(values.newPassword),
 | 
					        const res = await changePassword(userData.value.id, {
 | 
				
			||||||
          oldPassword: crypto.encrypt(values.oldPassword)
 | 
					          password: crypto.encrypt(values.newPassword),
 | 
				
			||||||
        })
 | 
					          oldPassword: crypto.encrypt(values.oldPassword)
 | 
				
			||||||
        if (res.success) {
 | 
					        })
 | 
				
			||||||
          pwdDialogVisible.value = false
 | 
					        if (res.success) {
 | 
				
			||||||
          message.success(res.message)
 | 
					          pwdDialogVisible.value = false
 | 
				
			||||||
          store.dispatch('permission/ResetRoutes')
 | 
					          message.success(res.message)
 | 
				
			||||||
        }
 | 
					          store.dispatch('permission/ResetRoutes')
 | 
				
			||||||
      } catch (error) {
 | 
					        }
 | 
				
			||||||
        console.log(error)
 | 
					      } catch (error) {
 | 
				
			||||||
      }
 | 
					        console.log(error)
 | 
				
			||||||
      loading.value = false
 | 
					      }
 | 
				
			||||||
    }
 | 
					      loading.value = false
 | 
				
			||||||
    const userData = computed(() => store.getters.userData || {})
 | 
					    }
 | 
				
			||||||
    const pwdRule = computed(() => {
 | 
					    const userData = computed(() => store.getters.userData || {})
 | 
				
			||||||
      const rule = store.state.app.systemConfig.pwdStrength
 | 
					    const pwdRule = computed(() => {
 | 
				
			||||||
      if (rule === 'required') return [required]
 | 
					      const rule = store.state.app.systemConfig.pwdStrength
 | 
				
			||||||
      return [required, complexPassword]
 | 
					      if (rule === 'required') return [required]
 | 
				
			||||||
    })
 | 
					      return [required, complexPassword]
 | 
				
			||||||
    // 登出
 | 
					    })
 | 
				
			||||||
    function logoutSystem() {
 | 
					    // 登出
 | 
				
			||||||
      Modal.confirm({
 | 
					    function logoutSystem() {
 | 
				
			||||||
        title: '提示',
 | 
					      Modal.confirm({
 | 
				
			||||||
        icon: createVNode(ExclamationCircleOutlined),
 | 
					        title: '提示',
 | 
				
			||||||
        content: '您确定要退出该系统吗?',
 | 
					        icon: createVNode(ExclamationCircleOutlined),
 | 
				
			||||||
        async onOk() {
 | 
					        content: '您确定要退出该系统吗?',
 | 
				
			||||||
          const res = await logout()
 | 
					        async onOk() {
 | 
				
			||||||
          if (res.success) {
 | 
					          const { isCASLogin, casLogoutPath } = await getCasConfig()
 | 
				
			||||||
            store.dispatch('permission/ResetRoutes')
 | 
					          if (isCASLogin) {
 | 
				
			||||||
          }
 | 
					            location.href = casLogoutPath
 | 
				
			||||||
        }
 | 
					          } else {
 | 
				
			||||||
      })
 | 
					            const res = await logout()
 | 
				
			||||||
    }
 | 
					            if (res.success) {
 | 
				
			||||||
    // 个人信息
 | 
					              await store.dispatch('permission/ResetRoutes', false)
 | 
				
			||||||
    const infoRef = ref()
 | 
					              location.href = '/login'
 | 
				
			||||||
    function openInfoDialog() {
 | 
					            }
 | 
				
			||||||
      infoRef.value.open()
 | 
					          }
 | 
				
			||||||
    }
 | 
					        }
 | 
				
			||||||
    return {
 | 
					      })
 | 
				
			||||||
      loading,
 | 
					    }
 | 
				
			||||||
      pwdData,
 | 
					    // 个人信息
 | 
				
			||||||
      pwdDialogVisible,
 | 
					    const infoRef = ref()
 | 
				
			||||||
      pwdRef,
 | 
					    function openInfoDialog() {
 | 
				
			||||||
      pwdRule,
 | 
					      infoRef.value.open()
 | 
				
			||||||
      openPwdDialog,
 | 
					    }
 | 
				
			||||||
      modifyPwdSubmit,
 | 
					    return {
 | 
				
			||||||
      logoutSystem,
 | 
					      loading,
 | 
				
			||||||
      infoRef,
 | 
					      pwdData,
 | 
				
			||||||
      openInfoDialog,
 | 
					      pwdDialogVisible,
 | 
				
			||||||
      userData,
 | 
					      pwdRef,
 | 
				
			||||||
      required
 | 
					      pwdRule,
 | 
				
			||||||
    }
 | 
					      openPwdDialog,
 | 
				
			||||||
  }
 | 
					      modifyPwdSubmit,
 | 
				
			||||||
})
 | 
					      logoutSystem,
 | 
				
			||||||
</script>
 | 
					      infoRef,
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					      openInfoDialog,
 | 
				
			||||||
.user-content {
 | 
					      userData,
 | 
				
			||||||
  margin-right: 10px;
 | 
					      required
 | 
				
			||||||
  display: flex;
 | 
					    }
 | 
				
			||||||
  align-items: center;
 | 
					  }
 | 
				
			||||||
  cursor: pointer;
 | 
					})
 | 
				
			||||||
  .head-portrait {
 | 
					</script>
 | 
				
			||||||
    display: inline-block;
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
    width: 24px;
 | 
					.user-content {
 | 
				
			||||||
    height: 24px;
 | 
					  margin-right: 10px;
 | 
				
			||||||
    border-radius: 50%;
 | 
					  display: flex;
 | 
				
			||||||
  }
 | 
					  align-items: center;
 | 
				
			||||||
}
 | 
					  cursor: pointer;
 | 
				
			||||||
.user-name {
 | 
					  .head-portrait {
 | 
				
			||||||
  max-width: 140px;
 | 
					    display: inline-block;
 | 
				
			||||||
  white-space: nowrap;
 | 
					    width: 24px;
 | 
				
			||||||
  overflow: hidden;
 | 
					    height: 24px;
 | 
				
			||||||
  text-overflow: ellipsis;
 | 
					    border-radius: 50%;
 | 
				
			||||||
  font-size: 14px;
 | 
					  }
 | 
				
			||||||
  margin: 0 2px 0 5px;
 | 
					}
 | 
				
			||||||
}
 | 
					.user-name {
 | 
				
			||||||
.user-dropdown {
 | 
					  max-width: 140px;
 | 
				
			||||||
  background: #2c2e3b;
 | 
					  white-space: nowrap;
 | 
				
			||||||
  border-color: #2c2e3b;
 | 
					  overflow: hidden;
 | 
				
			||||||
  ::v-deep(.ant-dropdown-menu-item) {
 | 
					  text-overflow: ellipsis;
 | 
				
			||||||
    color: #ccc;
 | 
					  font-size: 14px;
 | 
				
			||||||
    &:hover {
 | 
					  margin: 0 2px 0 5px;
 | 
				
			||||||
      background: #2d8cf0 !important;
 | 
					}
 | 
				
			||||||
      color: #fff;
 | 
					.user-dropdown {
 | 
				
			||||||
    }
 | 
					  background: #2c2e3b;
 | 
				
			||||||
  }
 | 
					  border-color: #2c2e3b;
 | 
				
			||||||
}
 | 
					  ::v-deep(.ant-dropdown-menu-item) {
 | 
				
			||||||
</style>
 | 
					    color: #ccc;
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: #2d8cf0 !important;
 | 
				
			||||||
 | 
					      color: #fff;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,52 +1,81 @@
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Created by HaijunZhang on 2018/11/12.
 | 
					 * Created by HaijunZhang on 2018/11/12.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
import store from './store'
 | 
					import store from './store'
 | 
				
			||||||
import router from './router'
 | 
					import router from './router'
 | 
				
			||||||
import { getToken, setToken } from 'utils/auth'
 | 
					import { getToken, setToken } from 'utils/auth'
 | 
				
			||||||
import { getQuery } from 'utils'
 | 
					import { getQuery } from 'utils'
 | 
				
			||||||
import { isEmpty, assign } from 'lodash-es'
 | 
					import { isEmpty, assign } from 'lodash-es'
 | 
				
			||||||
 | 
					import { getCasConfig, goLogin } from './store/utils'
 | 
				
			||||||
const { token } = getQuery(location.hash)
 | 
					
 | 
				
			||||||
if (token) {
 | 
					const redirectToCasLogin = (to, next, ticket, casLoginPath) => {
 | 
				
			||||||
  setToken(token)
 | 
					  if (!ticket) {
 | 
				
			||||||
}
 | 
					    location.href = casLoginPath
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
const whiteList = ['/login', '/404', '/401', '/license', '/sso']
 | 
					  }
 | 
				
			||||||
router.beforeEach(async (to, from, next) => {
 | 
					  if (to.path === '/caslogin') {
 | 
				
			||||||
  if (isEmpty(history.state.current)) {
 | 
					    next()
 | 
				
			||||||
    assign(history.state, { current: from.fullPath })
 | 
					    return
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (getToken()) {
 | 
					  next(`/caslogin?ticket=${ticket}`)
 | 
				
			||||||
    // 判断用户是否处于登录状态
 | 
					}
 | 
				
			||||||
    if (to.path === '/login') {
 | 
					
 | 
				
			||||||
      // 如果已经登录重定向到主页
 | 
					const { token } = getQuery(location.hash)
 | 
				
			||||||
      await store.dispatch('permission/ResetRoutes', false)
 | 
					if (token) {
 | 
				
			||||||
      next('/login')
 | 
					  setToken(token)
 | 
				
			||||||
    } else {
 | 
					}
 | 
				
			||||||
      // 为null的场景: 刷新页面或者新开窗口;
 | 
					
 | 
				
			||||||
      const addRoutes = store.getters.addRoutes
 | 
					const whiteList = ['/login', '/caslogin', '/404', '/401', '/license', '/sso']
 | 
				
			||||||
      if (addRoutes) {
 | 
					router.beforeEach(async (to, from, next) => {
 | 
				
			||||||
        next()
 | 
					  const ticket = to.query.ticket || new URLSearchParams(location.search).get('ticket')
 | 
				
			||||||
      } else {
 | 
					  if (isEmpty(history.state.current)) {
 | 
				
			||||||
        try {
 | 
					    assign(history.state, { current: from.fullPath })
 | 
				
			||||||
          await store.dispatch('permission/GenerateRoutes')
 | 
					  }
 | 
				
			||||||
          store.dispatch('GetUserInfo')
 | 
					  if (getToken()) {
 | 
				
			||||||
          next({ ...to, replace: true })
 | 
					    // 判断用户是否处于登录状态
 | 
				
			||||||
        } catch (error) {
 | 
					    if (to.path === '/login' || to.path === '/caslogin') {
 | 
				
			||||||
          // remove token and go to login page to re-login
 | 
					      // 如果已经登录重定向到主页
 | 
				
			||||||
          await store.dispatch('permission/ResetRoutes', false)
 | 
					      await store.dispatch('permission/ResetRoutes', false)
 | 
				
			||||||
          next('/login')
 | 
					      const { isCASLogin, casLoginPath } = await getCasConfig()
 | 
				
			||||||
        }
 | 
					      if (!isCASLogin) {
 | 
				
			||||||
      }
 | 
					        next('/login')
 | 
				
			||||||
    }
 | 
					      } else {
 | 
				
			||||||
  } else {
 | 
					        redirectToCasLogin(to, next, ticket, casLoginPath)
 | 
				
			||||||
    // 用户没有登录
 | 
					      }
 | 
				
			||||||
    if (whiteList.includes(to.path)) {
 | 
					    } else {
 | 
				
			||||||
      // 在白名单里直接跳转
 | 
					      // 为null的场景: 刷新页面或者新开窗口;
 | 
				
			||||||
      next()
 | 
					      const addRoutes = store.getters.addRoutes
 | 
				
			||||||
    } else {
 | 
					      if (addRoutes) {
 | 
				
			||||||
      next('/login')
 | 
					        next()
 | 
				
			||||||
    }
 | 
					      } else {
 | 
				
			||||||
  }
 | 
					        try {
 | 
				
			||||||
})
 | 
					          await store.dispatch('permission/GenerateRoutes')
 | 
				
			||||||
 | 
					          store.dispatch('GetUserInfo')
 | 
				
			||||||
 | 
					          next({ ...to, replace: true })
 | 
				
			||||||
 | 
					        } catch (error) {
 | 
				
			||||||
 | 
					          // remove token and go to login page to re-login
 | 
				
			||||||
 | 
					          await store.dispatch('permission/ResetRoutes', false)
 | 
				
			||||||
 | 
					          const { isCASLogin, casLoginPath } = await getCasConfig()
 | 
				
			||||||
 | 
					          if (!isCASLogin) {
 | 
				
			||||||
 | 
					            next('/login')
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            redirectToCasLogin(to, next, ticket, casLoginPath)
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    // 用户没有登录
 | 
				
			||||||
 | 
					    if (whiteList.includes(to.path)) {
 | 
				
			||||||
 | 
					      // 在白名单里直接跳转
 | 
				
			||||||
 | 
					      const { isCASLogin, casLoginPath } = await getCasConfig()
 | 
				
			||||||
 | 
					      if (!isCASLogin) {
 | 
				
			||||||
 | 
					        next()
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        redirectToCasLogin(to, next, ticket, casLoginPath)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      goLogin()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,12 @@ const routes: RouteRecordRaw[] = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    name: 'Login',
 | 
					    name: 'Login',
 | 
				
			||||||
    path: '/login',
 | 
					    path: '/login',
 | 
				
			||||||
    component: () => import('views/login/login.vue')
 | 
					    component: () => import('views/login/userLogin.vue')
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    name: 'CASLogin',
 | 
				
			||||||
 | 
					    path: '/caslogin',
 | 
				
			||||||
 | 
					    component: () => import('views/login/casLogin.vue')
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    path: '/sso',
 | 
					    path: '/sso',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,10 @@
 | 
				
			||||||
import request from 'utils/request'
 | 
					import request from 'utils/request'
 | 
				
			||||||
import { wrapperParams } from 'utils'
 | 
					import { wrapperParams } from 'utils'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function loginByCas(params) {
 | 
				
			||||||
 | 
					  return request.post('/sms/v1/users/login/cas', wrapperParams(params))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function login(params) {
 | 
					export function login(params) {
 | 
				
			||||||
  return request.post('/sms/v1/users/login', params)
 | 
					  return request.post('/sms/v1/users/login', params)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ import { getUserPermissions } from 'services'
 | 
				
			||||||
import BlankView from '@/layouts/blank.vue'
 | 
					import BlankView from '@/layouts/blank.vue'
 | 
				
			||||||
import router, { resetRouter } from '@/router'
 | 
					import router, { resetRouter } from '@/router'
 | 
				
			||||||
import { menuKey, enablePermissionStorage } from '@/config'
 | 
					import { menuKey, enablePermissionStorage } from '@/config'
 | 
				
			||||||
import { urlToList } from '../utils'
 | 
					import { urlToList, goLogin } from '../utils'
 | 
				
			||||||
import actionStore from '@/core/actions'
 | 
					import actionStore from '@/core/actions'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const resultRoutes = []
 | 
					const resultRoutes = []
 | 
				
			||||||
| 
						 | 
					@ -167,7 +167,7 @@ const actions = {
 | 
				
			||||||
      // 重置标签信息
 | 
					      // 重置标签信息
 | 
				
			||||||
      dispatch('tagsView/delAllViews', null, { root: true })
 | 
					      dispatch('tagsView/delAllViews', null, { root: true })
 | 
				
			||||||
      removeToken()
 | 
					      removeToken()
 | 
				
			||||||
      if (redirectToLogin) window.location.href = '/login'
 | 
					      if (redirectToLogin) goLogin()
 | 
				
			||||||
      resolve()
 | 
					      resolve()
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,14 +1,45 @@
 | 
				
			||||||
export const setBrowser = (icon, title) => {
 | 
					import { getSystemConfigs } from 'services'
 | 
				
			||||||
  const head = document.getElementsByTagName('head')[0]
 | 
					import store from '@/store'
 | 
				
			||||||
  const linkTag = document.createElement('link')
 | 
					export const setBrowser = (icon, title) => {
 | 
				
			||||||
  linkTag.href = icon
 | 
					  const head = document.getElementsByTagName('head')[0]
 | 
				
			||||||
  linkTag.setAttribute('rel', 'shortcut icon')
 | 
					  const linkTag = document.createElement('link')
 | 
				
			||||||
  linkTag.setAttribute('type', 'image/x-icon')
 | 
					  linkTag.href = icon
 | 
				
			||||||
  head.appendChild(linkTag)
 | 
					  linkTag.setAttribute('rel', 'shortcut icon')
 | 
				
			||||||
  document.title = title
 | 
					  linkTag.setAttribute('type', 'image/x-icon')
 | 
				
			||||||
}
 | 
					  head.appendChild(linkTag)
 | 
				
			||||||
// /system/configs/page -> [ '/system','/system/configs','/system/configs/page']
 | 
					  document.title = title
 | 
				
			||||||
export const urlToList = (url) => {
 | 
					}
 | 
				
			||||||
  const urllist = url.split('/').filter((i) => i)
 | 
					// /system/configs/page -> [ '/system','/system/configs','/system/configs/page']
 | 
				
			||||||
  return urllist.map((urlItem, index) => `/${urllist.slice(0, index + 1).join('/')}`)
 | 
					export const urlToList = (url) => {
 | 
				
			||||||
}
 | 
					  const urllist = url.split('/').filter((i) => i)
 | 
				
			||||||
 | 
					  return urllist.map((urlItem, index) => `/${urllist.slice(0, index + 1).join('/')}`)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export const getPageConfigs = async () => {
 | 
				
			||||||
 | 
					  const res = await getSystemConfigs({ category: '界面配置' })
 | 
				
			||||||
 | 
					  if (res.success) {
 | 
				
			||||||
 | 
					    return res.data
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  throw res.data
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export const getCasConfig = async () => {
 | 
				
			||||||
 | 
					  const Store = store
 | 
				
			||||||
 | 
					  let pageConfig = Store?.getters?.pageConfig || {}
 | 
				
			||||||
 | 
					  if (!Object.keys(pageConfig).length) {
 | 
				
			||||||
 | 
					    pageConfig = (await getPageConfigs()) || {}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const { cas, casLoginUrl, casLoginoutUrl } = pageConfig
 | 
				
			||||||
 | 
					  const isCASLogin = (cas === 'true' || cas === true) && !!casLoginUrl
 | 
				
			||||||
 | 
					  const casLoginPath = `${casLoginUrl}?service=${location.origin}/caslogin`
 | 
				
			||||||
 | 
					  const casLogoutPath = `${casLoginoutUrl}?service=${location.origin}/caslogin`
 | 
				
			||||||
 | 
					  return { isCASLogin, cas, casLoginPath, casLogoutPath }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export const goLogin = async (forceCasRedirect = false) => {
 | 
				
			||||||
 | 
					  const { isCASLogin, casLoginPath } = await getCasConfig()
 | 
				
			||||||
 | 
					  let path = '/login'
 | 
				
			||||||
 | 
					  // forceCasRedirect avoids reusing stale CAS tickets during logout or failed auth attempts
 | 
				
			||||||
 | 
					  const ticket = forceCasRedirect ? null : new URLSearchParams(location.search).get('ticket')
 | 
				
			||||||
 | 
					  if (isCASLogin) {
 | 
				
			||||||
 | 
					    path = ticket ? `/caslogin?ticket=${ticket}` : casLoginPath
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  window.location.href = path
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,8 @@ import 'nprogress/nprogress.css'
 | 
				
			||||||
import { notification } from 'ant-design-vue'
 | 
					import { notification } from 'ant-design-vue'
 | 
				
			||||||
import { getToken } from 'utils/auth'
 | 
					import { getToken } from 'utils/auth'
 | 
				
			||||||
import store from '@/store'
 | 
					import store from '@/store'
 | 
				
			||||||
 | 
					import { getCasConfig, goLogin } from '@/store/utils'
 | 
				
			||||||
 | 
					import { logout } from '@/services'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const codeMessage = {
 | 
					const codeMessage = {
 | 
				
			||||||
  200: '服务器成功返回请求的数据。',
 | 
					  200: '服务器成功返回请求的数据。',
 | 
				
			||||||
| 
						 | 
					@ -92,9 +94,17 @@ axiosInstance.interceptors.response.use(
 | 
				
			||||||
          break
 | 
					          break
 | 
				
			||||||
        case '401':
 | 
					        case '401':
 | 
				
			||||||
        case '509':
 | 
					        case '509':
 | 
				
			||||||
          store.dispatch('permission/ResetRoutes')
 | 
					          store.dispatch('permission/ResetRoutes', false).then(() => {
 | 
				
			||||||
          break
 | 
					            getCasConfig().then(({ isCASLogin, casLogoutPath }) => {
 | 
				
			||||||
        default:
 | 
					              if (isCASLogin) {
 | 
				
			||||||
 | 
					                location.href = casLogoutPath
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                logout().then((res) => {
 | 
				
			||||||
 | 
					                  if (res.success) goLogin()
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (!options.ignoreError) {
 | 
					      if (!options.ignoreError) {
 | 
				
			||||||
        notification.error({
 | 
					        notification.error({
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,61 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="casLogin">{{ msg }}</div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import { loginByCas } from 'services'
 | 
				
			||||||
 | 
					import setLoginData from './tools'
 | 
				
			||||||
 | 
					import { removeToken } from 'utils/auth'
 | 
				
			||||||
 | 
					import { goLogin } from '@/store/utils'
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  data() {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      msg: '',
 | 
				
			||||||
 | 
					      url: window.location.href
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  created() {
 | 
				
			||||||
 | 
					    this.init()
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  methods: {
 | 
				
			||||||
 | 
					    init() {
 | 
				
			||||||
 | 
					      let ticket = this.getUrlKey('ticket')
 | 
				
			||||||
 | 
					      if (!ticket || ticket == '') {
 | 
				
			||||||
 | 
					        const { redirect } = this.$route.query
 | 
				
			||||||
 | 
					        const path = redirect ? redirect.split('/#')[1] : '/sms-web/resource_dashboard'
 | 
				
			||||||
 | 
					        this.$router.replace({ path })
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      const service = `${window.location.origin}/caslogin`
 | 
				
			||||||
 | 
					      this.login(ticket, service)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getUrlKey(name) {
 | 
				
			||||||
 | 
					      return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(this.url) || ['', ''])[1].replace(/\+/g, '%20')) || null
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    handleLoginAfter(data) {
 | 
				
			||||||
 | 
					      setLoginData(data)
 | 
				
			||||||
 | 
					      const { redirect } = this.$route.query
 | 
				
			||||||
 | 
					      const path = redirect ? redirect.split('/#')[1] : '/sms-web/resource_dashboard'
 | 
				
			||||||
 | 
					      this.$router.replace(path)
 | 
				
			||||||
 | 
					      localStorage.removeItem('lockData')
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    login(ticket, service) {
 | 
				
			||||||
 | 
					      loginByCas({ ticket, service })
 | 
				
			||||||
 | 
					        .then((res) => {
 | 
				
			||||||
 | 
					          if (res.success) {
 | 
				
			||||||
 | 
					            this.handleLoginAfter(res.data)
 | 
				
			||||||
 | 
					            this.msg = res.message
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            console.log(res.message, 'res.message')
 | 
				
			||||||
 | 
					            goLogin(true)
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch(() => {
 | 
				
			||||||
 | 
					          this.msg = '登录失败'
 | 
				
			||||||
 | 
					          removeToken()
 | 
				
			||||||
 | 
					          goLogin(true)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -59,10 +59,10 @@ export default {
 | 
				
			||||||
      remember: false,
 | 
					      remember: false,
 | 
				
			||||||
      loginForm: {
 | 
					      loginForm: {
 | 
				
			||||||
        account: '',
 | 
					        account: '',
 | 
				
			||||||
        password: '',
 | 
					        password: ''
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      loading: false,
 | 
					      loading: false,
 | 
				
			||||||
      capsTooltip: false,
 | 
					      capsTooltip: false
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    const store = useStore()
 | 
					    const store = useStore()
 | 
				
			||||||
    const configs = computed(() => store.getters.pageConfig)
 | 
					    const configs = computed(() => store.getters.pageConfig)
 | 
				
			||||||
| 
						 | 
					@ -84,7 +84,7 @@ export default {
 | 
				
			||||||
      if (state.remember) {
 | 
					      if (state.remember) {
 | 
				
			||||||
        const obj = {
 | 
					        const obj = {
 | 
				
			||||||
          account: state.loginForm.account,
 | 
					          account: state.loginForm.account,
 | 
				
			||||||
          password: encrypt(state.loginForm.password),
 | 
					          password: encrypt(state.loginForm.password)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        localStorage.setItem('cmcLoginData', JSON.stringify(obj))
 | 
					        localStorage.setItem('cmcLoginData', JSON.stringify(obj))
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
| 
						 | 
					@ -104,12 +104,14 @@ export default {
 | 
				
			||||||
        const res = await login({
 | 
					        const res = await login({
 | 
				
			||||||
          account,
 | 
					          account,
 | 
				
			||||||
          password: encrypt(password),
 | 
					          password: encrypt(password),
 | 
				
			||||||
          isManager: true,
 | 
					          isManager: true
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        if (res.success) {
 | 
					        if (res.success) {
 | 
				
			||||||
          goLogin(res.data)
 | 
					          goLogin(res.data)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } catch (error) {}
 | 
					      } catch (error) {
 | 
				
			||||||
 | 
					        console.log(error)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      state.loading = false
 | 
					      state.loading = false
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,9 +133,9 @@ export default {
 | 
				
			||||||
      configs,
 | 
					      configs,
 | 
				
			||||||
      loginFormRef,
 | 
					      loginFormRef,
 | 
				
			||||||
      handleLogin,
 | 
					      handleLogin,
 | 
				
			||||||
      checkCapslock,
 | 
					      checkCapslock
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue