This commit is contained in:
tanyp 2023-04-19 16:55:37 +08:00
parent 7700c383d6
commit 44b0ca4601
26 changed files with 304 additions and 119 deletions

View File

@ -1,6 +1,6 @@
import request from '@/utils/request'
import global from '@/utils/global'
const userKey:string = 'tansci_boot_user'
const tokenKey:string = 'tansci_boot_token'
const menuKey:string = 'tansci_boot_menu'
@ -15,18 +15,6 @@ export function removeToken() {
sessionStorage.removeItem(tokenKey);
}
// 用户信息
export function getUser() {
let user = sessionStorage.getItem(userKey);
return user ? JSON.parse(user) : null;
}
export function setUser(data:any) {
return sessionStorage.setItem(userKey, JSON.stringify(data));
}
export function removeUser() {
return sessionStorage.removeItem(userKey);
}
// 菜单信息
export function getMenus() {
let menu = sessionStorage.getItem(menuKey);
@ -51,7 +39,6 @@ export function login(data:any){
}
}).then((res:any) => {
setToken(res.data.result.token)
setUser(res.data.result)
resolve(res.data.result.token)
}).catch((e:any) => {
reject(e)
@ -66,7 +53,6 @@ export function logout(){
method: 'get'
}).then(() => {
removeToken()
removeUser()
location.reload()
})
}
@ -84,3 +70,14 @@ export function getCode(){
})
})
}
export async function getUserInfo() {
await request({
url: '/tansci/sysuser/info',
method: 'get'
}).then((res:any) => {
if(res.data.result){
global.user.info = res.data.result
}
})
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -1,17 +1,29 @@
<script setup lang="ts">
import { reactive, onMounted, onBeforeMount, onDeactivated } from "vue"
import { reactive, onMounted, onBeforeMount, onDeactivated, getCurrentInstance, ref } from "vue"
import type { FormInstance, Action } from 'element-plus'
import { ElMessageBox } from 'element-plus'
import { isDark, toggleDark } from '@/composables'
import { getUser, getMenus, logout } from "@/api/auth"
import { getMenus, logout } from "@/api/auth"
import { modifyPass } from "@/api/system/user"
import Submenu from "@/components/Submenu.vue"
import TabsMenu from "@/components/TabsMenu.vue"
const { proxy } = getCurrentInstance()
const logo = new URL('../../assets/image/logo.png', import.meta.url).href
const state = reactive({
headerHeight: '52px',
asideWidth: '180px',
routers: [],
defaultHeight: null,
username: '未登录'
userVisible: false,
user: {
avatar: '',
username: '',
nickname: '未登录',
password: '',
rePassword: '',
oldPassword: ''
}
})
onBeforeMount(() => {
@ -30,10 +42,7 @@
})
state.routers = routers
let user:any = getUser()
if(user){
state.username = user.nickname
}
state.user = proxy.$global.user.info
window.addEventListener('resize', onDefaultHeight);
})
@ -48,11 +57,45 @@
function onHeaderCommand(command:any){
if('logout' === command){
logout()
} else if('password' === command){
} else if('personal' === command){
state.userVisible = true
}
}
const userRef = ref<FormInstance>();
const validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入确认密码'));
} else if (value !== state.user.password) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
}
const onUserSubmit = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid)=>{
if(valid){
modifyPass({
username: state.user.username,
password: state.user.password,
oldPassword: state.user.oldPassword
}).then(res=>{
if(res){
state.userVisible = false
ElMessageBox.alert('修改密码成功,请重新登录!', '提示', {
confirmButtonText: '确定',
type: 'warning',
callback: (action: Action) =>{
logout()
}
})
}
})
}
})
}
</script>
<template>
<div class="layout-container">
@ -60,6 +103,7 @@
<el-header :height="state.headerHeight">
<div class="header-logo">
<el-image :src="logo"></el-image>
<span class="title">{{proxy.$global.title}}</span>
</div>
<div class="header-content">
<div class="header-dark">
@ -73,12 +117,12 @@
<div class="header-login">
<el-dropdown @command="onHeaderCommand">
<span class="el-dropdown-link">
<span>{{state.username}}</span>
<span>{{state.user.nickname}}</span>
<el-icon class="el-icon--right"><arrow-down /></el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="password">修改密码</el-dropdown-item>
<el-dropdown-item command="personal">个人中心</el-dropdown-item>
<el-dropdown-item command="logout">退出</el-dropdown-item>
</el-dropdown-menu>
</template>
@ -102,11 +146,75 @@
</el-aside>
<el-main>
<TabsMenu></TabsMenu>
<router-view style="margin: 0 0.3rem 0 0.1rem"/>
<el-card :shadow="proxy.$global.cardShadow" style="margin: 0.3rem;">
<el-scrollbar :height="state.defaultHeight-150">
<router-view />
</el-scrollbar>
</el-card>
</el-main>
</el-container>
<el-backtop target=".el-main"></el-backtop>
</el-container>
<el-dialog v-model="state.userVisible" title="个人中心" width="40%" :show-close="false">
<el-form :model="state.user" ref="userRef" :rules="rules" label-width="80px" status-icon>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="用户头像" prop="avatar">
<el-avatar :size="50" :src="state.user.avatar" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="用户名称" prop="username">
<el-input v-model="state.user.username" disabled style="width: 100%"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="用户昵称" prop="nickname">
<el-input v-model="state.user.nickname" disabled placeholder="请输入昵称" style="width: 100%"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="用户电话" prop="phone">
<el-input v-model="state.user.phone" disabled style="width: 100%"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="用户邮箱" prop="email">
<el-input v-model="state.user.email" disabled style="width: 100%"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="原始密码" prop="oldPassword" :rules="[{required: true, message: '请输入原始密码', trigger: 'blur'}]">
<el-input v-model="state.user.oldPassword" type="password" placeholder="请输入原始密码" style="width: 100%"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="用户密码" prop="password" :rules="[{required: true, message: '请输入密码', trigger: 'blur'},
{pattern: /^[a-zA-Z]\w{5,17}$/, message: '以字母开头长度在6~18之间只能包含字母、数字和下划线', trigger: 'blur'}]">
<el-input v-model="state.user.password" type="password" placeholder="请输入密码" style="width: 100%"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item prop="rePassword" label="确认密码" :rules="[{required: true, message: '请输入确认密码', trigger: 'blur'},{validator: validatePass, trigger: 'blur'}]">
<el-input v-model="state.user.rePassword" type="password" placeholder="请输入确认密码"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="onUserSubmit(userRef)" type="primary">修改密码</el-button>
</template>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
@ -122,6 +230,12 @@
line-height: 52px;
padding-left: 0.2rem;
cursor: pointer;
.title{
padding-left: 0.6rem;
color: var(-t);
font-weight: 700;
font-size: 18px;
}
}
.header-content{
display: flex;
@ -171,7 +285,7 @@
.el-main{
padding: 0;
overflow-x: hidden;
overflow-y: auto;
overflow-y: hidden;
}
.el-main::-webkit-scrollbar{
width: 0px;

View File

@ -1,6 +1,6 @@
import { createRouter, createWebHistory } from "vue-router"
import { ElMessage } from 'element-plus'
import { getToken, removeToken, removeUser, setMenus } from "@/api/auth"
import { getToken, removeToken, setMenus, getUserInfo } from "@/api/auth"
import common from '@/utils/common'
import { generateRoutes } from "./permission"
@ -42,11 +42,11 @@ router.beforeEach(async (to:any, from:any, next) => {
setMenus([...routers])
})
await common.getDictData()
await getUserInfo()
next({ ...to, replace: true })
} catch (error:any) {
removeToken()
removeUser()
ElMessage.error(error.data || 'Has Error')
next(`/login`)
}

View File

@ -1,5 +1,4 @@
import request from '@/utils/request'
import common from '@/utils/common'
import Layout from '@/components/layout/Index.vue'
const modules = import.meta.glob('../views/**/**.vue')
@ -13,7 +12,7 @@ export const filterRouter = (routers:any, level:any) => {
var setIframe = () => {
router.component = loadView(`/common/Iframe`)
router.props = { url: router.path }
router.path = "/" + common.uuid()
router.path = "/" + router.name
}
if(router.path && router.path.startsWith('http') && router.meta.openMode === 1){

View File

@ -5,6 +5,9 @@
// 主题
--theme: #2F9688;
// 文字
--t: #1d1d1f;
// 局部背景
// --el-bg-color: radial-gradient( white 0%, #FAFDFE 10%, #ddf8e7 50%, #FAFDFE 90%, white 100%);
// --el-bg-color: radial-gradient(#d9f8e5 0%, #FAFDFE 80%, #e7fcef 100%);
@ -36,7 +39,7 @@ body {
* Dialog 对话框
*/
.el-dialog__header{
background-color: var(--el-color-primary);
border-bottom: 1px solid var(--el-border-color);
margin-right: 0;
padding: 0.5rem 1rem;
}

View File

@ -1,5 +1,9 @@
// 全局变量配置
export default {
title: 'Tansci Boot',
baseApi: import.meta.env.VITE_BASE_API,
cardShadow: 'always',
cardShadow: 'never',
user: {
info: {}
},
}

View File

@ -1,7 +1,6 @@
<script setup lang="ts">
import { reactive, onMounted, getCurrentInstance } from "vue"
import { reactive, onMounted } from "vue"
const { proxy } = getCurrentInstance()
const state = reactive({
})
@ -12,9 +11,9 @@
</script>
<template>
<el-card class="home-container" :shadow="proxy.$global.cardShadow">
<div class="home-container">
首页
</el-card>
</div>
</template>
<style lang="scss" scoped>
.home-container{

View File

@ -14,8 +14,8 @@
<style scoped>
iframe{
position: absolute;
left: 180px;
top: 100px;
left: 0;
top: 0;
right: 0;
bottom: 0;
}

View File

@ -8,7 +8,7 @@
const loginFormRef = ref<FormInstance>()
const logo = new URL('../../assets/image/logo.png', import.meta.url).href
const loginLogo = new URL('../../assets/image/login-icon.png', import.meta.url).href
const loginLogo = new URL('../../assets/image/login-left.png', import.meta.url).href
const codeImg = ref()
const state = reactive({
@ -81,7 +81,7 @@
<div class="main-title">帐号登录</div>
<div class="main-container">
<div class="logo">
<el-image :src="loginLogo" style="width: 100%; height: 100%;"></el-image>
<el-image :src="loginLogo" style="width: 100%; height: 80%;"></el-image>
</div>
<div class="form">
<el-form :model="state.loginForm" :rules="rules" size="large" ref="loginFormRef">
@ -95,8 +95,8 @@
<el-input type="password" v-model="state.loginForm.password" prefix-icon="Lock" show-password placeholder="请输入密码" style="width:100%"></el-input>
</el-form-item>
<el-form-item prop="code" :rules="[{required: true,message: '请输入验证码',trigger: 'blur'}]">
<el-input v-model="state.loginForm.code" prefix-icon="HelpFilled" placeholder="请输入验证码" style="width:70%; margin-right: 1%"></el-input>
<img :src="codeImg" @click="onCode" style="width: 29%; height: 38px;">
<el-input v-model="state.loginForm.code" prefix-icon="HelpFilled" placeholder="请输入验证码" style="width: calc(100% - 110px); margin-right: 6px;"></el-input>
<el-image @click="onCode" :src="codeImg" fit="fill" style="width: 102px; height: 38px; border: 1px solid #dcdfe6; border-radius: 4px;"/>
</el-form-item>
<el-form-item>
<el-checkbox v-model="state.loginForm.remember">记住密码</el-checkbox>
@ -134,7 +134,7 @@
padding: 0 20%;
.title{
padding: 0 1rem;
color: var(--t9);
color: var(--t);
font-size: 20px;
font-weight: 700;
}
@ -145,6 +145,7 @@
font-size: 32px;
text-align: center;
padding: 5rem 0;
color: var(--t);
}
.main-container{
display: flex;
@ -169,7 +170,7 @@
.login-footer{
height: 100%;
text-align: center;
color: #606266;
color: #1d1d1f;
padding-top: 1.2rem;
.copy{
padding-top: 1rem;

View File

@ -1,7 +1,5 @@
<script setup lang="ts">
import { reactive, onMounted, getCurrentInstance } from "vue"
const { proxy } = getCurrentInstance()
import { reactive, onMounted } from "vue"
const state = reactive({
shadow: 'always',
@ -13,9 +11,9 @@
</script>
<template>
<el-card class="codegen-container" :shadow="proxy.$global.cardShadow">
<div class="codegen-container">
开发中
</el-card>
</div>
</template>
<style lang="scss" scoped>
.codegen-container{

View File

@ -9,10 +9,16 @@
</script>
<template>
<e-card :shadow="proxy.$global.cardShadow">
<iframe :src="state.url" width="100%" height="90%" frameborder="0"></iframe>
</e-card>
<div>
<iframe :src="state.url" width="100%" height="100%" frameborder="0"></iframe>
</div>
</template>
<style scoped>
iframe{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
</style>

View File

@ -1,9 +1,8 @@
<script setup lang="ts">
import { reactive, onMounted, getCurrentInstance } from "vue"
import { reactive, onMounted } from "vue"
import Table from '@/components/Table.vue'
import { page } from "@/api/monitor/loginLog"
const { proxy } = getCurrentInstance()
const state = reactive({
loading: false,
page: {
@ -74,11 +73,11 @@
</script>
<template>
<el-card class="loginlog-container" :shadow="proxy.$global.cardShadow">
<div class="loginlog-container">
<Table :data="state.tableData" :column="state.tableTitle" :operation="state.operation" :page="state.page" :loading="state.loading"
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange" @setCellColor="setCellColor">
</Table>
</el-card>
</div>
</template>
<style lang="scss" scoped>
.loginlog-container{

View File

@ -1,11 +1,10 @@
<script setup lang="ts">
import {onMounted, reactive, ref, unref, getCurrentInstance} from 'vue'
import {onMounted, reactive, ref, unref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import type {FormInstance} from 'element-plus'
import Table from '@/components/Table.vue'
import {page,kick} from '@/api/monitor/onlineUser'
const { proxy } = getCurrentInstance()
const searchForm = reactive({
username: null
})
@ -85,7 +84,7 @@
</script>
<template>
<el-card class="onlineuser-container" :shadow="proxy.$global.cardShadow">
<div class="onlineuser-container">
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="table.page" :loading="table.loading"
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange">
<template #search>
@ -97,7 +96,7 @@
<el-button @click="onKick(scope)" type='primary' text='primary' style="color:var(--edit); padding:0;">踢人</el-button>
</template>
</Table>
</el-card>
</div>
</template>
<style scoped lang="scss">
.onlineuser-container{

View File

@ -1,9 +1,8 @@
<script setup lang="ts">
import { reactive, onMounted, getCurrentInstance } from "vue"
import { reactive, onMounted } from "vue"
import Table from '@/components/Table.vue'
import { page } from "@/api/monitor/operLog"
const { proxy } = getCurrentInstance()
const state = reactive({
loading: false,
page: {
@ -85,7 +84,7 @@
</script>
<template>
<el-card class="operlog-container" :shadow="proxy.$global.cardShadow">
<div class="operlog-container">
<Table :data="state.tableData" :column="state.tableTitle" :operation="state.operation" :page="state.page" :loading="state.loading"
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange" @setCellColor="setCellColor">
<template #column="scope">
@ -126,7 +125,7 @@
</el-descriptions-item>
</el-descriptions>
</el-dialog>
</el-card>
</div>
</template>
<style lang="scss" scoped>
.operlog-container{

View File

@ -1,12 +1,11 @@
<script setup lang="ts">
import {onMounted, reactive, ref, getCurrentInstance} from 'vue'
import {onMounted, reactive, ref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import type {FormInstance} from 'element-plus'
import common from '@/utils/common'
import Table from '@/components/Table.vue'
import {tree,save,update,del} from '@/api/system/dict'
const { proxy } = getCurrentInstance()
const table = reactive({
loading: false,
operation:{
@ -144,7 +143,7 @@
</script>
<template>
<el-card class="dict-container" :shadow="proxy.$global.cardShadow">
<div class="dict-container">
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="false" :loading="table.loading">
<template #search>
<div><el-button @click="onAdd(null)" type="primary">添加</el-button></div>
@ -206,7 +205,7 @@
</span>
</template>
</el-dialog>
</el-card>
</div>
</template>
<style lang="scss" scoped>
.dict-container{

View File

@ -1,11 +1,10 @@
<script setup lang="ts">
import {onMounted, reactive, ref, getCurrentInstance} from 'vue'
import {onMounted, reactive, ref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import type {FormInstance} from 'element-plus'
import {list,save,update,del} from '@/api/system/menu'
import ElIcon from '@/components/ElIcon.vue'
const { proxy } = getCurrentInstance()
const menuFormRef = ref<FormInstance>();
const state = reactive({
treeData: [],
@ -188,8 +187,9 @@
}
</script>
<template>
<el-card class="menu-container" :shadow="proxy.$global.cardShadow">
<el-card class="menu-tree" shadow="never">
<div class="menu-container">
<div class="menu-tree">
<el-scrollbar height="45rem">
<el-tree :data="state.treeData" :props="{children: 'children', label: 'chineseName'}" highlight-current @node-click="onNodeClick" empty-text="暂无菜单">
<template #default="{ node, data }">
<span class="custom-tree-node">
@ -200,8 +200,9 @@
</span>
</template>
</el-tree>
</el-card>
<el-card class="menu-form" shadow="never">
</el-scrollbar>
</div>
<div class="menu-form">
<el-radio-group @change="onTypeChange" v-model="state.type">
<el-radio-button :label="1">菜单</el-radio-button>
<el-radio-button :label="2">按钮</el-radio-button>
@ -268,17 +269,17 @@
<el-button type="primary" @click="onSubmit(menuFormRef)">提交</el-button>
</el-form-item>
</el-form>
</el-card>
</el-card>
</div>
</div>
</template>
<style lang="scss">
.menu-container{
padding-bottom: 1.5rem;
display: flex;
.menu-tree{
float: left;
margin-right: 1rem;
min-width: 300px;
min-height: 700px;
border-right: 1px solid #e4e7ed;
margin: 0 4rem 0 1rem;
min-width: 12rem;
.el-tree-node:hover>.el-tree-node__content{
background-color: #fff !important;
color: var(--theme) !important;
@ -290,6 +291,7 @@
}
}
.menu-form{
width: 100%;
}
}
</style>

View File

@ -1,11 +1,10 @@
<script setup lang="ts">
import {onMounted, reactive, ref, getCurrentInstance} from 'vue'
import {onMounted, reactive, ref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import type {FormInstance} from 'element-plus'
import Table from '@/components/Table.vue'
import {list,save,update,del} from '@/api/system/org'
const { proxy } = getCurrentInstance()
const table = reactive({
loading: false,
operation:{
@ -127,7 +126,7 @@
</script>
<template>
<el-card class="org-container" :shadow="proxy.$global.cardShadow">
<div class="org-container">
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="false" :loading="table.loading">
<template #search>
<div><el-button @click="onAdd(null)" type="primary">添加</el-button></div>
@ -157,7 +156,7 @@
</span>
</template>
</el-dialog>
</el-card>
</div>
</template>
<style lang="scss" scoped>
.org-container{

View File

@ -1,11 +1,10 @@
<script setup lang="ts">
import {onMounted, reactive, ref, unref, getCurrentInstance} from 'vue'
import {onMounted, reactive, ref, unref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import type {FormInstance} from 'element-plus'
import {page,save,update,del,dataPermissions,orgList,menuPermissions,menuList} from '@/api/system/role'
import Table from '@/components/Table.vue'
const { proxy } = getCurrentInstance()
const searchForm = reactive({
name: null,
})
@ -209,7 +208,7 @@
</script>
<template>
<el-card class="role-container" :shadow="proxy.$global.cardShadow">
<div class="role-container">
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="table.page" :loading="table.loading"
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange">
<template #search>
@ -263,7 +262,7 @@
</span>
</template>
</el-dialog>
</el-card>
</div>
</template>
<style scoped lang="scss">
.role-container{

View File

@ -1,11 +1,10 @@
<script setup lang="ts">
import {onMounted, reactive, ref, unref, getCurrentInstance} from 'vue'
import {onMounted, reactive, ref, unref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import type {FormInstance} from 'element-plus'
import Table from '@/components/Table.vue'
import {page,save,update,del,roleList} from '@/api/system/user'
const { proxy } = getCurrentInstance()
const searchForm = reactive({
username: null
})
@ -218,7 +217,7 @@
</script>
<template>
<el-card class="user-container" :shadow="proxy.$global.cardShadow">
<div class="user-container">
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="table.page" :loading="table.loading"
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange" @onSwitchChange="onSwitchChange">
<template #search>
@ -252,7 +251,7 @@
<el-col :span="12">
<el-form-item v-if="form.operate == 0" label="密码" prop="password" :rules="[{required: true, message: '请输入密码', trigger: 'blur'},
{pattern: /^[a-zA-Z]\w{5,17}$/, message: '以字母开头长度在6~18之间只能包含字母、数字和下划线', trigger: 'blur'}]">
<el-input v-model="form.userForm.password" placeholder="请输入密码" style="width: 100%"/>
<el-input v-model="form.userForm.password" type="password" placeholder="请输入密码" style="width: 100%"/>
</el-form-item>
</el-col>
<el-col :span="12">
@ -327,7 +326,7 @@
</span>
</template>
</el-dialog>
</el-card>
</div>
</template>
<style scoped lang="scss">
.user-container{

View File

@ -8,6 +8,7 @@ import com.tansci.common.Wrapper;
import com.tansci.common.annotation.Log;
import com.tansci.common.constant.Constants;
import com.tansci.domain.SysUser;
import com.tansci.domain.vo.UserAuthVo;
import com.tansci.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -48,6 +49,13 @@ public class SysUserController {
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.list(user));
}
@ApiOperation(value = "用户信息", notes = "用户信息")
@Log(modul = "用户管理", type = Constants.SELECT, desc = "用户信息")
@GetMapping("/info")
public Wrapper<UserAuthVo> info() {
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.info());
}
@ApiOperation(value = "添加", notes = "添加")
@Log(modul = "用户管理", type = Constants.INSERT, desc = "添加")
@PostMapping("/save")

View File

@ -93,6 +93,10 @@ public class SysUser {
@ApiModelProperty(value = "备注")
private String remarks;
@TableField(exist = false)
@ApiModelProperty(value = "原密码")
private String oldPassword;
@TableField(exist = false)
@ApiModelProperty(value = "角色ID")
private String roleId;

View File

@ -0,0 +1,42 @@
package com.tansci.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName UserAuthVo.java
* @ClassPath com.tansci.domain.vo.UserAuthVo.java
* @Description 用户权限信息
* @Author tanyp
* @Date 2023/3/29 9:13
**/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "用户权限信息")
public class UserAuthVo {
@ApiModelProperty(value = "用户名称")
private String username;
@ApiModelProperty(value = "用户昵称")
private String nickname;
@ApiModelProperty(value = "用户类型1、管理员2、普通用户")
private Integer type;
@ApiModelProperty(value = "头像")
private String avatar;
@ApiModelProperty(value = "手机号")
private String phone;
@ApiModelProperty(value = "邮箱")
private String email;
}

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.tansci.domain.SysUser;
import com.tansci.domain.vo.SysUserVo;
import com.tansci.domain.vo.UserAuthVo;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@ -22,6 +23,8 @@ public interface SysUserService extends IService<SysUser> {
List<SysUser> list(SysUser user);
UserAuthVo info();
Object insert(SysUser user);
Object update(SysUser user);

View File

@ -12,6 +12,7 @@ import com.tansci.domain.SysUser;
import com.tansci.domain.SysUserRole;
import com.tansci.domain.vo.SysUserSessionVo;
import com.tansci.domain.vo.SysUserVo;
import com.tansci.domain.vo.UserAuthVo;
import com.tansci.mapper.SysUserMapper;
import com.tansci.service.SysLoginLogService;
import com.tansci.service.SysUserRoleService;
@ -27,7 +28,6 @@ import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @ClassName SysUserServiceImpl.java
@ -77,6 +77,18 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
);
}
@Override
public UserAuthVo info() {
SysUser user = this.baseMapper.selectById(String.valueOf(StpUtil.getLoginId()));
return UserAuthVo.builder()
.username(user.getUsername())
.nickname(user.getNickname())
.type(user.getType())
.phone(user.getPhone())
.email(user.getEmail())
.build();
}
@Override
public Object insert(SysUser user) {
Integer count = this.baseMapper.selectCount(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, user.getUsername()));
@ -174,7 +186,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
public Object modifyPass(SysUser user) {
SysUser sysUser = this.baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, user.getUsername()));
if (Objects.isNull(sysUser) || !Objects.equals(Sha256Util.getSHA256(sysUser.getPassword()), Sha256Util.getSHA256(user.getPassword()))) {
if (Objects.isNull(sysUser) || !Objects.equals(sysUser.getPassword(), Sha256Util.getSHA256(user.getOldPassword()))) {
throw new BusinessException("原始密码错误,请重新输入!");
}