Commit af088afc by ningjihai

登录 permission--router.beforeEach store

parent 1fc0f2d8
......@@ -20,16 +20,20 @@
"@vueup/vue-quill": "1.2.0",
"@vueuse/core": "13.3.0",
"axios": "1.9.0",
"buffer": "^6.0.3",
"clipboard": "2.0.11",
"crypto-js": "^4.2.0",
"echarts": "5.6.0",
"element-plus": "2.9.9",
"file-saver": "2.0.5",
"fuse.js": "6.6.2",
"gm-crypt": "^0.0.2",
"js-beautify": "1.14.11",
"js-cookie": "3.0.5",
"jsencrypt": "3.3.2",
"nprogress": "0.2.0",
"pinia": "3.0.2",
"sm-crypto": "^0.3.13",
"sortablejs": "^1.15.6",
"splitpanes": "4.0.4",
"view-ui-plus": "^1.3.20",
......
......@@ -20,9 +20,15 @@ importers:
axios:
specifier: 1.9.0
version: 1.9.0
buffer:
specifier: ^6.0.3
version: 6.0.3
clipboard:
specifier: 2.0.11
version: 2.0.11
crypto-js:
specifier: ^4.2.0
version: 4.2.0
echarts:
specifier: 5.6.0
version: 5.6.0
......@@ -35,6 +41,9 @@ importers:
fuse.js:
specifier: 6.6.2
version: 6.6.2
gm-crypt:
specifier: ^0.0.2
version: 0.0.2
js-beautify:
specifier: 1.14.11
version: 1.14.11
......@@ -50,6 +59,9 @@ importers:
pinia:
specifier: 3.0.2
version: 3.0.2(vue@3.5.16)
sm-crypto:
specifier: ^0.3.13
version: 0.3.13
sortablejs:
specifier: ^1.15.6
version: 1.15.6
......@@ -362,56 +374,67 @@ packages:
resolution: {integrity: sha512-byyflM+huiwHlKi7VHLAYTKr67X199+V+mt1iRgJenAI594vcmGGddWlu6eHujmcdl6TqSNnvqaXJqZdnEWRGA==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.46.3':
resolution: {integrity: sha512-aLm3NMIjr4Y9LklrH5cu7yybBqoVCdr4Nvnm8WB7PKCn34fMCGypVNpGK0JQWdPAzR/FnoEoFtlRqZbBBLhVoQ==}
cpu: [arm]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.46.3':
resolution: {integrity: sha512-VtilE6eznJRDIoFOzaagQodUksTEfLIsvXymS+UdJiSXrPW7Ai+WG4uapAc3F7Hgs791TwdGh4xyOzbuzIZrnw==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.46.3':
resolution: {integrity: sha512-dG3JuS6+cRAL0GQ925Vppafi0qwZnkHdPeuZIxIPXqkCLP02l7ka+OCyBoDEv8S+nKHxfjvjW4OZ7hTdHkx8/w==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-loongarch64-gnu@4.46.3':
resolution: {integrity: sha512-iU8DxnxEKJptf8Vcx4XvAUdpkZfaz0KWfRrnIRrOndL0SvzEte+MTM7nDH4A2Now4FvTZ01yFAgj6TX/mZl8hQ==}
cpu: [loong64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-ppc64-gnu@4.46.3':
resolution: {integrity: sha512-VrQZp9tkk0yozJoQvQcqlWiqaPnLM6uY1qPYXvukKePb0fqaiQtOdMJSxNFUZFsGw5oA5vvVokjHrx8a9Qsz2A==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-gnu@4.46.3':
resolution: {integrity: sha512-uf2eucWSUb+M7b0poZ/08LsbcRgaDYL8NCGjUeFMwCWFwOuFcZ8D9ayPl25P3pl+D2FH45EbHdfyUesQ2Lt9wA==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.46.3':
resolution: {integrity: sha512-7tnUcDvN8DHm/9ra+/nF7lLzYHDeODKKKrh6JmZejbh1FnCNZS8zMkZY5J4sEipy2OW1d1Ncc4gNHUd0DLqkSg==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.46.3':
resolution: {integrity: sha512-MUpAOallJim8CsJK+4Lc9tQzlfPbHxWDrGXZm2z6biaadNpvh3a5ewcdat478W+tXDoUiHwErX/dOql7ETcLqg==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.46.3':
resolution: {integrity: sha512-F42IgZI4JicE2vM2PWCe0N5mR5vR0gIdORPqhGQ32/u1S1v3kLtbZ0C/mi9FFk7C5T0PgdeyWEPajPjaUpyoKg==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.46.3':
resolution: {integrity: sha512-oLc+JrwwvbimJUInzx56Q3ujL3Kkhxehg7O1gWAYzm8hImCd5ld1F2Gry5YDjR21MNb5WCKhC9hXgU7rRlyegQ==}
cpu: [x64]
os: [linux]
libc: [musl]
'@rollup/rollup-win32-arm64-msvc@4.46.3':
resolution: {integrity: sha512-lOrQ+BVRstruD1fkWg9yjmumhowR0oLAAzavB7yFSaGltY8klttmZtCLvOXCmGE9mLIn8IBV/IFrQOWz5xbFPg==}
......@@ -635,6 +658,9 @@ packages:
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
base@0.11.2:
resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==}
engines: {node: '>=0.10.0'}
......@@ -668,6 +694,9 @@ packages:
buffer-builder@0.2.0:
resolution: {integrity: sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==}
buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
cache-base@1.0.1:
resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==}
engines: {node: '>=0.10.0'}
......@@ -760,6 +789,9 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
crypto-js@4.2.0:
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
css-select@4.3.0:
resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==}
......@@ -1105,6 +1137,9 @@ packages:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'}
gm-crypt@0.0.2:
resolution: {integrity: sha512-eg3EaPQYCwWI7UNMvV4ReHD4rR1mtegDDyK80nr49FKw3PgyvVCZ44wIeqA88ITvjIVC3mT/8ZZG0qvH701LzA==}
good-listener@1.2.2:
resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==}
......@@ -1176,6 +1211,9 @@ packages:
htmlparser2@3.10.1:
resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==}
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
image-size@0.5.5:
resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
engines: {node: '>=0.10.0'}
......@@ -1383,6 +1421,9 @@ packages:
js-tokens@9.0.1:
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
jsbn@1.1.0:
resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
jsencrypt@3.3.2:
resolution: {integrity: sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==}
......@@ -1937,6 +1978,9 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
sm-crypto@0.3.13:
resolution: {integrity: sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==}
snapdragon-node@2.1.1:
resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==}
engines: {node: '>=0.10.0'}
......@@ -2774,6 +2818,8 @@ snapshots:
balanced-match@1.0.2: {}
base64-js@1.5.1: {}
base@0.11.2:
dependencies:
cache-base: 1.0.1
......@@ -2819,6 +2865,11 @@ snapshots:
buffer-builder@0.2.0: {}
buffer@6.0.3:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
cache-base@1.0.1:
dependencies:
collection-visit: 1.0.0
......@@ -2927,6 +2978,8 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
crypto-js@4.2.0: {}
css-select@4.3.0:
dependencies:
boolbase: 1.0.0
......@@ -3396,6 +3449,10 @@ snapshots:
define-properties: 1.2.1
gopd: 1.2.0
gm-crypt@0.0.2:
dependencies:
base64-js: 1.5.1
good-listener@1.2.2:
dependencies:
delegate: 3.2.0
......@@ -3464,6 +3521,8 @@ snapshots:
inherits: 2.0.4
readable-stream: 3.6.2
ieee754@1.2.1: {}
image-size@0.5.5: {}
immutable@5.1.3: {}
......@@ -3661,6 +3720,8 @@ snapshots:
js-tokens@9.0.1: {}
jsbn@1.1.0: {}
jsencrypt@3.3.2: {}
json5@1.0.2:
......@@ -4250,6 +4311,10 @@ snapshots:
signal-exit@4.1.0: {}
sm-crypto@0.3.13:
dependencies:
jsbn: 1.1.0
snapdragon-node@2.1.1:
dependencies:
define-property: 1.0.0
......
import request from '@/utils/request'
// 登录方法
export function login(username, password, code, uuid) {
export function login(username, password) {
const data = {
username,
password,
code,
uuid
password
}
return request({
url: '/login',
url: '/doLogin',
headers: {
isToken: false,
repeatSubmit: false
......
......@@ -11,7 +11,7 @@ import usePermissionStore from '@/store/modules/permission'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register', '/assetLibrary']
const whiteList = ['/login', '/register', '/assetLibrary', '/projectHome', '/projectManage','/classification']
const isWhiteList = (path) => {
return whiteList.some(pattern => isPathMatch(pattern, path))
......@@ -19,48 +19,55 @@ const isWhiteList = (path) => {
router.beforeEach((to, from, next) => {
NProgress.start()
if (getToken()) {
to.meta.title && useSettingsStore().setTitle(to.meta.title)
/* has token*/
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
} else if (isWhiteList(to.path)) {
next()
} else {
if (useUserStore().roles.length === 0) {
isRelogin.show = true
// 判断当前用户是否已拉取完user_info信息
useUserStore().getInfo().then(() => {
isRelogin.show = false
usePermissionStore().generateRoutes().then(accessRoutes => {
// 根据roles权限生成可访问的路由表
accessRoutes.forEach(route => {
if (!isHttp(route.path)) {
router.addRoute(route) // 动态添加可访问路由表
}
})
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
}).catch(err => {
useUserStore().logOut().then(() => {
ElMessage.error(err)
next({ path: '/' })
})
})
} else {
next()
}
}
} else {
// 没有token
if (isWhiteList(to.path)) {
// 在免登录白名单,直接进入
// if (getToken()) {
// to.meta.title && useSettingsStore().setTitle(to.meta.title)
// /* has token*/
// if (to.path === '/login') {
// next({ path: '/' })
// NProgress.done()
// } else if (isWhiteList(to.path)) {
// next()
// } else {
// if (useUserStore().roles.length === 0) {
// isRelogin.show = true
// // 判断当前用户是否已拉取完user_info信息
// useUserStore().getInfo().then(() => {
// isRelogin.show = false
// usePermissionStore().generateRoutes().then(accessRoutes => {
// // 根据roles权限生成可访问的路由表
// accessRoutes.forEach(route => {
// if (!isHttp(route.path)) {
// router.addRoute(route) // 动态添加可访问路由表
// }
// })
// next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
// })
// }).catch(err => {
// useUserStore().logOut().then(() => {
// ElMessage.error(err)
// next({ path: '/' })
// })
// })
// } else {
// next()
// }
// }
// } else {
// // 没有token
// if (isWhiteList(to.path)) {
// // 在免登录白名单,直接进入
// next()
// } else {
// next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
// NProgress.done()
// }
// }
if (sessionStorage.getItem('__token') || isWhiteList(to.path)){
next()
} else {
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
NProgress.done()
}
}else{
next(`/login?redirect=${to.fullPath}`)
}
})
......
......@@ -63,21 +63,30 @@ export const constantRoutes = [
hidden: true
},
{
// 项目管理
path: '/projectManage',
component: () => import('@/views/projectManage/index'),
hidden: true
},
{
// 项目首页
path: '/projectHome',
component: () => import('@/views/projectHome/index'),
hidden: true
},
{
// 加密设置
path: '/classification',
component: () => import('@/views/Classification/index'),
hidden: true
},
{
// 加密管理
path: '/encryptionManagement',
component: () => import('@/views/EncryptionManagement/index'),
hidden: true
},
{
path: '',
component: Layout,
redirect: '/index',
......
......@@ -4,7 +4,10 @@ import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { isHttp, isEmpty } from "@/utils/validate"
import defAva from '@/assets/images/profile.jpg'
import { sm4 as SM4 } from 'gm-crypt'
// import useAppStore from './app'
// const appStore = useAppStore()
const useUserStore = defineStore(
'user',
{
......@@ -21,19 +24,70 @@ const useUserStore = defineStore(
// 登录
login(userInfo) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
// const password = userInfo.password
console.log('userInfo.password',userInfo.password)
const password = this.encryptPassword(userInfo.password)
// const code = userInfo.code
// const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => {
setToken(res.token)
this.token = res.token
resolve()
login(username, password).then(res => {
console.log(res)
if (res.code == "POP_00014"){
resolve(res.data)
}else{
reject(error)
}
// return
// setToken(res.token)
// this.token = res.token
reject(error)
}).catch(error => {
reject(error)
})
// login(username, password, code, uuid).then(res => {
// setToken(res.token)
// this.token = res.token
// resolve()
// }).catch(error => {
// reject(error)
// })
})
},
// 加密方法
encryptPassword(plainPassword) {
const sm4Config = {
key: "GJstSK_YBD=gSOFT",
mode: 'ecb',
cipherType: 'base64'
}
const sm4 = new SM4(sm4Config)
try {
return sm4.encrypt(plainPassword)
} catch (error) {
console.error('加密失败:', error)
throw new Error('密码加密处理失败')
}
},
// 十六进制转Base64工具方法
hexToBase64(hexString) {
// 将十六进制字符串转换为字节数组
const byteArray = new Uint8Array(
hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16))
);
// 将字节数组转换为Base64
const base64String = btoa(
String.fromCharCode.apply(null, byteArray)
);
return base64String;
},
// 获取用户信息
getInfo() {
return new Promise((resolve, reject) => {
......
......@@ -74,7 +74,7 @@ service.interceptors.request.use(config => {
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200
const code = res.data.code || 'POP_00014'
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
......@@ -100,7 +100,7 @@ service.interceptors.response.use(res => {
} else if (code === 601) {
ElMessage({ message: msg, type: 'warning' })
return Promise.reject(new Error(msg))
} else if (code !== 200) {
} else if (code !== 'POP_00014') {
ElNotification.error({ title: msg })
return Promise.reject('error')
} else {
......
......@@ -129,6 +129,11 @@ const handleEditField = (field) => {
console.log('编辑字段', field)
}
const openDecrypt = ref(false)
function pageProjectManage() {
router.push({
path: '/projectManage'
})
}
defineExpose({
// handleRedInk,
// handleVoid
......
<script setup lang="ts" name="QueryForm">
import { computed,ref,watch } from 'vue'
import type { FormInstance } from 'element-plus'
import PageWrapperSearch from '@/components/search/PageWrapperSearch.vue'
// import { useDict } from '@/utils/dict'
// import { listDept } from '@/api/system/dept'// 部门
// const { approve_status, invoice_status} = useDict('approve_status', 'invoice_status')
const emit = defineEmits(['update:modelValue', 'query', 'reset'])
const invoice_status_filter = ref([])
const employeesList = ref([])
const props = defineProps<{
modelValue: any
}>()
const queryForm = computed({
get() {
return props.modelValue
},
set(val: any) {
console.log('query computed', val)
emit('update:modelValue', val)
}
})
// 搜索
function onSearch() {
emit('query')
}
// 重置
function onReset(formRef: FormInstance) {
queryForm.value.datasource = ''
queryForm.value.schema = ''
queryForm.value.tableName = ''
queryForm.value.fieldName = ''
queryForm.value.status = ''
emit('reset', formRef)
}
</script>
<template>
<!-- el-form -->
<page-wrapper-search
:model="queryForm"
@search="onSearch"
@reset="onReset">
<el-form-item label="数据源名称" prop="datasource">
<el-input
v-model="queryForm.datasource"
placeholder="请输入数据源名称"
clearable
/>
</el-form-item>
<el-form-item label="SCHEMA" prop="schema">
<el-input
v-model="queryForm.schema"
placeholder="请输入SCHEMA"
clearable
/>
</el-form-item>
<el-form-item label="表名称" prop="tableName">
<el-input
v-model="queryForm.tableName"
placeholder="请输入表名称"
clearable
/>
</el-form-item>
<el-form-item label="字段名称" prop="fieldName">
<el-input
v-model="queryForm.fieldName"
placeholder="请输入字段名称"
clearable
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryForm.status"
placeholder="请选择状态"
clearable
>
<el-option label="启用" value="active" />
<el-option label="禁用" value="inactive" />
</el-select>
</el-form-item>
</page-wrapper-search>
</template>
<style scoped>
</style>
<script setup lang="ts" name="projectManageIndex">
import { ref } from 'vue'
import list from './list.vue'
const widget = {
list: list
}
const page = ref('list')
const params = ref({})
function onChangePage(val: string, param?: any) {
page.value = val
params.value = param ?? {}
}
</script>
<template>
<component :is="widget[page]" v-bind="params" @page="onChangePage" />
</template>
<script setup name="ProjectManageList">
import { getCurrentInstance, reactive, ref, toRefs } from 'vue'
import { ElMessage } from 'element-plus'
import QueryForm from './QueryForm.vue'
// import ProjectEditDialog from './ProjectEditDialog.vue'
// import DownloadPluginDialog from './DownloadPluginDialog.vue'
// import ExportDialog from './ExportDialog.vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const emit = defineEmits(['page'])
const { proxy } = getCurrentInstance()
function onReset(formQuery) {
console.log('onReset')
formQuery.resetFields()
handleQuery()
}
function onQuery() {
handleQuery()
}
// 搜索按钮操作
function handleQuery() {
console.log('queryParams',queryParams.value)
queryParams.value.pageNum = 1
getList()
}
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 8
}
})
// 表格数据
const { queryParams } = toRefs(data)
const total = ref(3)
const loading = ref(false)
// 查询列表
function getList() {
loading.value = true
setTimeout(() => {
loading.value = false
}, 3000);
}
function pageProjectManage() {
router.push({
path: '/projectManage'
})
}
/**
* 删除多余列
*/
function deleteUnnecessaryColumns(){
console.log('删除多余列')
}
/**
* 批量加密
*/
function bulkEncryption(){
console.log('批量加密')
}
/**
* 批量解密
*/
function batchDecryption() {
console.log('批量解密')
}
</script>
<template>
<div class="app-container scroller">
<PageTitle :back="true" @back="pageProjectManage">
<template #title>
返回项目管理
</template>
<template #buttons>
<el-button
type="primary"
@click="deleteUnnecessaryColumns"
>
删除多余列
</el-button>
<el-button
type="primary"
@click="bulkEncryption"
>
批量加密
</el-button>
<el-button
type="primary"
@click="batchDecryption"
>
批量解密
</el-button>
</template>
</PageTitle>
<div class="app-container__body">
<div>
<query-form
ref="QueryFormRef"
v-model="queryParams"
@query="onQuery"
@reset="onReset"/>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.table-item {
margin-top: var(--container-pd);
margin-bottom: 20px;
}
.item-content {
margin: 8px 0;
.label {
width: 80px;
color: #888;
}
}
.flex-container {
display: flex;
}
.align-center {
align-items: center;
}
.justify-between {
justify-content: space-between;
}
.flex1 {
flex: 1;
}
</style>
\ No newline at end of file
......@@ -25,7 +25,7 @@
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
<!-- <el-form-item prop="code" v-if="captchaEnabled">
<el-input
v-model="loginForm.code"
size="large"
......@@ -39,8 +39,8 @@
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
</el-form-item> -->
<!-- <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox> -->
<el-form-item style="width:100%;">
<el-button
:loading="loading"
......@@ -67,13 +67,17 @@
<script setup>
import { getCodeImg } from "@/api/login"
import Cookies from "js-cookie"
import { sm4 as SM4 } from 'gm-crypt'
import { encrypt, decrypt } from "@/utils/jsencrypt"
import useUserStore from '@/store/modules/user'
const title = import.meta.env.VITE_APP_TITLE
const userStore = useUserStore()
import useAppStore from '@/store/modules/app'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
const title = import.meta.env.VITE_APP_TITLE
const userStore = useUserStore()
const appStore = useAppStore()
const { proxy } = getCurrentInstance()
const loginForm = ref({
......@@ -106,19 +110,65 @@ function handleLogin() {
proxy.$refs.loginRef.validate(valid => {
if (valid) {
loading.value = true
// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
if (loginForm.value.rememberMe) {
Cookies.set("username", loginForm.value.username, { expires: 30 })
Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 })
Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 })
} else {
// 否则移除
Cookies.remove("username")
Cookies.remove("password")
Cookies.remove("rememberMe")
}
// // 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
// if (loginForm.value.rememberMe) {
// Cookies.set("username", loginForm.value.username, { expires: 30 })
// Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 })
// Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 })
// } else {
// // 否则移除
// Cookies.remove("username")
// Cookies.remove("password")
// Cookies.remove("rememberMe")
// }
// 调用action的登录方法
userStore.login(loginForm.value).then(() => {
userStore.login(loginForm.value).then(async (res) => {
console.log('res123',res)
let data = res
let menus = data.menus.map(item => {
item.children = item.submenu.map(child => {
return {
children: [],
iconCls: child.icon,
id: child.id,
keepAlive: false,
name: child.menuname,
path: child.url,
requireAuth: false
}
})
return {
children: item.children,
name: item.menuname,
id: item.id,
path: item.url,
type: item.type,
iconCls: item.icon
}
})
// 用户数据整理
let user = data.tsysUser;
let loginBlankMenus = false
if(data.menus.length === 0) {
loginBlankMenus = true
}
try {
await appStore.signOut('login')
// 设置导航菜单
appStore.setNav({ menus: data.menus })
// 设置用户信息
appStore.setUserInfo({user, licenseRst: data.licenseRst, loginBlankMenus})
// 存储token和登录信息
window.sessionStorage.setItem('__token', data.token)
const loginStr = JSON.stringify({
username: loginForm.value.username,
password: encryptPassword(loginForm.value.password)
})
window.sessionStorage.setItem('login', loginStr)
const query = route.query
const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
if (cur !== "redirect") {
......@@ -126,18 +176,57 @@ function handleLogin() {
}
return acc
}, {})
router.push({ path: redirect.value || "/", query: otherQueryParams })
console.log('路由配置:', router.getRoutes())
router.push({ path:"/index", query: otherQueryParams })
// router.push({ path: redirect.value || "/index", query: otherQueryParams })
// if(redirect.value){
// console.log('redirect',redirect.value)
// router.push({ path: redirect.value, query: otherQueryParams })
// router.push({ path: redirect.value, query: otherQueryParams })
// console.log(2134)
// }else{
// router.push({ path: "/", query: otherQueryParams })
// }
// console.log('redirect',redirect.value)
// 跳转页面或其他操作
// router.push('/dashboard')
} catch (error) {
console.error('登录处理失败:', error)
}
}).catch(() => {
loading.value = false
// 重新获取验证码
if (captchaEnabled.value) {
getCode()
// getCode()
}
})
}
})
}
function encryptPassword(plainPassword) {
const sm4Config = {
key: "GJstSK_YBD=gSOFT",
mode: 'ecb',
cipherType: 'base64'
}
const sm4 = new SM4(sm4Config)
try {
return sm4.encrypt(plainPassword)
} catch (error) {
console.error('加密失败:', error)
throw new Error('密码加密处理失败')
}
}
function getCode() {
getCodeImg().then(res => {
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled
......@@ -159,8 +248,8 @@ function getCookie() {
}
}
getCode()
getCookie()
// getCode()
// getCookie()
</script>
<style lang='scss' scoped>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论