fix:问题修复

This commit is contained in:
huxuejian 2026-08-07 11:11:58 +08:00
parent 0c902ce825
commit f0ace56fad
6 changed files with 174 additions and 122 deletions

View File

@ -3,18 +3,15 @@
<my-layout>
<layout-main>
<div v-if="data" ref="paperRef" class="prescription-container rx-print-area">
<div class="header">
<div class="row">
<div class="company"></div>
<div class="prescription-type">
<div>普通</div>
<div>处方</div>
</div>
</div>
<div class="header pt-2 relative">
<div class="hospital">海宁康华医院互联网医院 <br />处方笺</div>
<div class="sub-header">
<span class="no">NO:{{ no }}</span>
</div>
<div class="absolute top-0 right-2 prescription-type">
<div>普通</div>
<div>处方</div>
</div>
</div>
<div class="patient-info">
<div class="info-row">
@ -86,7 +83,7 @@
调配
</div>
<div class="flex-shrink-0 w-1/3">
复核发药
复核
</div>
<div class="flex-shrink-0 w-1/3">
发药
@ -98,11 +95,25 @@
</layout-main>
<layout-item v-if="showPrint">
<div class="text-center py-12px bg-white" common-shadow--r>
<el-button type="primary" class="w-100px" @click="print">打印</el-button>
<el-button type="primary" class="w-100px" @click="openPrintDialog">打印</el-button>
</div>
</layout-item>
</my-layout>
</el-drawer>
<el-dialog v-model="printDialogVisible" title="选择打印纸张尺寸" width="360px" append-to-body :close-on-click-modal="false">
<div class="text-center py-3">
<el-radio-group v-model="printPaperSize">
<el-radio label="A4">A4</el-radio>
<el-radio label="A5">A5</el-radio>
</el-radio-group>
</div>
<template #footer>
<div class="text-center">
<el-button class="w-100px" @click="printDialogVisible = false">取消</el-button>
<el-button class="w-100px" type="primary" :loading="printing" @click="confirmPrint">确定并打印</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { computed, nextTick, ref, watch } from 'vue';
@ -128,6 +139,9 @@ const props = defineProps({
}
})
const paperRef = ref(null)
const printDialogVisible = ref(false)
const printPaperSize = ref('A4')
const printing = ref(false)
const doctorCode = ref('')
const pharmacistNo = ref('')
const diagnosis = computed(() => props.data && Array.isArray(props.data.diagnosisList) ? props.data.diagnosisList : [])
@ -174,17 +188,49 @@ function waitForPrintImages(root) {
return Promise.race([loaded, new Promise((resolve) => setTimeout(resolve, 3000))]);
}
async function print() {
function openPrintDialog() {
printPaperSize.value = 'A4';
printDialogVisible.value = true;
}
async function confirmPrint() {
if (printing.value) return;
printing.value = true;
printDialogVisible.value = false;
try {
await nextTick();
await print(printPaperSize.value);
} finally {
printing.value = false;
}
}
function createPrintPageStyle(paperSize) {
const size = paperSize === 'A5' ? 'A5' : 'A4';
const style = document.createElement('style');
style.textContent = `@media print { @page { size: ${size} portrait; margin: 8mm; } }`;
document.head.appendChild(style);
return style;
}
async function print(paperSize = 'A4') {
if (!paperRef.value) return;
await nextTick();
// Element Plus
// body 使
const size = paperSize === 'A5' ? 'A5' : 'A4';
const useDenseLayout = drugList.value.length >= (size === 'A5' ? 4 : 5);
const printRoot = document.createElement('div');
printRoot.className = 'rx-print-root';
printRoot.className = [
'rx-print-root',
`rx-print-root--${size.toLowerCase()}`,
useDenseLayout ? 'rx-print-root--dense' : ''
].filter(Boolean).join(' ');
printRoot.setAttribute('aria-hidden', 'true');
printRoot.appendChild(paperRef.value.cloneNode(true));
document.body.appendChild(printRoot);
const pageStyle = createPrintPageStyle(paperSize);
try {
await waitForPrintImages(printRoot);
@ -195,11 +241,12 @@ async function print() {
emits('printed');
} finally {
document.body.classList.remove('printing-rx');
pageStyle.remove();
printRoot.remove();
}
}
defineExpose({ print });
defineExpose({ print: openPrintDialog });
</script>
<style lang="scss" scoped>
@ -241,7 +288,7 @@ defineExpose({ print });
}
.prescription-type {
font-size: 14px;
font-size: 12px;
color: #666;
border: 1px solid #333;
width: 40px;
@ -252,7 +299,6 @@ defineExpose({ print });
font-size: 16px;
font-weight: bold;
text-align: center;
margin: 8px 0;
}
.sub-header {
@ -376,7 +422,7 @@ defineExpose({ print });
@media print {
@page {
size: A5 portrait;
size: A4 portrait;
margin: 8mm;
}
@ -395,6 +441,94 @@ defineExpose({ print });
box-sizing: border-box !important;
padding: 0 !important;
box-shadow: none !important;
font-size: 12px !important;
line-height: 1.25 !important;
}
body.printing-rx>.rx-print-root .header {
padding-bottom: 4px !important;
margin-bottom: 5px !important;
}
body.printing-rx>.rx-print-root .row {
margin-bottom: 2px !important;
}
body.printing-rx>.rx-print-root .hospital {
margin: 3px 0 !important;
font-size: 14px !important;
}
body.printing-rx>.rx-print-root .patient-info,
body.printing-rx>.rx-print-root .diagnosis-section,
body.printing-rx>.rx-print-root .medicine-section {
margin-top: 5px !important;
}
body.printing-rx>.rx-print-root .info-row {
padding: 2px !important;
}
body.printing-rx>.rx-print-root .diagnosis-header {
padding: 0 2px !important;
}
body.printing-rx>.rx-print-root .rp-symbol {
font-size: 17px !important;
}
body.printing-rx>.rx-print-root .medicine-item {
margin-bottom: 6px !important;
}
body.printing-rx>.rx-print-root .medicine-spec {
margin: 1px 0 !important;
}
body.printing-rx>.rx-print-root .medicine-section img {
width: 86px !important;
height: 86px !important;
margin-top: 2px !important;
}
body.printing-rx>.rx-print-root .footer {
margin-top: 6px !important;
}
body.printing-rx>.rx-print-root .footer .pt-3 {
padding-top: 4px !important;
}
body.printing-rx>.rx-print-root .signImage {
width: 76px !important;
height: 30px !important;
}
body.printing-rx>.rx-print-root .notice {
margin-top: 5px !important;
font-size: 10px !important;
}
body.printing-rx>.rx-print-root--a5 .rx-print-area,
body.printing-rx>.rx-print-root--dense .rx-print-area {
font-size: 11px !important;
line-height: 1.2 !important;
}
body.printing-rx>.rx-print-root--a5 .medicine-item,
body.printing-rx>.rx-print-root--dense .medicine-item {
margin-bottom: 4px !important;
}
body.printing-rx>.rx-print-root--a5 .medicine-section img,
body.printing-rx>.rx-print-root--dense .medicine-section img {
width: 72px !important;
height: 72px !important;
}
body.printing-rx>.rx-print-root--a5.rx-print-root--dense .rx-print-area {
font-size: 10px !important;
line-height: 1.15 !important;
}
body.printing-rx>.rx-print-root .medicine-item,

View File

@ -3,7 +3,8 @@
style="--el-drawer-padding-primary: 0" @close="close">
<my-layout>
<layout-main>
<el-form :label-width="140" label-suffix="" class="p-15px pr-30px" :class="loading ? 'pointer-events-none' : ''">
<el-form :label-width="140" label-suffix="" class="p-15px pr-30px"
:class="loading ? 'pointer-events-none' : ''">
<div active-title-bar class="my-2.5">药品基本信息</div>
<el-row>
<el-col :span="12" v-for="item in basicInfoList" :key="item.prop">
@ -13,15 +14,6 @@
</el-form-item>
</el-col>
</el-row>
<div active-title-bar class="my-2.5">适应诊断</div>
<el-row>
<el-col :span="24">
<el-form-item class="mb-5px" label="适应诊断">
<span v-if="diagnosisLoading">加载中...</span>
<span v-else>{{ diagnosisText || '-' }}</span>
</el-form-item>
</el-col>
</el-row>
<div active-title-bar class="my-2.5">药品标准用法用量</div>
<el-row>
<el-col :span="12" v-for="item in usageInfo" :key="item.prop">
@ -32,25 +24,11 @@
</el-col>
</el-row>
<div active-title-bar class="my-2.5">药品规则配置</div>
<el-row v-if="libType === 'online'">
<el-col :span="12" v-for="item in otherInfo" :key="item.prop">
<el-form-item class="mb-5px" :label="item.label" :prop="item.prop"
:class="requiredMap[item.prop] ? 'is-required' : ''">
{{ form[item.prop] }}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item class="mb-5px" label="是否上传用药证明">
{{ form.need_medication_proof }}
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item class="mb-5px" label="是否限制使用范围">
{{ form.has_usage_restriction }}
<el-form-item class="mb-5px" label="适应诊断">
<span v-if="diagnosisLoading">加载中...</span>
<span v-else>{{ diagnosisText || '-' }}</span>
</el-form-item>
</el-col>
</el-row>

View File

@ -31,7 +31,7 @@
</el-form-item>
</el-col>
</el-row>
<div active-title-bar class="mb-2.5">适应诊断</div>
<div active-title-bar class="mb-2.5">药品规则配置</div>
<el-row>
<el-col :span="24">
<el-form-item label="适应诊断" prop="applicableDiagnosisIds">

View File

@ -37,7 +37,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="岗位" prop="position">
<el-form-item class="is-required" label="岗位" prop="position">
<el-select clearable :model-value="form.job" placeholder="请选择" class="w-full"
@update:model-value="change($event, 'job')">
<el-option v-for="item in jobList" :key="item.value" :label="item.label" :value="item.value" />
@ -161,7 +161,7 @@ const rules = computed(() => ({
const deptCode = typeof val === 'string' ? val.trim() : (Array.isArray(val) ? val[0] || '' : '');
return verifyListItem(deptCode, depts.value.map(item => item.value), false, '科室')
},
job: val => verifyListItem(val, jobList.map(item => item.value), false, '岗位'),
job: val => verifyListItem(val, jobList.map(item => item.value), true, '岗位'),
doctorNo: val => {
if (/\W/.test(val)) {
return [false, '院内工号只能包含字母、数字和下划线'];

View File

@ -13,7 +13,7 @@
:avatar="memberInfo.avatar" :sex="sex" />
<template #dropdown>
<el-dropdown-menu>
<template v-if="showCAMenu">
<!-- <template v-if="showCAMenu">
<el-dropdown-item @click="getAuthCode">
<div class="text-14px py-4px">
<span class="-ml-3px">产生激活码</span>
@ -29,7 +29,12 @@
<span class="-ml-3px">关闭时效签</span>
</div>
</el-dropdown-item>
</template>
</template> -->
<el-dropdown-item @click="showModifyDialog = true">
<div class="text-14px py-4px">
<span class="-ml-3px">修改密码</span>
</div>
</el-dropdown-item>
<el-dropdown-item @click="logout">
<div class="text-14px py-4px">
<span class="-ml-3px">退出登录</span>
@ -71,45 +76,8 @@
</div>
</div>
</div>
<teams-modal :team-id="currentTeam ? currentTeam.teamId : ''" :teams="showTeams" :visible="teamVisible"
@close="teamVisible = false" />
<el-dialog v-model="visible" title="机构超级管理员" :width="width" :close-on-click-modal="false" @close="close()">
<el-scrollbar wrap-class="el-dialog-body-full-scroll">
<div color-normal class="pt-10px px-10px pb-20px text-14px bg-slate-100">
<div class="leading-24px font-semibold">
超级管理员为机构自己的管理员可以帮助使用本平台的机构员工开通账户数据维护管理培训支持等等服务如您在工作中需要管理员协助的可点击下方联系管理员
<div class="my-5px">机构超级管理员处理事项:</div>
</div>
<div class="leading-24px">1账户开通:包括员工基础信息维护平台账户开通功能权限管理</div>
<div class="leading-24px">2团队信息管理:团队组建管理包括团队名称团队介绍团队成员团队服务二维码的配置</div>
<div class="leading-24px">3基础信息数据维护:包括文章问卷常用语客户来源客户标签机构项目常用诊断档案模版字段配置</div>
<div class="leading-24px">4客户数据管理:包括平台内客户数据的上限数管理客户档案的删除客户档案与团队的授权客户档案与微信账号的解绑</div>
</div>
<div v-loading="loading" class="p-10px">
<div color-normal class="text-16px leading-28px font-semibold">本机构超级管理员</div>
<div v-for="i in admins" :key="i.userid" class="mt-15px flex items-center">
<div class="rounded-full w-24px h-24px justify-center flex items-center bg-zinc-600 text-white">
<el-icon :size="16">
<Avatar />
</el-icon>
</div>
<div color-normal class="min-w-80px mx-10px truncate flex-shrink-0 text-16px">
<span v-if="i.anotherName">{{ i.anotherName }}</span>
<ww-user v-else :openid="i.userid"></ww-user>
</div>
<el-button v-if="memberInfo.userid !== i.userid" type="primary" size="small" @click="contact(i.userid)">联系
</el-button>
</div>
</div>
</el-scrollbar>
<template #footer>
<div text-center>
<el-button class="w-100px" @click="close">关闭</el-button>
</div>
</template>
</el-dialog>
<open-auto-sign :visible="isQrCodeDialogVisible" :qrCodeText="qrCodeText" :title="qrViewTitle"
:subTitle="qrViewSubTitle" @close="closeQr"></open-auto-sign>
<modify-password-dialog :showModifyDialog="showModifyDialog" :username="loginUsername"
@close="showModifyDialog = false" />
</template>
<script setup>
import { computed, ref } from "vue";
@ -124,15 +92,14 @@ import { openChatWindow } from "@/utils/common";
import { useRouter } from "vue-router";
import UserAvatar from "@/components/user-avatar";
import SvgIcon from "@/components/svg-icon";
import TeamsModal from "./components/teams-modal.vue";
import { configStore } from "@/store/config";
import { tagsStore } from "@/store/tags";
import { ElMessageBox, ElMessage } from "element-plus";
import { useImStore } from "@/store/im";
import { doctorHasPendingOrder } from "@/api/hlw";
import openAutoSign from "@/components/ca-sign/open-auto-sign.vue";
import { caStore } from "@/components/ca-sign/store";
import ModifyPasswordDialog from "@/components/modify-password-dialog/modify-password-dialog.vue";
const logoPic = new URL("@/assets/logo.png", import.meta.url).href; // logo
const qrCodeText = ref("");
@ -149,7 +116,9 @@ const { memberInfo, customLogo, corpInfo } = storeToRefs(memberS);
const teamVisible = ref(false);
const teamName = ref("");
const isQrCodeDialogVisible = ref(false);
const showModifyDialog = ref(false);
const qrViewSubTitle = ref("");
const loginUsername = computed(() => memberInfo.value.mobile || memberInfo.value.username || sessionStorage.getItem("loginUsername") || "");
const showCAMenu = computed(() => {
return (memberInfo.value.doctorNo || memberInfo.value.workNo) && import.meta.env.VITE_NEED_CA === "true"
})

View File

@ -24,15 +24,8 @@
:loading="loading">立即登录</el-button>
</el-form>
<div class="mt-6 flex justify-end text-sm">
<span class="cursor-pointer text-gray-600 hover:text-blue-500 transition-colors"
@click.prevent="editPassword">修改密码</span>
</div>
</div>
<ModifyPasswordDialog :showModifyDialog="showModifyDialog" @close="closeModifyDialog"
:username="loginForm.username" />
</div>
</template>
<script setup>
import { ref, reactive, onUnmounted } from "vue";
@ -47,7 +40,6 @@ import { templateStore } from "@/store/template";
import { teamStore as useTeamStore } from "@/store/team";
import { configStore } from "@/store/config";
import { useRouter } from "vue-router";
import ModifyPasswordDialog from "@/components/modify-password-dialog/modify-password-dialog.vue";
import CaptchaVerifyDialog from "@/components/captcha-verify-dialog/index.vue";
import { useImStore } from "@/store/im";
import { caStore } from "@/components/ca-sign/store";
@ -277,7 +269,7 @@ const handleLogin = async () => {
ElMessage.error(message);
return;
}
const { user, defaultPassword, accessToken, refreshToken } = data;
const { user, accessToken, refreshToken } = data;
const auth = authStore();
await auth.setAccessToken(accessToken);
await auth.setRefreshToken(refreshToken);
@ -285,6 +277,7 @@ const handleLogin = async () => {
sessionStorage.setItem("corpId", import.meta.env.VITE_CORP_ID);
sessionStorage.setItem("isLogin", true);
sessionStorage.setItem("loginId", user.loginId);
sessionStorage.setItem("loginUsername", username);
const res = await loginSuccess(user);
if (!res) {
return;
@ -293,23 +286,7 @@ const handleLogin = async () => {
ElMessage.success("登录成功");
return;
}
// loading.value = false;
if (message === "密码未设置") {
ElMessageBox.confirm("您的密码为初始密码,请修改密码", "提示", {
confirmButtonText: "修改密码",
type: "warning",
}).then(() => {
showModifyDialog.value = true;
});
} else {
ElMessage.error(message);
}
};
//
function editPassword() {
showModifyDialog.value = true;
}
//
async function loginSuccess(user) {
const { userid, roleIds } = user;
@ -430,12 +407,6 @@ async function performFingerprintMatch(fingerA, fingerB) {
}
}
//
const showModifyDialog = ref(false);
function closeModifyDialog() {
showModifyDialog.value = false;
}
</script>
<style lang="scss">