初版完成

This commit is contained in:
gaofy 2023-12-26 17:11:15 +08:00
parent dc46f0f41a
commit 2219b5c718
19 changed files with 970 additions and 297 deletions

View File

@ -28,12 +28,15 @@
}
.el-button.is-link {
color: $main-color;
&:hover,
&:active {
&.el-button--danger {
color: red;
}
&:hover:not(.el-button--danger),
&:active:not(.el-button--danger) {
color: rgba($main-color, .8);
}
&:focus {
&:focus:not(.el-button--danger) {
color: rgba($main-color, .7);
}
&:focus-visible {

View File

@ -220,6 +220,9 @@ body {
background: rgba($main-color, .05);
}
}
.el-table__row.disable {
color: $text3-color;
}
.el-button.is-round {
height: 28px;
padding: 5px 10px;

View File

@ -1,5 +1,6 @@
import { createRouter, createWebHistory } from 'vue-router'
import { useLoginStore } from '@/stores/user-info-store'
import { ElMessage, ElMessageBox } from 'element-plus'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@ -133,12 +134,73 @@ const router = createRouter({
router.beforeEach((to, from, next) => {
const loginInfo = useLoginStore().getlogin()
const isLogin = loginInfo.isLogin
if (to.fullPath !=='/login' && !isLogin) {
next('/login') // 重定向登录页
} else {
// 如果用户有权限,正常进行导航
next()
console.log(from)
// 普通用户
const commonUser = [
'/login',
'/home',
'/patients-manage',
'/patients-manage/patients-manage',
'/patients-manage/surgery-info'
]
// 中级管理员
const IntermediateAdmin = [
'/login',
'/home',
'/patients-manage',
'/patients-manage/patients-manage',
'/patients-manage/surgery-info',
'/remote-manage',
'/remote-manage/remote-manage',
'/remote-manage/remote-control'
]
// 高级管理员
const SeniorAdmin = [
'/login',
'/home',
'/patients-manage',
'/patients-manage/patients-manage',
'/patients-manage/surgery-info',
'/remote-manage',
'/remote-manage/remote-manage',
'/remote-manage/remote-control',
'/permissions-manage',
'/permissions-manage/doctor-manage',
'/permissions-manage/role-manage',
'/permissions-manage/menu-manage',
'/logs-manage',
'/logs-manage/message-manage',
'/logs-manage/logs-manage'
]
const isViewRoute = () => {
let release = false
switch (loginInfo.permissions) {
case '超级管理员':
release = true
break;
case '高级管理员':
release = SeniorAdmin.some((p: string) => p === to.path)
break;
case '中级管理员':
release = IntermediateAdmin.some((p: string) => p === to.path)
break;
case '普通用户':
release = commonUser.some((p: string) => p === to.path)
break;
default:
break;
}
return release
}
if(to.fullPath ==='/login') {
next()
return
}
if (!isLogin) next('/login') // 重定向登录页
else if(!isViewRoute()) {
ElMessage.error('无权访问!')
next(from.fullPath)
}else next()
});
export default router

View File

@ -17,6 +17,23 @@ export const getDeptData = () => {
return depts
}
export const getMessageType = () => {
const type = []
type.push({ label: '通知', value: '通知' })
type.push({ label: '公告', value: '公告' })
return type
}
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: '编辑' })
return type
}
export const getusers = () => {
const user = []
while (user.length < 50) {

View File

@ -4,17 +4,17 @@ export const useLoginStore = defineStore('login', {
state: () => {
return {
login: {
isLogin: true,
account: 'admin',
name: '管理员',
isLogin: false,
account: '',
name: '',
/**
*
*
*
*
*/
permissions: '超级管理员',
hospital: '北京第一医院'
permissions: '',
hospital: ''
} as any
}
},

View File

@ -3,7 +3,11 @@
<div class="background-box">
<div class="left-content">
<div class="message-box swing_skew_1">
<el-carousel height="32px" direction="vertical" indicator-position="none" autoplay>
<el-carousel-item v-for="(item, index) in messages" :key="'message-' + index">
<p class="text-row-1" style="line-height: 32px;" :class="{'is-link': item.link}" @click="() => {item.link && router.push(item.link)}">{{ item.type }} {{ item.content }}</p>
</el-carousel-item>
</el-carousel>
</div>
<div class="header-box swing_skew_1">
<div class="header-item">
@ -67,8 +71,11 @@ import SystemLogs from "@/components/system-logs.vue";
const router = useRouter()
const userInfo = useLoginStore().getlogin()
const messages = ref([] as any)
const total = ref(0) //
messages.value.push({type: '通知', content: '测试测试测试测试测试测试测试测试测试测试', link: '/system-manage/system-home'})
messages.value.push({type: '公告', content: '公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试公告测试'})
</script>
<style lang='scss' scoped>
@ -89,7 +96,18 @@ const total = ref(0) // 日历添加的记录提醒统计
.left-content {
width: calc(100% - 350px);
height: 100%;
.message-box {
height: 34px;
background: #f8f8f8;
color: $text-color;
padding: 0 30px;
border: 1px solid $border1-color;
margin-bottom: 20px;
.is-link {
cursor: pointer;
color: $main-color;
}
}
.header-box {
width: 100%;
height: 90px;
@ -119,7 +137,7 @@ const total = ref(0) // 日历添加的记录提醒统计
.echart-box {
width: 100%;
height: calc(100% - 110px);
height: calc(100% - 164px);
margin-top: 20px;
display: flex;
flex-wrap: wrap;

View File

@ -14,8 +14,8 @@
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import * as echarts from 'echarts';
import { dateFormater, getMonthDays } from '@/utils/date-util';
import * as echarts from 'echarts'
import { dateFormater, getMonthDays } from '@/utils/date-util'
const chartDom = ref()

View File

@ -56,9 +56,9 @@
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import RecordForm from './record-form.vue';
import RecordForm from './record-form.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { dateFormater, getFirstDayOfWeek, getDays } from '@/utils/date-util';
import { dateFormater, getFirstDayOfWeek, getDays } from '@/utils/date-util'
const monthEn = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二']

View File

@ -72,14 +72,37 @@ const route = useRoute()
const userInfo = useLoginStore().getlogin()
const hospitals: any = getHospitalsData()
const menus = [
{ label: '首页', path: '/home', icon: 'icon-shouye' },
{ label: '权限管理', path: '/permissions-manage', icon: 'icon-users' },
{ label: '患者管理', path: '/patients-manage', icon: 'icon-renyuanguanli' },
{ label: '远程管理', path: '/remote-manage', icon: 'icon-anquanbaozhang' },
{ label: '后台管理', path: '/system-manage', icon: 'icon-houtaiguanli' },
{ label: '日志管理', path: '/logs-manage', icon: 'icon-setting' }
]
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;
}
const isShowUserInfoDrawer = ref(false)
const menuActive = ref('/')

View File

@ -172,6 +172,7 @@ const isShowRegister = ref(false)
const passwordLogin = ref(true)
const loginParams = ref({
account: '',
name: '',
password: '',
phone: '',
phoneArea: phoneAreas[0],
@ -209,6 +210,9 @@ const register = async () => {
type: 'success',
}
).then(() => {
loginParams.value.account = registerFormRef.value.account
loginParams.value.name = registerFormRef.value.name
currentHospital.value = registerFormRef.value.hospital
toHome()
}).catch(() => { })
} else {
@ -239,6 +243,10 @@ const sendCode = () => {
}
const login = async (type: string) => {
const obj = loginParams.value
if(!currentHospital.value) {
ElMessage.warning('请在右上角选择院区')
return
}
await loginFormRef.value.validate((valid: any, fields: any) => {
if (valid) {
console.log('submit!')
@ -249,7 +257,28 @@ const login = async (type: string) => {
})
}
const toHome = () => {
const getPermissions = () => {
let permissions = '普通用户'
switch (loginParams.value.account) {
case 'admin':
permissions = '超级管理员'
break;
case 'dev1':
permissions = '高级管理员'
break;
case 'dev2':
permissions = '中级管理员'
break;
default:
break;
}
return permissions
}
useLoginStore().setlogin('isLogin', true)
useLoginStore().setlogin('account', loginParams.value.account)
useLoginStore().setlogin('name', loginParams.value.name)
useLoginStore().setlogin('hospital', currentHospital.value)
useLoginStore().setlogin('permissions', getPermissions())
router.push('/home')
}

View File

@ -0,0 +1,118 @@
<template>
<div class="chart-box">
<div ref="chartDom" class="chart-dom"></div>
</div>
</template>
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import * as echarts from 'echarts'
import { dateFormater, getDays } from '@/utils/date-util'
const chartDom = ref()
onMounted(() => {
getData(new Date())
})
// true
function calcTime(time: any) {
return Boolean(new Date().getTime() < new Date(time).getTime())
}
function initChart(chartData: any) {
const chart = echarts.init(chartDom.value as HTMLElement);
chart.clear();
const option = {
color: [],
tooltip: {
trigger: 'axis',
formatter: (params: any) => {
console.log(params)
return dateFormater('yyyy-MM-dd', params[0].axisValue) + '<br>登录记录:' + params[0].value + '条'
}
},
grid: {
left: 20,
right: 50,
bottom: 5,
top: 20,
containLabel: true,
},
xAxis: {
name: '日期',
show: true,
type: 'category',
boundaryGap: false,
nameTextStyle: { color: '#909399' },
axisLine: { show: true, lineStyle: { color: '#006080', width: 2 } },
axisTick: { show: false },
axisLabel: { show: true, interval: chartData.xData.length - 2, formatter: (value: any) => dateFormater('MM-dd', value) },
splitLine: { show: true, lineStyle: { color: 'rgba(0, 96, 128, .05)', width: 1, type: 'solid' } },
data: chartData.xData,
},
yAxis: {
show: true,
type: 'value',
min: 0,
axisLine: { show: true, lineStyle: { color: '#006080', width: 2 } },
axisTick: { show: false },
axisLabel: { show: false },
splitLine: { show: false, lineStyle: { color: '#D4E8F0', width: 1, type: 'solid' } },
},
series: [{
type: 'line',
symbol: 'none',
smooth: true,
showSymbol: false,
lineStyle: {
color: 'rgb(0, 96, 128)',
width: 2,
shadowColor: 'rgba(0, 96, 128, .3)',
shadowBlur: 10,
shadowOffsetY: 20
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(0, 96, 128, 1)'
}, {
offset: 0.8,
color: 'rgba(255, 255, 255, 0.1)'
}], false)
},
data: chartData.data
}],
};
chart.setOption(option);
chart.resize();
window.addEventListener('resize', () => {
chart.resize();
});
}
const getData = (date: Date) => {
const xData = []
const data = []
for (let i = 0; i < 30; i++) {
xData.unshift(getDays(date, -1))
data.unshift(Math.ceil(Math.random() * 10))
}
initChart({ xData, data })
}
</script>
<style lang='scss' scoped>
.chart-box {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.chart-dom {
width: 100%;
height: 100%;
}
}
</style>

View File

@ -0,0 +1,90 @@
<template>
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100" :disabled="type === 'view'">
<el-form-item label="类型" prop="type">
<el-input :model-value="formData.type"></el-input>
</el-form-item>
<el-form-item label="标题" prop="title">
<el-input :model-value="formData.title"></el-input>
</el-form-item>
<el-form-item label="IP地址" prop="ip">
<el-input :model-value="formData.ip"></el-input>
</el-form-item>
<el-form-item label="请求方式" prop="requestMethod">
<el-input :model-value="formData.requestMethod"></el-input>
</el-form-item>
<el-form-item label="请求时间" prop="requestTime">
<el-input :model-value="dateFormater('yyyy-MM-dd HH:mm:ss', formData.requestTime)"></el-input>
</el-form-item>
<el-form-item label="操作人" prop="operator">
<el-input :model-value="formData.operator"></el-input>
</el-form-item>
</el-form>
</template>
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { dateFormater } from '@/utils/date-util'
const emit = defineEmits(['close'])
const props = defineProps({
type: String
})
const rules = reactive({
type: [
{ required: true, message: '请选择类型', trigger: ['blur', 'change'] },
],
})
const formRef = ref()
const formData = ref({
type: '',
title: '',
ip: '',
requestMethod: '',
requestTime: '',
operator: ''
} as any)
onMounted(() => {
resetData()
})
defineExpose({
formData,
resetData,
})
function close() {
emit('close')
}
function resetData() {
formRef.value.resetFields()
formData.value = {
type: '',
title: '',
ip: '',
requestMethod: '',
requestTime: '',
operator: ''
}
}
</script>
<style lang='scss' scoped>
:deep(.el-form-item) {
.el-form-item__label {
display: block;
text-align: right;
// text-align: justify;
// text-align-last: justify;
// padding: 0 10px 0 20px;
&:before {
display: none;
}
}
}
</style>

View File

@ -0,0 +1,134 @@
<template>
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100">
<el-form-item label="消息类型" prop="type">
<el-select v-model="formData.type" placeholder="请选择消息类型">
<el-option v-for="item in getMessageType()" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="所在医院" prop="hospital">
<el-select v-model="formData.hospital" placeholder="请选择医院">
<el-option v-for="item in getHospitalsData()" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="消息内容" prop="content">
<el-input v-model="formData.content" type="textarea" :rows="4" placeholder="请输入消息内容"></el-input>
</el-form-item>
<el-form-item label="可见组织" prop="showDept">
<el-select v-model="formData.showDept" multiple placeholder="请选择组织">
<el-option v-for="item in getHospitalsData()" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="组织权限" prop="permissions">
<el-select v-model="formData.permissions" placeholder="请选择组织权限">
<el-option v-for="item in [{value: 'default', label: '当前组织和下一组织可见'}]" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="跳转链接" prop="link">
<el-input v-model="formData.link" placeholder="跳转链接"></el-input>
</el-form-item>
<el-form-item label="是否热点" prop="isHot">
<el-switch v-model="formData.isHot" />
</el-form-item>
<div style="text-align: right;">
<el-button class="f18" @click="close">取消</el-button>
<el-button class="f18" type="primary" @click="saveData">确认</el-button>
</div>
</el-form>
</template>
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getHospitalsData, getMessageType } from '@/static-data/core'
const emit = defineEmits(['close'])
const props = defineProps({
type: String
})
const rules = reactive({
type: [
{ required: true, message: '请选择类型', trigger: ['blur', 'change'] },
],
hospital: [
{ required: true, message: '请选择医院', trigger: ['blur', 'change'] },
],
content: [
{ required: true, message: '请输入消息内容', trigger: ['blur', 'change'] },
],
showDept: [
{ required: true, message: '请选择可见组织', trigger: ['blur', 'change'] },
],
permissions: [
{ required: true, message: '请选择组织权限', trigger: ['blur', 'change'] },
],
})
const formRef = ref()
const formData = ref({
type: '',
hospital: '',
content: '',
showDept: '',
permissions: '',
link: '',
isHot: true,
} as any)
onMounted(() => {
resetData()
})
defineExpose({
formData,
resetData,
})
function close() {
emit('close')
}
function resetData() {
formRef.value.resetFields()
formData.value = {
type: '',
hospital: '',
content: '',
showDept: '',
permissions: '',
link: '',
isHot: true,
}
}
const saveData = async () => {
await formRef.value.validate((valid: any, fields: any) => {
if (valid) {
ElMessage.success('保存成功!')
close()
} else {
console.log('error submit!', fields)
}
})
}
</script>
<style lang='scss' scoped>
:deep(.el-form-item) {
.el-form-item__label {
display: block;
text-align: right;
// text-align: justify;
// text-align-last: justify;
// padding: 0 10px 0 20px;
&:before {
display: none;
}
}
}
</style>

View File

@ -1,184 +0,0 @@
<template>
<el-form ref="formRef" :model="formData" :rules="rules" label-width="60">
<el-row :gutter="gutter">
<el-col :span="12">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" placeholder="请输入姓名"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="住院号" prop="code" :label-width="rightWidth">
<el-input v-model="formData.code" placeholder="请输入住院号" :disabled="type === 'edit'"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="gutter">
<el-col :span="12">
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="formData.sex">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="科室" prop="dept" :label-width="rightWidth">
<el-select v-model="formData.dept" placeholder="请选择科室">
<el-option v-for="item in getDeptData()" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="gutter">
<el-col :span="12">
<el-form-item label="身高" prop="bodyHeight">
<el-input v-model="formData.bodyHeight" placeholder="请输入电话"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="有无病史" prop="isMedicalHistory" :label-width="rightWidth">
<el-radio-group v-model="formData.isMedicalHistory">
<el-radio label="无"></el-radio>
<el-radio label="有"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="gutter">
<el-col :span="12">
<el-form-item label="体重" prop="bodyWeight">
<el-input v-model="formData.bodyWeight" placeholder="请输入体重"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="病史名称" prop="medicalHistoryName" :label-width="rightWidth">
<el-input v-model="formData.medicalHistoryName" placeholder="请输入病史"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="gutter">
<el-col :span="12">
<el-form-item label="年龄" prop="age">
<el-input v-model="formData.age" placeholder="请输入年龄"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="过敏史名称" prop="allergyHistoryName" :label-width="rightWidth">
<el-input v-model="formData.medicalHistoryName" placeholder="请输入过敏史"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="gutter">
<el-col :span="12">
<el-form-item label="电话" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入电话"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="住院时间" prop="hospitalTime" :label-width="rightWidth">
<el-date-picker v-model="formData.hospitalTime" type="date" placeholder="请输入住院时间" />
</el-form-item>
</el-col>
</el-row>
<div v-if="type !== 'edit'" style="text-align: right;">
<el-button class="f18" @click="close">取消</el-button>
<el-button class="f18" type="primary" @click="saveData">确认</el-button>
</div>
<div v-else style="text-align: right;">
<el-button class="f18" @click="saveData">修改</el-button>
<el-button class="f18" type="primary" @click="saveData">更新</el-button>
</div>
</el-form>
</template>
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getDeptData } from '@/static-data/core'
const emit = defineEmits(['close'])
const props = defineProps({
type: String
})
const gutter = 20
const rightWidth = 100
const rules = reactive({
name: [
{ required: true, message: '请输入姓名', trigger: ['blur', 'change'] },
],
code: [
{ required: true, message: '请输入住院号', trigger: ['blur', 'change'] },
],
dept: [
{ required: true, message: '请选择科室', trigger: ['blur', 'change'] },
],
hospitalTime: [
{ required: true, message: '请输入住院时间', trigger: ['blur', 'change'] },
],
})
const formRef = ref()
const formData = ref({
id: '',
userName: '',
name: '',
role: '',
mailbox: '',
phone: '',
enable: true,
} as any)
onMounted(() => {
resetData()
})
defineExpose({
formData,
resetData,
})
function close() {
emit('close')
}
function resetData() {
formRef.value.resetFields()
formData.value = {
id: '',
userName: '',
name: '',
role: '',
mailbox: '',
phone: '',
enable: true,
}
}
const saveData = async () => {
await formRef.value.validate((valid: any, fields: any) => {
if (valid) {
ElMessage.success('保存成功!')
close()
} else {
console.log('error submit!', fields)
}
})
}
</script>
<style lang='scss' scoped>
:deep(.el-form-item) {
.el-form-item__label {
display: block;
text-align: justify;
text-align-last: justify;
// padding: 0 10px 0 20px;
&:before {
display: none;
}
}
}
</style>

View File

@ -1,14 +1,126 @@
<template>
<div>
<div class="table-page custom-table-table">
<h3 class="main-color" style="font-size: 30px;line-height: 1;padding: 10px 0;">近30天登陆汇总</h3>
<div style="width: 100%;height: 35%;">
<LoginChart />
</div>
<div class="search-part ">
<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>
<el-button icon="Download" @click="exportData('日志数据', tableData)">下载</el-button>
</div>
<div class="table-part">
<el-table ref="tableRef" :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">
<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>
</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 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'
const router = useRouter()
const route = useRoute()
const tableRef = ref()
const logFormRef = ref()
const isFormDialog = ref(false)
const formDialogTitle = ref('')
const queryParams = ref({} as any)
const tableData = ref([] as any)
queryData({ type: '正常' })
function queryData(e: any) {
console.log(e)
tableData.value = []
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'
})
}
}
const viewData = (e: any) => {
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 tableRowClick = (row: any) => {
tableRef.value.toggleRowSelection(row)
}
const paginationChange = (page: number, size: number) => {
}
</script>
<style lang='scss' scoped>
.table-page.custom-table-table {
.table-part {
height: calc(65% - 230px);
}
}
</style>

View File

@ -1,46 +1,41 @@
<template>
<div class="table-page">
<div class="search-part">
<div class="table-page custom-table-table">
<h3 class="main-color" style="font-size: 24px;line-height: 1;padding: 28px 0;">消息管理</h3>
<div class="search-part ">
<div class="search-cell">
<span class="label">患者姓名</span>
<el-input v-model="queryParams.name" placeholder="请输入患者姓名"></el-input>
</div>
<div class="search-cell">
<span class="label">科室名</span>
<el-select v-model="queryParams.dept" placeholder="请选择科室名">
<el-option v-for="item in getDeptData()" :key="item.value" :label="item.label"
<span class="label">消息类型</span>
<el-select v-model="queryParams.type" placeholder="请选择消息类型">
<el-option v-for="item in getMessageType()" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</div>
<div class="search-cell">
<span class="label">消息内容</span>
<el-input v-model="queryParams.content" placeholder="请输入消息内容"></el-input>
</div>
<el-button type="primary" icon="Search" @click="queryData(queryParams)">查询</el-button>
<el-button icon="Refresh" @click="queryParams = {}">重置</el-button>
<!-- <el-button icon="Refresh" @click="queryParams = {}">重置</el-button> -->
</div>
<div class="button-part" style="justify-content: space-between;">
<div>
<el-button type="primary" icon="FirstAidKit" @click="addData">新增</el-button>
<el-button icon="FirstAidKit" @click="importData">导入</el-button>
<el-button icon="Delete" @click="removeData()">删除</el-button>
</div>
<el-button icon="Download" @click="exportData('患者信息', tableData)">下载</el-button>
<el-button type="primary" icon="FirstAidKit" @click="addData">新增</el-button>
</div>
<div class="table-part">
<el-table ref="tableRef" :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="code" label="住院号" width="120" align="center" />
<el-table-column property="name" label="姓名" width="120" align="center" />
<el-table-column label="手机号" width="220" align="center">
<template #default="scope">{{ scope.row.phone.slice(0, 3) + '****' + scope.row.phone.slice(7)
}}</template>
<el-table ref="tableRef" :data="tableData" height="100%" border show-overflow-tooltip>
<el-table-column property="type" label="消息类型" width="120" align="center" />
<el-table-column property="content" label="消息内容" width="120" align="center" />
<el-table-column property="creator" 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.creatTime) }}</template>
</el-table-column>
<el-table-column property="dept" label="科室" width="160" align="center" />
<el-table-column property="doctor" label="主诊医生" width="160" align="center" />
<el-table-column label="手术数据" header-align="center">
<el-table-column property="editor" 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.editTime) }}</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<span @click.stop style="padding: 0 50px;">
<el-button v-if="scope.row.userInfo" type="primary" round @click="viewUserInfo(scope.row)">个人信息</el-button>
<el-button v-if="scope.row.surgeryInfo" type="primary" round @click="viewSurgeryInfo(scope.row)">手术信息</el-button>
<span @click.stop>
<el-button link icon="EditPen" @click="editData(scope.row)">修改</el-button>
<el-button type="danger" link icon="Delete" @click="removeData(scope.row)">删除</el-button>
</span>
</template>
</el-table-column>
@ -50,63 +45,64 @@
<CommonPagination :total="100" @paginationChange="paginationChange" />
</div>
</div>
<el-dialog v-model="isFormDialog" :title="formDialogTitle" width="40%"><PatientsForm ref="patientsFormRef" :type="formDialogTitle === '增加患者' ? 'add' : 'edit'" @close="isFormDialog = false" /></el-dialog>
<ImportDialog ref="importDialogRef" title="患者导入" templateUrl="#" importUrl="#" />
<el-dialog v-model="isFormDialog" :title="formDialogTitle" width="40%"><MessageForm ref="messageFormRef" :type="formDialogTitle === '新增消息' ? 'add' : '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 { tableRemoveRow, exportData } from '@/utils/table-util'
import CommonPagination from '@/components/common-pagination.vue'
import PatientsForm from './form/patients-form.vue'
import ImportDialog from '@/components/import-dialog.vue'
import { getDeptData } from '@/static-data/core'
import MessageForm from './form/message-form.vue'
import { tableRemoveRow } from '@/utils/table-util'
import { getMessageType } from '@/static-data/core'
import { dateFormater } from '@/utils/date-util'
const router = useRouter()
const route = useRoute()
const tableRef = ref()
const patientsFormRef = ref()
const importDialogRef = ref()
const messageFormRef = ref()
const isFormDialog = ref(false)
const formDialogTitle = ref('')
const queryParams = ref({
name: '',
dept: ''
} as any)
const queryParams = ref({} as any)
const tableData = ref([] as any)
queryData({name: '测试', dept: getDeptData()[0].label})
queryData({type: '公告', content: '测试测试测试'})
function queryData (e: any) {
tableData.value = []
while (tableData.value.length < 10) {
tableData.value.push({
code: '123456', //
name: e.name,
phone: '12312345678',
dept: e.dept,
doctor: '张医生',
userInfo: Boolean(tableData.value.length < 2),
surgeryInfo: Boolean(tableData.value.length < 1)
type: e.type,
content: e.content,
creator: 'admin',
creatTime: new Date(),
editor: 'admin',
editTime: new Date(),
hospital: '',
showDept: '',
permissions: '',
link: '',
isHot: true,
})
}
}
const addData = () => {
isFormDialog.value = true
formDialogTitle.value = '增加患者'
formDialogTitle.value = '新增消息'
setTimeout(() => {
patientsFormRef.value.resetData()
messageFormRef.value.resetData()
}, 0)
}
const importData = () => {
const editData = (e: any) => {
isFormDialog.value = true
formDialogTitle.value = '修改'
setTimeout(() => {
importDialogRef.value.open()
}, 0);
messageFormRef.value.resetData()
messageFormRef.value.formData = JSON.parse(JSON.stringify(e))
}, 0)
}
const removeData = (e?: any) => {
const selectRow = e || tableRef.value.getSelectionRows()
@ -116,29 +112,29 @@ const removeData = (e?: any) => {
}
})
}
const viewUserInfo = (e: any) => {
isFormDialog.value = true
formDialogTitle.value = '个人信息'
setTimeout(() => {
patientsFormRef.value.resetData()
patientsFormRef.value.formData = JSON.parse(JSON.stringify(e))
}, 0)
}
const viewSurgeryInfo = (e: any) => {
router.push({
path: '/patients-manage/surgery-info',
query: e
})
}
const tableRowClick = (row: any) => {
tableRef.value.toggleRowSelection(row)
}
const paginationChange = (page: number, size: number) => {
}
</script>
<style lang='scss' scoped>
.table-page.custom-table-table {
.search-part {
padding: 40px 30px;
border: 1px solid $border-color;
&>.search-cell ~ .search-cell {
margin-left: 50px;
}
.search-cell {
flex-grow: 1;
}
&>.el-button {
margin-left: 100px;
}
}
.table-part {
height: calc(100% - 292px);
}
}
</style>

View File

@ -15,7 +15,7 @@
<el-button icon="Download" @click="exportData('医生数据', tableData)">导出</el-button>
</div>
<div class="table-part">
<el-table ref="tableRef" :data="tableData" height="100%" border show-overflow-tooltip
<el-table ref="tableRef" :data="tableData" height="100%" border show-overflow-tooltip :row-class-name="({row}: any) => !row.enable && 'disable'"
@row-click="tableRowClick">
<el-table-column type="selection" width="55" />
<el-table-column type="index" label="#" width="55" align="center" />
@ -33,9 +33,9 @@
<el-table-column label="操作" align="center">
<template #default="scope">
<span @click.stop>
<el-button link icon="RefreshLeft" @click="resetPassword(scope.row)">密码</el-button>
<el-button link icon="EditPen" @click="editData(scope.row)">修改</el-button>
<el-button link icon="Delete" @click="removeData(scope.row)">删除</el-button>
<el-button link icon="RefreshLeft" @click="resetPassword(scope.row)" :disabled="!scope.row.enable">密码</el-button>
<el-button link icon="EditPen" @click="editData(scope.row)" :disabled="!scope.row.enable">修改</el-button>
<el-button link icon="Delete" @click="removeData(scope.row)" :disabled="!scope.row.enable">删除</el-button>
</span>
</template>
</el-table-column>
@ -102,7 +102,7 @@ const removeData = (e?: any) => {
})
}
const enableChange = (e: any) => {
ElMessage.success(e.enable ? '启用成功' : '禁用成功')
}
const resetPassword = (e: any) => {
ElMessageBox.confirm('是否确定要重置密码?', '系统提醒', { type: 'warning' }).then(() => {

View File

@ -0,0 +1,150 @@
<template>
<el-form ref="formRef" :model="formData" :rules="rules" label-width="80">
<el-form-item label="医院" prop="hospital">
<el-select v-model="formData.hospital" placeholder="请选择医院">
<el-option v-for="item in getHospitalsData()" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="用户名" prop="userName">
<el-input v-model="formData.userName" placeholder="请输入用户名" :disabled="type === 'edit'"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" placeholder="请输入姓名"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="角色" prop="role">
<el-select v-model="formData.role" placeholder="请选择角色">
<el-option v-for="item in roleOption" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="邮箱" prop="mailbox">
<el-input v-model="formData.mailbox" placeholder="请输入邮箱"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="电话" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入电话"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="启用" prop="enable">
<el-radio-group v-model="formData.enable">
<el-radio :label="true" border>有效</el-radio>
<el-radio :label="false" border>禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<div style="text-align: right;padding-top: 80px;">
<el-button class="f18" @click="close">取消</el-button>
<el-button class="f18" type="primary" @click="saveData">确认</el-button>
</div>
</el-form>
</template>
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getHospitalsData } from '@/static-data/core'
const emit = defineEmits(['close'])
const props = defineProps({
type: String
})
const roleOption = [
{ label: '普通用户', value: '普通用户' },
{ label: '中级管理员', value: '中级管理员' },
{ label: '高级管理员', value: '高级管理员' },
]
const rules = reactive({
userName: [
{ required: true, message: '请输入用户名', trigger: ['blur', 'change'] },
],
name: [
{ required: true, message: '请输入姓名', trigger: ['blur', 'change'] },
],
role: [
{ required: true, message: '请选择角色', trigger: ['blur', 'change'] },
],
phone: [
{ required: true, message: '请输入电话', trigger: ['blur', 'change'] },
],
})
const formRef = ref()
const formData = ref({
id: '',
hospital: '',
userName: '',
name: '',
role: '',
mailbox: '',
phone: '',
enable: true,
} as any)
onMounted(() => {
resetData()
})
defineExpose({
formData,
resetData,
})
function close() {
emit('close')
}
function resetData() {
formRef.value.resetFields()
formData.value = {
id: '',
hospital: '',
userName: '',
name: '',
role: '',
mailbox: '',
phone: '',
enable: true,
}
}
const saveData = async () => {
await formRef.value.validate((valid: any, fields: any) => {
if (valid) {
ElMessage.success('保存成功!')
close()
} else {
console.log('error submit!', fields)
}
})
}
</script>
<style lang='scss' scoped>
:deep(.el-form-item) {
.el-form-item__label {
display: block;
text-align: justify;
text-align-last: justify;
padding: 0 10px 0 20px;
&:before {
display: none;
}
}
}
</style>

View File

@ -1,14 +1,116 @@
<template>
<div>
<div class="table-page custom-table-page">
<div class="search-part">
<div class="search-cell">
<span class="label">用户名</span>
<el-input v-model="queryParams.userName" placeholder="请输入用户名"></el-input>
</div>
<el-button type="primary" icon="Search" @click="queryData(queryParams)">查询</el-button>
<el-button icon="Refresh" @click="queryParams = {}">重置</el-button>
</div>
<div class="table-part">
<el-table ref="tableRef" :data="tableData" height="100%" border show-overflow-tooltip :row-class-name="({row}: any) => !row.enable && 'disable'"
@row-click="tableRowClick">
<el-table-column type="selection" width="55" />
<el-table-column type="index" label="#" width="55" align="center" />
<el-table-column property="hospital" label="医院名称" width="200" align="center" />
<el-table-column property="name" label="姓名" width="120" align="center" />
<el-table-column label="手机号" width="220" align="center">
<template #default="scope">{{ scope.row.phone.slice(0, 3) + '****' + scope.row.phone.slice(7)
}}</template>
</el-table-column>
<el-table-column property="role" label="角色" width="220" align="center" />
<el-table-column label="启用" width="120" align="center">
<template #default="scope">
<span @click.stop><el-switch v-model="scope.row.enable" @change="enableChange(scope.row)" /></span>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<span @click.stop>
<el-button link icon="RefreshLeft" @click="resetPassword(scope.row)" :disabled="!scope.row.enable">密码</el-button>
<el-button link icon="EditPen" @click="editData(scope.row)" :disabled="!scope.row.enable">修改</el-button>
<el-button link icon="Delete" @click="removeData(scope.row)" :disabled="!scope.row.enable">删除</el-button>
</span>
</template>
</el-table-column>
</el-table>
</div>
<div class="pagination-part">
<CommonPagination :total="100" @paginationChange="paginationChange" />
</div>
</div>
<el-dialog v-model="isFormDialog" :title="formDialogTitle" width="40%"><UserForm ref="userFormRef" :type="formDialogTitle === '添加' ? 'add' : '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 { tableRemoveRow } from '@/utils/table-util'
import CommonPagination from '@/components/common-pagination.vue'
import UserForm from './form/user-form.vue'
const tableRef = ref()
const userFormRef = ref()
const isFormDialog = ref(false)
const formDialogTitle = ref('')
const queryParams = ref({
userName: ''
} as any)
const tableData = ref([] as any)
queryData({userName: '测试'})
function queryData (e: any) {
tableData.value = []
while (tableData.value.length < 10) {
tableData.value.push({
hospital: '北京朝阳医院',
userName: 'cscs',
name: e.userName,
phone: '12312345678',
role: '高级管理员',
enable: true,
})
}
}
const removeData = (e?: any) => {
const selectRow = e || tableRef.value.getSelectionRows()
tableRemoveRow({ data: selectRow }, (res: boolean) => {
if (res) {
console.log('调用删除', selectRow)
}
})
}
const enableChange = (e: any) => {
ElMessage.success(e.enable ? '启用成功' : '禁用成功')
}
const resetPassword = (e: any) => {
ElMessageBox.confirm('是否确定要重置密码?', '系统提醒', { type: 'warning' }).then(() => {
ElMessage.success('重置成功!')
}).catch(() => { })
}
const editData = (e: any) => {
isFormDialog.value = true
formDialogTitle.value = '修改'
setTimeout(() => {
userFormRef.value.resetData()
userFormRef.value.formData = JSON.parse(JSON.stringify(e))
}, 0)
}
const tableRowClick = (row: any) => {
tableRef.value.toggleRowSelection(row)
}
const paginationChange = (page: number, size: number) => {
}
</script>
<style lang='scss' scoped>
.table-page.custom-table-page {
.table-part {
height: calc(100% - 110px);
}
}
</style>