mirror of
https://gitee.com/xiongmao1988/rax-medical.git
synced 2025-08-23 20:44:58 +08:00
parent
2b42615aca
commit
03c27fd31b
4
.env
4
.env
|
@ -1,3 +1,5 @@
|
|||
VITE_PWD_ENC_KEY='thanks,rax4cloud'
|
||||
|
||||
VITE_OAUTH2_PASSWORD_CLIENT='rax:rax'
|
||||
VITE_OAUTH2_PASSWORD_CLIENT='rax:rax'
|
||||
|
||||
VITE_RAX_BASE_URL='/api'
|
|
@ -1,11 +1,10 @@
|
|||
import axios from "axios";
|
||||
import * as other from "@/utils/other";
|
||||
import {get, HOST, post} from "@/utils/request";
|
||||
import {ElMessage} from "element-plus";
|
||||
import request, {CommonHeaderEnum, postData} from "@/utils/request";
|
||||
|
||||
const FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded';
|
||||
const registerUrl = "/admin/register/user"
|
||||
|
||||
const logoutUrl = "/admin/token/logout"
|
||||
|
||||
export const login = (data: any) => {
|
||||
return new Promise(resolve => {
|
||||
|
@ -19,30 +18,46 @@ export const login = (data: any) => {
|
|||
data.grant_type = 'password';
|
||||
data.scope = 'server';
|
||||
|
||||
axios.request({
|
||||
url: '/api/admin/oauth2/token',
|
||||
request({
|
||||
url: '/admin/oauth2/token',
|
||||
method: 'post',
|
||||
data: {...data, password: encPassword},
|
||||
headers: {
|
||||
skipToken: true,
|
||||
Authorization: basicAuth,
|
||||
'Content-Type': FORM_CONTENT_TYPE,
|
||||
'Content-Type': CommonHeaderEnum.FORM_CONTENT_TYPE,
|
||||
},
|
||||
}).then(res => {
|
||||
resolve(res.data);
|
||||
}).then((res: any) => {
|
||||
resolve(res.data ? res.data : res.response.data)
|
||||
}).catch(err => {
|
||||
if (err && err.response && err.response.data && err.response.data.msg) {
|
||||
ElMessage.error(err.response.data.msg)
|
||||
} else {
|
||||
ElMessage.error('系统异常请联系管理员')
|
||||
}
|
||||
resolve(err)
|
||||
handleError(err)
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
export const register = (data: any) => {
|
||||
return new Promise(resolve => {
|
||||
console.log(data)
|
||||
resolve(true)
|
||||
postData(registerUrl, data).then(res => {
|
||||
resolve(res.data)
|
||||
}).catch(err => {
|
||||
resolve(err)
|
||||
handleError(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return request({
|
||||
url: logoutUrl,
|
||||
method: "DELETE"
|
||||
})
|
||||
}
|
||||
|
||||
function handleError(err: any) {
|
||||
if (err && err.msg) {
|
||||
ElMessage.error(err.msg)
|
||||
} else {
|
||||
ElMessage.error('系统异常请联系管理员')
|
||||
}
|
||||
}
|
|
@ -22,3 +22,56 @@ export const reqUserInfo = () =>
|
|||
//退出登录
|
||||
export const reqLogout = () => request.post<any, any>(API.LOGOUT_URL)
|
||||
*/
|
||||
import request, {getData} from "@/utils/request";
|
||||
|
||||
const userInfoUrl = '/admin/user/info'
|
||||
|
||||
const editUserUrl = '/admin/user/edit'
|
||||
|
||||
const editPasswordUrl = '/admin/user/password'
|
||||
|
||||
const userPageUrl = '/admin/user/page'
|
||||
|
||||
export function getUserInfo() {
|
||||
return new Promise(resolve => {
|
||||
getData(userInfoUrl).then((data: any) => {
|
||||
resolve(data.data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function updateUserInfo(data: any) {
|
||||
return new Promise(resolve => {
|
||||
request.request({
|
||||
url: editUserUrl,
|
||||
method: 'put',
|
||||
data
|
||||
}).then((res: any) => {
|
||||
resolve(res.data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function editPassword(data: any) {
|
||||
return new Promise(resolve => {
|
||||
request.request({
|
||||
url: editPasswordUrl,
|
||||
method: "PUT",
|
||||
data
|
||||
}).then((res: any) => {
|
||||
resolve(res.data)
|
||||
}).catch(err => {
|
||||
resolve(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function userPage(data: any) {
|
||||
return new Promise(resolve => {
|
||||
getData(userPageUrl, data).then((res: any) => {
|
||||
resolve(res.data)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import request from "@/utils/request";
|
||||
|
||||
export const fileUploadUrl = '/admin/sys-file/upload'
|
||||
|
||||
export const handleHttpUpload = (options: any) => {
|
||||
let formData = new FormData();
|
||||
formData.append('file', options.file);
|
||||
formData.append('dir', options.dir)
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
request({
|
||||
url: fileUploadUrl,
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: formData,
|
||||
}).then((res: any) => {
|
||||
resolve(res.data)
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,16 +1,15 @@
|
|||
import axios from "axios";
|
||||
import request, {CommonHeaderEnum} from "@/utils/request";
|
||||
|
||||
const getHospitalListUrl = "/api/admin/hospital/getHospitalList"
|
||||
const getHospitalPageUrl = "/api/admin/hospital/getHospitalPage"
|
||||
const FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded'
|
||||
const getHospitalListUrl = "/admin/hospital/getHospitalList"
|
||||
const getHospitalPageUrl = "/admin/hospital/getHospitalPage"
|
||||
|
||||
export const getHospitalList = () => {
|
||||
return new Promise(resolve => {
|
||||
axios.request({
|
||||
request({
|
||||
url: getHospitalListUrl,
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': FORM_CONTENT_TYPE,
|
||||
'Content-Type': CommonHeaderEnum.FORM_CONTENT_TYPE,
|
||||
},
|
||||
}).then(res => {
|
||||
resolve(res.data);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import request, {CommonHeaderEnum} from "@/utils/request";
|
||||
|
||||
const getMonthlyLogCountUrl = '/admin/log/getMonthlyLogCount'
|
||||
|
||||
export function getMonthlyLogCount(startTime: string, endTime: string) {
|
||||
return new Promise(resolve => {
|
||||
request({
|
||||
url: getMonthlyLogCountUrl,
|
||||
method: 'post',
|
||||
data: {
|
||||
startTime,
|
||||
endTime
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': CommonHeaderEnum.FORM_CONTENT_TYPE,
|
||||
},
|
||||
}).then(res => {
|
||||
resolve(res.data);
|
||||
})
|
||||
})
|
||||
}
|
|
@ -1,71 +1,88 @@
|
|||
<template>
|
||||
<div class="user-info-part">
|
||||
<div class="header-box">
|
||||
<h3>个人信息</h3>
|
||||
<el-icon @click="close">
|
||||
<Close />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="custom-tabs">
|
||||
<div class="tabs-item" v-for="(item, index) in ['基础信息', '安全信息']" :key="item"
|
||||
:class="{ 'active': tabActive === index }" @click="tabActive = index">{{ item }}</div>
|
||||
</div>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="60">
|
||||
<template v-if="tabActive === 0">
|
||||
<el-upload action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" :limit="1"
|
||||
:show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
|
||||
<img v-if="formData.avatar" :src="formData.avatar" class="avatar" />
|
||||
<img v-else src="@/assets/imgs/home/avatar.png" class="avatar" />
|
||||
</el-upload>
|
||||
<el-form-item label="用户名" prop="account">
|
||||
<el-input v-model="formData.account" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
<el-input v-model="formData.phone" placeholder="请输入手机号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入姓名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="mailbox">
|
||||
<el-input v-model="formData.mailbox" placeholder="请输入邮箱"></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-form-item label="密码" prop="password" label-width="100">
|
||||
<el-input v-model="formData.password" type="password" show-password placeholder="请输入密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword" label-width="100">
|
||||
<el-input v-model="formData.newPassword" type="password" show-password placeholder="请输入新密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword" label-width="100">
|
||||
<el-input v-model="formData.confirmPassword" type="password" show-password placeholder="请输入新密码"></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
<div class="submit-box">
|
||||
<el-button type="primary" @click="submitForm">{{ tabActive === 0 ? '更新个人信息' : '修改密码' }}</el-button>
|
||||
</div>
|
||||
<div class="user-info-part">
|
||||
<div class="header-box">
|
||||
<h3>个人信息</h3>
|
||||
<el-icon @click="close">
|
||||
<Close/>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="custom-tabs">
|
||||
<div class="tabs-item" v-for="(item, index) in ['基础信息', '安全信息']" :key="item"
|
||||
:class="{ 'active': tabActive === index }" @click="tabActive = index">{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="60">
|
||||
<template v-if="tabActive === 0">
|
||||
<el-upload action="#" :limit="1" :http-request="handleUpload" ref="uploadRef"
|
||||
:show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
|
||||
<img v-if="formData.avatar" :src="'/api' + formData.avatar" class="avatar"/>
|
||||
<img v-else src="@/assets/imgs/home/avatar.png" class="avatar"/>
|
||||
</el-upload>
|
||||
<el-form-item label="用户名" prop="account">
|
||||
<el-input v-model="formData.account" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
<el-input v-model="formData.phone" placeholder="请输入手机号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入姓名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="mailbox">
|
||||
<el-input v-model="formData.mailbox" placeholder="请输入邮箱"></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-form-item label="密码" prop="password" label-width="100">
|
||||
<el-input v-model="formData.password" type="password" show-password placeholder="请输入密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword" label-width="100">
|
||||
<el-input v-model="formData.newPassword" type="password" show-password placeholder="请输入新密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword" label-width="100">
|
||||
<el-input v-model="formData.confirmPassword" type="password" show-password
|
||||
placeholder="请输入新密码"></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
<div class="submit-box">
|
||||
<el-button type="primary" @click="submitForm">{{ tabActive === 0 ? '更新个人信息' : '修改密码' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup>
|
||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { UploadProps } from 'element-plus'
|
||||
import { useLoginStore } from '@/stores/user-info-store'
|
||||
import {onMounted, reactive, ref, toRefs, watch} from 'vue'
|
||||
import {ElMessage} from 'element-plus'
|
||||
import type {UploadProps} from 'element-plus'
|
||||
import {useLoginStore} from '@/stores/user-info-store'
|
||||
import {editPassword, getUserInfo, updateUserInfo} from "@/api/acl/user";
|
||||
import {handleHttpUpload} from "@/api/file-upload";
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
|
||||
const userInfo = useLoginStore().getlogin()
|
||||
// const userInfo = useLoginStore().getlogin()
|
||||
|
||||
const formRef = ref()
|
||||
const uploadRef = ref()
|
||||
|
||||
onMounted(() => {
|
||||
getUserInfo().then((res: any) => {
|
||||
if (res.data) {
|
||||
formData.value.account = res.data.sysUser.username
|
||||
formData.value.name = res.data.sysUser.name
|
||||
formData.value.phone = res.data.sysUser.phone
|
||||
formData.value.mailbox = res.data.sysUser.email
|
||||
formData.value.avatar = res.data.sysUser.avatar
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const validatePassword = (rule: any, value: any, callback: any) => {
|
||||
if (formData.value.newPassword !== formData.value.confirmPassword) {
|
||||
callback(new Error('两次密码不一致'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
if (formData.value.newPassword !== formData.value.confirmPassword) {
|
||||
callback(new Error('两次密码不一致'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
//自定义校验规则函数
|
||||
|
@ -93,103 +110,156 @@ const validatorPhone = (rule: any, value: any, callback: any) => {
|
|||
}
|
||||
|
||||
const rules = reactive({
|
||||
phone: [
|
||||
{ required: true, validator:validatorPhone, trigger: 'blur' },
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '请输入姓名', trigger: 'blur' },
|
||||
],
|
||||
mailbox: [
|
||||
{ type: 'email', message: '邮箱格式不正确', trigger: ['blur', 'change'] },
|
||||
],
|
||||
password: [
|
||||
{ required: true, validator: validatorPassword, trigger: 'change' },
|
||||
],
|
||||
newPassword: [
|
||||
{ required: true, validator: validatorPassword, trigger: 'change' },
|
||||
//{ validator: validatePassword, trigger: 'blur' }
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: '请输入密码', trigger: 'change' },
|
||||
{ validator: validatePassword, trigger: 'blur' }
|
||||
]
|
||||
phone: [
|
||||
{required: true, validator: validatorPhone, trigger: 'blur'},
|
||||
],
|
||||
name: [
|
||||
{required: true, message: '请输入姓名', trigger: 'blur'},
|
||||
],
|
||||
mailbox: [
|
||||
{type: 'email', message: '邮箱格式不正确', trigger: ['blur', 'change']},
|
||||
],
|
||||
password: [
|
||||
{required: true, validator: validatorPassword, trigger: 'change'},
|
||||
],
|
||||
newPassword: [
|
||||
{required: true, validator: validatorPassword, trigger: 'change'},
|
||||
//{ validator: validatePassword, trigger: 'blur' }
|
||||
],
|
||||
confirmPassword: [
|
||||
{required: true, message: '请输入密码', trigger: 'change'},
|
||||
{validator: validatePassword, trigger: 'blur'}
|
||||
]
|
||||
})
|
||||
const tabActive = ref(0)
|
||||
const formData = ref({
|
||||
avatar: '',
|
||||
account: userInfo.account,
|
||||
phone: '',
|
||||
name: userInfo.name,
|
||||
mailbox: '',
|
||||
password: '',
|
||||
newPassword: '',
|
||||
confirmPassword: ''
|
||||
avatar: '',
|
||||
account: "",
|
||||
phone: '',
|
||||
name: "",
|
||||
mailbox: '',
|
||||
password: '',
|
||||
newPassword: '',
|
||||
confirmPassword: ''
|
||||
})
|
||||
|
||||
const close = () => {
|
||||
emit('close')
|
||||
emit('close')
|
||||
}
|
||||
const handleAvatarSuccess: UploadProps['onSuccess'] = (
|
||||
uploadFile
|
||||
) => {
|
||||
formData.value.avatar = URL.createObjectURL(uploadFile.raw!)
|
||||
function handleAvatarSuccess(uploadFile: any) {
|
||||
}
|
||||
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
||||
if (rawFile.type !== 'image/jpeg') {
|
||||
ElMessage.error('图片必须为jpg格式!')
|
||||
return false
|
||||
} else if (rawFile.size / 1024 / 1024 > 2) {
|
||||
ElMessage.error('图片大小不得超过2MB!')
|
||||
return false
|
||||
|
||||
function handleUpload(options: any) {
|
||||
handleHttpUpload(options).then((res: any) => {
|
||||
console.log(res)
|
||||
if (res && res.code == 0) {
|
||||
formData.value.avatar = res.data.url
|
||||
const param = {
|
||||
avatar: formData.value.avatar,
|
||||
username: formData.value.account
|
||||
}
|
||||
updateUserInfo(param).then((res: any) => {
|
||||
uploadRef.value.clearFiles();
|
||||
if (res && res.code != 0) {
|
||||
ElMessage.error(res.msg)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ElMessage.error('图片格式错误')
|
||||
}
|
||||
return true
|
||||
|
||||
}).catch(err => {
|
||||
ElMessage.error('图片格式错误')
|
||||
options.onError(err);
|
||||
})
|
||||
}
|
||||
|
||||
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
||||
if (rawFile.type !== 'image/jpeg') {
|
||||
ElMessage.error('图片必须为jpg格式!')
|
||||
return false
|
||||
} else if (rawFile.size / 1024 / 1024 > 2) {
|
||||
ElMessage.error('图片大小不得超过2MB!')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
const submitForm = async () => {
|
||||
await formRef.value.validate((valid: any, fields: any) => {
|
||||
if (valid) {
|
||||
// console.log('submit!')
|
||||
// 更改用户名
|
||||
useLoginStore().setlogin('name', formData.value.name)
|
||||
await formRef.value.validate((valid: any, fields: any) => {
|
||||
if (valid) {
|
||||
// console.log('submit!')
|
||||
// 更改用户名
|
||||
// useLoginStore().setlogin('name', formData.value.name)
|
||||
if (tabActive.value == 0) {
|
||||
const param = {
|
||||
name: formData.value.name,
|
||||
phone: formData.value.phone,
|
||||
email: formData.value.mailbox,
|
||||
username: formData.value.account
|
||||
}
|
||||
updateUserInfo(param).then((res: any) => {
|
||||
if (res && res.code == 0) {
|
||||
ElMessage.success('更新成功')
|
||||
close()
|
||||
} else {
|
||||
// console.log('error submit!', fields)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ElMessage.error(res.msg)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
editPassword({
|
||||
password: formData.value.password,
|
||||
newpassword1: formData.value.newPassword
|
||||
}).then((res: any) => {
|
||||
if (res && res.code == 0) {
|
||||
formRef.value.resetFields(['password', 'newPassword', 'confirmPassword'])
|
||||
ElMessage.success("修改密码成功")
|
||||
close()
|
||||
} else {
|
||||
ElMessage.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// console.log('error submit!', fields)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.user-info-part {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 30px;
|
||||
|
||||
.header-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 30px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.header-box {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
h3 {
|
||||
color: $main-color;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: $main-color;
|
||||
font-size: 20px;
|
||||
}
|
||||
.el-icon {
|
||||
cursor: pointer;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
cursor: pointer;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
img.avatar {
|
||||
width: 128px;
|
||||
height: 148px;
|
||||
object-fit: contain;
|
||||
margin: 0 0 20px 60px;
|
||||
}
|
||||
.submit-box {
|
||||
padding-left: 60px;
|
||||
}
|
||||
img.avatar {
|
||||
width: 128px;
|
||||
height: 148px;
|
||||
object-fit: contain;
|
||||
margin: 0 0 20px 60px;
|
||||
}
|
||||
|
||||
.submit-box {
|
||||
padding-left: 60px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -34,11 +34,11 @@ export const getMessageType = () => {
|
|||
|
||||
export const getLogType = () => {
|
||||
const type = []
|
||||
type.push({ label: '正常', value: '正常' })
|
||||
type.push({ label: '异常', value: '异常' })
|
||||
type.push({ label: '添加', value: '添加' })
|
||||
type.push({ label: '删除', value: '删除' })
|
||||
type.push({ label: '编辑', value: '编辑' })
|
||||
type.push({ label: '正常', value: '0' })
|
||||
type.push({ label: '异常', value: '9' })
|
||||
type.push({ label: '添加', value: '1' })
|
||||
type.push({ label: '删除', value: '2' })
|
||||
type.push({ label: '编辑', value: '3' })
|
||||
return type
|
||||
}
|
||||
|
||||
|
|
|
@ -87,4 +87,8 @@ export function getDays(date: any, days: number) {
|
|||
const time = date.setDate(date.getDate() + days); // 天数
|
||||
return new Date(time);
|
||||
}
|
||||
}
|
||||
|
||||
export function getEndOfMonth(year: number, month: number) {
|
||||
return new Date(year, month, 0).getDate()
|
||||
}
|
|
@ -1,16 +1,29 @@
|
|||
//进行axios二次封装:使用请求与响应拦截器
|
||||
import axios from "axios";
|
||||
import {Session} from "@/utils/storage";
|
||||
import {decryption, encryption} from "@/utils/other";
|
||||
import {ElMessageBox} from "element-plus";
|
||||
/*
|
||||
import { ElMessage } from 'element-plus'
|
||||
//引入用户相关的仓库
|
||||
import useUserStore from '@/stores/modules/user'
|
||||
*/
|
||||
|
||||
export const HOST = 'http://localhost:9999';
|
||||
const BASE_URL = import.meta.env.BASE_URL
|
||||
const BASE_URL = import.meta.env.VITE_RAX_BASE_URL
|
||||
|
||||
export enum CommonHeaderEnum {
|
||||
'TENANT_ID' = 'TENANT-ID',
|
||||
'ENC_FLAG' = 'Enc-Flag',
|
||||
'AUTHORIZATION' = 'Authorization',
|
||||
'FORM_CONTENT_TYPE' = 'application/x-www-form-urlencoded'
|
||||
}
|
||||
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: BASE_URL
|
||||
});
|
||||
|
||||
export const get = (url: any, params: any, success: any) => {
|
||||
axios.get(HOST + url, params)
|
||||
axiosInstance.get(url, params)
|
||||
.then(res => {
|
||||
success(res);
|
||||
})
|
||||
|
@ -18,19 +31,63 @@ export const get = (url: any, params: any, success: any) => {
|
|||
success(err);
|
||||
});
|
||||
};
|
||||
export const post = (url: any, params: any, config?: any) => {
|
||||
return axios.post(HOST + url, params, config);
|
||||
export const post = (url: any, params: any, success: any) => {
|
||||
axiosInstance.post(url, params)
|
||||
.then(res => {
|
||||
success(res);
|
||||
})
|
||||
.catch(err => {
|
||||
success(err);
|
||||
});
|
||||
};
|
||||
export const getMapJson = (name: string) => {
|
||||
return axios.post(BASE_URL + '/static/json/' + name)
|
||||
return axiosInstance.post(BASE_URL+'/static/json/' + name)
|
||||
}
|
||||
export const getData = (url: string, params?: any) => {
|
||||
return axios.get(url, params)
|
||||
return axiosInstance.get(url, params)
|
||||
}
|
||||
export const postData = (url: string, params?: any) => {
|
||||
return axios.post(url, params)
|
||||
return axiosInstance.post(url, params)
|
||||
}
|
||||
|
||||
axiosInstance.interceptors.request.use(data => {
|
||||
const token = Session.getToken()
|
||||
if (token && !data.headers?.skipToken) {
|
||||
data.headers[CommonHeaderEnum.AUTHORIZATION] = `Bearer ${token}`
|
||||
}
|
||||
if (data.headers[CommonHeaderEnum.ENC_FLAG]) {
|
||||
const val = encryption(JSON.stringify(data.data), import.meta.env.VITE_PWD_ENC_KEY)
|
||||
data.data = {
|
||||
encryption: val
|
||||
}
|
||||
}
|
||||
return data
|
||||
})
|
||||
|
||||
function handleResponse(response: any) {
|
||||
if (response.data.code == 1) throw response.data
|
||||
if (response.data.encryption) {
|
||||
const val = JSON.parse(decryption(response.data.encryption, import.meta.env.VITE_PWD_ENC_KEY))
|
||||
response.data = val
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
axiosInstance.interceptors.response.use(handleResponse, error => {
|
||||
const code = error.response.status || 200
|
||||
if (code == 424) {
|
||||
ElMessageBox.confirm('令牌状态已过期,请点击重新登录', "系统提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: 'warning',
|
||||
});
|
||||
Session.clear();
|
||||
window.location.href = '/';
|
||||
}
|
||||
return error
|
||||
})
|
||||
|
||||
export default axiosInstance
|
||||
|
||||
/*
|
||||
//第一步:利用axios对象的create方法,去创建axios实例(其他的配置:基础路径、超时的时间)
|
||||
|
|
|
@ -1,71 +1,75 @@
|
|||
<template>
|
||||
<div class="page-content">
|
||||
<div class="head-box">
|
||||
<div class="logo-box">
|
||||
<img src="@/assets/imgs/logo.png" />
|
||||
</div>
|
||||
<ul class="menu-box">
|
||||
<li class="menu-item" v-for="item in menus" :key="item.path" :class="{ 'active': menuActive.indexOf(item.path) === 0 }"
|
||||
@click="menuToPath(item)"><i :class="item.icon"></i><span>{{ item.label
|
||||
}}</span></li>
|
||||
</ul>
|
||||
<div class="user-box">
|
||||
<!-- 超级管理员可切换医院 -->
|
||||
<el-select v-if="userInfo.permissions === '超级管理员'" class="select-hospital" style="width: 150px;"
|
||||
:model-value="userInfo.hospital" size="small" @change="selectHospital">
|
||||
<el-option v-for="item in hospitals" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<span v-else class="area">{{ userInfo.hospital }}</span>
|
||||
<el-button text>
|
||||
<el-icon>
|
||||
<Search />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-button text>
|
||||
<el-badge is-dot>
|
||||
<el-icon>
|
||||
<Bell />
|
||||
</el-icon>
|
||||
</el-badge>
|
||||
</el-button>
|
||||
<el-button text @click="toggleFullscreen">
|
||||
<el-icon>
|
||||
<FullScreen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-dropdown trigger="click" @command="userCommand">
|
||||
<div class="page-content">
|
||||
<div class="head-box">
|
||||
<div class="logo-box">
|
||||
<img src="@/assets/imgs/logo.png"/>
|
||||
</div>
|
||||
<ul class="menu-box">
|
||||
<li class="menu-item" v-for="item in menus" :key="item.path"
|
||||
:class="{ 'active': menuActive.indexOf(item.path) === 0 }"
|
||||
@click="menuToPath(item)"><i :class="item.icon"></i><span>{{
|
||||
item.label
|
||||
}}</span></li>
|
||||
</ul>
|
||||
<div class="user-box">
|
||||
<!-- 超级管理员可切换医院 -->
|
||||
<el-select v-if="userInfo.permissions === '超级管理员'" class="select-hospital" style="width: 150px;"
|
||||
:model-value="userInfo.hospital" size="small" @change="selectHospital">
|
||||
<el-option v-for="item in hospitals" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
<span v-else class="area">{{ userInfo.hospital }}</span>
|
||||
<el-button text>
|
||||
<el-icon>
|
||||
<Search/>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-button text>
|
||||
<el-badge is-dot>
|
||||
<el-icon>
|
||||
<Bell/>
|
||||
</el-icon>
|
||||
</el-badge>
|
||||
</el-button>
|
||||
<el-button text @click="toggleFullscreen">
|
||||
<el-icon>
|
||||
<FullScreen/>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-dropdown trigger="click" @command="userCommand">
|
||||
<span class="el-dropdown-link">
|
||||
{{ userInfo.name }}
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
<arrow-down/>
|
||||
</el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="info">个人信息</el-dropdown-item>
|
||||
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main-content">
|
||||
<RouterView />
|
||||
</div>
|
||||
<el-drawer v-model="isShowUserInfoDrawer" size="35%" :with-header="false">
|
||||
<userInfoForm @close="isShowUserInfoDrawer = false" />
|
||||
</el-drawer>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="info">个人信息</el-dropdown-item>
|
||||
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main-content">
|
||||
<RouterView/>
|
||||
</div>
|
||||
<el-drawer v-model="isShowUserInfoDrawer" size="35%" :with-header="false">
|
||||
<userInfoForm @close="isShowUserInfoDrawer = false"/>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup>
|
||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useLoginStore } from '@/stores/user-info-store'
|
||||
import { getHospitalsData } from '@/static-data/core'
|
||||
import {onMounted, reactive, ref, toRefs, watch} from 'vue'
|
||||
import {useRouter, useRoute} from 'vue-router'
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
import {useLoginStore} from '@/stores/user-info-store'
|
||||
import {getHospitalsData} from '@/static-data/core'
|
||||
import userInfoForm from '@/components/user-info.vue'
|
||||
import {wsApi} from "@/api/ws";
|
||||
import {Session} from "@/utils/storage";
|
||||
import {logout} from "@/api/acl/login";
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
@ -73,49 +77,49 @@ const route = useRoute()
|
|||
const userInfo = useLoginStore().getlogin()
|
||||
const hospitals = ref([] as any)
|
||||
getHospitalsData().then((res: any) => {
|
||||
hospitals.value = res
|
||||
// console.log(res)
|
||||
hospitals.value = res
|
||||
// console.log(res)
|
||||
})
|
||||
|
||||
const menus = [] as any
|
||||
switch (userInfo.permissions) {
|
||||
case '超级管理员':
|
||||
menus.push({ label: '首页', path: '/home', icon: 'icon-shouye' })
|
||||
menus.push({ label: '权限管理', path: '/permissions-manage', icon: 'icon-users' })
|
||||
menus.push({ label: '患者管理', path: '/patients-manage', icon: 'icon-renyuanguanli' })
|
||||
menus.push({ label: '远程管理', path: '/remote-manage', icon: 'icon-anquanbaozhang' })
|
||||
menus.push({ label: '后台管理', path: '/system-manage', icon: 'icon-houtaiguanli' })
|
||||
menus.push({ label: '系统管理', path: '/logs-manage', icon: 'icon-setting' })
|
||||
break;
|
||||
case '高级管理员':
|
||||
menus.push({ label: '首页', path: '/home', icon: 'icon-shouye' })
|
||||
menus.push({ label: '权限管理', path: '/permissions-manage', icon: 'icon-users' })
|
||||
menus.push({ label: '患者管理', path: '/patients-manage', icon: 'icon-renyuanguanli' })
|
||||
menus.push({ label: '远程管理', path: '/remote-manage', icon: 'icon-anquanbaozhang' })
|
||||
menus.push({ label: '系统管理', path: '/logs-manage', icon: 'icon-setting' })
|
||||
break;
|
||||
case '中级管理员':
|
||||
menus.push({ label: '首页', path: '/home', icon: 'icon-shouye' })
|
||||
menus.push({ label: '患者管理', path: '/patients-manage', icon: 'icon-renyuanguanli' })
|
||||
menus.push({ label: '远程管理', path: '/remote-manage', icon: 'icon-anquanbaozhang' })
|
||||
break;
|
||||
case '普通用户':
|
||||
menus.push({ label: '首页', path: '/home', icon: 'icon-shouye' })
|
||||
menus.push({ label: '患者管理', path: '/patients-manage', icon: 'icon-renyuanguanli' })
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case '超级管理员':
|
||||
menus.push({label: '首页', path: '/home', icon: 'icon-shouye'})
|
||||
menus.push({label: '权限管理', path: '/permissions-manage', icon: 'icon-users'})
|
||||
menus.push({label: '患者管理', path: '/patients-manage', icon: 'icon-renyuanguanli'})
|
||||
menus.push({label: '远程管理', path: '/remote-manage', icon: 'icon-anquanbaozhang'})
|
||||
menus.push({label: '后台管理', path: '/system-manage', icon: 'icon-houtaiguanli'})
|
||||
menus.push({label: '系统管理', path: '/logs-manage', icon: 'icon-setting'})
|
||||
break;
|
||||
case '高级管理员':
|
||||
menus.push({label: '首页', path: '/home', icon: 'icon-shouye'})
|
||||
menus.push({label: '权限管理', path: '/permissions-manage', icon: 'icon-users'})
|
||||
menus.push({label: '患者管理', path: '/patients-manage', icon: 'icon-renyuanguanli'})
|
||||
menus.push({label: '远程管理', path: '/remote-manage', icon: 'icon-anquanbaozhang'})
|
||||
menus.push({label: '系统管理', path: '/logs-manage', icon: 'icon-setting'})
|
||||
break;
|
||||
case '中级管理员':
|
||||
menus.push({label: '首页', path: '/home', icon: 'icon-shouye'})
|
||||
menus.push({label: '患者管理', path: '/patients-manage', icon: 'icon-renyuanguanli'})
|
||||
menus.push({label: '远程管理', path: '/remote-manage', icon: 'icon-anquanbaozhang'})
|
||||
break;
|
||||
case '普通用户':
|
||||
menus.push({label: '首页', path: '/home', icon: 'icon-shouye'})
|
||||
menus.push({label: '患者管理', path: '/patients-manage', icon: 'icon-renyuanguanli'})
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const isShowUserInfoDrawer = ref(false)
|
||||
const menuActive = ref('/')
|
||||
|
||||
router.isReady().then(() => {
|
||||
menuActive.value = route.path
|
||||
menuActive.value = route.path
|
||||
})
|
||||
router.beforeEach((to, from, next) => {
|
||||
menuActive.value = to.path
|
||||
next()
|
||||
menuActive.value = to.path
|
||||
next()
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
|
@ -123,167 +127,163 @@ onMounted(() => {
|
|||
})
|
||||
|
||||
const menuToPath = (e: any) => {
|
||||
menuActive.value = e.path
|
||||
router.push(e.path)
|
||||
menuActive.value = e.path
|
||||
router.push(e.path)
|
||||
}
|
||||
// 切换医院
|
||||
const selectHospital = (e: any) => {
|
||||
// 根据实际情况看是否需要重新登录
|
||||
ElMessageBox.confirm(
|
||||
'是否跳转到登录页面登录到所选择医院?',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'success',
|
||||
draggable: true
|
||||
}
|
||||
).then(() => {
|
||||
useLoginStore().setlogin('hospital', e)
|
||||
router.push('/login')
|
||||
}).catch(() => { })
|
||||
// 根据实际情况看是否需要重新登录
|
||||
ElMessageBox.confirm(
|
||||
'是否跳转到登录页面登录到所选择医院?',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'success',
|
||||
draggable: true
|
||||
}
|
||||
).then(() => {
|
||||
// useLoginStore().setlogin('hospital', e)
|
||||
router.push('/login')
|
||||
}).catch(() => {
|
||||
})
|
||||
}
|
||||
const toggleFullscreen = () => {
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen();
|
||||
} else {
|
||||
document.documentElement.requestFullscreen();
|
||||
}
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen();
|
||||
} else {
|
||||
document.documentElement.requestFullscreen();
|
||||
}
|
||||
}
|
||||
const userCommand = (e: string) => {
|
||||
switch (e) {
|
||||
case 'logout':
|
||||
useLoginStore().logout()
|
||||
router.push('/login')
|
||||
break;
|
||||
case 'info':
|
||||
isShowUserInfoDrawer.value = true
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const userCommand = async (e: string) => {
|
||||
switch (e) {
|
||||
case 'logout':
|
||||
// useLoginStore().logout()
|
||||
await logout()
|
||||
Session.clear();
|
||||
window.location.reload();
|
||||
break;
|
||||
case 'info':
|
||||
isShowUserInfoDrawer.value = true
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*wsApi.init("").then(() => {
|
||||
wsApi.openListener(fn1);
|
||||
})
|
||||
|
||||
|
||||
function fn1(res:any) {
|
||||
console.log(res);
|
||||
}*/
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.page-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.head-box {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: 70px;
|
||||
padding: 0 464px 0 284px;
|
||||
background: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.head-box {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
padding: 0 464px 0 284px;
|
||||
background: white;
|
||||
.logo-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 24px;
|
||||
margin-right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
img {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.menu-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
|
||||
.menu-item {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.logo-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 24px;
|
||||
margin-right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: $main-color;
|
||||
height: 70px;
|
||||
padding: 0 15px;
|
||||
margin: 0;
|
||||
transition: all .5s;
|
||||
-webkit-transition: all .5s;
|
||||
|
||||
img {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.menu-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
|
||||
.menu-item {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: $main-color;
|
||||
height: 70px;
|
||||
padding: 0 15px;
|
||||
margin: 0;
|
||||
transition: all .5s;
|
||||
-webkit-transition: all .5s;
|
||||
|
||||
&:hover {
|
||||
background: #f2f3f5;
|
||||
transition: all .5s;
|
||||
-webkit-transition: all .5s;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: #f2f3f5;
|
||||
transition: all .5s;
|
||||
-webkit-transition: all .5s;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: #f2f3f5;
|
||||
transition: all .5s;
|
||||
-webkit-transition: all .5s;
|
||||
}
|
||||
|
||||
.user-box {
|
||||
position: absolute;
|
||||
width: 440px;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
right: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
background: white;
|
||||
|
||||
.select-hospital {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.area {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: $main-color;
|
||||
line-height: 1.6;
|
||||
padding: 0 20px;
|
||||
border: 1px solid #8c9094;
|
||||
border-radius: 7px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
&>.el-button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&>.el-dropdown {
|
||||
flex-shrink: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-dropdown-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
&.active {
|
||||
background: #f2f3f5;
|
||||
transition: all .5s;
|
||||
-webkit-transition: all .5s;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&>.main-content {
|
||||
width: 100%;
|
||||
height: calc(100% - 70px);
|
||||
background: #f5f7fa;
|
||||
|
||||
.user-box {
|
||||
position: absolute;
|
||||
width: 440px;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
right: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
background: white;
|
||||
|
||||
.select-hospital {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.area {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: $main-color;
|
||||
line-height: 1.6;
|
||||
padding: 0 20px;
|
||||
border: 1px solid #8c9094;
|
||||
border-radius: 7px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
& > .el-button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
& > .el-dropdown {
|
||||
flex-shrink: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-dropdown-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .main-content {
|
||||
width: 100%;
|
||||
height: calc(100% - 70px);
|
||||
background: #f5f7fa;
|
||||
}
|
||||
}
|
||||
|
||||
// @media screen and (max-width: 1610px) {
|
||||
|
@ -297,6 +297,6 @@ function fn1(res:any) {
|
|||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
</style>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class="right-content">
|
||||
<div class="select-hospital-box">
|
||||
<el-select class="select-hospital" v-model="currentHospital" size="small" @change="selectHospital">
|
||||
<el-option v-for="item in hospitals" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
<el-option v-for="item in hospitals" :key="item.id" :label="item.name" :value="item.id"/>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
|
@ -66,7 +66,7 @@
|
|||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-button class="login-btn" type="primary" @click="login('code')">登录</el-button>
|
||||
<el-button class="login-btn" type="primary" @click="login('code')">登录</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
@ -94,8 +94,8 @@
|
|||
</el-form-item>
|
||||
<el-form-item label="医院" prop="hospital">
|
||||
<el-select v-model="registerParams.hospital" style="width: 100%;">
|
||||
<el-option v-for="item in hospitals" :key="item.value" :label="item.label"
|
||||
:value="item.value"/>
|
||||
<el-option v-for="item in hospitals" :key="item.id" :label="item.name"
|
||||
:value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="sex">
|
||||
|
@ -121,20 +121,18 @@
|
|||
</div>
|
||||
</div>
|
||||
<SliderVerify v-model:isShowSelf="sliderVConf.isShowSelf" :width="sliderVConf.width" :imgUrl="sliderImgUrl"
|
||||
:height="sliderVConf.height" @success="sliderSuccess"></SliderVerify>
|
||||
:height="sliderVConf.height" @success="sliderSuccess" @close="sliderClose"></SliderVerify>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup>
|
||||
import {ElNotification} from 'element-plus';
|
||||
import {ElMessage, ElMessageBox, ElNotification} from 'element-plus';
|
||||
//引入获取当前时间的函数
|
||||
import {getTime} from '@/utils/time';
|
||||
import {onMounted, reactive, ref, toRefs, watch} from 'vue'
|
||||
import {useRouter, useRoute} from 'vue-router'
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
import {onMounted, reactive, ref} from 'vue'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
import {useLoginStore} from '@/stores/user-info-store'
|
||||
import {getHospitalsData, getPhoneAreasData} from '@/static-data/core'
|
||||
import {getPhoneAreasData} from '@/static-data/core'
|
||||
import {v4} from "uuid";
|
||||
import {HOST, post} from "@/utils/request";
|
||||
import SliderVerify from "@/components/SliderVerify/index.vue";
|
||||
import * as loginApi from "@/api/acl/login";
|
||||
import {Session} from "@/utils/storage";
|
||||
|
@ -147,10 +145,7 @@ import * as hospitalApi from "@/api/hospital";
|
|||
|
||||
const router = useRouter()
|
||||
|
||||
const hospitals = ref([] as any)
|
||||
getHospitalsData().then((res: any) => {
|
||||
hospitals.value = res
|
||||
})
|
||||
const hospitals = ref([])
|
||||
const phoneAreas: any = getPhoneAreasData()
|
||||
|
||||
//定义变量控制按钮加载效果
|
||||
|
@ -269,9 +264,13 @@ const sliderImgUrl = ref('')
|
|||
let randomStr = ""
|
||||
|
||||
onMounted(() => {
|
||||
hospitalApi.getHospitalList().then(data => {
|
||||
console.log(data)
|
||||
});
|
||||
hospitalApi.getHospitalList().then((res: any) => {
|
||||
if (res.data) {
|
||||
hospitals.value = res.data
|
||||
} else {
|
||||
hospitals.value.length = 0
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const selectHospital = (e: string) => {
|
||||
|
@ -324,47 +323,18 @@ const sendCode = () => {
|
|||
}, 1000);
|
||||
}
|
||||
const login = async (type: string) => {
|
||||
//加载效果:开始加载
|
||||
loading.value=true;
|
||||
const obj = loginParams.value
|
||||
if (!currentHospital.value) {
|
||||
ElMessage.warning('请在右上角选择院区')
|
||||
return
|
||||
}
|
||||
//加载效果:开始加载
|
||||
loading.value = true;
|
||||
//保证全部表单正常再发请求
|
||||
await loginFormRef.value.validate((valid: any, fields: any) => {
|
||||
if (valid) {
|
||||
// console.log('submit!')
|
||||
sliderVConf.value.isShowSelf = true;
|
||||
|
||||
} else {
|
||||
// console.log('error submit!', fields)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*try {
|
||||
//保证登录成功
|
||||
await useStore.userLogin(loginFormRef);
|
||||
//编程式导航跳转到展示数据首页
|
||||
//判断登录的时候,路由路径当中是否有query参数,如果有就往query参数挑战,没有跳转到首页
|
||||
let redirect: any = $route.query.redirect;
|
||||
$router.push({ path: redirect || '/' });
|
||||
|
||||
//登录成功加载效果也消失
|
||||
loading.value = false;
|
||||
}*/
|
||||
|
||||
|
||||
/*} catch (error) {
|
||||
//登录失败加载效果消息
|
||||
loading.value = false;
|
||||
//登录失败的提示信息
|
||||
ElNotification({
|
||||
type: 'error',
|
||||
message: (error as Error).message
|
||||
})*/
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
@ -385,13 +355,24 @@ function sliderSuccess() {
|
|||
password: loginParams.value.password, // 密码
|
||||
randomStr: v4()
|
||||
}).then((data: any) => {
|
||||
// 存储token 信息
|
||||
Session.set('token', data.access_token);
|
||||
Session.set('refresh_token', data.refresh_token);
|
||||
toHome()
|
||||
sliderVConf.value.isShowSelf = false
|
||||
if (data.code == 1) {
|
||||
ElMessage.error(data.msg)
|
||||
loading.value = false
|
||||
} else {
|
||||
// 存储token 信息
|
||||
Session.set('token', data.access_token);
|
||||
Session.set('refresh_token', data.refresh_token);
|
||||
console.log(data)
|
||||
toHome()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function sliderClose() {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const toHome = () => {
|
||||
|
||||
ElNotification({
|
||||
|
|
|
@ -1,70 +1,72 @@
|
|||
<template>
|
||||
<div class="table-page custom-table-table">
|
||||
<h3 class="main-color" style="font-size: 25px;line-height: 1;padding: 8px 0;">近30天登陆汇总</h3>
|
||||
<div style="width: 100%;height: 35%;">
|
||||
<LoginChart />
|
||||
</div>
|
||||
<div class="search-part" v-show="isSearch">
|
||||
<div class="search-cell">
|
||||
<span class="label">类型</span>
|
||||
<el-select v-model="queryParams.type" placeholder="请选择类型">
|
||||
<el-option v-for="item in getLogType()" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="search-cell">
|
||||
<span class="label">请求时间</span>
|
||||
<el-date-picker v-model="queryParams.time" type="datetimerange" range-separator="-" start-placeholder="开始时间"
|
||||
end-placeholder="结束时间" />
|
||||
</div>
|
||||
<el-button type="primary" icon="Search" @click="queryData(queryParams)">查询</el-button>
|
||||
<el-button icon="Refresh" @click="queryParams = {}">重置</el-button>
|
||||
</div>
|
||||
<div class="button-part" style="justify-content: space-between;">
|
||||
<el-button icon="Delete" @click="removeData()">删除</el-button>
|
||||
<TableAbility @searchBtn="isSearch = !isSearch" @refreshBtn="queryData({})" @downloadBtn="exportData('日志数据', tableData)"></TableAbility>
|
||||
</div>
|
||||
<div class="table-part">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="tableData" height="100%" border show-overflow-tooltip
|
||||
<div class="table-page custom-table-table">
|
||||
<h3 class="main-color" style="font-size: 25px;line-height: 1;padding: 8px 0;">近30天登陆汇总</h3>
|
||||
<div style="width: 100%;height: 35%;">
|
||||
<LoginChart/>
|
||||
</div>
|
||||
<div class="search-part" v-show="isSearch">
|
||||
<div class="search-cell">
|
||||
<span class="label">类型</span>
|
||||
<el-select v-model="queryParams.type" placeholder="请选择类型">
|
||||
<el-option v-for="item in getLogType()" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="search-cell">
|
||||
<span class="label">请求时间</span>
|
||||
<el-date-picker v-model="queryParams.time" type="datetimerange" range-separator="-" start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"/>
|
||||
</div>
|
||||
<el-button type="primary" icon="Search" @click="queryData(queryParams)">查询</el-button>
|
||||
<el-button icon="Refresh" @click="queryParams = {}">重置</el-button>
|
||||
</div>
|
||||
<div class="button-part" style="justify-content: space-between;">
|
||||
<el-button icon="Delete" @click="removeData()">删除</el-button>
|
||||
<TableAbility @searchBtn="isSearch = !isSearch" @refreshBtn="queryData({})"
|
||||
@downloadBtn="exportData('日志数据', tableData)"></TableAbility>
|
||||
</div>
|
||||
<div class="table-part">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="tableData" height="100%" border show-overflow-tooltip
|
||||
@row-click="tableRowClick">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column type="index" label="#" width="55" align="center" />
|
||||
<el-table-column property="type" label="类型" width="120" align="center" />
|
||||
<el-table-column property="title" label="标题" width="120" align="center" />
|
||||
<el-table-column property="ip" label="IP地址" width="120" align="center" />
|
||||
<el-table-column property="requestMethod" label="请求方式" width="120" align="center" />
|
||||
<el-table-column label="请求时间" width="220" align="center">
|
||||
<template #default="scope">{{ dateFormater('yyyy-MM-dd HH:mm:ss', scope.row.requestTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="operator" label="操作人" width="120" align="center" />
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-table-column type="selection" width="55"/>
|
||||
<el-table-column type="index" label="#" width="55" align="center"/>
|
||||
<el-table-column property="type" label="类型" width="120" align="center"/>
|
||||
<el-table-column property="title" label="标题" width="120" align="center"/>
|
||||
<el-table-column property="ip" label="IP地址" width="120" align="center"/>
|
||||
<el-table-column property="requestMethod" label="请求方式" width="120" align="center"/>
|
||||
<el-table-column label="请求时间" width="220" align="center">
|
||||
<template #default="scope">{{ dateFormater('yyyy-MM-dd HH:mm:ss', scope.row.requestTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="operator" label="操作人" width="120" align="center"/>
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<span @click.stop>
|
||||
<el-button link icon="EditPen" @click="viewData(scope.row)">详情</el-button>
|
||||
<el-button link icon="Delete" @click="removeData(scope.row)">删除</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pagination-part">
|
||||
<CommonPagination :total="100" @paginationChange="paginationChange" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-dialog v-model="isFormDialog" :title="formDialogTitle" width="40%">
|
||||
<LogForm ref="logFormRef" :type="formDialogTitle === '详情' ? 'view' : 'edit'" @close="isFormDialog = false" />
|
||||
</el-dialog>
|
||||
<div class="pagination-part">
|
||||
<CommonPagination :total="100" @paginationChange="paginationChange"/>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog v-model="isFormDialog" :title="formDialogTitle" width="40%">
|
||||
<LogForm ref="logFormRef" :type="formDialogTitle === '详情' ? 'view' : 'edit'" @close="isFormDialog = false"/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup>
|
||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import {onMounted, reactive, ref, toRefs, watch} from 'vue'
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
import {useRouter, useRoute} from 'vue-router'
|
||||
import LoginChart from './chart/login-chart.vue'
|
||||
import CommonPagination from '@/components/common-pagination.vue'
|
||||
import LogForm from './form/log-form.vue'
|
||||
import { tableRemoveRow, exportData } from '@/utils/table-util'
|
||||
import { getLogType } from '@/static-data/core'
|
||||
import { dateFormater } from '@/utils/date-util'
|
||||
import {tableRemoveRow, exportData} from '@/utils/table-util'
|
||||
import {getLogType} from '@/static-data/core'
|
||||
import {dateFormater, getEndOfMonth} from '@/utils/date-util'
|
||||
import * as logManageApi from '@/api/log-manage'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
@ -78,54 +80,65 @@ const formDialogTitle = ref('')
|
|||
const queryParams = ref({} as any)
|
||||
const tableData = ref([] as any)
|
||||
|
||||
queryData({ type: '正常' })
|
||||
queryData({type: '正常'})
|
||||
|
||||
function queryData(e: any) {
|
||||
loading.value = true
|
||||
tableData.value = []
|
||||
setTimeout(() => {
|
||||
while (tableData.value.length < 10) {
|
||||
tableData.value.push({
|
||||
type: e.type || '正常',
|
||||
title: e.title || '测试',
|
||||
ip: '127.0.0.1',
|
||||
requestMethod: 'post',
|
||||
requestTime: new Date(),
|
||||
operator: 'admin'
|
||||
})
|
||||
}
|
||||
loading.value = false
|
||||
}, 200);
|
||||
loading.value = true
|
||||
tableData.value = []
|
||||
setTimeout(() => {
|
||||
while (tableData.value.length < 10) {
|
||||
tableData.value.push({
|
||||
type: e.type || '正常',
|
||||
title: e.title || '测试',
|
||||
ip: '127.0.0.1',
|
||||
requestMethod: 'post',
|
||||
requestTime: new Date(),
|
||||
operator: 'admin'
|
||||
})
|
||||
}
|
||||
loading.value = false
|
||||
}, 200);
|
||||
}
|
||||
|
||||
const viewData = (e: any) => {
|
||||
isFormDialog.value = true
|
||||
formDialogTitle.value = '详情'
|
||||
setTimeout(() => {
|
||||
logFormRef.value.resetData()
|
||||
logFormRef.value.formData = JSON.parse(JSON.stringify(e))
|
||||
}, 0)
|
||||
isFormDialog.value = true
|
||||
formDialogTitle.value = '详情'
|
||||
setTimeout(() => {
|
||||
logFormRef.value.resetData()
|
||||
logFormRef.value.formData = JSON.parse(JSON.stringify(e))
|
||||
}, 0)
|
||||
}
|
||||
const removeData = (e?: any) => {
|
||||
const selectRow = e || tableRef.value.getSelectionRows()
|
||||
tableRemoveRow({ data: selectRow }, (res: boolean) => {
|
||||
if (res) {
|
||||
// console.log('调用删除', selectRow)
|
||||
}
|
||||
})
|
||||
const selectRow = e || tableRef.value.getSelectionRows()
|
||||
tableRemoveRow({data: selectRow}, (res: boolean) => {
|
||||
if (res) {
|
||||
// console.log('调用删除', selectRow)
|
||||
}
|
||||
})
|
||||
}
|
||||
const tableRowClick = (row: any) => {
|
||||
tableRef.value.toggleRowSelection(row)
|
||||
tableRef.value.toggleRowSelection(row)
|
||||
}
|
||||
const paginationChange = (page: number, size: number) => {
|
||||
|
||||
}
|
||||
|
||||
function getMonthlyLogCount(startTime: string, endTime: string) {
|
||||
logManageApi.getMonthlyLogCount(startTime, endTime);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const month = dateFormater('yyyy-MM');
|
||||
const startTime = month + '-01'
|
||||
const endTime = month + '-' + getEndOfMonth(new Date().getFullYear(), new Date().getMonth() + 1);
|
||||
getMonthlyLogCount(startTime, endTime);
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.table-page.custom-table-table {
|
||||
.table-part {
|
||||
height: calc(65% - 230px);
|
||||
}
|
||||
.table-part {
|
||||
height: calc(65% - 230px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -64,6 +64,7 @@ import { tableRemoveRow, exportData } from '@/utils/table-util'
|
|||
import CommonPagination from '@/components/common-pagination.vue'
|
||||
import DoctorForm from './form/doctor-form.vue'
|
||||
import ImportDialog from '@/components/import-dialog.vue'
|
||||
import {userPage} from "@/api/acl/user";
|
||||
|
||||
const tableRef = ref()
|
||||
const doctorFormRef = ref()
|
||||
|
@ -76,6 +77,8 @@ const queryParams = ref({
|
|||
userName: ''
|
||||
} as any)
|
||||
const tableData = ref([] as any)
|
||||
let current = 0;
|
||||
const size = 10;
|
||||
|
||||
queryData()
|
||||
|
||||
|
@ -102,6 +105,11 @@ function queryData(e?: any) {
|
|||
loading.value = false
|
||||
}, 200);
|
||||
}
|
||||
userPage({
|
||||
current,
|
||||
size,
|
||||
name: queryParams.value.userName
|
||||
})
|
||||
}
|
||||
const addData = () => {
|
||||
isFormDialog.value = true
|
||||
|
|
|
@ -174,7 +174,10 @@ function getSurgeryData(username: string, db: string) {
|
|||
console.log(username, db);
|
||||
surgeryClient.publish({
|
||||
destination: "/front/getSurgeryData",
|
||||
body: JSON.stringify({status: "start", db, token: Session.get('token')})
|
||||
headers: {
|
||||
token: Session.get('token')
|
||||
},
|
||||
body: JSON.stringify({status: "start", db})
|
||||
});
|
||||
const account = "admin";
|
||||
surgeryClient.subscribe('/topic/user/' + account + ":" + db + '/surgeryData', (data: any) => {
|
||||
|
|
|
@ -24,14 +24,14 @@ export default defineConfig({
|
|||
proxy: {
|
||||
'/api': {
|
||||
//target: 'http://192.168.137.235:9999', // 目标服务器地址
|
||||
target: 'http://192.168.71.44:9999', // 目标服务器地址
|
||||
target: 'http://localhost:8888', // 目标服务器地址
|
||||
ws: true, // 是否启用 WebSocket
|
||||
changeOrigin: true, // 是否修改请求头中的 Origin 字段
|
||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||
},
|
||||
'/socket.io': {
|
||||
//target: 'ws://192.168.137.235:9999',
|
||||
target: 'ws://192.168.71.44:9999',
|
||||
target: 'ws://localhost:8888',
|
||||
ws: true,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/socket.io/, ''),
|
||||
|
|
Loading…
Reference in New Issue
Block a user