解决合并冲突

This commit is contained in:
2025-12-10 14:20:24 +08:00
parent e1385cb3e6
commit 18f6a845e6
804 changed files with 61881 additions and 13577 deletions

View File

@@ -0,0 +1,61 @@
import request from '@/utils/request'
// 查询比例调整申请记录分页
export function getPage(query) {
return request({
url: '/nenu/gf-ratio-application-record/page',
method: 'get',
params: query
})
}
// 查询比例调整申请记录详情
export function getDetail(id) {
return request({
url: `/nenu/gf-ratio-application-record/${id}`,
method: 'get'
})
}
// 创建比例调整申请
export function add(gfRatioApplicationRecordDto) {
return request({
url: '/nenu/gf-ratio-application-record',
method: 'post',
data: gfRatioApplicationRecordDto
})
}
// 取消比例调整申请
export function cancel(id) {
return request({
url: `/nenu/gf-ratio-application-record/${id}`,
method: 'delete'
})
}
// 处理比例调整申请
export function process(gfRatioApplicationProcessDto) {
return request({
url: '/nenu/gf-ratio-application-record',
method: 'put',
data: gfRatioApplicationProcessDto
})
}
// 查询申请项目选择弹窗分页
export function getDefinitionSelectPage(query) {
return request({
url: '/nenu/gf-ratio-application-record/definition-select-page',
method: 'get',
params: query
})
}
// 查询申请单打印列表
export function getPrintList(ids) {
return request({
url: '/nenu/gf-ratio-application-record/print-list?ids='+ids,
method: 'get'
})
}

View File

@@ -0,0 +1,28 @@
import request from '@/utils/request'
// 查询大项比例列表
export function getTypeRatioList() {
return request({
url: `/nenu/gf-ratio-manage/type-ratio-list`,
method: 'get'
})
}
// 保存大项比例列表
export function saveTypeRatioList(gfTypeRatioSaveDto) {
return request({
url: '/nenu/gf-ratio-manage/type-ratio-list',
method: 'put',
data: gfTypeRatioSaveDto
})
}
// 查询单项比例分页
export function getIndividualRatioPage(query) {
return request({
url: '/nenu/gf-ratio-manage/individual-ratio-page',
method: 'get',
params: query
})
}

View File

@@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询学生名单分页
export function getPage(query) {
return request({
url: '/nenu/gf-student-list/page',
method: 'get',
params: query
})
}
// 查询学生名单详情
export function getDetail(id) {
return request({
url: `/nenu/gf-student-list/${id}`,
method: 'get'
})
}
// 添加学生名单
export function add(gfStudentListDto) {
return request({
url: '/nenu/gf-student-list',
method: 'post',
data: gfStudentListDto
})
}
// 编辑学生名单
export function edit(gfStudentListDto) {
return request({
url: '/nenu/gf-student-list',
method: 'put',
data: gfStudentListDto
})
}
// 删除学生名单
export function remove(id) {
return request({
url: `/nenu/gf-student-list/${id}`,
method: 'delete'
})
}

View File

@@ -18,6 +18,33 @@ export function advicePrint(data) {
})
}
// 获取全部科室列表
export function getOrgList(data) {
return request({
url:'/app-common/department-list',
method: 'get',
params: data,
})
}
// 获取全部病区列表
export function getWardList(data) {
return request({
url:'/app-common/ward-list',
method: 'get',
params: data,
})
}
// 获取全部供应商列表
export function getSupplierList(data) {
return request({
url:'/app-common/supplier',
method: 'get',
params: data,
})
}
import axios from 'axios';
const env = import.meta.env.MODE;
@@ -27,7 +54,7 @@ if(env == 'development'){
return axios.create(
{
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: '',//ybplugin
baseURL: '/ybplugin',//ybplugin
// 超时
timeout: 60000
}
@@ -43,4 +70,4 @@ if(env == 'development'){
}
).post('http://localhost:5000/api/data/', data);
}
}
}

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1760526251510" class="icon" viewBox="0 0 4096 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19701" width="480" height="120" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M174.073172 628.114881L1846.7293 65.622417a613.293618 613.293618 0 0 1 390.668035 0l1676.949184 562.594679A255.539008 255.539008 0 0 1 4088.624122 870.468076v12.470303a141.057532 141.057532 0 0 1-186.032397 133.698009L2240.054941 457.925902a613.293618 613.293618 0 0 0-390.565819 0L186.032398 1016.636388A141.057532 141.057532 0 0 1 0 882.938379v-12.572519a255.539008 255.539008 0 0 1 174.073172-242.250979z" fill="#CCD3D9" p-id="19702"></path></svg>

After

Width:  |  Height:  |  Size: 784 B

View File

@@ -49,7 +49,7 @@
</div>
</div>
<el-dialog title="切换科室" v-model="showDialog" width="400px" append-to-body destroy-on-close>
<el-select v-model="orgId">
<el-select v-model="orgId" filterable clearable>
<el-option
v-for="item in orgOptions"
:key="item.orgId"

View File

@@ -14,42 +14,40 @@
>
{{ tag.title }}
<span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)">
<close class="el-icon-close" style="width: 1em; height: 1em;vertical-align: middle;" />
<close class="el-icon-close" style="width: 1em; height: 1em; vertical-align: middle" />
</span>
</router-link>
</scroll-pane>
<ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
<li @click="refreshSelectedTag(selectedTag)">
<refresh-right style="width: 1em; height: 1em;" /> 刷新页面
<refresh-right style="width: 1em; height: 1em" /> 刷新页面
</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">
<close style="width: 1em; height: 1em;" /> 关闭当前
</li>
<li @click="closeOthersTags">
<circle-close style="width: 1em; height: 1em;" /> 关闭其他
<close style="width: 1em; height: 1em" /> 关闭当前
</li>
<li @click="closeOthersTags"><circle-close style="width: 1em; height: 1em" /> 关闭其他</li>
<li v-if="!isFirstView()" @click="closeLeftTags">
<back style="width: 1em; height: 1em;" /> 关闭左侧
<back style="width: 1em; height: 1em" /> 关闭左侧
</li>
<li v-if="!isLastView()" @click="closeRightTags">
<right style="width: 1em; height: 1em;" /> 关闭右侧
<right style="width: 1em; height: 1em" /> 关闭右侧
</li>
<li @click="closeAllTags(selectedTag)">
<circle-close style="width: 1em; height: 1em;" /> 全部关闭
<circle-close style="width: 1em; height: 1em" /> 全部关闭
</li>
</ul>
</div>
</template>
<script setup>
import ScrollPane from './ScrollPane'
import { getNormalPath } from '@/utils/openhis'
import useTagsViewStore from '@/store/modules/tagsView'
import useSettingsStore from '@/store/modules/settings'
import usePermissionStore from '@/store/modules/permission'
import { toRaw } from 'vue'
import { toArray } from 'lodash'
import { toReactive, toRef } from '@vueuse/core'
import ScrollPane from './ScrollPane';
import { getNormalPath } from '@/utils/openhis';
import useTagsViewStore from '@/store/modules/tagsView';
import useSettingsStore from '@/store/modules/settings';
import usePermissionStore from '@/store/modules/permission';
import { toRaw } from 'vue';
import { toArray } from 'lodash';
import { toReactive, toRef } from '@vueuse/core';
const visible = ref(false);
const top = ref(0);
@@ -67,103 +65,115 @@ const routes = computed(() => usePermissionStore().routes);
const theme = computed(() => useSettingsStore().theme);
watch(route, () => {
addTags()
moveToCurrentTag()
})
addTags();
moveToCurrentTag();
});
watch(visible, (value) => {
if (value) {
document.body.addEventListener('click', closeMenu)
document.body.addEventListener('click', closeMenu);
} else {
document.body.removeEventListener('click', closeMenu)
document.body.removeEventListener('click', closeMenu);
}
})
});
onMounted(() => {
initTags()
addTags()
if(sessionStorage.getItem('visitedViews')){
isVisitedViews()
initTags();
addTags();
if (sessionStorage.getItem('visitedViews')) {
isVisitedViews();
}
})
function isVisitedViews(){
if(sessionStorage.getItem('visitedViews')!= "TransferManagent"){ //调拨单据号删除
sessionStorage.setItem('busNo',"")
}
if(sessionStorage.getItem('visitedViews')!= "BatchTransfer"){ //批量调拨单据号删除
sessionStorage.setItem('busNopl',"")
}
if(sessionStorage.getItem('visitedViews')!= "RequisitionManagement"){ //领用单据号删除
sessionStorage.setItem('busNoLY',"")
}
if(sessionStorage.getItem('visitedViews')!= "ReturningInventory"){ //领用退货单据号删除
sessionStorage.setItem('busNoLYTH',"")
}
if(sessionStorage.getItem('visitedViews')!= "LossReportingManagement"){ //报损单据号删除
sessionStorage.setItem('busNoBS',"")
}
if(sessionStorage.getItem('visitedViews')!= "ChkstockPart"){ //盘点单据号删除
sessionStorage.setItem('busNopd',"")
}
if(sessionStorage.getItem('visitedViews')!= "ChkstockBatch"){ //批量盘点单据号删除
sessionStorage.setItem('busNoplpd',"")
}
if(sessionStorage.getItem('visitedViews')&&sessionStorage.getItem('visitedViewsQuery')!=""){
sessionStorage.setItem('busNo',"")
sessionStorage.setItem('busNopl',"")
sessionStorage.setItem('busNoLY',"")
sessionStorage.setItem('busNoLYTH',"")
sessionStorage.setItem('busNoBS',"")
sessionStorage.setItem('busNopd',"")
sessionStorage.setItem('busNoplpd',"")
});
function isVisitedViews() {
if (sessionStorage.getItem('visitedViews') != 'TransferManagent') {
//调拨单据号删除
sessionStorage.setItem('busNo', '');
}
if (sessionStorage.getItem('visitedViews') != 'BatchTransfer') {
//批量调拨单据号删除
sessionStorage.setItem('busNopl', '');
}
if (sessionStorage.getItem('visitedViews') != 'RequisitionManagement') {
//领用单据号删除
sessionStorage.setItem('busNoLY', '');
}
if (sessionStorage.getItem('visitedViews') != 'ReturningInventory') {
//领用退货单据号删除
sessionStorage.setItem('busNoLYTH', '');
}
if (sessionStorage.getItem('visitedViews') != 'LossReportingManagement') {
//报损单据号删除
sessionStorage.setItem('busNoBS', '');
}
if (sessionStorage.getItem('visitedViews') != 'ChkstockPart') {
//盘点单据号删除
sessionStorage.setItem('busNopd', '');
}
if (sessionStorage.getItem('visitedViews') != 'ChkstockBatch') {
//批量盘点单据号删除
sessionStorage.setItem('busNoplpd', '');
}
if (sessionStorage.getItem('visitedViews') && sessionStorage.getItem('visitedViewsQuery') != '') {
sessionStorage.setItem('busNo', '');
sessionStorage.setItem('busNopl', '');
sessionStorage.setItem('busNoLY', '');
sessionStorage.setItem('busNoLYTH', '');
sessionStorage.setItem('busNoBS', '');
sessionStorage.setItem('busNopd', '');
sessionStorage.setItem('busNoplpd', '');
}
}
function isActive(r) {
return r.path === route.path
return r.path === route.path;
}
function activeStyle(tag) {
if (!isActive(tag)) return {};
return {
"background-color": theme.value,
"border-color": theme.value
'background-color': theme.value,
'border-color': theme.value,
};
}
function isAffix(tag) {
return tag.meta && tag.meta.affix
return tag.meta && tag.meta.affix;
}
function isFirstView() {
try {
return selectedTag.value.fullPath === '/index' || selectedTag.value.fullPath === visitedViews.value[1].fullPath
return (
selectedTag.value.fullPath === '/index' ||
selectedTag.value.fullPath === visitedViews.value[1].fullPath
);
} catch (err) {
return false
return false;
}
}
function isLastView() {
try {
return selectedTag.value.fullPath === visitedViews.value[visitedViews.value.length - 1].fullPath
return (
selectedTag.value.fullPath === visitedViews.value[visitedViews.value.length - 1].fullPath
);
} catch (err) {
return false
return false;
}
}
function filterAffixTags(routes, basePath = '') {
let tags = []
routes.forEach(route => {
let tags = [];
routes.forEach((route) => {
if (route.meta && route.meta.affix) {
const tagPath = getNormalPath(basePath + '/' + route.path)
const tagPath = getNormalPath(basePath + '/' + route.path);
tags.push({
fullPath: tagPath,
path: tagPath,
name: route.name,
meta: { ...route.meta }
})
meta: { ...route.meta },
});
}
if (route.children) {
const tempTags = filterAffixTags(route.children, route.path)
const tempTags = filterAffixTags(route.children, route.path);
if (tempTags.length >= 1) {
tags = [...tags, ...tempTags]
tags = [...tags, ...tempTags];
}
}
})
return tags
});
return tags;
}
function initTags() {
const res = filterAffixTags(routes.value);
@@ -171,19 +181,19 @@ function initTags() {
for (const tag of res) {
// Must have tag name
if (tag.name) {
useTagsViewStore().addVisitedView(tag)
useTagsViewStore().addVisitedView(tag);
}
}
}
function addTags() {
const { name } = route
const { name } = route;
if (name) {
useTagsViewStore().addView(route)
useTagsViewStore().addView(route);
if (route.meta.link) {
useTagsViewStore().addIframeView(route);
}
}
return false
return false;
}
function moveToCurrentTag() {
nextTick(() => {
@@ -192,118 +202,118 @@ function moveToCurrentTag() {
scrollPaneRef.value.moveToTarget(r);
// when query is different then update
if (r.fullPath !== route.fullPath) {
useTagsViewStore().updateVisitedView(route)
useTagsViewStore().updateVisitedView(route);
}
}
}
})
});
}
function refreshSelectedTag(view) {
console.log("latestViewall11www1770",view)
proxy.$tab.refreshPage(view);
if (route.meta.link) {
useTagsViewStore().delIframeView(route);
}
}
function closeSelectedTag(view) {
console.log("latestViewall11www177",view)
proxy.$tab.closePage(view).then(({ visitedViews }) => {
if (isActive(view)) {
toLastView(visitedViews, view)
toLastView(visitedViews, view);
}
})
});
}
function closeRightTags() {
console.log("latestViewall11www1",selectedTag.value,3)
proxy.$tab.closeRightPage(selectedTag.value).then(visitedViews => {
if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
toLastView(visitedViews)
proxy.$tab.closeRightPage(selectedTag.value).then((visitedViews) => {
if (!visitedViews.find((i) => i.fullPath === route.fullPath)) {
toLastView(visitedViews);
}
})
});
}
function closeLeftTags() {
console.log("latestViewall11177",selectedTag.value,11)
proxy.$tab.closeLeftPage(selectedTag.value).then(visitedViews => {
if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
toLastView(visitedViews)
proxy.$tab.closeLeftPage(selectedTag.value).then((visitedViews) => {
if (!visitedViews.find((i) => i.fullPath === route.fullPath)) {
toLastView(visitedViews);
}
})
});
}
function closeOthersTags() {
console.log("latestViewall111",selectedTag.value,view)
router.push(selectedTag.value).catch(() => { });
router.push(selectedTag.value).catch(() => {});
proxy.$tab.closeOtherPage(selectedTag.value).then(() => {
moveToCurrentTag()
})
moveToCurrentTag();
});
}
function closeAllTags(view) {
console.log("latestViewall",visitedViews,view)
proxy.$tab.closeAllPage().then(({ visitedViews }) => {
if (affixTags.value.some(tag => tag.path === route.path)) {
return
if (affixTags.value.some((tag) => tag.path === route.path)) {
return;
}
toLastView(visitedViews, view)
})
toLastView(visitedViews, view);
});
}
function toLastView(visitedViews, view) {
const latestView = visitedViews.slice(-1)[0]
console.log(latestView,"latestView",visitedViews,view)
if(view.name== "TransferManagent"){ //调拨单据号删除
sessionStorage.setItem('busNo',"")
}
if(view.name== "BatchTransfer"){ //批量调拨单据号删除
sessionStorage.setItem('busNopl',"")
}
if(view.name== "RequisitionManagement"){ //领用单据号删除
sessionStorage.setItem('busNoLY',"")
}
if(view.name== "ReturningInventory"){ //领用退货单据号删除
sessionStorage.setItem('busNoLYTH',"")
}
if(view.name== "LossReportingManagement"){ //报损单据号删除
sessionStorage.setItem('busNoBS',"")
}
if(view.name== "ChkstockPart"){ //盘点单据号删除
sessionStorage.setItem('busNopd',"")
}
if(view.name== "ChkstockBatch"){ //批量盘点单据号删除
sessionStorage.setItem('busNoplpd',"")
}
const latestView = visitedViews.slice(-1)[0];
if (view.name == 'TransferManagent') {
//调拨单据号删除
sessionStorage.setItem('busNo', '');
}
if (view.name == 'BatchTransfer') {
//批量调拨单据号删除
sessionStorage.setItem('busNopl', '');
}
if (view.name == 'RequisitionManagement') {
//领用单据号删除
sessionStorage.setItem('busNoLY', '');
}
if (view.name == 'ReturningInventory') {
//领用退货单据号删除
sessionStorage.setItem('busNoLYTH', '');
}
if (view.name == 'LossReportingManagement') {
//报损单据号删除
sessionStorage.setItem('busNoBS', '');
}
if (view.name == 'ChkstockPart') {
//盘点单据号删除
sessionStorage.setItem('busNopd', '');
}
if (view.name == 'ChkstockBatch') {
//批量盘点单据号删除
sessionStorage.setItem('busNoplpd', '');
}
if (latestView) {
router.push(latestView.fullPath)
router.push(latestView.fullPath);
} else {
// now the default is to redirect to the home page if there is no tags-view,
// you can adjust it according to your needs.
if (view.name === 'Dashboard') {
// to reload home page
router.replace({ path: '/redirect' + view.fullPath })
}else {
router.push('/')
router.replace({ path: '/redirect' + view.fullPath });
} else {
router.push('/');
}
}
}
function openMenu(tag, e) {
const menuMinWidth = 105
const offsetLeft = proxy.$el.getBoundingClientRect().left // container margin left
const offsetWidth = proxy.$el.offsetWidth // container width
const maxLeft = offsetWidth - menuMinWidth // left boundary
const l = e.clientX - offsetLeft + 15 // 15: margin right
const menuMinWidth = 105;
const offsetLeft = proxy.$el.getBoundingClientRect().left; // container margin left
const offsetWidth = proxy.$el.offsetWidth; // container width
const maxLeft = offsetWidth - menuMinWidth; // left boundary
const l = e.clientX - offsetLeft + 15; // 15: margin right
if (l > maxLeft) {
left.value = maxLeft
left.value = maxLeft;
} else {
left.value = l
left.value = l;
}
top.value = e.clientY
visible.value = true
selectedTag.value = tag
top.value = e.clientY;
visible.value = true;
selectedTag.value = tag;
}
function closeMenu() {
visible.value = false
visible.value = false;
}
function handleScroll() {
closeMenu()
closeMenu();
}
</script>
@@ -339,7 +349,7 @@ function handleScroll() {
color: #fff;
border-color: #42b983;
&::before {
content: "";
content: '';
background: #fff;
display: inline-block;
width: 8px;

View File

@@ -3,6 +3,7 @@ import { createApp } from 'vue'
import Cookies from 'js-cookie'
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import 'element-plus/dist/index.css'
import locale from 'element-plus/es/locale/lang/zh-cn'
@@ -15,7 +16,7 @@ import directive from './directive' // directive
// 注册指令
import plugins from './plugins' // plugins
import { download } from '@/utils/request'
import { download, downloadGet } from '@/utils/request'
// svg图标
import 'virtual:svg-icons-register'
@@ -27,6 +28,8 @@ import './permission' // permission control
import { useDict } from '@/utils/dict'
import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels} from '@/utils/openhis'
import { formatDateStr } from '@/utils/index';
// 分页组件
import Pagination from '@/components/Pagination'
// 自定义表格工具组件
@@ -61,12 +64,14 @@ if(chrome.webview !== undefined) {
// 全局方法挂载
app.config.globalProperties.useDict = useDict
app.config.globalProperties.download = download
app.config.globalProperties.downloadGet = downloadGet
app.config.globalProperties.parseTime = parseTime
app.config.globalProperties.resetForm = resetForm
app.config.globalProperties.handleTree = handleTree
app.config.globalProperties.addDateRange = addDateRange
app.config.globalProperties.selectDictLabel = selectDictLabel
app.config.globalProperties.selectDictLabels = selectDictLabels
app.config.globalProperties.formatDateStr = formatDateStr
// 全局挂载请求实例
app.config.globalProperties.$http = request
@@ -91,7 +96,7 @@ directive(app)
ElDialog.props.closeOnClickModal.default = false;
// 使用element-plus 并且设置全局的大小
app.use(ElementPlus, {
locale: locale,
locale: zhCn,
// 支持 large、default、small
size: Cookies.get('size') || 'default'
})

View File

@@ -1,6 +1,6 @@
import { createWebHistory, createRouter } from 'vue-router'
import { createWebHistory, createRouter } from 'vue-router';
/* Layout */
import Layout from '@/layout'
import Layout from '@/layout';
/**
* Note: 路由配置项
@@ -34,24 +34,29 @@ export const constantRoutes = [
children: [
{
path: '/redirect/:path(.*)',
component: () => import('@/views/redirect/index.vue')
}
]
component: () => import('@/views/redirect/index.vue'),
},
],
},
{
path: '/login',
component: () => import('@/views/login'),
hidden: true
hidden: true,
},
{
path: '/register',
component: () => import('@/views/register'),
hidden: true
hidden: true,
},
{
path: '/:pathMatch(.*)*',
component: () => import('@/views/error/404'),
hidden: true,
},
{
path: '/401',
component: () => import('@/views/error/401'),
hidden: true
hidden: true,
},
{
path: '',
@@ -62,10 +67,11 @@ export const constantRoutes = [
path: '/index',
component: () => import('@/views/index'),
name: 'Index',
meta: { title: '首页', icon: 'dashboard', affix: true }
}
]
meta: { title: '首页', icon: 'dashboard', affix: true },
},
],
},
{
path: '/user',
component: Layout,
@@ -76,6 +82,11 @@ export const constantRoutes = [
path: 'profile',
component: () => import('@/views/system/user/profile/index'),
name: 'Profile',
meta: { title: '个人中心', icon: 'user' },
},
],
},
];
meta: { title: '个人中心', icon: 'user' }
}
]
@@ -234,6 +245,9 @@ export const constantRoutes = [
path: 'set/:tenantId(\\d+)',
component: () => import('@/views/system/tenant/setUser'),
name: 'SetUser',
meta: { title: '所属用户', activeMenu: '/system/basicmanage/tenant' },
},
],
meta: { title: '所属用户', activeMenu: '/system/tenant' }
}
]
@@ -248,6 +262,9 @@ export const constantRoutes = [
path: 'set/:tenantId(\\d+)',
component: () => import('@/views/system/tenant/setContract'),
name: 'SetContract',
meta: { title: '合同管理', activeMenu: '/system/basicmanage/tenant' },
},
],
meta: { title: '合同管理', activeMenu: '/system/tenant' }
}
]
@@ -262,9 +279,9 @@ export const constantRoutes = [
path: 'role/:userId(\\d+)',
component: () => import('@/views/system/user/authRole'),
name: 'AuthRole',
meta: { title: '分配角色', activeMenu: '/system/user' }
}
]
meta: { title: '分配角色', activeMenu: '/system/user' },
},
],
},
{
path: '/system/role-auth',
@@ -276,9 +293,9 @@ export const constantRoutes = [
path: 'user/:roleId(\\d+)',
component: () => import('@/views/system/role/authUser'),
name: 'AuthUser',
meta: { title: '分配用户', activeMenu: '/system/role' }
}
]
meta: { title: '分配用户', activeMenu: '/system/role' },
},
],
},
{
path: '/system/dict-data',
@@ -290,9 +307,9 @@ export const constantRoutes = [
path: 'index/:dictId(\\d+)',
component: () => import('@/views/system/dict/data'),
name: 'Data',
meta: { title: '字典数据', activeMenu: '/system/dict' }
}
]
meta: { title: '字典数据', activeMenu: '/system/dict' },
},
],
},
{
path: '/monitor',
@@ -346,9 +363,9 @@ export const constantRoutes = [
path: 'index/:jobId(\\d+)',
component: () => import('@/views/monitor/job/log'),
name: 'JobLog',
meta: { title: '调度日志', activeMenu: '/monitor/job' }
}
]
meta: { title: '调度日志', activeMenu: '/monitor/job' },
},
],
},
{
path: '/tool/gen-edit',
@@ -360,6 +377,11 @@ export const constantRoutes = [
path: 'index/:tableId(\\d+)',
component: () => import('@/views/tool/gen/editTable'),
name: 'GenEdit',
meta: { title: '修改生成配置', activeMenu: '/tool/gen' },
},
],
},
];
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
}
]
@@ -381,9 +403,9 @@ const router = createRouter({
routes: allRoutes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
return savedPosition;
} else {
return { top: 0 }
return { top: 0 };
}
},
});

View File

@@ -19,6 +19,7 @@ const useUserStore = defineStore(
roles: [],
permissions: [],
tenantId: '',
hospitalName:'',
status: '' // 用户状态0-启用(管理员), 1-禁用(普通人员)
}),
actions: {
@@ -53,6 +54,7 @@ const useUserStore = defineStore(
} else {
this.roles = ['ROLE_DEFAULT']
}
// console.log('user info:', user);
this.id = user.userId
this.name = user.userName // 用户账号对应数据库的user_name字段如'admin'
this.orgId = user.orgId
@@ -61,6 +63,8 @@ const useUserStore = defineStore(
this.practitionerId = res.practitionerId
this.fixmedinsCode = res.optionJson.fixmedinsCode
this.avatar = avatar
this.hospitalName = res.optionJson.hospitalName
this.status = user.status // 保存用户状态
resolve(res)
}).catch(error => {

View File

@@ -14,6 +14,7 @@ export const useStore = defineStore('current', {
currentDataBS:null, //报损
currentDataLYCK:null, //领用出库
currentDataLYTK:null, //领用退库
remainingDays:null, //有效期天数
}),
actions: {
setCurrentData(data) {
@@ -54,6 +55,9 @@ export const useStore = defineStore('current', {
setCurrentDataLYTK(data) {
this.currentDataLYTK = data
},
setRemainingDays(data) {
this.remainingDays = data
},
clearCurrentDataDBAll() {
this.currentDataDBAll = null
@@ -92,6 +96,10 @@ export const useStore = defineStore('current', {
},
clearCurrentDataDB() {
this.currentDataDB = null
}
},
clearRemainingDays() {
this.remainingDays = null
},
}
})

View File

@@ -0,0 +1,897 @@
<template>
<div>
<div class="business">
<el-table
:data="tableDataSource"
border
stripe
fit
:header-cell-style="{ background: '#f2f2f2', color: 'black' }"
>
<el-table-column prop="content.recordTime" label="记录时间" />
<el-table-column prop="content.totalScore" label="评估分数" />
<el-table-column prop="content.patientCareSessionsTableList" label="护理措施" />
<el-table-column prop="content.nurseSignature" label="责任护士" />
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
plain
type="primary"
size="small"
@click="handleUpdate(scope.row)"
:disabled="admissionDataForm !== undefined"
>
编辑
</el-button>
<el-button
plain
type="danger"
size="small"
@click="handleDelete(scope.row)"
:disabled="admissionDataForm !== undefined"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<div name="跌倒/坠床评估护理记录单" class="changeMajor" style="width: 99.9%">
<div>
<el-form ref="formRef" :model="form" style="width: 99.9%">
<el-form-item style="text-align: center">
<div
style="
width: 100%;
font-size: 14pt;
color: black;
text-align: center;
font-weight: 600;
line-height: 36px;
"
>
<span class="space">跌倒/坠床评估护理记录单</span>
</div>
</el-form-item>
<el-form-item label="日期:" class="changeMajorFromItem" style="width: 100%">
<el-row :span="20">
<el-col :span="8" style="padding-left: 0px !important">
<el-form-item>
<el-date-picker
v-model="form.ZKDATE"
type="datetime"
placeholder="选择日期"
value-format="YYYY-MM-DD HH:mm:ss"
format="YYYY-MM-DD HH:mm:ss"
style="width: 800px"
:disabled="admissionDataForm !== undefined"
/>
<!-- <span style="margin-left: 5px">时间</span>
<el-time-picker
v-model="form.ZKTIME"
placeholder="选择时间"
value-format="HH:mm:ss"
style="width: 40%"
:disabled="admissionDataForm !== undefined"
/> -->
</el-form-item>
</el-col>
<el-col :span="5">
<el-button
v-if="!updateFlag"
type="primary"
size="medium"
style="margin-left: 25px"
@click="onSubmit"
>
新增记录
</el-button>
<el-button
v-else
type="primary"
size="small"
style="margin-left: 5px"
@click="onSubmit"
>
保存记录
</el-button>
</el-col>
</el-row>
</el-form-item>
<el-form-item style="padding-top: 10px; margin: 0px !important">
<el-table
:data="dangerData"
border
:span-method="handleSpan"
style="text-align: center"
>
<el-table-column
v-for="column in dangerColumns"
:key="column.key"
:prop="column.key"
:width="column.width"
:label="column.title"
align="center"
/>
<el-table-column prop="id" label="选择" width="80" align="center">
<template #default="{ row }">
<el-checkbox v-model="row.checked" @change="handleDangerChange(row)" />
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item
style="text-align: center; margin-bottom: 0px; padding: 0px"
class="changeMajorFromItem"
>
<el-row :span="24">
<el-col :span="24">
<span style="font-size: large">总分</span>
<span>{{ totalScore }}</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item style="padding-top: 10px">
<el-table
:data="nursingData"
border
:span-method="arraySpanMethod"
style="width: 100%"
>
<el-table-column
v-for="column in nursingColumns"
:key="column.key"
:prop="column.key"
:width="column.width"
:label="column.title"
align="center"
/>
<el-table-column prop="id" label="选择" width="80" align="center">
<template #default="{ row }">
<el-checkbox v-model="row.checked" @change="handleNursingChange(row)" />
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item
style="text-align: center; margin-bottom: 0px; padding: 0px"
class="changeMajorFromItem"
>
<el-row
:span="24"
style="display: flex; justify-content: center; align-items: center"
>
<div style="display: flex; align-items: center; gap: 10px">
<span style="font-size: large; margin-left: 10vh">护士签字</span>
<el-input
v-model="form.nurseSignature"
style="width: 300px; padding: 8px"
disabled
/>
</div>
</el-row>
</el-form-item>
<el-form-item>
<el-row :span="20">
<el-col :span="5">
<span>备注</span>
</el-col>
</el-row>
<el-form-item label-width="15px">
<ul class="instructions-list">
<li v-for="(item, index) in instructions" :key="index">{{ item }}</li>
</ul>
</el-form-item>
</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
</template>
<script setup>
defineOptions({
name: 'FallBedFallAssessment',
});
import { ref, reactive, computed, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
// import { webapp_ws_ajax_run, urlAddRandomNo } from '@/utils/grwebapp';
// import { useRoute, useRouter } from 'vue-router';
// 响应式数据
const route = useRoute();
const router = useRouter();
const queryRef = ref();
const formRef = ref();
const wardCode = ref('');
const patientId = ref('');
const visitId = ref('');
const type = '跌倒/坠床评估护理记录单';
const updateFlag = ref(false);
const info = ref('返回信息');
const updateId = ref('');
const tableDataSource = ref([]);
const content = ref({});
const totalScore = ref(0);
const lastSubmit = ref('');
const admissionDataForm = ref(route.params.admissionData);
const form = reactive({
ZKDATE: '',
ZKTIME: '',
recordTime: '',
totalScore: 0,
bedFallRiskAssessmentList: [],
nurseSignature: '',
patientCareSessionsCheckedList: [],
});
// 危险因素表格列
const dangerColumns = [
{
key: 'content',
title: '内容',
width: '100',
},
{
key: 'project',
title: '项目',
},
{
key: 'evalContent',
title: '评定内容',
},
{
key: 'score',
title: '分数',
},
];
// 危险因素数据 - 使用ref确保响应性
const dangerData = ref([
{
id: '1',
content: '危险因素',
project: '年龄',
evalContent: '≥80周岁',
score: 5,
checked: false,
},
{ id: '2', content: '', evalContent: '≤3周岁≥3个月', score: 5, checked: false },
{ id: '3', content: '', evalContent: '>70周岁', score: 3, checked: false },
{ id: '4', content: '', evalContent: '≤5周岁', score: 5, checked: false },
{ id: '5', project: '既往史', evalContent: '跌倒史', score: 1, checked: false },
{ id: '6', evalContent: '坠床史', score: 2, checked: false },
{ id: '7', evalContent: '癫痫史', score: 2, checked: false },
{ id: '8', project: '意识状态', evalContent: '嗜睡', score: 2, checked: false },
{ id: '9', evalContent: '意识模糊', score: 2, checked: false },
{ id: '10', evalContent: '谵妄', score: 3, checked: false },
{ id: '11', evalContent: '躁动', score: 3, checked: false },
{ id: '12', project: '感官因素', evalContent: '头晕', score: 4, checked: false },
{ id: '13', evalContent: '听力障碍', score: 2, checked: false },
{ id: '14', evalContent: '视力障碍', score: 2, checked: false },
{
id: '15',
project: '肢体活动',
evalContent: '关节僵硬、变形、疼痛',
score: 1,
checked: false,
},
{ id: '16', evalContent: '借助器械', score: 2, checked: false },
{ id: '17', evalContent: '肢体偏瘫', score: 3, checked: false },
{ id: '18', evalContent: '肌肉震颤麻痹', score: 3, checked: false },
{ id: '19', evalContent: '体质虚弱、乏力', score: 1, checked: false },
{ id: '20', evalContent: '尿频、尿急', score: 1, checked: false },
{ id: '21', evalContent: '腹泻、便秘', score: 2, checked: false },
{ id: '22', project: '药物因素', evalContent: '散瞳剂', score: 1, checked: false },
{ id: '23', evalContent: '降压药', score: 1, checked: false },
{ id: '24', evalContent: '降糖药', score: 1, checked: false },
{ id: '25', evalContent: '镇静安眠药', score: 2, checked: false },
{ id: '26', evalContent: '镇痛抗癫痫', score: 2, checked: false },
{ id: '27', evalContent: '麻醉止痛剂', score: 2, checked: false },
]);
// 护理措施表格列
const nursingColumns = [
{
key: 'content',
width: '100',
title: '',
},
{
key: 'project',
title: '内容',
},
];
// 护理措施数据 - 使用ref确保响应性
const nursingData = ref([
{
id: '1',
content: '护理措施',
project: '告知患者及家属可能导致跌倒、坠床的原因,并采取相应防范措施',
checked: false,
},
{ id: '2', project: '悬挂预防跌倒、坠床标识,必要时班班交接', checked: false },
{ id: '3', project: '患者日常用物放于可及处', checked: false },
{ id: '4', project: '将呼叫器放于可及处,提醒患者下床时若有必要寻求帮助', checked: false },
{ id: '5', project: '依据风险程度,必要时专人陪住', checked: false },
{ id: '6', project: '保持地面无水渍、障碍物,病室及活动区域灯光充足', checked: false },
{ id: '7', project: '指导患者穿长短合适的衣裤及防滑鞋', checked: false },
{ id: '8', project: '适当使用床栏或约束带', checked: false },
]);
// 说明信息
const instructions = [
'1.评估对象:新入患者、术后患者、有病情变化时必须评估;',
'2.评分<5分低度风险无需连续评估无需采取预防措施',
'3.评分≥5高度风险每周至少评估一次需采取适宜的预防措施同时填写《预防患者跌倒/坠床知情告知书》',
];
// 计算属性
const calculate = computed(() => {
return dangerData.value
.filter((option) => option.checked)
.reduce((total, option) => total + option.score, 0);
});
const isFormEmpty = computed(() => {
return (
form.ZKDATE === '' && form.ZKTIME === '' && form.recordTime === '' && form.nurseSignature === ''
);
});
// 方法 - 不再需要handleData方法通过表单输入和按钮加载数据
const handleDangerChange = (row) => {
totalScore.value = calculate.value;
form.bedFallRiskAssessmentList = dangerData.value
.filter((item) => item.checked)
.map((item) => item.id);
};
const handleNursingChange = (row) => {
form.patientCareSessionsCheckedList = nursingData.value
.filter((item) => item.checked)
.map((item) => item.id);
};
const init = async () => {
// 使用模拟数据不再调用后端API
try {
console.log('使用模拟数据初始化表格');
// 生成一些模拟数据
const mockData = [
{
id: '1',
content: {
ZKDATE: '2023-01-15',
ZKTIME: '09:30:00',
recordTime: '2023-01-15 09:30:00',
totalScore: 8,
bedFallRiskAssessmentList: ['1', '5', '12'],
nurseSignature: '张护士',
patientCareSessionsCheckedList: ['1', '2', '3'],
patientCareSessionsTableList: '1,2,3',
},
},
{
id: '2',
content: {
ZKDATE: '2023-01-20',
ZKTIME: '14:20:00',
recordTime: '2023-01-20 14:20:00',
totalScore: 5,
bedFallRiskAssessmentList: ['3', '11'],
nurseSignature: '李护士',
patientCareSessionsCheckedList: ['1', '4'],
patientCareSessionsTableList: '1,4',
},
},
];
tableDataSource.value = [];
if (mockData && mockData.length > 0) {
mockData.forEach((item) => {
tableDataSource.value.push(item);
});
if (admissionDataForm.value !== undefined) {
const rowData = tableDataSource.value.filter(
(item) => item.content.recordTime === JSON.parse(admissionDataForm.value).assessmentDate
);
if (rowData.length > 0) {
handleUpdate(rowData[0]);
}
}
} else {
tableDataSource.value = [];
reset();
}
ElMessage.success('模拟数据加载成功');
} catch (error) {
console.error('初始化失败:', error);
}
};
const handleSpan = ({ row, column, rowIndex, columnIndex }) => {
if (columnIndex === 0) {
if (rowIndex === 0) {
return [dangerData.value.length, 1];
} else if (rowIndex > 0 && rowIndex < 27) {
return [0, 0];
}
if (rowIndex === 27) {
return [1, 4];
}
}
if (columnIndex === 1) {
if (rowIndex === 0) {
return [4, 1];
} else if (rowIndex > 0 && rowIndex < 4) {
return [0, 0];
}
if (rowIndex === 4) {
return [3, 1];
} else if (rowIndex > 0 && rowIndex < 7) {
return [0, 0];
}
if (rowIndex === 7) {
return [4, 1];
} else if (rowIndex > 0 && rowIndex < 11) {
return [0, 0];
}
if (rowIndex === 11) {
return [3, 1];
} else if (rowIndex > 0 && rowIndex < 14) {
return [0, 0];
}
if (rowIndex === 14) {
return [7, 1];
} else if (rowIndex > 0 && rowIndex < 21) {
return [0, 0];
}
if (rowIndex === 21) {
return [6, 1];
} else if (rowIndex > 0 && rowIndex < 27) {
return [0, 0];
}
}
return [1, 1];
};
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
// 护理措施
if (columnIndex === 0) {
if (rowIndex === 0) {
return [nursingData.value.length, 1];
} else if (rowIndex > 0 && rowIndex < 8) {
return [0, 0];
}
// 护士签名
if (rowIndex === 8) {
return [1, 2];
}
}
return [1, 1];
};
const onSubmit = async () => {
// 检查上次提交时间
if (lastSubmit.value && new Date() - lastSubmit.value < 2000) {
ElMessage.error('禁止重复提交!');
return;
}
// 更新上次提交时间
lastSubmit.value = new Date();
// 时间处理
if (form.ZKDATE) {
form.recordTime = form.ZKDATE;
}
if (form.ZKTIME) {
form.recordTime = form.ZKTIME;
}
if (form.ZKDATE && form.ZKTIME) {
form.recordTime = form.ZKDATE + ' ' + form.ZKTIME;
}
form.recordTime ? new Date(form.recordTime) : null;
if (isFormEmpty.value) {
ElMessage.error('请填写跌倒/坠床评估护理记录单后再进行操作');
} else {
form.totalScore = totalScore.value;
// 模拟保存数据不再调用后端API
console.log('保存的数据:', form);
if (updateFlag.value) {
// 模拟更新操作
const updatedIndex = tableDataSource.value.findIndex((item) => item.id === updateId.value);
if (updatedIndex !== -1) {
tableDataSource.value[updatedIndex].content = { ...form };
}
ElMessage.success('模拟更新成功');
} else {
// 模拟新增操作
const newRecord = {
id: Date.now().toString(),
content: { ...form },
};
tableDataSource.value.unshift(newRecord);
ElMessage.success('模拟新增成功');
}
if (admissionDataForm.value !== undefined) {
const admissionDataBack = JSON.parse(admissionDataForm.value);
admissionDataBack.project2 = totalScore.value;
if (route.params.updateId !== undefined) {
router.push({
name: 'admissionEvaluation',
params: {
admissionData: JSON.stringify(admissionDataBack),
updateId: route.params.updateId,
},
});
} else {
router.push({
name: 'admissionEvaluation',
params: { admissionData: JSON.stringify(admissionDataBack) },
});
}
}
reset();
}
};
const handleUpdate = (row) => {
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
if (
row.content.nurseSignature !== loginUser.userName &&
window.localStorage.getItem('editFlg') === '0'
) {
window.confirm('没有操作该数据的权限!');
} else {
reset();
updateFlag.value = true;
// 深拷贝数据
Object.assign(form, JSON.parse(JSON.stringify(row.content)));
totalScore.value = row.content.totalScore;
// 评估项目
dangerData.forEach((item) => {
item.checked = form.bedFallRiskAssessmentList.includes(item.id);
});
nursingData.forEach((item) => {
item.checked = form.patientCareSessionsCheckedList.includes(item.id);
});
updateId.value = row.id;
}
};
const reset = () => {
Object.assign(form, {
ZKDATE: '',
ZKTIME: '',
recordTime: '',
totalScore: 0,
bedFallRiskAssessmentList: [],
nurseSignature: '',
patientCareSessionsCheckedList: [],
});
// 初始化评估项目
dangerData.forEach((session) => {
session.checked = false;
});
// 初始化护理措施
nursingData.forEach((session) => {
session.checked = false;
});
totalScore.value = 0;
updateId.value = '';
updateFlag.value = false;
if (admissionDataForm.value !== undefined) {
const [date, time] = JSON.parse(admissionDataForm.value).assessmentDate.split(' ');
form.ZKDATE = date;
form.ZKTIME = time;
}
};
const handleDelete = (row) => {
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
if (
row.content.nurseSignature !== loginUser.userName &&
window.localStorage.getItem('editFlg') === '0'
) {
window.confirm('没有操作该数据的权限!');
} else {
reset();
// 模拟删除操作不再调用后端API
const index = tableDataSource.value.findIndex((item) => item.id === row.id);
if (index !== -1) {
tableDataSource.value.splice(index, 1);
updateFlag.value = false;
ElMessage.success('模拟删除成功');
} else {
ElMessage.error('删除失败');
}
}
};
const dc_ajax_preview = () => {
var args = {
report: urlAddRandomNo('./grf/NurseRecord_Pressure_208.grf'),
data: transformData(),
type: 'preview',
};
webapp_ws_ajax_run(args);
};
const transformData = () => {
const jsonDate = [...tableDataSource.value];
jsonDate.forEach((element) => {
element.content.bedFallRiskAssessmentList.forEach((i) => {
switch (i) {
case '1':
element.FS1 = '√';
break;
case '2':
element.FS2 = '√';
break;
case '3':
element.FS3 = '√';
break;
case '4':
element.FS4 = '√';
break;
case '5':
element.FS5 = '√';
break;
case '6':
element.FS6 = '√';
break;
case '7':
element.FS7 = '√';
break;
case '8':
element.FS8 = '√';
break;
case '9':
element.FS9 = '√';
break;
case '10':
element.FS10 = '√';
break;
case '11':
element.FS11 = '√';
break;
case '12':
element.FS12 = '√';
break;
case '13':
element.FS13 = '√';
break;
case '14':
element.FS14 = '√';
break;
case '15':
element.FS15 = '√';
break;
case '16':
element.FS16 = '√';
break;
case '17':
element.FS17 = '√';
break;
case '18':
element.FS18 = '√';
break;
case '19':
element.FS19 = '√';
break;
case '20':
element.FS20 = '√';
break;
case '21':
element.FS21 = '√';
break;
case '22':
element.FS22 = '√';
break;
case '23':
element.FS23 = '√';
break;
case '24':
element.FS24 = '√';
break;
case '25':
element.FS25 = '√';
break;
case '26':
element.FS26 = '√';
break;
case '27':
element.FS27 = '√';
break;
}
});
element.countsum = element.content.totalScore;
element.RQ = element.content.ZKDATE;
element.SJ = element.content.ZKTIME;
element.recordTime = element.content.ZKDATE + ' ' + element.content.ZKTIME;
element.SIGN = element.content.nurseSignature;
element.content.patientCareSessionsCheckedList.forEach((i) => {
switch (i) {
case '1':
element.HL1 = '√';
break;
case '2':
element.HL2 = '√';
break;
case '3':
element.HL3 = '√';
break;
case '4':
element.HL4 = '√';
break;
case '5':
element.HL5 = '√';
break;
case '6':
element.HL6 = '√';
break;
case '7':
element.HL7 = '√';
break;
case '8':
element.HL8 = '√';
break;
}
});
});
if (jsonDate.length == 0) {
jsonDate[0] = {};
}
jsonDate[0].RYRQ = patientInfo.value.admissionDateTime;
jsonDate[0].KS = patientInfo.value.deptName;
jsonDate[0].CH = patientInfo.value.bedLabel;
jsonDate[0].name = patientInfo.value.name;
jsonDate[0].sex = patientInfo.value.sex;
jsonDate[0].AGE = patientInfo.value.age;
jsonDate[0].ZYH = patientInfo.value.patientIdAndVisitId;
jsonDate[0].ZD = patientInfo.value.diagnosis;
const transformedData = {
master: jsonDate,
};
return transformedData;
};
// 生命周期钩子
onMounted(() => {
try {
// 安全获取用户信息
let loginUser = {};
const userStr = window.localStorage.getItem('loginUser');
if (userStr) {
loginUser = JSON.parse(userStr);
}
form.nurseSignature = loginUser.userName || '测试护士';
wardCode.value = window.localStorage.getItem('wardInfo') || '';
admissionDataForm.value = route.params.admissionData;
// 自动初始化表格数据不再依赖患者ID参数
// 延迟执行,确保所有数据都已初始化
setTimeout(() => {
init();
}, 100);
} catch (error) {
console.error('初始化错误:', error);
// 即使出错也要初始化表格,显示默认数据
setTimeout(() => {
init();
}, 100);
}
});
</script>
<style scoped>
.business {
background: white;
border-radius: 5px;
padding: 10px 16px;
height: calc(100vh - var(--barHeight) * 1px - 50px);
overflow: auto;
display: grid;
grid-row-gap: 16px;
.changeMajor {
border: 2px solid gray;
padding: 20px;
border-radius: 5px;
}
.changeMajorFromItem {
border: 1px solid #ebeef5;
border-radius: 4px;
padding: 5px;
margin-bottom: 1px;
}
.tableBorder {
border: 1px solid #ebeef5;
}
.tableBorderRight {
border-right: 1px solid #ebeef5;
}
.tableBorderRightBottom {
border-right: 1px solid #ebeef5;
border-bottom: 1px solid #ebeef5;
}
.tableBorderBottom {
border-bottom: 1px solid #ebeef5;
}
.el-textarea {
overflow-y: auto;
min-height: 50px;
max-height: 300px;
}
.bed-no-label {
padding-right: 10px;
}
.title-inline {
display: inline-block;
}
.arrowhead {
margin-left: 6px;
font-size: 15px;
padding: 5px 10px;
}
.el-form-item {
margin-bottom: 0px !important;
}
}
</style>

View File

@@ -7,7 +7,9 @@
<el-tab-pane label="病案首页(二)" name="second">
<medicalRecordSecond :formData="formData"></medicalRecordSecond>
</el-tab-pane>
<el-tab-pane label="病案附页(一)" name="third"></el-tab-pane>
<el-tab-pane label="病案附页(一)" name="third">
<medicalRecordThird :formData="formData"></medicalRecordThird>
</el-tab-pane>
</el-tabs>
<div class="form-footer">
@@ -18,10 +20,17 @@
</template>
<script setup>
defineOptions({
name: 'HospitalRecordForm',
});
import { ref, reactive } from 'vue';
import medicalRecordFirst from './components/medicalRecordFirst.vue';
import medicalRecordSecond from './components/medicalRecordSecond.vue';
import medicalRecordFirstPrint from './components/medicalRecordFirstPrint.json';
// import medicalRecordFirst from './components/medicalRecordFirst.vue';
import medicalRecordFirst from '@/views/hospitalRecord/components/medicalRecordFirst.vue';
import medicalRecordSecond from '@/views/hospitalRecord/components/medicalRecordSecond.vue';
import medicalRecordThird from '@/views/hospitalRecord/components/medicalRecordThird.vue';
import medicalRecordFirstPrint from '@/views/hospitalRecord/components/medicalRecordFirstPrint.json';
import medicalRecordSecondPrint from '@/views/hospitalRecord/components/medicalRecordSecondPrint.json';
import medicalRecordThirdPrint from '@/views/hospitalRecord/components/medicalRecordThirdPrint.json';
//
const formData = reactive({
@@ -95,16 +104,15 @@ const printForm = () => {
if(activeName.value == 'first') {
printContent = medicalRecordFirstPrint.printContent;
}else if(activeName.value == 'second') {
printContent = medicalRecordSecondPrint.printContent;
}else {
printContent = medicalRecordThirdPrint.printContent;
}
//
printContent = printContent.replace(/\$\{([^}]+)\}/g, (match, expr) => {
// expr
return eval(expr); // 使eval
});
//
printWindow.document.write(printContent);
printWindow.document.close();
@@ -139,9 +147,10 @@ const resetForm = () => {
</script>
<style scoped>
/*max-width: 1000px;*/
.hospital-record-form {
font-family: 'SimSun', serif;
max-width: 1000px;
width: 100%;
margin: 0 auto;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);

View File

@@ -0,0 +1,828 @@
<template>
<div class="medical-form">
<h2 style="text-align: center;">{{ userStore.hospitalName || '长春市朝阳区中医院' }} -入院记录</h2>
<!-- 滚动内容区域 -->
<div class="form-scroll-container">
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="80px"
label-align="left"
class="medical-full-form"
>
<!-- 1. 基础信息区域自适应两列布局 -->
<h4 class="section-title">基础信息</h4>
<div class="adaptive-grid form-section">
<el-form-item label="姓名" prop="patientName" class="grid-item required">
<el-input
v-model="formData.patientName"
placeholder="请输入姓名"
clearable
/>
</el-form-item>
<el-form-item label="住院号" prop="hospitalNo" class="grid-item required">
<el-input
v-model="formData.hospitalNo"
placeholder="请输入住院号"
clearable
/>
</el-form-item>
<el-form-item label="性别" prop="gender" class="grid-item required">
<el-select v-model="formData.gender" placeholder="请选择" style="width: 100%;">
<el-option label="男" value="男"></el-option>
<el-option label="女" value="女"></el-option>
</el-select>
</el-form-item>
<el-form-item label="年龄" prop="age" class="grid-item required">
<div class="input-with-unit">
<el-input
v-model.number="formData.age"
placeholder="请输入年龄"
clearable
/>
<span class="unit"></span>
</div>
</el-form-item>
<el-form-item label="民族" prop="nation" class="grid-item">
<el-input
v-model="formData.nation"
placeholder="请输入民族"
clearable
/>
</el-form-item>
<el-form-item label="职业" prop="occupation" class="grid-item">
<el-input
v-model="formData.occupation"
placeholder="请输入职业"
clearable
/>
</el-form-item>
<el-form-item label="婚姻状况" prop="marriage" class="grid-item">
<el-select v-model="formData.marriage" placeholder="请选择" clearable style="width: 100%;">
<el-option label="已婚" value="已婚"></el-option>
<el-option label="未婚" value="未婚"></el-option>
<el-option label="离异" value="离异"></el-option>
</el-select>
</el-form-item>
<el-form-item label="出生地" prop="birthplace" class="grid-item">
<el-input
v-model="formData.birthplace"
placeholder="请输入出生地"
clearable
/>
</el-form-item>
<el-form-item label="入院时间" prop="admissionTime" class="grid-item required">
<el-date-picker
v-model="formData.admissionTime"
type="datetime"
placeholder="选择入院时间"
value-format="YYYY-MM-DD HH:mm"
style="width: 100%;"
/>
</el-form-item>
<el-form-item label="记录时间" prop="recordTime" class="grid-item required">
<el-date-picker
v-model="formData.recordTime"
type="datetime"
placeholder="选择记录时间"
value-format="YYYY-MM-DD HH:mm"
style="width: 100%;"
/>
</el-form-item>
<el-form-item label="病史陈述者" prop="historyReporter" class="grid-item">
<el-input
v-model="formData.historyReporter"
placeholder="请输入陈述者"
clearable
/>
</el-form-item>
<el-form-item label="可靠程度" prop="reliability" class="grid-item">
<el-select v-model="formData.reliability" placeholder="请选择" style="width: 100%;">
<el-option label="可靠" value="可靠"></el-option>
<el-option label="基本可靠" value="基本可靠"></el-option>
<el-option label="不可靠" value="不可靠"></el-option>
</el-select>
</el-form-item>
</div>
<!-- 2. 病史信息 -->
<h4 class="section-title">病史信息</h4>
<div class="form-section">
<el-form-item label="主诉" prop="complaint" class="history-item required">
<el-input
v-model="formData.complaint"
type="textarea"
placeholder="请输入主诉"
autosize
maxlength="200"
show-word-limit
/>
</el-form-item>
<el-form-item label="现病史" prop="presentIllness" class="history-item">
<el-input
v-model="formData.presentIllness"
type="textarea"
placeholder="请详细描述现病史"
autosize
maxlength="1000"
show-word-limit
/>
</el-form-item>
<el-form-item label="既往史" prop="pastHistory" class="history-item">
<el-input
v-model="formData.pastHistory"
type="textarea"
placeholder="请输入既往史"
autosize
maxlength="800"
show-word-limit
/>
</el-form-item>
<el-form-item label="个人史" prop="personalHistory" class="history-item">
<el-input
v-model="formData.personalHistory"
type="textarea"
placeholder="请输入个人史"
autosize
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-form-item label="婚育史" prop="maritalHistory" class="history-item">
<el-input
v-model="formData.maritalHistory"
type="textarea"
placeholder="请输入婚育史"
autosize
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-form-item label="月经史" prop="menstrualHistory" class="history-item">
<el-input
v-model="formData.menstrualHistory"
type="textarea"
placeholder="请输入月经史"
autosize
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-form-item label="家族史" prop="familyHistory" class="history-item">
<el-input
v-model="formData.familyHistory"
type="textarea"
placeholder="请输入家族史"
autosize
maxlength="500"
show-word-limit
/>
</el-form-item>
</div>
<!-- 3. 中医望闻问切 -->
<h4 class="section-title">中医望闻问切</h4>
<div class="form-section">
<el-form-item label="望闻问切" prop="tcmInfo" class="history-item">
<el-input
v-model="formData.tcmInfo"
type="textarea"
placeholder="请输入中医望闻问切结果"
autosize
maxlength="600"
show-word-limit
/>
</el-form-item>
</div>
<!-- 4. 体格检查 -->
<h4 class="section-title">体格检查</h4>
<div class="form-section">
<div class="adaptive-grid">
<el-form-item label="体温" prop="temp" class="grid-item">
<div class="input-with-unit">
<el-input
v-model.number="formData.temp"
type="number"
step="0.1"
placeholder="如36.0"
clearable
/>
<span class="unit"></span>
</div>
</el-form-item>
<el-form-item label="脉搏" prop="pulse" class="grid-item">
<div class="input-with-unit">
<el-input
v-model.number="formData.pulse"
type="number"
placeholder="如76"
clearable
/>
<span class="unit">/</span>
</div>
</el-form-item>
<el-form-item label="呼吸" prop="respiration" class="grid-item">
<div class="input-with-unit">
<el-input
v-model.number="formData.respiration"
type="number"
placeholder="如16"
clearable
/>
<span class="unit">/</span>
</div>
</el-form-item>
<el-form-item label="血压" prop="bp" class="grid-item">
<div class="input-with-unit">
<el-input
v-model="formData.bp"
placeholder="如188/94"
clearable
@blur="validateBloodPressure"
/>
<span class="unit">mmHg</span>
</div>
</el-form-item>
<el-form-item label="身高" prop="height" class="grid-item">
<div class="input-with-unit">
<el-input
v-model.number="formData.height"
type="number"
placeholder="如165"
clearable
/>
<span class="unit">cm</span>
</div>
</el-form-item>
<el-form-item label="体重" prop="weight" class="grid-item">
<div class="input-with-unit">
<el-input
v-model.number="formData.weight"
type="number"
placeholder="如79"
clearable
/>
<span class="unit">kg</span>
</div>
</el-form-item>
<el-form-item label="BMI" prop="bmi" class="grid-item">
<div class="input-with-unit">
<el-input
v-model="formData.bmi"
placeholder="如29.02"
readonly
/>
<span class="unit">kg/</span>
</div>
</el-form-item>
</div>
<el-form-item label="一般情况" prop="general" class="history-item">
<el-input
v-model="formData.general"
type="textarea"
placeholder="请输入一般情况"
autosize
maxlength="300"
show-word-limit
/>
</el-form-item>
<el-form-item label="皮肤粘膜" prop="skin" class="history-item">
<el-input
v-model="formData.skin"
type="textarea"
placeholder="请输入皮肤粘膜情况"
autosize
maxlength="300"
show-word-limit
/>
</el-form-item>
<el-form-item label="胸部(心、肺)" prop="chest" class="history-item">
<el-input
v-model="formData.chest"
type="textarea"
placeholder="请输入胸部检查结果"
autosize
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-form-item label="腹部" prop="abdomen" class="history-item">
<el-input
v-model="formData.abdomen"
type="textarea"
placeholder="请输入腹部检查结果"
autosize
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-form-item label="四肢/神经系统" prop="limbsNervous" class="history-item">
<el-input
v-model="formData.limbsNervous"
type="textarea"
placeholder="请输入四肢及神经系统检查结果"
autosize
maxlength="500"
show-word-limit
/>
</el-form-item>
</div>
<!-- 5. 辅助检查 -->
<h4 class="section-title">辅助检查</h4>
<div class="form-section">
<el-form-item label="检查结果" prop="auxExam" class="history-item">
<el-input
v-model="formData.auxExam"
type="textarea"
placeholder="请输入辅助检查结果"
autosize
maxlength="1000"
show-word-limit
/>
</el-form-item>
</div>
<!-- 6. 初步诊断 -->
<h4 class="section-title">初步诊断</h4>
<div class="form-section">
<el-form-item label="中医诊断" prop="tcmDiagnosis" class="history-item">
<el-input
v-model="formData.tcmDiagnosis"
type="textarea"
placeholder="如:胸痹心痛(气阴两虚证)"
autosize
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-form-item label="西医诊断" prop="westernDiagnosis" class="history-item">
<el-input
v-model="formData.westernDiagnosis"
type="textarea"
placeholder="如1.冠状动脉粥样硬化性心脏病"
autosize
maxlength="800"
show-word-limit
/>
</el-form-item>
</div>
<!-- 7. 签名信息三列布局 -->
<h4 class="section-title">签名信息</h4>
<div class="adaptive-grid form-section" style="grid-template-columns: repeat(3, 1fr);">
<el-form-item label="医师签名" prop="doctorSign" class="grid-item">
<el-input
v-model="formData.doctorSign"
placeholder="请签名"
clearable
/>
</el-form-item>
<el-form-item label="上级医师签名" prop="superiorSign" class="grid-item">
<el-input
v-model="formData.superiorSign"
placeholder="请签名"
clearable
/>
</el-form-item>
<el-form-item label="记录日期" prop="signDate" class="grid-item">
<el-date-picker
v-model="formData.signDate"
type="datetime"
placeholder="选择日期"
value-format="YYYY-MM-DD HH:mm"
style="width: 100%;"
/>
</el-form-item>
</div>
<!-- 新增表单操作按钮组重置按钮 -->
<div class="form-btn-group">
<el-button type="warning" @click="handleReset">重置表单</el-button>
</div>
</el-form>
</div>
</div>
</template>
<script setup>
import { ref, reactive, watch, onMounted } from 'vue';
import { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElMessage, ElMessageBox, ElForm, ElFormItem } from 'element-plus';
import useUserStore from '../store/modules/user';
defineOptions({
name: 'InHospitalRecord',
components: { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElForm, ElFormItem }
});
// Props与事件
const props = defineProps({
patientInfo: {
type: Object,
required: true,
},
});
const emits = defineEmits(['submitOk']);
// 数据初始化
const userStore = useUserStore();
const patient = props.patientInfo;
const formRef = ref(null);
// 表单数据
const formData = reactive({
// 基础信息
patientName: patient?.name || '',
hospitalNo: patient?.busNo || '',
gender: patient?.genderEnum_enumText || '',
age: patient?.age || '',
nation: '',
occupation: '',// 职业
marriage: '',// 婚姻状况
birthplace: '',// 出生地
admissionTime: '',// 入院时间
recordTime: '',// 记录时间
historyReporter: '',// 病史陈述者
reliability: '可靠',// 可靠程度
// 病史信息
complaint: '',// 主诉
presentIllness: '',// 现病史
pastIllness: '',// 既往史
personalHistory: '',// 个人史
allergyHistory: '',// 过敏史
pastHistory: '',// 既往史
familyHistory: '',// 家族史
maritalHistory: '',// 婚姻史
menstrualHistory: '',// 月经史
// 中医信息
tcmInfo: '',
// 体格检查
temp: '',
pulse: '',
respiration: '',
bp: '',
height: '',
weight: '',
bmi: '',
general: '',
skin: '',
chest: '',
abdomen: '',
limbsNervous: '',
// 辅助检查
auxExam: '',
// 诊断信息
tcmDiagnosis: '',
westernDiagnosis: '',
// 签名信息
doctorSign: '',
superiorSign: '',
signDate: ''
});
// 表单校验规则
const rules = reactive({
name: [
{ required: true, message: '请填写姓名', trigger: ['blur', 'submit'] }
],
hospitalNo: [
{ required: true, message: '请填写住院号', trigger: ['blur', 'submit'] }
],
gender: [
{ required: true, message: '请选择性别', trigger: ['change', 'submit'] }
],
age: [
{ required: true, message: '请填写年龄', trigger: ['blur', 'submit'] },
{ type: 'number', min: 1, max: 120, message: '年龄需在1-120岁之间', trigger: ['blur', 'submit'] }
],
admissionTime: [
{ required: true, message: '请选择入院时间', trigger: ['change', 'submit'] }
],
recordTime: [
{ required: true, message: '请选择记录时间', trigger: ['change', 'submit'] }
],
chiefComplaint: [
{ required: true, message: '请填写主诉', trigger: ['blur', 'submit'] }
]
});
// 生命周期
onMounted(() => {
// 初始化记录时间为当前时间
if (!formData.recordTime) {
formData.recordTime = formatDateTime(new Date());
}
if (!formData.admissionTime) {
formData.admissionTime = formatDateTime(new Date());
}
if (!formData.signDate) {
formData.signDate = formatDateTime(new Date());
}
if (!formData.patientName) {
formData.patientName = patient?.patientName || '';
}
if (!formData.gender) {
formData.gender = patient?.genderEnum_enumText || '';
}
if (!formData.age) {
formData.age = patient?.age || '';
}
if (!formData.hospitalNo) {
formData.hospitalNo = patient?.busNo || '';
}
});
// BMI自动计算
watch([() => formData.height, () => formData.weight], ([newHeight, newWeight]) => {
if (newHeight && newWeight && newHeight > 0 && newWeight > 0) {
const heightM = newHeight / 100;
formData.bmi = (newWeight / (heightM * heightM)).toFixed(2);
} else {
formData.bmi = '';
}
});
// 入院时间变化处理
watch(() => formData.admissionTime, (val) => {
if (val && !formData.recordTime) {
ElMessageBox.confirm(
'是否将记录时间同步为入院时间?',
'时间同步提示',
{
confirmButtonText: '同步',
cancelButtonText: '手动设置',
type: 'info'
}
).then(() => {
formData.recordTime = val;
}).catch(() => {});
}
});
// 血压格式校验
const validateBloodPressure = () => {
const bp = formData.bp;
if (!bp) return;
const reg = /^\d{2,3}\/\d{2,3}$/;
if (!reg.test(bp)) {
ElMessage.warning('血压格式不正确,请输入如 "120/80" 的格式');
formData.bp = '';
}
};
// 提交表单
const submit = () => {
formRef.value.validate((isValid) => {
if (isValid) {
// 额外校验血压格式
if (formData.bp) {
validateBloodPressure();
if (!formData.bp) return; // 格式错误时终止提交
}
emits('submitOk', formData);
ElMessage.success('记录保存成功!');
}
});
};
// 新增:重置表单方法(带确认提示)
const handleReset = () => {
ElMessageBox.confirm(
'确定要重置表单吗?所有已填写内容将被清空,且不可恢复',
'重置确认',
{
confirmButtonText: '确认重置',
cancelButtonText: '取消',
type: 'warning',
center: true
}
).then(() => {
// 执行表单重置
formRef.value.resetFields();
// 保留患者基础信息和默认值(避免清空关键基础数据)
formData.patientName = patient?.name || '';
formData.hospitalNo = patient?.busNo || '';
formData.gender = patient?.genderEnum_enumText || '';
formData.age = patient?.age || '';
formData.reliability = '可靠';
// 重置时间为当前时间
const today = new Date();
formData.admissionTime = formatDateTime(today);
formData.recordTime = formatDateTime(today);
formData.signDate = formatDateTime(today);
// 重置成功提示
ElMessage.success('表单已成功重置');
}).catch(() => {
// 取消重置提示
ElMessage.info('已取消表单重置');
});
};
// 表单数据赋值
const setFormData = (data) => {
if (data) {
Object.assign(formData, data);
}
};
// 日期格式化工具
const formatDateTime = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day} ${hour}:${minute}`;
};
// 暴露接口
defineExpose({ formData, submit, setFormData, handleReset });
</script>
<style scoped>
/* 表单外层容器 */
.medical-form {
max-width: 1200px;
width: 100%;
height: 700px;
margin: 15px auto;
padding: 15px;
border: 1px solid #ddd;
border-radius: 8px;
font-family: Arial, sans-serif;
box-sizing: border-box;
overflow: hidden;
}
/* 滚动内容容器 */
.form-scroll-container {
height: calc(100% - 80px);
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: thin;
scrollbar-color: #ccc #f5f5f5;
}
.form-scroll-container::-webkit-scrollbar {
width: 6px;
}
.form-scroll-container::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 3px;
}
.form-scroll-container::-webkit-scrollbar-track {
background-color: #f5f5f5;
}
/* 完整表单容器 */
.medical-full-form {
width: 100%;
}
/* 区域通用样式 */
.form-section {
margin-bottom: 25px;
padding: 10px;
background-color: #fafafa;
border-radius: 6px;
}
.section-title {
margin: 0 0 15px;
padding-bottom: 8px;
border-bottom: 1px solid #e0e0e0;
color: #333;
font-size: 16px;
font-weight: bold;
}
/* 自适应网格布局(核心调整) */
.adaptive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 15px;
}
.grid-item {
margin-bottom: 0;
display: flex;
flex-direction: column;
}
.grid-item .el-form-item__content {
flex: 1;
min-width: 0; /* 关键:允许内容收缩以适应容器 */
}
/* 病史项目样式 */
.history-item {
margin-bottom: 15px;
display: flex;
flex-direction: column;
width: 100%;
}
.history-item .el-form-item__content {
width: 100%;
}
.history-item .el-input__inner {
width: 100%;
min-height: 40px;
resize: vertical;
}
/* 带单位的输入框样式 */
.input-with-unit {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
}
.input-with-unit .el-input {
flex: 1;
min-width: 0; /* 允许输入框收缩 */
}
.unit {
font-weight: 500;
color: #333;
white-space: nowrap;
font-size: 14px;
}
/* 新增:表单按钮组样式 */
.form-btn-group {
margin-top: 30px;
margin-bottom: 15px;
text-align: center; /* 按钮居中对齐 */
}
.form-btn-group .el-button {
padding: 8px 20px;
}
/* 必填项红色星号 */
.required .el-form-item__label::before {
content: '* ';
color: #ff4d4f;
}
/* 按钮组 */
.btn-group {
text-align: center;
margin-top: 15px;
}
/* 响应式调整 */
@media (max-width: 768px) {
.medical-form {
height: 80vh;
padding: 10px;
}
.form-scroll-container {
height: calc(100% - 70px);
}
.el-form {
label-width: 60px !important;
}
.adaptive-grid {
grid-template-columns: 1fr; /* 小屏幕下单列显示 */
}
.grid-item, .history-item {
margin-bottom: 10px;
}
/* 小屏幕按钮居中 */
.form-btn-group {
text-align: center;
}
}
/* 中等屏幕调整 */
@media (min-width: 769px) and (max-width: 1024px) {
.adaptive-grid {
grid-template-columns: repeat(2, 1fr); /* 中等屏幕下两列显示 */
}
}
</style>

View File

@@ -0,0 +1,555 @@
<template>
<div class="medical-document">
<!-- 标题区域 -->
<div class="doc-header">
<h1 class="doc-title">{{ hospitalName }} 住院手术记录单</h1>
<div class="doc-subtitle">住院号: {{ formData.busNo || '待填写' }}</div>
</div>
<!-- 内容区域 -->
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="120px"
label-align="left"
class="doc-content"
style="height: 60vh; overflow: scroll;"
>
<!-- 患者与手术基础信息 -->
<section class="doc-section">
<h2 class="section-title">患者与手术基本信息</h2>
<div class="adaptive-grid">
<el-form-item label="患者姓名" prop="patientName" class="grid-item required">
<el-input v-model="formData.patientName" placeholder="请输入患者姓名" clearable />
</el-form-item>
<el-form-item label="性别" prop="gender" class="grid-item required">
<el-select v-model="formData.gender" placeholder="请选择性别">
<el-option label="男" value="男" />
<el-option label="女" value="女" />
</el-select>
</el-form-item>
<el-form-item label="年龄" prop="age" class="grid-item required">
<div class="input-with-unit">
<el-input v-model.number="formData.age" type="number" placeholder="请输入年龄" />
<span class="unit"></span>
</div>
</el-form-item>
<el-form-item label="科室" prop="department" class="grid-item required">
<el-input v-model="formData.department" placeholder="如:普外科" clearable />
</el-form-item>
<el-form-item label="病房/床号" prop="bedNo" class="grid-item required">
<el-input v-model="formData.bedNo" placeholder="如502-03" clearable />
</el-form-item>
<el-form-item label="手术日期/时间" prop="operationDateTime" class="grid-item required">
<el-date-picker
v-model="formData.operationDateTime"
type="datetime"
placeholder="选择手术日期时间"
value-format="YYYY-MM-DD HH:mm"
/>
</el-form-item>
</div>
</section>
<!-- 手术团队信息 -->
<section class="doc-section">
<h2 class="section-title">手术团队信息</h2>
<div class="adaptive-grid">
<el-form-item label="手术者" prop="surgeon" class="grid-item required">
<el-input v-model="formData.surgeon" placeholder="主刀医师姓名" clearable />
</el-form-item>
<el-form-item label="第一助手" prop="firstAssistant" class="grid-item required">
<el-input v-model="formData.firstAssistant" placeholder="第一助手姓名" clearable />
</el-form-item>
<el-form-item label="第二助手" prop="secondAssistant" class="grid-item">
<el-input v-model="formData.secondAssistant" placeholder="第二助手姓名" clearable />
</el-form-item>
<el-form-item label="麻醉医师" prop="anesthesiologist" class="grid-item required">
<el-input v-model="formData.anesthesiologist" placeholder="麻醉医师姓名" clearable />
</el-form-item>
<el-form-item label="巡回护士" prop="circulatingNurse" class="grid-item required">
<el-input v-model="formData.circulatingNurse" placeholder="巡回护士姓名" clearable />
</el-form-item>
<el-form-item label="器械护士" prop="scrubNurse" class="grid-item required">
<el-input v-model="formData.scrubNurse" placeholder="器械护士姓名" clearable />
</el-form-item>
</div>
</section>
<!-- 手术详情 -->
<section class="doc-section">
<h2 class="section-title">手术详情</h2>
<el-form-item label="手术名称" prop="operationName" class="full-width-item required">
<el-input v-model="formData.operationName" placeholder="规范手术名称(如:腹腔镜下胆囊切除术)" clearable />
</el-form-item>
<el-form-item label="手术方式" prop="operationMethod" class="full-width-item required">
<el-select v-model="formData.operationMethod" placeholder="选择手术方式">
<el-option label="开放手术" value="开放手术" />
<el-option label="微创手术" value="微创手术" />
<el-option label="介入手术" value="介入手术" />
</el-select>
</el-form-item>
<el-form-item label="手术入路" prop="surgicalApproach" class="full-width-item required">
<el-input v-model="formData.surgicalApproach" placeholder="如:右上腹经腹直肌切口" clearable />
</el-form-item>
<el-form-item label="术中发现" prop="intraoperativeFindings" class="full-width-item required">
<el-input
v-model="formData.intraoperativeFindings"
type="textarea"
placeholder="详细描述术中所见器官、病变情况"
autosize
maxlength="1000"
show-word-limit
/>
</el-form-item>
<el-form-item label="手术过程" prop="operationProcess" class="full-width-item required">
<el-input
v-model="formData.operationProcess"
type="textarea"
placeholder="按操作顺序描述手术步骤(如:游离胆囊三角→结扎胆囊管→切除胆囊..."
autosize
maxlength="1500"
show-word-limit
/>
</el-form-item>
</section>
<!-- 术后情况 -->
<section class="doc-section">
<h2 class="section-title">术后情况</h2>
<div class="adaptive-grid">
<el-form-item label="术中出血量" prop="bloodLoss" class="grid-item required">
<div class="input-with-unit">
<el-input v-model.number="formData.bloodLoss" type="number" placeholder="请输入出血量" />
<span class="unit">ml</span>
</div>
</el-form-item>
<el-form-item label="输血情况" prop="bloodTransfusion" class="grid-item">
<el-select v-model="formData.bloodTransfusion" placeholder="是否输血">
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
</el-form-item>
<el-form-item label="引流管放置" prop="drainageTube" class="grid-item">
<el-input v-model="formData.drainageTube" placeholder="如腹腔引流管1根" clearable />
</el-form-item>
<el-form-item label="标本处理" prop="specimenDisposal" class="grid-item required">
<el-input v-model="formData.specimenDisposal" placeholder="如:胆囊标本送病理检查" clearable />
</el-form-item>
<el-form-item label="手术结束时间" prop="operationEndTime" class="grid-item required">
<el-date-picker
v-model="formData.operationEndTime"
type="datetime"
placeholder="选择手术结束时间"
value-format="YYYY-MM-DD HH:mm"
/>
</el-form-item>
<el-form-item label="患者去向" prop="patientDestination" class="grid-item required">
<el-select v-model="formData.patientDestination" placeholder="选择去向">
<el-option label="ICU" value="ICU" />
<el-option label="普通病房" value="普通病房" />
</el-select>
</el-form-item>
</div>
</section>
<!-- 签署区域 -->
<section class="doc-section">
<h2 class="section-title">签署确认</h2>
<div class="adaptive-grid signature-area" style="grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));">
<el-form-item label="手术者签名" prop="surgeonSignature" class="grid-item required">
<el-input v-model="formData.surgeonSignature" placeholder="主刀医师签字" clearable />
<div class="signature-tip">请手术者亲笔签名</div>
</el-form-item>
<el-form-item label="记录者签名" prop="recorderSignature" class="grid-item required">
<el-input v-model="formData.recorderSignature" placeholder="记录者签字" clearable />
<div class="signature-tip">请记录者如第一助手签字</div>
</el-form-item>
<el-form-item label="记录日期" prop="recordDate" class="grid-item required">
<el-date-picker
v-model="formData.recordDate"
type="date"
placeholder="选择记录日期"
value-format="YYYY-MM-DD"
style="width: 100%;"
/>
</el-form-item>
</div>
</section>
</el-form>
<!-- 操作按钮 -->
<div class="btn-group">
<el-button type="primary" @click="submit">保存记录</el-button>
<el-button type="success" @click="handlePrint">打印记录</el-button>
<el-button type="warning" @click="handleReset">重置表单</el-button>
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { ElMessage, ElMessageBox, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElDatePicker, ElButton } from 'element-plus';
// 医院名称
const hospitalName = '长春市朝阳区中医院';
defineOptions({
name: 'iInHospitalSurgicalRecord'
});
// 表单引用
const formRef = ref(null);
// 表单数据
const formData = reactive({
// 患者与手术基础信息
busNo: '',
patientName: '',
gender: '',
age: '',
department: '',
bedNo: '',
operationDateTime: '',// 手术日期时间
// 手术团队信息
surgeon: '',// 主刀医师
firstAssistant: '',// 第一助手
secondAssistant: '',// 第二助手
anesthesiologist: '',// 麻醉医师
circulatingNurse: '',// 巡回护士
scrubNurse: '',// 器械护士
// 手术详情
operationName: '',// 规范手术名称
operationMethod: '',// 手术方式
surgicalApproach: '',// 手术入路
intraoperativeFindings: '',// 术中发现
operationProcess: '',// 手术过程
// 术后情况
bloodLoss: '',// 术中出血量
bloodTransfusion: '',// 输血情况
drainageTube: '',// 引流管放置
specimenDisposal: '',// 标本处理
operationEndTime: '',// 手术结束时间
patientDestination: '',// 患者去向
// 签署信息
surgeonSignature: '',// 手术者签名
recorderSignature: '',// 记录者签名
recordDate: ''// 记录日期
});
// 表单验证规则
const rules = reactive({
busNo: [
{ required: true, message: '请填写住院号', trigger: ['blur', 'submit'] }
],
patientName: [
{ required: true, message: '请填写患者姓名', trigger: ['blur', 'submit'] }
],
gender: [
{ required: true, message: '请选择性别', trigger: ['change', 'submit'] }
],
age: [
{ required: true, message: '请填写年龄', trigger: ['blur', 'submit'] },
{ type: 'number', min: 0, max: 150, message: '年龄需在0-150之间', trigger: ['blur', 'submit'] }
],
department: [
{ required: true, message: '请填写科室', trigger: ['blur', 'submit'] }
],
bedNo: [
{ required: true, message: '请填写病房/床号', trigger: ['blur', 'submit'] }
],
operationDateTime: [
{ required: true, message: '请选择手术日期时间', trigger: ['change', 'submit'] }
],
surgeon: [
{ required: true, message: '请填写手术者姓名', trigger: ['blur', 'submit'] }
],
firstAssistant: [
{ required: true, message: '请填写第一助手姓名', trigger: ['blur', 'submit'] }
],
anesthesiologist: [
{ required: true, message: '请填写麻醉医师姓名', trigger: ['blur', 'submit'] }
],
circulatingNurse: [
{ required: true, message: '请填写巡回护士姓名', trigger: ['blur', 'submit'] }
],
scrubNurse: [
{ required: true, message: '请填写器械护士姓名', trigger: ['blur', 'submit'] }
],
operationName: [
{ required: true, message: '请填写手术名称', trigger: ['blur', 'submit'] }
],
operationMethod: [
{ required: true, message: '请选择手术方式', trigger: ['change', 'submit'] }
],
surgicalApproach: [
{ required: true, message: '请填写手术入路', trigger: ['blur', 'submit'] }
],
intraoperativeFindings: [
{ required: true, message: '请描述术中发现', trigger: ['blur', 'submit'] }
],
operationProcess: [
{ required: true, message: '请描述手术过程', trigger: ['blur', 'submit'] }
],
bloodLoss: [
{ required: true, message: '请填写术中出血量', trigger: ['blur', 'submit'] },
{ type: 'number', min: 0, message: '出血量不能为负数', trigger: ['blur', 'submit'] }
],
specimenDisposal: [
{ required: true, message: '请填写标本处理方式', trigger: ['blur', 'submit'] }
],
operationEndTime: [
{ required: true, message: '请选择手术结束时间', trigger: ['change', 'submit'] }
],
patientDestination: [
{ required: true, message: '请选择患者去向', trigger: ['change', 'submit'] }
],
surgeonSignature: [
{ required: true, message: '请手术者签名', trigger: ['blur', 'submit'] }
],
recorderSignature: [
{ required: true, message: '请记录者签名', trigger: ['blur', 'submit'] }
],
recordDate: [
{ required: true, message: '请选择记录日期', trigger: ['change', 'submit'] }
]
});
// 生命周期
onMounted(() => {
// 初始化日期为当前日期时间
const today = new Date();
formData.operationDateTime = formatDateTime(today);
formData.operationEndTime = formatDateTime(today);
formData.recordDate = formatDate(today);
});
// 提交表单
const submit = () => {
formRef.value.validate((valid) => {
if (valid) {
ElMessage.success('手术记录保存成功');
console.log('手术记录数据:', formData);
}
});
};
// 打印功能
const handlePrint = () => {
formRef.value.validate((valid) => {
if (valid) {
window.print();
} else {
ElMessageBox.warning('请先完善表单信息再打印');
}
});
};
// 重置表单
const handleReset = () => {
ElMessageBox.confirm(
'确定要重置表单吗?所有已填写内容将被清空',
'确认重置',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
formRef.value.resetFields();
const today = new Date();
formData.operationDateTime = formatDateTime(today);
formData.operationEndTime = formatDateTime(today);
formData.recordDate = formatDate(today);
ElMessage.success('表单已重置');
});
};
// 日期格式化工具
const formatDate = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
const formatDateTime = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day} ${hour}:${minute}`;
};
</script>
<style scoped>
/* 样式与原代码保持一致,无需修改 */
.medical-document {
max-width: 1200px;
margin: 20px auto;
padding: 30px;
background: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
font-family: 'SimSun', '宋体', serif;
}
.doc-header {
text-align: center;
margin-bottom: 30px;
}
.doc-title {
font-size: 22px;
margin: 0 0 10px;
font-weight: bold;
}
.doc-subtitle {
font-size: 16px;
color: #666;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #333;
}
.doc-content {
width: 100%;
}
.doc-section {
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 1px dashed #ccc;
}
.section-title {
font-size: 18px;
margin: 0 0 15px;
color: #333;
font-weight: bold;
}
.adaptive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px 20px;
margin-bottom: 15px;
}
.grid-item {
margin-bottom: 0;
display: flex;
flex-direction: column;
}
.grid-item .el-form-item__content {
flex: 1;
min-width: 0;
}
.full-width-item {
width: 100%;
margin-bottom: 15px;
}
.input-with-unit {
display: flex;
align-items: center;
gap: 8px;
}
.unit {
white-space: nowrap;
color: #666;
}
.signature-area {
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.signature-tip {
font-size: 12px;
color: #f56c6c;
margin-top: 4px;
}
.btn-group {
display: flex;
justify-content: center;
gap: 15px;
margin-top: 30px;
padding-top: 20px;
border-top: 2px solid #333;
}
.required .el-form-item__label::before {
content: '*';
color: #ff4d4f;
margin-right: 4px;
}
@media (max-width: 768px) {
.medical-document {
padding: 15px;
}
.adaptive-grid {
grid-template-columns: 1fr;
}
.doc-title {
font-size: 18px;
}
.section-title {
font-size: 16px;
}
}
@media print {
.btn-group {
display: none;
}
.medical-document {
box-shadow: none;
margin: 0;
padding: 0;
}
.el-input__inner, .el-select__input, .el-textarea__inner {
border: none !important;
box-shadow: none !important;
background: transparent !important;
}
.el-form-item__label {
font-weight: bold !important;
}
}
</style>

View File

@@ -0,0 +1,553 @@
<template>
<div class="medical-document">
<!-- 标题区域 -->
<div class="doc-header">
<h1 class="doc-title">{{ hospitalName }} 住院患者入院沟通记录单</h1>
<div class="doc-subtitle">住院号: {{ formData.hospitalNo || '待填写' }}</div>
</div>
<!-- 内容区域 -->
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="100px"
label-align="left"
class="doc-content"
>
<!-- 患者基础信息 -->
<section class="doc-section">
<h2 class="section-title">患者基础信息</h2>
<div class="adaptive-grid">
<el-form-item label="姓名" prop="patientName" class="grid-item required">
<el-input v-model="formData.patientName" placeholder="请输入患者姓名" clearable />
</el-form-item>
<el-form-item label="性别" prop="gender" class="grid-item required">
<el-select v-model="formData.gender" placeholder="请选择性别">
<el-option label="男" value="男" />
<el-option label="女" value="女" />
</el-select>
</el-form-item>
<el-form-item label="年龄" prop="age" class="grid-item required">
<div class="input-with-unit">
<el-input v-model.number="formData.age" type="number" placeholder="请输入年龄" />
<span class="unit"></span>
</div>
</el-form-item>
<el-form-item label="科室/病区" prop="department" class="grid-item required">
<el-input v-model="formData.department" placeholder="如:内科疗区" clearable />
</el-form-item>
<el-form-item label="病房/床号" prop="bedNo" class="grid-item required">
<el-input v-model="formData.bedNo" placeholder="如307-12" clearable />
</el-form-item>
<el-form-item label="入院日期" prop="admissionDate" class="grid-item required">
<el-date-picker
v-model="formData.admissionDate"
type="date"
placeholder="选择入院日期"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</div>
</section>
<!-- 医疗团队信息 -->
<section class="doc-section">
<h2 class="section-title">医疗团队信息</h2>
<div class="adaptive-grid">
<el-form-item label="经治医师" prop="treatingDoctor" class="grid-item required">
<el-input v-model="formData.treatingDoctor" placeholder="请输入医师姓名" clearable />
</el-form-item>
<el-form-item label="主治医师" prop="attendingDoctor" class="grid-item required">
<el-input v-model="formData.attendingDoctor" placeholder="请输入医师姓名" clearable />
</el-form-item>
<el-form-item label="科主任" prop="departmentHead" class="grid-item required">
<el-input v-model="formData.departmentHead" placeholder="请输入主任姓名" clearable />
</el-form-item>
</div>
</section>
<!-- 病情与诊断 -->
<section class="doc-section">
<h2 class="section-title">病情与诊断</h2>
<el-form-item label="病情状况" prop="condition" class="full-width-item required">
<el-input
v-model="formData.condition"
type="textarea"
placeholder="详细描述患者病情状况"
autosize
maxlength="1000"
show-word-limit
/>
</el-form-item>
<div class="diagnosis-container">
<el-form-item label="中医诊断" prop="tcmDiagnosis" class="diagnosis-item">
<el-input
v-model="formData.tcmDiagnosis"
type="textarea"
placeholder="如:胸痹心痛(气阴两虚证)"
autosize
maxlength="500"
show-word-limit
/>
</el-form-item>
<el-form-item label="西医诊断" prop="westernDiagnosis" class="diagnosis-item">
<el-input
v-model="formData.westernDiagnosis"
type="textarea"
placeholder="如1.冠状动脉粥样硬化性心脏病..."
autosize
maxlength="800"
show-word-limit
/>
</el-form-item>
</div>
</section>
<!-- 治疗与检查计划 -->
<section class="doc-section">
<h2 class="section-title">治疗与检查计划</h2>
<el-form-item label="治疗方案" prop="treatmentPlan" class="full-width-item required">
<el-input
v-model="formData.treatmentPlan"
type="textarea"
placeholder="详细描述治疗方案"
autosize
maxlength="1000"
show-word-limit
/>
</el-form-item>
<el-form-item label="进一步检查项目" prop="examinationItems" class="full-width-item required">
<el-input
v-model="formData.examinationItems"
type="textarea"
placeholder="列出需要进行的检查项目"
autosize
maxlength="1000"
show-word-limit
/>
</el-form-item>
</section>
<!-- 风险告知 -->
<section class="doc-section">
<h2 class="section-title">风险告知</h2>
<el-form-item label="告知内容" prop="riskNotification" class="full-width-item required">
<el-input
v-model="formData.riskNotification"
type="textarea"
placeholder="告知患者可能存在的风险"
autosize
maxlength="800"
show-word-limit
/>
</el-form-item>
</section>
<!-- 签署区域优化后三列自适应+细节样式 -->
<section class="doc-section">
<h2 class="section-title">签署确认</h2>
<div class="adaptive-grid signature-area" style="grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));">
<el-form-item label="患者或家属签字" prop="patientSignature" class="grid-item required">
<el-input v-model="formData.patientSignature" placeholder="请签字" clearable />
<div class="signature-tip">请填写患者或家属签字</div>
</el-form-item>
<el-form-item label="与患者关系" prop="relationship" class="grid-item">
<el-input v-model="formData.relationship" placeholder="如:本人、配偶、子女" clearable />
</el-form-item>
<el-form-item label="签字日期" prop="signatureDate" class="grid-item required">
<el-date-picker
v-model="formData.signatureDate"
type="date"
placeholder="选择签字日期"
value-format="YYYY-MM-DD"
style="width: 100%;"
/>
</el-form-item>
<el-form-item label="沟通医师签字" prop="doctorSignature" class="grid-item required">
<el-input v-model="formData.doctorSignature" placeholder="请签字" clearable />
<div class="signature-tip">请填写沟通医师签字</div>
</el-form-item>
<el-form-item label="沟通日期" prop="communicationDate" class="grid-item required">
<el-date-picker
v-model="formData.communicationDate"
type="datetime"
placeholder="选择沟通日期时间"
value-format="YYYY-MM-DD HH:mm"
style="width: 100%;"
/>
</el-form-item>
</div>
</section>
</el-form>
<!-- 操作按钮 -->
<div class="btn-group">
<el-button type="primary" @click="submit">保存记录</el-button>
<el-button type="success" @click="handlePrint">打印记录</el-button>
<el-button type="warning" @click="handleReset">重置表单</el-button>
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { ElMessage, ElMessageBox, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElDatePicker, ElButton } from 'element-plus';
// 医院名称
const hospitalName = '长春市朝阳区中医院';
defineOptions({
name: 'InHospitalCommunicate'
});
// 表单引用
const formRef = ref(null);
// 表单数据
const formData = reactive({
// 基础信息
hospitalNo: '',
patientName: '',
gender: '',
age: '',
department: '',
bedNo: '',
admissionDate: '',
// 医疗团队
treatingDoctor: '',
attendingDoctor: '',
departmentHead: '',
// 病情诊断
condition: '',
tcmDiagnosis: '',
westernDiagnosis: '',
// 治疗检查
treatmentPlan: '',
examinationItems: '',
// 风险告知
riskNotification: '',
// 签署信息
patientSignature: '',
relationship: '',
signatureDate: '',
doctorSignature: '',
communicationDate: ''
});
// 表单验证规则
const rules = reactive({
hospitalNo: [
{ required: true, message: '请填写住院号', trigger: ['blur', 'submit'] }
],
patientName: [
{ required: true, message: '请填写患者姓名', trigger: ['blur', 'submit'] }
],
gender: [
{ required: true, message: '请选择性别', trigger: ['change', 'submit'] }
],
age: [
{ required: true, message: '请填写年龄', trigger: ['blur', 'submit'] },
{ type: 'number', min: 0, max: 150, message: '年龄需在0-150之间', trigger: ['blur', 'submit'] }
],
department: [
{ required: true, message: '请填写科室/病区', trigger: ['blur', 'submit'] }
],
bedNo: [
{ required: true, message: '请填写病房/床号', trigger: ['blur', 'submit'] }
],
admissionDate: [
{ required: true, message: '请选择入院日期', trigger: ['change', 'submit'] }
],
treatingDoctor: [
{ required: true, message: '请填写经治医师', trigger: ['blur', 'submit'] }
],
attendingDoctor: [
{ required: true, message: '请填写主治医师', trigger: ['blur', 'submit'] }
],
departmentHead: [
{ required: true, message: '请填写科主任', trigger: ['blur', 'submit'] }
],
condition: [
{ required: true, message: '请描述病情状况', trigger: ['blur', 'submit'] }
],
treatmentPlan: [
{ required: true, message: '请填写治疗方案', trigger: ['blur', 'submit'] }
],
examinationItems: [
{ required: true, message: '请填写检查项目', trigger: ['blur', 'submit'] }
],
riskNotification: [
{ required: true, message: '请填写风险告知内容', trigger: ['blur', 'submit'] }
],
patientSignature: [
{ required: true, message: '请填写患者或家属签字', trigger: ['blur', 'submit'] }
],
signatureDate: [
{ required: true, message: '请选择签字日期', trigger: ['change', 'submit'] }
],
doctorSignature: [
{ required: true, message: '请填写医师签字', trigger: ['blur', 'submit'] }
],
communicationDate: [
{ required: true, message: '请选择沟通日期', trigger: ['change', 'submit'] }
]
});
// 生命周期
onMounted(() => {
// 初始化日期为当前日期
const today = new Date();
formData.admissionDate = formatDate(today);
formData.signatureDate = formatDate(today);
formData.communicationDate = formatDateTime(today);
});
// 提交表单
const submit = () => {
formRef.value.validate((valid) => {
if (valid) {
ElMessage.success('记录保存成功');
console.log('表单数据:', formData);
}
});
};
// 打印功能
const handlePrint = () => {
formRef.value.validate((valid) => {
if (valid) {
window.print();
} else {
ElMessageBox.warning('请先完善表单信息再打印');
}
});
};
// 重置表单
const handleReset = () => {
ElMessageBox.confirm(
'确定要重置表单吗?所有已填写内容将被清空',
'确认重置',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
formRef.value.resetFields();
const today = new Date();
formData.admissionDate = formatDate(today);
formData.signatureDate = formatDate(today);
formData.communicationDate = formatDateTime(today);
ElMessage.success('表单已重置');
});
};
// 日期格式化工具
const formatDate = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
const formatDateTime = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day} ${hour}:${minute}`;
};
</script>
<style scoped>
.medical-document {
max-width: 1200px;
margin: 20px auto;
padding: 30px;
background: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
font-family: 'SimSun', '宋体', serif;
}
/* 标题样式 */
.doc-header {
text-align: center;
margin-bottom: 30px;
}
.doc-title {
font-size: 22px;
margin: 0 0 10px;
font-weight: bold;
}
.doc-subtitle {
font-size: 16px;
color: #666;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #333;
}
/* 内容区域 */
.doc-content {
width: 100%;
}
.doc-section {
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 1px dashed #ccc;
}
.section-title {
font-size: 18px;
margin: 0 0 15px;
color: #333;
font-weight: bold;
}
/* 自适应网格布局 */
.adaptive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px 20px;
margin-bottom: 15px;
}
.grid-item {
margin-bottom: 0;
display: flex;
flex-direction: column;
}
.grid-item .el-form-item__content {
flex: 1;
min-width: 0; /* 确保输入框可收缩适配列宽 */
}
/* 全宽项目 */
.full-width-item {
width: 100%;
margin-bottom: 15px;
}
/* 诊断区域布局 */
.diagnosis-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 15px;
}
.diagnosis-item {
margin-bottom: 0;
}
/* 带单位输入框 */
.input-with-unit {
display: flex;
align-items: center;
gap: 8px;
}
.unit {
white-space: nowrap;
color: #666;
}
/* 签名区域优化 */
.signature-area {
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.signature-tip {
font-size: 12px;
color: #f56c6c;
margin-top: 4px;
}
/* 按钮组 */
.btn-group {
display: flex;
justify-content: center;
gap: 15px;
margin-top: 30px;
padding-top: 20px;
border-top: 2px solid #333;
}
/* 必填项样式 */
.required .el-form-item__label::before {
content: '*';
color: #ff4d4f;
margin-right: 4px;
}
/* 响应式调整 */
@media (max-width: 768px) {
.medical-document {
padding: 15px;
}
.diagnosis-container {
grid-template-columns: 1fr;
}
.adaptive-grid {
grid-template-columns: 1fr;
}
.doc-title {
font-size: 18px;
}
.section-title {
font-size: 16px;
}
}
/* 打印样式优化 */
@media print {
.btn-group {
display: none;
}
.medical-document {
box-shadow: none;
margin: 0;
padding: 0;
}
.el-input__inner, .el-select__input, .el-textarea__inner {
border: none !important;
box-shadow: none !important;
background: transparent !important;
}
.el-form-item__label {
font-weight: bold !important;
}
}
</style>

View File

@@ -60,7 +60,7 @@
<!-- 基本信息记录表格 -->
<div class="vital-signs-table">
<el-table :data="state.vitalSigns" border style="width: 100%">
<el-table :data="state.formData.vitalSigns" border style="width: 100%">
<el-table-column label="日期" width="100">
<template #default="scope">
<el-date-picker
@@ -128,7 +128,7 @@
<el-table-column label="氧疗L/min" width="200">
<el-table-column label="方式" >
<template #default="scope">
<el-select v-model="scope.row.oxygenMethod" placeholder="选择">
<el-select v-model="scope.row.intake" placeholder="选择">
<el-option label="鼻导管" value="鼻导管"></el-option>
<el-option label="面罩" value="面罩"></el-option>
<el-option label="无" value="无"></el-option>
@@ -144,7 +144,7 @@
<el-table-column label="入量" width="200">
<el-table-column label="名称" >
<template #default="scope">
<el-select v-model="scope.row.oxygenMethod" placeholder="选择">
<el-select v-model="scope.row.intake" placeholder="选择">
<el-option label="鼻导管" value="鼻导管"></el-option>
<el-option label="面罩" value="面罩"></el-option>
<el-option label="无" value="无"></el-option>
@@ -165,7 +165,7 @@
<el-table-column label="出量" width="200">
<el-table-column label="名称" >
<template #default="scope">
<el-select v-model="scope.row.oxygenMethod" placeholder="选择">
<el-select v-model="scope.row.intake" placeholder="选择">
<el-option label="鼻导管" value="鼻导管"></el-option>
<el-option label="面罩" value="面罩"></el-option>
<el-option label="无" value="无"></el-option>
@@ -245,7 +245,7 @@ const props = defineProps({
});
// 表单数据
const state = reactive({
const state = ref({
formData: {
name: '',
age: '',
@@ -254,8 +254,7 @@ const state = reactive({
bedNumber: '',
hospitalNumber: '',
diagnosis: '',
},
vitalSigns: [
vitalSigns: [
{
date: new Date().toISOString().split('T')[0],
time: new Date().toTimeString().slice(0, 5),
@@ -264,17 +263,19 @@ const state = reactive({
heartRate: '',
respiratoryRate: '',
bloodPressure: '',
oxygenMethod: '',
intake: '',
flowRate: '',
nurseSignature: '',
},
],
},
});
// 添加生命体征记录
const addVitalSign = () => {
state.vitalSigns.push({
state.value.formData.vitalSigns.push({
date: new Date().toISOString().split('T')[0],
time: new Date().toTimeString().slice(0, 5),
consciousness: '清醒',
@@ -282,16 +283,17 @@ const addVitalSign = () => {
heartRate: '',
respiratoryRate: '',
bloodPressure: '',
oxygenMethod: '',
intake: '',
flowRate: '',
nurseSignature: '',
});
};
// 删除生命体征记录
const removeVitalSign = (index) => {
state.vitalSigns.splice(index, 1);
if (state.vitalSigns.length === 0) {
state.value.formData.vitalSigns.splice(index, 1);
if (state.value.formData.vitalSigns.length === 0) {
addVitalSign();
}
};
@@ -300,7 +302,7 @@ const removeVitalSign = (index) => {
// 重置表单
const resetForm = () => {
state.formData = {
state.value.formData = {
name: '',
age: '',
gender: '',
@@ -308,21 +310,9 @@ const resetForm = () => {
bedNumber: '',
hospitalNumber: '',
diagnosis: '',
vitalSigns:[]
};
state.vitalSigns = [
{
date: new Date().toISOString().split('T')[0],
time: new Date().toTimeString().slice(0, 5),
consciousness: '清醒',
temperature: '',
heartRate: '',
respiratoryRate: '',
bloodPressure: '',
oxygenMethod: '无',
flowRate: '',
nurseSignature: '',
},
];
};
onBeforeMount(() => {
@@ -335,8 +325,16 @@ onBeforeMount(() => {
onMounted(() => {
// 组件挂载后的逻辑
});
defineExpose({ state });
const submit = () => {
// ElMessage.success('提交成功');
emits('submitOk', state.formData);
};
const setFormData = (data) => {
if (data) {
state.value.formData = data;
}
};
defineExpose({ state, submit, setFormData });
</script>
<style lang="scss" scoped>

View File

@@ -0,0 +1,413 @@
<template>
<div class="medical-form">
<div class="patient-name">
患者姓名{{ patient?.patientName || '未知' }} &nbsp;&nbsp; 病历号{{
patient?.busNo || '未知'
}}
</div>
<h2 style="text-align: center">{{ userStore.hospitalName }}</h2>
<h2 style="text-align: center">门诊病历</h2>
<!-- 滚动内容区域 -->
<div class="form-scroll-container">
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="100px"
label-align="left"
class="medical-full-form"
>
<h4 class="section-title">基础信息</h4>
<!-- 1. 基础信息单行自适应排列 -->
<el-form-item class="form-section">
<div class="single-row-layout">
<el-form-item label="身高" prop="height" class="row-item">
<div class="input-with-unit">
<el-input v-model="formData.height" type="text" placeholder="请输入" />
<span class="unit">cm</span>
</div>
</el-form-item>
<el-form-item label="体重" prop="weight" class="row-item">
<div class="input-with-unit">
<el-input v-model="formData.weight" type="text" placeholder="请输入" />
<span class="unit">kg</span>
</div>
</el-form-item>
<el-form-item label="体温" prop="temperature" class="row-item">
<div class="input-with-unit">
<el-input v-model="formData.temperature" type="text" placeholder="请输入" />
<span class="unit"></span>
</div>
</el-form-item>
<el-form-item label="脉搏" prop="pulse" class="row-item">
<div class="input-with-unit">
<el-input v-model="formData.pulse" type="text" placeholder="请输入" />
<span class="unit">/</span>
</div>
</el-form-item>
<el-form-item label="发病日期" prop="onsetDate" class="row-item">
<el-date-picker
v-model="formData.onsetDate"
type="date"
placeholder="选择发病日期"
value-format="YYYY-MM-DD"
style="width: 100%"
/>
<!-- <el-input v-model="formData.onsetDate" type="date" /> -->
</el-form-item>
</div>
</el-form-item>
<h4 class="section-title">病史信息</h4>
<!-- 2. 病史信息单行自适应排列新增调整 -->
<el-form-item class="form-section">
<div class="single-row-layout">
<el-form-item label="现病史" prop="presentIllness" class="row-item history-item">
<el-input
v-model="formData.presentIllness"
type="textarea"
placeholder="无"
autosize
/>
</el-form-item>
<el-form-item label="既往史" prop="pastIllness" class="row-item history-item">
<el-input v-model="formData.pastIllness" type="textarea" placeholder="无" autosize />
</el-form-item>
<el-form-item label="个人史" prop="personalHistory" class="row-item history-item">
<el-input
v-model="formData.personalHistory"
type="textarea"
placeholder="无"
autosize
/>
</el-form-item>
<el-form-item label="过敏史" prop="allergyHistory" class="row-item history-item">
<el-input
v-model="formData.allergyHistory"
type="textarea"
placeholder="无"
autosize
/>
</el-form-item>
<el-form-item label="家族史" prop="familyHistory" class="row-item history-item">
<el-input
v-model="formData.familyHistory"
type="textarea"
placeholder="无"
autosize
/>
</el-form-item>
</div>
</el-form-item>
<h4 class="section-title">主诉查体(治疗)处置辅助检查</h4>
<!-- 3. 主诉必填 -->
<el-form-item label="主诉" prop="complaint" class="required form-item-single">
<el-input
v-model="formData.complaint"
type="textarea"
placeholder="请输入主诉"
class="tall-textarea"
autosize
/>
</el-form-item>
<!-- 4. 查体处理辅助检查 -->
<el-form-item label="查体(治疗)" prop="physicalExam" class="form-item-single">
<el-input
v-model="formData.physicalExam"
type="textarea"
placeholder="请输入查体结果"
class="tall-textarea"
autosize
/>
</el-form-item>
<el-form-item label="处置" prop="treatment" class="form-item-single">
<el-input
v-model="formData.treatment"
type="textarea"
placeholder="请输入处理方案"
class="tall-textarea"
autosize
/>
</el-form-item>
<el-form-item label="辅助检查" prop="auxiliaryExam" class="form-item-single">
<el-input
v-model="formData.auxiliaryExam"
type="textarea"
placeholder="请输入辅助检查结果"
class="tall-textarea"
autosize
/>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script setup>
import { reactive, ref, onBeforeMount, onMounted, watch } from 'vue';
import useUserStore from '../store/modules/user';
import { ElInput, ElMessage, ElForm, ElFormItem } from 'element-plus';
import { patientInfo } from '../views/doctorstation/components/store/patient';
import { pa } from 'element-plus/es/locales.mjs';
defineOptions({
name: 'OutpatientMedicalRecord',
components: { ElInput, ElMessage, ElForm, ElFormItem },
});
// // Props与事件,去掉props.patientInfo改为直接从store获取
// const props = defineProps({
// patientInfo: {
// type: Object,
// required: true,
// },
// });
const props = defineProps({});
const emits = defineEmits(['submitOk']);
// 数据初始化
const userStore = useUserStore();
const patient = ref(null);
const formRef = ref(null);
// 表单数据(全部字符类型)
const formData = reactive({
height: '', // 身高
weight: '', // 体重
temperature: '', // 体温
pulse: '', // 脉搏
onsetDate: '', // 发病日期
complaint: '', // 主诉(必填)
presentIllness: '', // 现病史
pastIllness: '', // 既往史
personalHistory: '', // 个人史
allergyHistory: '', // 过敏史
physicalExam: '', // 查体
treatment: '', // 处理
auxiliaryExam: '', // 辅助检查
familyHistory: '', // 家族史
});
// 表单校验规则
const rules = reactive({
complaint: [
{
required: true,
message: '请填写主诉',
trigger: ['blur', 'submit'],
},
],
});
// 提交函数
const submit = () => {
formRef.value.validate((isValid) => {
if (isValid) {
emits('submitOk', formData);
ElMessage.success('提交成功');
}
});
};
// 日期格式化工具
const formatDateTime = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day} ${hour}:${minute}`;
};
// 表单数据赋值
const setFormData = (data) => {
if (data) {
Object.assign(formData, data);
}
};
// 生命周期
onBeforeMount(() => {});
onMounted(() => {
console.log('当前患者信息:', patientInfo);
patient.value = patientInfo.value;
// 初始化发病日期为当前时间
if (!formData.onsetDate) {
formData.onsetDate = formatDateTime(new Date());
}
});
// 监听患者信息变化,实现联动显示
watch(
() => patientInfo.value,
(newPatientInfo) => {
patient.value = newPatientInfo;
},
{ deep: true }
);
// 暴露接口
defineExpose({ formData, submit, setFormData });
</script>
<style scoped>
/* 表单外层容器 */
.medical-form {
max-width: 1200px;
width: 100%;
min-height: 800px;
height: 900px;
margin: 15px auto;
padding: 15px;
border: 1px solid #ddd;
border-radius: 8px;
font-family: Arial, sans-serif;
box-sizing: border-box;
overflow: visible;
}
/* 顶部姓名样式 */
.patient-name {
display: inline-block;
margin-bottom: 15px;
font-size: 14px;
color: #333;
font-weight: 500;
}
/* 滚动内容容器 */
.form-scroll-container {
width: 100%;
max-height: 80vh;
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: thin;
scrollbar-color: #ccc #f5f5f5;
}
.form-scroll-container::-webkit-scrollbar {
width: 6px;
}
.form-scroll-container::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 3px;
}
.form-scroll-container::-webkit-scrollbar-track {
background-color: #f5f5f5;
}
/* 完整表单容器 */
.medical-full-form {
width: 100%;
}
/* 区域通用样式 */
.form-section {
margin-bottom: 20px;
}
.section-title {
margin: 0 0 12px;
padding-bottom: 6px;
border-bottom: 1px solid #f0f0f0;
color: #333;
font-size: 16px;
font-weight: bold;
}
/* 通用单行自适应布局(基础信息+病史信息共用) */
.single-row-layout {
display: flex;
flex-wrap: wrap; /* 自动换行 */
align-items: flex-start; /* 顶部对齐,适配文本域高度 */
gap: 15px; /* 统一元素间距 */
}
.row-item {
margin-bottom: 0; /* 取消底部间距,避免换行重叠 */
display: flex;
flex-direction: column;
}
/* 基础信息项:适配短输入框 */
.row-item:not(.history-item) {
min-width: 160px; /* 基础信息项最小宽度 */
}
/* 病史信息项:适配文本域,设置更大最小宽度 */
.history-item {
min-width: 220px; /* 确保文本域有足够宽度 */
}
/* 带单位的输入框样式 */
.input-with-unit {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
}
.input-with-unit .el-input {
flex: 1;
}
.unit {
font-weight: 500;
color: #333;
white-space: nowrap;
font-size: 14px;
}
/* 单行表单项样式(主诉、查体等) */
.form-item-single {
margin-bottom: 18px;
}
/* 文本域高度控制 */
.tall-textarea {
--el-input-textarea-min-height: 100px;
}
/* 病史信息文本域:适当降低高度,适配单行布局 */
.history-item .el-input__inner {
--el-input-textarea-min-height: 60px;
}
/* 必填项红色星号 */
.required .el-form-item__label::before {
content: '* ';
color: #ff4d4f;
}
/* 输入框统一样式 */
.el-form-item .el-input,
.el-form-item .el-input__wrapper {
width: 100%;
box-sizing: border-box;
}
.el-form-item .el-input__inner {
font-size: 14px;
padding: 8px 12px;
}
/* 响应式调整 */
@media (max-width: 768px) {
.medical-form {
height: 80vh;
padding: 10px;
}
.form-scroll-container {
height: calc(100% - 35px);
}
.el-form {
label-width: 70px !important;
}
.row-item:not(.history-item) {
min-width: 130px;
}
.history-item {
min-width: 100%; /* 移动端病史信息全屏宽度,单行显示 */
}
.form-item-single,
.form-section {
margin-bottom: 15px;
}
.tall-textarea {
--el-input-textarea-min-height: 80px;
}
}
</style>

View File

@@ -0,0 +1,359 @@
<template>
<div class="medical-document" >
<!-- 操作按钮 -->
<div class="btn-group">
<el-button type="success" @click="handlePrint">打印记录</el-button>
<!-- <el-button type="warning" @click="handleReset">重置表单</el-button> -->
</div>
<!-- 标题区域 -->
<div class="doc-header">
<h2 class="doc-title">{{ userStore.hospitalName}}</h2>
<h1 class="doc-title">手术记录</h1>
<div class="doc-subtitle">病历号: {{ formData.busNo || '待填写' }}</div>
</div>
<!-- 内容区域 -->
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="100px"
label-align="left"
class="doc-content"
style="height: 50vh;overflow: scroll;"
>
<!-- 患者基础信息 -->
<section class="doc-section">
<h2 class="section-title">患者基础信息</h2>
<div class="adaptive-grid">
<el-form-item label="姓名" prop="patientName" class="grid-item required">
<el-input v-model="formData.patientName" placeholder="请输入患者姓名" clearable />
</el-form-item>
<el-form-item label="性别" prop="gender" class="grid-item required">
<el-select v-model="formData.gender" placeholder="请选择性别">
<el-option label="男性" value="男性" />
<el-option label="女性" value="女性" />
</el-select>
</el-form-item>
<el-form-item label="年龄" prop="age" class="grid-item required">
<div class="input-with-unit">
<el-input v-model.number="formData.age" placeholder="请输入年龄" />
</div>
</el-form-item>
<el-form-item label="科室" prop="department" class="grid-item required">
<el-input v-model="formData.department" placeholder="如:普外科" clearable />
</el-form-item>
<!--
<el-form-item label="病房/床号" prop="bedNo" class="grid-item required">
<el-input v-model="formData.bedNo" placeholder="如502-03" clearable />
</el-form-item> -->
<el-form-item label="手术日期" prop="operationDate" class="grid-item required">
<el-date-picker
v-model="formData.operationDate"
type="date"
placeholder="选择手术日期"
value-format="YYYY-MM-DD"
style="width: 100%;"
/>
</el-form-item>
</div>
</section>
<!-- 手术综合信息 -->
<section class="doc-section">
<h2 class="section-title">手术综合信息</h2>
<el-form-item label="详细记录" prop="surgicalDetails" class="full-width-item required">
<el-input
v-model="formData.surgicalDetails"
type="textarea"
placeholder="请整合记录:手术团队、手术名称、术中发现、术后情况、签署信息等"
autosize
/>
</el-form-item>
</section>
</el-form>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { ElMessage, ElMessageBox, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElDatePicker, ElButton } from 'element-plus';
import { patientInfo } from '../views/doctorstation/components/store/patient';
import useUserStore from '../store/modules/user';
defineOptions({
name: 'tySurgicalRecord'
});
// 表单引用
const formRef = ref(null);
// // Props与事件,去掉props.patientInfo改为直接从store获取
// const props = defineProps({
// patientInfo: {
// type: Object,
// required: true,
// },
// });
const props = defineProps({});
const emits = defineEmits(['submitOk']);
const userStore = useUserStore();
const patient = patientInfo.value;
// 表单数据
const formData = reactive({
busNo: patient?.busNo || '',
patientName: patient?.patientName || '',
gender: patient?.genderEnum_enumText || '',
age: patient?.age || '',
department: '',
bedNo: '',
operationDate: '',
surgicalDetails: ''
});
// 表单验证规则
const rules = reactive({
busNo: [
{ required: true, message: '请填写病历号', trigger: ['blur', 'submit'] }
],
patientName: [
{ required: true, message: '请填写患者姓名', trigger: ['blur', 'submit'] }
],
gender: [
{ required: true, message: '请选择性别', trigger: ['change', 'submit'] }
],
age: [
{ required: true, message: '请填写年龄', trigger: ['blur', 'submit'] }
// { type: 'number', min: 0, max: 150, message: '年龄需在0-150之间', trigger: ['blur', 'submit'] }
],
department: [
{ required: true, message: '请填写科室', trigger: ['blur', 'submit'] }
],
// bedNo: [
// { required: true, message: '请填写病房/床号', trigger: ['blur', 'submit'] }
// ],
operationDate: [
{ required: true, message: '请选择手术日期', trigger: ['change', 'submit'] }
],
surgicalDetails: [
{ required: true, message: '请填写手术综合信息', trigger: ['blur', 'submit'] }
]
});
// 提交表单
const submit = () => {
formRef.value.validate((valid) => {
if (valid) {
emits('submitOk', formData);
ElMessage.success('手术记录保存成功');
console.log('手术记录数据:', formData);
}
});
};
// 打印功能
const handlePrint = () => {
formRef.value.validate((valid) => {
if (valid) {
// window.print();
ElMessage.warning('打印功能待实现');
} else {
ElMessage.warning('请先完善表单信息再打印');
}
});
};
// 重置表单
const handleReset = () => {
ElMessageBox.confirm(
'确定要重置表单吗?所有已填写内容将被清空',
'确认重置',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
formRef.value.resetFields();
const today = new Date();
formData.operationDate = formatDate(today);
ElMessage.success('表单已重置');
});
};
// 日期格式化
const formatDate = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
// 表单数据赋值
const setFormData = (data) => {
if (data) {
Object.assign(formData, data);
}
};
// 生命周期
onBeforeMount(() => {});
onMounted(() => {
// 初始化手术日期为当前时间
console.log('patientInfo', patient);
console.log('userStore', userStore, formData.department);
if (!formData.operationDate) {
formData.operationDate = formatDate(new Date());
}
if(formData.department==='' ){
formData.department=userStore.orgName;
}
});
// 暴露接口
defineExpose({ formData, submit, setFormData });
</script>
<style scoped>
.medical-document {
max-width: 1200px;
height: auto;
margin: 20px auto;
padding: 30px;
background: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
font-family: 'SimSun', '宋体', serif;
}
.doc-header {
text-align: center;
margin-bottom: 30px;
}
.doc-title {
font-size: 24px;
margin: 0 0 10px;
font-weight: bold;
}
.doc-subtitle {
font-size: 16px;
color: #666;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #333;
}
.doc-content {
width: 100%;
}
.doc-section {
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 1px dashed #ccc;
}
.section-title {
font-size: 18px;
margin: 0 0 15px;
color: #333;
font-weight: bold;
}
.adaptive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px 20px;
margin-bottom: 15px;
}
.grid-item {
margin-bottom: 0;
display: flex;
flex-direction: column;
}
.grid-item .el-form-item__content {
flex: 1;
min-width: 0;
}
.full-width-item {
width: 100%;
margin-bottom: 15px;
}
.input-with-unit {
display: flex;
align-items: center;
gap: 8px;
}
.unit {
white-space: nowrap;
color: #666;
}
/* 按钮组强制靠右增加margin确保间距 */
.btn-group {
display: flex;
justify-content: flex-end;
gap: 20px;
margin-bottom: 30px;
width: 100%; /* 确保容器占满宽度,实现真正靠右 */
}
.required .el-form-item__label::before {
content: '*';
color: #ff4d4f;
margin-right: 4px;
}
.el-textarea__inner {
line-height: 1.6;
padding: 12px;
}
@media (max-width: 768px) {
.medical-document {
padding: 15px;
}
.adaptive-grid {
grid-template-columns: 1fr;
}
.doc-title {
font-size: 20px;
}
.section-title {
font-size: 16px;
}
}
@media print {
.btn-group {
display: none;
}
.medical-document {
box-shadow: none;
margin: 0;
padding: 0;
}
.el-input__inner, .el-select__input, .el-textarea__inner {
border: none !important;
box-shadow: none !important;
background: transparent !important;
}
.el-form-item__label {
font-weight: bold !important;
}
}
</style>

View File

@@ -459,3 +459,46 @@ export async function selectPrinterAndPrint(data, template, showPrinterDialog, m
modal.msgError(error.message || '获取打印机列表失败');
}
}
// 分组标记处理
export function getGroupMarkers(tableData) {
// 初始化所有行的 groupIcon 为 null
tableData.forEach((item) => {
item.groupIcon = null;
});
// 创建一个映射来存储每个 groupId 对应的行索引
const groupMap = {};
// 遍历列表,按 groupId 分组(忽略无 groupId 的项)
tableData.forEach((item, index) => {
if (!item.groupId) {
return;
}
if (!groupMap[item.groupId]) {
groupMap[item.groupId] = [];
}
groupMap[item.groupId].push(index);
});
// 为每个组设置 groupIcon
Object.values(groupMap).forEach((indices) => {
// 只有当组内元素大于1个时才需要显示分组标记
if (indices.length > 1) {
indices.forEach((index, i) => {
if (i === 0) {
// 第一行
tableData[index].groupIcon = '┏';
} else if (i === indices.length - 1) {
// 最后一行
tableData[index].groupIcon = '┗';
} else {
// 中间行
tableData[index].groupIcon = '┃';
}
});
}
});
return tableData;
}

View File

@@ -0,0 +1,293 @@
/**
* 打印工具类
* 集中管理所有打印相关功能
*/
// 打印模板映射表
const TEMPLATE_MAP = {
// CLINIC_CHARGE: () => import('@/views/charge/cliniccharge/components/template.json'),
// DISPOSAL: () => import('@/views/clinicmanagement/disposal/components/disposalTemplate.json'),
//处方签
PRESCRIPTION: () => import('@/components/Print/Prescription.json'),
//处置单
DISPOSAL: () => import('@/components/Print/Disposal.json'),
//门诊日结
DAY_END: () => import('@/components/Print/DailyOutpatientSettlement.json'),
WESTERN_MEDICINE: () =>
import('@/views/pharmacymanagement/westernmedicine/components/templateJson.json'),
IN_HOSPITAL_DISPENSING: () =>
import('@/views/drug/inHospitalDispensing/components/templateJson.json'),
//门诊挂号
OUTPATIENT_REGISTRATION: () => import('@/components/Print/OutpatientRegistration.json'),
//门诊收费
OUTPATIENT_CHARGE: () => import('@/components/Print/OutpatientBilling.json'),
};
/**
* 极简打印方法
* @param {string} templateName 打印模板名称(常量或字符串)
* @param {Array|Object} data 打印数据
* @param {string} printerName 打印机名称(可选)
* @param {Object} options 打印选项(可选)
* @returns {Promise} 打印结果Promise
*/
export async function simplePrint(templateName, data, printerName, options = {}) {
try {
// 获取模板
const template = await loadTemplate(templateName);
// 执行打印,业务名称默认为模板名称
return await executePrint(data, template, printerName, options, templateName);
} catch (error) {
console.error('打印失败:', error);
throw error;
}
}
/**
* 加载打印模板
* @param {string} templateName 模板名称
* @returns {Promise<Object>} 模板对象
*/
async function loadTemplate(templateName) {
// 如果是常量形式,获取实际的键名
const templateKey = typeof templateName === 'symbol' ? templateName.description : templateName;
if (!TEMPLATE_MAP[templateKey]) {
throw new Error(`未找到打印模板: ${templateKey}`);
}
try {
const templateModule = await TEMPLATE_MAP[templateKey]();
return templateModule.default || templateModule;
} catch (error) {
console.error(`加载模板 ${templateKey} 失败:`, error);
throw error;
}
}
/**
* 带打印机选择的极简打印方法
* @param {string} templateName 打印模板名称
* @param {Array|Object} data 打印数据
* @param {Function} showPrinterDialog 显示打印机选择对话框的函数
* @param {Object} modal 消息提示对象
* @param {Function} callback 打印完成后的回调函数(可选)
* @returns {Promise} 打印结果Promise
*/
export async function simplePrintWithDialog(
templateName,
data,
showPrinterDialog,
modal,
callback
) {
try {
// 获取模板
const template = await loadTemplate(templateName);
// 执行打印
await selectPrinterAndPrint(data, template, showPrinterDialog, modal, callback, templateName);
} catch (error) {
modal.msgError(error.message || '打印失败');
if (callback) callback(error);
}
}
// 导出模板名称常量
export const PRINT_TEMPLATE = {
// CLINIC_CHARGE: 'CLINIC_CHARGE',
DAY_END: 'DAY_END',
WESTERN_MEDICINE: 'WESTERN_MEDICINE',
IN_HOSPITAL_DISPENSING: 'IN_HOSPITAL_DISPENSING',
//门诊挂号
OUTPATIENT_REGISTRATION: 'OUTPATIENT_REGISTRATION',
//门诊收费
OUTPATIENT_CHARGE: 'OUTPATIENT_CHARGE',
//处方签
PRESCRIPTION: 'PRESCRIPTION',
//处置单
DISPOSAL: 'DISPOSAL',
};
/**
* 获取打印机列表
* @returns {Array} 打印机列表
*/
export function getPrinterList() {
try {
const printerList =
window.hiprint && window.hiprint.hiwebSocket
? window.hiprint.hiwebSocket.getPrinterList()
: [];
return printerList || [];
} catch (error) {
console.error('获取打印机列表失败:', error);
return [];
}
}
import useUserStore from '@/store/modules/user';
/**
* 获取当前登录用户ID
* @returns {string} 用户ID
*/
function getCurrentUserId() {
try {
// 从Pinia store中获取当前用户ID
const userStore = useUserStore();
return userStore.id || '';
} catch (e) {
console.error('获取用户ID失败:', e);
return '';
}
}
/**
* 生成打印机缓存键
* @param {string} businessName 打印业务名称
* @returns {string} 缓存键
*/
function getPrinterCacheKey(businessName) {
const userId = getCurrentUserId();
return `selectedPrinter_${businessName || 'default'}_${userId}`;
}
/**
* 从缓存获取上次选择的打印机
* @param {string} businessName 打印业务名称
* @returns {string} 打印机名称
*/
export function getCachedPrinter(businessName = 'default') {
const cacheKey = getPrinterCacheKey(businessName);
return localStorage.getItem(cacheKey) || '';
}
/**
* 保存打印机选择到缓存
* @param {string} printerName 打印机名称
* @param {string} businessName 打印业务名称
*/
export function savePrinterToCache(printerName, businessName = 'default') {
if (printerName) {
const cacheKey = getPrinterCacheKey(businessName);
localStorage.setItem(cacheKey, printerName);
}
}
/**
* 执行打印操作
* @param {Array} data 打印数据
* @param {Object} template 打印模板
* @param {string} printerName 打印机名称(可选)
* @param {Object} options 打印选项(可选)
* @param {string} businessName 打印业务名称(可选)
* @returns {Promise} 打印结果Promise
*/
export function executePrint(data, template, printerName, options = {}, businessName = 'default') {
return new Promise((resolve, reject) => {
try {
if (!window.hiprint) {
throw new Error('打印插件未加载');
}
const hiprintTemplate = new window.hiprint.PrintTemplate({ template });
const printOptions = {
title: '打印标题',
height: 210,
width: 148,
...options,
};
// 如果指定了打印机,添加到打印选项中
if (printerName) {
printOptions.printer = printerName;
// 保存到缓存
savePrinterToCache(printerName, businessName);
}
// 打印成功回调
hiprintTemplate.on('printSuccess', function (e) {
resolve({ success: true, event: e });
});
// 打印失败回调
hiprintTemplate.on('printError', function (e) {
reject({ success: false, event: e, message: '打印失败' });
});
// 执行打印
hiprintTemplate.print2(data, printOptions);
} catch (error) {
reject({ success: false, error: error, message: error.message || '打印过程中发生错误' });
}
});
}
/**
* 选择打印机并执行打印
* @param {Array} data 打印数据
* @param {Object} template 打印模板
* @param {Function} showPrinterDialog 显示打印机选择对话框的函数
* @param {Object} modal 消息提示对象
* @param {Function} callback 打印完成后的回调函数
* @param {string} businessName 打印业务名称(可选)
*/
export async function selectPrinterAndPrint(
data,
template,
showPrinterDialog,
modal,
callback,
businessName = 'default'
) {
try {
// 获取打印机列表
const printerList = getPrinterList();
if (printerList.length === 0) {
modal.msgWarning('未检测到可用打印机');
return;
}
// 获取缓存的打印机
const cachedPrinter = getCachedPrinter(businessName);
let selectedPrinter = '';
// 判断打印机选择逻辑
if (printerList.length === 1) {
selectedPrinter = printerList[0].name;
await executePrint(data, template, selectedPrinter, {}, businessName);
if (callback) callback();
} else if (cachedPrinter && printerList.some((printer) => printer.name === cachedPrinter)) {
selectedPrinter = cachedPrinter;
await executePrint(data, template, selectedPrinter, {}, businessName);
if (callback) callback();
} else {
// 调用显示打印机选择对话框的函数
showPrinterDialog(printerList, async (chosenPrinter) => {
try {
await executePrint(data, template, chosenPrinter, {}, businessName);
if (callback) callback();
} catch (error) {
modal.msgError(error.message || '打印失败');
}
});
}
} catch (error) {
modal.msgError(error.message || '获取打印机列表失败');
}
}
// 默认导出简化的打印方法
export default {
print: simplePrint,
printWithDialog: simplePrintWithDialog,
TEMPLATE: PRINT_TEMPLATE,
executePrint,
selectPrinterAndPrint,
getPrinterList,
getCachedPrinter,
savePrinterToCache,
};

View File

@@ -116,7 +116,7 @@ const props = defineProps({
})
const userStore = useUserStore();
const formRef = ref(null)
console.log(components,'----components');
const dialogVisible= defineModel( 'dialogVisible', {
type: Boolean,
default: false

View File

@@ -0,0 +1,195 @@
<template>
<div class="LaboratoryTests-container">
<el-dialog
title="批量导入项目"
:model-value="props.dialogVisible"
@update:modelValue="(val) => emit('update:dialogVisible', val)"
width="842"
append-to-body
destroy-on-close
:draggable="true"
>
<el-row :gutter="10">
<el-col :span="24">
<el-form ref="formEl" :rules="rules" :model="form" label-width="100px">
<el-form-item label="项目类型" prop="clinicalType">
<el-select
v-model="form.clinicalType"
placeholder="请选择"
@change="getList()"
filterable
clearable
style="width: 200px"
>
<el-option
v-for="item in categoryCodeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row :gutter="30" style="margin-top: 30px">
<el-col :span="24">
<el-transfer
v-model="transferValue"
:data="applicationList"
filter-placeholder="项目代码/名称"
filterable
:titles="['未选择', '已选择']"
style="width: 100%"
/>
</el-col>
</el-row>
<template #footer>
<div class="dialog-footer">
<el-button @click="onCancel">取消</el-button>
<el-button type="primary" @click="onConfirm"> 确认 </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="LaboratoryTests">
import { getCurrentInstance, onBeforeMount, onMounted, reactive, ref } from 'vue';
import {
getApplicationList,
editImplementDepartment,
addImplementDepartment,
} from './implementDepartment.js';
const { proxy } = getCurrentInstance();
// 属性
const props = defineProps({
// 弹框显示信息
dialogVisible: {
type: Boolean,
default: false,
},
// 选择科室
organizationId: {
type: String,
default: '',
},
});
const emit = defineEmits(['update:dialogVisible', 'confirm', 'cancel', 'submitOk']);
// 申请项目列表
const applicationListAll = ref();
// 获取所有申请项目
const applicationList = ref();
// 申请项目列表
const transferValue = ref([]);
// 项目类型
const formEl = ref();
const form = reactive({ clinicalType: '23' });
// 加载中
const loading = ref(false);
// 弹窗显隐由父组件控制,通过 v-model 事件同步
// 项目类型
const categoryCodeList = ref([
{ label: '治疗', value: '21' },
{ label: '检验', value: '22' },
{ label: '检查', value: '23' },
{ label: '手术', value: '24' },
]);
// 规则校验
const rules = ref({
clinicalType: [{ required: true, message: '请选择项目类型', trigger: 'change' }],
});
const getList = () => {
if (!form.clinicalType) {
return;
}
loading.value = true;
getApplicationList({
pageSize: 10000,
pageNum: 1,
// 项目类型 枚举类中
categoryCode: form.clinicalType,
adviceTypes: '3', //1 药品 2耗材 3诊疗
}).then((res) => {
if (res.code === 200) {
loading.value = false;
applicationListAll.value = res.data.records;
applicationList.value = res.data.records.map((item) => {
return {
label: item.adviceName + item.adviceDefinitionId,
key: item.adviceDefinitionId,
};
});
} else {
proxy.$message.error(res.message);
applicationList.value = [];
}
});
};
function onCancel() {
emit('cancel');
emit('update:dialogVisible', false);
}
// 批量添加
async function onConfirm() {
if (!formEl) return;
formEl.value.validate(async (valid) => {
if (!valid) return;
if (!transferValue.value || transferValue.value.length === 0) {
proxy.$message.error('请选择至少一个项目');
return;
}
const requests = (transferValue.value || []).map((defId) => {
const params = {
// 诊疗定义id
activityDefinitionId: defId,
// 科室ID
organizationId: props.organizationId,
// 诊疗类型
activityCategoryCode: form.clinicalType,
// 开始时间
startTime: '00:00:00',
// 结束时间
endTime: '23:59:59',
/*
方法类别DistributionCategoryCodeEnum 枚举
desription: 8代表诊疗
*/
distributionCategoryCode: '8',
};
return handleSave(params);
});
await Promise.all(requests);
emit('submitOk');
emit('update:dialogVisible', false);
transferValue.value = [];
});
}
// 保存
async function handleSave(params) {
if (params.id) {
return editImplementDepartment(params).then((res) => {
proxy.$modal.msgSuccess('保存成功!');
return res;
});
} else {
delete params.id;
return addImplementDepartment(params).then((res) => {
proxy.$modal.msgSuccess('保存成功!');
return res;
});
}
}
onMounted(() => {
getList();
});
</script>
<style lang="scss" scoped>
:deep(.el-transfer-panel) {
width: 300px;
}
</style>

View File

@@ -1,68 +1,83 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 初始化
export function getImplementDepartmentList(query) {
return request({
export function getImplementDepartmentList (query) {
return request ({
url: '/base-data-manage/organization/organization',
method: 'get',
params: query
})
params: query,
});
}
// 查询诊疗目录列表
export function getDiagnosisTreatmentList(query) {
return request({
export function getDiagnosisTreatmentList (query) {
return request ({
url: '/base-data-manage/org-loc/org-loc',
method: 'get',
params: query
})
params: query,
});
}
//查询诊疗目录详细
export function getImplementDepartmentOne(query) {
return request({
export function getImplementDepartmentOne (query) {
return request ({
url: '/data-dictionary/diagnosis-treatment/information-page',
method: 'get',
params: query // 确保参数正确传递
})
params: query, // 确保参数正确传递
});
}
// 新增
export function addImplementDepartment(data) {
return request({
export function addImplementDepartment (data) {
return request ({
url: '/base-data-manage/org-loc/org-loc',
method: 'post',
data: data
})
data: data,
});
}
// 修改
export function editImplementDepartment(data) {
return request({
export function editImplementDepartment (data) {
return request ({
url: '/base-data-manage/org-loc/org-loc',
method: 'post',
data: data
})
data: data,
});
}
// 删除
export function deleteImplementDepartment(data) {
return request({
export function deleteImplementDepartment (data) {
return request ({
url: '/base-data-manage/org-loc/org-loc?orgLocId=' + data.orgLocId,
method: 'delete',
})
});
}
// 目录分类查询
export function getDiseaseTreatmentInit() {
return request({
export function getDiseaseTreatmentInit () {
return request ({
url: '/data-dictionary/diagnosis-treatment/init',
method: 'get'
})
method: 'get',
});
}
// 目录分类子查询
export function getDiseaseTreatmentInitLoc(id) {
return request({
export function getDiseaseTreatmentInitLoc (id) {
return request ({
url: '/data-dictionary/diagnosis-treatment/information-one?id=' + id,
method: 'get'
})
method: 'get',
});
}
//医嘱大下拉
export function getApplicationList (queryParams) {
return request ({
url: '/doctor-station/advice/advice-base-info',
method: 'get',
params: queryParams,
});
}
// 获取所有诊疗项目
export function getAllTreatmentList () {
return request ({
url: '/app-common/activity-definition',
method: 'get',
});
}

View File

@@ -33,6 +33,17 @@
>添加新项目</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Plus"
:disabled="isAddDisable"
@click="handleBacthAddItem"
v-hasPermi="['system:user:add']"
>批量新增项目配置</el-button
>
</el-col>
</el-row>
<el-table
@@ -41,54 +52,49 @@
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="100" align="center" />
<el-table-column label="诊疗目录" width="150" align="center" :show-overflow-tooltip="true">
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: center">
<el-select
v-model="scope.row.activityCategoryCode"
placeholder="请选择"
ref="dropdown"
@change="DiagnosisTreatmentList(scope.row,scope.$index,1)"
:class="{ 'error-border': scope.row.error }"
clearable
>
<el-option
v-for="dict in catagoryDicts"
:key="dict.value"
:label="dict.info"
:value="dict.value"
/>
</el-select>
</div>
</template>
</el-table-column>
<el-table-column
label="项目名称"
label="诊疗目录"
width="150"
align="center"
:show-overflow-tooltip="true"
>
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: center">
<el-select
v-model="scope.row.activityDefinitionId"
filterable
remote
reserve-keyword
placeholder="请选择"
remote-show-suffix
:remote-method="(query) => debouncedRemoteMethod(query, scope.row)"
:loading="loading"
style="width: 350px"
:class="{ 'error-border': scope.row.error }"
>
<el-option
v-for="item in scope.row.projectList"
:key="item.value"
:label="item.info"
:value="item.value"
/>
</el-select>
</div>
<el-select
v-model="scope.row.activityCategoryCode"
placeholder="请选择"
ref="dropdown"
:class="{ 'error-border': scope.row.error }"
clearable
>
<el-option
v-for="dict in catagoryDicts"
:key="dict.value"
:label="dict.info"
:value="dict.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="项目名称" align="center" :show-overflow-tooltip="true">
<template #default="scope">
<el-select
v-model="scope.row.activityDefinitionId"
filterable
remote
reserve-keyword
placeholder="请选择"
remote-show-suffix
style="width: 400px; max-width: 500px"
:class="{ 'error-border': scope.row.error }"
clearable
>
<el-option
v-for="item in allImplementDepartmentList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column
@@ -97,18 +103,15 @@
key="startTime"
prop="startTime"
:show-overflow-tooltip="true"
width="300"
>
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: center">
<el-time-picker
v-model="scope.row.startTime"
placeholder="选择时间"
format="HH:mm:ss"
value-format="HH:mm:ss"
>
</el-time-picker>
</div>
<el-time-picker
v-model="scope.row.startTime"
placeholder="选择时间"
format="HH:mm:ss"
value-format="HH:mm:ss"
>
</el-time-picker>
</template>
</el-table-column>
@@ -117,19 +120,16 @@
align="center"
key="endTime"
prop="endTime"
:show-overflow-tooltip="true"
width="300"
show-overflow-tooltip
>
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: center">
<el-time-picker
v-model="scope.row.endTime"
placeholder="选择时间"
format="HH:mm:ss"
value-format="HH:mm:ss"
>
</el-time-picker>
</div>
<el-time-picker
v-model="scope.row.endTime"
placeholder="选择时间"
format="HH:mm:ss"
value-format="HH:mm:ss"
>
</el-time-picker>
</template>
</el-table-column>
<el-table-column
@@ -169,6 +169,11 @@
/>
</el-col>
</el-row>
<BacthAddItemDialog
v-model:dialogVisible="bacthAddItemDialogVisible"
:organizationId="organizationId"
@submitOk="getList"
/>
</div>
</template>
@@ -178,14 +183,12 @@ import {
getImplementDepartmentList,
getDiagnosisTreatmentList,
getDiseaseTreatmentInit,
getImplementDepartmentOne,
// getDiseaseTreatmentInitLoc,
getAllTreatmentList,
addImplementDepartment,
editImplementDepartment,
deleteImplementDepartment,
} from './components/implementDepartment';
import { debounce } from 'lodash-es';
import { fa } from 'element-plus/es/locales.mjs';
import BacthAddItemDialog from './components/batchAddDialog.vue';
const { proxy } = getCurrentInstance();
const organization = ref([]);
const loading = ref(true);
@@ -194,10 +197,11 @@ const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const catagoryList = ref([]);
const projectList = ref([]);
const catagoryDicts = ref([]);
const isAddDisable = ref(true);
const organizationId = ref('');
// 批量添加
const bacthAddItemDialogVisible = ref(false);
//默认传8(诊疗)
const distributionCategoryCode = ref('8');
const data = reactive({
@@ -212,29 +216,15 @@ const data = reactive({
},
isAdding: false,
});
const debouncedRemoteMethod = debounce((query, row) => {
remoteMethod(query, row);
}, 300);
const { queryParams, tableRules } = toRefs(data);
/** 查询表格数据列表 */
function getList() {
let params = {
// 科室id
organizationId: organizationId.value,
// 类别
distributionCategoryCode: distributionCategoryCode.value,
};
getDiagnosisTreatmentList(params).then((res) => {
console.log(res.data.records)
queryParams.value.organizationId = organizationId.value;
queryParams.value.distributionCategoryCode = distributionCategoryCode.value;
loading.value = true;
getDiagnosisTreatmentList(queryParams.value).then((res) => {
loading.value = false;
catagoryList.value = res.data.records
catagoryList.value.map((k,index)=>{
// if(k.activityCategoryCode){
DiagnosisTreatmentList(k,index, 2)
// }
})
catagoryList.value = res.data.records;
total.value = res.data.total;
});
}
@@ -243,69 +233,21 @@ const filterNode = (value, data) => {
if (!value) return true;
return data.name.indexOf(value) !== -1;
};
//下拉诊疗目录点击事件
function DiagnosisTreatmentList(row,index,type) {
let params = {
statusEnum: 2, // 状态(包括 1预置2启用3停用
...row,
categoryCode: row.activityCategoryCode,
pageSize:100,
}
if(type == 1){
catagoryList.value[index].activityDefinitionId =''
}else if(type == 2){
params.searchKey = row.activityDefinitionId_dictText
}
console.log(params,'params');
getImplementDepartmentOne(params)
.then((res) => {
if (res.code === 200) {
projectList.value = [];
row.name = null;
projectList.value = res.data.records.map((item) => ({ value: item.id, info: item.name }));
catagoryList.value[index].projectList = projectList.value
} else {
proxy.$modal.msgError(res.msg);
}
})
.catch((error) => {
console.error('请求失败', error);
});
}
function remoteMethod(query, row) {
// 所有诊疗项目列表
const allImplementDepartmentList = ref([]);
function getAllImplementDepartment() {
loading.value = true;
const params = {
statusEnum: 2,
activityCategoryCode: row.activityCategoryCode, // 确保已选诊疗目录
searchKey: query, // 模糊搜索关键字
...row,
categoryCode: row.activityCategoryCode,
pageSize:100,
};
console.log(params,row,query,'params');
getImplementDepartmentOne(params).then((res) => {
getAllTreatmentList().then((res) => {
allImplementDepartmentList.value = res.data.map((item) => ({
value: item.activityDefinitionId,
label: item.activityDefinitionName,
}));
loading.value = false;
if (res.code === 200) {
// 更新当前行的 projectList 数据
row.projectList = res.data.records.map((item) => ({
value: item.id,
info: item.name,
}));
} else {
proxy.$modal.msgError(res.msg);
}
});
loading.value = false;
}
/** 选择条数 */
function handleSelectionChange(selection) {
// selectedData.value = selection.map((item) => ({ ...item })); // 存储选择的行数据
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
@@ -317,13 +259,18 @@ function handleAddItem() {
return;
}
const newRow = {
startTime:'00:00:00',
endTime:'23:59:59'
startTime: '00:00:00',
endTime: '23:59:59',
};
catagoryList.value.push(newRow);
total.value = organization.value.length;
data.isAdding = true; // 设置标志位为 true表示有未保存的
}
// 批量添加
function handleBacthAddItem() {
// 批量添加显示对话框
bacthAddItemDialogVisible.value = true;
}
// 检验 编辑或 保存数据
function handleBlur(row, index) {
let hasError = false;
@@ -336,8 +283,7 @@ function handleBlur(row, index) {
if (message) {
proxy.$message.error(message);
} else {
console.error(`No rule defined for field: ${field}`);
proxy.$message.error(`No rule defined for field: ${field}`);
proxy.$message.error(`检验未通过`);
}
}
});
@@ -357,6 +303,7 @@ function openSaveImplementDepartment(row) {
handleBlur(row);
if (row.error) {
hasError = true;
return;
}
const startTime = params.startTime;
const endTime = params.endTime;
@@ -383,22 +330,22 @@ function openSaveImplementDepartment(row) {
}
// 删除当前所选行
function deleteSelectedRows(row) {
if (row.id) {
deleteImplementDepartment({ orgLocId: row.id }).then((res) => {});
} else {
catagoryList.value.pop();
}
proxy.$modal.msgSuccess('删除成功');
data.isAdding = false;
getList();
proxy.$modal.confirm('是否删除选中数据').then(() => {
if (row.id) {
deleteImplementDepartment({ orgLocId: row.id }).then((res) => {});
} else {
catagoryList.value.pop();
}
proxy.$modal.msgSuccess('删除成功');
data.isAdding = false;
getList();
});
}
/** 节点单击事件 */
function handleNodeClick(data, node) {
catagoryList.value.map(k=>{
if(!k.id){
openSaveImplementDepartment(k)
}
})
function handleNodeClick(res, node) {
// 新增按钮是否 disable
data.isAdding = false;
// 新增按钮是否 disable
if (node.parent === null || node.level === 1) {
isAddDisable.value = true;
@@ -418,7 +365,10 @@ function handleNodeClick(data, node) {
/** 目录分类查询 */
function getDiseaseTreatmentList() {
loading.value = true;
getDiseaseTreatmentInit().then(({ data }) => {
loading.value = false;
//分类目录初始化获取
catagoryDicts.value = data.diagnosisCategoryOptions.sort((a, b) => {
return parseInt(a.value) - parseInt(b.value);
@@ -431,6 +381,7 @@ function getDiseaseTreatmentList() {
}
// 诊疗目录分类查询下拉树结d构
function getImplDepartList() {
loading.value = true;
getImplementDepartmentList().then((res) => {
loading.value = false;
if (res.code === 200) {
@@ -450,8 +401,10 @@ function getImplDepartList() {
}
});
}
// 获取左侧执行科室配置目录
getDiseaseTreatmentList();
onMounted(() => {
getAllImplementDepartment();
getDiseaseTreatmentList();
});
</script>
<style scoped>
.el-form--inline .el-form-item {
@@ -463,15 +416,4 @@ getDiseaseTreatmentList();
.error-border {
border: 1px solid red;
}
/* ::v-deep.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{ */
/* background-color: #c5e1ff!important; */
/* #d8ebff!important; */
/* #c5e1ff!important; */
/* #9fceff!important; */
/* } */
/* ::v-deep.el-tree--highlight-current{ */
/* background-color:#f8f8f9 !important; */
/* #ebf5ff!important; */
/* } */
</style>

View File

@@ -48,7 +48,7 @@ const currentSelectRow = ref({});
const queryParams = ref({
pageSize: 100,
pageNum: 1,
adviceTypes: '2,3',
adviceTypes: '1,2,3',
});
const adviceBaseList = ref([]);
// 节流函数

View File

@@ -35,59 +35,27 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
>添加</el-button
>
<el-button type="primary" plain icon="Plus" @click="handleAdd">添加</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Remove"
:disabled="multiple"
@click="handleClose"
<el-button type="danger" plain icon="Remove" :disabled="multiple" @click="handleClose"
>停用</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="CirclePlus"
:disabled="multiple"
@click="handleStart"
<el-button type="success" plain icon="CirclePlus" :disabled="multiple" @click="handleStart"
>启用</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Search"
@click="getList"
>查询</el-button
>
<el-button type="primary" plain icon="Search" @click="getList">查询</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="CircleClose"
@click="handleClear"
>清空条件</el-button
>
<el-button type="warning" plain icon="CircleClose" @click="handleClear">清空条件</el-button>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="supplierList"
@selection-change="handleSelectionChange"
>
<el-table v-loading="loading" :data="supplierList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="编号" align="center" key="busNo" prop="busNo" />
<el-table-column
@@ -111,26 +79,9 @@
prop="typeEnum_enumText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="地址"
align="center"
key="address"
prop="address"
width="120"
/>
<el-table-column
label="联系人电话"
align="center"
key="phone"
prop="phone"
/>
<el-table-column
label="联系人邮箱"
align="center"
key="email"
prop="email"
width="160"
/>
<el-table-column label="地址" align="center" key="address" prop="address" width="120" />
<el-table-column label="联系人电话" align="center" key="phone" prop="phone" />
<el-table-column label="联系人邮箱" align="center" key="email" prop="email" width="160" />
<el-table-column
label="活动标识"
align="center"
@@ -152,20 +103,10 @@
class-name="small-padding fixed-width"
>
<template #default="scope">
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(scope.row)"
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
>编辑</el-button
>
<el-button
link
type="primary"
icon="View"
@click="handleView(scope.row)"
>查看</el-button
>
<el-button link type="primary" icon="View" @click="handleView(scope.row)">查看</el-button>
</template>
</el-table-column>
</el-table>
@@ -179,28 +120,16 @@
<!-- 添加或修改用户配置对话框 -->
<el-dialog :title="title" v-model="open" width="600px" append-to-body>
<el-form
:model="form"
:rules="rules"
ref="supplierRef"
label-width="110px"
>
<el-form :model="form" :rules="rules" ref="supplierRef" label-width="110px">
<el-row>
<el-col :span="12">
<el-form-item label="名称" prop="name">
<el-input
v-model="form.name"
placeholder="请输入名称"
/>
<el-input v-model="form.name" placeholder="请输入名称" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.id != undefined">
<el-form-item label="编码" prop="busNo">
<el-input
v-model="form.busNo"
placeholder="请输入编码"
disabled
/>
<el-input v-model="form.busNo" placeholder="请输入编码" disabled />
</el-form-item>
</el-col>
</el-row>
@@ -261,17 +190,17 @@
</el-col>
<el-col :span="12">
<!-- <el-form-item label="机构编号" prop="orgId"> -->
<!-- <el-input v-model="form.orgId" maxlength="11" /> -->
<el-form-item label="提供部门" prop="orgId">
<el-tree-select
v-model="form.orgId"
:data="deptOptions"
:props="{ value: 'id', label: 'name', children: 'children' }"
value-key="id"
placeholder="请选择提供部门"
check-strictly
clearable
/>
<!-- <el-input v-model="form.orgId" maxlength="11" /> -->
<el-form-item label="提供部门" prop="orgId">
<el-tree-select
v-model="form.orgId"
:data="deptOptions"
:props="{ value: 'id', label: 'name', children: 'children' }"
value-key="id"
placeholder="请选择提供部门"
check-strictly
clearable
/>
<!-- </el-form-item> -->
</el-form-item>
</el-col>
@@ -297,14 +226,11 @@ import {
startSupplier,
getSupplierInit,
deptTreeSelect,
} from "./components/supplier";
} from './components/supplier';
const router = useRouter();
const { proxy } = getCurrentInstance();
const { sys_normal_disable, sys_user_sex } = proxy.useDict(
"sys_normal_disable",
"sys_user_sex"
);
const { sys_normal_disable, sys_user_sex } = proxy.useDict('sys_normal_disable', 'sys_user_sex');
const supplierList = ref([]);
const open = ref(false);
@@ -314,7 +240,7 @@ const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const title = ref('');
const supplierTypeOptions = ref(undefined);
const deptOptions = ref(undefined); // 部门树选项
// 是否停用
@@ -334,8 +260,10 @@ const data = reactive({
// sourceEnum: undefined, // 来源(包括 1厂商/产地目录分类2自定义
},
rules: {
name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
typeEnum: [{ required: true, message: "类型不能为空", trigger: "blur" }],
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
typeEnum: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
orgId: [{ required: true, message: '提供部门不能为空', trigger: 'blur' }],
// address: [{ required: true, message: "地址不能为空", trigger: "blur" }],
// phone: [{ required: true, message: "联系人电话不能为空", trigger: "blur" }],
// email: [{ required: true, message: "联系人邮箱不能为空", trigger: "blur" },
@@ -347,30 +275,30 @@ const data = reactive({
const { queryParams, form, rules } = toRefs(data);
/** 验证邮箱地址是否有效*/
function validateEmail (rule, value, callback) {
function validateEmail(rule, value, callback) {
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (!emailRegex.test(value)) {
callback(new Error('请输入有效的邮箱地址'));
} else {
callback();
}
};
}
/** 厂商种类查询下拉树结构 */
function getsupplierTypeList() {
getSupplierInit().then((response) => {
console.log(response, "response");
console.log(response, 'response');
supplierTypeOptions.value = response.data.supplierTypeOptions;
});
}
/** 查询部门下拉树结构 */
function getDeptTree() {
console.log("查询部门下拉树结构");
console.log('查询部门下拉树结构');
deptTreeSelect().then((response) => {
console.log(response, "response查询部门下拉树结构");
console.log(response, 'response查询部门下拉树结构');
deptOptions.value = response.data.records;
console.log(deptOptions.value, "部门下拉树结构");
console.log(deptOptions.value, '部门下拉树结构');
});
}
@@ -378,14 +306,14 @@ function getDeptTree() {
function getList() {
loading.value = true;
// queryParams.value.statusEnum = +queryParams.value.statusEnum
console.log(queryParams.value, "queryParams.value");
console.log(queryParams.value, 'queryParams.value');
getSupplierList(queryParams.value).then((res) => {
loading.value = false;
console.log(res, "res", res.data.records);
console.log(res, 'res', res.data.records);
supplierList.value = res.data.records;
console.log(supplierList.value, "supplierList.value");
console.log(supplierList.value, 'supplierList.value');
total.value = res.data.total;
console.log(total.value, "total.value");
console.log(total.value, 'total.value');
});
}
/** 节点单击事件 */
@@ -403,13 +331,13 @@ function handleQuery() {
function handleStart(row) {
const stardIds = row.id || ids.value;
proxy.$modal
.confirm("是否确定启用数据!")
.confirm('是否确定启用数据!')
.then(function () {
return startSupplier(stardIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("启用成功");
proxy.$modal.msgSuccess('启用成功');
})
.catch(() => {});
}
@@ -417,13 +345,13 @@ function handleStart(row) {
function handleClose(row) {
const stopIds = row.id || ids.value;
proxy.$modal
.confirm("是否确认停用数据!")
.confirm('是否确认停用数据!')
.then(function () {
return stopSupplier(stopIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("停用成功");
proxy.$modal.msgSuccess('停用成功');
})
.catch(() => {});
}
@@ -435,13 +363,13 @@ function handleClear() {
// queryParams.value.sourceEnum = undefined;
// queryParams.value.busNo = undefined;
// 清空查询条件
proxy.resetForm("queryRef");
proxy.resetForm('queryRef');
getList();
}
/** 选择条数 */
function handleSelectionChange(selection) {
console.log(selection, "selection");
console.log(selection, 'selection');
// selectedData.value = selection.map((item) => ({ ...item })); // 存储选择的行数据
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
@@ -457,7 +385,7 @@ function reset() {
status: undefined,
statusEnum: undefined,
};
proxy.resetForm("supplierRef");
proxy.resetForm('supplierRef');
}
/** 取消按钮 */
function cancel() {
@@ -468,34 +396,34 @@ function cancel() {
function handleAdd() {
reset();
open.value = true;
title.value = "新增";
title.value = '新增';
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
console.log(row, "row");
console.log(row, 'row');
form.value = JSON.parse(JSON.stringify(row));
form.value.activeFlag == 1 ? (form.value.activeFlag = true) : (form.value.activeFlag = false); //是否为活性
// console.log(form.value.ty, "form.value");
open.value = true;
title.value = "厂商/产地编辑";
title.value = '厂商/产地编辑';
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["supplierRef"].validate((valid) => {
proxy.$refs['supplierRef'].validate((valid) => {
if (valid) {
form.value.activeFlag == true ? (form.value.activeFlag = 1) : (form.value.activeFlag = 0); //是否为活性
console.log(form.value, "*****************");
console.log(form.value, '*****************');
if (form.value.id != undefined) {
console.log(form.value, "editSupplier");
console.log(form.value, 'editSupplier');
editSupplier(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
proxy.$modal.msgSuccess('修改成功');
open.value = false;
getList();
});
} else {
addSupplier(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
proxy.$modal.msgSuccess('新增成功');
open.value = false;
getList();
});
@@ -507,10 +435,10 @@ function submitForm() {
/** 详细按钮操作 */
function handleView(row) {
reset();
title.value = "查看";
title.value = '查看';
open.value = true;
getSupplierOne(row.id).then((response) => {
console.log(response, "responsebbbb", row.id);
console.log(response, 'responsebbbb', row.id);
form.value = response.data;
});
}
@@ -523,4 +451,4 @@ getDeptTree();
display: flex;
align-items: center;
}
</style>
</style>

View File

@@ -753,6 +753,7 @@ const transformFormData = (form) => {
price,
description,
ybType,
ybNo,
title,
comment,
practitionerId,
@@ -769,6 +770,7 @@ const transformFormData = (form) => {
// locationId,
name,
contact,
ybNo,
appointmentRequiredFlag,
extraDetails,
comment,
@@ -782,6 +784,7 @@ const transformFormData = (form) => {
description,
typeCode: cwTypeCode,
ybType,
ybNo,
price,
},
};
@@ -807,6 +810,7 @@ const transformFormEditData = (form) => {
price,
description,
ybType,
ybNo,
title,
comment,
practitionerId,
@@ -823,6 +827,7 @@ const transformFormEditData = (form) => {
// locationId,
name,
contact,
ybNo,
appointmentRequiredFlag,
extraDetails,
comment,

View File

@@ -1,40 +1,47 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询器材目录列表
export function getDeviceList(query) {
console.log(query,'aaaaa')
return request({
export function getDeviceList (query) {
return request ({
url: '/data-dictionary/device/information-page',
method: 'get',
params: query
})
params: query,
});
}
// 查询器材目录详细
export function getDeviceOne(id) {
return request({
export function getDeviceOne (id) {
return request ({
url: '/data-dictionary/device/information-one',
method: 'get',
params: { id } // 确保参数正确传递
})
params: {id}, // 确保参数正确传递
});
}
// 校验器材是否可以编辑
export function validateEditDevice (deviceId) {
return request ({
url: '/data-dictionary/device/validate-edit',
method: 'get',
params: {deviceId}, // 确保参数正确传递
});
}
// 新增器材目录
export function addDevice(data) {
return request({
export function addDevice (data) {
return request ({
url: '/data-dictionary/device/information',
method: 'post',
data: data
})
data: data,
});
}
// 修改器材目录
export function editDevice(data) {
return request({
export function editDevice (data) {
return request ({
url: '/data-dictionary/device/information',
method: 'put',
data: data
})
data: data,
});
}
// // 删除器材目录
@@ -46,56 +53,56 @@ export function editDevice(data) {
// }
// 器材目录分类查询
export function getDiseaseTreatmentInit() {
return request({
export function getDiseaseTreatmentInit () {
return request ({
url: '/data-dictionary/device/init',
method: 'get'
})
method: 'get',
});
}
// 停用病种目录
export function stopDevice(ids) {
console.log(ids)
return request({
export function stopDevice (ids) {
console.log (ids);
return request ({
url: '/data-dictionary/device/information-stop',
method: 'put',
data: ids
})
data: ids,
});
}
// 启用病种目录
export function startDevice(ids) {
console.log(ids)
return request({
export function startDevice (ids) {
console.log (ids);
return request ({
url: '/data-dictionary/device/information-start',
method: 'put',
data: ids
})
data: ids,
});
}
// 查询部门树形数据
export function deptTreeSelect(queryParams) {
return request({
export function deptTreeSelect (queryParams) {
return request ({
url: '/base-data-manage/organization/organization',
method: 'get',
params: queryParams
})
params: queryParams,
});
}
// 查询地点树形数据
export function locationTreeSelect(queryParams) {
return request({
export function locationTreeSelect (queryParams) {
return request ({
url: '/base-data-manage/location/location-page-tree',
method: 'get',
params: queryParams
})
params: queryParams,
});
}
// 获取医疗服务项目目录
export function getYbDeviceList(queryParams) {
return request({
export function getYbDeviceList (queryParams) {
return request ({
url: '/catalog/page',
method: 'get',
params: queryParams
})
params: queryParams,
});
}

View File

@@ -22,12 +22,12 @@
<el-row :gutter="24">
<el-col :span="8" v-if="form.id != undefined">
<el-form-item label="编号" prop="busNo">
<el-input v-model="form.busNo" placeholder="请输入编码" disabled />
<el-input v-model="form.busNo" clearable placeholder="请输入编码" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="器材名称" prop="name">
<el-input v-model="form.name" placeholder="请输入器材名称" />
<el-input v-model="form.name" clearable placeholder="请输入器材名称" />
</el-form-item>
</el-col>
<el-col :span="8">
@@ -35,10 +35,10 @@
<el-tree-select
v-model="form.categoryCode"
:data="deviceCategories"
filterable
:props="{ value: 'value', label: 'info', children: 'children' }"
:disabled="false"
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
value-key="value"
placeholder=""
check-strictly
clearable
/>
@@ -48,7 +48,7 @@
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="器材种类" prop="typeCode">
<el-select v-model="form.typeCode" placeholder="请选择" clearable>
<el-select v-model="form.typeCode" clearable filterable>
<el-option
v-for="dict in device_type_code"
:key="dict.value"
@@ -68,6 +68,7 @@
placeholder="请选择提供部门"
check-strictly
clearable
filterable
/>
</el-form-item>
</el-col>
@@ -81,6 +82,7 @@
placeholder="请选择地点"
check-strictly
clearable
filterable
/>
</el-form-item>
</el-col>
@@ -90,9 +92,10 @@
<el-form-item label="包装单位" prop="unitCode">
<el-select
v-model="form.unitCode"
placeholder="请选择"
clearable
filterable
@change="handleUnitCodeChange"
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
>
<el-option
v-for="dict in unit_code"
@@ -105,7 +108,7 @@
</el-col>
<el-col :span="8">
<el-form-item label="销售单位" prop="salesUnitCode">
<el-select v-model="form.salesUnitCode" placeholder="请选择" clearable>
<el-select v-model="form.salesUnitCode" clearable filterable>
<el-option
v-for="dict in unit_code"
:key="dict.value"
@@ -117,7 +120,12 @@
</el-col>
<el-col :span="8">
<el-form-item label="最小单位" prop="minUnitCode">
<el-select v-model="form.minUnitCode" placeholder="请选择" clearable>
<el-select
v-model="form.minUnitCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
>
<el-option
v-for="dict in unit_code"
:key="dict.value"
@@ -131,95 +139,70 @@
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="包装规格" prop="size">
<el-input v-model="form.size" placeholder="" />
<el-input
v-model="form.size"
clearable
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="拆零比" prop="partPercent">
<el-input-number v-model="form.partPercent" controls-position="right" placeholder="" :min="1"/>
<el-input-number
v-model="form.partPercent"
controls-position="right"
:min="1"
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品型号" prop="modelNumber">
<el-input v-model="form.modelNumber" placeholder="" />
<el-input v-model="form.modelNumber" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="批准文号" prop="approvalNumber">
<el-input v-model="form.approvalNumber" placeholder="" />
<el-input v-model="form.approvalNumber" clearable />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="医保编码" prop="ybNo">
<el-input v-model="form.ybNo" placeholder="" />
<el-input v-model="form.ybNo" clearable />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="医药机构目录编码" prop="ybOrgNo" label-width="125px">
<el-input v-model="form.ybOrgNo" placeholder="" />
<el-input v-model="form.ybOrgNo" clearable />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="主要成分" prop="substanceText">
<el-input v-model="form.substanceText" placeholder="" />
<el-input v-model="form.substanceText" clearable />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="警戒线最低值(常规单位)" prop="itemMinQuantity" label-width="180px">
<el-input-number
v-model="form.itemMinQuantity"
placeholder=""
controls-position="right"
:min="0"
/>
<el-input-number v-model="form.itemMinQuantity" controls-position="right" :min="0" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="警戒线最高值(常规单位)" prop="itemMaxQuantity" label-width="180px">
<el-input-number
v-model="form.itemMaxQuantity"
placeholder=""
controls-position="right"
:min="0"
/>
<el-input-number v-model="form.itemMaxQuantity" controls-position="right" :min="0" />
</el-form-item>
</el-col>
<!-- <el-col :span="8">
<el-form-item label="器材版本" prop="version">
<el-input v-model="form.version" placeholder="" />
</el-form-item>
</el-col> -->
</el-row>
<el-row :gutter="24">
<!-- <el-col :span="8">
<el-form-item label="状态" prop="statusEnum">
<el-select
v-model="form.statusEnum"
placeholder="请选择"
clearable
>
<el-option
v-for="dict in statusFlagOptions"
:key="dict.value"
:label="dict.info"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col> -->
</el-row>
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="生产厂家" prop="manufacturerText">
<el-input v-model="form.manufacturerText" placeholder="" />
<el-input v-model="form.manufacturerText" clearable />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="供应商" prop="supplyId">
<el-select v-model="form.supplyId" placeholder="" clearable style="width: 150px">
<el-select v-model="form.supplyId" filterable clearable style="width: 150px">
<el-option
v-for="supplier in supplierListOptions"
:key="supplier.value"
@@ -255,7 +238,12 @@
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="财务类型" prop="itemTypeCode">
<el-select v-model="form.itemTypeCode" clearable>
<el-select
v-model="form.itemTypeCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
>
<el-option
v-for="category in fin_type_code"
:key="category.value"
@@ -271,7 +259,9 @@
v-model="form.ybType"
placeholder="医保类别"
clearable
filterable
style="width: 240px"
:disabled="form.isEditInfoDisable === 1"
>
<el-option
v-for="dict in med_chrgitm_type"
@@ -284,7 +274,7 @@
</el-col>
<el-col :span="8">
<el-form-item label="适用范围" prop="jurisdiction">
<el-input v-model="form.jurisdiction" placeholder="" />
<el-input v-model="form.jurisdiction" clearable />
</el-form-item>
</el-col>
</el-row>
@@ -293,20 +283,23 @@
<el-form-item label="购入价" prop="purchasePrice">
<el-input
v-model="form.purchasePrice"
placeholder=""
:disabled="false"
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
@input="updatePrices"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="零售价" prop="retailPrice">
<el-input v-model="form.retailPrice" placeholder="" :disabled="false" />
<el-input
v-model="form.retailPrice"
clearable
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="最高零售价" prop="maximumRetailPrice">
<el-input v-model="form.maximumRetailPrice" placeholder="" :disabled="false" />
<el-input v-model="form.maximumRetailPrice" clearable :disabled="false" />
</el-form-item>
</el-col>
</el-row>
@@ -317,7 +310,9 @@
v-model="form.chrgitmLv"
placeholder="医保等级"
clearable
filterable
style="width: 240px"
:disabled="form.isEditInfoDisable === 1"
>
<el-option
v-for="dict in chrgitm_lv"
@@ -336,7 +331,7 @@
v-model="form.description"
:autosize="{ minRows: 4, maxRows: 10 }"
type="textarea"
placeholder=""
clearable
/>
</el-form-item>
</el-col>
@@ -376,52 +371,27 @@ const supplierListOptions = ref([]); // 供应商列表
const data = reactive({
form: {},
rules: {
// busNo: [{ required: true, message: "编码不能为空", trigger: "blur" }],
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
// pyStr: [{ required: true, message: "拼音不能为空", trigger: "blur" }],
// wbStr: [{ required: true, message: "五笔拼音不能为空", trigger: "blur" }],
categoryCode: [{ required: true, message: '器材分类不能为空', trigger: 'blur' }],
//typeCode: [{ required: true, message: '器材种类不能为空', trigger: 'blur' }],
unitCode: [{ required: true, message: '包装单位不能为空', trigger: 'blur' }],
size: [{ required: true, message: '包装规格不能为空', trigger: 'blur' }],
partPercent: [{ required: true, message: '拆零比不能为空', trigger: 'blur' }],
minUnitCode: [{ required: true, message: '最小使用单位不能为空', trigger: 'blur' }],
// modelNumber: [{ required: true, message: '产品型号不能为空', trigger: 'blur' }],
// hvcmFlag: [
// { required: true, message: "高值器材标志不能为空", trigger: "blur" },
// ],
itemMinQuantity: [{ required: true, message: '警戒线最低值不能为空', trigger: 'blur' }],
itemMaxQuantity: [{ required: true, message: '警戒线最高值不能为空', trigger: 'blur' }],
salesUnitCode: [{ required: true, message: '销售单位不能为空', trigger: 'blur' }],
//approvalNumber: [{ required: true, message: '批准文号不能为空', trigger: 'blur' }],
// ybFlag: [{ required: true, message: "医保标记不能为空", trigger: "blur" }],
// // ybNo: [{ required: true, message: "医保编码不能为空", trigger: "blur" }],
// ybMatchFlag: [
// { required: true, message: "医保对码标记不能为空", trigger: "blur" },
// ],
// statusEnum: [{ required: true, message: "状态不能为空", trigger: "blur" }],
manufacturerId: [{ required: true, message: '生产厂家不能为空', trigger: 'blur' }],
// supplyId: [{ required: true, message: '供应商不能为空', trigger: 'blur' }],
// description: [{ required: true, message: "说明不能为空", trigger: "blur" }],
//jurisdiction: [{ required: true, message: '适用范围不能为空', trigger: 'blur' }],
ruleId: [{ required: true, message: '执行科室不能为空', trigger: 'blur' }],
// version: [{ required: true, message: "器材版本不能为空", trigger: "blur" }],
// substanceText: [{ required: true, message: "主要成分不能为空", trigger: "blur" }],
// allergenFlag: [
// { required: true, message: "过敏标记不能为空", trigger: "blur" },
// ],
// orgId: [{ required: true, message: '提供部门不能为空', trigger: 'blur' }],
locationId: [{ required: true, message: '地点不能为空', trigger: 'blur' }],
purchasePrice: [{ required: true, message: '购入价不能为空', trigger: 'blur' }],
retailPrice: [{ required: true, message: '零售价不能为空', trigger: 'blur' }],
//maximumRetailPrice: [{ required: true, message: '最高零售价不能为空', trigger: 'blur' }],
ybType: [{ required: true, message: '医保类型不能为空', trigger: 'blur' }],
chrgitmLv: [{ required: true, message: '医保等级不能为空', trigger: 'blur' }],
itemTypeCode: [{ required: true, message: '财务类型不能为空', trigger: 'blur' }],
},
});
const { queryParams, form, rules } = toRefs(data);
const { form, rules } = toRefs(data);
const props = defineProps({
item: {
@@ -465,8 +435,8 @@ function show() {
supplierListOptions.value = props.supplierListOptions;
form.value.partPercent = 1;
form.value.itemTypeCode = '2005';
form.value.ybType = '8';
console.log(props, '22222', title.value, props.deviceCategories);
form.value.ybType = '08';
form.value.size = '-';
getDeptTree();
getLocationTree();
visible.value = true;
@@ -476,21 +446,16 @@ function setValue(row) {
form.value = {
name: formatValue(row.consumableName), //医疗服务项目名称
ybNo: formatValue(row.medicalCatalogCode), // 医保编码
// modelNumber: formatValue(row.productModel), // 产品型号
modelNumber: formatValue(row.specification), // 规格
manufacturerText: formatValue(row.manufacturerName), // 厂家名称
partPercent: 1,
itemMinQuantity: formatValue(row.itemMinQuantity), // 警戒线最低值
itemMaxQuantity: formatValue(row.itemMaxQuantity), // 警戒线最高值
// chrgitmLv: formatValue(
// row.insuranceClass == '甲' ? '1' : row.insuranceClass == '乙' ? '2' : '3'
// ), // 医保等级
};
}
/** 查询部门下拉树结构 */
function getDeptTree() {
deptTreeSelect().then((response) => {
console.log(response, 'response查询部门下拉树结构');
deptOptions.value = response.data.records;
});
}
@@ -538,13 +503,11 @@ function reset() {
ybNo: undefined, // 医保编码
ybOrgNo: undefined, //医药机构目录编码
ybMatchFlag: undefined, // 医保对码标记
// statusEnum: undefined, // 状态(包括 1预置2启用3停用
manufacturerId: undefined, // 厂家编码
supplyId: undefined, // 供应商编码
description: undefined, // 说明
jurisdiction: undefined, // 适用范围
ruleId: undefined, // 执行科室
// version: undefined, // 器材版本
substanceText: undefined, // 主要成分
allergenFlag: undefined, // 过敏标记
orgId: undefined, // 科室ID
@@ -567,7 +530,6 @@ function submitForm() {
form.value.ybFlag ? (form.value.ybFlag = 1) : (form.value.ybFlag = 0);
form.value.ybMatchFlag ? (form.value.ybMatchFlag = 1) : (form.value.ybMatchFlag = 0);
form.value.allergenFlag ? (form.value.allergenFlag = 1) : (form.value.allergenFlag = 0);
console.log(form.value, 'form.value');
if (form.value.id != undefined) {
editDevice(form.value).then((response) => {
// 触发自定义事件,并传递数据给父组件

View File

@@ -5,49 +5,81 @@
<el-col :span="4" :xs="24">
<div class="head-title">器材目录</div>
<div class="head-container">
<el-tree :data="deviceCategories" :props="{ label: 'info', children: 'children' }"
:expand-on-click-node="false" :filter-node-method="filterNode" ref="treeRef" node-key="id" highlight-current
default-expand-all @node-click="handleNodeClick" />
<el-tree
:data="deviceCategories"
:props="{ label: 'info', children: 'children' }"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="treeRef"
node-key="id"
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
</div>
</el-col>
<!--器材目录-->
<el-col :span="20" :xs="24">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-row :gutter="24">
<!-- <el-col :span="6"> -->
<el-form-item label="项目名" prop="searchKey" label-width="55">
<el-input v-model="queryParams.searchKey" placeholder="品名/商品名/英文品名/编码/拼音" clearable style="width: 220px"
@keyup.enter="handleQuery" />
<el-input
v-model="queryParams.searchKey"
placeholder="品名/商品名/英文品名/编码/拼音"
clearable
style="width: 220px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<!-- </el-col> -->
<!-- <el-col :span="5"> -->
<el-form-item label="状态" prop="statusEnum" label-width="50">
<el-select v-model="queryParams.statusEnum" clearable>
<el-option v-for="status in statusFlagOptions" :key="status.value" :label="status.info"
:value="status.value" />
<el-option
v-for="status in statusFlagOptions"
:key="status.value"
:label="status.info"
:value="status.value"
/>
</el-select>
</el-form-item>
<!-- </el-col> -->
<!-- <el-col :span="5"> -->
<el-form-item label="医保是否对码" prop="ybMatchFlag" label-width="100">
<el-select v-model="queryParams.ybMatchFlag" placeholder="" clearable>
<el-option v-for="item in statusYBWeatherOptions" :key="item.value" :label="item.info"
:value="item.value" />
<el-option
v-for="item in statusYBWeatherOptions"
:key="item.value"
:label="item.info"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- </el-col> -->
</el-row>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="openAddDevice">添加新项目</el-button>
<el-button type="primary" plain icon="Plus" @click="openAddDevice"
>添加新项目</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Remove" :disabled="multiple" @click="handleClose">停用</el-button>
<el-button type="danger" plain icon="Remove" :disabled="multiple" @click="handleClose"
>停用</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="CirclePlus" :disabled="multiple" @click="handleStart">启用</el-button>
<el-button
type="success"
plain
icon="CirclePlus"
:disabled="multiple"
@click="handleStart"
>启用</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Upload" @click="handleImport">导入</el-button>
@@ -66,50 +98,170 @@
</el-col> -->
</el-row>
<el-table
v-loading="loading"
:data="deviceList"
@selection-change="handleSelectionChange"
width="90%"
>
<el-table v-loading="loading" :data="deviceList" @selection-change="handleSelectionChange" width="90%" border resizable-column>
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="编码" align="center" key="busNo" prop="busNo" :show-overflow-tooltip="true" />
<el-table-column label="器材名称" align="center" key="name" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="拼音" align="center" key="pyStr" prop="pyStr" :show-overflow-tooltip="true" />
<el-table-column label="器材分类" align="center" key="categoryCode_dictText" prop="categoryCode_dictText"
:show-overflow-tooltip="true" width="100" />
<el-table-column label="器材种类" align="center" key="typeCode_dictText" prop="typeCode_dictText"
:show-overflow-tooltip="true" width="50" />
<el-table-column label="包装单位" align="center" key="unitCode_dictText" prop="unitCode_dictText"
:show-overflow-tooltip="true" />
<el-table-column label="包装规格" align="center" key="size" prop="size" :show-overflow-tooltip="true" />
<el-table-column label="拆零比" align="center" key="partPercent" prop="partPercent"
:show-overflow-tooltip="true">
<el-table-column
label="编码"
align="center"
key="busNo"
prop="busNo"
:show-overflow-tooltip="true"
width="200"
/>
<el-table-column
label="器材名称"
align="center"
key="name"
prop="name"
:show-overflow-tooltip="true"
width="200"
/>
<!-- <el-table-column
label="拼音"
align="center"
key="pyStr"
prop="pyStr"
:show-overflow-tooltip="true"
/> -->
<el-table-column
label="器材分类"
align="center"
key="categoryCode_dictText"
prop="categoryCode_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<!-- <el-table-column
label="器材种类"
align="center"
key="typeCode_dictText"
prop="typeCode_dictText"
:show-overflow-tooltip="true"
width="50"
/> -->
<el-table-column
label="包装单位"
align="center"
key="unitCode_dictText"
prop="unitCode_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<el-table-column
label="包装规格"
align="center"
key="size"
prop="size"
width="200"
:show-overflow-tooltip="true"
/>
<el-table-column
label="拆零比"
align="center"
key="partPercent"
prop="partPercent"
:show-overflow-tooltip="true"
>
<template #default="scope">
{{ scope.row.partPercent !== null && scope.row.partPercent !== undefined ? scope.row.partPercent : 1 }}
{{
scope.row.partPercent !== null && scope.row.partPercent !== undefined
? scope.row.partPercent
: 1
}}
</template>
</el-table-column>
<el-table-column label="最小使用单位" align="center" key="minUnitCode_dictText" prop="minUnitCode_dictText"
:show-overflow-tooltip="true" />
<el-table-column label="所属科室" align="center" key="orgId_dictText" prop="orgId_dictText"
:show-overflow-tooltip="true" />
<el-table-column label="所在位置" align="center" key="locationId_dictText" prop="locationId_dictText"
:show-overflow-tooltip="true" />
<el-table-column label="产品型号" align="center" key="modelNumber" prop="modelNumber"
:show-overflow-tooltip="true" />
<el-table-column label="高值器材标志" align="center" key="hvcmFlag_enumText" prop="hvcmFlag_enumText"
:show-overflow-tooltip="true" />
<el-table-column
label="最小使用单位"
align="center"
key="minUnitCode_dictText"
prop="minUnitCode_dictText"
:show-overflow-tooltip="true"
width="120"
/>
<!-- <el-table-column
label="所属科室"
align="center"
key="orgId_dictText"
prop="orgId_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="所在位置"
align="center"
key="locationId_dictText"
prop="locationId_dictText"
:show-overflow-tooltip="true"
/> -->
<!-- <el-table-column
label="产品型号"
align="center"
key="modelNumber"
prop="modelNumber"
:show-overflow-tooltip="true"
/> -->
<el-table-column label="销售单位" align="center" key="salesUnitCode_dictText" prop="salesUnitCode_dictText"
:show-overflow-tooltip="true" width="100" />
<el-table-column label="批准文号" align="center" key="approvalNumber" prop="approvalNumber"
:show-overflow-tooltip="true" />
<el-table-column label="医保标记" align="center" key="ybFlag_enumText" prop="ybFlag_enumText"
:show-overflow-tooltip="true" width="110" />
<el-table-column label="医保编码" align="center" key="ybNo" prop="ybNo" :show-overflow-tooltip="true"
width="110" />
<el-table-column label="医药机构目录编码" align="center" key="ybOrgNo" prop="ybOrgNo" :show-overflow-tooltip="true"
width="130" />
<el-table-column label="医保对码标记" align="center" key="ybMatchFlag_enumText" prop="ybMatchFlag_enumText"
:show-overflow-tooltip="true" width="105" />
<el-table-column label="状态" align="center" key="statusEnum_enumText" prop="statusEnum_enumText"
:show-overflow-tooltip="true" width="90" />
<el-table-column
label="销售单位"
align="center"
key="salesUnitCode_dictText"
prop="salesUnitCode_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<!-- <el-table-column
label="批准文号"
align="center"
key="approvalNumber"
prop="approvalNumber"
:show-overflow-tooltip="true"
/> -->
<!-- <el-table-column
label="医保标记"
align="center"
key="ybFlag_enumText"
prop="ybFlag_enumText"
:show-overflow-tooltip="true"
width="110"
/> -->
<el-table-column
label="医保编码"
align="center"
key="ybNo"
prop="ybNo"
:show-overflow-tooltip="true"
width="110"
/>
<el-table-column
label="医药机构目录编码"
align="center"
key="ybOrgNo"
prop="ybOrgNo"
:show-overflow-tooltip="true"
width="130"
/>
<!-- <el-table-column
label="医保对码标记"
align="center"
key="ybMatchFlag_enumText"
prop="ybMatchFlag_enumText"
:show-overflow-tooltip="true"
width="105"
/> -->
<el-table-column
label="状态"
align="center"
key="statusEnum_enumText"
prop="statusEnum_enumText"
:show-overflow-tooltip="true"
width="90"
/>
<!-- <el-table-column
label="生产厂家"
align="center"
@@ -118,59 +270,165 @@
:show-overflow-tooltip="true"
width="90"
/> -->
<el-table-column label="生产厂家" align="center" key="manufacturerText" prop="manufacturerText"
:show-overflow-tooltip="true" width="90" />
<el-table-column label="供应商" align="center" key="supplyId_dictText" prop="supplyId_dictText"
:show-overflow-tooltip="true" width="110" />
<el-table-column label="说明" align="center" key="description" prop="description"
:show-overflow-tooltip="true" />
<el-table-column label="适用范围" align="center" key="jurisdiction" prop="jurisdiction"
:show-overflow-tooltip="true" width="120" />
<el-table-column label="器材版本" align="center" key="version" prop="version" :show-overflow-tooltip="true"
width="120" />
<el-table-column label="主要成分" align="center" key="substanceText" prop="substanceText"
:show-overflow-tooltip="true" />
<el-table-column label="过敏标记" align="center" key="allergenFlag_enumText" prop="allergenFlag_enumText"
:show-overflow-tooltip="true" width="90" />
<el-table-column label="售价" align="center" key="retailPrice" prop="retailPrice" :show-overflow-tooltip="true"
width="90" />
<el-table-column label="财务类别" align="center" key="itemTypeCode_dictText" prop="itemTypeCode_dictText"
:show-overflow-tooltip="true" width="90" />
<el-table-column label="医保类别" align="center" key="ybType_dictText" prop="ybType_dictText"
:show-overflow-tooltip="true" width="90" />
<el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width" fixed="right">
<el-table-column
label="生产厂家"
align="center"
key="manufacturerText"
prop="manufacturerText"
:show-overflow-tooltip="true"
width="200"
/>
<!-- <el-table-column
label="供应商"
align="center"
key="supplyId_dictText"
prop="supplyId_dictText"
:show-overflow-tooltip="true"
width="110"
/>
<el-table-column
label="说明"
align="center"
key="description"
prop="description"
:show-overflow-tooltip="true"
/>
<el-table-column
label="适用范围"
align="center"
key="jurisdiction"
prop="jurisdiction"
:show-overflow-tooltip="true"
width="120"
/>
<el-table-column
label="器材版本"
align="center"
key="version"
prop="version"
:show-overflow-tooltip="true"
width="120"
/>
<el-table-column
label="主要成分"
align="center"
key="substanceText"
prop="substanceText"
:show-overflow-tooltip="true"
/> -->
<!-- <el-table-column
label="过敏标记"
align="center"
key="allergenFlag_enumText"
prop="allergenFlag_enumText"
:show-overflow-tooltip="true"
width="90"
/> -->
<el-table-column
label="售价"
align="center"
key="retailPrice"
prop="retailPrice"
:show-overflow-tooltip="true"
width="90"
/>
<el-table-column
label="财务类别"
align="center"
key="itemTypeCode_dictText"
prop="itemTypeCode_dictText"
:show-overflow-tooltip="true"
width="90"
/>
<el-table-column
label="高值器材标志"
align="center"
key="hvcmFlag_enumText"
prop="hvcmFlag_enumText"
:show-overflow-tooltip="true"
width="120"
/>
<!-- <el-table-column
label="医保类别"
align="center"
key="ybType_dictText"
prop="ybType_dictText"
:show-overflow-tooltip="true"
width="90"
/> -->
<el-table-column
label="操作"
align="center"
width="150"
class-name="small-padding fixed-width"
fixed="right"
>
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="openEditDevice(scope.row)">编辑</el-button>
<el-button link type="primary" icon="Edit" @click="openEditDevice(scope.row)">
编辑
</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize" @pagination="getList" />
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</el-col>
</el-row>
<device-dialog ref="deviceRef" :title="title" :item="currentData" :currentCategoryEnum="currentCategoryEnum"
:deviceCategories="deviceCategorieList" :statusFlagOptions="statusFlagOptions"
:supplierListOptions="supplierListOptions" @submit="getList()" @ybDialog="() => {
proxy.$refs['deviceYbRef'].show()
}" />
<DeviceYbDialog ref="deviceYbRef" @selectDevice="
(row) => {
proxy.$refs['deviceRef'].setValue(row);
}
" />
<device-dialog
ref="deviceRef"
:title="title"
:item="currentData"
:currentCategoryEnum="currentCategoryEnum"
:deviceCategories="deviceCategorieList"
:statusFlagOptions="statusFlagOptions"
:supplierListOptions="supplierListOptions"
@submit="getList()"
@ybDialog="
() => {
proxy.$refs['deviceYbRef'].show();
}
"
/>
<DeviceYbDialog
ref="deviceYbRef"
@selectDevice="
(row) => {
proxy.$refs['deviceRef'].setValue(row);
}
"
/>
<!-- 器材目录导入对话框 -->
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
<el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip text-center">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
@click="importTemplate">下载模板</el-link>
<el-link
type="primary"
:underline="false"
style="font-size: 12px; vertical-align: baseline"
@click="importTemplate"
>下载模板</el-link
>
</div>
</template>
</el-upload>
@@ -185,17 +443,18 @@
</template>
<script setup name="Device">
import { getToken } from "@/utils/auth";
import { getToken } from '@/utils/auth';
import {
getDeviceList,
stopDevice,
startDevice,
getDiseaseTreatmentInit,
getDeviceOne,
} from "./components/device";
import deviceDialog from "./components/deviceDialog";
import DeviceYbDialog from "./components/deviceYbDialog";
import { nextTick } from "vue";
validateEditDevice,
} from './components/device';
import deviceDialog from './components/deviceDialog';
import DeviceYbDialog from './components/deviceYbDialog';
import { nextTick } from 'vue';
const { proxy } = getCurrentInstance();
@@ -206,7 +465,7 @@ const ids = ref([]); // 存储选择的行数据
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const title = ref('');
const deviceCategories = ref(undefined);
const deviceCategorieList = ref(undefined);
const statusFlagOptions = ref(undefined);
@@ -216,22 +475,22 @@ const supplierListOptions = ref(undefined);
const currentData = ref({});
// 使用 ref 定义当前查看器材数据
const viewData = ref({});
const currentCategoryEnum = ref("");
const currentCategoryEnum = ref('');
/*** 器材目录导入参数 */
const upload = reactive({
// 是否显示弹出层
open: false,
// 弹出层标题
title: "",
title: '',
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
headers: { Authorization: 'Bearer ' + getToken() },
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + "/data-dictionary/device/import-data"
url: import.meta.env.VITE_APP_BASE_API + '/data-dictionary/device/import-data',
});
const data = reactive({
@@ -260,15 +519,15 @@ const filterNode = (value, data) => {
/** 器材目录分类查询下拉树结构 */
function getDiseaseTreatmentList() {
getDiseaseTreatmentInit().then((response) => {
console.log(response, "response器材目录分类查询下拉树结构");
deviceCategories.value = JSON.parse(JSON.stringify(response.data.deviceCategories)).sort((a, b) => {
return parseInt(a.value) - parseInt(b.value);
});
deviceCategories.value.push({ info: "全部", value: "" });
deviceCategories.value = JSON.parse(JSON.stringify(response.data.deviceCategories)).sort(
(a, b) => {
return parseInt(a.value) - parseInt(b.value);
}
);
deviceCategories.value.push({ info: '全部', value: '' });
deviceCategorieList.value = response.data.deviceCategories.sort((a, b) => {
return parseInt(a.value) - parseInt(b.value);
});
console.log(deviceCategorieList.value, "deviceCategorieList");
statusFlagOptions.value = response.data.statusFlagOptions;
statusYBWeatherOptions.value = response.data.statusYBWeatherOptions;
supplierListOptions.value = response.data.supplierListOptions;
@@ -281,7 +540,6 @@ function getList() {
loading.value = false;
deviceList.value = res.data.records;
total.value = res.data.total;
console.log(deviceList.value, "getList", total.value);
});
}
/** 节点单击事件 */
@@ -301,34 +559,34 @@ function handleStart() {
const stardIds = ids.value;
// selectedData
proxy.$modal
.confirm("是否确定启用数据!")
.confirm('是否确定启用数据!')
.then(function () {
return startDevice(stardIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("启用成功");
proxy.$modal.msgSuccess('启用成功');
})
.catch(() => { });
.catch(() => {});
}
/** 停用按钮操作 */
function handleClose() {
const stopIds = ids.value;
proxy.$modal
.confirm("是否确认停用数据!")
.confirm('是否确认停用数据!')
.then(function () {
return stopDevice(stopIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("停用成功");
proxy.$modal.msgSuccess('停用成功');
})
.catch(() => { });
.catch(() => {});
}
/** 导出按钮操作 */
function handleExport() {
proxy.download(
"system/user/export",
'system/user/export',
{
...queryParams.value,
},
@@ -343,7 +601,11 @@ function handleImport() {
}
/** 下载模板操作 */
function importTemplate() {
proxy.download('/data-dictionary/device/import-template', {}, `device_template_${new Date().getTime()}.xlsx`);
proxy.download(
'/data-dictionary/device/import-template',
{},
`device_template_${new Date().getTime()}.xlsx`
);
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
@@ -356,8 +618,8 @@ const handleFileSuccess = (response, file, fileList) => {
proxy.$refs['uploadRef'].handleRemove(file);
proxy.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
'</div>',
response.msg +
'</div>',
'导入结果',
{ dangerouslyUseHTMLString: true }
);
@@ -370,7 +632,6 @@ function submitFileForm() {
/** 选择条数 */
function handleSelectionChange(selection) {
console.log(selection, "selection");
// selectedData.value = selection.map((item) => ({ ...item })); // 存储选择的行数据
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
@@ -379,22 +640,29 @@ function handleSelectionChange(selection) {
/** 打开新增弹窗 */
function openAddDevice() {
// if (!currentCategoryEnum.value) {
// return proxy.$modal.msgError("请选择器材目录分类");
// }
console.log("打开新增弹窗");
title.value = "新增";
title.value = '新增';
nextTick(() => {
proxy.$refs.deviceRef.show();
});
}
const isEditInfoDisable = ref(0);
/** 打开编辑弹窗 */
function openEditDevice(row) {
currentData.value = {};
console.log("打开编辑弹窗");
validateEditDevice(row.id).then((res) => {
// res.data == 1 医生开过该耗材,不可编辑
// res.data == 2 该耗材已经入库过,不可编辑
isEditInfoDisable.value = res.data;
getDeviceInfo(row);
});
}
// 根据耗材id 查询耗材信息
function getDeviceInfo(row) {
getDeviceOne(row.id).then((response) => {
console.log(response, "currentDataform");
currentData.value = response.data;
currentData.value = {
...response.data,
// 禁用编辑
isEditInfoDisable: isEditInfoDisable.value,
};
if (currentData.value) {
currentData.value.hvcmFlag == 1
? (currentData.value.hvcmFlag = true)
@@ -409,9 +677,9 @@ function openEditDevice(row) {
? (currentData.value.allergenFlag = true)
: (currentData.value.allergenFlag = false);
}
title.value = "编辑";
title.value = '编辑';
nextTick(() => {
proxy.$refs["deviceRef"].edit();
proxy.$refs['deviceRef'].edit();
});
getList();
});

View File

@@ -74,7 +74,12 @@
</el-col>
<el-col :span="8">
<el-form-item label="目录分类" prop="categoryCode">
<el-select v-model="form.categoryCode" clearable filterable :disabled="false">
<el-select
v-model="form.categoryCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 1"
>
<el-option
v-for="category in activity_category_code"
:key="category.value"
@@ -96,18 +101,6 @@
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="8">
<el-form-item label="状态" prop="statusEnum">
<el-select v-model="form.statusEnum" clearable>
<el-option
v-for="status in statusFlagOptions"
:key="status.value"
:label="status.info"
:value="status.value"
/>
</el-select>
</el-form-item>
</el-col> -->
</el-row>
<el-row :gutter="24">
<el-col :span="8">
@@ -136,6 +129,7 @@
clearable
filterable
style="width: 240px"
:disabled="form.isEditInfoDisable === 1"
>
<el-option
v-for="dict in med_chrgitm_type"
@@ -164,7 +158,7 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="所需标本" prop="specimenCode">
<el-select v-model="form.specimenCode" clearable filterable>
@@ -181,7 +175,13 @@
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="医保等级" prop="chrgitmLv">
<el-select v-model="form.chrgitmLv" placeholder="" clearable filterable>
<el-select
v-model="form.chrgitmLv"
placeholder=""
clearable
filterable
:disabled="form.isEditInfoDisable === 1"
>
<el-option
v-for="item in chrgitm_lv"
:key="item.value"
@@ -191,18 +191,7 @@
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="8">
<el-form-item label="执行科室" prop="ruleId">
<el-select v-model="form.ruleId" placeholder="" clearable>
<el-option
v-for="item in exeOrganizations"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col> -->
<el-col :span="8">
<el-form-item label="使用单位" prop="permittedUnitCode">
<el-select v-model="form.permittedUnitCode" clearable filterable>
@@ -217,7 +206,12 @@
</el-col>
<el-col :span="8">
<el-form-item label="财务类型" prop="itemTypeCode">
<el-select v-model="form.itemTypeCode" clearable filterable>
<el-select
v-model="form.itemTypeCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 1"
>
<el-option
v-for="category in fin_type_code"
:key="category.value"
@@ -229,22 +223,13 @@
</el-col>
</el-row>
<el-row :gutter="24">
<!-- <el-col :span="8">
<el-form-item label="购入价" prop="purchasePrice">
<el-input
v-model="form.purchasePrice"
placeholder=""
:disabled="form.id != undefined"
/>
</el-form-item>
</el-col> -->
<el-col :span="8">
<el-form-item label="零售价" prop="retailPrice">
<el-input
v-model="form.retailPrice"
placeholder=""
:disabled="false"
@input="updatePrices"
:disabled="form.isEditInfoDisable === 1"
/>
</el-form-item>
</el-col>
@@ -268,14 +253,34 @@
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="诊疗子项">
<el-select v-model="item.adviceDefinitionId" placeholder="诊疗子项" filterable>
<el-option
v-for="item in diagnosisTreatmentList"
:key="item.id"
:label="item.name"
:value="item.id"
<div v-if="form.isEditInfoDisable === 0" style="position: relative">
<PopoverList @search="handleSearch" :width="1000" :modelValue="item.name">
<template #popover-content="{}">
<medicineList
@selectRow="(row) => selectRow(row, index)"
:searchKey="medicineSearchKey"
:shouldLoadData="isFirstOpen"
:preloadedData="diagnosisTreatmentList"
/>
</template>
</PopoverList>
<!-- 清空按钮 -->
<el-button
v-if="item.name && item.name !== ''"
type="text"
icon="Delete"
size="small"
@click.stop="clearItem(index)"
style="
position: absolute;
right: 3px;
top: 50%;
transform: translateY(-50%);
color: #909399;
"
/>
</el-select>
</div>
<span v-else>{{ item.name || '' }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
@@ -285,11 +290,22 @@
controls-position="right"
:min="1"
:max="999"
@change="calculateTotalPrice"
:disabled="form.isEditInfoDisable === 1"
/>
</el-form-item>
</el-col>
<el-col :span="8" style="display: flex; align-items: center; padding-bottom: 15px">
<el-button @click="addItem" circle type="priamry" size="small" plain icon="Plus" />
<!-- <div style="margin-right: 20px; font-weight: bold; color: #333">
小计: ¥{{
item.retailPrice && item.childrenRequestNum
? (parseFloat(item.retailPrice) * parseInt(item.childrenRequestNum)).toFixed(
2
)
: '0.00'
}}
</div> -->
<el-button @click="addItem" circle type="primary" size="small" plain icon="Plus" />
<el-button
@click="removeItem(index)"
circle
@@ -313,6 +329,11 @@
/>
</el-form-item>
</el-col>
<el-col :span="8" style="display: flex; align-items: center; justify-content: flex-start">
<div style="font-size: 18px; font-weight: bold; color: #276ef1">
总价: ¥{{ totalPrice }}
</div>
</el-col>
</el-row>
</el-form>
<template #footer v-if="title != '查看'">
@@ -334,7 +355,10 @@ import {
bodyTreeSelect,
locationTreeSelect,
} from './diagnosistreatment';
import PopoverList from '@/components/OpenHis/popoverList/index.vue';
import medicineList from './medicineList.vue';
import MedicineList from '../components/medicineList.vue';
import { getCurrentInstance, nextTick, watch } from 'vue';
const { proxy } = getCurrentInstance();
const { unit_code, med_chrgitm_type, fin_type_code, activity_category_code, chrgitm_lv } =
proxy.useDict(
@@ -348,7 +372,6 @@ const { unit_code, med_chrgitm_type, fin_type_code, activity_category_code, chrg
const title = ref('');
const visible = ref(false);
const emits = defineEmits(['submit']); // 声明自定义事件
const categoryCode = ref('');
const deptOptions = ref(undefined); // 部门树选项
const bodyOptions = ref(undefined); // 身体部位树选项
const locationOptions = ref(undefined); // 地点树选项
@@ -363,26 +386,16 @@ const data = reactive({
rules: {
busNo: [{ required: true, message: "编码不能为空", trigger: "blur" }],
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
// statusEnum: [{ required: true, message: "状态不能为空", trigger: "blur" }],
categoryCode: [{ required: true, message: '诊疗目录不能为空', trigger: 'blur' }],
// typeEnum: [{ required: true, message: '器材种类不能为空', trigger: 'blur' }],
permittedUnitCode: [{ required: true, message: '使用单位不能为空', trigger: 'blur' }],
// ybFlag: [{ required: true, message: "医保标记不能为空", trigger: "blur" }],
// ybMatchFlag: [
// { required: true, message: "医保对码标记不能为空", trigger: "blur" },
// ],
// purchasePrice: [
// { required: true, message: "购入价不能为空", trigger: "blur" },
// ],
retailPrice: [{ required: true, message: '零售价不能为空', trigger: 'blur' }],
// maximumRetailPrice: [{ required: true, message: '最高零售价不能为空', trigger: 'blur' }],
ybType: [{ required: true, message: '医保类型不能为空', trigger: 'blur' }],
chrgitmLv: [{ required: true, message: '医保等级不能为空', trigger: 'blur' }],
itemTypeCode: [{ required: true, message: '财务类型不能为空', trigger: 'blur' }],
},
});
const { queryParams, form, rules } = toRefs(data);
const { form, rules } = toRefs(data);
const props = defineProps({
item: {
@@ -416,17 +429,45 @@ const props = defineProps({
});
// 表单数组,初始一条记录
const treatmentItems = ref([{ adviceDefinitionId: '', childrenRequestNum: 1 }]);
const treatmentItems = ref([
{ adviceDefinitionId: '', childrenRequestNum: 1, name: '', retailPrice: 0 },
]);
const medicineSearchKey = ref('');
const isFirstOpen = ref(true); // 标记是否首次打开弹窗
const totalPrice = ref('0.00'); // 总价
// 计算总价
function calculateTotalPrice() {
try {
let sum = 0;
treatmentItems.value.forEach((item) => {
if (item.adviceDefinitionId && item.retailPrice && item.childrenRequestNum) {
const price = parseFloat(item.retailPrice) || 0;
const count = parseInt(item.childrenRequestNum) || 0;
sum += price * count;
}
});
totalPrice.value = sum.toFixed(2);
} catch (error) {
totalPrice.value = '0.00';
proxy.$modal.msgWarning('价格计算过程中遇到错误,请检查输入数据');
}
}
// 添加表单项
function addItem() {
treatmentItems.value.push({ adviceDefinitionId: '', childrenRequestNum: 1 });
treatmentItems.value.push({ adviceDefinitionId: '', childrenRequestNum: 1, retailPrice: 0 });
// 使用nextTick确保DOM更新后再计算
nextTick(() => {
calculateTotalPrice();
});
}
// 删除表单项
function removeItem(index) {
if (treatmentItems.value.length > 1) {
treatmentItems.value.splice(index, 1);
calculateTotalPrice();
}
}
@@ -438,9 +479,10 @@ function handleImportYb() {
function show() {
reset();
getLocationTree();
getItemList();
getBodyTree();
getDeptTree();
getItemList();
title.value = '';
title.value = props.title;
diagnosisCategoryOptions.value = props.diagnosisCategoryOptions;
@@ -457,9 +499,6 @@ function setValue(row) {
ybNo: formatValue(row.medicalCatalogCode), // 医保编码
busNo: formatValue(row.medicalCatalogCode), // 项目编码使用医保编码
categoryCode: props.currentCategoryEnum,
// chrgitmLv: formatValue(
// row.insuranceClass == '甲' ? '1' : row.insuranceClass == '乙' ? '2' : '3'
// ), // 医保等级
};
}
@@ -467,16 +506,24 @@ function setValue(row) {
function edit() {
reset();
getLocationTree();
getItemList();
getBodyTree();
getDeptTree();
getItemList();
title.value = '';
title.value = props.title;
form.value = props.item;
form.value.chrgitmLv = form.value.chrgitmLv ? form.value.chrgitmLv.toString() : undefined;
treatmentItems.value = props.item.childrenJson
? JSON.parse(props.item.childrenJson)
: [{ adviceDefinitionId: '', childrenRequestNum: 1 }];
// 处理子项数据确保包含retailPrice字段
if (props.item.childrenJson) {
const parsedItems = JSON.parse(props.item.childrenJson);
treatmentItems.value = parsedItems.map((item) => ({
...item,
retailPrice: item.retailPrice || 0,
}));
} else {
treatmentItems.value = [{ adviceDefinitionId: '', childrenRequestNum: 1, retailPrice: 0 }];
}
form.value.permittedUnitCode = form.value.permittedUnitCode
? form.value.permittedUnitCode.toString()
: undefined;
@@ -485,6 +532,11 @@ function edit() {
exeOrganizations.value = props.exeOrganizations;
typeEnumOptions.value = props.typeEnumOptions;
visible.value = true;
// 编辑时计算初始总价
nextTick(() => {
calculateTotalPrice();
});
}
/** 重置操作表单 */
function reset() {
@@ -514,7 +566,8 @@ function reset() {
descriptionText: undefined, // 说明
chrgitmLv: undefined, //医保等级
};
treatmentItems.value = [{ adviceDefinitionId: '', childrenRequestNum: 1 }];
treatmentItems.value = [{ adviceDefinitionId: '', childrenRequestNum: 1, retailPrice: 0 }];
totalPrice.value = '0.00';
proxy.resetForm('diagnosisTreatmentRef');
}
@@ -552,51 +605,74 @@ function submitForm() {
/** 查询部门下拉树结构 */
function getDeptTree() {
deptTreeSelect().then((response) => {
console.log(response, 'response查询部门下拉树结构');
deptOptions.value = response.data.records;
});
}
/** 查询身体部位拉树结构 */
function getBodyTree() {
bodyTreeSelect().then((response) => {
console.log(response, 'response查询身体部位下拉树结构');
bodyOptions.value = response.data.records;
});
}
/** 查询地点下拉树结构 */
function getLocationTree() {
locationTreeSelect({ formList: '8,4,10' }).then((response) => {
console.log(response, 'response查询部门下拉树结构');
locationOptions.value = response.data.records;
});
}
// 获取诊疗子项列表,只筛出无子项的数据
function getItemList() {
getDiagnosisTreatmentList({ statusEnum: 2, pageSize: 1000, pageNo: 1 }).then((response) => {
diagnosisTreatmentList.value = response.data.records.filter((item) => {
return item.childrenJson == null;
});
});
}
/** 取消按钮 */
function cancel() {
visible.value = false;
reset();
}
// 获取诊疗子项列表,只筛出无子项的数据
function getItemList() {
getDiagnosisTreatmentList({ statusEnum: 2, pageSize: 1000, pageNo: 1 }).then((res) => {
diagnosisTreatmentList.value = res.data.records.filter((item) => {
return item.childrenJson == null;
});
});
}
function formatValue(str) {
if (str === null || str === undefined || str === '' || str === 'null') {
return undefined;
}
return str;
}
function handleSearch(value) {
medicineSearchKey.value = value;
}
function selectRow(row, index) {
treatmentItems.value[index].name = row.name;
treatmentItems.value[index].adviceDefinitionId = row.id;
treatmentItems.value[index].retailPrice = row.retailPrice || 0;
calculateTotalPrice();
}
// 清空诊疗子项
function clearItem(index) {
treatmentItems.value[index].name = '';
treatmentItems.value[index].adviceDefinitionId = '';
treatmentItems.value[index].retailPrice = 0;
calculateTotalPrice();
}
// 在这里可以根据购入价来更新零售价
function updatePrices(value) {
form.value.maximumRetailPrice = form.value.retailPrice;
}
// 监听treatmentItems变化实时更新总价
watch(
() => treatmentItems.value,
() => {
calculateTotalPrice();
},
{ deep: true }
);
defineExpose({
show,
edit,

View File

@@ -1,99 +1,106 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询诊疗目录列表
export function getDiagnosisTreatmentList(query) {
return request({
export function getDiagnosisTreatmentList (query) {
return request ({
url: '/data-dictionary/diagnosis-treatment/information-page',
method: 'get',
params: query
})
params: query,
});
}
// 查询诊疗目录详细
export function getDiagnosisTreatmentOne(id) {
return request({
export function getDiagnosisTreatmentOne (id) {
return request ({
url: '/data-dictionary/diagnosis-treatment/information-one/',
method: 'get',
params: { id } // 确保参数正确传递
})
params: {id}, // 确保参数正确传递
});
}
// 查询诊疗目录详细
export function validateActivityEdit (activityId) {
return request ({
url: '/data-dictionary/diagnosis-treatment/validate-edit',
method: 'get',
params: {activityId}, // 确保参数正确传递
});
}
// 新增诊疗目录
export function addDiagnosisTreatment(data) {
return request({
export function addDiagnosisTreatment (data) {
return request ({
url: '/data-dictionary/diagnosis-treatment/information',
method: 'post',
data: data
})
data: data,
});
}
// 修改诊疗目录
export function editDiagnosisTreatment(data) {
return request({
export function editDiagnosisTreatment (data) {
return request ({
url: '/data-dictionary/diagnosis-treatment/information',
method: 'put',
data: data
})
data: data,
});
}
// 诊疗目录分类查询
export function getDiseaseTreatmentInit() {
return request({
export function getDiseaseTreatmentInit () {
return request ({
url: '/data-dictionary/diagnosis-treatment/init',
method: 'get'
})
method: 'get',
});
}
// 停用诊疗目录
export function stopDiseaseTreatment(ids) {
console.log(ids)
return request({
export function stopDiseaseTreatment (ids) {
console.log (ids);
return request ({
url: '/data-dictionary/diagnosis-treatment/information-stop',
method: 'put',
data: ids
})
data: ids,
});
}
// 启用诊疗目录
export function startDiseaseTreatment(ids) {
console.log(ids)
return request({
export function startDiseaseTreatment (ids) {
console.log (ids);
return request ({
url: '/data-dictionary/diagnosis-treatment/information-start',
method: 'put',
data: ids
})
data: ids,
});
}
// 查询部门树形数据
export function deptTreeSelect(queryParams) {
return request({
export function deptTreeSelect (queryParams) {
return request ({
url: '/base-data-manage/organization/organization',
method: 'get',
param: queryParams
})
param: queryParams,
});
}
// 查询身体部位树形数据
export function bodyTreeSelect(queryParams) {
return request({
export function bodyTreeSelect (queryParams) {
return request ({
url: '/base-data-manage/body-structure/body',
method: 'get',
params: queryParams
})
params: queryParams,
});
}
// 查询地点树形数据
export function locationTreeSelect(queryParams) {
return request({
export function locationTreeSelect (queryParams) {
return request ({
url: '/base-data-manage/location/location-page-tree',
method: 'get',
params: queryParams
})
params: queryParams,
});
}
// 获取医用耗材目录
export function getYbDiagnosisTreatmentList(queryParams) {
return request({
export function getYbDiagnosisTreatmentList (queryParams) {
return request ({
url: '/catalog/page',
method: 'get',
params: queryParams
})
params: queryParams,
});
}

View File

@@ -0,0 +1,114 @@
<template>
<div>
<el-table ref="medicineRef" height="300" :data="filteredList" @cell-click="clickRow">
<el-table-column label="项目名称" align="center" prop="name" width="300" />
<el-table-column label="零售价" align="center" prop="retailPrice" />
<el-table-column label="最高零售价" align="center" prop="maximumRetailPrice" />
</el-table>
</div>
</template>
<script setup>
import { getDiagnosisTreatmentList } from './diagnosistreatment';
import { ref, watch } from 'vue';
const props = defineProps({
itemType: {
type: String,
default: '',
},
searchKey: {
type: String,
default: '',
},
shouldLoadData: {
type: Boolean,
default: false,
},
// 新增:从父组件接收预加载的数据
preloadedData: {
type: Array,
default: () => [],
},
});
const emit = defineEmits(['selectRow']);
const diagnosisTreatmentList = ref([]); // 原始数据列表
const filteredList = ref([]); // 过滤后的数据列表
const hasLoaded = ref(false); // 标记是否已加载数据
// 获取诊疗项目列表
function getList() {
if (hasLoaded.value) return; // 如果已经加载过数据,则不再重复请求
// 优先使用父组件传递的数据
if (props.preloadedData && props.preloadedData.length > 0) {
diagnosisTreatmentList.value = props.preloadedData;
filterList(); // 初始化过滤
hasLoaded.value = true;
return;
}
// 如果父组件没有传递数据或数据为空,则自己请求
getDiagnosisTreatmentList({ statusEnum: 2, pageSize: 1000, pageNo: 1 })
.then((res) => {
diagnosisTreatmentList.value =
res.data?.records?.filter((item) => item.childrenJson == null) || [];
filterList(); // 初始化过滤
hasLoaded.value = true; // 标记为已加载
})
.catch((err) => {
console.error('获取诊疗项目数据失败:', err);
});
}
// 监听shouldLoadData属性变化仅在首次为true时加载数据
watch(
() => props.shouldLoadData,
(newValue) => {
if (newValue && !hasLoaded.value) {
getList();
}
},
{ immediate: true }
);
// 监听preloadedData变化当父组件数据更新时同步更新列表
watch(
() => props.preloadedData,
(newData) => {
if (newData && newData.length > 0) {
diagnosisTreatmentList.value = newData;
filterList(); // 更新过滤
hasLoaded.value = true;
}
},
{ immediate: true }
);
// 监听搜索关键词变化,实时过滤数据
watch(
() => props.searchKey,
() => {
filterList();
}
);
// 根据搜索关键词过滤列表
function filterList() {
if (!props.searchKey || props.searchKey.trim() === '') {
filteredList.value = diagnosisTreatmentList.value;
} else {
const searchTerm = props.searchKey.toLowerCase().trim();
filteredList.value = diagnosisTreatmentList.value.filter(
(item) => item.name && item.name.toLowerCase().includes(searchTerm)
);
}
}
function clickRow(row) {
emit('selectRow', row);
}
</script>
<style scoped></style>

View File

@@ -28,7 +28,6 @@
label-width="68px"
>
<el-row :gutter="24">
<!-- <el-col :span="5"> -->
<el-form-item label="项目名" prop="searchKey" label-width="55">
<el-input
v-model="queryParams.searchKey"
@@ -38,8 +37,7 @@
@keyup.enter="handleQuery"
/>
</el-form-item>
<!-- </el-col> -->
<!-- <el-col :span="5"> -->
<el-form-item label="状态" prop="statusEnum" label-width="80">
<el-select v-model="queryParams.statusEnum" clearable>
<el-option
@@ -50,8 +48,6 @@
/>
</el-select>
</el-form-item>
<!-- </el-col> -->
<!-- <el-col :span="5"> -->
<el-form-item label="医保是否对码" prop="ybMatchFlag" label-width="120">
<el-select v-model="queryParams.ybMatchFlag" placeholder="" clearable>
<el-option
@@ -62,24 +58,7 @@
/>
</el-select>
</el-form-item>
<!-- </el-col> -->
<!-- <el-col :span="4">
<el-form-item label="执行科室" prop="ruleId" label-width="100">
<el-select
v-model="queryParams.ruleId"
placeholder=""
clearable
>
<el-option
v-for="item in exeOrganizations"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col> -->
<!-- <el-col :span="4"> -->
<el-form-item label="类型" prop="typeEnum" label-width="100">
<el-select v-model="queryParams.typeEnum" placeholder="" clearable>
<el-option
@@ -116,9 +95,9 @@
>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Upload" @click="handleImport">导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Upload" @click="handleImport">导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="Search" @click="getList">查询</el-button>
@@ -148,7 +127,7 @@
key="busNo"
prop="busNo"
:show-overflow-tooltip="true"
width="150"
width="200"
/>
<el-table-column
label="项目名称"
@@ -156,22 +135,9 @@
key="name"
prop="name"
:show-overflow-tooltip="true"
width="150"
/>
<el-table-column
label="拼音"
align="center"
key="pyStr"
prop="pyStr"
:show-overflow-tooltip="true"
/>
<el-table-column
label="五笔码"
align="center"
key="wbStr"
prop="wbStr"
:show-overflow-tooltip="true"
width="200"
/>
<el-table-column
label="目录类别"
align="center"
@@ -180,94 +146,6 @@
:show-overflow-tooltip="true"
width="100"
/>
<el-table-column
label="业务类型"
align="center"
key="typeEnum_enumText"
prop="typeEnum_enumText"
:show-overflow-tooltip="true"
width="90"
/>
<el-table-column
label="使用单位"
align="center"
key="permittedUnitCode_dictText"
prop="permittedUnitCode_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="医保标记"
align="center"
key="ybFlag_enumText"
prop="ybFlag_enumText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="医保编码"
align="center"
key="ybNo"
prop="ybNo"
:show-overflow-tooltip="true"
/>
<el-table-column
label="医保对码标记"
align="center"
key="ybMatchFlag_enumText"
prop="ybMatchFlag_enumText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="状态"
align="center"
key="statusEnum_enumText"
prop="statusEnum_enumText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="归属科室"
align="center"
key="orgId_dictText"
prop="orgId_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="所在位置"
align="center"
key="locationId_dictText"
prop="locationId_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="身体部位"
align="center"
key="bodySiteCode_dictText"
prop="bodySiteCode_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="所需标本"
align="center"
key="specimenCode_dictText"
prop="specimenCode_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<el-table-column
label="财务类别"
align="center"
key="itemTypeCode_dictText"
prop="itemTypeCode_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<el-table-column
label="医保类别"
align="center"
key="ybType_dictText"
prop="ybType_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<el-table-column
label="售价"
align="center"
@@ -277,20 +155,34 @@
width="100"
/>
<el-table-column
label="说明"
label="财务类别"
align="center"
key="descriptionText"
prop="descriptionText"
key="itemTypeCode_dictText"
prop="itemTypeCode_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<el-table-column
label="使用单位"
align="center"
key="permittedUnitCode_dictText"
prop="permittedUnitCode_dictText"
:show-overflow-tooltip="true"
/>
<!-- <el-table-column
label="执行科室"
<el-table-column
label="医保编码"
align="center"
key="ruleId"
prop="ruleId"
key="ybNo"
prop="ybNo"
:show-overflow-tooltip="true"
width="90"
/> -->
/>
<el-table-column
label="状态"
align="center"
key="statusEnum_enumText"
prop="statusEnum_enumText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="操作"
align="center"
@@ -345,16 +237,30 @@
<!-- 诊疗目录导入对话框 -->
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
<el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip text-center">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
@click="importTemplate">下载模板</el-link>
<el-link
type="primary"
:underline="false"
style="font-size: 12px; vertical-align: baseline"
@click="importTemplate"
>下载模板</el-link
>
</div>
</template>
</el-upload>
@@ -369,13 +275,14 @@
</template>
<script setup name="DiagnosisTreatment">
import { getToken } from "@/utils/auth";
import { getToken } from '@/utils/auth';
import {
getDiagnosisTreatmentList,
stopDiseaseTreatment,
startDiseaseTreatment,
getDiseaseTreatmentInit,
getDiagnosisTreatmentOne,
validateActivityEdit,
} from './components/diagnosistreatment';
import diagnosisTreatmentDialog from './components/diagnosisTreatmentDialog';
import DiagTreYbDialog from './components/diagTreYbDialog';
@@ -407,18 +314,17 @@ const upload = reactive({
// 是否显示弹出层
open: false,
// 弹出层标题
title: "",
title: '',
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
headers: { Authorization: 'Bearer ' + getToken() },
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + "/data-dictionary/diagnosis-treatment/import-data"
url: import.meta.env.VITE_APP_BASE_API + '/data-dictionary/diagnosis-treatment/import-data',
});
const data = reactive({
form: {},
queryParams: {
@@ -445,7 +351,6 @@ const filterNode = (value, data) => {
/** 诊断目录分类查询下拉树结构 */
function getDiseaseTreatmentList() {
getDiseaseTreatmentInit().then((response) => {
console.log(response, 'response诊疗目录分类查询下拉树结构');
diagnosisCategoryOptions.value = response.data.diagnosisCategoryOptions.sort((a, b) => {
return parseInt(a.value) - parseInt(b.value);
});
@@ -458,18 +363,15 @@ function getDiseaseTreatmentList() {
}
/** 查询诊断目录列表 */
function getList() {
console.log(queryParams.value, 'queryParams***********************');
loading.value = true;
getDiagnosisTreatmentList(queryParams.value).then((res) => {
loading.value = false;
diagnosisTreatmentList.value = res.data.records;
console.log(diagnosisTreatmentList, 'res.data');
total.value = res.data.total;
});
}
/** 节点单击事件 */
function handleNodeClick(data) {
console.log(data, '节点单击事件');
queryParams.value.categoryCode = data.value;
currentCategoryEnum.value = data.value;
handleQuery();
@@ -477,7 +379,6 @@ function handleNodeClick(data) {
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNo = 1;
console.log(queryParams, 'queryParams搜索');
getList();
}
@@ -528,7 +429,11 @@ function handleImport() {
}
/** 下载模板操作 */
function importTemplate() {
proxy.download('/data-dictionary/diagnosis-treatment/import-template', {}, `diagnosis_treatment_template_${new Date().getTime()}.xlsx`);
proxy.download(
'/data-dictionary/diagnosis-treatment/import-template',
{},
`diagnosis_treatment_template_${new Date().getTime()}.xlsx`
);
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
@@ -541,8 +446,8 @@ const handleFileSuccess = (response, file, fileList) => {
proxy.$refs['uploadRef'].handleRemove(file);
proxy.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
'</div>',
response.msg +
'</div>',
'导入结果',
{ dangerouslyUseHTMLString: true }
);
@@ -555,7 +460,6 @@ function submitFileForm() {
/** 选择条数 */
function handleSelectionChange(selection) {
console.log(selection, 'selection');
// selectedData.value = selection.map((item) => ({ ...item })); // 存储选择的行数据
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
@@ -564,22 +468,28 @@ function handleSelectionChange(selection) {
/** 打开新增弹窗 */
function openAddDiagnosisTreatment() {
// if (currentCategoryEnum.value) {
console.log('打开新增弹窗');
title.value = '新增';
nextTick(() => {
proxy.$refs.diagnosisTreatmentRef.show();
});
// } else {
// proxy.$modal.msgError("请先选择目录分类!");
// }
}
const isEditInfoDisable = ref(0);
/** 打开编辑弹窗 */
function openEditDiagnosisTreatment(row) {
validateActivityEdit(row.id).then((res) => {
// res.data == 1 医生开过该诊疗项目,不可编辑
isEditInfoDisable.value = res.data;
getDiagnosisTreatmentInfo(row);
});
}
// 根据诊疗id 查询诊疗信息
function getDiagnosisTreatmentInfo(row) {
getDiagnosisTreatmentOne(row.id).then((response) => {
console.log(response, 'response88888');
currentData.value = response.data;
currentData.value = {
...response.data,
// 禁用编辑
isEditInfoDisable: isEditInfoDisable.value,
};
currentData.value.ybFlag == 1
? (currentData.value.ybFlag = true)
: (currentData.value.ybFlag = false);

View File

@@ -46,6 +46,21 @@
/>
</el-select>
</el-form-item>
<el-form-item label="诊断类型" prop="typeCode">
<el-select
v-model="queryParams.typeCode"
placeholder="请选择"
style="width: 240px"
clearable
>
<el-option
v-for="dict in condition_type_code"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
@@ -86,6 +101,84 @@
</el-col> -->
</el-row>
<el-table v-loading="loading" :data="diseaseList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="编码" align="center" key="conditionCode" prop="conditionCode" />
<el-table-column
label="名称"
align="center"
key="name"
prop="name"
:show-overflow-tooltip="true"
/>
<el-table-column
label="疾病分类"
align="center"
key="sourceEnum_enumText"
prop="sourceEnum_enumText"
:show-overflow-tooltip="true"
/>
<!-- <el-table-column
label="拼音助记码"
align="center"
key="pyStr"
prop="pyStr"
:show-overflow-tooltip="true"
/> -->
<el-table-column
label="类型"
align="center"
key="typeCode_dictText"
prop="typeCode_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="医保编码 "
align="center"
key="ybNo"
prop="ybNo"
:show-overflow-tooltip="true"
/>
<!-- <el-table-column
label="医保标记"
align="center"
key="ybMatchFlag"
prop="ybMatchFlag_enumText"
/>
<el-table-column
label="医保对码标志"
align="center"
key="ybMatchFlag"
prop="ybMatchFlag_enumText"
/> -->
<el-table-column
label="状态"
align="center"
key="statusEnum_enumText"
prop="statusEnum_enumText"
width="160"
/>
<el-table-column
label="描述"
align="center"
key="description"
prop="description"
width="160"
/>
<el-table-column
label="操作"
align="center"
width="150"
class-name="small-padding fixed-width"
>
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
>编辑</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
<!-- 添加外层滚动容器确保表格可以水平滚动 -->
<div class="table-scroll-container">
<!-- 移除style="width: 100%"让Element UI表格根据内容自动调整 -->
@@ -211,7 +304,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="类型" prop="typeCode">
<el-form-item label="诊断类型" prop="typeCode">
<el-select v-model="form.typeCode" placeholder="请选择" clearable>
<el-option
v-for="dict in condition_type_code"

View File

@@ -18,6 +18,13 @@ export function getMedicationList(query) {
})
}
export function getYbCatalogResult(address,v) {
return request({
url: '/yb-request/query-catalog?address=1301&v=1',
method: 'get',
})
}
// 查询药品目录详细
export function getMedicationOne(id) {
return request({
@@ -26,6 +33,14 @@ export function getMedicationOne(id) {
params: { id } // 确保参数正确传递
})
}
// 校验药品是否可以编辑
export function validateEditMedictaion(medicationId) {
return request({
url: '/data-dictionary/medication/validate-edit',
method: 'get',
params: { medicationId } // 确保参数正确传递
})
}
// 新增药品目录
export function addMedication(data) {

View File

@@ -46,7 +46,9 @@
clearable
@change="handleLvChange"
style="width: 240px"
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
>
>
<el-option
v-for="dict in chrgitm_lv"
:key="dict.value"
@@ -70,7 +72,12 @@
</el-col>
<el-col :span="6">
<el-form-item label="药品分类" prop="categoryCode">
<el-select v-model="form.categoryCode" clearable>
<el-select
v-model="form.categoryCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 2 || form.isEditInfoDisable === 1"
>
<el-option
v-for="category in med_category_code"
:key="category.value"
@@ -107,17 +114,31 @@
</el-col>
<el-col :span="6">
<el-form-item label="规格" prop="totalVolume">
<el-input v-model="form.totalVolume" placeholder="" />
<el-input
v-model="form.totalVolume"
placeholder=""
clearable
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计量换算" prop="totalVolume">
<el-input v-model="form.unitConversionRatio" placeholder="" />
<el-input
v-model="form.unitConversionRatio"
placeholder=""
clearable
:disabled="form.isEditInfoDisable === 1"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="剂量单位" prop="doseUnitCode">
<el-select v-model="form.doseUnitCode" clearable filterable>
<el-select
v-model="form.doseUnitCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 1"
>
<el-option
v-for="category in unit_code"
:key="category.value"
@@ -131,7 +152,12 @@
<el-row :gutter="24">
<el-col :span="6">
<el-form-item label="剂型" prop="doseFormCode">
<el-select v-model="form.doseFormCode" clearable filterable>
<el-select
v-model="form.doseFormCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 1"
>
<el-option
v-for="category in dose_form_code"
:key="category.value"
@@ -182,6 +208,18 @@
<el-input v-model="form.maxUnit" placeholder="" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="用法说明" prop="dosageInstruction">
<el-select v-model="form.dosageInstruction" clearable filterable>
<el-option
v-for="category in dosage_instruction"
:key="category.value"
:label="category.label"
:value="category.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<div class="title">库存信息</div>
<el-row :gutter="24">
@@ -222,7 +260,12 @@
</el-col>
<el-col :span="6">
<el-form-item label="包装单位" prop="unitCode">
<el-select v-model="form.unitCode" clearable filterable>
<el-select
v-model="form.unitCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 2 || form.isEditInfoDisable === 1"
>
<el-option
v-for="category in unit_code"
:key="category.value"
@@ -234,7 +277,12 @@
</el-col>
<el-col :span="6">
<el-form-item label="最小单位" prop="minUnitCode">
<el-select v-model="form.minUnitCode" clearable filterable>
<el-select
v-model="form.minUnitCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 2 || form.isEditInfoDisable === 1"
>
<el-option
v-for="category in unit_code"
:key="category.value"
@@ -245,8 +293,12 @@
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="警戒线最低值(常规单位)" prop="itemMinQuantity" label-width="180px">
<el-input-number
<el-form-item
label="警戒线最低值(常规单位)"
prop="itemMinQuantity"
label-width="180px"
>
<el-input-number
v-model="form.itemMinQuantity"
placeholder=""
controls-position="right"
@@ -287,12 +339,23 @@
</el-col>
<el-col :span="6">
<el-form-item label="拆零比" prop="partPercent">
<el-input-number v-model="form.partPercent" controls-position="right" placeholder="" :min="1"/>
<el-input-number
v-model="form.partPercent"
controls-position="right"
placeholder=""
:min="1"
clearable
:disabled="form.isEditInfoDisable === 2 || form.isEditInfoDisable === 1"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="警戒线最高值(常规单位)" prop="itemMaxQuantity" label-width="180px">
<el-form-item
label="警戒线最高值(常规单位)"
prop="itemMaxQuantity"
label-width="180px"
>
<el-input-number
v-model="form.itemMaxQuantity"
placeholder=""
@@ -306,12 +369,22 @@
<el-row :gutter="24">
<el-col :span="6">
<el-form-item label="购入价" prop="purchasePrice">
<el-input v-model="form.purchasePrice" placeholder="" :disabled="false" />
<el-input
v-model="form.purchasePrice"
placeholder=""
clearable
:disabled="form.isEditInfoDisable === 2 || form.isEditInfoDisable === 1"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="零售价" prop="retailPrice">
<el-input v-model="form.retailPrice" placeholder="" :disabled="false" />
<el-input
v-model="form.retailPrice"
placeholder=""
clearable
:disabled="form.isEditInfoDisable === 2 || form.isEditInfoDisable === 1"
/>
</el-form-item>
</el-col>
<el-col :span="6">
@@ -324,7 +397,12 @@
<el-row :gutter="24">
<el-col :span="6">
<el-form-item label="财务类型" prop="typeCode">
<el-select v-model="form.typeCode" clearable filterable>
<el-select
v-model="form.typeCode"
clearable
filterable
:disabled="form.isEditInfoDisable === 2 || form.isEditInfoDisable === 1"
>
<el-option
v-for="category in fin_type_code"
:key="category.value"
@@ -375,6 +453,7 @@
clearable
filterable
style="width: 240px"
:disabled="form.isEditInfoDisable === 1"
>
<el-option
v-for="dict in med_chrgitm_type"
@@ -399,19 +478,28 @@
</el-col> -->
<el-col :span="6">
<el-form-item label="基药标识" prop="basicFlag">
<el-checkbox v-model="form.basicFlag"></el-checkbox>
<el-checkbox
v-model="form.basicFlag"
:disabled="form.isEditInfoDisable === 1"
></el-checkbox>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="皮试判别" prop="skinTestFlag">
<el-checkbox v-model="form.skinTestFlag"></el-checkbox>
<el-checkbox
v-model="form.skinTestFlag"
:disabled="form.isEditInfoDisable === 1"
></el-checkbox>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="6">
<el-form-item label="注射药品" prop="injectFlag">
<el-checkbox v-model="form.injectFlag"></el-checkbox>
<el-checkbox
v-model="form.injectFlag"
:disabled="form.isEditInfoDisable === 1"
></el-checkbox>
</el-form-item>
</el-col>
<el-col :span="6">
@@ -448,8 +536,8 @@
</el-col>
<el-col :span="6">
<el-form-item label="处方标志" prop="rxFlag">
<el-radio-group v-model="form.rxFlag">
<el-radio v-for="item in rx_flag" :key="item.value" :label="item.value">
<el-radio-group v-model="form.rxFlag" :disabled="form.isEditInfoDisable === 1">
<el-radio v-for="item in rx_flag" :key="item.value" :value="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
@@ -583,6 +671,7 @@ const {
ddd_code,
dose_from_code,
rx_flag,
dosage_instruction,
chrgitm_lv,
} = proxy.useDict(
'med_category_code',
@@ -598,6 +687,7 @@ const {
'ddd_code',
'dose_from_code',
'rx_flag',
'dosage_instruction',
'chrgitm_lv'
);
@@ -639,23 +729,11 @@ const data = reactive({
form: {},
antibioticForm: {},
rules: {
// statusEnum: [
// { required: true, message: "药品状态不能为空", trigger: "blur" },
// ],
// orgId: [{ required: true, message: "所属科室不能为空", trigger: "blur" }],
locationId: [{ required: true, message: '所在位置不能为空', trigger: 'blur' }],
doseFormCode: [{ required: true, message: '剂型不能为空', trigger: 'blur' }],
totalVolume: [{ required: true, message: '规格不能为空', trigger: 'blur' }],
// activeFlag: [{ required: true, message: "活性不能为空", trigger: "blur" }],
// methodCode: [{ required: true, message: '用法不能为空', trigger: 'blur' }],
// rateCode: [{ required: true, message: '用药频次不能为空', trigger: 'blur' }],
// dose: [{ required: true, message: '单次剂量不能为空', trigger: 'blur' }],
doseUnitCode: [{ required: true, message: '剂量单位不能为空', trigger: 'blur' }],
manufacturerText: [{ required: true, message: '生产厂家不能为空', trigger: 'blur' }],
// maxUnit: [
// { required: true, message: '单次最大剂量不能为空', trigger: 'blur' },
// { validator: validateMaxUnit, trigger: 'blur' },
// ],
busNo: [{ required: true, message: '药品编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '药品名称不能为空', trigger: 'blur' }],
categoryCode: [{ required: true, message: '药品分类不能为空', trigger: 'blur' }],
@@ -665,29 +743,10 @@ const data = reactive({
minUnitCode: [{ required: true, message: '最小单位不能为空', trigger: 'blur' }],
ingredient: [{ required: true, message: '成分不能为空', trigger: 'blur' }],
partPercent: [{ required: true, message: '拆零比不能为空', trigger: 'blur' }],
// itemMinQuantity: [{ required: true, message: '警戒线最低值不能为空', trigger: 'blur' }],
// itemMaxQuantity: [{ required: true, message: '警戒线最高值不能为空', trigger: 'blur' }],
doseFrom: [{ required: true, message: '剂量形式不能为空', trigger: 'blur' }],
// approvalNumber: [{ required: true, message: '批准文号不能为空', trigger: 'blur' }],
// ybMatchFlag: [
// { required: true, message: "医保对码不能为空", trigger: "blur" },
// ],
ybNo: [{ required: false, message: '医保编码不能为空', trigger: 'blur' }],
pharmacologyCategoryCode: [{ required: true, message: '药品性质不能为空', trigger: 'blur' }],
// skinTestFlag: [
// { required: true, message: "皮试不能为空", trigger: "blur" },
// ],
// injectFlag: [{ required: true, message: "注射不能为空", trigger: "blur" }],
supplyId: [{ required: true, message: '供应商不能为空', trigger: 'blur' }],
// restrictedFlag: [
// { required: true, message: "限制使用不能为空", trigger: "blur" },
// ],
// childrenFlag: [
// { required: true, message: "儿童用药不能为空", trigger: "blur" },
// ],
// restrictedScope: [
// { required: true, message: "限制使用范围不能为空", trigger: "blur" },
// ],
nationalDrugCode: [{ required: false, message: '贯标国家编码不能为空', trigger: 'blur' }],
partAttributeEnum: [{ required: true, message: '拆分属性不能为空', trigger: 'blur' }],
thoPartAttributeEnum: [
@@ -697,16 +756,8 @@ const data = reactive({
trigger: 'blur',
},
],
// basicFlag: [
// { required: true, message: "基药标识不能为空", trigger: "blur" },
// ],
// antibioticFlag: [
// { required: true, message: "抗生素不能为空", trigger: "blur" },
// ],
// selfFlag: [{ required: true, message: "自制不能为空", trigger: "blur" }],
purchasePrice: [{ required: true, message: '购入价不能为空', trigger: 'blur' }],
retailPrice: [{ required: true, message: '零售价不能为空', trigger: 'blur' }],
// maximumRetailPrice: [{ required: true, message: '最高零售价不能为空', trigger: 'blur' }],
ybType: [{ required: true, message: '医保类型不能为空', trigger: 'blur' }],
rxFlag: [{ required: true, message: '处方标志不能为空', trigger: 'blur' }],
chrgitmLv: [{ required: true, message: '医保等级不能为空', trigger: 'blur' }],
@@ -762,15 +813,12 @@ function validateMaxUnit(rule, value, callback) {
/** 查询部门下拉树结构 */
function getDeptTree() {
deptTreeSelect().then((response) => {
console.log(response, 'response查询部门下拉树结构');
deptOptions.value = response.data.records;
console.log(deptOptions.value, '部门下拉树结构');
});
}
/** 查询地点下拉树结构 */
function getLocationTree() {
locationTreeSelect({ formList: '11,16' }).then((response) => {
console.log(response, 'response查询部门下拉树结构');
locationOptions.value = response.data.records;
});
}
@@ -787,10 +835,7 @@ function show(row) {
statusRestrictedOptions.value = props.statusRestrictedOptions;
partAttributeEnumOptions.value = props.partAttributeEnumOptions;
tempOrderSplitPropertyOptions.value = props.tempOrderSplitPropertyOptions;
console.log(form.value.categoryCode, 'form.value.categoryCode');
// setValue(row);
form.value.categoryCode = props.currentCategoryEnum;
console.log(form.value, 1234567890);
visible.value = true;
}
@@ -799,38 +844,22 @@ function setValue(row) {
name: formatValue(props.currentCategoryEnum == '4' ? row.singleDrugName : row.registeredName), // 通用名称
merchandiseName: formatValue(row.registeredName), // 商品名称
ybNo: formatValue(row.medicalCatalogCode), // 医保编码
// categoryCode: row.drugCategory, // 药品分类
// ybMatchFlag: row., // 医保对码
// pharmacologyCategoryCode: row., // 药品性质
totalVolume: formatValue(
props.currentCategoryEnum == '4' ? row.conventionalUsage : row.drugSpecification
), // 规格
doseode: formatValue(row.drugForm), // 剂型
doseUnitCode: formatValue(row.minMeasurementUnit), // 剂量单位
// usageLimit: row.dosage, // 用量限定
methodCode: formatValue(row.usage), // 用法
rateCode: formatValue(row.frequency), // 用药频次
// maxUnit: row., // 单次最大剂量
// skinTestFlag: row., // 皮试判别
// locationId: row., // 采购入库位置
unitCode: formatValue(row.packagingUnit), // 包装单位
minUnitCode: formatValue(row.minUseUnit), // 最小单位
// partAttributeEnum: row., // 门诊拆分属性
// thoPartAttributeEnum: row., // 住院临时医嘱拆分属性
partPercent: formatValue(row.conversionRatio), // 拆零比
itemMinQuantity: formatValue(row.itemMinQuantity), // 警戒线最低值
itemMaxQuantity: formatValue(row.itemMaxQuantity), // 警戒线最高值
// purchasePrice: row., // 购入价
// retailPrice: row., // 零售价
// maximumRetailPrice: row., // 最高零售价
// typeCode: row., // 财务类型
nationalDrugCode: formatValue(row.nationalDrugCode), // 贯标国家编码
version: formatValue(row.version), // 药品版本
approvalNumber: formatValue(row.approvalNo), // 批准文号
// ybType: formatValue(row.insuranceClass), // 医保类别
manufacturerText: formatValue(row.manufacturerName), // 生产厂家
// supplyId: row., // 供应商
basicFlag: formatValue(row.essentialDrugFlag), // 基药标识
// injectFlag: row., // 注射药物
// childrenFlag: row.pediatricUse, // 儿童用药标志
@@ -887,7 +916,6 @@ function edit() {
antibioticForm.value.maxRateCode = form.value.maxRateCode;
antibioticForm.value.dddUnitCode = form.value.dddUnitCode;
antibioticForm.value.dddCode = form.value.dddCode;
//antibioticForm.value.chrgitmLv = form.value.chrgitmLv ? form.value.chrgitmLv.toString() : undefined;
form.value.chrgitmLv = form.value.chrgitmLv ? form.value.chrgitmLv.toString() : undefined;
visible.value = true;
}
@@ -941,7 +969,6 @@ function reset() {
minUnitCode: undefined,
doseUnitCode: undefined,
doseFormCode: undefined,
// statusEnum: undefined,
skinTestFlag: undefined,
injectFlag: undefined,
childrenFlag: undefined,
@@ -968,8 +995,6 @@ function reset() {
nationalDrugCode: undefined,
antibioticFlag: undefined,
selfFlag: undefined,
// minRateCode: undefined,
// maxRateCode: undefined,
partAttributeEnum: undefined,
thoPartAttributeEnum: undefined,
usageLimit: undefined,

View File

@@ -3,7 +3,7 @@
<el-dialog
title="医保药品目录"
v-model="visible"
width="1500px"
width="1800px"
append-to-body
destroy-on-close
@close="cancel"
@@ -29,22 +29,32 @@
<span v-else>{{ scope.row.registeredName }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="药品类别" prop="drugCategoryName">
<el-table-column align="center" label="药品类别" prop="drugCategoryName" width="120">
<template #default="scope">
{{ formatStr(scope.row.drugCategoryName) }}
</template>
</el-table-column>
<el-table-column align="center" label="国药准字" prop="drugCategoryName">
<template #default="scope">
{{ formatStr(scope.row.approvalNo) }}
</template>
</el-table-column>
<el-table-column align="center" label="药品规格" prop="drugSpecification">
<template #default="scope">
<span v-if="props.currentCategoryEnum == '4'">{{ scope.row.conventionalUsage }}</span>
<span v-else>{{ scope.row.drugSpecification }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="处方药" prop="otcFlagName">
<el-table-column align="center" label="处方药" prop="otcFlagName" width="120">
<template #default="scope">
{{ formatStr(scope.row.otcFlagName) }}
</template>
</el-table-column>
<el-table-column align="center" label="厂家" prop="manufacturerName">
<template #default="scope">
{{ formatStr(scope.row.manufacturerName) }}
</template>
</el-table-column>
<el-table-column align="center" label="批准文号" prop="approvalNo" />
<el-table-column align="center" label="操作" width="80">
<template #default="scope">

View File

@@ -62,6 +62,24 @@
/>
</el-select>
</el-form-item>
<el-form-item label="医保接口编号" prop="searchKey" label-width="120">
<el-input
v-model="queryParams.address"
placeholder="1301-1321"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="版本号" prop="searchKey" label-width="120">
<el-input
v-model="queryParams.v"
placeholder="版本号"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<!-- </el-col> -->
</el-row>
<!-- <el-form-item>
@@ -91,20 +109,17 @@
>启用</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="Upload"
@click="handleImport"
>导入</el-button
>
<el-button type="info" plain icon="Upload" @click="handleImport">导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="Search" @click="getList">查询</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="Search" @click="getYbCatalog">查询目录</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button
type="warning"
@@ -129,7 +144,8 @@
key="busNo"
prop="busNo"
:show-overflow-tooltip="true"
width="90"
min-width="90"
width="200px"
/>
<el-table-column
label="药品名称"
@@ -137,7 +153,17 @@
key="name"
prop="name"
:show-overflow-tooltip="true"
width="110"
min-width="110"
width="200px"
/>
<el-table-column
label="规格"
align="center"
key="totalVolume"
prop="totalVolume"
:show-overflow-tooltip="true"
min-width="200px"
width="200px"
/>
<el-table-column
label="药品状态"
@@ -146,11 +172,13 @@
prop="statusEnum_enumText"
:show-overflow-tooltip="true"
>
<template #default="scope">
<el-tag v-if="scope.row.statusEnum == 2" type="success" >{{ scope.row.statusEnum_enumText }}</el-tag>
<el-tag v-else type="error">{{ scope.row.statusEnum_enumText }}</el-tag>
</template>
</el-table-column>
<template #default="scope">
<el-tag v-if="scope.row.statusEnum == 2" type="success">{{
scope.row.statusEnum_enumText
}}</el-tag>
<el-tag v-else type="error">{{ scope.row.statusEnum_enumText }}</el-tag>
</template>
</el-table-column>
<el-table-column
label="药品分类"
align="center"
@@ -166,21 +194,14 @@
prop="orgId_dictText"
:show-overflow-tooltip="true"
/> -->
<el-table-column
<!-- <el-table-column
label="采购入库位置"
align="center"
key="locationId_dictText"
prop="locationId_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="规格"
align="center"
key="totalVolume"
prop="totalVolume"
:show-overflow-tooltip="true"
width="200px"
/>
/> -->
<el-table-column
label="医保编码"
align="center"
@@ -310,15 +331,17 @@
</template>
<script setup name="Medication">
import { getToken } from "@/utils/auth";
import { getToken } from '@/utils/auth';
import {
getMedicationList,
editMedication,
addMedication,
getMedicationCategory,
validateEditMedictaion,
getMedicationOne,
startMedication,
stopMedication,
getYbCatalogResult,
} from './components/medicine';
import medicineDialog from './components/medicineDialog';
import MedicineYbDialog from './components/medicineYbDialog';
@@ -356,15 +379,15 @@ const upload = reactive({
// 是否显示弹出层
open: false,
// 弹出层标题
title: "",
title: '',
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
headers: { Authorization: 'Bearer ' + getToken() },
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + "/data-dictionary/medication/import-data"
url: import.meta.env.VITE_APP_BASE_API + '/data-dictionary/medication/import-data',
});
const data = reactive({
@@ -376,6 +399,8 @@ const data = reactive({
statusEnum: undefined, // 状态(包括 1预置2启用3停用
ybMatchFlag: undefined, // 是否医保匹配(包括 10
categoryCode: undefined, // 目录
address: undefined, // 目录
v: undefined, // 目录
},
rules: {},
});
@@ -391,7 +416,6 @@ const filterNode = (value, data) => {
/** 病种目录分类查询下拉树结构 */
function getMedicationCategoryList() {
getMedicationCategory().then((response) => {
console.log(response, 'response药品目录分类查询下拉树结构');
medicationOptions.value = response.data.medicationCategoryCodeOptions;
medicationOptions.value.unshift({ info: '全部', value: '' });
statusFlagOptions.value = response.data.statusFlagOptions;
@@ -406,14 +430,20 @@ function getMedicationCategoryList() {
/** 查询病种目录列表 */
function getList() {
loading.value = true;
console.log(queryParams.value, 'queryParams***********************');
getMedicationList(queryParams.value).then((res) => {
loading.value = false;
console.log(res, 'res');
medicationList.value = res.data.records;
total.value = res.data.total;
});
}
/** 查询病种目录列表 */
function getYbCatalog() {
loading.value = true;
getYbCatalogResult(queryParams.value).then((res) => {
loading.value = false;
});
}
/** 节点单击事件 */
function handleNodeClick(data) {
queryParams.value.categoryCode = data.value;
@@ -423,7 +453,6 @@ function handleNodeClick(data) {
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNo = 1;
console.log(queryParams.value, 'queryParams');
getList();
}
@@ -444,7 +473,6 @@ function handleStart() {
/** 停用按钮操作 */
function handleClose() {
const stopIds = ids.value;
console.log(data, 'data');
proxy.$modal
.confirm('是否确认停用数据!')
.then(function () {
@@ -474,7 +502,11 @@ function handleImport() {
}
/** 下载模板操作 */
function importTemplate() {
proxy.download('/data-dictionary/medication/import-template', {}, `medication_template_${new Date().getTime()}.xlsx`);
proxy.download(
'/data-dictionary/medication/import-template',
{},
`medication_template_${new Date().getTime()}.xlsx`
);
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
@@ -508,25 +540,34 @@ function handleSelectionChange(selection) {
/** 打开新增弹窗 */
function openAddMedicine() {
// if (!currentCategoryEnum.value) {
// return proxy.$modal.msgError("请选择药品目录分类");
// }
// proxy.$refs['medicineYbRef'].show();
proxy.$refs['medicineRef'].show();
}
const isEditInfoDisable = ref(0);
/** 打开编辑弹窗 */
function openEditMedicine(row) {
validateEditMedictaion(row.id).then((res) => {
// res.data == 1 医生开过该药品,不可编辑
// res.data == 2 该药品已经入库过,不可编辑
isEditInfoDisable.value = res.data;
getMedicationInfo(row);
});
}
// 根据药品id 查询药品信息
function getMedicationInfo(row) {
getMedicationOne(row.id).then((response) => {
currentData.value = response.data;
currentData.value = {
...response.data,
// 禁用编辑
isEditInfoDisable: isEditInfoDisable.value,
};
nextTick(() => {
proxy.$refs['medicineRef'].edit();
});
});
}
/** 提交按钮 */
function submitForm(formData) {
console.log(formData, 'submitForm');
if (formData.id != undefined) {
editMedication(formData).then((response) => {
proxy.$modal.msgSuccess('修改成功');

View File

@@ -0,0 +1,477 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<!-- 搜索条件区域 -->
<el-col :span="24">
<el-form :model="queryParams" ref="queryForm" :inline="true" size="small">
<el-form-item label="项目名">
<el-input v-model="queryParams.searchKey" placeholder="国临编码/国临名称/医保编码/医保名称" clearable style="width: 280px" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-col>
<!-- 操作按钮区域 -->
<el-col :span="24" class="mb20">
<el-button type="primary" icon="Plus" @click="handleAdd">添加新项目</el-button>
<el-button type="danger" icon="Stop" @click="handleDelete">删除</el-button>
<el-button type="success" icon="Check">启用</el-button>
<el-button type="info" icon="Download">导入</el-button>
</el-col>
<!-- 数据表格区域 -->
<el-col :span="24">
<el-table
v-loading="loading"
:data="dataList"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="glNo"
label="国临版疾病编码"
key="glNo"
:show-overflow-tooltip="true"
align="center"
width="180" />
<el-table-column prop="glName"
label="国临版疾病名称"
key="glName"
:show-overflow-tooltip="true"
align="center"
min-width="200" />
<el-table-column prop="icd10No"
label="医保版疾病编码"
key="icd10No"
:show-overflow-tooltip="true"
align="center"
width="180" />
<el-table-column prop="icd10Name"
label="医保版疾病名称"
key="icd10Name"
:show-overflow-tooltip="true"
align="center"
min-width="200" />
<el-table-column label="操作" width="120" align="center">
<template #default="scope">
<el-button type="primary" link size="small" @click="handleEdit(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页控件 -->
<el-pagination
v-model:current-page="queryParams.pageNum"
v-model:page-size="queryParams.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-col>
</el-row>
<!-- 添加对话框 -->
<el-dialog
v-model="addDialogVisible"
title="添加国临编码"
width="600px"
:before-close="handleClose"
>
<el-form
ref="addFormRef"
:model="addFormData"
:rules="rules"
label-width="120px"
size="small"
>
<el-form-item label="国临版疾病编码" prop="glNo">
<el-input v-model="addFormData.glNo" placeholder="请输入国临版疾病编码" clearable />
</el-form-item>
<el-form-item label="国临版疾病名称" prop="glName">
<el-input v-model="addFormData.glName" placeholder="请输入国临版疾病名称" clearable />
</el-form-item>
<el-form-item label="医保版疾病编码" prop="icd10No">
<el-input v-model="addFormData.icd10No" placeholder="请输入医保版疾病编码" clearable />
</el-form-item>
<el-form-item label="医保版疾病名称" prop="icd10Name">
<el-input v-model="addFormData.icd10Name" placeholder="请输入医保版疾病名称" clearable />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</template>
</el-dialog>
<!-- 编辑对话框 -->
<el-dialog
v-model="editDialogVisible"
title="编辑国临编码"
width="600px"
:before-close="handleEditClose"
>
<el-form
ref="editFormRef"
:model="editFormData"
:rules="rules"
label-width="120px"
size="small"
>
<el-form-item label="国临版疾病编码" prop="glNo">
<el-input v-model="editFormData.glNo" placeholder="请输入国临版疾病编码" clearable />
</el-form-item>
<el-form-item label="国临版疾病名称" prop="glName">
<el-input v-model="editFormData.glName" placeholder="请输入国临版疾病名称" clearable />
</el-form-item>
<el-form-item label="医保版疾病编码" prop="icd10No">
<el-input v-model="editFormData.icd10No" placeholder="请输入医保版疾病编码" clearable />
</el-form-item>
<el-form-item label="医保版疾病名称" prop="icd10Name">
<el-input v-model="editFormData.icd10Name" placeholder="请输入医保版疾病名称" clearable />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleEditClose">取消</el-button>
<el-button type="primary" @click="handleEditSubmit">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="NationalCode">
import { ref, reactive, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
import request from '@/utils/request';
const router = useRouter();
const route = useRoute();
// 页面数据
const loading = ref(true);
const dataList = ref([]);
const total = ref(0);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
// 对话框相关
const addDialogVisible = ref(false);
const editDialogVisible = ref(false); // 编辑对话框可见性
const addFormRef = ref(null);
const editFormRef = ref(null); // 编辑表单引用
const addFormData = reactive({
glNo: '',
glName: '',
icd10No: '',
icd10Name: ''
});
// 编辑表单数据
const editFormData = reactive({
id: '',
glNo: '',
glName: '',
icd10No: '',
icd10Name: ''
});
// 表单验证规则
const rules = {
glNo: [
{ required: true, message: '请输入国临版疾病编码', trigger: 'blur' }
],
glName: [
{ required: true, message: '请输入国临版疾病名称', trigger: 'blur' }
],
icd10No: [
{ required: true, message: '请输入医保版疾病编码', trigger: 'blur' }
],
icd10Name: [
{ required: true, message: '请输入医保版疾病名称', trigger: 'blur' }
]
};
// 查询参数
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
searchKey: undefined
});
// 查询
function handleQuery() {
queryParams.pageNum = 1;
getList();
}
// 重置
function resetQuery() {
Object.assign(queryParams, {
searchKey: undefined,
status: undefined,
ybFlag: undefined,
type: undefined
});
handleQuery();
}
// 分页变化
function handleSizeChange(size) {
queryParams.pageSize = size;
getList();
}
function handleCurrentChange(current) {
queryParams.pageNum = current;
getList();
}
function handleDelete() {
// 安全检查ids.value是否存在且为数组
if (!ids.value || ids.value.length === 0) {
ElMessage.warning('请先选择要删除的数据');
return;
}
// 显示确认对话框
ElMessageBox.confirm('确定要删除选中的数据吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
loading.value = true;
// 修复确保ids.value是数组并过滤掉无效值
const validIds = Array.isArray(ids.value) ? ids.value.filter(id => id) : [];
if (validIds.length === 0) {
loading.value = false;
ElMessage.warning('没有有效的数据可删除');
return;
}
// 简化删除逻辑,改为单个请求,因为后端可能不支持批量删除
// 先删除第一个,后续可以根据需要调整
const firstId = validIds[0];
request({
url: '/base-data-manage/ICD10/delete-icd-Information',
method: 'delete',
params: { glNo: firstId } // 传递glNo参数
}).then(res => {
loading.value = false;
if (res.code === 200) {
ElMessage.success('删除成功');
// 刷新列表
getList();
// 清空选中状态
ids.value = [];
} else {
ElMessage.error(res.msg || '删除失败');
}
}).catch(error => {
loading.value = false;
console.error('删除数据失败:', error);
ElMessage.error('删除失败,请稍后重试');
});
}).catch(() => {
// 用户取消删除操作
});
}
// 同时修复handleSelectionChange函数确保正确设置ids
function handleSelectionChange(selection) {
// 确保selection是数组
if (Array.isArray(selection)) {
ids.value = selection.map(item => {
// 尝试使用glNo如果没有则使用id确保返回有效的值
return item.glNo || item.id || '';
}).filter(Boolean); // 过滤掉空值
single.value = ids.value.length <= 1;
multiple.value = !single.value;
} else {
// 如果selection不是数组重置ids
ids.value = [];
single.value = true;
multiple.value = false;
}
}
// 打开添加对话框
function handleAdd() {
// 重置表单
addFormRef.value?.resetFields();
Object.assign(addFormData, {
glNo: '',
glName: '',
icd10No: '',
icd10Name: ''
});
// 显示对话框
addDialogVisible.value = true;
}
// 关闭对话框
function handleClose() {
addDialogVisible.value = false;
}
function handleEdit(row) {
// 填充编辑表单数据
Object.assign(editFormData, {
id: row.id || '',
glNo: row.glNo || '',
glName: row.glName || '',
icd10No: row.icd10No || '',
icd10Name: row.icd10Name || ''
});
// 显示编辑对话框
editDialogVisible.value = true;
}
function handleEditClose() {
editDialogVisible.value = false;
}
function handleEditSubmit() {
editFormRef.value?.validate((valid) => {
if (valid) {
// 移除查重校验,直接进行编辑操作
loading.value = true;
// 调用后端编辑接口
request({
url: '/base-data-manage/ICD10/update-icd-Information',
method: 'put',
data: editFormData
}).then(res => {
loading.value = false;
if (res.code === 200) {
console.log('编辑国临编码成功');
ElMessage.success('编辑成功');
editDialogVisible.value = false;
getList();
} else {
ElMessage.error(res.msg || '编辑失败');
}
}).catch(error => {
loading.value = false;
console.error('编辑国临编码失败:', error);
ElMessage.error('编辑失败,请稍后重试');
});
}
});
}
// 提交表单
function handleSubmit() {
addFormRef.value?.validate((valid) => {
if (valid) {
// 先进行查重校验
checkAddDuplicate().then(isDuplicate => {
if (isDuplicate) {
ElMessage.warning('该项目已存在,请检查国临编码或医保编码是否重复');
return;
}
loading.value = true;
// 调用后端添加接口
request({
url: '/base-data-manage/ICD10/add-icd-Information',
method: 'post',
data: addFormData // 直接提交表单数据
}).then(res => {
loading.value = false;
if (res.code === 200) {
// 成功提示
ElMessage.success('添加成功');
// 关闭对话框
addDialogVisible.value = false;
// 刷新列表
getList();
} else {
// 失败提示
ElMessage.error(res.msg || '添加失败');
}
}).catch(error => {
loading.value = false;
console.error('添加国临编码失败:', error);
ElMessage.error('添加失败,请稍后重试');
});
}).catch(error => {
console.error('查重校验失败:', error);
ElMessage.error('校验失败,请稍后重试');
});
}
});
}
// 查重校验函数
async function checkAddDuplicate() {
try {
// 查询现有数据列表
const res = await request({
url: '/base-data-manage/ICD10/information-page',
method: 'get',
params: {
pageNum: 1,
pageSize: 1000, // 查询足够多的数据进行校验
searchKey: undefined
}
});
if (res.code === 200 && res.data.records) {
// 检查是否存在相同的国临编码或医保编码
const isExist = res.data.records.some(item =>
item.glNo === addFormData.glNo || item.icd10No === addFormData.icd10No
);
return isExist;
}
return false;
} catch (error) {
console.error('查重校验请求失败:', error);
return false;
}
}
// 获取列表数据
function getList() {
loading.value = true;
request({
url: '/base-data-manage/ICD10/information-page',
method: 'get',
params: queryParams
}).then(res => {
loading.value = false;
if (res.code === 200) {
dataList.value = res.data.records || [];
total.value = res.data.total || 0;
}
}).catch(error => {
loading.value = false;
console.error('获取国临编码数据失败:', error);
});
}
// 页面初始化
onMounted(() => {
getList();
});
</script>
<style scoped>
.app-container {
padding: 20px;
}
.mb20 {
margin-bottom: 20px;
}
</style>

View File

@@ -20,6 +20,19 @@
@keyup.enter="getClinicRecord"
/>
</el-form-item>
<el-form-item label="发票状态:" prop="invoiceStatus">
<el-select
v-model="queryParams.invoiceStatus"select
placeholder="发票状态"
clearable
style="width: 240px"
@keyup.enter="getClinicRecord"
>
<el-option v-for="item in invoiceStatusList" :key="item.value" :label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="结算时间:" prop="activeFlag">
<el-date-picker
v-model="occurrenceTime"
@@ -38,6 +51,12 @@
</div>
</el-form>
</div>
<div style="float: right; margin: 0 20px 10px 0">
<span style="margin-right: 20px">
{{ '总数:' + count + '/' + '成功:' + successCount }}
</span>
<el-button type="primary" :loading="loading" plain @click="handleBatchProcess">批量开具</el-button>
</div>
<el-table :data="clinicRecord" border>
<!-- <el-table-column label="计算类型" align="center" prop="statusEnum_enumText" /> -->
<el-table-column label="患者姓名" align="center" prop="patientName" :show-overflow-tooltip="true"/>
@@ -140,10 +159,17 @@ const queryParams = ref({
billDateSTime:"",
billDateETime:"",
searchKey:"",
invoiceStatus:1,
kinsEnum: 1
});
const invoiceStatusList = ref([
{ value: 1, label: '已开具' },
{ value: 0, label: '未开具' },
]);
const paymentDetailShow = ref(false)
const clinicRecord = ref([]);
const successCount = ref(0);
const count = ref(0);
const reasonDialogVisible = ref(false);
const reasonForm = ref({
reason: ''
@@ -215,6 +241,49 @@ function handleReset() {
// function handleEdit(row){
// }
const loading = ref(false)
async function handleBatchProcess() {
// 遍历list并异步执行invoiceReissue方法
let list = clinicRecord.value.filter(item =>{
return item.statusEnum == 1 && (item.invoiceNo == undefined || item.invoiceNo == null)
})
loading.value = true
count.value = list.length;
for (const item of list) {
try {
const res = await invoiceReissue({
paymentId: item.id,
encounterId: item.encounterId ? item.encounterId : ""
});
if (res.data) {
// 门诊电子发票开具失败 住院电子发票开具失败 电子发票类型不明确
if (
res.data.includes(" 挂号电子发票开具失败") ||
res.data.includes(" 住院电子发票开具失败") ||
res.data.includes(" 门诊电子发票开具失败") ||
res.data.includes(" 电子发票类型不明确")
) {
// proxy.$message.error(res.data);
} else {
successCount.value++;
// window.open(res.data);
}
}
if (res.code == 200) {
// getLists();
} else {
// proxy.$message.error(res.data);
}
} catch (err) {
console.error(err);
}
}
loading.value = false
getLists()
}
function handleOpen(row,type){
if(type==1){
invoiceReissue({paymentId:row.id,encounterId:row.encounterId?row.encounterId:""}).then((res) => {

View File

@@ -5,41 +5,62 @@ import request from '@/utils/request'
*/
export function getList(queryParams) {
return request({
url: '/charge-manage/charge/encounter-patient-page',
method: 'get',
params: queryParams
url: '/charge-manage/charge/encounter-patient-page',
method: 'get',
params: queryParams
})
}
/**
* 患者处方列表
*/
export function getChargeList(encounterId) {
return request({
url: '/charge-manage/charge/patient-prescription?encounterId=' + encounterId,
method: 'get',
url: '/charge-manage/charge/patient-prescription?encounterId=' + encounterId,
method: 'get',
})
}
/**
* 医保转自费
*/
export function changeToSelfPay(encounterId) {
return request({
url: '/charge-manage/charge/self-pay?encounterId=' + encounterId,
method: 'put',
url: '/charge-manage/charge/self-pay?encounterId=' + encounterId,
method: 'put',
})
}
/**
* 自费转医保
*/
export function changeToMedicalInsurance(encounterId) {
return request({
url: '/charge-manage/charge/medical-insurance?encounterId=' + encounterId,
method: 'put',
url: '/charge-manage/charge/medical-insurance?encounterId=' + encounterId,
method: 'put',
})
}
/**
* 学生医保转学生自费
*/
export function changeStudentPayTosStudentSelf(encounterId) {
return request({
url: '/charge-manage/charge/student-self-pay?encounterId=' + encounterId,
method: 'put',
})
}
/**
* 学生自费转学生医保
*/
export function changeStudentSelfToStudentPay(encounterId) {
return request({
url: '/charge-manage/charge/student-yb-pay?encounterId=' + encounterId,
method: 'put',
})
}
@@ -48,9 +69,9 @@ export function changeToMedicalInsurance(encounterId) {
*/
export function savePayment(data) {
return request({
url: '/payment/payment/charge',
method: 'post',
data: data
url: '/payment/payment/charge',
method: 'post',
data: data
})
}
@@ -59,8 +80,8 @@ export function savePayment(data) {
*/
export function init() {
return request({
url: '/charge-manage/charge/init',
method: 'get',
url: '/charge-manage/charge/init',
method: 'get',
})
}
@@ -69,9 +90,9 @@ export function init() {
*/
export function precharge(data) {
return request({
url: '/payment/payment/precharge',
method: 'post',
data: data
url: '/payment/payment/precharge',
method: 'post',
data: data
})
}
@@ -80,21 +101,32 @@ export function precharge(data) {
*/
export function unprecharge(data) {
return request({
url: '/payment/payment/unprecharge',
method: 'post',
params: data
url: '/payment/payment/unprecharge',
method: 'post',
params: data
})
}
/**
* 发耗材
*/
export function dispenseMedicalConsumables(data) {
return request({
url: '/pharmacy-manage/device-dispense/consumables-dispense',
method: 'put',
data: data
url: '/pharmacy-manage/device-dispense/consumables-dispense',
method: 'put',
data: data
})
}
/**
* 补打小票
*/
export function getChargeInfo(param) {
return request({
url: '/payment/bill/getDetail',
method: 'get',
params: param
})
}

View File

@@ -5,6 +5,7 @@
width="700px"
append-to-body
destroy-on-close
@open="handleOpen"
@close="close"
>
<div v-loading="dialogLoading">
@@ -18,47 +19,55 @@
{{ props.totalAmount.toFixed(2) + ' 元' }}
</el-text>
</div>
<div class="amount-row">
<el-text size="large">折扣金额</el-text>
<el-text size="large" type="warning" class="amount">
{{ discountAmount.toFixed(2) + ' 元' }}
</el-text>
</div>
<!-- 自费支付 -->
<div class="payment-container">
<div v-for="(item, index) in formData.selfPay" :key="index" class="payment-item">
<span>支付方式</span>
<el-select
v-model="item.payEnum"
placeholder="选择支付方式"
style="width: 160px"
@change="clearAmount(index)"
>
<el-option
v-for="payEnum in selfPayMethods"
:key="payEnum.value"
:label="payEnum.label"
:value="payEnum.value"
:disabled="isMethodDisabled(payEnum.value)"
<template v-for="(item, index) in formData.selfPay" :key="index">
<div v-show="item.payEnum != 220500" class="payment-item">
<span>支付方式</span>
<el-select
v-model="item.payEnum"
placeholder="选择支付方式"
style="width: 160px"
@change="clearAmount(index)"
>
<el-option
v-for="payEnum in selfPayMethods"
:key="payEnum.value"
:label="payEnum.label"
:value="payEnum.value"
:disabled="isMethodDisabled(payEnum.value)"
/>
</el-select>
<span>支付金额</span>
<div class="suffix-wrapper">
<el-input-number
v-model="item.amount"
:precision="2"
:min="0"
:max="getMax(index)"
:controls="false"
placeholder="金额"
class="amount-input"
@change="handleAmountChange"
/>
<span class="suffix-text"></span>
</div>
<el-button
type="danger"
circle
:icon="Delete"
@click="removePayment(index)"
v-if="index > 0"
/>
</el-select>
<span>支付金额</span>
<div class="suffix-wrapper">
<el-input-number
v-model="item.amount"
:precision="2"
:min="0"
:max="getMax(index)"
:controls="false"
placeholder="金额"
class="amount-input"
@change="handleAmountChange"
/>
<span class="suffix-text"></span>
</div>
<el-button
type="danger"
circle
:icon="Delete"
@click="removePayment(index)"
v-if="index > 0"
/>
</div>
</template>
<div class="add-payment">
<el-button
type="primary"
@@ -72,6 +81,18 @@
金额已满足应收不可继续添加
</el-text>
</div>
<div style="margin-top: 10px" v-if="userStore.hospitalName == '同一医院'">
<span>折扣</span>
<el-radio-group v-model="discountRadio" @change="handleDiscountChange">
<el-radio-button
v-for="item in charge_discount"
:key="item.value"
link
:label="item.label"
:value="item.value"
/>
</el-radio-group>
</div>
</div>
<div>
<el-table :data="props.details" max-height="200" border>
@@ -105,10 +126,10 @@
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="throttledGetList" :disabled="dialogLoading"
> </el-button
>
<el-button type="primary" @click="print()" :disabled="dialogLoading"> </el-button>
<el-button type="primary" @click="throttledGetList" :disabled="dialogLoading">
</el-button>
<!-- <el-button type="primary" @click="print()" :disabled="dialogLoading"> </el-button> -->
<el-button @click="close" :disabled="dialogLoading"> </el-button>
</div>
</template>
@@ -116,7 +137,7 @@
</template>
<script setup>
import { savePayment, unprecharge, dispenseMedicalConsumables } from './api';
import { savePayment, unprecharge, dispenseMedicalConsumables, getChargeInfo } from './api';
import { computed, watch, reactive, ref, getCurrentInstance, nextTick } from 'vue';
import { Delete } from '@element-plus/icons-vue';
import { debounce } from 'lodash-es';
@@ -170,7 +191,11 @@ const props = defineProps({
const { proxy } = getCurrentInstance();
const { charge_discount } = proxy.useDict('charge_discount');
const userStore = useUserStore();
const discountRadio = ref(undefined);
const discountAmount = ref(0);
const formData = reactive({
totalAmount: 0,
@@ -186,97 +211,105 @@ const dialogLoading = ref(false);
watch(
() => props.totalAmount,
(newValue) => {
nextTick(() => {});
formData.totalAmount = newValue;
formData.selfPay[0].amount = newValue;
}
);
const emit = defineEmits(['close']);
async function printReceipt(param) {
console.log(param, 'param');
console.log(props.patientInfo, 'props.patientInfo');
let displayAmountTemp = 0;
// 打印小票
function printReceipt(param) {
let total = 0;
props.chargedItems.forEach((item) => {
total += item.totalPrice || 0;
});
// 构造一个新的对象,添加头 "data"
const result = {
data: [
{
...param,
// 基础支付类型
YB_FUND_PAY: param.detail.find((t) => t.payEnum === 100000)?.amount ?? 0, // 基金支付总额
SELF_PAY: param.detail.find((t) => t.payEnum === 200000)?.amount ?? 0, // 个人负担总金
OTHER_PAY: param.detail.find((t) => t.payEnum === 300000)?.amount ?? 0, // 其他(如医院负担金额
YB_FUND_PAY:
param.detail?.find((t) => t.payEnum === 100000)?.amount.toFixed(2) + ' 元' ?? 0, // 基金支付总
SELF_PAY: param.detail?.find((t) => t.payEnum === 200000)?.amount.toFixed(2) + ' 元' ?? 0, // 个人负担金额
OTHER_PAY: param.detail?.find((t) => t.payEnum === 300000)?.amount ?? 0, // 其他(如医院负担金额)
// 基本医保统筹基金支出
YB_TC_FUND_AMOUNT: param.detail.find((t) => t.payEnum === 110000)?.amount ?? 0, // 基本医保统筹基金支出
YB_BC_FUND_AMOUNT: param.detail.find((t) => t.payEnum === 120000)?.amount ?? 0, // 补充医疗保险基金支出
YB_JZ_FUND_AMOUNT: param.detail.find((t) => t.payEnum === 130000)?.amount ?? 0, // 医疗救助基金支出
YB_OTHER_AMOUNT: param.detail.find((t) => t.payEnum === 140000)?.amount ?? 0, // 其他支出
YB_TC_FUND_AMOUNT:
param.detail?.find((t) => t.payEnum === 110000)?.amount.toFixed(2) + ' 元' ?? 0, // 基本医保统筹基金支出
YB_BC_FUND_AMOUNT:
param.detail?.find((t) => t.payEnum === 120000)?.amount.toFixed(2) + ' 元' ?? 0, // 补充医疗保险基金支出
YB_JZ_FUND_AMOUNT:
param.detail?.find((t) => t.payEnum === 130000)?.amount.toFixed(2) + ' 元' ?? 0, // 医疗救助基金支出
// YB_OTHER_AMOUNT: param.detail.find((t) => t.payEnum === 140000)?.amount ?? 0, // 其他支出
// 职工基本医疗保险
YB_TC_ZG_FUND_VALUE: param.detail.find((t) => t.payEnum === 110100)?.amount ?? 0, // 职工基本医疗保险
YB_TC_JM_FUND_VALUE: param.detail.find((t) => t.payEnum === 110200)?.amount ?? 0, // 居民基本医疗保险(修正原错误注释)
// YB_TC_ZG_FUND_VALUE: param.detail.find((t) => t.payEnum === 110100)?.amount ?? 0, // 职工基本医疗保险
// YB_TC_JM_FUND_VALUE: param.detail.find((t) => t.payEnum === 110200)?.amount ?? 0, // 居民基本医疗保险(修正原错误注释)
// 补充医疗保险基金支出细分
YB_BC_JM_DB_VALUE: param.detail.find((t) => t.payEnum === 120100)?.amount ?? 0, // 全体参保人的居民大病保险
YB_BC_DE_BZ_VALUE: param.detail.find((t) => t.payEnum === 120200)?.amount ?? 0, // 大额医疗费用补助
YB_BC_ZG_DE_BZ_VALUE: param.detail.find((t) => t.payEnum === 120300)?.amount ?? 0, // 企业职工大额医疗费用补助
YB_BC_GWY_BZ_VALUE: param.detail.find((t) => t.payEnum === 120400)?.amount ?? 0, // 公务员医疗补助
// YB_BC_JM_DB_VALUE: param.detail.find((t) => t.payEnum === 120100)?.amount ?? 0, // 全体参保人的居民大病保险
// YB_BC_DE_BZ_VALUE: param.detail.find((t) => t.payEnum === 120200)?.amount ?? 0, // 大额医疗费用补助
// YB_BC_ZG_DE_BZ_VALUE: param.detail.find((t) => t.payEnum === 120300)?.amount ?? 0, // 企业职工大额医疗费用补助
// YB_BC_GWY_BZ_VALUE: param.detail.find((t) => t.payEnum === 120400)?.amount ?? 0, // 公务员医疗补助
// 其他支出细分
OTHER_PAY_DD_FUND_VALUE: param.detail.find((t) => t.payEnum === 300001)?.amount ?? 0, // 兜底基金支出
OTHER_PAY_YW_SH_FUND_VALUE: param.detail.find((t) => t.payEnum === 300002)?.amount ?? 0, // 意外伤害基金支出
OTHER_PAY_LX_YL_FUND_VALUE: param.detail.find((t) => t.payEnum === 300003)?.amount ?? 0, // 离休人员医疗保障金支出
OTHER_PAY_LX_YH_FUND_VALUE: param.detail.find((t) => t.payEnum === 300004)?.amount ?? 0, // 离休人员优惠金支出
OTHER_PAY_CZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300005)?.amount ?? 0, // 财政基金支出
OTHER_PAY_CZ_YZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300006)?.amount ?? 0, // 财政预支支出
OTHER_PAY_ZG_DB_FUND_VALUE: param.detail.find((t) => t.payEnum === 300007)?.amount ?? 0, // 职工大病基金支出
OTHER_PAY_EY_FUND_VALUE: param.detail.find((t) => t.payEnum === 300008)?.amount ?? 0, // 二乙基金支出
OTHER_PAY_QX_JZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300009)?.amount ?? 0, // 倾斜救助支出
OTHER_PAY_YL_JZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300010)?.amount ?? 0, // 医疗救助再救助基金
HOSP_PART_AMT: param.detail.find((t) => t.payEnum === 300011)?.amount ?? 0, // 医院负担金额
// OTHER_PAY_DD_FUND_VALUE: param.detail.find((t) => t.payEnum === 300001)?.amount ?? 0, // 兜底基金支出
// OTHER_PAY_YW_SH_FUND_VALUE: param.detail.find((t) => t.payEnum === 300002)?.amount ?? 0, // 意外伤害基金支出
// OTHER_PAY_LX_YL_FUND_VALUE: param.detail.find((t) => t.payEnum === 300003)?.amount ?? 0, // 离休人员医疗保障金支出
// OTHER_PAY_LX_YH_FUND_VALUE: param.detail.find((t) => t.payEnum === 300004)?.amount ?? 0, // 离休人员优惠金支出
// OTHER_PAY_CZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300005)?.amount ?? 0, // 财政基金支出
// OTHER_PAY_CZ_YZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300006)?.amount ?? 0, // 财政预支支出
// OTHER_PAY_ZG_DB_FUND_VALUE: param.detail.find((t) => t.payEnum === 300007)?.amount ?? 0, // 职工大病基金支出
// OTHER_PAY_EY_FUND_VALUE: param.detail.find((t) => t.payEnum === 300008)?.amount ?? 0, // 二乙基金支出
// OTHER_PAY_QX_JZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300009)?.amount ?? 0, // 倾斜救助支出
// OTHER_PAY_YL_JZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300010)?.amount ?? 0, // 医疗救助再救助基金
// HOSP_PART_AMT: param.detail.find((t) => t.payEnum === 300011)?.amount ?? 0, // 医院负担金额
// 医保结算返回值
FULAMT_OWNPAY_AMT: param.detail.find((t) => t.payEnum === 1)?.amount ?? 0, // 全自费金额
OVERLMT_SELFPAY: param.detail.find((t) => t.payEnum === 3)?.amount ?? 0, // 超限价自费费用
PRESELFPAY_AMT: param.detail.find((t) => t.payEnum === 4)?.amount ?? 0, // 先行自付金额
INSCP_SCP_AMT: param.detail.find((t) => t.payEnum === 5)?.amount ?? 0, // 符合政策范围金额
ACT_PAY_DEDC: param.detail.find((t) => t.payEnum === 6)?.amount ?? 0, // 实际支付起付线
POOL_PROP_SELFPAY: param.detail.find((t) => t.payEnum === 7)?.amount ?? 0, // 基本医疗保险统筹基金支付比例
BALC: param.detail.find((t) => t.payEnum === 8)?.amount ?? 0, // 余额
FULAMT_OWNPAY_AMT:
param.detail?.find((t) => t.payEnum === 1)?.amount.toFixed(2) + ' 元' ?? 0, // 全自费金额
// OVERLMT_SELFPAY: param.detail.find((t) => t.payEnum === 3)?.amount ?? 0, // 超限价自费费用
// PRESELFPAY_AMT: param.detail.find((t) => t.payEnum === 4)?.amount ?? 0, // 先行自付金额
INSCP_SCP_AMT: param.detail?.find((t) => t.payEnum === 5)?.amount.toFixed(2) + ' 元' ?? 0, // 符合政策范围金额
// ACT_PAY_DEDC: param.detail.find((t) => t.payEnum === 6)?.amount ?? 0, // 实际支付起付线
// POOL_PROP_SELFPAY: param.detail.find((t) => t.payEnum === 7)?.amount ?? 0, // 基本医疗保险统筹基金支付比例
// BALC: param.detail.find((t) => t.payEnum === 8)?.amount ?? 0, // 余额
// 特殊支付方式
SELF_YB_ZH_PAY: param.detail.find((t) => t.payEnum === 210000)?.amount ?? 0, // 个人医保账户支付
SELF_YB_ZH_GJ_VALUE: param.detail.find((t) => t.payEnum === 210100)?.amount ?? 0, // 账户共济支付金额
SELF_CASH_PAY: param.detail.find((t) => t.payEnum === 220000)?.amount ?? 0, // 个人现金支付金额
SELF_VX_PAY: param.detail.find((t) => t.payEnum === 230000)?.amount ?? 0, // 微信支付金额
SELF_ALI_PAY: param.detail.find((t) => t.payEnum === 240000)?.amount ?? 0, // 阿里支付金额
SELF_YB_ZH_PAY:
param.detail?.find((t) => t.payEnum === 210000)?.amount.toFixed(2) + ' 元' ?? 0, // 个人医保账户支付
// SELF_YB_ZH_GJ_VALUE: param.detail.find((t) => t.payEnum === 210100)?.amount ?? 0, // 账户共济支付金额
// SELF_CASH_PAY: param.detail.find((t) => t.payEnum === 220000)?.amount ?? 0, // 个人现金支付金额
// SELF_VX_PAY: param.detail.find((t) => t.payEnum === 230000)?.amount ?? 0, // 微信支付金额
// SELF_ALI_PAY: param.detail.find((t) => t.payEnum === 240000)?.amount ?? 0, // 阿里支付金额
// 现金支付细分
SELF_CASH_VALUE: param.detail.find((t) => t.payEnum === 220400)?.amount ?? 0, // 个人现金支付金额(现金)
SELF_CASH_VX_VALUE: param.detail.find((t) => t.payEnum === 220100)?.amount ?? 0, // 个人现金支付金额(微信)
SELF_CASH_ALI_VALUE: param.detail.find((t) => t.payEnum === 220200)?.amount ?? 0, // 个人现金支付金额(支付宝)
SELF_CASH_UNION_VALUE: param.detail.find((t) => t.payEnum === 220300)?.amount ?? 0, // 个人现金支付金额(银联)
// SELF_CASH_VALUE: param.detail.find((t) => t.payEnum === 220400)?.amount ?? 0, // 个人现金支付金额(现金)
// SELF_CASH_VX_VALUE: param.detail.find((t) => t.payEnum === 220100)?.amount ?? 0, // 个人现金支付金额(微信)
// SELF_CASH_ALI_VALUE: param.detail.find((t) => t.payEnum === 220200)?.amount ?? 0, // 个人现金支付金额(支付宝)
// SELF_CASH_UNION_VALUE: param.detail.find((t) => t.payEnum === 220300)?.amount ?? 0, // 个人现金支付金额(银联)
// 基金类型(扩展)
BIRTH_FUND: param.detail.find((t) => t.payEnum === 510100)?.amount ?? 0, // 生育基金
RETIREE_MEDICAL: param.detail.find((t) => t.payEnum === 340100)?.amount ?? 0, // 离休人员医疗保障基金
URBAN_BASIC_MEDICAL: param.detail.find((t) => t.payEnum === 390100)?.amount ?? 0, // 城乡居民基本医疗保险基金
URBAN_SERIOUS_ILLNESS: param.detail.find((t) => t.payEnum === 390200)?.amount ?? 0, // 城乡居民大病医疗保险基金
MEDICAL_ASSISTANCE: param.detail.find((t) => t.payEnum === 610100)?.amount ?? 0, // 医疗救助基金
GOVERNMENT_SUBSIDY: param.detail.find((t) => t.payEnum === 640100)?.amount ?? 0, // 政府兜底基金
ACCIDENT_INSURANCE: param.detail.find((t) => t.payEnum === 390400)?.amount ?? 0, // 意外伤害基金
CARE_INSURANCE: param.detail.find((t) => t.payEnum === 620100)?.amount ?? 0, // 照护保险基金
FINANCIAL_FUND: param.detail.find((t) => t.payEnum === 360100)?.amount ?? 0, // 财政基金
HOSPITAL_ADVANCE: param.detail.find((t) => t.payEnum === 999900)?.amount ?? 0, // 医院垫付
SUPPLEMENTARY_INSURANCE: param.detail.find((t) => t.payEnum === 390300)?.amount ?? 0, // 城乡居民大病补充保险基金
HEALTHCARE_PREPAYMENT: param.detail.find((t) => t.payEnum === 360300)?.amount ?? 0, // 保健预支基金
// BIRTH_FUND: param.detail.find((t) => t.payEnum === 510100)?.amount ?? 0, // 生育基金
// RETIREE_MEDICAL: param.detail.find((t) => t.payEnum === 340100)?.amount ?? 0, // 离休人员医疗保障基金
// URBAN_BASIC_MEDICAL: param.detail.find((t) => t.payEnum === 390100)?.amount ?? 0, // 城乡居民基本医疗保险基金
// URBAN_SERIOUS_ILLNESS: param.detail.find((t) => t.payEnum === 390200)?.amount ?? 0, // 城乡居民大病医疗保险基金
// MEDICAL_ASSISTANCE: param.detail.find((t) => t.payEnum === 610100)?.amount ?? 0, // 医疗救助基金
// GOVERNMENT_SUBSIDY: param.detail.find((t) => t.payEnum === 640100)?.amount ?? 0, // 政府兜底基金
// ACCIDENT_INSURANCE: param.detail.find((t) => t.payEnum === 390400)?.amount ?? 0, // 意外伤害基金
// CARE_INSURANCE: param.detail.find((t) => t.payEnum === 620100)?.amount ?? 0, // 照护保险基金
// FINANCIAL_FUND: param.detail.find((t) => t.payEnum === 360100)?.amount ?? 0, // 财政基金
// HOSPITAL_ADVANCE: param.detail.find((t) => t.payEnum === 999900)?.amount ?? 0, // 医院垫付
// SUPPLEMENTARY_INSURANCE: param.detail.find((t) => t.payEnum === 390300)?.amount ?? 0, // 城乡居民大病补充保险基金
// HEALTHCARE_PREPAYMENT: param.detail.find((t) => t.payEnum === 360300)?.amount ?? 0, // 保健预支基金
Mr_QR_Code: param.regNo,
sex: props.patientInfo.genderEnum_enumText,
age: props.patientInfo.age,
personType: '职工医保',
fixmedinsName: param.fixmedinsName + '门诊收费明细',
name: props.patientInfo.patientName, // 姓名
gender: props.patientInfo.genderEnum_enumText, // 性别
age: props.patientInfo.age, // 年龄
@@ -284,85 +317,59 @@ async function printReceipt(param) {
currentDate: currentDate.value, // 收费日期
chargedItems: props.chargedItems, // 收费项目
totalAmount: props.totalAmount.toFixed(2) + ' 元', // 应收金额
displayAmount: displayAmount.value + ' 元', // 收金额
itemTotalAmount: total.toFixed(2) + ' 元', // 收金额
displayAmount: displayAmountTemp + ' 元', // 实收金额
returnedAmount: returnedAmount.value + ' 元', // 应找零
userName: userStore.nickName,
},
],
// feeDetial: param.detail, //收费项目,后端还未返回
};
console.log(result, '==result.data==');
const printElements = templateJson;
var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
const printerList = hiprintTemplate.getPrinterList();
console.log(hiprintTemplate, '打印机列表');
hiprintTemplate.print2(result.data[0], {
printer: 'xp',
title: '门诊收费结算单',
});
// // 将对象转换为 JSON 字符串
// let jsonString = JSON.stringify(result, null, 2);
// console.log(jsonString, 'jsonString');
// await CefSharp.BindObjectAsync('boundAsync');
// await boundAsync.printReport(
// '门诊收费明细单.grf',
// jsonString
// )
// .then((response) => {
// //返回结果是jsonString可判断其调用是否成功
// console.log(response, 'response');
// var res = JSON.parse(response);
// if (!res.IsSuccess) {
// proxy.$modal.msgError('调用打印插件失败:' + res.ErrorMessage);
// }
// })
// .catch((error) => {
// proxy.$modal.msgError('调用打印插件失败:' + error);
// });
}
const throttledGetList = debounce(submit, 300);
function handleOpen() {
formData.totalAmount = props.totalAmount;
formData.selfPay[0].amount = props.totalAmount;
}
async function submit() {
displayAmountTemp = displayAmount.value;
console.log(parseFloat(displayAmount.value), 'parseFloat(displayAmount.value)');
console.log(formData.totalAmount, 'formData.totalAmount');
if (parseFloat(displayAmount.value) < formData.totalAmount.toFixed(2)) {
let amount = formData.selfPay
.reduce((sum, item) => {
return sum + (Number(item.amount) || 0);
}, 0)
.toFixed(2);
if (parseFloat(amount) < formData.totalAmount.toFixed(2)) {
proxy.$modal.msgError('请输入正确的结算金额');
return;
}
// if(chrome.webview === undefined) {
// alert('当前版本不支持银联支付');
// }
// else {
// try {
// let jsonResult = await window.chrome.webview.hostObjects.CSharpAccessor.ReadCardAsync();
// let cardInfo = JSON.parse(jsonResult);
// console.log(cardInfo.CardType);
// } catch (error) {
// console.error('调用失败:', error);
// }
// }
dialogLoading.value = true;
savePayment({
// paymentEnum: 0,
// kindEnum: 1,
// patientId: props.patientInfo.patientId,
// chrgBchnoList: props.chrgBchnoList,
chargeItemIds: props.chargeItemIds,
encounterId: props.patientInfo.encounterId,
id: props.paymentId,
paymentDetails: formData.selfPay,
ybMdtrtCertType: props.userCardInfo.psnCertType,
busiCardInfo: props.userCardInfo.busiCardInfo,
// returnedAmount: parseFloat(returnedAmount.value),
})
.then((res) => {
if (res.code == 200) {
printReceipt(res.data);
(formData.selfPay = [{ payEnum: 220100, amount: 0.0, payLevelEnum: 2 }]),
emit('close', 'success', res.msg);
getChargeInfo({ paymentId: props.paymentId }).then((res) => {
printReceipt(res.data);
});
formData.selfPay = [{ payEnum: 220100, amount: 0.0, payLevelEnum: 2 }];
emit('close', 'success', res.msg);
emit('refresh'); // 发送刷新事件给父组件
// 长春大学自动发耗材
if (userStore.fixmedinsCode == 'H22010200672' && props.consumablesIdList.length > 0) {
@@ -419,6 +426,7 @@ const selfPayMethods = [
{ label: '微信', value: 220100 },
{ label: '支付宝', value: 220200 },
{ label: '银联', value: 220300 },
{ label: '优惠', value: 220500 },
];
// 计算剩余可输入金额
@@ -440,6 +448,16 @@ const getMax = (index) => {
return formData.totalAmount - otherSum;
};
// 折扣计算
function handleDiscountChange(value) {
let amount = props.totalAmount * Number(value);
discountAmount.value = props.totalAmount - amount;
formData.selfPay = [
{ payEnum: 220100, amount: amount, payLevelEnum: 2 },
{ payEnum: 220500, amount: discountAmount.value, payLevelEnum: 2 },
];
}
// 检查支付方式是否已使用
const isMethodDisabled = (payEnum) => {
return formData.selfPay.some((item) => item.payEnum === payEnum);
@@ -466,9 +484,15 @@ const clearAmount = (index) => {
// 计算属性
const displayAmount = computed(() => {
return formData.selfPay.reduce((sum, item) => sum + (Number(item.amount) || 0), 0).toFixed(2);
return formData.selfPay
.reduce((sum, item) => {
if (item.payEnum !== 220500) {
return sum + (Number(item.amount) || 0);
}
return sum;
}, 0)
.toFixed(2);
});
const returnedAmount = computed(() => {
const display = parseFloat(displayAmount.value);
if (isNaN(display) || display <= 0) {
@@ -486,8 +510,23 @@ function close() {
// proxy.$modal.msgError(res.message);
// }
// });
formData.totalAmount = 0;
formData.selfPay = [{ payEnum: 220100, amount: 0.0, payLevelEnum: 2 }];
formData.medicalInsurance = {
account: '',
poolPay: 0,
personalPay: 0,
};
// 重置折扣相关状态
discountRadio.value = undefined;
discountAmount.value = 0;
emit('close');
}
defineExpose({
printReceipt,
});
</script>
<style scoped>

View File

@@ -6,8 +6,11 @@
"paperType": "自定义",
"height": 160,
"width": 80,
"paperHeader": 0,
"paperFooter": 450.7086614173229,
"paperNumberDisabled": true,
"paperNumberContinue": true,
"expandCss": "",
"overPrintOptions": {
"content": "",
"opacity": 0.7,
@@ -28,8 +31,6 @@
"layoutRowGap": 0,
"layoutColumnGap": 0
},
"paperHeader": 0,
"paperFooter": 841.8897637795277,
"printElements": [
{
"options": {
@@ -258,10 +259,10 @@
},
{
"options": {
"left": 138,
"left": 99,
"top": 147,
"height": 9.75,
"width": 84,
"height": 15,
"width": 123,
"title": "合计金额",
"field": "itemTotalAmount",
"coordinateSync": false,
@@ -278,7 +279,7 @@
"left": 6,
"top": 171,
"height": 14,
"width": 88.5,
"width": 108,
"title": "应收金额",
"coordinateSync": false,
"widthHeightSync": false,
@@ -292,10 +293,10 @@
},
{
"options": {
"left": 132,
"left": 124.5,
"top": 171,
"height": 14,
"width": 88.5,
"width": 97.5,
"title": "实收金额",
"coordinateSync": false,
"widthHeightSync": false,
@@ -310,9 +311,43 @@
{
"options": {
"left": 6,
"top": 190.5,
"top": 193.5,
"height": 14,
"width": 117,
"width": 108,
"title": "全自费金额",
"coordinateSync": false,
"widthHeightSync": false,
"qrCodeLevel": 0,
"field": "FULAMT_OWNPAY_AMT"
},
"printElementType": {
"title": "文本",
"type": "text"
}
},
{
"options": {
"left": 124.5,
"top": 193.5,
"height": 13.5,
"width": 97.5,
"title": "医保政策金额",
"coordinateSync": false,
"widthHeightSync": false,
"qrCodeLevel": 0,
"field": "INSCP_SCP_AMT"
},
"printElementType": {
"title": "文本",
"type": "text"
}
},
{
"options": {
"left": 6,
"top": 216,
"height": 14,
"width": 108,
"title": "基金支付",
"coordinateSync": false,
"widthHeightSync": false,
@@ -326,10 +361,10 @@
},
{
"options": {
"left": 132,
"top": 190.5,
"left": 124.5,
"top": 216,
"height": 13.5,
"width": 88.5,
"width": 97.5,
"title": "统筹支付",
"coordinateSync": false,
"widthHeightSync": false,
@@ -344,9 +379,9 @@
{
"options": {
"left": 6,
"top": 211.5,
"top": 240,
"height": 14,
"width": 117,
"width": 216,
"title": "个人医保账户支付",
"coordinateSync": false,
"widthHeightSync": false,
@@ -361,43 +396,9 @@
{
"options": {
"left": 6,
"top": 235.5,
"top": 268.5,
"height": 14,
"width": 115.5,
"title": "全自费金额",
"coordinateSync": false,
"widthHeightSync": false,
"qrCodeLevel": 0,
"field": "FULAMT_OWNPAY_AMT"
},
"printElementType": {
"title": "文本",
"type": "text"
}
},
{
"options": {
"left": 133.5,
"top": 235.5,
"height": 14,
"width": 87,
"title": "应找零",
"coordinateSync": false,
"widthHeightSync": false,
"qrCodeLevel": 0,
"field": "returnedAmount"
},
"printElementType": {
"title": "文本",
"type": "text"
}
},
{
"options": {
"left": 6,
"top": 256.5,
"height": 14,
"width": 100,
"width": 106.5,
"title": "收费员",
"coordinateSync": false,
"widthHeightSync": false,
@@ -412,9 +413,9 @@
{
"options": {
"left": 6,
"top": 277.5,
"top": 294,
"height": 14,
"width": 170,
"width": 214.5,
"title": "收费时间",
"coordinateSync": false,
"widthHeightSync": false,

View File

@@ -1,63 +1,31 @@
<template>
<div
style="display: flex; justify-content: space-between"
class="app-container"
v-loading="readCardLoading"
:element-loading-text="loadingText"
>
<div style="display: flex; justify-content: space-between" class="app-container" v-loading="readCardLoading"
:element-loading-text="loadingText">
<el-card style="width: 30%">
<template #header>
<span style="vertical-align: middle">患者列表</span>
</template>
<div style="width: 100%">
<el-input
v-model="queryParams.searchKey"
placeholder="请输入患者名/病历号"
clearable
style="width: 48%; margin-bottom: 10px; margin-right: 10px"
@keyup.enter="getPatientList"
>
<el-input v-model="queryParams.searchKey" placeholder="请输入患者名/病历号" clearable
style="width: 48%; margin-bottom: 10px; margin-right: 10px" @keyup.enter="getPatientList">
<template #append>
<el-button icon="Search" @click="getPatientList" />
</template>
</el-input>
<el-select
v-model="queryParams.statusEnum"
style="width: 48%; margin-bottom: 10px; margin-right: 10px"
placeholder="收费状态"
@change="getPatientList"
>
<el-option
v-for="item in chargeStatusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-select v-model="queryParams.statusEnum" style="width: 48%; margin-bottom: 10px; margin-right: 10px"
placeholder="收费状态" @change="getPatientList">
<el-option v-for="item in chargeStatusOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<div style="width: 100%">
<el-date-picker
v-model="receptionTime"
type="daterange"
range-separator="~"
start-placeholder="开始时间"
end-placeholder="结束时间"
placement="bottom"
value-format="YYYY-MM-DD"
style="width: 84%; margin-bottom: 10px; margin-right: 10px"
@change="getPatientList"
/>
<el-date-picker v-model="receptionTime" type="daterange" range-separator="~" start-placeholder="开始时间"
end-placeholder="结束时间" placement="bottom" value-format="YYYY-MM-DD"
style="width: 84%; margin-bottom: 10px; margin-right: 10px" @change="getPatientList" />
<el-button type="primary" style="margin-bottom: 10px" @click="getPatientList">
搜索
</el-button>
</div>
<el-table
ref="patientListRef"
height="620"
:data="patientList"
row-key="encounterId"
@cell-click="clickRow"
highlight-current-row
>
<el-table ref="patientListRef" height="620" :data="patientList" row-key="encounterId" @cell-click="clickRow"
highlight-current-row>
<el-table-column label="病历号" align="center" prop="encounterBusNo" />
<el-table-column label="姓名" align="center" prop="patientName" />
<!-- <el-table-column label="时间" align="center" prop="receptionTime" width="160">
@@ -80,12 +48,12 @@
{{ patientInfo.genderEnum_enumText }}
</el-descriptions-item>
<el-descriptions-item label="年龄:">{{ patientInfo.age }}</el-descriptions-item>
<el-descriptions-item label="科室:">{{
patientInfo.organizationName
}}</el-descriptions-item>
<el-descriptions-item label="就诊时间:">{{
formatDateStr(patientInfo.receptionTime, 'YYYY-MM-DD HH:mm:ss')
}}</el-descriptions-item>
<el-descriptions-item label="科室:">
{{ patientInfo.organizationName }}
</el-descriptions-item>
<el-descriptions-item label="就诊时间:">
{{ formatDateStr(patientInfo.receptionTime, 'YYYY-MM-DD HH:mm:ss') }}
</el-descriptions-item>
<!-- <el-descriptions-item label="身份证号:">{{ patientInfo.idCard }}</el-descriptions-item> -->
<!-- <el-descriptions-item label="手机号">{{ patientInfo.name }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ patientInfo.name }}</el-descriptions-item> -->
@@ -102,47 +70,31 @@
<el-button type="primary" plain @click="handleReadCard('01')" style="width: 65px">
电子凭证
</el-button>
<el-button
type="primary"
plain
@click="handleReadCard('02')"
style="width: 65px"
:disabled="true"
>
<el-button type="primary" plain @click="handleReadCard('02')" style="width: 65px" :disabled="true">
身份证
</el-button>
<el-button type="primary" plain @click="handleReadCard('03')" style="width: 65px">
医保卡
</el-button>
<el-button
type="primary"
@click="payToSelt()"
style="margin-left: 20px"
:disabled="buttonDisabled"
>
<el-button type="primary" @click="payToSelt()" style="margin-left: 20px" :disabled="buttonDisabled">
医保转自费
</el-button>
<el-button
type="primary"
@click="patToMedicalInsurance()"
style="margin-left: 20px"
:disabled="buttonDisabled"
>
<el-button type="primary" @click="patToMedicalInsurance()" style="margin-left: 20px"
:disabled="buttonDisabled">
自费转医保
</el-button>
<span style="float: right"
>合计金额{{ totalAmounts ? totalAmounts.toFixed(2) : 0 }}</span
>
<el-button type="primary" @click="studentPayTosStudentSelf()" style="margin-left: 20px"
:disabled="buttonDisabled">
学生医保转学生自费
</el-button>
<el-button type="primary" @click="studentSelfToStudentPay()" style="margin-left: 20px"
:disabled="buttonDisabled">
学生自费转学生医保
</el-button>
<span style="float: right">合计金额{{ totalAmounts ? totalAmounts.toFixed(2) : 0 }}</span>
</div>
<el-table
ref="chargeListRef"
height="530"
:data="chargeList"
row-key="id"
@selection-change="handleSelectionChange"
v-loading="chargeLoading"
border
>
<el-table ref="chargeListRef" height="530" :data="chargeList" row-key="id"
@selection-change="handleSelectionChange" v-loading="chargeLoading" :span-method="objectSpanMethod" border>
<el-table-column type="selection" :selectable="checkSelectable" width="55" />
<el-table-column label="单据号" align="center" prop="busNo" width="180" />
<el-table-column label="收费项目" align="center" prop="itemName" width="200" />
@@ -152,10 +104,7 @@
<el-table-column label="费用性质" align="center" prop="contractName" />
<el-table-column label="收费状态" align="center" prop="statusEnum_enumText" width="150">
<template #default="scope">
<el-tag
:type="scope.row.statusEnum === 1 ? 'default' : 'success'"
disable-transitions
>
<el-tag :type="scope.row.statusEnum === 1 ? 'default' : 'success'" disable-transitions>
{{ scope.row.statusEnum_enumText }}
</el-tag>
</template>
@@ -166,9 +115,17 @@
</template>
</el-table-column>
<el-table-column label="收款人" align="center" prop="entererId_dictText" />
<el-table-column label="操作" align="center" fixed="right" header-align="center" class-name="no-hover-column">
<template #default="scope">
<el-button :disabled="!scope.row.paymentId" link type="primary" @click="printCharge(scope.row)">
打印
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
<ChargeDialog
:open="openDialog"
@close="handleClose"
@@ -197,11 +154,15 @@ import {
changeToMedicalInsurance,
init,
precharge,
getChargeInfo,
changeStudentPayTosStudentSelf,
changeStudentSelfToStudentPay,
} from './components/api';
import { invokeYbPlugin } from '@/api/public';
import ChargeDialog from './components/chargeDialog.vue';
import { formatDateStr } from '@/utils';
import useUserStore from '@/store/modules/user';
import Decimal from 'decimal.js';
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
@@ -241,6 +202,20 @@ watch(
(newVlaue) => {
if (newVlaue && newVlaue.length > 0) {
handleTotalAmount();
} else {
totalAmounts.value = 0;
}
},
{ immediate: true }
);
watch(
() => chargeList.value,
(newVlaue) => {
if (newVlaue && newVlaue.length > 0) {
handleTotalAmount();
} else {
totalAmounts.value = 0;
}
},
{ immediate: true }
@@ -249,9 +224,16 @@ function handleSelectionChange(selection) {
selectedRows.value = selection;
}
function handleTotalAmount() {
totalAmounts.value = selectedRows.value.reduce((accumulator, currentRow) => {
return accumulator + (Number(currentRow.totalPrice) || 0);
}, 0);
if (selectedRows.value.length == 0) {
totalAmounts.value = chargeList.value.reduce((accumulator, currentRow) => {
return new Decimal(accumulator).add(currentRow.totalPrice.toFixed(2) || 0);
}, new Decimal(0));
} else {
totalAmounts.value = selectedRows.value.reduce((accumulator, currentRow) => {
return new Decimal(accumulator).add(currentRow.totalPrice.toFixed(2) || 0);
}, 0);
}
}
getPatientList();
initOption();
@@ -346,7 +328,9 @@ function confirmCharge() {
paymentId.value = res.data.paymentId;
chrgBchnoList.value = res.data.chrgBchnoList;
totalAmount.value = res.data.details.find((item) => item.payEnum == 220000).amount;
details.value = res.data.details;
details.value = res.data.details.filter((item) => {
return item.amount > 0;
});
openDialog.value = true;
} else {
proxy.$modal.msgError(res.msg);
@@ -502,6 +486,8 @@ async function handleReadCard(value) {
chargeItemIdList.value = selectRows.map((item) => {
return item.id;
});
// 打印项目赋值
chargedItems.value = selectRows;
consumablesIdList.value = selectRows
.filter((item) => {
return item.serviceTable == 'wor_device_request';
@@ -543,5 +529,80 @@ function patToMedicalInsurance() {
}
});
}
/**
* 学生医保转学生自费
*/
function studentPayTosStudentSelf() {
changeStudentPayTosStudentSelf(encounterId.value).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess('操作成功');
}
});
}
/**
* 学生自费转学生医保
*/
function studentSelfToStudentPay() {
changeStudentSelfToStudentPay(encounterId.value).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess('操作成功');
}
});
}
// 添加行合并方法
function objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// 只对操作列进行合并(根据列索引判断,操作列为最后一列)
if (columnIndex === 10) {
// 操作列索引为10从0开始计数
// 如果当前行的paymentId为空则不合并
if (!row.paymentId) {
return [1, 1];
}
// 查找相同paymentId的连续行
let spanCount = 1;
if (rowIndex === 0 || chargeList.value[rowIndex - 1].paymentId !== row.paymentId) {
// 这是具有相同paymentId的第一行计算需要合并的行数
for (let i = rowIndex + 1; i < chargeList.value.length; i++) {
if (chargeList.value[i].paymentId === row.paymentId) {
spanCount++;
} else {
break;
}
}
return [spanCount, 1];
} else {
// 这不是具有相同paymentId的第一行返回0表示不显示
return [0, 0];
}
}
// 其他列不合并
return [1, 1];
}
function printCharge(row) {
// 打印功能实现
let rows = [];
chargeList.value.forEach((item, index) => {
if (item.paymentId === row.paymentId) {
rows.push(item);
}
});
chargedItems.value = rows;
getChargeInfo({ paymentId: row.paymentId }).then((res) => {
proxy.$refs['chargeDialogRef'].printReceipt(res.data);
});
}
</script>
<style scoped></style>
<style scoped>
:deep(.no-hover-column) .cell:hover {
background-color: transparent !important;
}
:deep(.el-table__body) tr:hover td.no-hover-column {
background-color: inherit !important;
}
</style>

View File

@@ -322,9 +322,13 @@ function handleRefund(row) {
// }, 0);
getReturnDetail({ id: row.paymentId }).then((res) => {
if (res.data.length > 0) {
totalAmount.value = res.data.find((item) => item.payEnum === 220000).amount;
totalAmount.value =
res.data.find((item) => item.payEnum === 220000).amount -
(res.data.find((item) => item.payEnum === 220500)?.amount || 0);
}
details.value = res.data;
details.value = res.data.filter((item) => {
return item.amount > 0;
});
});
paymentId.value = row.paymentId;
patientInfo.value.patientId = row.patientId;

View File

@@ -350,6 +350,7 @@
</template>
<script setup name="PatientAddDialog">
import { watch } from 'vue';
import { watch, defineProps } from "vue";
import pcas from 'china-division/dist/pcas-code.json';
import { addPatient, patientlLists, getOutpatientRegistrationList } from './outpatientregistration';
@@ -711,22 +712,22 @@ watch(
const birthYear = parseInt(newIdCard.substring(6, 10));
const birthMonth = parseInt(newIdCard.substring(10, 12));
const birthDay = parseInt(newIdCard.substring(12, 14));
// 设置出生日期
form.value.birthDate = `${birthYear}-${birthMonth.toString().padStart(2, '0')}-${birthDay.toString().padStart(2, '0')}`;
const today = new Date();
const currentYear = today.getFullYear();
const currentMonth = today.getMonth() + 1;
const currentDay = today.getDate();
let age = currentYear - birthYear;
// 如果当前月份小于出生月份或者月份相同但当前日期小于出生日期则年龄减1
if (
currentMonth < birthMonth ||
(currentMonth === birthMonth && currentDay < birthDay)
) {
if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
age--;
}
form.value.age = age;
form.value.age = age ;
}

View File

@@ -239,6 +239,12 @@
highlight-current
default-expand-all
@node-click="handleNodeClick"
@change="
() => {
form.serviceTypeId = undefined;
setchargeItem;
}
"
@clear="handleOrgClear"
clearable
/>
@@ -414,6 +420,7 @@
key="genderEnum_enumText"
prop="genderEnum_enumText"
/>
<el-table-column label="联系电话" align="center" key="phone" prop="phone" />
<el-table-column
label="科室名称"
align="center"
@@ -758,6 +765,8 @@ const patientInfoList = ref(undefined);
// 费用性质
const contractList = ref(undefined);
// const locationOptions = ref(undefined); // 地点树选项
const doctorList = ref(undefined); // 医生选项
const healthcareList = ref([]); // 挂号项目选项
const doctorList = ref(undefined); // 医生选项(过滤后的)
const allDoctorList = ref(undefined); // 所有医生选项(用于过滤)
const healthcareList = ref(undefined); // 挂号项目选项
@@ -1068,15 +1077,17 @@ function setInfo() {
// 设定费用项管理表单
function setchargeItem() {
const healthcareData = healthcareList.value.filter(
(healthcare) => healthcare.id === form.value.serviceTypeId
);
form.value.locationId_dictText = healthcareData.length > 0 ? healthcareData[0].name : '';
form.value.price = healthcareData.length > 0 ? healthcareData[0].price : '';
form.value.activityPrice = healthcareData.length > 0 ? healthcareData[0].activityPrice : '';
form.value.totalPrice =
healthcareData.length > 0 ? healthcareData[0].price + healthcareData[0].activityPrice : '';
form.value.definitionId = healthcareData.length > 0 ? healthcareData[0].definitionId : '';
if (healthcareList.value.length > 0) {
const healthcareData = healthcareList.value.filter(
(healthcare) => healthcare.id === form.value.serviceTypeId
);
form.value.locationId_dictText = healthcareData.length > 0 ? healthcareData[0].name : '';
form.value.price = healthcareData.length > 0 ? healthcareData[0].price : '';
form.value.activityPrice = healthcareData.length > 0 ? healthcareData[0].activityPrice : '';
form.value.totalPrice =
healthcareData.length > 0 ? healthcareData[0].price + healthcareData[0].activityPrice : '';
form.value.definitionId = healthcareData.length > 0 ? healthcareData[0].definitionId : '';
}
}
/** 处理挂号类型变化 */

View File

@@ -300,16 +300,16 @@ function handleCardClick(item, index) {
}
}
}
::v-deep .el-tabs__header {
:deep(.el-tabs__header) {
padding: 0;
position: relative;
margin: 0 0 5px !important;
}
::v-deep .el-drawer__header {
:deep(.el-drawer__header) {
margin-bottom: 15px !important;
}
::v-deep .el-drawer__body {
:deep(.el-drawer__body) {
padding: 10px !important;
}
.el-badge {

View File

@@ -108,7 +108,7 @@
"top": 58.5,
"height": 13.5,
"width": 145.5,
"title": "机构名称:医院",
"title": "机构名称:长春大学医院",
"coordinateSync": false,
"widthHeightSync": false,
"fontSize": 9,

View File

@@ -357,7 +357,7 @@ async function print() {
...reportValue.value, // 将 reportValue.value 中的所有属性展开到 result 中
nickName: userStore.nickName,
orgName: userStore.orgName,
fixmedinsName: '医院',
fixmedinsName: '长春大学医院',
queryTime: queryTime.value[0] + '~' + queryTime.value[1],
zfAmount: new Decimal(reportValue.value.zhSum || 0).add(reportValue.value.fundSum || 0),
feeAmount: new Decimal(reportValue.value.DIAGNOSTIC_FEE || 0)

View File

@@ -92,7 +92,7 @@
</el-col>
<el-col :span="5">
<span class="label">机构</span>
<span class="value">{{ '医院' }}</span>
<span class="value">{{ userStore.hospitalName }}</span>
</el-col>
<el-col :span="7">
<span class="label">时间</span>
@@ -449,7 +449,7 @@ async function print() {
...reportValue.value, // 将 reportValue.value 中的所有属性展开到 result 中
nickName: userStore.nickName,
orgName: userStore.orgName,
fixmedinsName: '医院',
fixmedinsName: userStore.hospitalName,
createTime: formatDateStr(new Date(), 'YYYY-MM-DD HH:mm:ss'),
scheduler: userStore.nickName,
timeRange: queryTime.value[0] + '~' + queryTime.value[1],

View File

@@ -1,92 +1,94 @@
import request from '@/utils/request'
import request from '@/utils/request';
/**
* 获取患者列表
*/
export function getList(queryParams) {
return request({
export function getList (queryParams) {
return request ({
url: '/outpatient-manage/treatment/encounter-list',
method: 'get',
params: queryParams
})
params: queryParams,
});
}
/**
* 诊疗列表
*/
export function getDisposalList(encounterId) {
return request({
url: '/outpatient-manage/treatment/treatment-list?encounterId=' + encounterId,
export function getDisposalList (encounterId, serviceCategory) {
return request ({
url: '/outpatient-manage/treatment/treatment-list?encounterId=' +
encounterId +
(serviceCategory ? '&serviceCategory=' + serviceCategory : ''),
method: 'get',
})
});
}
/**
* 执行列表
*/
export function getExecuteList(queryParams) {
return request({
export function getExecuteList (queryParams) {
return request ({
url: '/outpatient-manage/treatment/execute-list',
method: 'get',
params: queryParams
})
params: queryParams,
});
}
/**
* 初始化
*/
export function init() {
return request({
export function init () {
return request ({
url: '/outpatient-manage/treatment/init',
method: 'get',
})
});
}
/**
* 执行
*/
export function execute(data) {
return request({
export function execute (data) {
return request ({
url: '/outpatient-manage/treatment/perform',
method: 'put',
data: data
})
data: data,
});
}
/**
* 取消
*/
export function cancel(data) {
return request({
export function cancel (data) {
return request ({
url: '/outpatient-manage/treatment/cancel-perform',
method: 'put',
data: data
})
data: data,
});
}
/**
* 获取执行记录
*/
export function getPerformRecord(params) {
return request({
export function getPerformRecord (params) {
return request ({
url: '/outpatient-manage/treatment/perform-record',
method: 'get',
params: params
})
params: params,
});
}
export function listWesternmedicine(query) {
return request({
export function listWesternmedicine (query) {
return request ({
url: '/pharmacy-manage/western-medicine-dispense/prescription-list',
method: 'get',
params: query
})
params: query,
});
}
export function printBloodCode(query) {
return request({
export function printBloodCode (query) {
return request ({
url: '/outpatient-manage/treatment/blood-transfusion-patch',
method: 'get',
params: query
})
}
params: query,
});
}

View File

@@ -33,7 +33,7 @@
"top": 22.5,
"height": 12,
"width": 88.5,
"title": "医院",
"title": "长春大学医院",
"coordinateSync": false,
"widthHeightSync": false,
"fontSize": 13.5,

View File

@@ -1,25 +1,17 @@
<template>
<el-dialog
title="执行记录"
v-model="props.open"
:model-value="props.open"
width="1000px"
append-to-body
destroy-on-close
@close="close"
@open="openDialog"
>
<el-table
:data="recordList"
highlight-current-row
@row-click="handlePatientSelect"
max-height="650"
style="width: 100%"
border
>
<el-table-column prop="occurrenceTime" label="执行时间" align="center" width="150" />
<el-table :data="recordList" highlight-current-row max-height="650" style="width: 100%" border>
<el-table-column prop="occurrenceTime" label="执行时间" align="center" />
<el-table-column prop="statusEnum_enumText" label="执行状态" align="center" />
<el-table-column prop="orgName" label="执行科室" align="center" width="100" />
<el-table-column prop="practitionerName" label="执行人" align="center" width="100" />
<el-table-column prop="orgName" label="执行科室" align="center" />
<el-table-column prop="practitionerName" label="执行人" align="center" />
</el-table>
<template #footer>
<div class="dialog-footer">
@@ -36,7 +28,7 @@ const props = defineProps({
default: false,
},
recordList: {
type: [],
type: Array,
},
});
const emit = defineEmits(['close']);

View File

@@ -37,7 +37,7 @@
"top": 16.5,
"height": 22.5,
"width": 120,
"title": "医院",
"title": "长春大学医院",
"coordinateSync": false,
"widthHeightSync": false,
"fontFamily": "Microsoft YaHei",

View File

@@ -1,222 +1,311 @@
<template>
<div class="his-container">
<!-- 主体内容区域 -->
<div class="main-content">
<!-- 左侧患者列表区域 -->
<div class="section patient-section">
<div class="section-header">
<div class="section-title">
<i class="el-icon-user"></i>
<h2>患者列表</h2>
</div>
</div>
<div class="search-area">
<el-input
v-model="queryParams.searchKey"
style="width: 45%; margin-bottom: 10px"
placeholder="搜索患者"
clearable
class="search-input"
@keydown.enter="getPatientList"
>
<template #append>
<el-button icon="Search" @click="getPatientList" />
</template>
</el-input>
<el-date-picker
v-model="receptionTime"
@change="getPatientList"
type="daterange"
style="width: 55%; margin-bottom: 10px"
placeholder="挂号时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</div>
<el-table
:data="patientList"
highlight-current-row
@row-click="handlePatientSelect"
max-height="650"
style="width: 100%"
border
>
<el-table-column prop="encounterNo" label="就诊号" align="center" width="150" />
<el-table-column prop="patientName" label="姓名" align="center" />
<el-table-column prop="genderEnum_enumText" label="性别" align="center" width="100" />
<el-table-column prop="age" label="年龄" align="center" width="100" />
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
layout="total, sizes, prev, pager, next"
@pagination="getPatientList"
/>
</div>
<!-- 右侧区域 -->
<div class="right-section">
<!-- 处置项目区域 -->
<div class="section treatment-section">
<div class="section-header">
<div class="section-title">
<i class="el-icon-first-aid-kit"></i>
<h2>处置项目</h2>
<el-button type="primary" plain @click="printBottleLabel()">打印瓶签</el-button>
<el-button type="primary" plain @click="printBloodBarcode()">打印采血条码</el-button>
<el-button type="primary" plain @click="printPrescription()">打印处方</el-button>
<el-button type="primary" plain @click="printDisposal()">打印处置单</el-button>
</div>
</div>
<el-table
:data="activityList"
ref="activityListRef"
height="calc(100% - 60px)"
style="width: 100%"
border
v-loading="loading"
:span-method="operationSpanMethod"
>
<el-table-column type="selection" align="center" width="50" />
<el-table-column label="序号" align="center" prop="sortNumber" width="60" />
<el-table-column align="center" prop="busNo" label="项目编号" width="150" />
<el-table-column align="center" prop="itemName" label="项目名称" />
<!-- <el-table-column align="center" prop="medicationName" label="药品名称" /> -->
<el-table-column
align="center"
prop="serviceCategory_dictText"
label="项目类型"
width="80"
<div class="app-container">
<el-row :gutter="20">
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
<el-card>
<template #header>患者信息</template>
<el-row :gutter="10">
<el-col :span="10" :xs="24" :sm="10" :md="10">
<el-input
v-model="queryParams.searchKey"
placeholder="搜索患者"
clearable
class="search-input"
style="width: 100%"
@keydown.enter="getPatientList"
>
<template #append>
<el-button icon="Search" @click="getPatientList" />
</template>
</el-input>
</el-col>
<el-col :span="14" :xs="24" :sm="14" :md="14">
<el-date-picker
v-model="receptionTime"
@change="getPatientList"
type="daterange"
placeholder="挂号时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
style="width: 100%"
/>
</el-col>
</el-row>
<el-row>
<el-col :span="24" :xs="24">
<el-table
:data="patientList"
highlight-current-row
@row-click="handlePatientSelect"
style="width: 100%; height: calc(100vh - 300px)"
border
>
<el-table-column prop="encounterNo" label="就诊号" align="center" width="150" />
<el-table-column prop="patientName" label="姓名" align="center" />
<el-table-column prop="genderEnum_enumText" label="性别" align="center" />
<el-table-column prop="age" label="年龄" align="center" />
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
layout="total, sizes, prev, pager, next"
@pagination="getPatientList"
/>
</el-col>
</el-row>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="18">
<el-row :gutter="20">
<el-col :xs="24" :sm="24" :md="12" class="mb8">
<el-button
type="primary"
plain
icon="Printer"
@click="printBottleLabel()"
:disabled="isCurrentPatient"
>
<template #default="scope">
{{
scope.row.medCategory
? scope.row.medCategory_dictText
: scope.row.serviceCategory_dictText
}}
</template>
</el-table-column>
<el-table-column align="center" prop="size" label="数量" width="100">
<template #default="scope">
{{ scope.row.quantity + ' ' + scope.row.unitCode_dictText }}
</template>
</el-table-column>
<el-table-column align="center" prop="size" label="规格" width="100" />
<el-table-column align="center" prop="executeNum" label="执行次数" width="90" />
<el-table-column align="center" label="已执行次数" width="90">
<template #default="scope">
{{ scope.row.performCount - scope.row.cancelCount }}
</template>
</el-table-column>
<el-table-column
align="right"
header-align="center"
prop="unitPrice"
label="单价"
width="90"
打印瓶签
</el-button>
<el-button
type="danger"
plain
icon="Printer"
@click="printBloodBarcode()"
:disabled="isCurrentPatient"
>
<template #default="scope">
<span>
打印采血条码
</el-button>
<el-button
type="primary"
plain
icon="Printer"
@click="printPrescription()"
:disabled="isCurrentPatient"
>
打印处方
</el-button>
<el-button
type="danger"
plain
icon="Printer"
@click="printDisposal()"
:disabled="isCurrentPatient"
>
打印处置单
</el-button>
</el-col>
<el-col :xs="24" :sm="12" :md="6">
<el-form
ref="queryRef"
:model="queryParams"
inline-style="width: 100%"
label-width="150px"
:rules="rules"
>
<el-form-item label="处置类型" prop="serviceCategory" label-width="100px">
<el-select
v-model="queryParams.serviceCategory"
placeholder="请选择"
clearable
filterable
style="width: 100%"
@change="handleServiceCategoryChange"
:disabled="isCurrentPatient"
>
<el-option
v-for="item in activityCategoryList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-form>
</el-col>
<el-col :xs="24" :sm="12" :md="6" class="mb8">
<el-button
type="primary"
icon="Check"
@click="handleBatchExecute()"
:disabled="isMultiple"
>
批量执行
</el-button>
<el-button
type="danger"
icon="Delete"
@click="handleBatchCancel()"
:disabled="isMultiple"
>
批量取消
</el-button>
</el-col>
</el-row>
<div class="cards-column">
<el-card class="half-card">
<template #header>处置项目</template>
<el-table
:data="activityList"
ref="activityListRef"
style="width: 100%; height: 100%"
border
v-loading="loading"
:span-method="operationSpanMethod"
@select="handleSelectionChange"
>
<el-table-column type="selection" align="center" width="50" />
<el-table-column label="组" align="center" width="40" prop="groupIcon" />
<!-- <el-table-column label="序号" align="center" prop="sortNumber" width="60" /> -->
<el-table-column align="center" prop="busNo" label="项目编号" width="150" />
<el-table-column align="center" prop="itemName" label="项目名称" />
<el-table-column
align="center"
prop="serviceStatus_enumText"
label="状态"
width="100"
>
<template #default="{ row }">
<el-tag type="primary" size="small">
{{
row.serviceStatus_enumText
? row.serviceStatus_enumText
: row.chargeStatus_enumText
}}
</el-tag>
</template>
</el-table-column>
<el-table-column
align="center"
prop="serviceCategory_dictText"
label="项目类型"
width="80"
>
<template #default="scope">
{{
scope.row.unitPrice ? scope.row.unitPrice.toFixed(2) + ' 元' : '0.00' + ' 元'
scope.row.medCategory
? scope.row.medCategory_dictText
: scope.row.serviceCategory_dictText
}}
</span>
</template>
</el-table-column>
<el-table-column
align="right"
header-align="center"
prop="totalPrice"
label="总价"
width="90"
>
<template #default="scope">
<span>{{
scope.row.totalPrice ? scope.row.totalPrice.toFixed(2) + ' 元' : '0.00' + ' 元'
}}</span>
</template>
</el-table-column>
<el-table-column align="center" prop="serviceStatus_enumText" label="状态" width="100">
<template #default="{ row }">
<el-tag type="primary" size="small">
{{
row.serviceStatus_enumText
? row.serviceStatus_enumText
: row.chargeStatus_enumText
}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="200" fixed="right">
<template #default="{ row }">
<el-button type="text" @click="handleExecute(row)"> 执行 </el-button>
<el-button type="danger" link @click="handleCancel(row)"> 取消 </el-button>
<el-button type="text" @click="getRecord(row)">执行记录</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
</el-table-column>
<el-table-column align="center" prop="size" label="数量" width="100">
<template #default="scope">
<span v-if="scope.row.quantity !== 0 && scope.row.unitCode_dictText">
{{ scope.row.quantity + ' ' + scope.row.unitCode_dictText }}
</span>
<span v-else> - </span>
</template>
</el-table-column>
<el-table-column align="center" prop="size" label="规格" width="100" />
<el-table-column align="center" prop="executeNum" label="执行次数" width="90" />
<el-table-column align="center" label="已执行次数" width="120">
<template #default="scope">
{{ scope.row.performCount - scope.row.cancelCount }}
</template>
</el-table-column>
<el-table-column
align="right"
header-align="center"
prop="unitPrice"
label="单价"
width="90"
>
<template #default="scope">
<span>
{{
scope.row.unitPrice ? scope.row.unitPrice.toFixed(2) + ' 元' : '0.00' + ' 元'
}}
</span>
</template>
</el-table-column>
<el-table-column
align="right"
header-align="center"
prop="totalPrice"
label="总价"
width="90"
>
<template #default="scope">
<span>
{{
scope.row.totalPrice
? scope.row.totalPrice.toFixed(2) + ' 元'
: '0.00' + ' 元'
}}
</span>
</template>
</el-table-column>
<!-- 耗材区域 -->
<div class="section material-section">
<div class="section-header">
<div class="section-title">
<i class="el-icon-box"></i>
<h2>耗材使用</h2>
</div>
</div>
<el-table
:data="deviceList"
height="calc(100% - 60px)"
style="width: 100%"
ref="deviceListRef"
v-loading="loading"
border
>
<el-table-column type="selection" align="center" width="50" />
<el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column prop="itemName" align="center" label="耗材名称" />
<el-table-column prop="size" align="center" label="规格" />
<el-table-column prop="quantity" align="center" label="使用数量">
<template #default="scope">
<span>{{ scope.row.quantity + ' ' + scope.row.unitCode_dictText }}</span>
</template>
</el-table-column>
<el-table-column align="right" header-align="center" prop="unitPrice" label="单价">
<template #default="scope">
<span>{{ scope.unitPrice ? scope.unitPrice.toFixed(2) : '0.00' + ' 元' }}</span>
</template>
</el-table-column>
<el-table-column align="right" header-align="center" prop="totalPrice" label="总价">
<template #default="scope">
<span>{{ scope.totalPrice ? scope.totalPrice.toFixed(2) : '0.00' + ' 元' }}</span>
</template>
</el-table-column>
<el-table-column align="center" prop="serviceStatus_enumText" label="状态">
<template #default="{ row }">
<el-tag type="primary" size="small">
{{ row.dispenseStatus_enumText }}
</el-tag>
</template>
</el-table-column>
<!-- <el-table-column label="操作" width="80">
<template #default="{ row }">
<el-button type="text" size="small" @click="removeMaterial(row)">移除</el-button>
</template>
</el-table-column> -->
</el-table>
<el-table-column
label="操作"
align="center"
width="150"
fixed="right"
class-name="no-hover-column"
>
<template #default="{ row }">
<!-- <el-button type="text" @click="handleExecute(row)"> 执行 </el-button> -->
<!-- <el-button type="danger" link @click="handleCancel(row)"> 取消 </el-button> -->
<el-button link type="primary" icon="EditPen" @click="getRecord(row)">
执行记录
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-card class="half-card">
<template #header> 耗材使用 </template>
<el-table
:data="deviceList"
style="width: 100%; height: 100%"
ref="deviceListRef"
v-loading="loading"
border
>
<el-table-column type="selection" align="center" width="50" />
<el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column prop="itemName" align="center" label="耗材名称" />
<el-table-column align="center" prop="serviceStatus_enumText" label="状态">
<template #default="{ row }">
<el-tag type="primary" size="small">
{{ row.dispenseStatus_enumText }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="size" align="center" label="规格" />
<el-table-column prop="quantity" align="center" label="使用数量">
<template #default="scope">
<span>{{ scope.row.quantity + ' ' + scope.row.unitCode_dictText }}</span>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" prop="unitPrice" label="单价">
<template #default="scope">
<span>
{{ scope.unitPrice ? scope.unitPrice.toFixed(2) : '0.00' + ' 元' }}
</span>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" prop="totalPrice" label="总价">
<template #default="scope">
<span>
{{ scope.totalPrice ? scope.totalPrice.toFixed(2) : '0.00' + ' 元' }}
</span>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</div>
</div>
</el-col>
</el-row>
<PerformRecordDialog :open="openDialog" :recordList="recordList" @close="openDialog = false" />
</div>
</template>
<script setup>
import { getCurrentInstance } from 'vue';
import { getCurrentInstance, ref, computed } from 'vue';
import {
getList,
getDisposalList,
@@ -235,6 +324,7 @@ import { formatDateStr } from '@/utils';
import { hiprint } from 'vue-plugin-hiprint';
import { advicePrint } from '@/api/public';
import useUserStore from '@/store/modules/user';
import { getGroupMarkers } from '@/utils/his';
// 患者搜索
const queryParams = ref({
pageNo: 1,
@@ -254,6 +344,7 @@ const deviceList = ref([]);
// 诊疗项目 + 耗材 打印处置单用
const deviceActivityList = ref([]);
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
// 当前选中的患者
const currentPatient = ref({});
@@ -261,21 +352,40 @@ const recordList = ref([]);
const openDialog = ref(false);
const loading = ref(false);
const activityListRef = ref(null);
const { proxy } = getCurrentInstance();
// 总费用计算
const totalCost = computed(() => {
if (!currentPatient.value.id) return 0;
const treatmentCost = currentPatient.value.treatments.reduce((sum, item) => sum + item.cost, 0);
const materialCost = currentPatient.value.materials.reduce(
(sum, item) => sum + item.cost * item.quantity,
0
const deviceListRef = ref(null);
const rules = ref({
serviceCategory: [{ required: true, message: '请选择处置类型', trigger: 'blur' }],
});
//
const { activity_category_code } = proxy.useDict('activity_category_code');
const activityCategoryList = computed(() => {
const keywords = ['检验', '检查', '治疗'];
return (activity_category_code.value || []).filter((item) =>
keywords.some((k) => String(item.label || '').includes(k))
);
});
const activitySelectedList = ref([]);
const deviceSelectedList = ref([]);
// 是否有批量选择:无任何选择时禁用
const isMultiple = computed(() => {
// 未选择患者或为空对象时禁用
if (!currentPatient.value || Object.keys(currentPatient.value).length === 0) {
return true;
}
// 选中 处置列表
activitySelectedList.value = activityListRef.value?.getSelectionRows
? activityListRef.value.getSelectionRows()
: [];
return treatmentCost + materialCost;
// 选中 耗材列表
deviceSelectedList.value = deviceListRef.value?.getSelectionRows
? deviceListRef.value.getSelectionRows()
: [];
return deviceSelectedList.value.length === 0 && activitySelectedList.value.length === 0;
});
// 是否为当前患者
const isCurrentPatient = computed(() => {
return Object.keys(currentPatient.value).length === 0;
});
getPatientList();
function getPatientList() {
@@ -286,9 +396,32 @@ function getPatientList() {
total.value = res.data.total;
});
}
// 切换处置类型
function handleServiceCategoryChange(value) {
// 就诊id
let encounterId = currentPatient.value.encounterId;
// 处置类型
let serviceCategory = value;
// 如果就诊id和处置类型不为空则获取处置列表
if (encounterId && serviceCategory) {
getDisposalList(encounterId, serviceCategory).then((res) => {
deviceList.value = res.data.records.filter((item) => {
return item.requestTable == 'wor_device_request';
});
activityList.value = res.data.records.filter((item) => {
return (
item.requestTable == 'wor_service_request' ||
item.requestTable == 'med_medication_request'
);
});
deviceActivityList.value = res.data.records.filter((item) => {
return item.deviceCategory == '7' || item.serviceCategory == '21';
});
});
}
}
function handlePatientSelect(row) {
console.log(row, 3456789);
loading.value = true;
currentPatient.value = row;
getDisposalList(row.encounterId).then((res) => {
@@ -300,14 +433,84 @@ function handlePatientSelect(row) {
item.requestTable == 'wor_service_request' || item.requestTable == 'med_medication_request'
);
});
activityList.value = getGroupMarkers(activityList.value);
deviceActivityList.value = res.data.records.filter((item) => {
return item.deviceCategory == '7' || item.serviceCategory == '21';
});
loading.value = false;
console.log(activityList.value, 345678);
});
}
// 批量操作校验
function handleBatchValidate(type) {
let params = [];
// 是否批量选择了数据
if (isMultiple.value) {
proxy.$modal.msgError('请选择要执行的项目');
return;
}
if (type === 'execute') {
let activityList = activitySelectedList.value
.filter((item) => {
return item.chargeStatus === 5;
})
.map((item) => {
return {
requestId: item.requestId,
dispenseId: item.dispenseId,
requestTable: item.requestTable,
chargeStatus: item.chargeStatus_enumText,
dispenseStatus: item.dispenseStatus_enumText,
name: item.itemName,
};
});
let deviceList = deviceSelectedList.value
.filter((item) => {
return item.dispenseStatus === 2;
})
.map((item) => {
return {
requestId: item.requestId,
dispenseId: item.dispenseId,
requestTable: item.requestTable,
chargeStatus: item.chargeStatus_enumText,
dispenseStatus: item.dispenseStatus_enumText,
name: item.itemName,
};
});
return [...activityList, ...deviceList];
} else if (type === 'cancel') {
let list = [...activitySelectedList.value, ...deviceSelectedList.value];
list.forEach((item) => {
params.push({
requestId: item.requestId,
dispenseId: item.dispenseId,
requestTable: item.requestTable,
});
});
return list;
}
}
// 批量执行
function handleBatchExecute() {
// 获取校验后数据
let params = handleBatchValidate('execute');
// 如果参数数组为空 不执行
if (params.length == 0) {
proxy.$modal.msgError('不存在需要执行的处置或耗材!');
return;
}
// 执行批量操作
execute(params).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess('执行成功');
handlePatientSelect(currentPatient.value);
} else {
proxy.$modal.msgError(res.message);
}
});
}
// 单个执行
function handleExecute(row) {
let data = {
requestId: row.requestId,
@@ -316,7 +519,9 @@ function handleExecute(row) {
};
let params = activityList.value
.filter((item) => {
return item.groupId == row.groupId;
return (
(item.medCategory != null || item.medCategory != undefined) && item.groupId == row.groupId
);
})
.map((item) => {
return {
@@ -325,14 +530,16 @@ function handleExecute(row) {
requestTable: item.requestTable,
};
});
let list = proxy.$refs.deviceListRef.getSelectionRows().map((item) => {
let list = (
deviceListRef.value?.getSelectionRows ? deviceListRef.value.getSelectionRows() : []
).map((item) => {
return {
requestId: item.requestId,
dispenseId: item.dispenseId,
requestTable: item.requestTable,
};
});
list.push(data);
params.push(...list);
execute(params).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess('执行成功');
@@ -346,7 +553,7 @@ function handleExecute(row) {
// 添加操作列的合并方法
function operationSpanMethod({ row, column, rowIndex, columnIndex }) {
// 操作列是最后一列索引为11 (从0开始)
if (columnIndex === 11) {
if (columnIndex === 12) {
const groupId = row.groupId;
// 如果没有groupId则不合并
if (groupId === undefined || groupId === null) {
@@ -377,6 +584,7 @@ function operationSpanMethod({ row, column, rowIndex, columnIndex }) {
return [1, 1];
}
// 打印处方
function printPrescription() {
// 取出状态为已收费已发药的requestId
let requestIds = activityList.value
@@ -387,6 +595,10 @@ function printPrescription() {
return item.requestId;
})
.join(',');
if (requestIds.length == 0) {
proxy.$modal.msgWarning('没有可打印的处方!');
return;
}
advicePrint({ requestIds: requestIds, isPrescription: 1 }).then((res) => {
// 按 sortNumber 排序
const sortedList = res.data.adviceItemList.sort((a, b) => {
@@ -430,7 +642,7 @@ function printPrescription() {
}); //开始打印
});
}
// 打印处置单
function printDisposal() {
let requestIds = deviceActivityList.value
.map((item) => {
@@ -469,6 +681,7 @@ function isFirstRowInGroup(rowIndex) {
return true;
}
// 打印血条码
function printBloodBarcode() {
const selectedRows = activityListRef.value.getSelectionRows();
if (selectedRows.length === 0) {
@@ -488,6 +701,27 @@ function printBloodBarcode() {
}
}
// 批量取消
function handleBatchCancel() {
// 获取校验后数据
let params = handleBatchValidate('cancel');
// 如果参数数组为空 不执行
if (params.length == 0) {
proxy.$modal.msgError('不存在需要执行的处置或耗材!');
return;
}
//
cancel(params).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess('操作成功');
handlePatientSelect(currentPatient.value);
} else {
proxy.$modal.msgError(res.message);
}
});
}
// 单个取消
function handleCancel(row) {
let data = {
requestId: row.requestId,
@@ -514,13 +748,22 @@ function handleCancel(row) {
}
});
}
// 打印瓶贴
function printBottleLabel() {
let result = [];
// 过滤出全部输液药品
let printLiist = activityList.value.filter((item) => {
return item.medCategory == '2';
});
let selectRows = activityListRef.value.getSelectionRows();
let printLiist = [];
// 有选中的优先打印选中行,没有的话打印全部的输液药品
if (selectRows.length > 0) {
printLiist = selectRows.filter((item) => {
return item.medCategory == '2' || item.medCategory == '1';
});
} else {
printLiist = activityList.value.filter((item) => {
return item.medCategory == '2' || item.medCategory == '1';
});
}
// 按照groupId分组但将多天的项目展开为独立项目
let expandedList = [];
@@ -585,6 +828,7 @@ function printBottleLabel() {
var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
console.log(result, '打印机列表');
hiprintTemplate.print2(result, {
// printer: 'Xprinter XP-365B',
height: 210,
width: 148,
});
@@ -599,6 +843,18 @@ function printBottleLabel() {
});
}
// 选择框改变时的处理
function handleSelectionChange(selection, row) {
const isSelected = selection.some((item) => item.requestId === row.requestId);
activityList.value
.filter((item) => {
return item.groupId && item.groupId == row?.groupId;
})
.forEach((row) => {
activityListRef.value.toggleRowSelection(row, isSelected);
});
}
function getRecord(row) {
getPerformRecord({ reqId: row.requestId }).then((res) => {
recordList.value = res.data;
@@ -618,26 +874,6 @@ function getRecord(row) {
box-sizing: border-box;
}
.main-content {
display: flex;
flex: 1;
gap: 20px;
overflow: hidden;
height: calc(100% - 70px);
}
.patient-section {
min-width: 400px;
width: 28%;
background: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
padding: 20px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.right-section {
flex: 2;
display: flex;
@@ -646,6 +882,28 @@ function getRecord(row) {
min-width: 600px;
}
.cards-column {
display: flex;
flex-direction: column;
gap: 12px;
height: calc(90vh - 140px);
min-height: 300px;
}
.half-card {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
.half-card :deep(.el-card__body) {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
.current-patient {
background: white;
border-radius: 12px;
@@ -773,4 +1031,12 @@ function getRecord(row) {
width: 200px;
margin-bottom: 10px;
}
:deep(.no-hover-column) .cell:hover {
background-color: transparent !important;
}
:deep(.el-table__body) tr:hover td.no-hover-column {
background-color: inherit !important;
}
</style>

View File

@@ -27,7 +27,7 @@
<span>CF0000000001</span>
</div>
<div style="text-align: center">
<h2>医院</h2>
<h2>长春大学医院</h2>
</div>
<div style="text-align: center">
<h3>处方单</h3>

View File

@@ -112,7 +112,7 @@ import historicalPrescriptionDetail from './component/details.vue';
import Prescription from './component/prescription.vue';
const { proxy } = getCurrentInstance();
const { item_type } = proxy.useDict('item_type');
const { item_category_code } = proxy.useDict('item_category_code');
const prescriptionNo = ref('');
const typeDetail = ref('1');
const purchaseinventoryList = ref([]);

View File

@@ -36,8 +36,10 @@
<el-table-column label="单次剂量" align="center">
<template #default="scope">
<span>
{{
parseFloat(scope.row.dose).toFixed(2) === '0.00'
{{
!scope.row.dose || isNaN(parseFloat(scope.row.dose))
? '-'
: parseFloat(scope.row.dose).toFixed(2) === '0.00'
? '-'
: parseFloat(scope.row.dose).toFixed(2) + scope.row.doseUnitCode_dictText
}}
@@ -46,8 +48,13 @@
</el-table-column>
<el-table-column label="规格" align="center" prop="volume" />
<el-table-column label="用法" align="center" prop="methodCode_dictText" />
<el-table-column label="库存名称" align="center">
<template #default="scope">{{ getLocationName(scope.row) }}</template>
<!-- 修改价格列从inventoryList中获取价格 -->
<el-table-column label="价格" align="center">
<template #default="scope">
<span>
{{ getPriceFromInventory(scope.row) }}
</span>
</template>
</el-table-column>
<el-table-column label="库存数量" align="center">
<template #default="scope">{{ handleQuantity(scope.row) }}</template>
@@ -199,19 +206,31 @@ watch(
// 全部类型
queryParams.value.adviceTypes = '1,2,3';
}
// 设置categoryCode筛选条件用于筛选西药和中成药
if (newValue.categoryCode) {
queryParams.value.categoryCode = newValue.categoryCode;
} else {
queryParams.value.categoryCode = undefined;
}
console.log('发送请求参数:', queryParams.value);
getList();
throttledGetList();
},
{ deep: true, immediate: true }
{ deep: true }
);
getList();
function getList() {
queryParams.value.organizationId = props.patientInfo.orgId;
getAdviceBaseInfo(queryParams.value).then((res) => {
if (res.data.records.length > 0) {
adviceBaseList.value = res.data.records.filter((item) => {
if (item.adviceType == 1 || item.adviceType == 2) {
return handleQuantity(item) != 0;
} else {
return true;
}
});
total.value = res.data.total;
nextTick(() => {
currentIndex.value = 0;
// adviceBaseRef.value.setCurrentRow(adviceBaseList.value[0]);
});
}
});
}
// 从priceList列表中获取价格
function getPriceFromInventory(row) {
if (row.priceList && row.priceList.length > 0) {
@@ -441,6 +460,7 @@ defineExpose({
<style scoped>
.popover-table-wrapper:focus {
outline: 2px solid #409eff; /* 聚焦时的高亮效果 */
outline: 2px solid #409eff;
/* 聚焦时的高亮效果 */
}
</style>

View File

@@ -543,6 +543,16 @@ export function saveTcmDiagnosis(data) {
})
}
/**
* 删除中医诊断
*/
export function deleteTcmDiagnosis(syndromeGroupNo) {
return request({
url: '/doctor-station/chinese-medical/tcm-diagnosis?syndromeGroupNo=' + syndromeGroupNo,
method: 'delete',
})
}
/**
* 保存中医医嘱
*/
@@ -707,11 +717,11 @@ export function getOrderGroup(data) {
}
/**
* 查询诊疗项目耗材绑定信息
* 查询项目绑定信息
*/
export function getActivityBindDevice(data) {
export function getBindDevice(data) {
return request({
url: '/doctor-station/advice/activity-bind-device-info',
url: '/doctor-station/advice/order-bind-info',
method: 'get',
params: data
})

View File

@@ -2,61 +2,36 @@
<div>
<el-row :gutter="24">
<el-col :span="4" :xs="24">
<el-input
v-model="diagnosis"
placeholder="诊断名称"
clearable
style="width: 100%; margin-bottom: 10px"
@keyup.enter="queryDiagnosisUse"
>
<el-input v-model="diagnosis" placeholder="诊断名称" clearable style="width: 100%; margin-bottom: 10px"
@keyup.enter="queryDiagnosisUse">
<template #append>
<el-button icon="Search" @click="queryDiagnosisUse" />
</template>
</el-input>
<el-tree
ref="treeRef"
:data="tree"
node-key="id"
:props="{ label: 'name', children: 'children' }"
highlight-current
default-expand-all
:filter-node-method="filterNode"
@node-click="handleNodeClick"
>
<el-tree ref="treeRef" :data="tree" node-key="id" :props="{ label: 'name', children: 'children' }"
highlight-current default-expand-all :filter-node-method="filterNode" @node-click="handleNodeClick">
<template #default="{ node, data }">
<div class="custom-tree-node">
<span>{{ node.label }}</span>
<span class="tree-node-actions">
<template v-if="node.level === 1 && data.name != '常用' && data.name != '历史'">
<el-button
style="color: #000000"
type="text"
size="small"
@click.stop="addChild(data)"
>
<el-icon><Plus /></el-icon>
<el-button style="color: #000000" type="text" size="small" @click.stop="addChild(data)">
<el-icon>
<Plus />
</el-icon>
</el-button>
</template>
<el-popconfirm
width="200"
:hide-after="10"
title="确认删除此常用诊断吗"
placement="top-start"
@confirm="deleteChild(data)"
>
<el-popconfirm width="200" :hide-after="10" title="确认删除此常用诊断吗" placement="top-start"
@confirm="deleteChild(data)">
<template #reference>
<el-button
style="color: #000000"
v-if="
node.level === 2 &&
node.parent.data.name != '常用' &&
node.parent.data.name != '历史'
"
type="text"
size="small"
@click.stop=""
>
<el-icon><Minus /></el-icon>
<el-button style="color: #000000" v-if="
node.level === 2 &&
node.parent.data.name != '常用' &&
node.parent.data.name != '历史'
" type="text" size="small" @click.stop="">
<el-icon>
<Minus />
</el-icon>
</el-button>
</template>
</el-popconfirm>
@@ -78,25 +53,15 @@
<el-table-column label="序号" type="index" width="50" />
<el-table-column label="诊断排序" align="center" prop="diagSrtNo" width="120">
<template #default="scope">
<el-form-item
:prop="`diagnosisList.${scope.$index}.diagSrtNo`"
:rules="rules.diagSrtNo"
>
<el-input-number
v-model="scope.row.diagSrtNo"
controls-position="right"
:controls="false"
style="width: 80px"
/>
<el-form-item :prop="`diagnosisList.${scope.$index}.diagSrtNo`" :rules="rules.diagSrtNo">
<el-input-number v-model="scope.row.diagSrtNo" controls-position="right" :controls="false"
style="width: 80px" />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="诊断类别" align="center" prop="diagSrtNo" width="180">
<template #default="scope">
<el-form-item
:prop="`diagnosisList.${scope.$index}.medTypeCode`"
:rules="rules.medTypeCode"
>
<el-form-item :prop="`diagnosisList.${scope.$index}.medTypeCode`" :rules="rules.medTypeCode">
<el-select v-model="scope.row.medTypeCode" placeholder=" " style="width: 150px">
<el-option
v-for="item in diag_type"
@@ -111,25 +76,12 @@
<el-table-column label="诊断名称" align="center" prop="name">
<template #default="scope">
<el-form-item :prop="`diagnosisList.${scope.$index}.name`" :rules="rules.name">
<el-popover
:popper-style="{ padding: '0' }"
placement="bottom-start"
:visible="scope.row.showPopover"
trigger="manual"
:width="800"
>
<diagnosislist
:diagnosisSearchkey="diagnosisSearchkey"
@selectDiagnosis="handleSelsectDiagnosis"
/>
<el-popover :popper-style="{ padding: '0' }" placement="bottom-start" :visible="scope.row.showPopover"
trigger="manual" :width="800">
<diagnosislist :diagnosisSearchkey="diagnosisSearchkey" @selectDiagnosis="handleSelsectDiagnosis" />
<template #reference>
<el-input
v-model="scope.row.name"
placeholder="请选择诊断"
@input="handleChange"
@focus="handleFocus(scope.row, scope.$index)"
@blur="handleBlur(scope.row)"
/>
<el-input v-model="scope.row.name" placeholder="请选择诊断" @input="handleChange"
@focus="handleFocus(scope.row, scope.$index)" @blur="handleBlur(scope.row)" />
</template>
</el-popover>
</el-form-item>
@@ -169,11 +121,7 @@
</el-table-column>
<el-table-column label="操作" align="center" width="130">
<template #default="scope">
<el-button
link
type="primary"
@click="handleDeleteDiagnosis(scope.row, scope.$index)"
>
<el-button link type="primary" @click="handleDeleteDiagnosis(scope.row, scope.$index)">
删除
</el-button>
</template>
@@ -182,16 +130,9 @@
</el-form>
</el-col>
</el-row>
<diagnosisdialog
:openDiagnosis="openDiagnosis"
@close="closeDiagnosisDialog"
:radio="orgOrUser"
/>
<AddDiagnosisDialog
:openAddDiagnosisDialog="openAddDiagnosisDialog"
:patientInfo="props.patientInfo"
@close="closeDiagnosisDialog"
/>
<diagnosisdialog :openDiagnosis="openDiagnosis" @close="closeDiagnosisDialog" :radio="orgOrUser" />
<AddDiagnosisDialog :openAddDiagnosisDialog="openAddDiagnosisDialog" :patientInfo="props.patientInfo"
@close="closeDiagnosisDialog" />
</div>
</template>
@@ -208,6 +149,7 @@ import {
getChronicDisease,
getTcmDiagnosis,
delEncounterDiagnosis,
deleteTcmDiagnosis,
isFoodDiseasesNew,
} from '../api';
import diagnosisdialog from '../diagnosis/diagnosisdialog.vue';
@@ -280,7 +222,6 @@ function getList() {
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
emits('diagnosisSave', false);
console.log(form.value.diagnosisList);
}
});
@@ -298,7 +239,6 @@ function getList() {
});
}
emits('diagnosisSave', false);
console.log(form.value.diagnosisList);
}
});
@@ -553,7 +493,7 @@ function closeDiagnosisDialog(str) {
getTree();
}
function queryDiagnosisUse(value) {}
function queryDiagnosisUse(value) { }
function handleChange(value) {
diagnosisSearchkey.value = value;
@@ -627,6 +567,7 @@ defineExpose({ getList, getDetail, handleSaveDiagnosis });
.el-checkbox.is-bordered.el-checkbox--small {
background-color: #ffffff;
}
.custom-tree-node {
display: flex;
align-items: center;

View File

@@ -9,8 +9,8 @@
@cell-click="clickRow"
>
<el-table-column label="模板名称" align="center" prop="templateName" />
<el-table-column label="使用范围" align="center" prop="useScopeCode" />
<el-table-column label="操作" align="center">
<!-- <el-table-column label="使用范围" align="center" prop="useScopeCode" /> -->
<el-table-column label="操作" align="center" width="100">
<template #default="scope">
<el-button link type="primary" @click.stop="handelDelete(scope.row)">删除</el-button>
</template>
@@ -43,7 +43,11 @@ const props = defineProps({
required: true,
},
});
<<<<<<< HEAD
getList();
=======
getList();
>>>>>>> upstream/develop
function getList() {
queryParams.value.useScopeCode = 1;
getEmrTemplateList(queryParams.value).then((res) => {

View File

@@ -743,7 +743,6 @@ function selectMedRow(key, row, index) {
const item = list.sort((a, b) => {
return new Date(b.begndate) - new Date(a.begndate);
});
//debugger
if (item.length > 0) {
if (item[0].medChrgitmType != '11' && item[0].medChrgitmType != '09') {
form.medicationInfoList.shift();

View File

@@ -11,14 +11,8 @@
</div>
<div>处方信息</div>
<el-table
max-height="650"
ref="eprescriptionRef"
:data="prescriptionList"
row-key="prescriptionNo"
border
@selection-change="handleSelectionChange"
>
<el-table max-height="650" ref="eprescriptionRef" :data="prescriptionList" row-key="prescriptionNo" border
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" :selectable="selectable" />
<el-table-column label="处方号" align="center" prop="prescriptionNo" width="200" sortable>
<template #default="scope">
@@ -46,16 +40,8 @@
<span v-if="!scope.row.isEdit">
{{ scope.row.validityDays }}
</span>
<el-input-number
v-else
:min="0"
controls-position="right"
:controls="false"
v-model="scope.row.validityDays"
placeholder=""
@input="handleValidityDaysChange(scope.$index, $event)"
style="width: 90%"
/>
<el-input-number v-else :min="0" controls-position="right" :controls="false" v-model="scope.row.validityDays"
placeholder="" @input="handleValidityDaysChange(scope.$index, $event)" style="width: 90%" />
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="statusEnum_enumText" width="80">
@@ -65,13 +51,7 @@
</span>
</template>
</el-table-column>
<el-table-column
label="开方医师"
align="center"
prop="practitionerName"
header-align="center"
width="90"
>
<el-table-column label="开方医师" align="center" prop="practitionerName" header-align="center" width="90">
<template #default="scope">
<span v-if="!scope.row.isEdit">
{{ scope.row.practitionerName }}
@@ -138,44 +118,19 @@
<el-table-column label="操作" align="center" width="220" fixed="right">
<template #default="scope">
<el-button link type="primary" icon="View" @click="handleView(scope.row)">查看</el-button>
<el-button
link
type="primary"
icon="Edit"
@click="handleEdit(scope.row)"
:disabled="scope.row.statusEnum == 2 || scope.row.statusEnum == 3 || scope.row.statusEnum == 6"
>编辑</el-button
>
<el-button
link
type="primary"
icon="Plus"
@click="savePrescriptionData(scope.row, scope.$index)"
:disabled="!scope.row.isEdit"
>保存</el-button
>
<el-button link type="primary" icon="Edit" @click="handleEdit(scope.row)"
:disabled="scope.row.statusEnum == 2 || scope.row.statusEnum == 3 || scope.row.statusEnum == 6">编辑</el-button>
<el-button link type="primary" icon="Plus" @click="savePrescriptionData(scope.row, scope.$index)"
:disabled="!scope.row.isEdit">保存</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
style="margin-bottom: 5px"
/>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" style="margin-bottom: 5px" />
<eprescriptiondialog
ref="prescriptionDialogRef"
:openPrescription="openPrescription"
:patient="props.patientInfo"
:prescriptionType="prescriptionTypeList"
:medicationInfo="medicationInfoList"
:prescriptionData="prescriptionInfo"
:title="title"
@close="closePrescriptionDialog"
/>
<eprescriptiondialog ref="prescriptionDialogRef" :openPrescription="openPrescription" :patient="props.patientInfo"
:prescriptionType="prescriptionTypeList" :medicationInfo="medicationInfoList" :prescriptionData="prescriptionInfo"
:title="title" @close="closePrescriptionDialog" />
</div>
</template>
@@ -285,20 +240,12 @@ getElepPrescriptionInit();
/** 处方信息取得 */
function getList() {
console.log(
queryParams.value,
'queryParams.value电子处方',
props.patientInfo,
'props.patientInfo'
);
prescriptionList.value = [];
medicationInfoList.value = [];
prescriptionNoTemp.value = undefined;
queryParams.value.patientId = props.patientInfo.patientId;
console.log(queryParams.value, 'queryParams.value电子处方');
getPrescriptionInfo(queryParams.value).then((res) => {
prescriptionList.value = res.data.records;
console.log(res, '电子处方列表');
total.value = res.data.total;
});
}
@@ -307,13 +254,11 @@ function getList() {
function getElepPrescriptionInit() {
elepPrescriptionInit().then((res) => {
prescriptionTypeList.value = res.data.rxTypeCodeListOptions;
console.log(res, '电子处方下拉框');
});
}
/** 选择条数 */
function handleSelectionChange(selection) {
console.log(selection, 'selection');
selectDataList.value = selection.map((item) => ({ ...item })); // 存储选择的行数据
prescriptionNos.value = selection.map((item) => item.prescriptionNo);
ids.value = selection
@@ -341,7 +286,6 @@ function handleAddPrescription() {
*/
function selectable(row, index) {
// 返回 true 表示该行可选,返回 false 表示该行不可选
// console.log(row, 'selectable', rowIndex.value);
return ![2, 3, 6].includes(row.statusEnum);
}
@@ -359,7 +303,6 @@ function handleView(row) {
prescriptionInfo.value.extensionReason = row.extensionReason;
prescriptionInfo.value.rxTypeCode = row.rxTypeCode;
prescriptionInfo.value.prescriptionNo = row.prescriptionNo;
console.log(queryMedicationParams.value, '处方详细的药品信息参数', row.prescriptionNo);
getMedicationInfo(queryMedicationParams.value).then((response) => {
medicationInfoList.value = response.data.records;
medicationInfoList.value.forEach((medicationInfo) => {
@@ -369,7 +312,6 @@ function handleView(row) {
prescriptionInfo.value.conditionId = response.data.records[0].conditionId;
openPrescriptionDialog();
console.log(response, '处方详细的药品信息', medicationInfoList.value);
});
}
@@ -385,7 +327,6 @@ function handleEdit(row) {
prescriptionInfo.value.extensionReason = row.extensionReason;
prescriptionInfo.value.rxTypeCode = row.rxTypeCode;
prescriptionInfo.value.prescriptionNo = row.prescriptionNo;
console.log(queryMedicationParams.value, '处方详细的药品信息参数', row.prescriptionNo);
getMedicationInfo(queryMedicationParams.value).then((response) => {
medicationInfoList.value = response.data.records;
medicationInfoList.value.forEach((medicationInfo) => {
@@ -393,7 +334,6 @@ function handleEdit(row) {
});
prescriptionInfo.value.conditionId = response.data.records[0].conditionId;
openPrescriptionDialog();
console.log(response, '处方详细的药品信息', medicationInfoList.value);
});
}
@@ -419,7 +359,6 @@ function openPrescriptionDialog() {
nextTick(() => {
proxy.$refs['prescriptionDialogRef'].getPrescriptionNoInit();
});
console.log(openPrescription.value, '打开新增处方弹窗');
}
/**
@@ -456,10 +395,8 @@ async function savePrescriptionData(row, index) {
rxTypeCode: row.rxTypeCode,
};
console.log(updateParam, ' 保存处方updateParam');
updatePrescriptionInfo(updateParam).then((response) => {
if (response.code == 200) {
console.log(response, '保存成功');
proxy.$modal.msgSuccess('保存成功');
getList();
} else {
@@ -467,7 +404,6 @@ async function savePrescriptionData(row, index) {
}
});
// } catch (error) {
// console.log('验证失败:', error);
// // 验证失败,不执行保存
// }
}
@@ -513,7 +449,6 @@ function deletePrescription(index) {
idList: ids.value,
prescriptionNoList: prescriptionNos.value,
};
console.log('deletePrescription删除', data);
proxy.$modal
.confirm('是否确认删除以上数据!')
.then(function () {
@@ -530,13 +465,12 @@ function deletePrescription(index) {
// form.value.medicationInfoList.forEach((medicationInfo) => {
// medicationInfo.isEdit = false;
// });
// console.log(response, '处方详细的药品信息', form.value.medicationInfoList);
// totalMedication.value = response.data.total;
// });
// }
proxy.$modal.msgSuccess('删除成功');
})
.catch(() => {});
.catch(() => { });
}
defineExpose({ getList });

View File

@@ -0,0 +1,60 @@
/*
* @Author: sjjh
* @Date: 2025-09-20 17:02:37
* @Description:
*/
import request from '@/utils/request'
// ====== 文书记录
// 新增记录
export function addRecord(data) {
return request({
url: '/document/record/addRecord',
method: 'post',
data
})
}
// 根据患者ID或就诊ID获取文书记录列表,只针对不需返回患者具体信息的列表,体温单除外,单独处理
export function getRecordByEncounterIdList(params) {
return request({
url: '/document/record/getRecordByEncounterIdList',
method: 'get',
params
})
}
// 初始化文书定义
export function init() {
return request({
url: '/document/record/init',
method: 'get',
})
}
// ====== 文书模板
// 新增模板
export function addTemplate(data) {
return request({
url: '/document/template/add',
method: 'post',
data
})
}
//
export function getListByDefinitionId(definitionId) {
return request({
url: '/document/template/getListByDefinitionId',
method: 'get',
params: {definitionId}
})
}
// 更新模板
export function updateTemplate(data) {
return request({
url: '/document/template/update',
method: 'put',
data
})
}

View File

@@ -0,0 +1,96 @@
<template>
<div class="emr-history-container">
<div class="search-box">
<el-input placeholder="病历名称搜索..." v-model="queryParams.searchKey">
<template #append>
<el-button @click="queryList">查询</el-button>
</template>
</el-input>
</div>
<el-scrollbar class="emr-history-scrollbar-container" style="width: 100%">
<div v-for="item in historyData" :key="item.id" class="scrollbar-item">
<el-tooltip effect="dark" :content="`${item.name}(${item.recordTime})`" placement="bottom">
<el-text class="w-150px mb-2" truncated @click="handleNodeClick(item)">
{{ item.name }}({{ item.recordTime }})
</el-text>
</el-tooltip>
</div>
</el-scrollbar>
</div>
</template>
<script setup>
import { ref, reactive, defineEmits, unref } from 'vue';
import { getRecordByEncounterIdList } from '../api';
import { ElTree } from 'element-plus';
import { ElMessageBox, ElMessage, ElLoading } from 'element-plus';
import { patientInfo } from '../../store/patient.js';
const emits = defineEmits(['historyClick']);
const props = defineProps({
definitionId: {
type: String,
default: '',
},
});
const definitionId = defineModel('definitionId', {
type: String,
default: '',
});
const defaultProps = {
children: 'children',
label: 'name',
};
const queryParams = ref({
searchKey: '',
isPage: 0,
});
const historyData = ref([]);
const queryList = async () => {
try {
if (patientInfo.value.encounterId && unref(definitionId) && unref(definitionId) !== '') {
const res = await getRecordByEncounterIdList({
...queryParams.value,
encounterId: patientInfo.value.encounterId,
patientId: patientInfo.value.patientId,
definitionId: unref(definitionId),
});
historyData.value = res.data || [];
} else {
historyData.value = [];
}
} catch (error) {
// ElMessage.error('获取模板树失败');
historyData.value = [];
}
};
const handleNodeClick = (data) => {
emits('historyClick', data);
};
const currentSelectTemplate = ref({});
defineExpose({ queryList });
</script>
<style lang="scss" scoped>
.emr-history-container {
height: 100%;
// padding: 8px;
.search-box {
height: 40px;
line-height: 40px;
}
.emr-history-scrollbar-container {
padding: 8px;
height: calc(100% - 40px);
.scrollbar-item {
height: 40px;
line-height: 40px;
border-radius: 4px;
cursor: pointer;
background: var(--el-color-primary-light-9);
& + .scrollbar-item {
margin-top: 8px;
}
}
}
}
</style>

View File

@@ -0,0 +1,112 @@
<template>
<div class="emr-template-container">
<!-- <div class="search-box">
<el-input placeholder="病历名称搜索..." v-model="queryParams.searchKey">
<template #append>
<el-button @click="queryList">查询</el-button>
</template>
</el-input>
</div> -->
<el-scrollbar class="emr-template-scrollbar-container" style="width: 100%">
<div v-for="item in templateData" :key="item.id" class="scrollbar-item">
<el-tooltip
effect="dark"
:content="`${item.name}`"
placement="bottom"
>
<el-text class="2" truncated @click="handleNodeClick(item)">
<div class="template-item">{{ item.name }}
<el-space>
<el-icon><Edit @click="handleEdit(item)" /></el-icon>
</el-space></div>
</el-text>
</el-tooltip>
</div>
</el-scrollbar>
</div>
</template>
<script setup>
import { ref, reactive, defineEmits, unref } from 'vue';
import { getListByDefinitionId } from '../api';
import { ElTree } from 'element-plus';
import { ElMessageBox, ElMessage, ElLoading } from 'element-plus';
import { patientInfo } from '../../store/patient.js';
const emits = defineEmits(['templateClick','edit']);
const props = defineProps({
definitionId: {
type: String,
default: '',
},
});
const definitionId = defineModel('definitionId', {
type: String,
default: '',
});
const defaultProps = {
children: 'children',
label: 'name',
};
const queryParams = ref({
searchKey: '',
isPage: 0,
});
const templateData = ref([]);
const queryList = async () => {
try {
if ( unref(definitionId)&&unref(definitionId) !== '') {
const res = await getListByDefinitionId(unref(definitionId));
templateData.value = res.data || [];
}else{
templateData.value = [];
}
} catch (error) {
ElMessage.error('获取模板失败');
templateData.value = [];
}
};
const handleNodeClick = (data) => {
emits('templateClick', data);
};
const handleEdit = (data) => {
emits('edit', data);
};
const currentSelectTemplate = ref({});
defineExpose({ queryList });
</script>
<style lang="scss" scoped>
.emr-template-container {
height: 100%;
// padding: 8px;
.emr-template-scrollbar-container{
padding: 8px;
height: 100%;
.scrollbar-item {
height: 40px;
line-height: 40px;
border-radius: 4px;
cursor: pointer;
background: var(--el-color-primary-light-9);
& + .scrollbar-item {
margin-top: 8px;
}
.el-text{
width: calc(100% - 0px);
display: flex;
justify-content: space-between;
padding: 0 8px;
}
.template-item{
width: 100%;
display: flex;
justify-content: space-between;
}
}
}
}
</style>

View File

@@ -0,0 +1,133 @@
<template>
<!-- 病历文件基本信息弹窗 -->
<el-dialog
:title="formData.id ? '编辑模板' : '新增模板'"
v-model="dialogVisible"
width="900px"
destroy-on-close
@open="handleOpen"
>
<!-- 使用el-form包裹表单 -->
<el-form :model="formData" ref="formRef" :rules="rules" label-width="120px">
<el-row :gutter="24" class="mb8">
<el-col :span="24">
<el-form-item label="模板名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入模板名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="使用范围" prop="useRange">
<el-radio-group v-model="formData.useRange">
<el-radio :value="0" size="large">全院</el-radio>
<el-radio :value="1" size="large">指定机构</el-radio>
<el-radio :value="2" size="large">指定用户</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入版本"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer"></div>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import useUserStore from '@/store/modules/user';
import { addTemplate, updateTemplate } from '../api';
import { ElMessage } from 'element-plus';
import { components } from '@/template';
const emits = defineEmits(['submitOk']);
const props = defineProps({
formData: {
type: Object,
default: () => ({}),
},
});
const formRef = ref(null);
const dialogVisible = defineModel('dialogVisible', {
type: Boolean,
default: false,
});
// 表单数据
const formData = ref({
id: 0,
name: '',
displayOrder: 0,
contextJson: '',
definitionId: 0,
useRange: 2,
organizationId: 0,
userId: 0,
remark: '',
});
// 表单验证规则(响应式,支持动态验证)
const rules = reactive({
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
});
const handleOpen = () => {
if (props.formData) {
formData.value = props.formData;
} else {
resetForm();
}
};
// 提交表单
const submitForm = () => {
formRef.value.validate((valid) => {
if (valid) {
// 表单验证通过,执行保存操作
saveForm();
} else {
// 表单验证失败
ElMessage.error('请填写必填项');
return false;
}
});
};
// 保存表单
const saveForm = async () => {
try {
// 如果有当前节点数据,表示是编辑操作
if (formData.value.id && formData.value.id !== '') {
const res = await updateTemplate(formData.value);
if (res.code == 200) {
ElMessage.success('更新成功');
emits('submitOk');
} else {
ElMessage.error('更新失败', error);
}
} else {
// 新建操作
const res = await addTemplate(formData.value);
if (res.code == 200) {
ElMessage.success('保存成功');
emits('submitOk');
} else {
ElMessage.error('保存失败', error);
}
}
} catch (error) {
console.log(error);
// ElMessage.error('保存失败',error);
}
};
// 重置表单
const resetForm = () => {
formRef.value?.resetFields();
};
onMounted(() => {});
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,584 @@
<!--
* @Author: sjjh
* @Date: 2025-09-18 15:41:10
* @Description: 门诊病历组件
-->
<template>
<div class="emr-use-container">
<div
class="disBtn"
:class="{ disLeftBtnNor: leftShow, disLeftBtnAct: !leftShow }"
@click="disNode"
>
<img src="../../../../assets/icons/svg/foldup.svg" />
</div>
<div
class="disBtn"
:class="{ disRightBtnNor: rightShow, disRightBtnAct: !rightShow }"
@click="disNode_R"
>
<img src="../../../../assets/icons/svg/foldup.svg" />
</div>
<transition name="el-zoom-in-left">
<div class="template-tree-container" v-if="leftShow">
<div class="search-box">
<el-input placeholder="病历名称搜索..." v-model="queryParams.name">
<template #append>
<el-button @click="queryTemplateTree">查询</el-button>
</template>
</el-input>
</div>
<el-scrollbar class="template-tree-scrollbar">
<el-tree
ref="templateTree"
:data="templateData"
:props="defaultProps"
auto-expand-parent
node-key="id"
@node-click="handleNodeClick"
class="template-tree"
></el-tree>
</el-scrollbar>
</div>
</transition>
<div class="operate-container">
<div class="operate-btns">
<el-space>
<!-- <el-button type="primary" @click="newEmr">新建</el-button> -->
<el-button type="primary" @click="saveAsModel">存为模版</el-button>
<el-button @click="refresh">刷新</el-button>
<el-button type="primary" @click="save">保存</el-button>
<!-- <el-button type="primary" @click="print">打印</el-button> -->
</el-space>
</div>
<div class="operate-main">
<el-scrollbar class="template-tree-scrollbar">
<component
:is="currentComponent"
ref="emrComponentRef"
:patientInfo="props.patientInfo"
@submitOk="handleSubmitOk"
/>
</el-scrollbar>
</div>
</div>
<transition name="el-zoom-in-left">
<div class="quickly-container" v-if="rightShow">
<el-tabs v-model="quicklyactiveName" type="card">
<el-tab-pane label="历史" name="history">
<History
@historyClick="handleHistoryClick"
ref="historyRef"
v-model:definitionId="currentSelectTemplate.id"
/>
</el-tab-pane>
<el-tab-pane label="模版" name="model">
<Template
@templateClick="handleTemplateClick"
ref="templateRef"
v-model:definitionId="currentSelectTemplate.id"
@edit="templateEdit"
/>
</el-tab-pane>
</el-tabs>
</div>
</transition>
<TemplateEdit
ref="templateEditRef"
:formData="editTemplateForm"
v-model:dialogVisible="templateEditVisible"
@submitOk="templateEditSubmitOk"
/>
</div>
</template>
<script setup>
import { getCurrentInstance, nextTick, onBeforeMount, onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage, ElLoading } from 'element-plus';
import { getTreeList } from '@/views/basicmanage/caseTemplates/api';
import { addRecord, addTemplate } from './api';
import { patientInfo } from '../store/patient.js';
import dayjs from 'dayjs';
// 打印工具
// import { simplePrint, PRINT_TEMPLATE } from '@/utils/printUtils.js';
const { proxy } = getCurrentInstance();
const emits = defineEmits(['emrSaved']);
const props = defineProps({
/** 患者信息 doctorStation 传递信息*/
patientInfo: {
type: Object,
required: true,
},
activeTab: {
type: String,
},
});
const state = reactive({});
import History from './components/history';
import Template from './components/template';
import TemplateEdit from './components/templateEdit.vue';
import useUserStore from '@/store/modules/user';
const userStore = useUserStore();
// 定义响应式变量
const templateData = ref([]);
const queryParams = ref({
name: '',
useRanges: [1, 2], // 0 暂不使用 1 全院 2 科室 3 个人
organizationId: userStore.orgId,
});
const currentSelectTemplate = ref({
id: '',
});
const currentComponent = ref('');
const emrComponentRef = ref(null);
const quicklyactiveName = ref('history');
const leftShow = ref(true);
const rightShow = ref(true);
// 树配置(模板树)
const defaultProps = {
children: 'children',
label: 'name',
value: 'id',
};
/** 初始化病历模板树(按科室筛选) */
const queryTemplateTree = async () => {
try {
const res = await getTreeList(queryParams.value);
templateData.value = res.data || [];
} catch (error) {
// ElMessage.error('获取模板树失败');
templateData.value = [];
}
};
// 处理节点点击,根据后台返回的路径加载组件
const handleNodeClick = (data, node) => {
if (node.isLeaf) {
// 存储当前节点数据
currentSelectTemplate.value = data.document;
currentComponent.value = currentSelectTemplate.value.vueRouter || '';
// currentComponent.value = data.document.vueRouter || '';
} else {
currentSelectTemplate.value = {
id: '',
};
// currentComponent.value = null;
}
historyRef.value?.queryList();
templateRef.value?.queryList();
};
const newEmr = () => {
if (currentSelectTemplate.value) {
currentComponent.value = currentSelectTemplate.value.vueRouter || '';
return;
}
ElMessage.error('请选择模版!');
};
const saveAsModel = async () => {
try {
currentOperate.value = 'addTemplate';
await emrComponentRef.value?.submit();
} catch (error) {
ElMessage.error('存为模版失败');
}
};
const editForm = ref({
id: '',
definitionId: '',
definitionBusNo: '',
contentJson: '',
statusEnum: 1, // 0草稿/暂存 1提交 2归档 3修改
organizationId: 0,
encounterId: '',
patientId: '',
recordTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
createBy: '',
source: '',
});
const editTemplateForm = ref({
id: '',
name: '',
displayOrder: 0,
contextJson: '',
definitionId: '',
useRange: 2,
organizationId: '',
userId: '',
remark: '',
});
const currentOperate = ref('add');
const handleSubmitOk = async (data) => {
if (currentOperate.value === 'add') {
//
try {
if (!patientInfo.value?.encounterId || !patientInfo.value?.patientId) {
ElMessage.error('请先选择患者!');
return;
}
editForm.value.definitionId = currentSelectTemplate.value.id;
editForm.value.definitionBusNo = currentSelectTemplate.value.busNo;
editForm.value.contentJson = JSON.stringify(data);
editForm.value.encounterId = patientInfo.value.encounterId;
editForm.value.patientId = patientInfo.value.patientId;
editForm.value.recordTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
await addRecord(editForm.value);
ElMessage.success('病历保存成功');
historyRef.value?.queryList();
templateRef.value?.queryList();
// 通知父组件病历保存成功
emits('emrSaved', true);
} catch (error) {
ElMessage.error('提交失败');
console.log(error);
}
} else if (currentOperate.value === 'addTemplate') {
// 新增或者编辑模板
// editTemplateForm.value.id=
editTemplateForm.value.name =
currentSelectTemplate.value.name + dayjs().format('YYYY/MM/DD HH:mm');
editTemplateForm.value.contextJson = JSON.stringify(data);
editTemplateForm.value.definitionId = currentSelectTemplate.value.id;
templateEditVisible.value = true;
}
};
const refresh = () => {
queryTemplateTree();
historyRef.value?.queryList();
templateRef.value?.queryList();
};
const deleteEmr = async () => {
try {
// 这里应该添加实际的删除逻辑
ElMessage.success('删除成功!');
} catch (error) {
ElMessage.error('删除失败');
}
};
const save = async () => {
try {
currentOperate.value = 'add';
await emrComponentRef.value?.submit();
} catch (error) {
ElMessage.error('保存失败');
}
};
const historyRef = ref(null);
const handleHistoryClick = (data) => {
newEmr();
editForm.value = data;
nextTick(() => {
emrComponentRef.value?.setFormData(JSON.parse(editForm.value.contentJson));
});
};
const templateRef = ref(null);
const handleTemplateClick = (data) => {
newEmr();
editForm.value = data;
nextTick(() => {
emrComponentRef.value?.setFormData(JSON.parse(editForm.value.contextJson));
});
};
const templateEdit = (data) => {
editTemplateForm.value = data;
templateEditVisible.value = true;
};
// ====dialog
const templateEditVisible = ref(false);
// const templateEditSubmitOk = () => {};
// 打印方法实现
const print = async () => {
try {
// 检查是否有选中的病历模板
if (!currentSelectTemplate.value || !currentSelectTemplate.value.id) {
ElMessage.warning('请先选择病历模板');
return;
}
// 获取当前病历组件的表单数据
const formData = emrComponentRef.value?.formData || {};
// 准备打印数据不依赖子组件的getPrintData方法
// const printData = {
// // 使用当前选中的模板信息
// templateInfo: currentSelectTemplate.value,
// // 添加患者信息
// patientInfo: props.patientInfo,
// // 添加打印时间
// printTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
// // 添加基本病历信息
// emrInfo: {
// documentName: currentSelectTemplate.value.name || '住院病历',
// documentId: currentSelectTemplate.value.id || '',
// encounterId: props.patientInfo.encounterId || '',
// patientId: props.patientInfo.patientId || '',
// recordTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
// },
// // 添加病历表单数据(包含红框内的所有字段)
// formData: formData,
// doctorName: userStore.nickName,
// };
const printData = {
// 模板信息
templateName: currentSelectTemplate.value.name || '住院病历',
templateId: currentSelectTemplate.value.id || '',
// 医生信息
doctorName: userStore.nickName,
// 患者信息
patientName: props.patientInfo.patientName || '',
patientId: props.patientInfo.patientId || '',
medicalRecordNo: props.patientInfo.medicalRecordNo || '',
gender: props.patientInfo.gender || '',
age: props.patientInfo.age || '',
genderEnum_enumText: props.patientInfo.genderEnum_enumText || '',
idCard: props.patientInfo.idCard || '',
phone: props.patientInfo.phone || '',
registerTime: props.patientInfo.registerTime || '',
// 就诊信息
encounterId: props.patientInfo.encounterId || '',
department: props.patientInfo.department || '',
attendingDoctor: props.patientInfo.attendingDoctor || '',
// 病历信息
documentName: currentSelectTemplate.value.name || '住院病历',
documentId: currentSelectTemplate.value.id || '',
recordTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
printTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
// 表单数据 - 需要将嵌套结构展开
...flattenObject(formData),
};
// 执行打印
await simplePrint(PRINT_TEMPLATE.OUTPATIENT_MEDICAL_RECORD, printData);
ElMessage.success('打印成功');
} catch (error) {
console.error('打印失败:', error);
ElMessage.error('打印失败: ' + (error.message || '未知错误'));
}
};
// 辅助函数:将嵌套对象扁平化为单层结构
const flattenObject = (obj, prefix = '') => {
const flattened = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
const newKey = prefix ? `${prefix}_${key}` : key;
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
// 递归处理嵌套对象
Object.assign(flattened, flattenObject(obj[key], newKey));
} else if (Array.isArray(obj[key])) {
// 数组转换为字符串
flattened[newKey] = JSON.stringify(obj[key]);
} else {
// 基本类型直接赋值
flattened[newKey] = obj[key];
}
}
}
return flattened;
};
// 重新添加被覆盖的函数定义
const templateEditSubmitOk = () => {
templateEditVisible.value = false;
historyRef.value?.queryList();
templateRef.value?.queryList();
};
// onBeforeMount(() => {});
// 刚进页面默认显示门诊病历
const selectDefaultTemplate = () => {
nextTick(() => {
// 查找门诊病历(1.0.0)节点
const findTemplate = (nodes) => {
for (const node of nodes) {
if (node.children && node.children.length > 0) {
const found = findTemplate(node.children);
if (found) {
return found;
}
}
// 根据ID查找门诊病历模板
if (node.document && node.document.id === '1963474077201162242') {
return node;
}
}
return null;
};
const defaultTemplate = findTemplate(templateData.value);
if (defaultTemplate) {
// 模拟点击节点
const mockNode = {
isLeaf: true,
};
handleNodeClick(defaultTemplate, mockNode);
}
});
};
onMounted(async () => {
console.log('hospitalizationEmr mounted', userStore);
await queryTemplateTree();
selectDefaultTemplate();
});
defineExpose({ state });
const disNode = () => {
leftShow.value = !leftShow.value;
};
const disNode_R = () => {
rightShow.value = !rightShow.value;
};
</script>
<style lang="scss" scoped>
.emr-use-container {
display: flex;
height: 100%;
img {
width: 200%;
height: 200%;
}
.disBtn {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
overflow: hidden;
}
.disLeftBtnNor {
cursor: pointer;
position: absolute;
top: 40%;
left: 18%;
width: 20px;
height: 60px;
z-index: 1111;
img {
transform: rotate(-90deg);
}
}
.disLeftBtnAct {
cursor: pointer;
position: absolute;
top: 40%;
left: 0;
width: 20px;
height: 60px;
z-index: 1111;
img {
transform: rotate(90deg);
}
}
.disRightBtnNor {
cursor: pointer;
position: absolute;
top: 40%;
right: 18.5%;
width: 20px;
height: 60px;
z-index: 1111;
img {
transform: rotate(90deg);
}
}
.disRightBtnAct {
cursor: pointer;
position: absolute;
top: 40%;
right: 0;
width: 20px;
height: 60px;
z-index: 1111;
img {
transform: rotate(-90deg);
}
}
.template-tree-container {
border-right: 1px solid #ebeef5;
width: 300px;
flex: none;
height: 100%;
padding: 0 8px 8px 0;
display: flex;
flex-direction: column;
.search-box {
height: 40px;
display: flex;
align-items: center;
flex: none;
border-bottom: 1px solid #ebeef5;
}
.template-tree-scrollbar {
height: calc(100% - 48px);
flex: auto;
overflow-y: auto;
}
}
.operate-container {
width: 100%;
//width: 300px;
//flex: auto;
display: flex;
flex-direction: column;
padding: 0 8px 8px 8px;
.operate-btns {
height: 40px;
flex: none;
display: flex;
align-items: center;
border-bottom: 1px solid #ebeef5;
}
.operate-main {
height: calc(100vh - 150px);
flex: auto;
}
.operate-main .template-tree-scrollbar {
height: 100%;
overflow-y: auto;
}
}
.quickly-container {
border-left: 1px solid #ebeef5;
width: 300px;
padding: 0 8px 8px 8px;
flex: none;
.el-tabs {
height: 100%;
}
}
}
@layer utilities {
.transition-width {
transition-property: width;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 300ms;
}
}
</style>

View File

@@ -0,0 +1,210 @@
<!-- consumableDialog.vue -->
<template>
<el-dialog
v-model="dialogVisible"
title="绑定耗材"
width="700px"
:close-on-click-modal="false"
:before-close="handleClose"
>
<div class="consumable-dialog">
<div class="dialog-header">
<el-alert
title="该诊疗项目已绑定所需耗材,可修改数量或删除不需要的耗材,点击确定将自动添加到医嘱列表"
type="warning"
show-icon
:closable="false"
/>
</div>
<div class="table-container">
<el-table
ref="consumableTableRef"
:data="consumableList"
row-key="orderDefinitionId"
border
style="width: 100%"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column prop="orderDefinitionName" align="center" label="项目名称" />
<el-table-column prop="unitCodeName" label="单位" align="center" width="80">
<template #default="scope">
{{ scope.row.unitCodeName || '-' }}
</template>
</el-table-column>
<el-table-column label="数量/执行次数" align="center" width="120">
<template #default="scope">
<el-input-number
v-model="scope.row.quantity"
:min="1"
size="small"
controls-position="right"
style="width: 100%"
@change="handleQuantityChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center" fixed="right">
<template #default="scope">
<el-button type="danger" link size="small" @click="handleDeleteRow(scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 下次不再提示复选框 -->
<div class="dont-show-again">
<el-checkbox v-model="dontShowAgain" @change="handleDontShowAgainChange">
下次不再提示
</el-checkbox>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button ref="submitRef" type="primary" @click="handleSubmit">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { ElMessageBox, ElMessage } from 'element-plus';
import { ref, nextTick, onBeforeUnmount } from 'vue';
import useUserStore from '@/store/modules/user';
const dialogVisible = ref(false);
const consumableList = ref([]);
const consumableTableRef = ref();
const submitRef = ref();
const dontShowAgain = ref(false); // 下次不再提示的状态
const userStore = useUserStore();
// 定义事件
const emit = defineEmits(['submit']);
// 键盘事件处理函数
const handleKeyDown = (event) => {
// 检查是否按下了回车键
if (event.key === 'Enter' && dialogVisible.value) {
event.preventDefault();
handleSubmit();
}
};
// 打开弹窗方法
const open = (data) => {
consumableList.value = data;
dialogVisible.value = true;
// 默认全选
nextTick(() => {
if (consumableTableRef.value) {
consumableList.value.forEach((row) => {
consumableTableRef.value.toggleRowSelection(row, true);
});
}
// 注册键盘事件监听器
document.addEventListener('keydown', handleKeyDown);
});
};
// 关闭弹窗方法
const handleClose = () => {
// 移除键盘事件监听器
document.removeEventListener('keydown', handleKeyDown);
dialogVisible.value = false;
consumableList.value = [];
};
// 页面卸载前清理事件监听器
onBeforeUnmount(() => {
document.removeEventListener('keydown', handleKeyDown);
});
// 数量变化处理
const handleQuantityChange = (row) => {
if (row.quantity < 1) {
row.quantity = 1;
}
};
// 删除行处理
const handleDeleteRow = (row) => {
ElMessageBox.confirm(`确定要删除 "${row.orderDefinitionName}" 吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
const index = consumableList.value.findIndex(
(item) => item.orderDefinitionId === row.orderDefinitionId
);
if (index > -1) {
consumableList.value.splice(index, 1);
}
});
};
// 提交处理
const handleSubmit = () => {
const selectedRows = consumableTableRef.value.getSelectionRows();
// 保存到本地存储
localStorage.setItem('doctor' + userStore.id.toString(), dontShowAgain.value);
if (selectedRows.length === 0) {
ElMessage.warning('请至少选择一项耗材');
return;
}
// 发送事件给父组件
emit('submit', selectedRows);
// 关闭弹窗并清理事件监听器
document.removeEventListener('keydown', handleKeyDown);
dialogVisible.value = false;
consumableList.value = [];
};
// 暴露方法给父组件
defineExpose({
open,
close: handleClose,
});
</script>
<style lang="scss" scoped>
.consumable-dialog {
.dialog-header {
margin-bottom: 20px;
}
.table-container {
margin-bottom: 20px;
}
.dont-show-again {
margin-top: 10px;
text-align: left;
}
.dialog-footer-summary {
text-align: right;
.summary-text {
font-size: 14px;
color: #606266;
.total-amount {
font-size: 16px;
font-weight: bold;
color: #e64545;
}
}
}
}
.dialog-footer {
display: flex;
justify-content: flex-end;
align-items: center;
}
</style>

View File

@@ -42,7 +42,7 @@ const props = defineProps({
organizationId: {
type: String,
required: true,
}
},
});
const drawer = ref(false);
@@ -59,7 +59,7 @@ function handleOpen() {
getList();
}
function handelRadioChange(value){
function handelRadioChange(value) {
switch (value) {
case 1:
orderList.value = result.value.personalList;
@@ -74,24 +74,14 @@ function handelRadioChange(value){
}
function handleUseOrderGroup(row) {
// let value = JSON.parse(row.groupJson);
// value = value.map((item) => {
// return {
// ...item,
// conditionId: props.diagnosis.conditionId,
// conditionDefinitionId: props.diagnosis.definitionId,
// };
// });
// value.conditionId = props.diagnosis.conditionId;
// value.conditionDefinitionId = props.diagnosis.definitionId;
emit('useOrderGroup', row.detailList);
drawer.value = false;
}
function getList() {
getOrderGroup({ organizationId: props.organizationId }).then((res) => {
result.value = res.data
orderList.value = res.data.organizationList;
result.value = res.data;
handelRadioChange(queryParams.value.rangeCode);
});
}

View File

@@ -19,7 +19,7 @@
<span>{{ item.prescriptionNo }}</span>
</div>
<div style="text-align: center">
<h2>医院</h2>
<h2>长春大学医院</h2>
</div>
<div style="text-align: center">
<h3>处方单</h3>
@@ -76,7 +76,7 @@
<div class="medicen-list">
<div
style="margin-bottom: 3px"
v-for="(medItem, index) in item.prescriptionInfoDetail"
v-for="(medItem, index) in item.prescriptionInfoDetailList"
:key="medItem.requestId"
>
<span>{{ index + 1 + '. ' }}</span>
@@ -104,7 +104,7 @@
<div style="display: flex; justify-content: space-between">
<div>
<span class="item-label">医师</span>
<span class="item-value"></span>
<span class="item-value">{{ item.practitionerName }}</span>
</div>
<div>
<span class="item-label">收费</span>
@@ -112,7 +112,7 @@
</div>
<div>
<span class="item-label">合计</span>
<span class="item-value"></span>
<span class="item-value">{{ getTotalPrice(item) }}</span>
</div>
</div>
<div style="display: flex; justify-content: space-between">
@@ -139,9 +139,11 @@
</template>
</el-dialog>
</template>
<script setup>
import { formatDateStr } from '@/utils/index';
//高精度库
import Decimal from 'decimal.js';
const props = defineProps({
open: {
type: Boolean,
@@ -154,6 +156,17 @@ const props = defineProps({
});
const emit = defineEmits(['close']);
//合计
function getTotalPrice(item) {
let totalPrice = new Decimal(0);
item.prescriptionInfoDetailList.forEach((medItem) => {
const price = new Decimal(medItem.totalPrice);
const qty = new Decimal(medItem.quantity);
totalPrice = totalPrice.plus(price.times(qty));
});
return totalPrice.toNumber();
}
function close() {
emit('close');
}
@@ -202,4 +215,4 @@ function clickRow(row) {
width: 87px;
display: inline-block;
}
</style>
</style>

View File

@@ -126,7 +126,7 @@
<el-form-item prop="lotNumber" label="药房">
<el-select
v-model="scope.row.inventoryId"
style="width: 400px; margin-right: 20px"
style="width: 330px; margin-right: 20px"
placeholder="药房"
>
<el-option
@@ -167,7 +167,11 @@
</el-form-item>
<span class="medicine-info"> 注射药品:{{ scope.row.injectFlag_enumText }} </span>
<span class="total-amount">
总金额:{{ scope.row.totalPrice ? scope.row.totalPrice + ' 元' : '0.00 元' }}
总金额:{{
scope.row.totalPrice
? Number(scope.row.totalPrice).toFixed(2) + ' 元'
: '0.00 元'
}}
</span>
</div>
<div style="display: flex; align-items: center; gap: 12px; flex-wrap: wrap">
@@ -198,11 +202,7 @@
>
<template v-for="item in scope.row.unitCodeList" :key="item.value">
<el-option
v-if="
scope.row.unitCodeList.length == 3
? item.type == unitMap['minUnit']
: item.type == unitMap['unit']
"
v-if="item.type == unitMap['minUnit']"
:value="item.value"
:label="item.label"
/>
@@ -264,6 +264,8 @@
>
<el-option
v-for="dict in method_code"
@click="() => (scope.row.methodCode_dictText = dict.label)"
@keyup="handleEnter('methodCode', scope.row, scope.$index)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@@ -292,12 +294,14 @@
if (!value) {
handleEnter('rateCode', scope.row, scope.$index);
}
// inputRefs.rateCode.blur();
}
"
:ref="(el) => { if (!inputRefs[scope.$index]) inputRefs[scope.$index] = {}; inputRefs[scope.$index].rateCode = el; }"
>
<el-option
v-for="dict in rate_code"
@click="() => (scope.row.rateCode_dictText = dict.label)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@@ -371,7 +375,7 @@
>
<template v-for="item in scope.row.unitCodeList" :key="item.value">
<el-option
v-if="item.type != unitMap['dose']"
v-if="checkUnit(item, scope.row)"
:value="item.value"
:label="item.label"
@click="
@@ -750,7 +754,12 @@
/>
</el-form-item>
<span class="total-amount">
总金额:{{ scope.row.totalPrice ? scope.row.totalPrice + ' 元' : '0.00 元' }}
总金额:
{{
scope.row.totalPrice
? Number(scope.row.totalPrice).toFixed(2) + ' 元'
: '0.00 元'
}}
</span>
<span style="font-size: 16px; font-weight: 600">
<!-- 金额: {{ scope.row.priceList[0].price }} -->
@@ -798,7 +807,7 @@
<!-- 医嘱类型列 -->
<el-table-column label="医嘱类型" align="center" width="120">
<template #default="scope">
<template v-if="getRowDisabled(scope.row)">
<template v-if="scope.row.isEdit">
<el-select
v-model="scope.row.adviceType"
:ref="'adviceTypeRef_' + prescription.id + '_' + scope.$index"
@@ -832,7 +841,11 @@
:popoverVisible="scope.row.showPopover"
:adviceQueryParams="adviceQueryParams"
:patientInfo="props.patientInfo"
@selectAdviceBase="(row) => selectAdviceBase(scope.row.uniqueKey, row)"
@selectAdviceBase="
(row) => {
selectAdviceBase(scope.row.uniqueKey, row);
}
"
/>
<template #reference>
<el-input
@@ -841,6 +854,7 @@
placeholder="请选择项目"
@input="handleChange"
@click="handleFocus(scope.row, scope.$index)"
@blur="handleBlur(scope.row)"
@keyup.enter.stop="handleFocus(scope.row, scope.$index)"
@keydown="handleInputKeyDown(scope.row, $event)"
@blur="handleBlur(scope.row)"
@@ -964,9 +978,38 @@
:patientInfo="props.patientInfo"
@userPrescriptionHistory="handleSaveHistory"
/>
<OrderBindInfo ref="orderBindInfoRef" @submit="handleOrderBindInfo" />
</div>
<!-- 打印机选择对话框 -->
<!-- <el-dialog
v-model="isPrinterDialogVisible"
title="选择打印机"
width="400px"
:before-close="cancelPrinter"
>
<div class="printer-dialog-content">
<el-form label-position="top">
<el-form-item label="可用打印机">
<el-select v-model="selectedPrinter" placeholder="请选择打印机" style="width: 100%">
<el-option
v-for="printer in printerList"
:key="printer.name"
:label="printer.name"
:value="printer.name"
/>
</el-select>
</el-form-item>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="cancelPrinter">取消</el-button>
<el-button type="primary" @click="confirmPrinter">确定</el-button>
</span>
</template>
</el-dialog> -->
</template>
<script setup>
import {
getDiagnosisDefinitionList,
@@ -981,16 +1024,25 @@ import {
updateGroupId,
getContract,
getAdviceBaseInfo,
getActivityBindDevice,
getBindDevice,
} from '../api';
import adviceBaseList from '../adviceBaseList.vue';
import { computed, getCurrentInstance, nextTick, watch, unref, reactive } from 'vue';
import { calculateQuantityByDays, formatNumber } from '@/utils/his';
import OrderGroupDrawer from './orderGroupDrawer';
import PrescriptionHistory from './prescriptionHistory';
import OrderBindInfo from './orderBindInfo';
import Decimal from 'decimal.js';
import useUserStore from '@/store/modules/user';
import { ElMessageBox } from 'element-plus';
import { ElMessageBox, ElMessage } from 'element-plus';
import { ArrowDown } from '@element-plus/icons-vue';
import { advicePrint } from '@/api/public';
// import printUtils, {
// PRINT_TEMPLATE,
// getPrinterList,
// getCachedPrinter,
// savePrinterToCache,
// } from '@/utils/printUtils';
const emit = defineEmits(['selectDiagnosis']);
const total = ref(0);
@@ -1006,7 +1058,6 @@ const adviceQueryParams = ref({
});
const rowIndex = ref(-1);
const groupIndex = ref(1);
const groupIndexList = ref([]);
const diagnosisList = ref([]);
const nextId = ref(1);
const unitCodeList = ref([]);
@@ -1047,6 +1098,7 @@ const props = defineProps({
},
});
const isAdding = ref(false);
const isSaving = ref(false);
const prescriptionRef = ref();
const expandOrder = ref([]); //目前的展开行
const stockList = ref([]);
@@ -1054,6 +1106,7 @@ const contractList = ref([]);
const conditionId = ref('');
const accountId = ref('');
const checkAll = ref(false);
const bindMethod = ref({});
const { proxy } = getCurrentInstance();
const inputRefs = ref({}); // 存储输入框实例,格式: { rowIndex: { fieldName: el } }
const requiredProps = ref([]); // 存储必填项 prop 顺序
@@ -1164,7 +1217,6 @@ watch(
() => prescriptionList.value,
(newVlaue) => {
if (newVlaue && newVlaue.length > 0) {
console.log(prescriptionList.value, 'prescriptionList.value');
handleTotalAmount();
}
},
@@ -1256,16 +1308,16 @@ function handleAdviceTypeChange(row, index) {
function handleTotalAmount() {
totalAmount.value = prescriptionList.value.reduce((accumulator, currentRow) => {
if (currentRow.chargeStatus != 8) {
return accumulator + (Number(currentRow.totalPrice) || 0);
return new Decimal(accumulator).add(currentRow.totalPrice || 0);
} else {
return 0;
// 跳过已退费项目,保持累加结果不变
return accumulator;
}
}, 0);
}, new Decimal(0));
}
getList();
function getList() {
getDiagnosisDefinitionList(queryParams.value).then((res) => {
// prescriptionList.value = res.data.records;
total.value = res.data.total;
});
}
@@ -1565,6 +1617,16 @@ function clickRow(row, column, cell, event, prescriptionId) {
emit('selectDiagnosis', row);
}
function checkUnit(item, row) {
if (item.type == 'dose') {
return false;
} else if (row.partAttributeEnum == '2' && item.type == 'minUnit') {
return false;
} else {
return true;
}
}
// 行双击打开编辑块,仅待发送的可编辑
function clickRowDb(row, event, prescriptionId) {
// 如果传入了处方ID先切换到该处方
@@ -1573,9 +1635,7 @@ function clickRowDb(row, event, prescriptionId) {
}
if (row.statusEnum == 1) {
row = { ...row, ...JSON.parse(row.contentJson), uniqueKey: row.uniqueKey };
row.isEdit = true;
row.doseUnitCode == JSON.parse(JSON.stringify(row.minUnitCode));
const index = prescriptionList.value.findIndex((item) => item.uniqueKey === row.uniqueKey);
prescriptionList.value[index] = row;
// 确保只有当前行展开先清空数组再添加当前行的uniqueKey
@@ -2018,11 +2078,12 @@ function handleDelete(prescriptionId) {
let sum = 0; // 未保存总数量
for (let i = prescriptionList.value.length - 1; i >= 0; i--) {
let deleteItem = prescriptionList.value[i];
let index = selectRows.findIndex((item) => item.uniqueKey === deleteItem.uniqueKey);
// 通过requestId判断是否已保存如果选中项未保存 直接从数组中移除,如果已保存,调接口删除
if (deleteItem.check && deleteItem.statusEnum == 1 && !deleteItem.requestId) {
if (index != -1 && deleteItem.statusEnum == 1 && !deleteItem.requestId) {
prescriptionList.value.splice(i, 1);
sum++;
} else if (deleteItem.check && deleteItem.statusEnum == 1 && deleteItem.requestId) {
} else if (index != -1 && deleteItem.statusEnum == 1 && deleteItem.requestId) {
deleteList.push({
requestId: deleteItem.requestId,
dbOpType: '3',
@@ -2037,14 +2098,12 @@ function handleDelete(prescriptionId) {
adviceQueryParams.value.categoryCode = undefined;
if (sum == selectRow.length) {
proxy.$modal.msgSuccess('删除成功');
groupIndexList.value = [];
return;
}
if (deleteList.length > 0) {
savePrescription({ adviceSaveList: deleteList }).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess('删除成功');
groupIndexList.value = [];
getListInfo(false);
}
});
@@ -2052,7 +2111,6 @@ function handleDelete(prescriptionId) {
proxy.$modal.msgWarning('所选医嘱不可删除,请先撤回后再删除');
return;
}
groupMarkers.value = getGroupMarkers(prescriptionList.value); // 删除行会出现组号混乱的情况,所以这里重新更新标记
}
// 选择药房/耗材房处理
@@ -2173,9 +2231,11 @@ function handleEmrTreatment() {
// 病历辅助检查字符串拼接
let auxiliaryExamination = '';
let auxiliaryExaminationIndex = 1;
prescriptionList.value.forEach((item, index) => {
if (item.chargeStatus != 8) {
if (item.adviceType == 1) {
// 药品处方
treatment += '处方[' + (index + 1) + ']' + ' ';
treatment += item.adviceName + ' ' + item.volume + ' ';
treatment +=
@@ -2188,9 +2248,22 @@ function handleEmrTreatment() {
item.methodCode_dictText +
' ';
treatmentIndex++;
} else if (item.adviceType == 2) {
// 诊疗项目
treatment += '诊疗[' + (index + 1) + ']' + ' ';
treatment += item.adviceName + ' ';
if (item.quantity) {
treatment += '数量:' + item.quantity + item.unitCode_dictText + ' ';
}
treatment += '频次:' + item.rateCode_dictText + ' ';
if (item.methodCode_dictText) {
treatment += '方式:' + item.methodCode_dictText + ' ';
}
treatment += ' ';
} else if (item.adviceType == 3) {
treatment += '[' + (index + 1) + ']' + ' ';
treatment += item.adviceName + ' ';
// 检查项目
auxiliaryExamination += '[' + (index + 1) + ']' + ' ';
auxiliaryExamination += item.adviceName + ' ';
auxiliaryExaminationIndex++;
}
}
@@ -2207,23 +2280,79 @@ function handleEmrTreatment() {
});
}
function handleClickOutside(row, index) {
nextTick(() => {
handleSaveSign(row, index);
});
}
function stockFormat(partPercent, unitList, quantity) {
let unitCode = unitList.find((item) => {
return item.type == 'unit';
})?.label;
let minUnitCode = unitList.find((item) => {
return item.type == 'minUnit';
})?.label;
function stockFormat(partPercent, unit, minUnit, quantity) {
let a = quantity % partPercent;
let b = Math.floor(quantity / partPercent);
console.log(partPercent, unit, minUnit, quantity);
if (a == 0) {
return b + ' ' + unit;
return b + ' ' + unitCode;
}
return b + ' ' + unit + ' ' + a + ' ' + minUnit;
return b + ' ' + unitCode + ' ' + a + ' ' + minUnitCode;
}
// 处理自动带出的诊疗或者耗材
function handleOrderBindInfo(bindIdInfo) {
const adviceDefinitionIds = bindIdInfo.map((row) => row.orderDefinitionId);
getAdviceBaseInfo({ adviceDefinitionIdParamList: adviceDefinitionIds.join(',') }).then((res) => {
const list = res.data.records.map((item) => {
const info = bindIdInfo.find((k) => k.orderDefinitionId == item.adviceDefinitionId);
return {
...item,
quantity: info.quantity,
unitCode: info.unitCode,
};
});
list?.forEach((item) => {
rowIndex.value = prescriptionList.value.length;
setValue(item);
// 创建新的处方项目
const newRow = {
...prescriptionList.value[rowIndex.value],
uniqueKey: nextId.value++,
patientId: props.patientInfo.patientId,
encounterId: props.patientInfo.encounterId,
accountId: accountId.value,
quantity: item.quantity,
methodCode: item.methodCode,
rateCode: item.rateCode,
dispensePerDuration: item.dispensePerDuration,
dose: item.dose,
doseQuantity: item.doseQuantity,
executeNum: 1,
unitCode: item.unitCode,
unitCode_dictText: item.unitCodeName || '',
statusEnum: 1,
dbOpType: prescriptionList.value[rowIndex.value].requestId ? '2' : '1',
conditionId: conditionId.value,
conditionDefinitionId: conditionDefinitionId.value,
encounterDiagnosisId: encounterDiagnosisId.value,
};
// 计算价格和总量
const unitInfo = unitCodeList.value.find((k) => k.value == item.unitCode);
if (unitInfo && unitInfo.type == 'minUnit') {
newRow.price = newRow.minUnitPrice;
newRow.totalPrice = (item.quantity * newRow.minUnitPrice).toFixed(6);
newRow.minUnitQuantity = item.quantity;
} else {
newRow.price = newRow.unitPrice;
newRow.totalPrice = (item.quantity * newRow.unitPrice).toFixed(6);
newRow.minUnitQuantity = item.quantity * item.partPercent;
}
newRow.contentJson = JSON.stringify(newRow);
prescriptionList.value[rowIndex.value] = newRow;
});
});
}
// 单行处方保存
function handleSaveSign(row, index, prescriptionId) {
// 如果传入了处方ID先切换到该处方
@@ -2272,6 +2401,29 @@ function handleSaveSign(row, index, prescriptionId) {
formRef.validate((valid) => {
if (valid) {
if (row.adviceType != 2) {
// 1:用法绑东西 2:诊疗绑东西
let typeCode = row.adviceType == 1 ? '1' : '2';
// 用法字典值/诊疗定义id
let itemNo = row.adviceType == 1 ? row.methodCode : row.adviceDefinitionId;
getBindDevice({ typeCode: typeCode, itemNo: itemNo }).then((res) => {
if (res.data.length == 0) {
return;
}
// 是否需要打开弹窗
let openBindDialog = localStorage.getItem('doctor' + userStore.id);
if (!JSON.parse(openBindDialog)) {
proxy.$refs['orderBindInfoRef'].open(res.data);
} else {
// 如果弹窗不提示带出的项目,自动带出
// 如果有未签发的项目,并且当前的项目没有带出过绑定项目,则自动带出
if (!bindMethod.value[itemNo]) {
handleOrderBindInfo(res.data);
bindMethod.value[itemNo] = true;
}
}
});
}
row.isEdit = false;
isAdding.value = false;
updateExpandOrder([]);
@@ -2453,23 +2605,17 @@ function handleSaveBatch(prescriptionId) {
function setValue(row) {
unitCodeList.value = [];
unitCodeList.value.push({ value: row.unitCode, label: row.unitCode_dictText, type: 'unit' });
if (row.doseUnitCode != row.minUnitCode) {
unitCodeList.value.push({
value: row.doseUnitCode,
label: row.doseUnitCode_dictText,
type: 'dose',
});
}
if (
(row.partAttributeEnum == 1 || row.partAttributeEnum == 3) &&
row.minUnitCode != row.unitCode
) {
unitCodeList.value.push({
value: row.minUnitCode,
label: row.minUnitCode_dictText,
type: 'minUnit',
});
}
unitCodeList.value.push({
value: row.doseUnitCode,
label: row.doseUnitCode_dictText,
type: 'dose',
});
unitCodeList.value.push({
value: row.minUnitCode,
label: row.minUnitCode_dictText,
type: 'minUnit',
});
if (row.adviceType == 2 && row.minUnitCode != row.unitCode) {
unitCodeList.value.push({
value: row.minUnitCode,
@@ -2527,10 +2673,9 @@ function setValue(row) {
return item.quantity > 0 && item.locationId == row.positionId;
})[0];
if (stock == {} || stock == undefined) {
proxy.$modal.msgWarning('该项目库存不足,请选择其它库房');
proxy.$modal.msgWarning(row.adviceName + '库存不足,请选择其它库房');
return;
}
// proxy.$modal.msgWarning('该项目库存不足,请选择其它库房');
// return;
}
prescriptionList.value[targetIndex].lotNumber = stock.lotNumber;
prescriptionList.value[targetIndex].inventoryId = stock.inventoryId;
@@ -2539,7 +2684,8 @@ function setValue(row) {
prescriptionList.value[targetIndex].positionName = stock.locationName;
prescriptionList.value[targetIndex].minUnitPrice = new Decimal(stock.price)
.div(row.partPercent)
.toFixed(2);
.toFixed(6);
prescriptionList.value[rowIndex.value].positionName = stock.locationName;
}
} else {
// 执行科室默认逻辑:优先使用诊疗项目维护的所属科室,如果没有则使用开单科室
@@ -2549,34 +2695,11 @@ function setValue(row) {
}
}
// 组套保存
// 选择组套
function handleSaveGroup(orderGroupList) {
// orderGroupList.map((item) => {
// item.patientId = props.patientInfo.patientId;
// item.encounterId = props.patientInfo.encounterId;
// item.accountId = accountId.value;
// item.dbOpType = item.requestId ? '2' : '1';
// item.minUnitQuantity = item.quantity * item.partPercent;
// item.conditionId = conditionId.value;
// item.conditionDefinitionId = conditionDefinitionId.value;
// item.encounterDiagnosisId = encounterDiagnosisId.value;
// item.contentJson = JSON.stringify(item);
// prescriptionList.value.push(item);
// });
// let paramList = orderGroupList.map((item) => {
// return item.adviceDefinitionId;
// });
// getAdviceBaseInfo({
// adviceDefinitionIdParamList: paramList.join(','),
// organizationId: props.patientInfo.orgId,
// }).then((res) => {
// getOrgList();
orderGroupList.forEach((item, index) => {
orderGroupList.forEach((item) => {
rowIndex.value = prescriptionList.value.length;
setValue(item.orderDetailInfos);
// let orderGroupValue = orderGroupList.find(
// (k) => k.adviceDefinitionId == item.adviceDefinitionId
// );
prescriptionList.value[targetIndex] = {
...prescriptionList.value[targetIndex],
@@ -2698,7 +2821,7 @@ function escKeyListener(e) {
}
prescriptionList.value.shift();
isAdding.value = false;
groupMarkers.value = getGroupMarkers(prescriptionList.value); // 删除行会出现组号混乱的情况,所以这里重新更新标记
getGroupMarkers(); // 删除行会出现组号混乱的情况,所以这里重新更新标记
}
}
}
@@ -2712,13 +2835,14 @@ function handleSingOut(prescriptionId) {
let requestIdList = prescriptionList.value
.filter((item) => {
return item.check && item.statusEnum == 2;
return item.statusEnum == 2;
})
.map((item) => {
return item.requestId;
});
if (requestIdList.length == 0) {
proxy.$modal.msgWarning('请选择已签发医嘱撤回');
return;
}
singOut(requestIdList).then((res) => {
if (res.code == 200) {
@@ -2726,12 +2850,11 @@ function handleSingOut(prescriptionId) {
getListInfo(false);
}
});
prescriptionRef.value.clearSelection();
}
function handleGroupId(paramList) {
updateGroupId(paramList).then(() => {
getListInfo(false);
});
updateGroupId(paramList);
}
// 组合
@@ -2747,31 +2870,22 @@ function combination(prescriptionId) {
proxy.$modal.msgWarning('至少选择两项');
return;
}
// 相同分组用法需要相同
let uniqueValues = new Set();
// 相同分组诊断需要相同
let uniqDiagnosis = new Set();
// 相同分组诊断需要相同
let uniqInjectFlag = new Set();
// 相同状态
let statusEnum = new Set();
let status = false;
let isSave = false;
groupIndexList.value.forEach((index) => {
if (prescriptionList.value[index].statusEnum == 2) {
selectRows.forEach((item) => {
if (item.statusEnum == 2) {
status = true;
}
if (prescriptionList.value[index].statusEnum == 1 && !prescriptionList.value[index].requestId) {
isSave = true;
}
uniqueValues.add(prescriptionList.value[index].methodCode);
uniqDiagnosis.add(prescriptionList.value[index].diagnosisName);
uniqInjectFlag.add(prescriptionList.value[index].injectFlag);
uniqueValues.add(item.methodCode);
uniqDiagnosis.add(item.diagnosisName);
statusEnum.add(item.statusEnumf);
});
// 校验是否有已签发的医嘱
if (isSave) {
proxy.$modal.msgWarning('请先保存当前医嘱后再进行分组');
return;
}
if (status) {
proxy.$modal.msgWarning('已签发医嘱不允许分组');
return;
@@ -2784,28 +2898,31 @@ function combination(prescriptionId) {
proxy.$modal.msgWarning('同一分组诊断必须相同');
return;
}
if (uniqInjectFlag.size != 1) {
proxy.$modal.msgWarning('同一分组必须全部为输液药品');
if (statusEnum.size != 1) {
proxy.$modal.msgWarning('不同状态医嘱无法组合');
return;
}
// 获取当前时间戳拼接组号做唯一组号
let timestamp = Date.now().toString();
let updateList = [];
groupIndexList.value.forEach((index) => {
selectRows.forEach((item) => {
// 直接更新表格数据中的groupId
const index = prescriptionList.value.findIndex((row) => row.uniqueKey === item.uniqueKey);
if (index !== -1) {
prescriptionList.value[index].groupId = timestamp + groupIndex.value;
}
updateList.push({
requestId: prescriptionList.value[index].requestId,
requestId: item.requestId,
groupId: timestamp + groupIndex.value,
});
// prescriptionList.value[index].groupId = JSON.parse(JSON.stringify(groupIndex.value));
prescriptionList.value[index].check = false;
});
// 更新组号
handleGroupId({ groupList: updateList });
// 根据组号排序
sortPrescriptionList();
groupMarkers.value = getGroupMarkers(prescriptionList.value); // 更新标记
groupIndex.value++;
groupIndexList.value = [];
if (selectRows[0].statusEnum == 1 && selectRows[0].requestId) {
// 更新组号
handleGroupId({ groupList: updateList });
}
prescriptionRef.value.clearSelection();
getGroupMarkers(); // 更新标记
}
// 拆组
@@ -2819,84 +2936,51 @@ function split(prescriptionId) {
proxy.$modal.msgWarning('至少选择一项');
return;
}
// 获取选中的所有行
const selectedRows = groupIndexList.value.map((index) => prescriptionList.value[index]);
// 校验是否包含已签发的医嘱
if (selectedRows.some((row) => row.statusEnum === 2)) {
if (selectRows.some((row) => row.statusEnum === 2)) {
proxy.$modal.msgWarning('已签发医嘱不允许拆组');
return;
}
// 提取出这些行涉及的所有 groupId
const selectedGroupIds = [...new Set(selectedRows.map((row) => row.groupId).filter(Boolean))];
if (selectedGroupIds.length === 0) {
if (selectRows.length === 0) {
proxy.$modal.msgWarning('请选择已分组的医嘱');
return;
}
// 构建最终要更新的列表
let updateList = [];
// 遍历每个 groupId
selectedGroupIds.forEach((groupId) => {
// 当前分组下所有的医嘱
const groupItems = prescriptionList.value.filter((item) => item.groupId === groupId);
// 当前分组中被选中的医嘱
const selectedInGroup = selectedRows.filter((row) => row.groupId === groupId);
// 如果选中数 = 总数 - 1 → 拆掉整个分组
if (selectedInGroup.length === groupItems.length - 1) {
updateList.push(
...groupItems.map((item) => ({
requestId: item.requestId,
groupId: '',
}))
);
} else {
// 否则只更新选中的
updateList.push(
...selectedInGroup.map((item) => ({
requestId: item.requestId,
groupId: '',
}))
);
selectRows.forEach((item) => {
// 直接更新表格数据中的groupId
const index = prescriptionList.value.findIndex((row) => row.uniqueKey === item.uniqueKey);
if (index !== -1) {
prescriptionList.value[index].groupId = undefined;
}
updateList.push({
requestId: item.requestId,
groupId: null,
});
});
// 清除本地数据中的 groupId
prescriptionList.value.forEach((item) => {
if (updateList.some((u) => u.requestId === item.requestId)) {
item.groupId = undefined;
item.check = false; // 取消勾选
}
});
// 更新分组号
handleGroupId({ groupList: updateList });
if (selectRows[0].statusEnum == 1 && selectRows[0].requestId) {
// 更新组号
handleGroupId({ groupList: updateList });
}
prescriptionRef.value.clearSelection();
// 更新分组标记
groupMarkers.value = getGroupMarkers(prescriptionList.value);
// 排序保持一致性
sortPrescriptionList();
// 清空选中索引
groupIndexList.value = [];
getGroupMarkers();
proxy.$modal.msgSuccess('拆组成功');
}
// 分组标记处理
function getGroupMarkers(prescriptionList) {
const groupMap = {};
const markers = [];
function getGroupMarkers() {
// 初始化所有行的 groupIcon 为 null
prescriptionList.value.forEach((item) => {
item.groupIcon = null;
});
// 遍历处方列表,记录每组的索引范围(忽略无 groupId 的项)
prescriptionList.forEach((item, index) => {
// 创建一个映射来存储每个 groupId 对应的行索引
const groupMap = {};
// 遍历处方列表,按 groupId 分组(忽略无 groupId 的项)
prescriptionList.value.forEach((item, index) => {
if (!item.groupId) {
markers[index] = null; // 没有组号的标记为 null
return;
}
@@ -2906,37 +2990,36 @@ function getGroupMarkers(prescriptionList) {
groupMap[item.groupId].push(index);
});
// 根据每组的索引范围设置标记
// 为每个组设置 groupIcon
Object.values(groupMap).forEach((indices) => {
if (indices.length === 1) {
// 单个组成员,显示上下括号
markers[indices[0]] = 'all';
} else {
// 只有当组内元素大于1个时才需要显示分组标记
if (indices.length > 1) {
indices.forEach((index, i) => {
if (i === 0) {
markers[index] = '┏';
// 第一行
prescriptionList.value[index].groupIcon = '┏';
} else if (i === indices.length - 1) {
markers[index] = '┗';
// 最后一行
prescriptionList.value[index].groupIcon = '┗';
} else {
markers[index] = '┃';
// 中间行
prescriptionList.value[index].groupIcon = '┃';
}
});
}
});
return markers;
}
const groupMarkers = ref([]);
// 计算总价
function calculateTotalPrice(row, index) {
nextTick(() => {
if (row.adviceType == 3) {
row.totalPrice = (row.unitPrice * row.quantity * 100) / 100;
row.totalPrice = (row.unitPrice * row.quantity).toFixed(6);
} else {
if (row.unitCode == row.minUnitCode) {
row.totalPrice = row.minUnitPrice * row.quantity;
row.totalPrice = (row.minUnitPrice * row.quantity).toFixed(6);
} else {
row.totalPrice = (row.unitPrice * row.quantity * 100) / 100;
row.totalPrice = (row.unitPrice * row.quantity).toFixed(6);
}
}
});
@@ -2945,7 +3028,7 @@ function calculateTotalPrice(row, index) {
// 单位切换时 自动计算对应单位的总量
function convertValues(row, index) {
nextTick(() => {
let code = unitCodeList.value.filter((item) => {
let code = row.unitCodeList.filter((item) => {
return item.value == row.doseUnitCode;
})[0];
@@ -2966,13 +3049,13 @@ function convertValues(row, index) {
break;
}
});
calculateTotalAmount(row, index);
// calculateTotalAmount(row, index);
}
// 单次剂量数量改变时自动计算总量
function convertDoseValues(row, index) {
nextTick(() => {
let code = unitCodeList.value.filter((item) => {
let code = row.unitCodeList.filter((item) => {
return item.value == row.doseUnitCode;
})[0];
@@ -2993,7 +3076,7 @@ function convertDoseValues(row, index) {
break;
}
});
calculateTotalAmount(row, index);
// calculateTotalAmount(row, index);
}
// 总量计算,仅适用只有两种单位的情况
@@ -3002,7 +3085,7 @@ function calculateTotalAmount(row, index) {
// 项目为西药或中成药时,根据用药天数和用药频次自动计算总量
if (row.adviceType == 1 || row.adviceType == 2) {
if (row.rateCode && row.dispensePerDuration) {
// 根据用药天数和用药频次计算数量
// 根据用药天数和用药频次计算数量,医生按顺序填的情况
let count = calculateQuantityByDays(row.rateCode, row.dispensePerDuration);
if (count) {
let quantity;
@@ -3038,6 +3121,13 @@ function calculateTotalAmount(row, index) {
}
}
}
} else if (row.quantity) {
// 如果医生开药先填总量 直接计算总价格
if (row.unitCode == row.minUnitCode) {
prescriptionList.value[index].totalPrice = (row.quantity * row.minUnitPrice).toFixed(6);
} else {
prescriptionList.value[index].totalPrice = (row.quantity * row.unitPrice).toFixed(6);
}
}
}
});
@@ -3577,11 +3667,12 @@ function getSignedPrescriptionInfo() {
defineExpose({ getListInfo, getDiagnosisInfo, getSignedPrescriptionInfo });
</script>
<style lang="scss" scoped>
:deep(.el-table__expand-icon) {
display: none !important;
}
.medicine-title {
font-size: 16px;
font-weight: 600;
@@ -3623,6 +3714,7 @@ defineExpose({ getListInfo, getDiagnosisInfo, getSignedPrescriptionInfo });
.el-input-number .el-input__inner {
text-align: center;
}
.el-table__cell .el-form-item--default {
margin-bottom: 0px;
}
@@ -3683,4 +3775,4 @@ defineExpose({ getListInfo, getDiagnosisInfo, getSignedPrescriptionInfo });
display: inline-block !important;
opacity: 1 !important;
}
</style>
</style>

View File

@@ -10,7 +10,9 @@
>
<div class="footer">
<div class="statistics">
<span> {{ total }} 个项目</span>
<span> </span>
<el-tag type="danger" style="font-size: 20px">{{ total }}</el-tag>
<span> 个项目 </span>
<!-- <span class="total">合计金额¥ {{ totalAmount.toFixed(2) }}</span> -->
</div>
</div>
@@ -38,6 +40,7 @@
v-loading="tableLoading"
border
height="600"
:span-method="tableSpanMethod"
>
<el-table-column
type="selection"
@@ -50,14 +53,15 @@
}
"
/>
<el-table-column label="支付单据号" align="center" prop="paymentId" width="180" />
<el-table-column label="处方号" align="center" prop="prescriptionNo" />
<el-table-column label="项目名" align="center" prop="itemName" />
<el-table-column label="项目名" align="center" prop="itemName" width="180" />
<el-table-column label="数量" align="center" prop="quantity" />
<el-table-column label="单位" align="center" prop="unitCode_dictText" />
<el-table-column label="收款金额" align="center" prop="totalPrice" />
<el-table-column label="发放状态" align="center">
<template #default="scope">
<el-tag v-if="scope.row.dispenseStatus != 0" type="default">
<el-tag v-if="scope.row.dispenseStatus != 0" type="danger">
{{ scope.row.dispenseStatus_enumText }}
</el-tag>
<el-tag v-else type="default">{{ scope.row.serviceStatus_enumText }}</el-tag>
@@ -110,7 +114,7 @@ const props = defineProps({
default: '',
},
});
const emit = defineEmits(['close']);
const emit = defineEmits(['close', 'refresh']);
const total = ref(0);
const tableLoading = ref(false);
const queryParams = ref({
@@ -126,7 +130,6 @@ const totalAmount = ref(0);
function openDialog() {
getList();
}
function getList() {
refundList.value = [];
tableLoading.value = true;
@@ -140,6 +143,40 @@ function getList() {
});
}
// 计算相同支付单据号的行合并信息(仅对相邻行生效)
const paymentIdRowSpans = computed(() => {
const data = refundList.value || [];
const spans = [];
let index = 0;
while (index < data.length) {
let next = index + 1;
while (next < data.length && data[next].paymentId === data[index].paymentId) {
next++;
}
const groupSize = next - index;
spans[index] = groupSize; // 首行显示合并行数
for (let i = index + 1; i < next; i++) {
spans[i] = 0; // 其余行隐藏
}
index = next;
}
return spans;
});
function tableSpanMethod({ row, column, rowIndex }) {
// 仅合并“支付单据号”列
if (column && column.property === 'paymentId') {
const rowspan = paymentIdRowSpans.value[rowIndex] ?? 1;
return { rowspan, colspan: rowspan > 0 ? 1 : 0 };
}
// 仅合并“处方号”列
if (column && column.property === 'prescriptionNo') {
const rowspan = paymentIdRowSpans.value[rowIndex] ?? 1;
return { rowspan, colspan: rowspan > 0 ? 1 : 0 };
}
return { rowspan: 1, colspan: 1 };
}
function submit() {
// 1. 获取当前选中行并提取去重的 paymentId 列表
const selectedRows = proxy.$refs['refundListRef'].getSelectionRows();
@@ -162,6 +199,7 @@ function submit() {
if (res.code === 200) {
proxy.$modal.msgSuccess('操作成功');
getList();
emit('refresh');
}
});

View File

@@ -0,0 +1,20 @@
/*
* @Author: sjjh
* @Date: 2025-04-09 17:55:05
* @Description:
*/
// import { IInPatient } from '@/model/IInPatient'
import { ref } from 'vue';
// 定义护士等级(没接口前mock)
export const nursingLevel = ref('0');
export function updateNursingLevel(level) {
nursingLevel.value = level;
}
// 选择患者信息
export const patientInfo = ref();
export function updatePatientInfo(info) {
patientInfo.value = info;
}

View File

@@ -26,7 +26,7 @@
<el-date-picker
v-model="registerTime"
@change="handleTimeChange"
type="daterange"
type="date"
style="width: 100%; margin-bottom: 10px"
:clearable="false"
placeholder="挂号时间"
@@ -78,8 +78,8 @@
</div>
<div class="disabled-wrapper" style="width: 85%; border: 1px solid #eee; position: relative">
<div style="padding: 10px; border: 1px solid #eee; height: 50px; border-left: 0">
<el-descriptions :column="4">
<el-descriptions-item label="患者信息:" width="150">
<el-descriptions :column="5" class="patient-info-descriptions">
<el-descriptions-item label="患者信息:" width="420">
{{
Object.keys(patientInfo).length !== 0
? patientInfo.patientName +
@@ -88,13 +88,47 @@
' / ' +
patientInfo.genderEnum_enumText +
' / ' +
patientInfo.contractName
patientInfo.contractName +
'/' +
patientInfo.phone
: '-'
}}
</el-descriptions-item>
<el-descriptions-item label="挂号时间:" width="150">
<el-descriptions-item label="挂号时间:" width="300">
{{ Object.keys(patientInfo).length !== 0 ? formatDate(patientInfo.registerTime) : '-' }}
</el-descriptions-item>
<el-descriptions-item label="医生:" width="250">
{{ userStore.nickName }}
</el-descriptions-item>
<el-descriptions-item label="" width="300">
<el-button type="primary" plain @click.stop="handleFinish(patientInfo.encounterId)">
完诊
</el-button>
<el-button type="primary" plain @click.stop="handleLeave(patientInfo.encounterId)">
暂离
</el-button>
<el-button type="primary" plain @click.stop="handleRefund(patientInfo.encounterId)">
退费
</el-button>
<el-button
type="primary"
plain
@click.stop="getEnPrescription(patientInfo.encounterId)"
>
处方单
</el-button>
<el-button
type="primary"
plain
@click.stop="
() => {
openDialog = true;
}
"
>
办理住院
</el-button>
</el-descriptions-item>
<el-descriptions-item label="医生:" width="150">{{
userStore.name
}}</el-descriptions-item>
@@ -145,6 +179,13 @@
v-model="activeTab"
@tab-change="handleClick(activeTab)"
>
<el-tab-pane label="门诊病历" name="hospitalizationEmr">
<hospitalizationEmr
:patientInfo="patientInfo"
:activeTab="activeTab"
@emrSaved="handleEmrSaved"
/>
</el-tab-pane>
<el-tab-pane label="病历" name="emr">
<Emr
:patientInfo="patientInfo"
@@ -174,14 +215,16 @@
:patientInfo="patientInfo"
ref="prescriptionRef"
:activeTab="activeTab"
:outpatientEmrSaved="outpatientEmrSaved"
/>
</el-tab-pane>
<el-tab-pane label="中医" name="tcm">
<tcmAdvice :patientInfo="patientInfo" ref="tcmRef" />
</el-tab-pane>
<el-tab-pane label="电子处方" name="eprescription">
<!-- <el-tab-pane label="电子处方" name="eprescription">
<eprescriptionlist :patientInfo="patientInfo" ref="eprescriptionRef" />
</el-tab-pane>
-->
</el-tabs>
<div class="overlay" v-if="disabled"></div>
</div>
@@ -193,6 +236,7 @@
:open="openRefundListDialog"
:encounterId="currentEncounterId"
@close="openRefundListDialog = false"
@refresh="() => prescriptionRef.getListInfo()"
/>
<HospitalizationDialog
:open="openDialog"
@@ -208,6 +252,7 @@
</div>
</template>
<script setup>
import hospitalizationEmr from './components/hospitalizationEmr/index.vue';
import Emr from './components/emr/emr.vue';
import {
getList,
@@ -222,13 +267,14 @@ import RefundListDialog from './components/prescription/refundListDialog.vue';
import PatientList from './components/patientList.vue';
import Diagnosis from './components/diagnosis/diagnosis.vue';
import PrescriptionInfo from './components/prescription/prescriptionInfo.vue';
import eprescriptionlist from './components/eprescriptionlist.vue';
// import eprescriptionlist from './components/eprescriptionlist.vue';
import HospitalizationDialog from './components/hospitalizationDialog.vue';
import tcmAdvice from './components/tcm/tcmAdvice.vue';
import { formatDate, formatDateStr } from '@/utils/index';
import useUserStore from '@/store/modules/user';
import { nextTick } from 'vue';
import { onBeforeRouteLeave } from 'vue-router';
import { updatePatientInfo } from './components/store/patient.js';
// // 监听路由离开事件
// onBeforeRouteLeave((to, from, next) => {
@@ -257,15 +303,18 @@ const openRefundListDialog = ref(false);
const openDialog = ref(false);
const openPrescriptionDialog = ref(false);
const saveStatus = ref(false);
const outpatientEmrSaved = ref(false); // 门诊病历保存状态
const currentEncounterId = ref('');
const emits = defineEmits(['click']);
const activeTab = ref('emr');
// const activeTab = ref('emr');
const activeTab = ref('hospitalizationEmr');
const patientList = ref([]);
const patientInfo = ref({});
const visitTypeDisabled = ref(false);
const prescriptionInfo = ref([]);
const registerTime = ref([formatDate(new Date()), formatDate(new Date())]);
const registerTime = ref(formatDate(new Date()));
const patientDrawerRef = ref();
const prescriptionRef = ref();
const tcmRef = ref();
@@ -279,12 +328,41 @@ const firstVisitDate = ref('');
const disabled = computed(() => {
return Object.keys(patientInfo.value).length === 0;
});
const shortcuts = [
{
text: '今天',
value: new Date(),
},
{
text: '昨天',
value: () => {
const date = new Date();
date.setDate(date.getDate() - 1);
return date;
},
},
{
text: '三天内',
value: () => {
const date = new Date();
date.setDate(date.getDate() - 3);
return date;
},
},
{
text: '一周内',
value: () => {
const date = new Date();
date.setDate(date.getDate() - 7);
return date;
},
},
];
const eprescriptionRef = ref();
// const eprescriptionRef = ref();
onMounted(() => {
getWaitPatient();
});
getPatientList();
// 获取现诊患者列表
function getPatientList() {
@@ -373,9 +451,9 @@ function handleClick(tab) {
case 'tcm':
tcmRef.value.getDiagnosisInfo();
break;
case 'eprescription':
eprescriptionRef.value.getList();
break;
// case 'eprescription':
// eprescriptionRef.value.getList();
// break;
}
// if (tab != 'emr') {
// if (!saveStatus.value) {
@@ -393,6 +471,11 @@ function handleClick(tab) {
// 查看本次就诊处方单从医嘱Tab页获取已开立的处方单信息
function getEnPrescription(encounterId) {
getEnPrescriptionInfo({ encounterId: encounterId }).then((res) => {
console.log('处方单 res', res);
prescriptionInfo.value = res.data.records;
openPrescriptionDialog.value = true;
});
// 检查是否有选中的患者
if (!patientInfo.value || !patientInfo.value.encounterId) {
proxy.$modal.msgWarning('请先选择患者');
@@ -470,6 +553,9 @@ function handleCardClick(item, index) {
patient.active = patient.encounterId === item.encounterId;
});
patientInfo.value = item;
// 将患者信息保存到store中供hospitalizationEmr组件使用
updatePatientInfo(item);
activeTab.value = 'hospitalizationEmr';
// 优先使用数据库中保存的初复诊值
if (item.visitType) {
@@ -489,7 +575,7 @@ function handleCardClick(item, index) {
prescriptionRef.value.getListInfo();
tcmRef.value.getListInfo();
diagnosisRef.value.getList();
eprescriptionRef.value.getList();
// eprescriptionRef.value.getList();
emrRef.value.getDetail(item.encounterId);
setTimeout(() => {
loading.value = false;
@@ -520,8 +606,8 @@ function handleFinish(encounterId) {
}
function handleTimeChange(value) {
queryParams.value.registerTimeSTime = value[0] + ' 00:00:00';
queryParams.value.registerTimeETime = value[1] + ' 23:59:59';
queryParams.value.registerTimeSTime = value + ' 00:00:00';
queryParams.value.registerTimeETime = value + ' 23:59:59';
getPatientList();
}
@@ -534,6 +620,11 @@ function handleReceive(row) {
getWaitPatient();
}
// 处理门诊病历保存成功事件
function handleEmrSaved(isSaved) {
outpatientEmrSaved.value = isSaved;
}
function openDrawer() {
drawer.value = true;
}
@@ -564,6 +655,16 @@ function handleCancelEncounter(){
</script>
<style lang="scss" scoped>
// 患者信息
.patient-info-descriptions {
:deep(.el-descriptions__label) {
font-size: 16px !important;
}
:deep(.el-descriptions__content) {
font-size: 16px !important;
}
}
.patient-card {
width: 100%;
overflow: hidden;

View File

@@ -15,7 +15,7 @@
"top": 16.5,
"height": 22.5,
"width": 120,
"title": "医院",
"title": "长春大学医院",
"coordinateSync": false,
"widthHeightSync": false,
"fontFamily": "Microsoft YaHei",

View File

@@ -0,0 +1,330 @@
<template>
<div
class="app-container"
style="border: 1px solid #e0e0e0; border-radius: 4px; box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.1)"
>
<el-row :gutter="10" justify="end" align="middle" style="margin-bottom: 10px">
<el-button type="danger" plain icon="Refresh" @click="handleSendDrug" :disabled="!encounterId"
>发药</el-button
>
<el-button type="primary" plain icon="Download" @click="handleExport" :disabled="!encounterId"
>导出</el-button
>
<el-button
type="success"
plain
icon="Refresh"
@click="handleDispense"
:disabled="!encounterId"
>退药</el-button
>
</el-row>
<div class="tableContainer">
<el-table
v-loading="loading"
:data="displayTableData"
style="width: 100%; height: 70vh"
border
stripe
:header-cell-style="headerCellStyle"
:row-style="rowStyle"
:cell-style="{ textAlign: 'center' }"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<!-- 基础信息 -->
<el-table-column prop="itemName" label="项目名称" min-width="120" />
<el-table-column prop="totalVolume" label="规格" min-width="100" />
<el-table-column prop="locationName" label="发放药房" min-width="100" />
<el-table-column prop="lotNumber" label="批次号" min-width="100" />
<el-table-column prop="departmentName" label="科室" min-width="100" />
<el-table-column prop="doctorName" label="开单医生" min-width="100" />
<el-table-column prop="dispenseDoctorName" label="发药医生" min-width="100" />
<el-table-column prop="itemType_dictText" label="项目类型" min-width="100">
<template #default="scope">
{{ scope.row.itemType_dictText || scope.row.itemType || '-' }}
</template>
</el-table-column>
<el-table-column prop="statusEnum_enumText" label="发药状态" min-width="100">
<template #default="scope">
{{ scope.row.statusEnum_enumText || scope.row.statusEnum || '-' }}
</template>
</el-table-column>
<el-table-column prop="conditionName" label="诊断名称" min-width="100" />
<el-table-column prop="prescriptionNo" label="处方号" min-width="120" />
<!-- 用药信息 -->
<el-table-column prop="dose" label="单次剂量" min-width="100" />
<el-table-column prop="rateCode_dictText" label="用药频次" min-width="100">
<template #default="scope">
{{ scope.row.rateCode_dictText || scope.row.rateCode || '-' }}
</template>
</el-table-column>
<el-table-column prop="methodCode_dictText" label="用法" min-width="100">
<template #default="scope">
{{ scope.row.methodCode_dictText || scope.row.methodCode || '-' }}
</template>
</el-table-column>
<el-table-column prop="doseUnitCode_dictText" label="剂量单位" min-width="100">
<template #default="scope">
{{ scope.row.doseUnitCode_dictText || scope.row.doseUnitCode || '-' }}
</template>
</el-table-column>
<el-table-column prop="unitCode_dictText" label="单位" min-width="80">
<template #default="scope">
{{ scope.row.unitCode_dictText || scope.row.unitCode || '-' }}
</template>
</el-table-column>
<el-table-column prop="dispensePerQuantity" label="单次发药数" min-width="100" />
<el-table-column prop="dispensePerDuration" label="每次发药供应天数" min-width="150" />
<el-table-column prop="quantity" label="数量" min-width="80" />
<el-table-column prop="unitPrice" label="单价" min-width="80" />
<el-table-column prop="totalPrice" label="金额" min-width="80" />
<!-- 其他信息 -->
<el-table-column prop="manufacturerText" label="生产厂家" min-width="150" />
<el-table-column prop="traceNo" label="追溯码" min-width="120" />
<el-table-column prop="encounterBusNo" label="就诊NO" min-width="120" />
<el-table-column prop="reqAuthoredTime" label="开具日期" min-width="150">
<template #default="scope">
{{ formatDate(scope.row.reqAuthoredTime) }}
</template>
</el-table-column>
<el-table-column prop="skinTestFlag" label="皮试标志" min-width="100">
<template #default="scope">
{{ scope.row.skinTestFlag === 1 ? '是' : scope.row.skinTestFlag === 0 ? '否' : '-' }}
</template>
</el-table-column>
<el-table-column prop="tcmFlag" label="中药标识" min-width="100">
<template #default="scope">
{{ scope.row.tcmFlag === 1 ? '是' : scope.row.tcmFlag === 0 ? '否' : '-' }}
</template>
</el-table-column>
<el-table-column prop="itemTable" label="所在表" min-width="100" />
</el-table>
</div>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { totalSendDrug, totalReturnDrug } from './api';
import { getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
const emit = defineEmits(['call-medication-summary-detail']);
// 定义props接收父组件传递的表格数据和选中的ID
const props = defineProps({
tableData: {
type: Array,
default: () => [],
},
encounterId: {
type: String,
default: '',
},
});
// 定义响应式数据
const selectedRows = ref([]);
const loading = ref(false);
// 计算属性直接使用props.tableData并添加日志用于调试
const displayTableData = computed(() => {
return props.tableData;
});
// 处理表格选择变化
function handleSelectionChange(rows) {
selectedRows.value = rows;
}
// 格式化日期
function formatDate(dateTime) {
if (!dateTime) return '-';
const date = new Date(dateTime);
if (isNaN(date.getTime())) return '-';
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// 监听props.tableData变化当外部数据变化时清空选中状态
watch(
() => props.tableData,
() => {
selectedRows.value = [];
}
);
// 表格样式
const headerCellStyle = {
backgroundColor: '#f5f7fa',
color: '#333',
fontWeight: 'bold',
height: '48px',
textAlign: 'center',
lineHeight: '48px',
padding: '0',
fontSize: '14px',
};
const rowStyle = {
height: '40px',
};
// 发药功能
const handleSendDrug = () => {
if (!props.encounterId) {
ElMessage.warning('请先选择患者');
return;
}
if (selectedRows.value.length === 0) {
ElMessage.warning('请先选择需要发药的数据');
return;
}
let data = [];
selectedRows.value.forEach((row) => {
data.push({
dispenseId: row.dispenseId,
});
});
loading.value = true;
proxy.$modal
.confirm('确定要发药吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
const response = await totalSendDrug(data);
if (response.code === 200) {
ElMessage.success('发药成功');
loading.value = false;
}
})
.catch(() => {
loading.value = false;
});
};
// 导出功能
const handleExport = () => {
if (!props.encounterId) {
ElMessage.warning('请先选择患者');
return;
}
if (displayTableData.value.length === 0) {
ElMessage.warning('暂无数据可导出');
return;
}
if (selectedRows.value.length === 0) {
ElMessage.warning('请先选择要导出的数据');
return;
}
// 这里可以实现导出逻辑
console.log('导出数据:', selectedRows.value);
ElMessage.success('导出成功');
};
// 退药功能
const handleDispense = () => {
if (!props.encounterId) {
ElMessage.warning('请先选择患者');
return;
}
if (selectedRows.value.length === 0) {
ElMessage.warning('请先选择需要退药的数据');
return;
}
let data = [];
selectedRows.value.forEach((row) => {
data.push({
dispenseId: row.dispenseId,
});
});
loading.value = true;
proxy.$modal
.confirm('确定要退药吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
const response = await totalReturnDrug(data);
emit('call-medication-summary-detail', props.encounterId);
console.log(response);
if (response.code === 200) {
ElMessage.success('退药成功');
loading.value = false;
// 通知父组件刷新明细数据
emit('call-medication-summary-detail', props.encounterId);
} else {
console.log(response.message);
ElMessage.error('退药失败');
}
})
.catch(() => {
loading.value = false;
});
};
// 定义暴露给父组件的数据和方法
defineExpose({
selectedRows,
});
</script>
<style lang="scss" scoped>
.medicationTableDetail {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
.buttonGroup {
display: flex;
justify-content: flex-end;
padding: 10px 0;
gap: 10px;
margin-right: 20px;
:deep(.el-button) {
padding: 6px 16px;
font-size: 14px;
}
}
.tableContainer {
flex: 1;
overflow-x: auto; /* 启用横向滚动 */
overflow-y: auto; /* 同时启用纵向滚动 */
border: 1px solid #e0e0e0;
border-radius: 4px;
:deep(.el-table) {
height: 100%;
.el-table__header {
th {
background-color: #f5f7fa;
height: 48px !important;
line-height: 48px !important;
padding: 0 !important;
}
}
.el-table__row:hover {
background-color: #f5f7fa;
}
}
}
}
</style>

View File

@@ -0,0 +1,187 @@
<template>
<div
class="app-container"
style="border: 1px solid #e0e0e0; border-radius: 4px; box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.1)"
>
<el-row :gutter="10" justify="end" align="middle" style="margin-bottom: 10px">
<el-button type="danger" plain icon="Refresh" @click="handleSendDrug" :disabled="!busNo">
发药
</el-button>
<el-button type="primary" plain icon="Download" @click="handleExport" :disabled="!busNo">
导出
</el-button>
</el-row>
<div class="tableContainer">
<el-table
:data="tableData"
style="width: 100%; height: 70vh"
:header-cell-style="headerCellStyle"
:row-style="rowStyle"
:cell-style="{ textAlign: 'center' }"
>
<el-table-column prop="currentIndex" label="序号" min-width="60" />
<el-table-column prop="itemName" label="项目名称" min-width="150">
<template #default="scope">
{{ scope.row.itemName || '-' }}
</template>
</el-table-column>
<el-table-column prop="totalVolume" label="规格" min-width="120">
<template #default="scope">
{{ scope.row.totalVolume || '-' }}
</template>
</el-table-column>
<el-table-column prop="lotNumber" label="批次号" min-width="100">
<template #default="scope">
{{ scope.row.lotNumber || '-' }}
</template>
</el-table-column>
<el-table-column prop="quantity" label="数量" min-width="80" align="center">
<template #default="scope">
<el-tag v-if="scope.row.quantity" size="mini">
{{ scope.row.quantity }}
</el-tag>
<el-tag v-if="scope.row.maxUnitCode_dictText" size="mini" type="danger">
{{ scope.row.maxUnitCode_dictText }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="sourceLocationName" label="发放地点" min-width="100">
<template #default="scope">
{{ scope.row.sourceLocationName || '-' }}
</template>
</el-table-column>
<el-table-column prop="manufacturerText" label="生产厂家" min-width="120">
<template #default="scope">
{{ scope.row.manufacturerText || '-' }}
</template>
</el-table-column>
<el-table-column prop="busNo" label="单据号" min-width="150">
<template #default="scope">
{{ scope.row.busNo || '-' }}
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
import { totalSendDrug } from './api.js';
import { getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
// 定义组件属性
const props = defineProps({
tableData: {
type: Array,
default: () => [],
},
selectedId: {
type: String,
default: '',
},
busNo: {
type: String,
default: '',
},
});
// 定义响应式数据
const selectedRows = ref([]);
// 定义loading状态
const loading = ref(false);
// 表格样式
const headerCellStyle = {
backgroundColor: '#f5f7fa',
color: '#333',
fontWeight: 'bold',
height: '48px',
textAlign: 'center',
lineHeight: '48px',
padding: '0',
fontSize: '14px',
};
const rowStyle = {
height: '40px',
};
// 发药功能
const handleSendDrug = () => {
if (!props.busNo) {
ElMessage.warning('请先选择单据号');
return;
}
let data = [{ busNo: props.busNo }];
loading.value = true;
proxy.$modal
.confirm('确定要发药吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
const response = await totalSendDrug(data);
if (response.code === 200) {
ElMessage.success('发药成功');
loading.value = false;
}
})
.catch(() => {
loading.value = false;
});
};
// 定义暴露给父组件的数据和方法
defineExpose({
selectedRows,
});
</script>
<style lang="scss" scoped>
.medicationTableDetail {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
.buttonGroup {
display: flex;
justify-content: flex-end;
padding: 10px 0;
gap: 10px;
margin-right: 20px;
:deep(.el-button) {
padding: 6px 16px;
font-size: 14px;
}
}
.tableContainer {
flex: 1;
overflow: hidden;
border: 1px solid #e0e0e0;
border-radius: 4px;
:deep(.el-table) {
height: 100%;
.el-table__header {
th {
background-color: #f5f7fa;
height: 48px !important;
lineheight: 48px !important;
padding: 0 !important;
}
}
.el-table__row:hover {
background-color: #f5f7fa;
}
}
}
}
</style>

View File

@@ -0,0 +1,123 @@
import request from '@/utils/request';
// 获取病区下拉选
export function getPractitionerWard (queryParams) {
return request ({
url: '/app-common/practitioner-ward',
method: 'get',
params: queryParams,
});
}
// 住院汇总发药单左侧
export function getFromSummaryList (queryParams) {
return request ({
url: 'pharmacy-manage/summary-dispense-medicine/from_summary-list',
method: 'get',
params: queryParams,
});
}
// 住院汇总发药单右侧
export function getFromDetailList (queryParams) {
return request ({
url: 'pharmacy-manage/summary-dispense-medicine/from-list',
method: 'get',
params: queryParams,
});
}
// 明细左侧
export function getEncounterList (queryParams) {
return request ({
url: '/pharmacy-manage/summary-dispense-medicine/encounter-list',
method: 'get',
params: queryParams,
});
}
//明细 右侧
export function getMedicationSummaryDetail (queryParams) {
return request ({
url: '/pharmacy-manage/summary-dispense-medicine/medication_summary-list',
method: 'get',
params: queryParams,
});
}
//以下是组件的接口
/**
* 获取住院患者列表
*/
export function getPatientList (queryParams) {
return request ({
url: '/nurse-station/advice-process/inpatient',
method: 'get',
params: queryParams,
});
}
/**
* 获取当前登录人管理病区
*/
export function getWardList (queryParams) {
return request ({
url: '/app-common/practitioner-ward',
method: 'get',
params: queryParams,
});
}
/**
* 获取当前选中患者全部医嘱
*/
export function getPrescriptionList (queryParams) {
return request ({
url: '/nurse-station/advice-process/inpatient-advice',
method: 'get',
params: queryParams,
});
}
/**
* 执行医嘱
*/
export function adviceExecute (data) {
return request ({
url: '/nurse-station/advice-process/advice-execute',
method: 'post',
data: data,
});
}
/**
* 取消执行医嘱
*/
export function adviceCancel (data) {
return request ({
url: '/nurse-station/advice-process/advice-cancel',
method: 'post',
data: data,
});
}
/**
* 明细发药
*
*/
export function totalSendDrug (data) {
return request ({
url: '/pharmacy-manage/summary-dispense-medicine/summary-dispense-medicine',
method: 'put',
data: data,
});
}
/**
* 明细退药
*/
export function totalReturnDrug (data) {
return request ({
url: '/pharmacy-manage/summary-dispense-medicine/medicine-return',
method: 'put',
data: data,
});
}

View File

@@ -0,0 +1,456 @@
<template>
<div class="app-container">
<el-row :gutter="20" style="margin-bottom: 20px">
<el-col :span="4" :xs="24">
<el-button
:type="selectType === 'total' ? 'primary' : 'default'"
@click="handleSelectType('total')"
>汇总</el-button
>
<el-button
:type="selectType === 'drug' ? 'primary' : 'default'"
@click="handleSelectType('drug')"
>发药</el-button
>
</el-col>
<!-- <el-col :span="18" :xs="24">
<el-form ref="queryParams" label-width="100px" :model="queryParams" :inline="true">
<el-form-item label="窗口" prop="windowDataText" label-width="120px">
<el-select
v-model="queryParams.windowDataText"
placeholder="请选择"
clearable
filterable
>
<el-option
v-for="item in windowData"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="摆药单" prop="medicationListText" label-width="120px">
<el-select
v-model="queryParams.medicationListText"
placeholder="请选择"
clearable
filterable
>
<el-option
v-for="item in medicationList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="范围" prop="time" label-width="100px">
<el-radio-group v-model="queryParams.timeRange">
<el-radio v-for="(item, index) in timeRangeList" :key="index" :value="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="时间" prop="time" label-width="100px">
<el-date-picker
v-model="dateRange"
type="datetimerange"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</el-form>
</el-col> -->
</el-row>
<el-row :gutter="20">
<el-col :span="6" class="left-container">
<el-row>
<el-col :span="24">
<el-form
:model="queryParamsPatient"
ref="queryRef"
v-show="showSearch"
label-width="120"
inline="true"
>
<el-form-item label="患者信息" prop="searchKey" label-width="120">
<el-input
v-model="queryParamsPatient.searchKey"
placeholder="请输入姓名/证件号"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item
label="发药状态"
prop="statusEnum"
v-if="selectType !== 'drug'"
label-width="120"
>
<el-select
v-model="queryParamsPatient.statusEnum"
placeholder="请选择"
clearable
filterable
style="width: 240px"
@change="handleQuery"
>
<el-option
v-for="item in dispenseStatusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="就诊日期" prop="startTime">
<el-date-picker
v-model="dateRange"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
style="width: 240px"
@keyup.enter="handleQuery"
@change="handleQuery"
/>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row :gutter="20" style="border-radius: 4px">
<el-col :span="24">
<el-table
:data="patientList"
border
highlight-current-row
style="height: cal(100%-200px); width: 100%"
@row-click="handleCurrentChange"
>
<!-- 汇总状态下显示的字段 -->
<template v-if="selectType === 'total'">
<el-table-column prop="applicantName" label="申请人" align="center" />
<el-table-column prop="sourceLocationName" label="发药药房" align="center" />
<el-table-column prop="statusEnum_enumText" label="状态" align="center" />
<el-table-column prop="applyTime" label="申请日期" align="center">
<template #default="scope">
{{ scope.row.applyTime ? parseTime(scope.row.applyTime, '{y}-{m}-{d}') : '-' }}
</template>
</el-table-column>
</template>
<!-- 明细状态下显示的字段 -->
<template v-else>
<el-table-column prop="patientName" label="姓名" align="center" />
<el-table-column prop="genderEnum_enumText" label="性别" align="center" />
<el-table-column prop="age" label="年龄" align="center" />
<el-table-column prop="startTime" label="就诊日期" align="center">
<template #default="scope">
{{ scope.row.startTime ? parseTime(scope.row.startTime, '{y}-{m}-{d}') : '-' }}
</template>
</el-table-column>
</template>
</el-table>
</el-col>
<el-col :span="24" style="padding: 10px 12px 12px 12px">
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</el-col>
</el-row>
</el-col>
<el-col :span="18" :xs="24">
<!-- 根据当前选中的tab显示不同的表格组件 -->
<MedicationTable v-if="selectType === 'total'" :tableData="tableData" :busNo="busNo" />
<DetailMedicationTable
v-else-if="selectType === 'drug'"
:tableData="detailTableData"
:encounterId="encounterId"
@call-medication-summary-detail="callMedicationSummaryDetail"
/>
</el-col>
</el-row>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import MedicationTable from './components/MedicationTable.vue';
import DetailMedicationTable from './components/DetailMedicationTable.vue';
import { getCurrentInstance } from 'vue';
import {
getFromSummaryList,
getEncounterList,
getMedicationSummaryDetail,
getFromDetailList,
} from './components/api';
// 响应式数据
const loading = ref(false);
const patientList = ref([]);
const total = ref(0);
const showSearch = ref(true);
const { proxy } = getCurrentInstance();
// 查询参数
const queryParams = reactive({
searchKey: '',
statusEnum: '',
pageNo: 1,
pageSize: 10,
windowDataText: '',
medicationListText: '',
timeRange: 1,
});
const queryParamsPatient = ref({
searchKey: '',
statusEnum: '1',
pageNo: 1,
pageSize: 10,
});
// 日期范围
const dateRange = ref([
new Date().toISOString().split('T')[0],
new Date().toISOString().split('T')[0],
]);
// 发药状态选项
const dispenseStatusOptions = ref([
{ label: '待发药', value: '1' },
{ label: '已发药', value: '2' },
{ label: '全部', value: '0' },
]);
// 加载患者列表数据
async function getList() {
if (dateRange.value == null) {
proxy.$message.warning('请选择日期');
return;
}
loading.value = true;
try {
let response;
// 构建查询参数 - 只保留必要的分页和筛选条件
const params = {
searchKey: queryParamsPatient.value.searchKey,
statusEnum: queryParamsPatient.value.statusEnum,
pageNo: queryParamsPatient.value.pageNo,
pageSize: queryParamsPatient.value.pageSize,
startTime: dateRange.value[0],
endTime: dateRange.value[1],
};
// 根据当前标签页调用不同的接口
if (selectType.value === 'total') {
// 汇总标签页
response = await getFromSummaryList(params);
patientList.value = response.data;
total.value = response.data.length || 0;
} else {
// 明细标签页
response = await getEncounterList(params);
patientList.value = response.data.records;
total.value = response.data.total || 0;
}
} catch (error) {
patientList.value = [];
total.value = 0;
} finally {
loading.value = false;
}
}
// 搜索处理
async function handleQuery() {
queryParamsPatient.value.pageNo = 1; // 重置为第一页
await getList();
}
const busNo = ref('');
const encounterId = ref('');
// 处理表格行点击
function handleCurrentChange(row) {
busNo.value = row.busNo;
encounterId.value = row.encounterId;
if (selectType.value === 'total') {
// 汇总标签页
callSummaryMedicationDetail(row.busNo);
} else {
// 明细标签页
callMedicationSummaryDetail(row.encounterId);
}
}
// 明细标签页
async function callMedicationSummaryDetail(encounterId) {
console.log('点击明细标签页', encounterId);
// 显示加载提示
loading.value = true;
try {
const params = {
encounterId,
};
const response = await getMedicationSummaryDetail(params);
// 处理药品汇总详情数据
handleMedicationSummaryDetail(response.data);
} catch (error) {
ElMessage.error('获取药品汇总详情失败:' + (error.message || '未知错误'));
// 发生错误时清空数据
handleMedicationSummaryDetail([]);
} finally {
// 无论成功失败都关闭加载状态
loading.value = false;
}
}
// 汇总标签页
async function callSummaryMedicationDetail(busNo) {
// 显示加载提示
loading.value = true;
try {
const params = {
busNo,
};
const response = await getFromDetailList(params);
// 处理汇总药品详情数据
handleMedicationSummaryDetail(response.data);
} catch (error) {
ElMessage.error('获取汇总药品详情失败:' + (error.message || '未知错误'));
// 发生错误时清空数据
handleMedicationSummaryDetail([]);
} finally {
// 无论成功失败都关闭加载状态
loading.value = false;
}
}
// 窗口数据
const windowData = reactive([
{
label: '窗口1',
value: 1,
},
{
label: '窗口2',
value: 2,
},
{
label: '窗口3',
value: 3,
},
]);
// 摆药单数据
const medicationList = reactive([
{
label: '药单1',
value: 1,
},
{
label: '药单2',
value: 2,
},
{
label: '药单3',
value: 3,
},
]);
// 时间范围选项
const timeRangeList = [
{
label: '全部',
value: 1,
},
{
label: '长期',
value: 2,
},
{
label: '临时',
value: 3,
},
];
// 表格类型
const selectType = ref('total');
// 表格数据用于显示右侧药品列表汇总tab
const tableData = reactive([]);
// 明细表格数据用于明细tab
const detailTableData = reactive([]);
// 切换表格类型
function handleSelectType(type) {
selectType.value = type;
reset();
getList();
}
function reset() {
busNo.value = '';
encounterId.value = '';
patientList.value = [];
total.value = 0;
// 保持响应式引用不变,逐字段还原默认
queryParamsPatient.value.searchKey = '';
queryParamsPatient.value.statusEnum = '1';
queryParamsPatient.value.pageNo = 1;
queryParamsPatient.value.pageSize = 10;
}
// 处理子组件传递的药品汇总详情数据
function handleMedicationSummaryDetail(data) {
// 检查数据是否为数组
const medicationData = Array.isArray(data)
? data
: typeof data === 'object' && data !== null && Array.isArray(data.records)
? data.records
: [];
// 根据当前tab将数据分配到不同的表格
if (selectType.value === 'total') {
// 汇总tab - 清空表格数据
tableData.splice(0, tableData.length);
if (medicationData.length > 0) {
medicationData.forEach((item, index) => {
tableData.push({
currentIndex: index + 1,
...item,
});
});
}
} else {
// 明细tab - 将数据渲染到DetailMedicationTable组件
detailTableData.splice(0, detailTableData.length);
medicationData.forEach((item) => {
detailTableData.push({
...item,
});
});
}
}
// 组件挂载时初始化数据
onMounted(() => {
getList();
});
</script>
<style scoped>
.left-container {
border-radius: 4px;
border: 1px solid #f5f5f5;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
padding: 20px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,664 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :span="6">
<el-row class="section-title">公费医疗自付总体比例</el-row>
<el-form :inline="true" label-width="68px">
<el-form-item>
<el-button type="primary" icon="Edit" @click="handleEdit">修改</el-button>
<el-button icon="Refresh" @click="resetTypeQuery">刷新</el-button>
</el-form-item>
</el-form>
<el-table v-loading="typeLoading" :data="typeRatioList" height="600" stripe>
<el-table-column label="医保分项编码" prop="ybClass" :show-overflow-tooltip="true" align="center" />
<el-table-column label="医保分项名称" prop="ybClassName" :show-overflow-tooltip="true" align="center" />
<el-table-column label="医保等级" prop="ybLvName" :show-overflow-tooltip="true" align="center" />
<!-- 自付比例列 -->
<el-table-column label="自付比例" align="center" width="150">
<template #default="scope">
<span
v-if="scope.row.selfRatio !== null && scope.row.selfRatio !== undefined && scope.row.selfRatio !== ''">
{{ scope.row.selfRatio }}%
</span>
<span v-else>-</span>
</template>
</el-table-column>
</el-table>
</el-col>
<el-col :span="18">
<el-row class="section-title">单个药品/诊疗现行自付比例</el-row>
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true" label-width="68px">
<el-form-item label="项目" prop="searchKey">
<el-input v-model="queryParams.searchKey" placeholder="项目编号/项目名称/医保编码" clearable style="width: 240px"
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="项目分类" prop="itemType" label-width="100">
<el-select v-model="queryParams.itemType" clearable style="width: 200px;">
<el-option label="药品" value="1"></el-option>
<el-option label="诊疗" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetIndividualQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 表格数据 -->
<el-table v-loading="individualLoading" :data="individualRatioList">
<el-table-column label="项目编号" prop="busNo" :show-overflow-tooltip="true" />
<el-table-column label="项目名称" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="医保编码" width="250">
<template #default="scope">
<span v-if="scope.row.ybNo !== null && scope.row.ybNo !== undefined && scope.row.ybNo !== ''">
{{ scope.row.ybNo }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="项目分类" prop="itemTypeName" :show-overflow-tooltip="true" width="110" align="center" />
<el-table-column label="医保等级" prop="chrgitmLvName" :show-overflow-tooltip="true" width="110" align="center" />
<!-- 自付比例列 -->
<el-table-column label="自付比例" align="center" width="150">
<template #default="scope">
<span
v-if="scope.row.selfRatio !== null && scope.row.selfRatio !== undefined && scope.row.selfRatio !== ''">
{{ scope.row.selfRatio }}%
</span>
<span v-else>-</span>
</template>
</el-table-column>
<!-- 二次自付比例列 -->
<el-table-column label="二次自付比例" align="center" width="150">
<template #default="scope">
<span
v-if="scope.row.twiceRatio !== null && scope.row.twiceRatio !== undefined && scope.row.twiceRatio !== ''">
{{ scope.row.twiceRatio }}%
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="开始时间" prop="startDate" :show-overflow-tooltip="true" align="center" />
<el-table-column label="结束时间" prop="endDate" :show-overflow-tooltip="true" align="center" />
</el-table>
<pagination v-show="individualTotal > 0" :total="individualTotal" v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize" @pagination="getIndividualList" />
</el-col>
</el-row>
<!-- 修改对话框 -->
<el-dialog title="修改总体自付比例" v-model="typeRatioOpen" width="1000px" append-to-body>
<el-form ref="typeRatioRef" :model="typeRatioForm" :rules="rules" label-width="180px">
<el-row :gutter="20">
<!-- 左侧列 -->
<el-col :span="12">
<el-form-item label="床位费比例(甲类)" prop="a01ratio">
<el-input v-model="typeRatioForm.a01ratio" placeholder="请输入床位费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="诊察费比例(甲类)" prop="a02ratio">
<el-input v-model="typeRatioForm.a02ratio" placeholder="请输入诊察费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="检查费比例(甲类)" prop="a03ratio">
<el-input v-model="typeRatioForm.a03ratio" placeholder="请输入检查费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="化验费比例(甲类)" prop="a04ratio">
<el-input v-model="typeRatioForm.a04ratio" placeholder="请输入化验费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="治疗费比例(甲类)" prop="a05ratio">
<el-input v-model="typeRatioForm.a05ratio" placeholder="请输入治疗费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="手术费比例(甲类)" prop="a06ratio">
<el-input v-model="typeRatioForm.a06ratio" placeholder="请输入手术费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="护理费比例(甲类)" prop="a07ratio">
<el-input v-model="typeRatioForm.a07ratio" placeholder="请输入护理费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="卫生材料费比例(甲类)" prop="a08ratio">
<el-input v-model="typeRatioForm.a08ratio" placeholder="请输入卫生材料费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="西药费比例(甲类)" prop="a09ratio">
<el-input v-model="typeRatioForm.a09ratio" placeholder="请输入西药费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="中药饮片费比例(甲类)" prop="a10ratio">
<el-input v-model="typeRatioForm.a10ratio" placeholder="请输入中药饮片费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="中成药费比例(甲类)" prop="a11ratio">
<el-input v-model="typeRatioForm.a11ratio" placeholder="请输入中成药费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="一般诊疗费比例(甲类)" prop="a12ratio">
<el-input v-model="typeRatioForm.a12ratio" placeholder="请输入一般诊疗费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="挂号费比例(甲类)" prop="a13ratio">
<el-input v-model="typeRatioForm.a13ratio" placeholder="请输入挂号费比例(甲类)" style="width: 100%" />
</el-form-item>
<el-form-item label="其他费比例(甲类)" prop="a14ratio">
<el-input v-model="typeRatioForm.a14ratio" placeholder="请输入其他费比例(甲类)" style="width: 100%" />
</el-form-item>
</el-col>
<!-- 右侧列 -->
<el-col :span="12">
<el-form-item label="床位费比例(乙类)" prop="b01ratio">
<el-input v-model="typeRatioForm.b01ratio" placeholder="请输入床位费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="诊察费比例(乙类)" prop="b02ratio">
<el-input v-model="typeRatioForm.b02ratio" placeholder="请输入诊察费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="检查费比例(乙类)" prop="b03ratio">
<el-input v-model="typeRatioForm.b03ratio" placeholder="请输入检查费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="化验费比例(乙类)" prop="b04ratio">
<el-input v-model="typeRatioForm.b04ratio" placeholder="请输入化验费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="治疗费比例(乙类)" prop="b05ratio">
<el-input v-model="typeRatioForm.b05ratio" placeholder="请输入治疗费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="手术费比例(乙类)" prop="b06ratio">
<el-input v-model="typeRatioForm.b06ratio" placeholder="请输入手术费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="护理费比例(乙类)" prop="b07ratio">
<el-input v-model="typeRatioForm.b07ratio" placeholder="请输入护理费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="卫生材料费比例(乙类)" prop="b08ratio">
<el-input v-model="typeRatioForm.b08ratio" placeholder="请输入卫生材料费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="西药费比例(乙类)" prop="b09ratio">
<el-input v-model="typeRatioForm.b09ratio" placeholder="请输入西药费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="中药饮片费比例(乙类)" prop="b10ratio">
<el-input v-model="typeRatioForm.b10ratio" placeholder="请输入中药饮片费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="中成药费比例(乙类)" prop="b11ratio">
<el-input v-model="typeRatioForm.b11ratio" placeholder="请输入中成药费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="一般诊疗费比例(乙类)" prop="b12ratio">
<el-input v-model="typeRatioForm.b12ratio" placeholder="请输入一般诊疗费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="挂号费比例(乙类)" prop="b13ratio">
<el-input v-model="typeRatioForm.b13ratio" placeholder="请输入挂号费比例(乙类)" style="width: 100%" />
</el-form-item>
<el-form-item label="其他费比例(乙类)" prop="b14ratio">
<el-input v-model="typeRatioForm.b14ratio" placeholder="请输入其他费比例(乙类)" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="GfRatioManage">
import {
getTypeRatioList,
saveTypeRatioList,
getIndividualRatioPage
} from "@/api/gf/ratioManage";
const { proxy } = getCurrentInstance();
const typeRatioOpen = ref(false);
const showSearch = ref(true);
const individualRatioList = ref([]);
const individualLoading = ref(true);
const individualTotal = ref(0);
const individualDateRange = ref([]);
const typeRatioList = ref([]);
const typeLoading = ref(true);
const typeDateRange = ref([]);
// 验证规则
const validateRatio = (rule, value, callback) => {
if (value === '' || value === null) {
return callback(new Error('自付比例不能为空'));
}
const numValue = parseFloat(value);
if (isNaN(numValue)) {
return callback(new Error('请输入有效数字'));
}
if (numValue < 0 || numValue > 100) {
return callback(new Error('自付比例必须在0~100之间'));
}
// 验证小数位(可选)
if (value.toString().includes('.') && value.toString().split('.')[1].length > 2) {
return callback(new Error('最多保留两位小数'));
}
callback();
};
const data = reactive({
typeRatioForm: {},
queryParams: {
pageNo: 1,
pageSize: 10,
searchKey: undefined,
itemType: undefined,
},
rules: {
a01ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b01ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a02ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b02ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a03ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b03ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a04ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b04ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a05ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b05ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a06ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b06ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a07ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b07ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a08ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b08ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a09ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b09ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a10ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b10ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a11ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b11ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a12ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b12ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a13ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b13ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
a14ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
b14ratio: [
{ pattern: /^\d*(\.\d{0,2})?$/, message: '请输入数字,最多保留两位小数', trigger: 'blur' },
{ validator: validateRatio, trigger: 'blur' }
],
}
});
const { queryParams, typeRatioForm, rules } = toRefs(data);
/** 查询单项比例分页 */
function getIndividualList() {
individualLoading.value = true;
getIndividualRatioPage(proxy.addDateRange(queryParams.value, individualDateRange.value)).then(response => {
individualRatioList.value = response.data.records;
individualTotal.value = response.data.total;
individualLoading.value = false;
});
}
/** 查询单项比例分页 */
function getTypeList() {
typeLoading.value = true;
getTypeRatioList(proxy.addDateRange(queryParams.value, typeDateRange.value)).then(response => {
typeRatioList.value = response.data;
typeLoading.value = false;
});
}
/** 刷新按钮操作 */
function resetTypeQuery() {
getTypeList();
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNo = 1;
getIndividualList();
}
/** 重置按钮操作 */
function resetIndividualQuery() {
individualDateRange.value = [];
proxy.resetForm("queryRef");
handleQuery();
}
/** 修改总体比例 */
function handleEdit() {
typeRatioOpen.value = true;
getTypeRatioList(proxy.addDateRange(queryParams.value, typeDateRange.value)).then(response => {
typeRatioList.value = response.data;
for (const r of typeRatioList.value) {
if (r.ybClass == '01' && r.ybLv == '1') {
typeRatioForm.value.a01ratio = r.selfRatio
}
if (r.ybClass == '01' && r.ybLv == '2') {
typeRatioForm.value.b01ratio = r.selfRatio
}
if (r.ybClass == '02' && r.ybLv == '1') {
typeRatioForm.value.a02ratio = r.selfRatio
}
if (r.ybClass == '02' && r.ybLv == '2') {
typeRatioForm.value.b02ratio = r.selfRatio
}
if (r.ybClass == '03' && r.ybLv == '1') {
typeRatioForm.value.a03ratio = r.selfRatio
}
if (r.ybClass == '03' && r.ybLv == '2') {
typeRatioForm.value.b03ratio = r.selfRatio
}
if (r.ybClass == '04' && r.ybLv == '1') {
typeRatioForm.value.a04ratio = r.selfRatio
}
if (r.ybClass == '04' && r.ybLv == '2') {
typeRatioForm.value.b04ratio = r.selfRatio
}
if (r.ybClass == '05' && r.ybLv == '1') {
typeRatioForm.value.a05ratio = r.selfRatio
}
if (r.ybClass == '05' && r.ybLv == '2') {
typeRatioForm.value.b05ratio = r.selfRatio
}
if (r.ybClass == '06' && r.ybLv == '1') {
typeRatioForm.value.a06ratio = r.selfRatio
}
if (r.ybClass == '06' && r.ybLv == '2') {
typeRatioForm.value.b06ratio = r.selfRatio
}
if (r.ybClass == '07' && r.ybLv == '1') {
typeRatioForm.value.a07ratio = r.selfRatio
}
if (r.ybClass == '07' && r.ybLv == '2') {
typeRatioForm.value.b07ratio = r.selfRatio
}
if (r.ybClass == '08' && r.ybLv == '1') {
typeRatioForm.value.a08ratio = r.selfRatio
}
if (r.ybClass == '08' && r.ybLv == '2') {
typeRatioForm.value.b08ratio = r.selfRatio
}
if (r.ybClass == '09' && r.ybLv == '1') {
typeRatioForm.value.a09ratio = r.selfRatio
}
if (r.ybClass == '09' && r.ybLv == '2') {
typeRatioForm.value.b09ratio = r.selfRatio
}
if (r.ybClass == '10' && r.ybLv == '1') {
typeRatioForm.value.a10ratio = r.selfRatio
}
if (r.ybClass == '10' && r.ybLv == '2') {
typeRatioForm.value.b10ratio = r.selfRatio
}
if (r.ybClass == '11' && r.ybLv == '1') {
typeRatioForm.value.a11ratio = r.selfRatio
}
if (r.ybClass == '11' && r.ybLv == '2') {
typeRatioForm.value.b11ratio = r.selfRatio
}
if (r.ybClass == '12' && r.ybLv == '1') {
typeRatioForm.value.a12ratio = r.selfRatio
}
if (r.ybClass == '12' && r.ybLv == '2') {
typeRatioForm.value.b12ratio = r.selfRatio
}
if (r.ybClass == '13' && r.ybLv == '1') {
typeRatioForm.value.a13ratio = r.selfRatio
}
if (r.ybClass == '13' && r.ybLv == '2') {
typeRatioForm.value.b13ratio = r.selfRatio
}
if (r.ybClass == '14' && r.ybLv == '1') {
typeRatioForm.value.a14ratio = r.selfRatio
}
if (r.ybClass == '14' && r.ybLv == '2') {
typeRatioForm.value.b14ratio = r.selfRatio
}
}
});
}
/** 提交按钮 */
function submitForm() {
let form = {
typeRatioList: [{
ybClass: "01",
ybLv: "1",
selfRatio: typeRatioForm.value.a01ratio
}, {
ybClass: "01",
ybLv: "2",
selfRatio: typeRatioForm.value.b01ratio
}, {
ybClass: "02",
ybLv: "1",
selfRatio: typeRatioForm.value.a02ratio
}, {
ybClass: "02",
ybLv: "2",
selfRatio: typeRatioForm.value.b02ratio
}, {
ybClass: "03",
ybLv: "1",
selfRatio: typeRatioForm.value.a03ratio
}, {
ybClass: "03",
ybLv: "2",
selfRatio: typeRatioForm.value.b03ratio
}, {
ybClass: "04",
ybLv: "1",
selfRatio: typeRatioForm.value.a04ratio
}, {
ybClass: "04",
ybLv: "2",
selfRatio: typeRatioForm.value.b04ratio
}, {
ybClass: "05",
ybLv: "1",
selfRatio: typeRatioForm.value.a05ratio
}, {
ybClass: "05",
ybLv: "2",
selfRatio: typeRatioForm.value.b05ratio
}, {
ybClass: "06",
ybLv: "1",
selfRatio: typeRatioForm.value.a06ratio
}, {
ybClass: "06",
ybLv: "2",
selfRatio: typeRatioForm.value.b06ratio
}, {
ybClass: "07",
ybLv: "1",
selfRatio: typeRatioForm.value.a07ratio
}, {
ybClass: "07",
ybLv: "2",
selfRatio: typeRatioForm.value.b07ratio
}, {
ybClass: "08",
ybLv: "1",
selfRatio: typeRatioForm.value.a08ratio
}, {
ybClass: "08",
ybLv: "2",
selfRatio: typeRatioForm.value.b08ratio
}, {
ybClass: "09",
ybLv: "1",
selfRatio: typeRatioForm.value.a09ratio
}, {
ybClass: "09",
ybLv: "2",
selfRatio: typeRatioForm.value.b09ratio
}, {
ybClass: "10",
ybLv: "1",
selfRatio: typeRatioForm.value.a10ratio
}, {
ybClass: "10",
ybLv: "2",
selfRatio: typeRatioForm.value.b10ratio
}, {
ybClass: "11",
ybLv: "1",
selfRatio: typeRatioForm.value.a11ratio
}, {
ybClass: "11",
ybLv: "2",
selfRatio: typeRatioForm.value.b11ratio
}, {
ybClass: "12",
ybLv: "1",
selfRatio: typeRatioForm.value.a12ratio
}, {
ybClass: "12",
ybLv: "2",
selfRatio: typeRatioForm.value.b12ratio
}, {
ybClass: "13",
ybLv: "1",
selfRatio: typeRatioForm.value.a13ratio
}, {
ybClass: "13",
ybLv: "2",
selfRatio: typeRatioForm.value.b13ratio
}, {
ybClass: "14",
ybLv: "1",
selfRatio: typeRatioForm.value.a14ratio
}, {
ybClass: "14",
ybLv: "2",
selfRatio: typeRatioForm.value.b14ratio
}]
}
proxy.$refs["typeRatioRef"].validate(valid => {
if (valid) {
saveTypeRatioList(form).then(response => {
proxy.$modal.msgSuccess("修改成功");
typeRatioOpen.value = false;
getTypeList();
})
}
})
}
/** 取消按钮 */
function cancel() {
open.value = false;
reset();
}
getIndividualList();
getTypeList();
</script>
<style>
.form-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px 15px;
}
.grid-item {
margin-bottom: 0;
background: white;
border-radius: 8px;
padding: 5px;
transition: all 0.3s ease;
}
.grid-item :deep(.el-input) {
width: 100%;
}
/* 描述文本样式 */
.item-description {
font-size: 12px;
color: #7f8c8d;
margin-top: 8px;
line-height: 1.4;
padding: 5px;
background-color: #f9f9f9;
border-radius: 4px;
}
.section-title {
margin-bottom: 20px;
font-weight: 550;
font-size: 18px;
color: #515A6E;
}
</style>

View File

@@ -0,0 +1,459 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true" label-width="68px">
<el-form-item label="学生" prop="searchKey">
<el-input v-model="queryParams.searchKey" placeholder="学号/姓名/身份证号" clearable style="width: 240px"
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="在校状态" prop="studentStatus" label-width="100">
<el-select v-model="queryParams.studentStatus" clearable style="width: 200px;">
<el-option v-for="dict in student_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="体检结果" prop="physicalExamResult" label-width="100">
<el-select v-model="queryParams.physicalExamResult" clearable style="width: 200px;">
<el-option v-for="dict in physical_exam_result" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd">添加</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Upload" @click="handleImport">导入</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 表格数据 -->
<el-table v-loading="loading" :data="studentList">
<el-table-column label="学号" prop="studentId" :show-overflow-tooltip="true" width="150" />
<el-table-column label="姓名" prop="name" :show-overflow-tooltip="true" width="150" />
<el-table-column label="性别" prop="gender_dictText" :show-overflow-tooltip="true" width="70" align="center" />
<el-table-column label="年龄" prop="age" :show-overflow-tooltip="true" width="70" align="center" />
<el-table-column label="身份证号" prop="idNumber" :show-overflow-tooltip="true" width="200" />
<el-table-column label="电话" prop="phone" :show-overflow-tooltip="true" width="150" />
<el-table-column label="学院" prop="college" :show-overflow-tooltip="true" width="150" />
<el-table-column label="专业" prop="major" :show-overflow-tooltip="true" width="150" />
<el-table-column label="年级" prop="grade" :show-overflow-tooltip="true" width="100" />
<el-table-column label="学历层次" prop="educationLevel_dictText" :show-overflow-tooltip="true" width="120"
align="center" />
<el-table-column label="入校时间" prop="enrollmentDate" :show-overflow-tooltip="true" width="120" align="center" />
<el-table-column label="离校时间" prop="graduationDate" :show-overflow-tooltip="true" width="120" align="center" />
<el-table-column label="学习形式" prop="studyMode_dictText" :show-overflow-tooltip="true" width="120"
align="center" />
<el-table-column label="在校状态" prop="studentStatus_dictText" :show-overflow-tooltip="true" width="100"
align="center" />
<el-table-column label="体检结果" prop="physicalExamResult_dictText" :show-overflow-tooltip="true" width="120"
align="center" />
<el-table-column label="辅导员" width="120">
<template #default="scope">
<span v-if="scope.row.counselor !== null && scope.row.counselor !== undefined && scope.row.counselor !== ''">
{{ scope.row.counselor }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="辅导员电话" width="170">
<template #default="scope">
<span
v-if="scope.row.counselorPhone !== null && scope.row.counselorPhone !== undefined && scope.row.counselorPhone !== ''">
{{ scope.row.counselorPhone }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
<template #default="scope">
<el-tooltip content="编辑" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">编辑</el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
<!-- 添加或修改对话框 -->
<el-dialog :title="title" v-model="open" width="700px" append-to-body>
<el-form ref="studentListRef" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<!-- 左侧列 -->
<el-col :span="12">
<el-form-item label="学号" prop="studentId">
<el-input v-model="form.studentId" placeholder="请输入学号" style="width: 100%" />
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名" style="width: 100%" />
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-radio-group v-model="form.gender">
<el-radio v-for="dict in sys_user_sex" :key="dict.value" :label="dict.value">
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input :disabled="true" v-model="form.age" placeholder="根据身份证自动计算,无需填写" style="width: 100%" />
</el-form-item>
<el-form-item label="身份证号" prop="idNumber">
<el-input v-model="form.idNumber" placeholder="请输入身份证号" style="width: 100%" />
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入电话" style="width: 100%" />
</el-form-item>
<el-form-item label="学院" prop="college">
<el-input v-model="form.college" placeholder="请输入学院" style="width: 100%" />
</el-form-item>
<el-form-item label="专业" prop="major">
<el-input v-model="form.major" placeholder="请输入专业" style="width: 100%" />
</el-form-item>
</el-col>
<!-- 右侧列 -->
<el-col :span="12">
<el-form-item label="年级" prop="grade">
<el-input v-model="form.grade" placeholder="请输入年级" style="width: 100%" />
</el-form-item>
<el-form-item label="学历层次" prop="educationLevel">
<el-select v-model="form.educationLevel" clearable style="width: 100%">
<el-option v-for="dict in education_level" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="入校时间" prop="enrollmentDate">
<el-date-picker v-model="form.enrollmentDate" type="date" placeholder="请选择入校时间" value-format="YYYY-MM-DD"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="离校时间" prop="graduationDate">
<el-date-picker v-model="form.graduationDate" type="date" placeholder="请选择离校时间" value-format="YYYY-MM-DD"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="学习形式" prop="studyMode">
<el-select v-model="form.studyMode" clearable style="width: 100%">
<el-option v-for="dict in study_mode" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="在校状态" prop="studentStatus">
<el-select v-model="form.studentStatus" clearable style="width: 100%">
<el-option v-for="dict in student_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="体检结果" prop="physicalExamResult">
<el-select v-model="form.physicalExamResult" clearable style="width: 100%">
<el-option v-for="dict in physical_exam_result" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="辅导员" prop="counselor">
<el-input v-model="form.counselor" placeholder="请输入辅导员" style="width: 100%" />
</el-form-item>
<el-form-item label="辅导员电话" prop="counselorPhone">
<el-input v-model="form.counselorPhone" placeholder="请输入辅导员电话" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
<!-- 导入对话框 -->
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
<el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip text-center">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
@click="importTemplate">下载模板</el-link>
</div>
</template>
</el-upload>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="GfStudentList">
import { getToken } from "@/utils/auth";
import {
getPage,
getDetail,
add,
edit,
remove
} from "@/api/gf/studentList";
const { proxy } = getCurrentInstance();
const {
sys_user_sex,
education_level,
study_mode,
student_status,
physical_exam_result
} = proxy.useDict(
"sys_user_sex",
"education_level",
"study_mode",
"student_status",
"physical_exam_result",
);
const studentList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const title = ref("");
const dateRange = ref([]);
/*** 器材目录导入参数 */
const upload = reactive({
// 是否显示弹出层
open: false,
// 弹出层标题
title: "",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + "/nenu/gf-student-list/import-data"
});
const data = reactive({
form: {},
queryParams: {
pageNo: 1,
pageSize: 10,
searchKey: undefined,
studentStatus: undefined,
physicalExamResult: undefined,
},
rules: {
studentId: [
{ required: true, message: "学号不能为空", trigger: "blur" }
],
name: [
{ required: true, message: "姓名不能为空", trigger: "blur" }
],
gender: [
{ required: true, message: "性别不能为空", trigger: "blur" }
],
idNumber: [
{ required: true, message: "身份证号不能为空", trigger: "blur" }
],
phone: [
{ required: true, message: "电话不能为空", trigger: "blur" }
],
college: [
{ required: true, message: "学院不能为空", trigger: "blur" }
],
major: [
{ required: true, message: "专业不能为空", trigger: "blur" }
],
grade: [
{ required: true, message: "年级不能为空", trigger: "blur" }
],
educationLevel: [
{ required: true, message: "学历层次不能为空", trigger: "blur" }
],
enrollmentDate: [
{ required: true, message: "入校时间不能为空", trigger: "blur" }
],
graduationDate: [
{ required: true, message: "离校时间不能为空", trigger: "blur" }
],
studyMode: [
{ required: true, message: "学习形式不能为空", trigger: "blur" }
],
studentStatus: [
{ required: true, message: "在校状态不能为空", trigger: "blur" }
],
physicalExamResult: [
{ required: true, message: "体检结果不能为空", trigger: "blur" }
],
},
});
const { queryParams, form, rules } = toRefs(data);
/** 查询学生名单 */
function getList() {
loading.value = true;
getPage(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
studentList.value = response.data.records;
total.value = response.data.total;
loading.value = false;
});
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNo = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
dateRange.value = [];
proxy.resetForm("queryRef");
handleQuery();
}
/** 重置新增的表单以及其他数据 */
function reset() {
form.value = {
id: undefined,
name: undefined,
gender: undefined,
age: undefined,
studentId: undefined,
idNumber: undefined,
phone: undefined,
college: undefined,
major: undefined,
educationLevel: undefined,
enrollmentDate: undefined,
graduationDate: undefined,
grade: undefined,
studyMode: undefined,
studentStatus: undefined,
physicalExamResult: undefined,
counselor: undefined,
counselorPhone: undefined,
patientId: undefined,
};
proxy.resetForm("studentListRef");
}
/** 添加学生 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加学生信息";
}
/** 修改学生 */
function handleUpdate(row) {
reset();
getDetail(row.id).then(response => {
form.value = response.data;
//字典str与实际值num不匹配导致无法回显加了这个
form.value.gender = response.data.gender.toString()
form.value.educationLevel = response.data.educationLevel.toString()
form.value.studyMode = response.data.studyMode.toString()
form.value.studentStatus = response.data.studentStatus.toString()
form.value.physicalExamResult = response.data.physicalExamResult.toString()
open.value = true;
title.value = "修改学生信息";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["studentListRef"].validate(valid => {
if (valid) {
if (form.value.id != undefined) {
edit(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
add(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 取消按钮 */
function cancel() {
open.value = false;
reset();
}
/** 导入按钮操作 */
function handleImport() {
upload.title = '学生名单导入';
upload.open = true;
}
/** 下载模板操作 */
function importTemplate() {
proxy.download('/nenu/gf-student-list/import-template', {}, `student_template_${new Date().getTime()}.xlsx`);
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true;
};
/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {
upload.open = false;
upload.isUploading = false;
proxy.$refs['uploadRef'].handleRemove(file);
proxy.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
'</div>',
'导入结果',
{ dangerouslyUseHTMLString: true }
);
getList();
};
/** 提交上传文件 */
function submitFileForm() {
proxy.$refs['uploadRef'].submit();
}
getList();
</script>
<style>
.form-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px 15px;
}
.grid-item {
margin-bottom: 0;
background: white;
border-radius: 8px;
padding: 5px;
transition: all 0.3s ease;
}
.grid-item :deep(.el-input) {
width: 100%;
}
/* 描述文本样式 */
.item-description {
font-size: 12px;
color: #7f8c8d;
margin-top: 8px;
line-height: 1.4;
padding: 5px;
background-color: #f9f9f9;
border-radius: 4px;
}
</style>

View File

@@ -302,6 +302,149 @@ import { ref, reactive } from 'vue';
// 表单数据
const formData = reactive({
//组织机构代码
medins_orgcode: '',
//医疗付费方式
//健康卡号
//姓名--患者姓名
patient_name: '',
//性别--患者性别
gend: '',
//出生日期
brdy: '',
//年龄
age: '',
//国籍
ntly: '',
//籍贯
napl: '',
//民族
naty: '',
//身份证号
certNo: '',
//户口地址
resd_addr:'',
//工作单位及地址
empr_addr: '',
//联系人姓名
coner_name: '',
//关系
patn_rlts: '',
//地址
addr: '',
//电话
tel: '',
//第几次住院
patn_ipt_cnt: '',
//住院号 mdtrtsn
ipt_no: '',
//病案号
medcasno: '',
//入院途径
adm_way: '',
//入院时间
adm_time: '',
//入院科室 adm_dept_codg
adm_dept_name: '',
//病房 入院病房
adm_ward: '',
//实际住院天数
act_ipt_days: '',
//主要诊断----不确定
diag_code: '',
//其他诊断
//是否输血
//血型
//Rh
//药物过敏史
//科主任 科主任姓名--deptort_name:
deptort: '',
//主任(副主任)医师
chfdr_name: '',
//主治医师 主诊医师姓名--chfpdr_name
atddr_no: '',
//住院医师 住院医师姓名--ipdr_name
ipdr_code: '',
//责任护士 责任护士姓名--resp_nurs_name
resp_nurs_code: '',
//住院总医师
//实习医师
intn_dr_name: '',
//病案质量 病案质量名称--medcas_qlt_name
medcas_qlt_code: '',
//编码员
codr_name: '',
//质控日期
qltctrl_date: '',
hospital: {
orgCode: '41275054-7',
paymentMethod: '城乡居民基本医疗保险'

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,804 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
.hisSec {
padding: 10px 0;
width: 100vw;
min-height: 100vh;
display: flex;
flex-direction: row;
justify-content: center;
}
.font_1 {
font-size: 14px;
font-weight: bold;
}
.font_2 {
font-size: 14px;
}
.font_3 {
font-size: 13px;
}
.font_4 {
font-size: 12px;
}
.hisSecInner {
width: 1000px;
height: 100%;
}
.tableBox {
margin: 10px 0;
}
.tableBoxInner {
}
.borderRight {
border-right: 1px solid #333333;
}
.borderBottom {
border-bottom: 1px solid #333333;
}
.tableBoxItemHeader {
font-weight: bold;
display: flex;
flex-direction: row;
align-items: center;
height: 50px;
}
.tableBoxItemHeader .item {
white-space: wrap;
border-top: 1px solid #333333;
border-left: 1px solid #333333;
box-sizing: border-box;
padding: 10px 2px;
height: 100%;
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.tableBoxItemHeader .itemIndex {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 3.5%;
}
.tableBoxItemHeader .chooseAllBtn {
width: 18px;
height: 18px;
}
.tableBoxItemHeader .itemDate {
width: 10%;
}
.tableBoxItemHeader .itemSurgeryLevel {
width: 7%;
}
.tableBoxItemHeader .itemSurgeryName {
width: 23%;
}
.tableBoxItemHeader .itemCutLevel {
width: 9%;
}
.tableBoxItemHeader .itemCutLevel1 {
width: 12%;
}
.tableBoxItemHeader .itemCutLevel2 {
width: 7%;
}
.tableBoxItemHeader .itemTime {
width: 9%;
}
.tableBoxItemHeader .itemSpec {
width: 20%;
border-top: 1px solid #333333;
border-left: 1px solid #333333;
height: 50px;
}
.tableBoxItemHeader .itemSpec .spec {
width: 100%;
text-align: center;
height: 50%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.tableBoxItemHeader .itemSpec .spec .specItem {
width: 33.33%;
height: 100%;
line-height: 25px;
}
.tableBoxItemHeader .itemSpec .spec_ {
width: 100%;
text-align: center;
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.tableBoxItemHeader .itemSpec .spec_ .specItem {
width: 33.33%;
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.tableBoxItemHeader .itemCheckBox {
width: 18px;
height: 18px;
cursor: pointer;
border: 1px solid #ccc;
border-radius: 2px;
}
.tableBoxItemHeader .itemCheckBoxAct {
line-height: 16px;
text-align: center;
font-size: 12px;
width: 18px;
height: 18px;
cursor: pointer;
border: 1px solid #ccc;
border-radius: 2px;
background: #333333;
color: #fff;
}
.tableBoxItemHeader .itemCheckBox:hover {
border: 1px solid #333333;
}
.tableBoxItem {
display: flex;
flex-direction: row;
align-items: center;
height: 55px;
}
.tableBoxItem .item {
border-top: 1px solid #333333;
border-left: 1px solid #333333;
//line-height: 40px;
box-sizing: border-box;
padding: 10px 2px;
height: 100%;
text-align: center;
}
.tableBoxItem .itemIndex {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 3.5%;
}
.tableBoxItem .itemDate {
width: 10%;
}
.tableBoxItem .itemSurgeryLevel {
width: 7%;
}
.tableBoxItem .itemSurgeryName {
width: 23%;
}
.tableBoxItem .itemCutLevel {
width: 9%;
}
.tableBoxItem .itemCutLevel1 {
width: 12%;
}
.tableBoxItem .itemCutLevel2 {
width: 7%;
}
.tableBoxItem .itemTime {
width: 9%;
}
.tableBoxItem .itemSpec {
width: 20%;
border-top: 1px solid #333333;
border-left: 1px solid #333333;
height: 55px;
}
.tableBoxItem .itemSpec .spec {
width: 100%;
text-align: center;
height: 50%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.tableBoxItem .itemSpec .spec .specItem {
width: 33.33%;
height: 100%;
line-height: 25px;
}
.tableBoxItem .itemSpec .spec_ {
width: 100%;
text-align: center;
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.tableBoxItem .itemSpec .spec_ .specItem {
width: 33.33%;
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.tableBoxItem .itemCheckBox {
width: 18px;
height: 18px;
cursor: pointer;
border: 1px solid #ccc;
border-radius: 2px;
}
.tableBoxItem .itemCheckBoxAct {
line-height: 16px;
text-align: center;
font-size: 12px;
width: 18px;
height: 18px;
cursor: pointer;
border: 1px solid #ccc;
border-radius: 2px;
background: #409eff;
color: #fff;
}
.tableBoxItem .itemCheckBox:hover {
border: 1px solid #409eff;
}
.topBar {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #333333;
padding-bottom: 5px;
margin-bottom: 10px;
}
.secItem {
width: 100%;
display: flex;
flex-direction: row;
//align-items: center;
justify-content: left;
border-bottom: 1px solid #333333;
padding-bottom: 5px;
margin-bottom: 10px;
}
.secItem1 {
width: 100%;
border-bottom: 1px solid #333333;
padding-bottom: 5px;
margin-bottom: 10px;
}
.chooseBox {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 15px;
height: 15px;
border: 1px solid #333;
font-size: 12px;
margin: 0 5px;
}
.rowBox {
display: flex;
flex-direction: row;
align-items: center;
}
.writeArea {
display: inline-block;
width: 150px;
border-bottom: 1px solid #333333;
padding-bottom: 2px;
}
.writeAreaCenter {
display: inline-block;
width: 100px;
border-bottom: 1px solid #333333;
padding-bottom: 2px;
text-align: center;
}
.writeAreaSort {
display: inline-block;
width: 35px;
border-bottom: 1px solid #333333;
//padding-bottom: 2px;
text-align: center;
}
.marginSmall {
margin: 0 5px;
}
.marginNor {
margin: 0 10px;
}
.marginBig {
margin: 0 20px;
}
.marginB {
margin-bottom: 10px;
}
.marginR_B {
margin-right: 40px;
}
.marginR_S {
margin-right: 20px;
}
.subTable {
}
.tableBarHeader {
text-align: center;
height: 35px;line-height: 35px;
border-top: 1px solid #333333;
border-left: 1px solid #333333;
border-right: 1px solid #333333;
font-size: 15px;
}
.tableBar {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: left;
height: 35px;
}
.barItem {
height: 100%;
width: 33.33%;
box-sizing: border-box;
padding: 10px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-top: 1px solid #333333;
border-left: 1px solid #333333;
}
.barItem1 {
height: 100%;
width: 120%;
box-sizing: border-box;
padding: 10px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-top: 1px solid #333333;
border-left: 1px solid #333333;
}
.barItem2 {
height: 100%;
width: 30%;
box-sizing: border-box;
padding: 10px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-top: 1px solid #333333;
border-left: 1px solid #333333;
}
.borderR {
border-right: 1px solid #333333;
}
.borderB {
border-bottom: 1px solid #333333;
}
</style>
</head>
<body>
<div class="hisSec">
<div class="hisSecInner">
<div class="topBar">
<div class="font_2">姓名:金长存</div>
<div class="font_2">病案号12345678</div>
</div>
<div class="secItem">
<div class="font_1">住院费用(元):</div>
<div class="rowBox">
<div class="marginSmall font_3">总费用:<span class="writeAreaCenter"></span> (自付金额:<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">1.综合医疗服务类:</div>
<div class="marginSmall font_3">1一般医疗服务费<span class="writeAreaCenter"></span></div>
</div>
<div class="rowBox">
<div class="marginSmall font_3">2一般治疗操作费<span class="writeAreaCenter"></span></div>
<div class="marginSmall font_3">3护理费<span class="writeAreaCenter"></span></div>
<div class="marginSmall font_3">4其他费用<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">2.诊断类:</div>
<div class="marginSmall font_3">5病理诊断费<span class="writeAreaCenter"></span></div>
<div class="marginSmall font_3">6实验室诊断费<span class="writeAreaCenter"></span></div>
</div>
<div class="rowBox">
<div class="marginSmall font_3">7影像学诊断费<span class="writeAreaCenter"></span></div>
<div class="marginSmall font_3">8临床诊断项目费<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">3.医疗类:</div>
<div class="marginSmall font_3">9非手术治疗项目费<span class="writeAreaCenter"></span></div>
<div class="marginSmall font_3">(临床物理治疗费:<span class="writeAreaCenter"></span></div>
</div>
<div class="rowBox">
<div class="marginSmall font_3">10手术治疗费<span class="writeAreaCenter"></span></div>
<div class="marginSmall font_3">(麻醉费:<span class="writeAreaCenter"></span>手术费:<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">4.康复类:</div>
<div class="marginSmall font_3">11康复费<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">5.中医类:</div>
<div class="marginSmall font_3">12中医治疗费<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">6.西药类:</div>
<div class="marginSmall font_3">13西药费<span class="writeAreaCenter"></span></div>
<div class="marginSmall font_3">(抗菌药物费用:<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">7.中药类:</div>
<div class="marginSmall font_3">14中成药费<span class="writeAreaCenter"></span></div>
<div class="marginSmall font_3">15中草药费<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">8.血液和血液制品类:</div>
<div class="font_3">16血费<span class="writeAreaCenter"></span></div>
<div class="font_3">17白蛋白类制品费<span class="writeAreaCenter"></span></div>
</div>
<div class="rowBox">
<div class="font_3">18球蛋白类制品费<span class="writeAreaCenter"></span></div>
<div class="font_3">19凝血因子类制品费<span class="writeAreaCenter"></span></div>
</div>
<div class="rowBox">
<div class="font_3">20细胞因子类制品费<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">9.耗材类:</div>
<div class="font_3">21检查用一次性医用材料费<span class="writeAreaCenter"></span></div>
</div>
<div class="rowBox">
<div class="font_3">22治疗用一次性医用材料费<span class="writeAreaCenter"></span></div>
<div class="font_3">23手术用用一次性医用材料费<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">10.其他类:</div>
<div class="font_3">24其他费<span class="writeAreaCenter"></span></div>
</div>
</div>
<div class="secItem1">
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_1">说明:</div>
<div class="font_3 marginNor">(一)医疗付费方式 </div>
<div class="font_3 marginNor">1.城镇职工基本医疗保险 </div>
<div class="font_3 marginNor">2.城镇居民基本医疗保险 </div>
</div>
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_3 marginNor">3.新型农村合作医疗 </div>
<div class="font_3 marginNor">4.贫困救助 </div>
<div class="font_3 marginNor">5.商业医疗保险 </div>
</div>
<div class="rowBox" style="margin-bottom: 10px;">
<div class="font_3 marginNor">6.全公费 </div>
<div class="font_3 marginNor">7.全自费 </div>
<div class="font_3 marginNor">8.其他社会保险 </div>
<div class="font_3 marginNor">9.其他 </div>
</div>
</div>
<div class="subTable">
<div class="tableBarHeader font_1">其他诊断及手术附加页</div>
<div class="tableBar">
<div class="font_1 barItem1">出院诊断</div>
<div class="font_1 barItem2">疾病编码</div>
<div class="font_1 barItem2">入院病情</div>
<div class="font_1 barItem2 borderR">转归情况</div>
</div>
<div class="tableBar">
<div class="font_3 barItem1"></div>
<div class="font_3 barItem2"></div>
<div class="font_3 barItem2"></div>
<div class="font_3 barItem2 borderR"></div>
</div>
<div class="tableBar borderB">
<div class="font_3 barItem1"></div>
<div class="font_3 barItem2"></div>
<div class="font_3 barItem2"></div>
<div class="font_3 barItem2 borderR"></div>
</div>
</div>
<div class="secItem1" style="padding: 0;">
<div class="rowBox" style="margin: 10px 0 5px;">
<div class="font_2 marginR_S">入院病情:</div>
<div class="font_2 marginR_S">1.有 </div>
<div class="font_2 marginR_S">2.临床未确定</div>
<div class="font_2 marginR_S">3.情况不明</div>
<div class="font_2 marginR_B">4.无 </div>
</div>
<div class="rowBox" style="margin: 10px 0 5px;">
<div class="font_2 marginR_S">转归:</div>
<div class="font_2 marginR_S">1.治愈 </div>
<div class="font_2 marginR_S">2.好转</div>
<div class="font_2 marginR_S">3.未愈</div>
<div class="font_2 marginR_S">4.死亡</div>
<div class="font_2 marginR_S">5.其他</div>
</div>
</div>
<div class="tableBox">
<div class="tableBoxInner">
<div class="tableBoxItemHeader font_4">
<div class="item itemDate">手术操作日期</div>
<div class="item itemSurgeryLevel">手术级别</div>
<div class="item itemSurgeryName">手术及操作名称</div>
<div class="itemSpec">
<div class="spec" style="width: 100%;border-bottom: 1px solid #333333;">手术及操作医师</div>
<div class="spec">
<div class="specItem">术者</div>
<div class="specItem" style="border-left: 1px solid #333333;">Ⅰ助</div>
<div class="specItem" style="border-left: 1px solid #333333;">Ⅱ助</div>
</div>
</div>
<div class="item itemCutLevel">切口愈合等级</div>
<div class="item itemCutLevel1">麻醉方式</div>
<div class="item itemCutLevel">麻醉医师</div>
<div class="item itemCutLevel2">麻醉分级</div>
<div class="item itemTime borderRight">手术时长(H)</div>
</div>
<div class="tableBoxItem font_4">
<div class="item itemDate">2023-11-6</div>
<div class="item itemSurgeryLevel">5</div>
<div class="item itemSurgeryName">腰椎间盘切除,椎管减压,植骨融合内固定术</div>
<div class="itemSpec">
<div class="spec_">
<div class="specItem">
牛粪
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
渣渣辉
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
长存
</div>
</div>
</div>
<div class="item itemCutLevel">1/甲</div>
<div class="item itemCutLevel1">静吸复合麻醉</div>
<div class="item itemCutLevel">马本慧</div>
<div class="item itemCutLevel2">2</div>
<div class="item itemTime borderRight">2.35</div>
</div>
<div class="tableBoxItem font_4">
<div class="item itemDate">2023-11-6</div>
<div class="item itemSurgeryLevel">1</div>
<div class="item itemSurgeryName">PICC管去除</div>
<div class="itemSpec">
<div class="spec_">
<div class="specItem">
牛粪
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
渣渣辉
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
长存
</div>
</div>
</div>
<div class="item itemCutLevel">1/甲</div>
<div class="item itemCutLevel1">静吸复合麻醉</div>
<div class="item itemCutLevel">马本慧</div>
<div class="item itemCutLevel2">2</div>
<div class="item itemTime borderRight">2.35</div>
</div>
<div class="tableBoxItem font_4">
<div class="item itemDate">2023-11-6</div>
<div class="item itemSurgeryLevel">1</div>
<div class="item itemSurgeryName">经外周静脉穿刺中心静脉置管技术</div>
<div class="itemSpec">
<div class="spec_">
<div class="specItem">
王丽丽
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
</div>
</div>
<div class="item itemCutLevel">1/甲</div>
<div class="item itemCutLevel1">静吸复合麻醉</div>
<div class="item itemCutLevel">马本慧</div>
<div class="item itemCutLevel2">2</div>
<div class="item itemTime borderRight">2.35</div>
</div>
<div class="tableBoxItem font_4">
<div class="item itemDate"></div>
<div class="item itemSurgeryLevel"></div>
<div class="item itemSurgeryName"></div>
<div class="itemSpec">
<div class="spec_">
<div class="specItem">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
</div>
</div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel1"></div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel2"></div>
<div class="item itemTime borderRight"></div>
</div>
<div class="tableBoxItem font_4">
<div class="item itemDate"></div>
<div class="item itemSurgeryLevel"></div>
<div class="item itemSurgeryName"></div>
<div class="itemSpec">
<div class="spec_">
<div class="specItem">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
</div>
</div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel1"></div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel2"></div>
<div class="item itemTime borderRight"></div>
</div>
<div class="tableBoxItem font_4">
<div class="item itemDate"></div>
<div class="item itemSurgeryLevel"></div>
<div class="item itemSurgeryName"></div>
<div class="itemSpec">
<div class="spec_">
<div class="specItem">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
</div>
</div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel1"></div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel2"></div>
<div class="item itemTime borderRight"></div>
</div>
<div class="tableBoxItem font_4">
<div class="item itemDate"></div>
<div class="item itemSurgeryLevel"></div>
<div class="item itemSurgeryName"></div>
<div class="itemSpec">
<div class="spec_">
<div class="specItem">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
</div>
</div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel1"></div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel2"></div>
<div class="item itemTime borderRight"></div>
</div>
<div class="tableBoxItem font_4">
<div class="item itemDate"></div>
<div class="item itemSurgeryLevel"></div>
<div class="item itemSurgeryName"></div>
<div class="itemSpec">
<div class="spec_">
<div class="specItem">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
</div>
</div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel1"></div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel2"></div>
<div class="item itemTime borderRight"></div>
</div>
<div class="tableBoxItem font_4 borderBottom">
<div class="item itemDate"></div>
<div class="item itemSurgeryLevel"></div>
<div class="item itemSurgeryName"></div>
<div class="itemSpec">
<div class="spec_">
<div class="specItem">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
<div class="specItem" style="border-left: 1px solid #333333;">
</div>
</div>
</div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel1"></div>
<div class="item itemCutLevel"></div>
<div class="item itemCutLevel2"></div>
<div class="item itemTime borderRight"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -25,7 +25,6 @@
<script setup >
import { ref, inject } from 'vue';
import { FormInstance } from 'element-plus';
// const form = inject('formState') as any;
// const formRef = ref<FormInstance>();
@@ -49,7 +48,6 @@ const handleUpload = () => {
border-radius: 4px;
padding-left: 16px;
:deep(.el-form) {
display: flex;
align-items: center;
@@ -83,9 +81,6 @@ const handleUpload = () => {
.operate-btns {
.main-btn {
// margin-left: 16px;
// width: 100px;
&:first-child {
margin-left: 0;
}

View File

@@ -462,7 +462,7 @@ onMounted(() => {
.el-button{
border: 1px #166773 solid;
span{
span {
color: red;
margin-left: 5px;
}
@@ -471,7 +471,7 @@ onMounted(() => {
.el-button:hover{
border: 1px #166773 solid;
color: #166773;
span{
span {
color: red;
margin-left: 5px;
}

View File

@@ -1,8 +1,4 @@
/*
* @Author: sjjh
* @Date: 2025-09-07 12:09:26
* @Description:
*/
import request from '@/utils/request'
// 申请单相关接口
@@ -48,6 +44,46 @@ export function getSurgery(queryParams) {
}
/**
* 查询护理医嘱信息
*/
export function getNursingOrdersInfos() {
return request({
url: '/reg-doctorstation/special-advice/nursing-orders',
method: 'get'
})
}
/**
* 保存护理医嘱信息
* @param {Object} data - 护理医嘱数据
* @param {number} data.encounterId - 就诊id
* @param {number} data.patientId - 患者id
* @param {number} data.conditionId - 诊断ID
* @param {number} data.encounterDiagnosisId - 就诊诊断id
* @param {string} data.startTime - 医嘱开始时间 (yyyy-MM-dd HH:mm:ss)
* @param {Array} data.nursingOrdersSaveDetailDtoList - 护理医嘱详情保存集合
* @param {number} data.nursingOrdersSaveDetailDtoList[].definitionId - 护理项目定义ID
* @param {number} data.nursingOrdersSaveDetailDtoList[].categoryEnum - 护理项目类别编码:
* 26(护理级别)、38(病情)、39(护理常规)、27(膳食)、40(体位)、41(陪护)、42(隔离等级)
*/
export function saveNursingOrders(data) {
return request({
url: '/reg-doctorstation/special-advice/nursing-orders',
method: 'post',
data: data
})
}
/**
* 获取患者护理状态信息(用于回显)
*/
export function getEncounterNursingOrders(params) {
return request({
url: '/reg-doctorstation/special-advice/encounter-nursing-orders',
method: 'get',
params: params
})
}

Some files were not shown because too many files have changed in this diff Show More