feat(invoice): 完善发票管理权限控制和检验申请功能

- 超级管理员可以编辑操作员字段,普通用户不可编辑
- 修改权限判断逻辑,只有用户名等于 'admin' 的用户才是超级管理员
- 非超级管理员用户只能查询自己的发票数据
- 添加根据员工ID更新操作员名称功能
- 新增行时根据用户权限填充信息
- 严格检查权限,超级管理员可以删除所有记录,普通用户只能删除自己维护的记录
- 在 bargain 组件中验证患者选择
- 添加检验申请单相关API接口
- 在医生工作站中添加检验申请tab页
- 实现检验申请单的增删改查功能
- 添加公告通知已读记录相关功能
- 实现用户未读公告数量统计和标记已读功能
This commit is contained in:
2025-12-30 13:52:15 +08:00
parent 49b8a975a8
commit 1c16d6ba0f
10 changed files with 443 additions and 41 deletions

View File

@@ -4,6 +4,14 @@
<template v-if="appStore.device !== 'mobile'">
<header-search id="header-search" class="right-menu-item" />
</template>
<!-- 公告和通知按钮 -->
<el-tooltip content="公告/通知" placement="bottom">
<div class="right-menu-item notice-btn" @click="openNoticePanel">
<el-badge :value="unreadCount" :hidden="unreadCount === 0" class="notice-badge">
<el-icon><Bell /></el-icon>
</el-badge>
</div>
</el-tooltip>
<div class="avatar-container">
<div class="avatar-wrapper">
<el-dropdown
@@ -83,22 +91,28 @@
</div>
</template>
</el-dialog>
<!-- 公告/通知面板 -->
<NoticePanel ref="noticePanelRef" @updateUnreadCount="updateUnreadCount" />
</div>
</template>
<script setup>
import { onMounted } from 'vue';
import { onMounted, ref } from 'vue';
import { ElMessageBox } from 'element-plus';
import { Bell } from '@element-plus/icons-vue';
import Breadcrumb from '@/components/Breadcrumb';
import TopNav from '@/components/TopNav';
import Hamburger from '@/components/Hamburger';
import Screenfull from '@/components/Screenfull';
import SizeSelect from '@/components/SizeSelect';
import HeaderSearch from '@/components/HeaderSearch';
import NoticePanel from '@/components/NoticePanel';
import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user';
import useSettingsStore from '@/store/modules/settings';
import { getOrg, switchOrg } from '@/api/login';
import { getUnreadCount } from '@/api/system/notice';
const appStore = useAppStore();
const userStore = useUserStore();
@@ -106,6 +120,22 @@ const settingsStore = useSettingsStore();
const orgOptions = ref([]);
const showDialog = ref(false);
const orgId = ref('');
const noticePanelRef = ref(null);
const unreadCount = ref(0);
// 加载未读数量
function loadUnreadCount() {
getUnreadCount().then(res => {
unreadCount.value = res.data || 0;
}).catch(() => {
unreadCount.value = 0;
});
}
// 更新未读数量
function updateUnreadCount() {
loadUnreadCount();
}
function loadOrgList() {
getOrg().then((res) => {
@@ -115,6 +145,7 @@ function loadOrgList() {
onMounted(() => {
loadOrgList();
loadUnreadCount();
});
function handleOrgSwitch(selectedOrgId) {
@@ -160,12 +191,12 @@ function logout() {
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
userStore.logOut().then(() => {
location.href = '/index';
});
})
.catch(() => {});
.then(() => {
userStore.logOut().then(() => {
location.href = '/index';
});
})
.catch(() => {});
}
function submit() {
@@ -182,6 +213,13 @@ const emits = defineEmits(['setLayout']);
function setLayout() {
emits('setLayout');
}
// 打开公告/通知面板
function openNoticePanel() {
if (noticePanelRef.value) {
noticePanelRef.value.open();
}
}
</script>
<style lang='scss' scoped>
@@ -222,7 +260,31 @@ function setLayout() {
transition: background 0.3s;
&:hover {
background: rgba(255, 255, 255, 0.1);
background: rgba(255,255,255,0.1);
}
}
}
.notice-btn {
cursor: pointer;
padding: 0 10px;
height: 100%;
display: flex;
align-items: center;
.notice-badge {
:deep(.el-badge__content) {
top: -5px;
right: -5px;
}
}
.el-icon {
font-size: 20px;
color: #606266;
&:hover {
color: #409eff;
}
}
}