Merge remote-tracking branch 'origin/develop' into develop
# Conflicts: # openhis-ui-vue3/src/views/doctorstation/components/diagnosis/addDiagnosisDialog.vue # openhis-ui-vue3/src/views/doctorstation/components/tcm/tcmAdvice.vue
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { bodyTemperature, TOP_KEYS, HEAD_HEIGHT, LINE_HEIGHT } from './config'
|
||||
import { bodyTemperature, TOP_KEYS, HEAD_HEIGHT, LINE_HEIGHT } from './config';
|
||||
|
||||
export default class viewConfig {
|
||||
constructor({
|
||||
@@ -12,47 +12,44 @@ export default class viewConfig {
|
||||
strokeWidth = 2, // stroke width of line and dots
|
||||
strokeLinecap = 'round', // stroke line cap of line
|
||||
strokeLinejoin = 'round', // stroke line join of line
|
||||
renderData
|
||||
renderData,
|
||||
} = {}) {
|
||||
// 基础配置赋值
|
||||
this.width = width
|
||||
this.height = height
|
||||
this.stroke = stroke
|
||||
this.strokeWidth = strokeWidth
|
||||
this.strokeLinecap = strokeLinecap
|
||||
this.renderData = renderData
|
||||
this.strokeLinejoin = strokeLinejoin
|
||||
this.marginRight = marginRight
|
||||
this.marginLeft = marginLeft
|
||||
this.marginBottom = marginBottom
|
||||
this.marginTop = marginTop
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.stroke = stroke;
|
||||
this.strokeWidth = strokeWidth;
|
||||
this.strokeLinecap = strokeLinecap;
|
||||
this.renderData = renderData;
|
||||
this.strokeLinejoin = strokeLinejoin;
|
||||
this.marginRight = marginRight;
|
||||
this.marginLeft = marginLeft;
|
||||
this.marginBottom = marginBottom;
|
||||
this.marginTop = marginTop;
|
||||
// 计算属性赋值
|
||||
this.contentWidth = width - marginLeft - marginRight
|
||||
this.step = this.contentWidth / 8
|
||||
this.bottomPos = height - HEAD_HEIGHT - marginTop - (marginBottom - 30) // 底部坐标,30是因为默认的30,忘记计算了,后续的按照30的偏移量计算
|
||||
this.tableHeight = height - marginBottom - HEAD_HEIGHT
|
||||
const { micoStep, verticalHeight } = this.utilsGetMicoPos(
|
||||
this.step,
|
||||
this.bottomPos
|
||||
)
|
||||
this.micoStep = micoStep
|
||||
this.verticalHeight = verticalHeight
|
||||
this.X_OFFSET = micoStep / 2 // 为了让图标在小格子居中展示,需要进行一个偏移
|
||||
this.xRange = [this.step, width - marginLeft - marginRight] // [60, 860]
|
||||
this.topPos = marginTop + HEAD_HEIGHT
|
||||
this.topKeysPos = LINE_HEIGHT * (TOP_KEYS.length + 1) // 1 是时间那一行
|
||||
this.bottomKeysPosStart = this.topKeysPos + verticalHeight + 20
|
||||
this.yRange = [this.bottomKeysPosStart - 20, this.topKeysPos]
|
||||
this.contentWidth = width - marginLeft - marginRight;
|
||||
this.step = this.contentWidth / 8;
|
||||
this.bottomPos = height - HEAD_HEIGHT - marginTop - (marginBottom - 30); // 底部坐标,30是因为默认的30,忘记计算了,后续的按照30的偏移量计算
|
||||
this.tableHeight = height - marginBottom - HEAD_HEIGHT;
|
||||
const { micoStep, verticalHeight } = this.utilsGetMicoPos(this.step, this.bottomPos);
|
||||
this.micoStep = micoStep;
|
||||
this.verticalHeight = verticalHeight;
|
||||
this.X_OFFSET = micoStep / 2; // 为了让图标在小格子居中展示,需要进行一个偏移
|
||||
this.xRange = [this.step, width - marginLeft - marginRight]; // [60, 860]
|
||||
this.topPos = marginTop + HEAD_HEIGHT;
|
||||
this.topKeysPos = LINE_HEIGHT * (TOP_KEYS.length + 1); // 1 是时间那一行
|
||||
this.bottomKeysPosStart = this.topKeysPos + verticalHeight + 20;
|
||||
this.yRange = [this.bottomKeysPosStart - 20, this.topKeysPos];
|
||||
}
|
||||
|
||||
// 获取折线区域的高度
|
||||
utilsGetMicoPos(step, botpos) {
|
||||
const micoStep = (step * 7) / 42 // 折线小格子的宽度
|
||||
const verticalLength = bodyTemperature[1] - bodyTemperature[0] // 根据体温来计算格子
|
||||
const verticalHeight = micoStep * 5 * verticalLength
|
||||
const micoStep = (step * 7) / 42; // 折线小格子的宽度
|
||||
const verticalLength = bodyTemperature[1] - bodyTemperature[0]; // 根据体温来计算格子
|
||||
const verticalHeight = micoStep * 5 * verticalLength;
|
||||
return {
|
||||
micoStep,
|
||||
verticalHeight
|
||||
}
|
||||
verticalHeight,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,271 +1,215 @@
|
||||
import dayjs from 'dayjs'
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
HospitalName,
|
||||
temperatureName,
|
||||
showPainFlag,
|
||||
getInfoKeys,
|
||||
getBottomKeys
|
||||
} from './template'
|
||||
getBottomKeys,
|
||||
} from './template';
|
||||
|
||||
// 存放体温单的配置信息
|
||||
export const Header = {
|
||||
HospitalName,
|
||||
temperatureName
|
||||
}
|
||||
temperatureName,
|
||||
};
|
||||
// 患者信息
|
||||
export const INFO_KEYS = getInfoKeys()
|
||||
export const INFO_KEYS = getInfoKeys();
|
||||
// 头部信息标签
|
||||
export const TOP_KEYS = [
|
||||
//{
|
||||
// name: '患病日数',
|
||||
// getValue: (i, renderData) => {
|
||||
// const { beginDate, hospDays, outdate = '', dateClosed } = renderData.infoData
|
||||
// const tieml = new Date()
|
||||
// const timeNew = new Date((tieml / 1000 + 86400) * 1000)
|
||||
// const todayDate = dayjs(timeNew).format('YYYY-MM-DD')
|
||||
// const endDate = dayjs(outdate).add(1, 'day').format('YYYY-MM-DD')
|
||||
// const eachTime = dayjs(beginDate)
|
||||
// .add(i, 'day')
|
||||
// .format('YYYY-MM-DD')
|
||||
// if (eachTime === endDate || todayDate === eachTime) {
|
||||
// dateClosed.stopNumber = true
|
||||
// }
|
||||
// return dateClosed.stopNumber ? hospDays + i + 1 : ''
|
||||
// }
|
||||
//},
|
||||
{
|
||||
name: '日 期',
|
||||
getValue: (i, renderData) => {
|
||||
const { beginDate, outdate = '', hospDate = '', dateClosed } = renderData.infoData
|
||||
const tieml = new Date()
|
||||
const timeNew = new Date((tieml / 1000 + 86400) * 1000)
|
||||
const todayDate = dayjs(timeNew).format('YYYY-MM-DD')
|
||||
const endDate = dayjs(outdate).format('YYYY-MM-DD')
|
||||
const startDate = dayjs(hospDate).format('YYYY-MM-DD')
|
||||
let eachTime = dayjs(beginDate).add(i, 'day').format('YYYY-MM-DD')
|
||||
const { beginDate, outdate = '', hospDate = '', dateClosed } = renderData.infoData;
|
||||
const tieml = new Date();
|
||||
const timeNew = new Date((tieml / 1000 + 86400) * 1000);
|
||||
const todayDate = dayjs(timeNew).format('YYYY-MM-DD');
|
||||
const endDate = dayjs(outdate).format('YYYY-MM-DD');
|
||||
const startDate = dayjs(hospDate).format('YYYY-MM-DD');
|
||||
let eachTime = dayjs(beginDate).add(i, 'day').format('YYYY-MM-DD');
|
||||
if (eachTime === endDate || eachTime === todayDate) {
|
||||
dateClosed.stopTime = true
|
||||
dateClosed.stopTime = true;
|
||||
}
|
||||
if ((startDate === eachTime && i === 0) || dayjs(eachTime).format('MM-DD') === '01-01') {
|
||||
eachTime = dayjs(eachTime).format('YYYY年MM月DD日')
|
||||
eachTime = dayjs(eachTime).format('YYYY年MM月DD日');
|
||||
} else if (i === 0 || dayjs(eachTime).format('DD') === '01') {
|
||||
eachTime = dayjs(eachTime).format('MM月DD日')
|
||||
eachTime = dayjs(eachTime).format('MM月DD日');
|
||||
} else {
|
||||
eachTime = dayjs(eachTime).format('DD日')
|
||||
eachTime = dayjs(eachTime).format('DD日');
|
||||
}
|
||||
return dateClosed.stopTime ? eachTime : ''
|
||||
}
|
||||
return dateClosed.stopTime ? eachTime : '';
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '住院日数',
|
||||
getValue: (i, renderData) => {
|
||||
const { beginDate, hospDays, outdate = '', dateClosed } = renderData.infoData
|
||||
const tieml = new Date()
|
||||
const timeNew = new Date((tieml / 1000 + 86400) * 1000)
|
||||
const todayDate = dayjs(timeNew).format('YYYY-MM-DD')
|
||||
const endDate = dayjs(outdate).add(1, 'day').format('YYYY-MM-DD')
|
||||
const eachTime = dayjs(beginDate).add(i, 'day').format('YYYY-MM-DD')
|
||||
const { beginDate, hospDays, outdate = '', dateClosed } = renderData.infoData;
|
||||
const tieml = new Date();
|
||||
const timeNew = new Date((tieml / 1000 + 86400) * 1000);
|
||||
const todayDate = dayjs(timeNew).format('YYYY-MM-DD');
|
||||
const endDate = dayjs(outdate).add(1, 'day').format('YYYY-MM-DD');
|
||||
const eachTime = dayjs(beginDate).add(i, 'day').format('YYYY-MM-DD');
|
||||
if (eachTime === endDate || todayDate === eachTime) {
|
||||
dateClosed.stopNumber = false
|
||||
dateClosed.stopNumber = false;
|
||||
}
|
||||
const num = dateClosed.stopNumber ? hospDays + i + 1 : ''
|
||||
let hosNum = ''
|
||||
const num = dateClosed.stopNumber ? hospDays + i + 1 : '';
|
||||
let hosNum = '';
|
||||
if (num !== '') {
|
||||
hosNum = '第' + "\xa0\xa0\xa0" + num + "\xa0\xa0\xa0" + '日'
|
||||
hosNum = '第' + '\xa0\xa0\xa0' + num + '\xa0\xa0\xa0' + '日';
|
||||
} else {
|
||||
hosNum = '第' + "\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0" + '日'
|
||||
hosNum = '第' + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' + '日';
|
||||
}
|
||||
return hosNum
|
||||
}
|
||||
return hosNum;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '术/娩后日数',
|
||||
getValue: (i, renderData) => {
|
||||
const { beginDate } = renderData.infoData
|
||||
const surgeryNumDays = renderData.surgeryNumDays
|
||||
const eachTime = dayjs(beginDate).add(i, 'day').format('YYYY-MM-DD')
|
||||
let num = surgeryNumDays.filter(item => item.date === eachTime)
|
||||
let hosNum = ''
|
||||
const { beginDate } = renderData.infoData;
|
||||
const surgeryNumDays = renderData.surgeryNumDays;
|
||||
const eachTime = dayjs(beginDate).add(i, 'day').format('YYYY-MM-DD');
|
||||
let num = surgeryNumDays.filter((item) => item.date === eachTime);
|
||||
let hosNum = '';
|
||||
if (num.length > 0) {
|
||||
hosNum = '第' + "\xa0\xa0\xa0" + num[0].typeValue + "\xa0\xa0\xa0" + '日'
|
||||
hosNum = '第' + '\xa0\xa0\xa0' + num[0].typeValue + '\xa0\xa0\xa0' + '日';
|
||||
} else {
|
||||
hosNum = '第' + "\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0" + '日'
|
||||
hosNum = '第' + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' + '日';
|
||||
}
|
||||
return hosNum
|
||||
}
|
||||
}
|
||||
]
|
||||
return hosNum;
|
||||
},
|
||||
},
|
||||
];
|
||||
// 最底部的字段绘制
|
||||
export const BOTTOM_KEYS = getBottomKeys()
|
||||
export const BOTTOM_KEYS = getBottomKeys();
|
||||
// 是否显示疼痛评分
|
||||
export const showPain = showPainFlag
|
||||
export const showPain = showPainFlag;
|
||||
|
||||
/** *********** 以下是固定选项 **************************/
|
||||
export const timeNumber = [2, 6, 10, 14, 18, 22] // 时间展示
|
||||
export const nightTime = [2, 18, 22] // 夜间红色高亮时间
|
||||
//export const leftTEXT1 = [
|
||||
// // ['脉3搏,(次/分), 180', '160', '140', '120', '100', '80', '60', '40'],
|
||||
// // ['体4温,(℃), 42', '41', '40', '39', '38', '37', '36', '35']
|
||||
// // ['华氏,( °F), 107.6', '105.8', '104', '102.2', '100.4', '98.6', '96.8', '95']
|
||||
// ['华氏,( °F), ', '', '107', '106', '105', '104', '103', '102', '101', '100', '99', '98', '97', '96', '95', '94']
|
||||
// // ['摄氏,(℃), 42', '41', '40', '39', '38', '37', '36', '35']
|
||||
//]
|
||||
//export const leftTEXT2 = [
|
||||
// ['摄氏,(℃), ', '42', '41', '40', '39', '38', '37', '36', '35']
|
||||
//]
|
||||
//export const rightTEXT = [
|
||||
// [',, ', '180', '160', '140', '120', '100', '80', '60', '40']
|
||||
//]
|
||||
//export const painTEXT = [
|
||||
// ['疼 痛'],
|
||||
// ['8', '6', '4', '2']
|
||||
//]
|
||||
export const timeNumber = [2, 6, 10, 14, 18, 22]; // 时间展示
|
||||
export const nightTime = [2, 18, 22]; // 夜间红色高亮时间
|
||||
export const leftTEXT = [
|
||||
['脉搏,(次/分),', '180', '160', '140', '120', '100', '80', '60', '40'],
|
||||
['体温,(℃), ', '42', '41', '40', '39', '38', '37', '36', '35']
|
||||
]
|
||||
export const painTEXT = [['疼 痛 强 度'], ['10', '8', '6', '4', '2', '0']]
|
||||
export const inOutItem = ['入观', '分娩', '手术', '转入', '出观', '死亡']
|
||||
export const otherItem = ['外出', '请假', '拒测', '离院', '其他']
|
||||
['体温,(℃), ', '42', '41', '40', '39', '38', '37', '36', '35'],
|
||||
];
|
||||
export const painTEXT = [['疼 痛 强 度'], ['10', '8', '6', '4', '2', '0']];
|
||||
export const inOutItem = ['入观', '分娩', '手术', '转入', '出观', '死亡'];
|
||||
export const otherItem = ['外出', '请假', '拒测', '离院', '其他'];
|
||||
export const sheetOptions = {
|
||||
locations: [{
|
||||
code: '1',
|
||||
display: '体温'
|
||||
}, {
|
||||
code: '2',
|
||||
display: '口温'
|
||||
}, {
|
||||
code: '3',
|
||||
display: '肛温'
|
||||
}, {
|
||||
code: '4',
|
||||
display: '耳温'
|
||||
}],
|
||||
breath: [{
|
||||
code: '',
|
||||
display: '自主呼吸'
|
||||
}, {
|
||||
code: '®',
|
||||
display: '机械通气'
|
||||
}],
|
||||
poop: [{
|
||||
code: '',
|
||||
display: '正常'
|
||||
}, {
|
||||
code: '※',
|
||||
display: '失禁'
|
||||
}, {
|
||||
code: '☆',
|
||||
display: '人工肛门'
|
||||
}, {
|
||||
code: '/E',
|
||||
display: '灌肠'
|
||||
}],
|
||||
pee: [{
|
||||
code: '',
|
||||
display: '正常'
|
||||
}, {
|
||||
code: '※',
|
||||
display: '失禁'
|
||||
}, {
|
||||
code: 'C+',
|
||||
display: '导尿'
|
||||
}],
|
||||
locations: [
|
||||
{
|
||||
code: '1',
|
||||
display: '体温',
|
||||
},
|
||||
{
|
||||
code: '2',
|
||||
display: '口温',
|
||||
},
|
||||
{
|
||||
code: '3',
|
||||
display: '肛温',
|
||||
},
|
||||
{
|
||||
code: '4',
|
||||
display: '耳温',
|
||||
},
|
||||
],
|
||||
breath: [
|
||||
{
|
||||
code: '',
|
||||
display: '自主呼吸',
|
||||
},
|
||||
{
|
||||
code: '®',
|
||||
display: '机械通气',
|
||||
},
|
||||
],
|
||||
poop: [
|
||||
{
|
||||
code: '',
|
||||
display: '正常',
|
||||
},
|
||||
{
|
||||
code: '※',
|
||||
display: '失禁',
|
||||
},
|
||||
{
|
||||
code: '☆',
|
||||
display: '人工肛门',
|
||||
},
|
||||
{
|
||||
code: '/E',
|
||||
display: '灌肠',
|
||||
},
|
||||
],
|
||||
pee: [
|
||||
{
|
||||
code: '',
|
||||
display: '正常',
|
||||
},
|
||||
{
|
||||
code: '※',
|
||||
display: '失禁',
|
||||
},
|
||||
{
|
||||
code: 'C+',
|
||||
display: '导尿',
|
||||
},
|
||||
],
|
||||
heart: ['窦性心律', '起搏心律', '房性心律', '异常心律'],
|
||||
weight: ['正常', '卧床', '轮椅', '平车']
|
||||
}
|
||||
weight: ['正常', '卧床', '轮椅', '平车'],
|
||||
};
|
||||
// 此处是显示数字的 要和leftTEXT保持一直
|
||||
// export const bodyTemperature1 = [94, 107]
|
||||
// export const starNumEnv1 = bodyTemperature1[0] // 开始体温
|
||||
// export const endNumEnv1 = bodyTemperature1[1] // 结束体温
|
||||
export const bodyTemperature = [33, 43]
|
||||
export const starNumEnv = bodyTemperature[0] // 开始体温
|
||||
export const endNumEnv = bodyTemperature[1] // 结束体温
|
||||
export const heartRange = [0, 200]
|
||||
export const painScore = [0, 10]
|
||||
export const bodyTemperature = [33, 43];
|
||||
export const starNumEnv = bodyTemperature[0]; // 开始体温
|
||||
export const endNumEnv = bodyTemperature[1]; // 结束体温
|
||||
export const heartRange = [0, 200];
|
||||
export const painScore = [0, 10];
|
||||
|
||||
// 中间图表字段对应
|
||||
export const CHART_KEYS = [
|
||||
{
|
||||
key: '001',
|
||||
code: 'breath',
|
||||
name: '呼吸'
|
||||
name: '呼吸',
|
||||
},
|
||||
{
|
||||
key: '002',
|
||||
code: 'sphygmus',
|
||||
name: '脉搏'
|
||||
name: '脉搏',
|
||||
},
|
||||
{
|
||||
key: '003',
|
||||
code: 'temperature',
|
||||
name: '体温'
|
||||
name: '体温',
|
||||
},
|
||||
{
|
||||
key: '012',
|
||||
code: 'inOut',
|
||||
name: '特殊标记'
|
||||
name: '特殊标记',
|
||||
},
|
||||
{
|
||||
key: '013',
|
||||
code: 'refuse',
|
||||
name: '标记内容'
|
||||
name: '标记内容',
|
||||
},
|
||||
{
|
||||
key: '014',
|
||||
code: 'heartRate',
|
||||
name: '心率'
|
||||
name: '心率',
|
||||
},
|
||||
{
|
||||
key: '015',
|
||||
code: 'lowerTemp',
|
||||
name: '物理降温'
|
||||
name: '物理降温',
|
||||
},
|
||||
{
|
||||
key: '016',
|
||||
code: 'painScore',
|
||||
name: '疼痛评分'
|
||||
}
|
||||
// {
|
||||
// key: '017',
|
||||
// code: 'admission',
|
||||
// name: '入院'
|
||||
// },
|
||||
// {
|
||||
// key: '018',
|
||||
// code: 'bigSurgery',
|
||||
// name: '大手术'
|
||||
// },
|
||||
// {
|
||||
// key: '019',
|
||||
// code: 'smallSurgery',
|
||||
// name: '小手术'
|
||||
// },
|
||||
// {
|
||||
// key: '020',
|
||||
// code: 'discharge',
|
||||
// name: '出院'
|
||||
// },
|
||||
// {
|
||||
// key: '021',
|
||||
// code: 'parturition',
|
||||
// name: '分娩'
|
||||
// },
|
||||
// {
|
||||
// key: '022',
|
||||
// code: 'transfer',
|
||||
// name: '转科'
|
||||
// },
|
||||
// {
|
||||
// key: '9507',
|
||||
// code: 'death',
|
||||
// name: '死亡'
|
||||
// }
|
||||
]
|
||||
|
||||
export const HEAD_HEIGHT = 80 // 头部文字预留位置
|
||||
export const LINE_HEIGHT = 20 // 一行的行高
|
||||
export const textLeftMargin = 4 // 文字左边边距
|
||||
export const TEXT_MARGIN_BOTTOM = 6 // 文字向上偏移量
|
||||
export const symbolArrowHeight = 20
|
||||
name: '疼痛评分',
|
||||
},
|
||||
];
|
||||
|
||||
export const HEAD_HEIGHT = 120; // 头部文字预留位置
|
||||
export const LINE_HEIGHT = 20; // 一行的行高
|
||||
export const textLeftMargin = 4; // 文字左边边距
|
||||
export const TEXT_MARGIN_BOTTOM = 6; // 文字向上偏移量
|
||||
export const symbolArrowHeight = 20;
|
||||
|
||||
@@ -4,42 +4,32 @@
|
||||
// index: 0
|
||||
// value: 36
|
||||
// }
|
||||
export function getMaxList({
|
||||
list = [],
|
||||
max = 0,
|
||||
min = 0,
|
||||
maxDefault = 0,
|
||||
minDefault = 0
|
||||
} = {}) {
|
||||
return list.map(item => {
|
||||
if (((item.value > max) || (item.value < min)) && item.value !== null) {
|
||||
const ismax = item.value > max
|
||||
export function getMaxList({ list = [], max = 0, min = 0, maxDefault = 0, minDefault = 0 } = {}) {
|
||||
return list.map((item) => {
|
||||
if ((item.value > max || item.value < min) && item.value !== null) {
|
||||
const ismax = item.value > max;
|
||||
return {
|
||||
...item,
|
||||
value: ismax ? maxDefault : minDefault,
|
||||
sourceValue: item.value,
|
||||
ismax: ismax,
|
||||
max,
|
||||
min
|
||||
}
|
||||
min,
|
||||
};
|
||||
} else {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
export function levelingData({
|
||||
list = [],
|
||||
maxDefault = 0,
|
||||
minDefault = 0
|
||||
}) {
|
||||
return list.map(item => {
|
||||
if (item.value === null) return item
|
||||
export function levelingData({ list = [], maxDefault = 0, minDefault = 0 }) {
|
||||
return list.map((item) => {
|
||||
if (item.value === null) return item;
|
||||
if (item.value > maxDefault) {
|
||||
item.value = maxDefault
|
||||
item.value = maxDefault;
|
||||
} else if (item.value < minDefault) {
|
||||
item.value = minDefault
|
||||
item.value = minDefault;
|
||||
}
|
||||
return item
|
||||
})
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
// 数据处理
|
||||
import * as d3 from 'd3'
|
||||
import { symbol } from 'd3-shape'
|
||||
import * as d3 from 'd3';
|
||||
import { symbol } from 'd3-shape';
|
||||
import {
|
||||
getTypeData,
|
||||
getTypeDatas,
|
||||
@@ -13,12 +13,19 @@ import {
|
||||
getType,
|
||||
getHeartRate,
|
||||
disconnectEvents,
|
||||
getBrokenLine
|
||||
} from './utils'
|
||||
import { HEAD_HEIGHT, LINE_HEIGHT, TOP_KEYS, BOTTOM_KEYS, symbolArrowHeight, textLeftMargin} from './config'
|
||||
getBrokenLine,
|
||||
} from './utils';
|
||||
import {
|
||||
HEAD_HEIGHT,
|
||||
LINE_HEIGHT,
|
||||
TOP_KEYS,
|
||||
BOTTOM_KEYS,
|
||||
symbolArrowHeight,
|
||||
textLeftMargin,
|
||||
} from './config';
|
||||
export const iconDrawObj = {
|
||||
// 绘制圆形图标
|
||||
getDrawRoundIcon: ({ content,data, x, y, fill = 'blue',stroke = 'blue', r = 5 }) => {
|
||||
getDrawRoundIcon: ({ content, data, x, y, fill = 'blue', stroke = 'blue', r = 5 }) => {
|
||||
// 增加icon 红色空心
|
||||
content
|
||||
.append('g')
|
||||
@@ -29,23 +36,32 @@ export const iconDrawObj = {
|
||||
.data(data)
|
||||
.join('circle')
|
||||
.attr('transform', (i) => {
|
||||
const yVal = y(i) || 0
|
||||
const yVal = y(i) || 0;
|
||||
if (!yVal) {
|
||||
return 'scale(0)'
|
||||
return 'scale(0)';
|
||||
}
|
||||
return ''
|
||||
return '';
|
||||
})
|
||||
.attr('cx', x)
|
||||
.attr('cy', y)
|
||||
.attr('r', (i) => {
|
||||
if (y(i)) {
|
||||
return r
|
||||
return r;
|
||||
}
|
||||
return 0
|
||||
})
|
||||
return 0;
|
||||
});
|
||||
},
|
||||
// 绘制圆形点图标
|
||||
getDrawRoundDotIcon: ({ content, data, x, y, fill = 'white', stroke = 'blue', deepFill = 'blue', r = 6 }) => {
|
||||
getDrawRoundDotIcon: ({
|
||||
content,
|
||||
data,
|
||||
x,
|
||||
y,
|
||||
fill = 'white',
|
||||
stroke = 'blue',
|
||||
deepFill = 'blue',
|
||||
r = 6,
|
||||
}) => {
|
||||
content
|
||||
.append('g')
|
||||
.attr('fill', fill)
|
||||
@@ -55,11 +71,11 @@ export const iconDrawObj = {
|
||||
.data(data)
|
||||
.join('circle')
|
||||
.attr('transform', (i) => {
|
||||
const yVal = y(i) || 0
|
||||
const yVal = y(i) || 0;
|
||||
if (!yVal) {
|
||||
return 'scale(0)'
|
||||
return 'scale(0)';
|
||||
}
|
||||
return ''
|
||||
return '';
|
||||
})
|
||||
.attr('cx', x)
|
||||
.attr('cy', y)
|
||||
@@ -68,7 +84,7 @@ export const iconDrawObj = {
|
||||
.attr('cx', x)
|
||||
.attr('cy', y)
|
||||
.attr('r', 1)
|
||||
.attr('fill', deepFill)
|
||||
.attr('fill', deepFill);
|
||||
},
|
||||
// 绘制x
|
||||
getDrawXIcon: ({ content, data, x, y, fill = 'blue', stroke = 'blue' }) => {
|
||||
@@ -81,43 +97,43 @@ export const iconDrawObj = {
|
||||
.data(data)
|
||||
.join('line')
|
||||
.attr('transform', (i) => {
|
||||
let yVal = y
|
||||
let yVal = y;
|
||||
if (typeof y === 'function') {
|
||||
yVal = y(i) || 0
|
||||
yVal = y(i) || 0;
|
||||
}
|
||||
if (!yVal) {
|
||||
return 'scale(0)'
|
||||
return 'scale(0)';
|
||||
}
|
||||
return ''
|
||||
return '';
|
||||
})
|
||||
.attr('x1', function(d) {
|
||||
return x(d) - 4
|
||||
.attr('x1', function (d) {
|
||||
return x(d) - 4;
|
||||
})
|
||||
.attr('y1', function(d) {
|
||||
return y(d) - 4
|
||||
.attr('y1', function (d) {
|
||||
return y(d) - 4;
|
||||
})
|
||||
.attr('x2', function(d) {
|
||||
return x(d) + 4
|
||||
.attr('x2', function (d) {
|
||||
return x(d) + 4;
|
||||
})
|
||||
.attr('y2', function(d) {
|
||||
return y(d) + 4
|
||||
.attr('y2', function (d) {
|
||||
return y(d) + 4;
|
||||
})
|
||||
.clone()
|
||||
.attr('x1', function(d) {
|
||||
return x(d) + 4
|
||||
.attr('x1', function (d) {
|
||||
return x(d) + 4;
|
||||
})
|
||||
.attr('y1', function(d) {
|
||||
return y(d) - 4
|
||||
.attr('y1', function (d) {
|
||||
return y(d) - 4;
|
||||
})
|
||||
.attr('x2', function(d) {
|
||||
return x(d) - 4
|
||||
})
|
||||
.attr('y2', function(d) {
|
||||
return y(d) + 4
|
||||
.attr('x2', function (d) {
|
||||
return x(d) - 4;
|
||||
})
|
||||
.attr('y2', function (d) {
|
||||
return y(d) + 4;
|
||||
});
|
||||
},
|
||||
// 绘制三角形
|
||||
drawThreeIcon: ({ content, data, x,y, fill = 'blue', stroke = 'blue', riangle = 48 }) => {
|
||||
drawThreeIcon: ({ content, data, x, y, fill = 'blue', stroke = 'blue', riangle = 48 }) => {
|
||||
// 蓝色三角形
|
||||
content
|
||||
.append('g')
|
||||
@@ -126,74 +142,82 @@ export const iconDrawObj = {
|
||||
.data(data)
|
||||
.join('g')
|
||||
.attr('transform', (i) => {
|
||||
const yVal = y(i) || 0
|
||||
const yVal = y(i) || 0;
|
||||
if (!yVal) {
|
||||
return 'scale(0)'
|
||||
return 'scale(0)';
|
||||
}
|
||||
return `translate(${x(i)},${yVal})`
|
||||
return `translate(${x(i)},${yVal})`;
|
||||
})
|
||||
.append('path')
|
||||
.call((path) => {
|
||||
const symbolThree = symbol()
|
||||
const symbolIndex = 5
|
||||
symbolThree.type(d3.symbols[symbolIndex])
|
||||
path.attr('d', symbolThree.size(riangle)).attr('fill', fill) .attr('stroke', stroke)
|
||||
const symbolThree = symbol();
|
||||
const symbolIndex = 5;
|
||||
symbolThree.type(d3.symbols[symbolIndex]);
|
||||
path.attr('d', symbolThree.size(riangle)).attr('fill', fill).attr('stroke', stroke);
|
||||
// .transition()
|
||||
// .duration(1500)
|
||||
// .attr('d', symbolThree.size(48))
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export function getG(svg, viewConfig) {
|
||||
return svg .append('g') .attr( 'transform', `translate(${viewConfig.marginLeft},${viewConfig.marginTop + HEAD_HEIGHT})` )
|
||||
return svg
|
||||
.append('g')
|
||||
.attr('transform', `translate(${viewConfig.marginLeft},${viewConfig.marginTop + HEAD_HEIGHT})`);
|
||||
}
|
||||
|
||||
// 设置数据
|
||||
export function getData(allData) {
|
||||
const rowsData = allData.rows // allData, '【全部数据】'
|
||||
const infoData = allData.grParamBOS
|
||||
const typesData = getTypeDatas(allData.types, allData.grParamBOS.beginDate)
|
||||
const selectOp = allData.selectOp
|
||||
const symbolTextArr = getTypeData('018', rowsData, false, allData.grParamBOS.beginDate) // 【特殊标记】
|
||||
const symbolGoUp = getType('003', rowsData, allData.grParamBOS.beginDate) // 不升
|
||||
const rowsData = allData.rows; // allData, '【全部数据】'
|
||||
const infoData = allData.grParamBOS;
|
||||
const typesData = getTypeDatas(allData.types, allData.grParamBOS.beginDate);
|
||||
const selectOp = allData.selectOp;
|
||||
const symbolTextArr = getTypeData('018', rowsData, false, allData.grParamBOS.beginDate); // 【特殊标记】
|
||||
const symbolGoUp = getType('003', rowsData, allData.grParamBOS.beginDate); // 不升
|
||||
// 体温单特殊数据
|
||||
const dicData = JSON.parse(window.localStorage.getItem('transDictCode'))
|
||||
const signsManagementList = dicData ? dicData.filter(item => item.name === '95')[0].concept.sort((a, b) => { return a.displayOrder - b.displayOrder }) :[]
|
||||
const otherArr = []
|
||||
const dicData = JSON.parse(window.localStorage.getItem('transDictCode'));
|
||||
const signsManagementList = dicData
|
||||
? dicData
|
||||
.filter((item) => item.name === '95')[0]
|
||||
.concept.sort((a, b) => {
|
||||
return a.displayOrder - b.displayOrder;
|
||||
})
|
||||
: [];
|
||||
const otherArr = [];
|
||||
if (signsManagementList.length > 0) {
|
||||
for (let j = 0; j < signsManagementList.length; j++) {
|
||||
if (signsManagementList[j].code !== '9502' & signsManagementList[j].code !== '9503') {
|
||||
const otherArrItem = getTypeData(signsManagementList[j].code, rowsData, false, allData.grParamBOS.beginDate)
|
||||
otherArr.push(otherArrItem)
|
||||
if ((signsManagementList[j].code !== '9502') & (signsManagementList[j].code !== '9503')) {
|
||||
const otherArrItem = getTypeData(
|
||||
signsManagementList[j].code,
|
||||
rowsData,
|
||||
false,
|
||||
allData.grParamBOS.beginDate
|
||||
);
|
||||
otherArr.push(otherArrItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
const surgeryNumDays = allData.types.filter(item => item.typeCode === '031')
|
||||
const surgeryArr = getTypeData('9502', rowsData, false, allData.grParamBOS.beginDate) // '【手术】'
|
||||
const minSurgeryArr = getTypeData('9503', rowsData, false, allData.grParamBOS.beginDate) // '【小手术】'
|
||||
const temArr = getTypeData('00301', rowsData, false, allData.grParamBOS.beginDate) // '【体温拒测等】'
|
||||
// const symbolGoUp = getType('003', rowsData, allData.grParamBOS.beginDate) // symbolGoUp, '不升'
|
||||
const surgeryNumDays = allData.types.filter((item) => item.typeCode === '031');
|
||||
const surgeryArr = getTypeData('9502', rowsData, false, allData.grParamBOS.beginDate); // '【手术】'
|
||||
const minSurgeryArr = getTypeData('9503', rowsData, false, allData.grParamBOS.beginDate); // '【小手术】'
|
||||
const temArr = getTypeData('00301', rowsData, false, allData.grParamBOS.beginDate); // '【体温拒测等】'
|
||||
// const symbolGoUp = getType('003', rowsData, allData.grParamBOS.beginDate) // symbolGoUp, '不升'
|
||||
// 35度线上的内容
|
||||
const symbolDegreesEvents = degreesOnline(symbolTextArr, selectOp, 0)
|
||||
const symbolDegreesOnline = disconnectEvents( symbolTextArr, selectOp, 'isBeforeAfter', 0 )
|
||||
const symbolDegreesEvents = degreesOnline(symbolTextArr, selectOp, 0);
|
||||
const symbolDegreesOnline = disconnectEvents(symbolTextArr, selectOp, 'isBeforeAfter', 0);
|
||||
// 40~42线上的内容
|
||||
const symbolTopOnline = degreesOnline(symbolTextArr, selectOp, 1)
|
||||
const symbolTopDegreesOnline = disconnectEvents(
|
||||
symbolTextArr,
|
||||
selectOp,
|
||||
'isBeforeAfter',
|
||||
1
|
||||
)
|
||||
const symbolContent = getTypeData('013', rowsData, false, allData.grParamBOS.beginDate) // symbolContent, '【标记内容】'
|
||||
const mergeTag = setMergeTag(symbolTopOnline, symbolContent) // mergeTag, '【合并标记,标记内容】'
|
||||
const symbolTopOnline = degreesOnline(symbolTextArr, selectOp, 1);
|
||||
const symbolTopDegreesOnline = disconnectEvents(symbolTextArr, selectOp, 'isBeforeAfter', 1);
|
||||
const symbolContent = getTypeData('013', rowsData, false, allData.grParamBOS.beginDate); // symbolContent, '【标记内容】'
|
||||
const mergeTag = setMergeTag(symbolTopOnline, symbolContent); // mergeTag, '【合并标记,标记内容】'
|
||||
// 产后日数
|
||||
infoData.postpartum = postpartumDays('031', typesData) // infoData, '产后日数'
|
||||
infoData.postpartum = postpartumDays('031', typesData); // infoData, '产后日数'
|
||||
// 写死的先
|
||||
infoData.dateClosed = {
|
||||
stopTime: true, // 控制结束日期
|
||||
stopNumber: true // 控制住院天数
|
||||
}
|
||||
stopNumber: true, // 控制住院天数
|
||||
};
|
||||
// 折线
|
||||
const brokenLineData = getBrokenLine(
|
||||
'003',
|
||||
@@ -202,22 +226,23 @@ export function getData(allData) {
|
||||
symbolGoUp,
|
||||
symbolTopDegreesOnline,
|
||||
allData.grParamBOS.beginDate
|
||||
)
|
||||
);
|
||||
// 模拟数据 体温
|
||||
const datasetAnus = getTypeAnimalHeat('003', rowsData, '1', allData.grParamBOS.beginDate) // datasetAnus, '腋温【x】'
|
||||
const bodyData = getTypeAnimalHeat('003', rowsData, '2', allData.grParamBOS.beginDate) // dbodyData, '口温'
|
||||
const datasetAnus = getTypeAnimalHeat('003', rowsData, '1', allData.grParamBOS.beginDate); // datasetAnus, '腋温【x】'
|
||||
const bodyData = getTypeAnimalHeat('003', rowsData, '2', allData.grParamBOS.beginDate); // dbodyData, '口温'
|
||||
// const datasetHeartrate = getTypeAnimalHeat('003', rowsData)
|
||||
const datasetHeartrate = getTypeAnimalHeat('003', rowsData, '3', allData.grParamBOS.beginDate) // datasetHeartrate, '肛温【红空圆】'
|
||||
const earCool = getTypeAnimalHeat('003', rowsData, '4', allData.grParamBOS.beginDate) // earCool, '耳朵温'
|
||||
const painScore = getHeartRate( // painScore, '疼痛'
|
||||
const datasetHeartrate = getTypeAnimalHeat('003', rowsData, '3', allData.grParamBOS.beginDate); // datasetHeartrate, '肛温【红空圆】'
|
||||
const earCool = getTypeAnimalHeat('003', rowsData, '4', allData.grParamBOS.beginDate); // earCool, '耳朵温'
|
||||
const painScore = getHeartRate(
|
||||
// painScore, '疼痛'
|
||||
'016',
|
||||
rowsData,
|
||||
symbolDegreesOnline,
|
||||
symbolTopDegreesOnline,
|
||||
true,
|
||||
allData.grParamBOS.beginDate
|
||||
)
|
||||
const allTemperatureData = [bodyData, datasetAnus, datasetHeartrate, earCool] // 所有的温度记录
|
||||
);
|
||||
const allTemperatureData = [bodyData, datasetAnus, datasetHeartrate, earCool]; // 所有的温度记录
|
||||
// '脉搏【红实圆】'
|
||||
const datasetPulse = getHeartRate(
|
||||
'002',
|
||||
@@ -226,7 +251,7 @@ export function getData(allData) {
|
||||
symbolTopDegreesOnline,
|
||||
true,
|
||||
allData.grParamBOS.beginDate
|
||||
)
|
||||
);
|
||||
// 心率【空心】
|
||||
const datasetHeartRate = getHeartRate(
|
||||
'014',
|
||||
@@ -235,14 +260,14 @@ export function getData(allData) {
|
||||
symbolTopDegreesOnline,
|
||||
true,
|
||||
allData.grParamBOS.beginDate
|
||||
)
|
||||
);
|
||||
// const allTemperatureData = getDrawData('003', rowsData, '1', allData.grParamBOS.beginDate) // datasetAnus, '腋温【x】'
|
||||
// const dataCool = getDrawCoolData('015', rowsData, true, allData.grParamBOS.beginDate) // dataCool, '【物理降温】'
|
||||
const dataCool = getTypeData('015', rowsData, true, allData.grParamBOS.beginDate) // 【物理降温】
|
||||
const dataCool = getTypeData('015', rowsData, true, allData.grParamBOS.beginDate); // 【物理降温】
|
||||
// 呼吸【黑实圆】
|
||||
const datasetPain = getTypeData('001', rowsData, false, allData.grParamBOS.beginDate)// 呼吸
|
||||
const datasetPain = getTypeData('001', rowsData, false, allData.grParamBOS.beginDate); // 呼吸
|
||||
|
||||
const title = infoData.title
|
||||
const title = infoData.title;
|
||||
return {
|
||||
title,
|
||||
datasetHeartRate,
|
||||
@@ -269,8 +294,8 @@ export function getData(allData) {
|
||||
temArr,
|
||||
surgeryArr,
|
||||
minSurgeryArr,
|
||||
surgeryNumDays
|
||||
}
|
||||
surgeryNumDays,
|
||||
};
|
||||
}
|
||||
|
||||
export function drawTopMask(svg, viewConfig) {
|
||||
@@ -289,19 +314,17 @@ export function drawTopMask(svg, viewConfig) {
|
||||
.attr('height', LINE_HEIGHT * (TOP_KEYS.length + 7.5) - 1)
|
||||
.attr('stroke', viewConfig.stroke)
|
||||
.attr('fill', '#fff')
|
||||
.attr('style', 'stroke-width: 0')
|
||||
.attr('style', 'stroke-width: 0');
|
||||
|
||||
drawTopVerticalLine(svg, viewConfig)
|
||||
drawTopVerticalLine(svg, viewConfig);
|
||||
}
|
||||
|
||||
export function drawTopVerticalLine(svg, viewConfig) {
|
||||
// 补上下竖线
|
||||
let start = viewConfig.step
|
||||
const lineG = getG(svg, viewConfig)
|
||||
.append('g')
|
||||
.attr('class', 'maskline-top')
|
||||
let start = viewConfig.step;
|
||||
const lineG = getG(svg, viewConfig).append('g').attr('class', 'maskline-top');
|
||||
while (start < viewConfig.contentWidth) {
|
||||
// const isLastLine = (start + viewConfig.step) >= viewConfig.contentWidth
|
||||
// const isLastLine = (start + viewConfig.step) >= viewConfig.contentWidth
|
||||
lineG
|
||||
.append('line')
|
||||
.attr('fill', 'stroke')
|
||||
@@ -311,13 +334,13 @@ export function drawTopVerticalLine(svg, viewConfig) {
|
||||
.attr('x2', start)
|
||||
.attr('stroke', start > viewConfig.step ? '#B22222' : viewConfig.stroke)
|
||||
// .attr('stroke', isLastLine ? 'black' : (start > viewConfig.step ? '#B22222' : viewConfig.stroke))
|
||||
.attr('stroke-width', 4) // 设置线条宽度为2
|
||||
start = start + viewConfig.step
|
||||
.attr('stroke-width', 4); // 设置线条宽度为2
|
||||
start = start + viewConfig.step;
|
||||
}
|
||||
}
|
||||
|
||||
export function drawBottomMask(svg, viewConfig) {
|
||||
const g = getG(svg, viewConfig)
|
||||
const g = getG(svg, viewConfig);
|
||||
// 遮罩层挡住超出的折线
|
||||
g.append('rect')
|
||||
.attr('class', 'mask-rect')
|
||||
@@ -327,18 +350,16 @@ export function drawBottomMask(svg, viewConfig) {
|
||||
.attr('height', LINE_HEIGHT * (BOTTOM_KEYS.length + 5))
|
||||
.attr('stroke', viewConfig.stroke)
|
||||
.attr('fill', '#ffffff')
|
||||
.attr('style', 'stroke-width: 0')
|
||||
drawBottomMaskLine(svg, viewConfig)
|
||||
.attr('style', 'stroke-width: 0');
|
||||
drawBottomMaskLine(svg, viewConfig);
|
||||
}
|
||||
|
||||
function drawBottomMaskLine(svg, viewConfig) {
|
||||
// 补上下竖线
|
||||
let start = viewConfig.step
|
||||
const lineG = getG(svg, viewConfig)
|
||||
.append('g')
|
||||
.attr('class', 'maskline')
|
||||
let start = viewConfig.step;
|
||||
const lineG = getG(svg, viewConfig).append('g').attr('class', 'maskline');
|
||||
while (start < viewConfig.contentWidth) {
|
||||
// const isLastLine = (start + viewConfig.step) >= viewConfig.contentWidth;
|
||||
// const isLastLine = (start + viewConfig.step) >= viewConfig.contentWidth;
|
||||
lineG
|
||||
.append('line')
|
||||
.attr('fill', 'stroke')
|
||||
@@ -348,14 +369,14 @@ function drawBottomMaskLine(svg, viewConfig) {
|
||||
.attr('x2', start)
|
||||
.attr('stroke', start > viewConfig.step ? '#B22222' : viewConfig.stroke)
|
||||
//.attr('stroke', isLastLine ? 'black' : (start > viewConfig.step ? '#B22222' : viewConfig.stroke))
|
||||
.attr('stroke-width', 4) // 设置线条宽度为2
|
||||
start = start + viewConfig.step
|
||||
.attr('stroke-width', 4); // 设置线条宽度为2
|
||||
start = start + viewConfig.step;
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制特殊事件文字 --- 有时间
|
||||
export function drawSpecialText(svg, viewConfig, textData) {
|
||||
const g = getG(svg, viewConfig)
|
||||
const g = getG(svg, viewConfig);
|
||||
g.append('g')
|
||||
.selectAll('text')
|
||||
.data(textData)
|
||||
@@ -363,43 +384,46 @@ export function drawSpecialText(svg, viewConfig, textData) {
|
||||
.attr('style', 'font-size:14px; fill: red;')
|
||||
.attr('class', 'mytext')
|
||||
.html((d, i) => {
|
||||
const t = (d?.value || '').split(',')
|
||||
let time = ''
|
||||
const t = (d?.value || '').split(',');
|
||||
let time = '';
|
||||
if (t.length > 1) {
|
||||
time = t[0] + '于' + transNum(t[1].split(':')[0]) + '时' + transNum(t[1].split(':')[1]) + '分'
|
||||
time =
|
||||
t[0] + '于' + transNum(t[1].split(':')[0]) + '时' + transNum(t[1].split(':')[1]) + '分';
|
||||
// time = t[0] + '㇑' + transNum(t[1].split(':')[0]) + '时' + transNum(t[1].split(':')[1]) + '分'
|
||||
}
|
||||
const texts = time.split('')
|
||||
const texts = time.split('');
|
||||
return texts
|
||||
.map((text, i) => {
|
||||
return `<tspan dx="${i === 1 ? -14 : i === 0 ? 0 : Number(text) ? -8 : -14}" dy="${20}">${text}</tspan>`
|
||||
return `<tspan dx="${
|
||||
i === 1 ? -14 : i === 0 ? 0 : Number(text) ? -8 : -14
|
||||
}" dy="${20}">${text}</tspan>`;
|
||||
})
|
||||
.join('')
|
||||
.join('');
|
||||
})
|
||||
.attr('x', (d, i) => {
|
||||
return viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin
|
||||
return viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin;
|
||||
})
|
||||
.attr('y', () => {
|
||||
return viewConfig.topKeysPos - textLeftMargin
|
||||
})
|
||||
return viewConfig.topKeysPos - textLeftMargin;
|
||||
});
|
||||
}
|
||||
// 绘制特殊事件文字 --- 大手术小手术
|
||||
export function drawSurgery(svg, viewConfig, textData) {
|
||||
const g = getG(svg, viewConfig)
|
||||
const textDatas = []
|
||||
const g = getG(svg, viewConfig);
|
||||
const textDatas = [];
|
||||
if (textData.length > 0) {
|
||||
for (let j = 0; j < textData.length; j++) {
|
||||
let item = {}
|
||||
let item = {};
|
||||
if (textData[j].value) {
|
||||
item = {
|
||||
index: textData[j].index,
|
||||
value: textData[j].value.split(',')[0],
|
||||
date: textData[j].date
|
||||
}
|
||||
date: textData[j].date,
|
||||
};
|
||||
} else {
|
||||
item = textData[j]
|
||||
item = textData[j];
|
||||
}
|
||||
textDatas.push(item)
|
||||
textDatas.push(item);
|
||||
}
|
||||
}
|
||||
g.append('g')
|
||||
@@ -409,40 +433,39 @@ export function drawSurgery(svg, viewConfig, textData) {
|
||||
.attr('style', 'font-size:15px; fill: red;')
|
||||
.attr('class', 'mytext')
|
||||
.html((d, i) => {
|
||||
const texts = (d?.value || '').split('')
|
||||
const texts = (d?.value || '').split('');
|
||||
return texts
|
||||
.map((text, i) => {
|
||||
return `<tspan dx="${
|
||||
i === 1 ? -15 : i === 0 ? 0 : Number(text) ? -8 : -15
|
||||
}" dy="${20}">${text}</tspan>`
|
||||
}" dy="${20}">${text}</tspan>`;
|
||||
})
|
||||
.join('')
|
||||
.join('');
|
||||
})
|
||||
.attr('x', (d, i) => {
|
||||
return viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin - 2;
|
||||
})
|
||||
.attr(
|
||||
'x',
|
||||
(d, i) => { return viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin - 2 }
|
||||
)
|
||||
.attr('y', () => {
|
||||
return viewConfig.topKeysPos - textLeftMargin
|
||||
})
|
||||
return viewConfig.topKeysPos - textLeftMargin;
|
||||
});
|
||||
}
|
||||
// 绘制特殊事件文字 --- 无时间
|
||||
export function drawSpecialNoTimeText(svg, viewConfig, textData) {
|
||||
const g = getG(svg, viewConfig)
|
||||
const textDatas = []
|
||||
const g = getG(svg, viewConfig);
|
||||
const textDatas = [];
|
||||
if (textData.length > 0) {
|
||||
for (let j = 0; j < textData.length; j++) {
|
||||
let item = {}
|
||||
let item = {};
|
||||
if (textData[j].value) {
|
||||
item = {
|
||||
index: textData[j].index,
|
||||
value: textData[j].value.split(',')[0],
|
||||
date: textData[j].date
|
||||
}
|
||||
date: textData[j].date,
|
||||
};
|
||||
} else {
|
||||
item = textData[j]
|
||||
item = textData[j];
|
||||
}
|
||||
textDatas.push(item)
|
||||
textDatas.push(item);
|
||||
}
|
||||
}
|
||||
g.append('g')
|
||||
@@ -452,7 +475,7 @@ export function drawSpecialNoTimeText(svg, viewConfig, textData) {
|
||||
.attr('style', 'font-size:15px; fill: red;')
|
||||
.attr('class', 'mytext')
|
||||
.html((d, i) => {
|
||||
const texts = (d?.value || '').split('')
|
||||
const texts = (d?.value || '').split('');
|
||||
// let time = ''
|
||||
// if (t.length > 1) {
|
||||
// time = t[0] + '㇑' + transNum(t[1].split(':')[0]) + '时' + transNum(t[1].split(':')[1]) + '分'
|
||||
@@ -460,39 +483,38 @@ export function drawSpecialNoTimeText(svg, viewConfig, textData) {
|
||||
// const texts = time.split('')
|
||||
return texts
|
||||
.map((text, i) => {
|
||||
return `<tspan dx="${
|
||||
i === 1 ? -15 : i === 0 ? 0 : Number(text) ? -8 : -15
|
||||
}" dy="${ i === 0 ? 20 : 80}">${text}</tspan>`
|
||||
return `<tspan dx="${i === 1 ? -15 : i === 0 ? 0 : Number(text) ? -8 : -15}" dy="${
|
||||
i === 0 ? 20 : 80
|
||||
}">${text}</tspan>`;
|
||||
})
|
||||
.join('')
|
||||
.join('');
|
||||
})
|
||||
.attr('x', (d, i) => {
|
||||
return viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin - 2;
|
||||
})
|
||||
.attr(
|
||||
'x',
|
||||
(d, i) => { return viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin - 2 }
|
||||
)
|
||||
.attr('y', () => {
|
||||
return viewConfig.topKeysPos - textLeftMargin
|
||||
})
|
||||
return viewConfig.topKeysPos - textLeftMargin;
|
||||
});
|
||||
}
|
||||
|
||||
// 数字转换成文字
|
||||
function transNum(num) {
|
||||
const arr1 = ['', '十']
|
||||
const arr2 = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
|
||||
const sw = num.split('')[0]
|
||||
const gw = num.split('')[1]
|
||||
const str1 = sw > 1 ? arr2[sw] + '十' : arr1[sw]
|
||||
let strNum = str1 + arr2[gw]
|
||||
const arr1 = ['', '十'];
|
||||
const arr2 = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
|
||||
const sw = num.split('')[0];
|
||||
const gw = num.split('')[1];
|
||||
const str1 = sw > 1 ? arr2[sw] + '十' : arr1[sw];
|
||||
let strNum = str1 + arr2[gw];
|
||||
// 若H为十点整小时,则把零去掉,若m为十分,则去掉零
|
||||
if (strNum.indexOf('十') > 0 || strNum.indexOf('零') === 1) {
|
||||
strNum = strNum.replace('零', '')
|
||||
strNum = strNum.replace('零', '');
|
||||
}
|
||||
return strNum
|
||||
return strNum;
|
||||
}
|
||||
|
||||
// 绘制标签文字
|
||||
export function drawTagText(svg, viewConfig, textData) {
|
||||
const g = getG(svg, viewConfig)
|
||||
const g = getG(svg, viewConfig);
|
||||
g.append('g')
|
||||
.selectAll('text')
|
||||
.data(textData)
|
||||
@@ -500,25 +522,24 @@ export function drawTagText(svg, viewConfig, textData) {
|
||||
.attr('style', 'font-size:14px; fill: black;')
|
||||
.attr('class', 'mytext')
|
||||
.html((d, i) => {
|
||||
const texts = (d?.value || '').split('')
|
||||
const texts = (d?.value || '').split('');
|
||||
return texts
|
||||
.map((text, i) => {
|
||||
return `<tspan dx="${i === 1 ? -14 : i === 0 ? 0 : Number(text) ? -8 : -14}" dy="${20}">${text}</tspan>`
|
||||
return `<tspan dx="${
|
||||
i === 1 ? -14 : i === 0 ? 0 : Number(text) ? -8 : -14
|
||||
}" dy="${20}">${text}</tspan>`;
|
||||
})
|
||||
.join('')
|
||||
.join('');
|
||||
})
|
||||
.attr(
|
||||
'x',
|
||||
(d, i) => viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin
|
||||
)
|
||||
.attr('x', (d, i) => viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin)
|
||||
.attr('y', () => {
|
||||
return viewConfig.topKeysPos - textLeftMargin + 198
|
||||
})
|
||||
return viewConfig.topKeysPos - textLeftMargin + 198;
|
||||
});
|
||||
}
|
||||
|
||||
// 绘制特殊事件文字底部
|
||||
export function drawBottomSpecialText(svg, viewConfig, textData) {
|
||||
const g = getG(svg, viewConfig)
|
||||
const g = getG(svg, viewConfig);
|
||||
g.append('g')
|
||||
.selectAll('text')
|
||||
.data(textData)
|
||||
@@ -526,23 +547,20 @@ export function drawBottomSpecialText(svg, viewConfig, textData) {
|
||||
.attr('style', 'font-size:14px; fill: blue;')
|
||||
.attr('class', 'mytext')
|
||||
.html((d, i) => {
|
||||
const texts = (d?.value || '').split('')
|
||||
const texts = (d?.value || '').split('');
|
||||
return texts
|
||||
.map((text, i) => {
|
||||
return `<tspan dx="${
|
||||
i === 1 ? -14 : i === 0 ? 0 : Number(text) ? -8 : -14
|
||||
}" dy="${20}">${text}</tspan>`
|
||||
}" dy="${20}">${text}</tspan>`;
|
||||
})
|
||||
.join('')
|
||||
.join('');
|
||||
})
|
||||
.attr(
|
||||
'x',
|
||||
(d, i) => viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin
|
||||
)
|
||||
.attr('x', (d, i) => viewConfig.step + d.index * viewConfig.micoStep + textLeftMargin)
|
||||
.attr('y', (d) => {
|
||||
const texts = (d?.value || '').split('')
|
||||
return viewConfig.bottomKeysPosStart - texts.length * LINE_HEIGHT - 6 - 58
|
||||
})
|
||||
const texts = (d?.value || '').split('');
|
||||
return viewConfig.bottomKeysPosStart - texts.length * LINE_HEIGHT - 6 - 58;
|
||||
});
|
||||
}
|
||||
|
||||
export function initArrow(svg) {
|
||||
@@ -556,12 +574,9 @@ export function initArrow(svg) {
|
||||
.attr('viewBox', '0 0 12 12')
|
||||
.attr('refX', '6')
|
||||
.attr('refY', '6')
|
||||
.attr('orient', 'auto')
|
||||
const arrowPath = 'M2,2 L10,6 L2,10 L6,6 L2,2'
|
||||
arrowMarkerRed
|
||||
.append('path')
|
||||
.attr('d', arrowPath)
|
||||
.attr('fill', 'red')
|
||||
.attr('orient', 'auto');
|
||||
const arrowPath = 'M2,2 L10,6 L2,10 L6,6 L2,2';
|
||||
arrowMarkerRed.append('path').attr('d', arrowPath).attr('fill', 'red');
|
||||
const arrowMarkerBlue = svg
|
||||
.append('defs')
|
||||
.append('marker')
|
||||
@@ -572,16 +587,13 @@ export function initArrow(svg) {
|
||||
.attr('viewBox', '0 0 12 12')
|
||||
.attr('refX', '6')
|
||||
.attr('refY', '6')
|
||||
.attr('orient', 'auto')
|
||||
arrowMarkerBlue
|
||||
.append('path')
|
||||
.attr('d', arrowPath)
|
||||
.attr('fill', 'blue')
|
||||
.attr('orient', 'auto');
|
||||
arrowMarkerBlue.append('path').attr('d', arrowPath).attr('fill', 'blue');
|
||||
}
|
||||
|
||||
export function lineArrow({ svg, viewConfig, scale, data } = {}) {
|
||||
const g = getG(svg, viewConfig)
|
||||
const vaildData = data.filter((item) => item)
|
||||
const g = getG(svg, viewConfig);
|
||||
const vaildData = data.filter((item) => item);
|
||||
// {
|
||||
// ...item,
|
||||
// value: ismax ? maxDefault : minDefault,
|
||||
@@ -595,96 +607,85 @@ export function lineArrow({ svg, viewConfig, scale, data } = {}) {
|
||||
.data(vaildData)
|
||||
.join('line')
|
||||
.attr('x1', (d, i) => {
|
||||
return scale(d.index) + +viewConfig.X_OFFSET
|
||||
return scale(d.index) + +viewConfig.X_OFFSET;
|
||||
})
|
||||
.attr('y1', (d, i) => {
|
||||
if (d.ismax) {
|
||||
// 顶部箭头
|
||||
return viewConfig.topKeysPos + symbolArrowHeight * 1.5
|
||||
return viewConfig.topKeysPos + symbolArrowHeight * 1.5;
|
||||
} else {
|
||||
// 底部箭头
|
||||
return viewConfig.bottomKeysPosStart - symbolArrowHeight * 1.5
|
||||
return viewConfig.bottomKeysPosStart - symbolArrowHeight * 1.5;
|
||||
}
|
||||
})
|
||||
.attr('x2', (d, i) => {
|
||||
return scale(d.index) + +viewConfig.X_OFFSET
|
||||
return scale(d.index) + +viewConfig.X_OFFSET;
|
||||
})
|
||||
.attr('y2', (d, i) => {
|
||||
if (d.ismax) {
|
||||
// 顶部箭头
|
||||
return viewConfig.topKeysPos + symbolArrowHeight / 2
|
||||
return viewConfig.topKeysPos + symbolArrowHeight / 2;
|
||||
} else {
|
||||
// 底部箭头
|
||||
return viewConfig.bottomKeysPosStart - symbolArrowHeight / 2
|
||||
return viewConfig.bottomKeysPosStart - symbolArrowHeight / 2;
|
||||
}
|
||||
})
|
||||
.attr('stroke', (d) => {
|
||||
return d.ismax ? 'red' : 'blue'
|
||||
return d.ismax ? 'red' : 'blue';
|
||||
})
|
||||
.attr('stroke-width', 2)
|
||||
.attr('marker-end', (d, i) => {
|
||||
return d.ismax ? 'url(#redArrow)' : 'url(#blueArrow)'
|
||||
})
|
||||
return d.ismax ? 'url(#redArrow)' : 'url(#blueArrow)';
|
||||
});
|
||||
g.selectAll('text')
|
||||
.data(vaildData)
|
||||
.join('text')
|
||||
.attr('class', 'desctextname')
|
||||
.html((item, i) => {
|
||||
const value = `${item.sourceValue}`.split('')
|
||||
const dotIndex = value.indexOf('.')
|
||||
const value = `${item.sourceValue}`.split('');
|
||||
const dotIndex = value.indexOf('.');
|
||||
return value
|
||||
.map((d, index) => {
|
||||
let y
|
||||
let multiple = index
|
||||
let addition = 0 // dot height
|
||||
let y;
|
||||
let multiple = index;
|
||||
let addition = 0; // dot height
|
||||
if (item.ismax) {
|
||||
if (index >= dotIndex) {
|
||||
addition = 8
|
||||
multiple = index - 1
|
||||
addition = 8;
|
||||
multiple = index - 1;
|
||||
}
|
||||
y =
|
||||
viewConfig.topKeysPos +
|
||||
symbolArrowHeight * 1.5 +
|
||||
(2 + multiple * 1.5) * viewConfig.X_OFFSET +
|
||||
addition
|
||||
addition;
|
||||
} else {
|
||||
if (index >= dotIndex) {
|
||||
addition = 9
|
||||
multiple = index - 1
|
||||
addition = 9;
|
||||
multiple = index - 1;
|
||||
}
|
||||
y =
|
||||
viewConfig.bottomKeysPosStart -
|
||||
(2 + (value.length - multiple) * 1.5) * viewConfig.X_OFFSET +
|
||||
addition
|
||||
addition;
|
||||
}
|
||||
return `
|
||||
<tspan rotate="90" x="${scale(item.index) +
|
||||
viewConfig.X_OFFSET -
|
||||
4}"
|
||||
y="${y}">${d}</tspan>`
|
||||
<tspan rotate="90" x="${scale(item.index) + viewConfig.X_OFFSET - 4}"
|
||||
y="${y}">${d}</tspan>`;
|
||||
})
|
||||
.join('')
|
||||
.join('');
|
||||
})
|
||||
.attr('x', (item, i) => {
|
||||
return scale(item.index) + viewConfig.X_OFFSET - 4
|
||||
return scale(item.index) + viewConfig.X_OFFSET - 4;
|
||||
})
|
||||
.attr('y', item => {
|
||||
.attr('y', (item) => {
|
||||
if (item.ismax) {
|
||||
return (
|
||||
viewConfig.topKeysPos + symbolArrowHeight * 1.5 + LINE_HEIGHT / 2
|
||||
)
|
||||
return viewConfig.topKeysPos + symbolArrowHeight * 1.5 + LINE_HEIGHT / 2;
|
||||
} else {
|
||||
return (
|
||||
viewConfig.bottomKeysPosStart -
|
||||
symbolArrowHeight / 2 -
|
||||
LINE_HEIGHT / 2
|
||||
)
|
||||
return viewConfig.bottomKeysPosStart - symbolArrowHeight / 2 - LINE_HEIGHT / 2;
|
||||
}
|
||||
})
|
||||
.attr('style', item => {
|
||||
return `font-size:14px;fill:${
|
||||
item.ismax ? 'red' : 'blue'
|
||||
};font-weight: bold;`
|
||||
})
|
||||
.attr('style', (item) => {
|
||||
return `font-size:14px;fill:${item.ismax ? 'red' : 'blue'};font-weight: bold;`;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
* @LastEditors: 程堡
|
||||
* @Description: 体温单
|
||||
* @FilePath: src\action\nurseStation\temperatureSheet\index.js
|
||||
*/
|
||||
import Request from '@/axios/index.js'
|
||||
const temperaturePath = 'app/temperature'
|
||||
const getTemperaturePath = 'app/temperature/by-encounter-id'
|
||||
const delTemperaturePath = 'app/temperature/retired'
|
||||
*/
|
||||
import Request from '@/axios/index.js';
|
||||
const temperaturePath = 'app/temperature';
|
||||
const getTemperaturePath = 'app/temperature/by-encounter-id';
|
||||
const delTemperaturePath = 'app/temperature/retired';
|
||||
// import data from '../temperatureSheet/datas.js';
|
||||
export const API = {
|
||||
|
||||
/**
|
||||
* @description 查询患者体温单
|
||||
* @param encounterId
|
||||
@@ -23,27 +22,24 @@ export const API = {
|
||||
method: 'get', // 提交方法get
|
||||
verification: true, // 是否统一拦截验证
|
||||
untoken: false, // 是否不带token
|
||||
params: { // 参数列表
|
||||
id
|
||||
}
|
||||
})
|
||||
params: {
|
||||
// 参数列表
|
||||
id,
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 创建体温单
|
||||
* @param encounterId
|
||||
*/
|
||||
createTemperature(encounterId,
|
||||
hisNo,
|
||||
clinicCode,
|
||||
recordTime,
|
||||
type,
|
||||
content) {
|
||||
createTemperature(encounterId, hisNo, clinicCode, recordTime, type, content) {
|
||||
return Request({
|
||||
url: temperaturePath,
|
||||
method: 'post',
|
||||
verification: true,
|
||||
untoken: false,
|
||||
data: { // 参数列表
|
||||
data: {
|
||||
// 参数列表
|
||||
encounterId,
|
||||
hisNo,
|
||||
clinicCode,
|
||||
@@ -52,28 +48,23 @@ export const API = {
|
||||
operName: sessionStorage.getItem('userName'),
|
||||
type,
|
||||
content,
|
||||
hospitalOrgId: sessionStorage.getItem('hospitalOrgId')
|
||||
}
|
||||
})
|
||||
hospitalOrgId: sessionStorage.getItem('hospitalOrgId'),
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @description 修改体温单
|
||||
* @param encounterId
|
||||
*/
|
||||
updateTemperature(encounterId,
|
||||
hisNo,
|
||||
clinicCode,
|
||||
recordTime,
|
||||
type,
|
||||
content,
|
||||
id) {
|
||||
updateTemperature(encounterId, hisNo, clinicCode, recordTime, type, content, id) {
|
||||
return Request({
|
||||
url: temperaturePath,
|
||||
method: 'put',
|
||||
verification: true,
|
||||
untoken: false,
|
||||
data: { // 参数列表
|
||||
data: {
|
||||
// 参数列表
|
||||
encounterId,
|
||||
hisNo,
|
||||
clinicCode,
|
||||
@@ -82,9 +73,9 @@ export const API = {
|
||||
operName: sessionStorage.getItem('userName'),
|
||||
type,
|
||||
content,
|
||||
id
|
||||
}
|
||||
})
|
||||
id,
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 删除记录
|
||||
@@ -96,10 +87,11 @@ export const API = {
|
||||
method: 'post',
|
||||
verification: true,
|
||||
untoken: false,
|
||||
data: { // 参数列表
|
||||
id
|
||||
}
|
||||
})
|
||||
data: {
|
||||
// 参数列表
|
||||
id,
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @description 获取患者时间线
|
||||
@@ -107,24 +99,22 @@ export const API = {
|
||||
*/
|
||||
NewSheet(patientInfo) {
|
||||
return {
|
||||
grParamBOS:
|
||||
{
|
||||
age: patientInfo.age,
|
||||
birth: 868723200000,
|
||||
cwh: patientInfo.bedName,
|
||||
cardNo: patientInfo.hisId,
|
||||
hospDate: patientInfo.firstInBedTime.substring(0, 10),
|
||||
inDate: patientInfo.firstInBedTime,
|
||||
inDiagName: patientInfo.diag,
|
||||
name: patientInfo.patientName,
|
||||
deptName: patientInfo.deptName,
|
||||
operaDays: null,
|
||||
outdate: patientInfo.checkOutWardTime,
|
||||
sex: patientInfo.gender.display
|
||||
},
|
||||
grParamBOS: {
|
||||
age: patientInfo.age,
|
||||
birth: 868723200000,
|
||||
cwh: patientInfo.bedName,
|
||||
cardNo: patientInfo.hisId,
|
||||
hospDate: patientInfo.firstInBedTime.substring(0, 10),
|
||||
inDate: patientInfo.firstInBedTime,
|
||||
inDiagName: patientInfo.diag,
|
||||
name: patientInfo.patientName,
|
||||
deptName: patientInfo.deptName,
|
||||
operaDays: null,
|
||||
outdate: patientInfo.checkOutWardTime,
|
||||
sex: patientInfo.gender.display,
|
||||
},
|
||||
rows: [],
|
||||
types: []
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
types: [],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,264 +1,296 @@
|
||||
// 医院名称
|
||||
// export const HospitalName = '中国人民解放军联勤保障部队第九六四医院'
|
||||
export const HospitalName = ''
|
||||
export const HospitalName = '';
|
||||
// 体温单名称
|
||||
export const temperatureName = '体 温 单'
|
||||
export const temperatureName = '体 温 单';
|
||||
// 患者信息显示项目(修改显示顺序及是否显示)
|
||||
export const INFO_KEYS = [
|
||||
{
|
||||
name: '姓名',
|
||||
key: 'name',
|
||||
order: 1,
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '科室',
|
||||
key: 'deptName',
|
||||
name: '性别',
|
||||
key: 'sex',
|
||||
order: 2,
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '年龄',
|
||||
key: 'age',
|
||||
order: 3,
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '病室',
|
||||
key: 'deptName',
|
||||
order: 4,
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '床号',
|
||||
key: 'cwh',
|
||||
order: 3,
|
||||
show: true
|
||||
},
|
||||
{
|
||||
name: '病人ID',
|
||||
key: 'patientId',
|
||||
order: 4,
|
||||
show: true
|
||||
},
|
||||
{
|
||||
name: '住院号',
|
||||
key: 'hosNum',
|
||||
order: 5,
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
// {
|
||||
// name: '入院日期',
|
||||
// key: 'hospDate',
|
||||
// order: 6,
|
||||
// show: true
|
||||
// }
|
||||
]
|
||||
{
|
||||
name: '病历号',
|
||||
key: 'hosNum',
|
||||
order: 6,
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '入院日期',
|
||||
key: 'hospDate',
|
||||
order: 6,
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
name: '诊断',
|
||||
key: 'inDiagName',
|
||||
order: 8,
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
// 体温单录入项目(修改显示顺序及是否显示)
|
||||
// 新增项目注意 key值、code值唯一性,不要与之前的项目重复
|
||||
export const BOTTOM_KEYS = [
|
||||
{
|
||||
name: '血\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0压',
|
||||
name: '血压(mmHg)',
|
||||
code: 'bloodPressure',
|
||||
key: '008',
|
||||
times: 2,
|
||||
order: 1,
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '大便次数',
|
||||
name: '大\u00A0便\u00A0次\u00A0数',
|
||||
code: 'poop',
|
||||
key: '005',
|
||||
order: 2,
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '体\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0重',
|
||||
code: 'weight',
|
||||
key: '009',
|
||||
order: 3,
|
||||
show: true
|
||||
},
|
||||
{
|
||||
name: '尿\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0量',
|
||||
name: '小\u00A0便\u00A0次\u00A0数',
|
||||
code: 'urine',
|
||||
key: '004',
|
||||
order: 4,
|
||||
show: true
|
||||
order: 3,
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '摄入液量',
|
||||
name: '液体总入量(ml)',
|
||||
code: 'input',
|
||||
key: '006',
|
||||
order: 5,
|
||||
show: true
|
||||
order: 4,
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '排出液量',
|
||||
name: '其\u00A0\u00A0他(ml)',
|
||||
code: 'output',
|
||||
key: '007',
|
||||
order: 6,
|
||||
show: true
|
||||
order: 5,
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '术后天数',
|
||||
code: 'output',
|
||||
key: '010',
|
||||
name: '尿\u00A0\u00A0量(ml)',
|
||||
code: 'urineOutput',
|
||||
key: '011',
|
||||
order: 6,
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '体\u00A0\u00A0重(kg)',
|
||||
code: 'weight',
|
||||
key: '009',
|
||||
order: 8,
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '身\u00A0\u00A0高(cm)',
|
||||
code: 'height',
|
||||
key: '030',
|
||||
order: 9,
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: 'SPO2',
|
||||
code: 'SPO2',
|
||||
key: '021',
|
||||
times: 2,
|
||||
order: 10,
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
name: '皮\u00A0试\u00A0阳\u00A0性',
|
||||
code: 'allergy',
|
||||
key: '017',
|
||||
order: 11,
|
||||
show: true,
|
||||
lines: 2,
|
||||
},
|
||||
{
|
||||
name: '过\u00A0敏\u00A0试\u00A0验',
|
||||
code: 'allergyTest',
|
||||
key: '020',
|
||||
order: 12,
|
||||
show: false,
|
||||
lines: 2,
|
||||
},
|
||||
{
|
||||
name: '其\u00A0\u00A0他',
|
||||
code: 'other',
|
||||
key: '025',
|
||||
order: 7,
|
||||
show: true
|
||||
show: false,
|
||||
lines: 2,
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
code: 'useless1',
|
||||
key: '100',
|
||||
order: 20,
|
||||
show: true
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
code: 'useless2',
|
||||
key: '100',
|
||||
order: 21,
|
||||
show: true
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
code: 'useless3',
|
||||
key: '100',
|
||||
order: 22,
|
||||
show: true
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
code: 'useless4',
|
||||
key: '100',
|
||||
order: 23,
|
||||
show: true
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
code: 'useless5',
|
||||
key: '100',
|
||||
order: 24,
|
||||
show: true
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
code: 'useless6',
|
||||
key: '100',
|
||||
order: 25,
|
||||
show: true
|
||||
}
|
||||
]
|
||||
];
|
||||
// 是否显示疼痛评分
|
||||
export const showPainFlag = true
|
||||
export const showPainFlag = true;
|
||||
|
||||
/** *********** 以上信息是本地化可以修改的部分 **************************/
|
||||
// 获取患者信息显示项目
|
||||
export function getInfoKeys() {
|
||||
return INFO_KEYS.filter(x => x.show).sort((a, b) => a.order - b.order)
|
||||
return INFO_KEYS.filter((x) => x.show).sort((a, b) => a.order - b.order);
|
||||
}
|
||||
// 获取患者信息显示项目
|
||||
export function getBottomKeys() {
|
||||
return BOTTOM_KEYS.filter(x => x.show).sort((a, b) => a.order - b.order)
|
||||
return BOTTOM_KEYS.filter((x) => x.show).sort((a, b) => a.order - b.order);
|
||||
}
|
||||
|
||||
export const timeNumber = [2, 6, 10, 14, 18, 22] // 时间展示
|
||||
export const nightTime = [2, 18, 22] // 夜间红色高亮时间
|
||||
export const timeNumber = [2, 6, 10, 14, 18, 22]; // 时间展示
|
||||
export const nightTime = [2, 18, 22]; // 夜间红色高亮时间
|
||||
export const leftTEXT = [
|
||||
['脉搏,(次/分),180', '160', '140', '120', '100', '80', '60', '40'],
|
||||
['体温,(℃), 42', '41', '40', '39', '38', '37', '36', '35']
|
||||
]
|
||||
['体温,(℃), 42', '41', '40', '39', '38', '37', '36', '35'],
|
||||
];
|
||||
|
||||
export const inOutItem = ['入观', '分娩', '手术', '转入', '出观', '死亡']
|
||||
export const otherItem = ['外出', '请假', '拒测', '离院', '其他']
|
||||
export const inOutItem = ['入观', '分娩', '手术', '转入', '出观', '死亡'];
|
||||
export const otherItem = ['外出', '请假', '拒测', '离院', '其他'];
|
||||
export const sheetOptions = {
|
||||
locations: [{
|
||||
code: '1',
|
||||
display: '体温'
|
||||
}, {
|
||||
code: '2',
|
||||
display: '口温'
|
||||
}, {
|
||||
code: '3',
|
||||
display: '肛温'
|
||||
}, {
|
||||
code: '4',
|
||||
display: '耳温'
|
||||
}],
|
||||
breath: [{
|
||||
code: '',
|
||||
display: '自主呼吸'
|
||||
}, {
|
||||
code: '®',
|
||||
display: '机械通气'
|
||||
}],
|
||||
poop: [{
|
||||
code: '',
|
||||
display: '正常'
|
||||
}, {
|
||||
code: '※',
|
||||
display: '失禁'
|
||||
}, {
|
||||
code: '☆',
|
||||
display: '人工肛门'
|
||||
}, {
|
||||
code: '/E',
|
||||
display: '灌肠'
|
||||
}],
|
||||
pee: [{
|
||||
code: '',
|
||||
display: '正常'
|
||||
}, {
|
||||
code: '※',
|
||||
display: '失禁'
|
||||
}, {
|
||||
code: 'C+',
|
||||
display: '导尿'
|
||||
}],
|
||||
locations: [
|
||||
{
|
||||
code: '1',
|
||||
display: '体温',
|
||||
},
|
||||
{
|
||||
code: '2',
|
||||
display: '口温',
|
||||
},
|
||||
{
|
||||
code: '3',
|
||||
display: '肛温',
|
||||
},
|
||||
{
|
||||
code: '4',
|
||||
display: '耳温',
|
||||
},
|
||||
],
|
||||
breath: [
|
||||
{
|
||||
code: '',
|
||||
display: '自主呼吸',
|
||||
},
|
||||
{
|
||||
code: '®',
|
||||
display: '机械通气',
|
||||
},
|
||||
],
|
||||
poop: [
|
||||
{
|
||||
code: '',
|
||||
display: '正常',
|
||||
},
|
||||
{
|
||||
code: '※',
|
||||
display: '失禁',
|
||||
},
|
||||
{
|
||||
code: '☆',
|
||||
display: '人工肛门',
|
||||
},
|
||||
{
|
||||
code: '/E',
|
||||
display: '灌肠',
|
||||
},
|
||||
],
|
||||
pee: [
|
||||
{
|
||||
code: '',
|
||||
display: '正常',
|
||||
},
|
||||
{
|
||||
code: '※',
|
||||
display: '失禁',
|
||||
},
|
||||
{
|
||||
code: 'C+',
|
||||
display: '导尿',
|
||||
},
|
||||
],
|
||||
heart: ['窦性心律', '起搏心律', '房性心律', '异常心律'],
|
||||
weight: ['正常', '卧床', '轮椅', '平车']
|
||||
}
|
||||
weight: ['正常', '卧床', '轮椅', '平车'],
|
||||
};
|
||||
// 此处是显示数字的 要和leftTEXT保持一直
|
||||
export const bodyTemperature = [34, 42]
|
||||
export const starNumEnv = bodyTemperature[0] // 开始体温
|
||||
export const endNumEnv = bodyTemperature[1] // 结束体温
|
||||
export const heartRange = [20, 180]
|
||||
export const bodyTemperature = [34, 42];
|
||||
export const starNumEnv = bodyTemperature[0]; // 开始体温
|
||||
export const endNumEnv = bodyTemperature[1]; // 结束体温
|
||||
export const heartRange = [20, 180];
|
||||
|
||||
// 中间图表字段对应
|
||||
export const CHART_KEYS = [
|
||||
{
|
||||
key: '001',
|
||||
code: 'breath',
|
||||
name: '呼吸'
|
||||
name: '呼吸',
|
||||
},
|
||||
{
|
||||
key: '002',
|
||||
code: 'sphygmus',
|
||||
name: '脉搏'
|
||||
name: '脉搏',
|
||||
},
|
||||
{
|
||||
key: '003',
|
||||
code: 'temperature',
|
||||
name: '不升'
|
||||
name: '不升',
|
||||
},
|
||||
{
|
||||
key: '012',
|
||||
code: 'inOut',
|
||||
name: '特殊标记'
|
||||
name: '特殊标记',
|
||||
},
|
||||
{
|
||||
key: '013',
|
||||
code: 'refuse',
|
||||
name: '标记内容'
|
||||
name: '标记内容',
|
||||
},
|
||||
{
|
||||
key: '014',
|
||||
code: 'heartRate',
|
||||
name: '心率'
|
||||
name: '心率',
|
||||
},
|
||||
{
|
||||
key: '015',
|
||||
code: 'lowerTemp',
|
||||
name: '物理降温'
|
||||
name: '物理降温',
|
||||
},
|
||||
{
|
||||
key: '016',
|
||||
code: 'painScore',
|
||||
name: '疼痛评分'
|
||||
}
|
||||
]
|
||||
name: '疼痛评分',
|
||||
},
|
||||
];
|
||||
|
||||
export const HEAD_HEIGHT = 120 // 头部文字预留位置
|
||||
export const LINE_HEIGHT = 20 // 一行的行高
|
||||
export const textLeftMargin = 4 // 文字左边边距
|
||||
export const TEXT_MARGIN_BOTTOM = 6 // 文字向上偏移量
|
||||
export const symbolArrowHeight = 20
|
||||
export const HEAD_HEIGHT = 120; // 头部文字预留位置
|
||||
export const LINE_HEIGHT = 20; // 一行的行高
|
||||
export const textLeftMargin = 4; // 文字左边边距
|
||||
export const TEXT_MARGIN_BOTTOM = 6; // 文字向上偏移量
|
||||
export const symbolArrowHeight = 20;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import moment from 'moment'
|
||||
import moment from 'moment';
|
||||
|
||||
export function getG(svg, translateX, translateY) {
|
||||
return svg
|
||||
.append('g')
|
||||
.attr('transform', `translate(${translateX},${translateY})`)
|
||||
return svg.append('g').attr('transform', `translate(${translateX},${translateY})`);
|
||||
}
|
||||
|
||||
// function generatePointer ({ pathData, type, yScaleInstance }) {
|
||||
@@ -51,247 +49,259 @@ export function getG(svg, translateX, translateY) {
|
||||
// }
|
||||
// }
|
||||
export function getTypeDatas(typeData, beginDate) {
|
||||
const types = typeData.sort((a, b) => new Date(a.date) - new Date(b.date))
|
||||
return types.map(item => {
|
||||
const types = typeData.sort((a, b) => new Date(a.date) - new Date(b.date));
|
||||
return types.map((item) => {
|
||||
return {
|
||||
index: getIndex(beginDate, item.date, '00:00:00') / 6,
|
||||
times: 0,
|
||||
date: item.date,
|
||||
typeCode: item.typeCode,
|
||||
typeValue: (item.typeValue) || null
|
||||
}
|
||||
})
|
||||
typeValue: item.typeValue || null,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function getTypeData(type, allData = [], isNumber = true, beginDate) {
|
||||
const getList = allData
|
||||
.map((rowBOSItem, index) => {
|
||||
const rowBOS = rowBOSItem.rowBOS
|
||||
const rowBOS = rowBOSItem.rowBOS;
|
||||
const cur =
|
||||
rowBOS.find((item) => {
|
||||
return item.typeCode === type
|
||||
}) || {}
|
||||
return item.typeCode === type;
|
||||
}) || {};
|
||||
return {
|
||||
index: getIndex(beginDate, cur.date, cur.times),
|
||||
date: cur.date,
|
||||
value: (isNumber ? +cur.typeValue : cur.typeValue) || null
|
||||
}
|
||||
value: (isNumber ? +cur.typeValue : cur.typeValue) || null,
|
||||
};
|
||||
})
|
||||
.map((item) => {
|
||||
if (item.value) {
|
||||
// item.value = NaN
|
||||
}
|
||||
return item
|
||||
})
|
||||
return getList.sort((a, b) => a.index - b.index)
|
||||
return item;
|
||||
});
|
||||
return getList.sort((a, b) => a.index - b.index);
|
||||
}
|
||||
// 获取不升
|
||||
export function getType(type, allData = [], beginDate) {
|
||||
const getList = allData
|
||||
.map((rowBOSItem, index) => {
|
||||
const rowBOS = rowBOSItem.rowBOS
|
||||
const rowBOS = rowBOSItem.rowBOS;
|
||||
const cur =
|
||||
rowBOS.find((item) => {
|
||||
return item.typeCode === type
|
||||
}) || {}
|
||||
return item.typeCode === type;
|
||||
}) || {};
|
||||
return {
|
||||
index: getIndex(beginDate, cur.date, cur.times),
|
||||
date: cur.date,
|
||||
value: cur.typeValue !== '' ? (parseFloat(cur.typeValue) <= 35 ? '不升' : null) : null
|
||||
}
|
||||
value: cur.typeValue !== '' ? (parseFloat(cur.typeValue) <= 35 ? '不升' : null) : null,
|
||||
};
|
||||
})
|
||||
.map((item) => {
|
||||
if (item.value) {
|
||||
// item.value = NaN
|
||||
}
|
||||
return item
|
||||
})
|
||||
return getList.sort((a, b) => a.index - b.index)
|
||||
return item;
|
||||
});
|
||||
return getList.sort((a, b) => a.index - b.index);
|
||||
}
|
||||
// 合并标记内容
|
||||
export function setMergeTag(ymbolTextArr = [], symbolContent = []) {
|
||||
const arr = []
|
||||
ymbolTextArr.forEach(item => {
|
||||
symbolContent.forEach(res => {
|
||||
const arr = [];
|
||||
ymbolTextArr.forEach((item) => {
|
||||
symbolContent.forEach((res) => {
|
||||
if (item.index === res.index) {
|
||||
arr.push({ ...item, ...res, value: (item.value !== null ? item.value : '') + (res.value !== null ? res.value : '') })
|
||||
arr.push({
|
||||
...item,
|
||||
...res,
|
||||
value: (item.value !== null ? item.value : '') + (res.value !== null ? res.value : ''),
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
return arr
|
||||
});
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
// 筛选手术产后日数
|
||||
export function postpartumDays(type, arr) {
|
||||
return arr.filter(item => item.typeCode === type).map(i => i.typeValue)
|
||||
return arr.filter((item) => item.typeCode === type).map((i) => i.typeValue);
|
||||
}
|
||||
// 筛选体温
|
||||
export function getTypeAnimalHeat(type, allData = [], code, beginDate) {
|
||||
const getList = allData
|
||||
.map((rowBOSItem, index) => {
|
||||
console.log(rowBOSItem.rowBOS, 'rowBOSItem.rowBOS')
|
||||
const rowBOS = rowBOSItem.rowBOS
|
||||
const curList = // 改为 filter 来获取所有符合条件的项
|
||||
rowBOS.filter((item) => {
|
||||
return item.typeCode === type
|
||||
}) || []
|
||||
|
||||
// 针对每个 cur 处理并生成新的对象数组
|
||||
return curList.map((cur) => ({
|
||||
const rowBOS = rowBOSItem.rowBOS;
|
||||
const cur =
|
||||
rowBOS.find((item) => {
|
||||
return item.typeCode === type;
|
||||
}) || {};
|
||||
return {
|
||||
index: getIndex(beginDate, cur.date, cur.times),
|
||||
date: cur.date,
|
||||
value: (+cur.collectionMode === +code ? +cur.typeValue : null) || null
|
||||
}))
|
||||
value: (+cur.collectionMode === +code ? +cur.typeValue : null) || null,
|
||||
};
|
||||
})
|
||||
.flat() // 将二维数组展平为一维数组
|
||||
.map((item) => {
|
||||
if (item.value) {
|
||||
// item.value = NaN
|
||||
}
|
||||
return item
|
||||
})
|
||||
console.log(getList, 'getList')
|
||||
return getList.sort((a, b) => a.index - b.index)
|
||||
return item;
|
||||
});
|
||||
return getList.sort((a, b) => a.index - b.index);
|
||||
}
|
||||
// 设置折线
|
||||
export function getBrokenLine(type, allData = [], arr = [], list = [], topList = [], beginDate) {
|
||||
const result = []
|
||||
const result = [];
|
||||
const getList = allData
|
||||
.map((rowBOSItem, index) => {
|
||||
const rowBOS = rowBOSItem.rowBOS
|
||||
const rowBOS = rowBOSItem.rowBOS;
|
||||
const cur =
|
||||
rowBOS.find((item) => {
|
||||
return item.typeCode === type
|
||||
}) || {}
|
||||
rowBOS.find((item) => {
|
||||
return item.typeCode === type;
|
||||
}) || {};
|
||||
return {
|
||||
index: getIndex(beginDate, cur.date, cur.times),
|
||||
date: cur.date,
|
||||
value: +cur.typeValue
|
||||
}
|
||||
value: +cur.typeValue,
|
||||
};
|
||||
})
|
||||
.map((item) => {
|
||||
if (item.value) {
|
||||
// item.value = NaN
|
||||
}
|
||||
return item
|
||||
})
|
||||
const _a = arr.filter(item => item.value)
|
||||
const _b = list.filter(item => item.value)
|
||||
const _c = topList.filter(item => item.value)
|
||||
const mergingData = [..._a, ..._b, ..._c, { index: 50 }].sort((a, b) => a.index - b.index)
|
||||
let start = 0
|
||||
mergingData.forEach(item => {
|
||||
const _p = getList.sort((a, b) => a.index - b.index).slice(start, item.index)
|
||||
start = item.index + 1
|
||||
result.push(_p)
|
||||
})
|
||||
return result
|
||||
return item;
|
||||
});
|
||||
const _a = arr.filter((item) => item.value);
|
||||
const _b = list.filter((item) => item.value);
|
||||
const _c = topList.filter((item) => item.value);
|
||||
const mergingData = [..._a, ..._b, ..._c, { index: 50 }].sort((a, b) => a.index - b.index);
|
||||
let start = 0;
|
||||
mergingData.forEach((item) => {
|
||||
const _p = getList.sort((a, b) => a.index - b.index).slice(start, item.index);
|
||||
start = item.index + 1;
|
||||
result.push(_p);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
// 处理脉搏心率
|
||||
export function getHeartRate(type, allData = [], arr = [], topList = [], isNumber = true, beginDate) {
|
||||
const result = []
|
||||
export function getHeartRate(
|
||||
type,
|
||||
allData = [],
|
||||
arr = [],
|
||||
topList = [],
|
||||
isNumber = true,
|
||||
beginDate
|
||||
) {
|
||||
const result = [];
|
||||
const getList = allData
|
||||
.map((rowBOSItem, index) => {
|
||||
const rowBOS = rowBOSItem.rowBOS
|
||||
const rowBOS = rowBOSItem.rowBOS;
|
||||
const cur =
|
||||
rowBOS.find((item) => {
|
||||
return item.typeCode === type
|
||||
}) || {}
|
||||
rowBOS.find((item) => {
|
||||
return item.typeCode === type;
|
||||
}) || {};
|
||||
return {
|
||||
index: getIndex(beginDate, cur.date, cur.times),
|
||||
date: cur.date,
|
||||
value: (isNumber ? +cur.typeValue : cur.typeValue) || null
|
||||
}
|
||||
value: (isNumber ? +cur.typeValue : cur.typeValue) || null,
|
||||
};
|
||||
})
|
||||
.map((item) => {
|
||||
if (item.value) {
|
||||
// item.value = NaN
|
||||
}
|
||||
return item
|
||||
})
|
||||
const _a = arr.filter(item => item.value)
|
||||
const _c = topList.filter(item => item.value)
|
||||
const mergingData = [..._a, ..._c, { index: 50 }].sort((a, b) => a.index - b.index)
|
||||
let start = 0
|
||||
mergingData.forEach(item => {
|
||||
const _p = getList.slice(start, item.index).sort((a, b) => { return a.index - b.index })
|
||||
start = item.index
|
||||
result.push(_p)
|
||||
})
|
||||
return result
|
||||
return item;
|
||||
});
|
||||
const _a = arr.filter((item) => item.value);
|
||||
const _c = topList.filter((item) => item.value);
|
||||
const mergingData = [..._a, ..._c, { index: 50 }].sort((a, b) => a.index - b.index);
|
||||
let start = 0;
|
||||
mergingData.forEach((item) => {
|
||||
const _p = getList.slice(start, item.index).sort((a, b) => {
|
||||
return a.index - b.index;
|
||||
});
|
||||
start = item.index;
|
||||
result.push(_p);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
function getIndex(beginDate, date, time) {
|
||||
if (beginDate === undefined || date === undefined) return
|
||||
const diffTime = moment(date.substring(0, 10)).diff(moment(beginDate.substring(0, 10))) / 1000 / 3600 / 24
|
||||
const diffIndex = parseInt(time.substring(0, 2))
|
||||
return diffTime * 6 + Math.floor(diffIndex / 4)
|
||||
if (beginDate === undefined || date === undefined) return;
|
||||
const diffTime =
|
||||
moment(date.substring(0, 10)).diff(moment(beginDate.substring(0, 10))) / 1000 / 3600 / 24;
|
||||
const diffIndex = parseInt(time.substring(0, 2));
|
||||
return diffTime * 6 + Math.floor(diffIndex / 4);
|
||||
}
|
||||
// 筛选35和40~42数据
|
||||
export function degreesOnline(allData, data, type) {
|
||||
const arr = allData.map((item, index) => {
|
||||
const cur = data?.find(res => item.value === res.name && +res.isShowPlace === type) || null
|
||||
const cur = data?.find((res) => item.value === res.name && +res.isShowPlace === type) || null;
|
||||
return {
|
||||
index: index,
|
||||
date: item.date,
|
||||
value: cur?.name || null
|
||||
}
|
||||
})
|
||||
return arr
|
||||
value: cur?.name || null,
|
||||
};
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
// 35或42上断开的事件
|
||||
export function disconnectEvents(allData, data, code, type) {
|
||||
const arr = allData.map((item, index) => {
|
||||
const cur = data?.find(res => item.value === res.name && +res.isShowPlace === type && +res[code] === 1) || null
|
||||
const cur =
|
||||
data?.find(
|
||||
(res) => item.value === res.name && +res.isShowPlace === type && +res[code] === 1
|
||||
) || null;
|
||||
return {
|
||||
index: index,
|
||||
date: item.date,
|
||||
value: cur?.name || null
|
||||
}
|
||||
})
|
||||
return arr
|
||||
value: cur?.name || null,
|
||||
};
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
|
||||
export function getDrawCoolData(type, allData = [], isNumber = true, beginDate) {
|
||||
const getList = allData
|
||||
.map((rowBOSItem, index) => {
|
||||
const rowBOS = rowBOSItem.rowBOS
|
||||
const rowBOS = rowBOSItem.rowBOS;
|
||||
const cur =
|
||||
rowBOS.find((item) => {
|
||||
return item.typeCode === type
|
||||
}) || {}
|
||||
return item.typeCode === type;
|
||||
}) || {};
|
||||
return {
|
||||
index: getIndex(beginDate, cur.date, cur.times),
|
||||
date: cur.date + cur.times,
|
||||
value: (isNumber ? +cur.typeValue : cur.typeValue) || null
|
||||
}
|
||||
value: (isNumber ? +cur.typeValue : cur.typeValue) || null,
|
||||
};
|
||||
})
|
||||
.map((item) => {
|
||||
if (item.value) {
|
||||
// item.value = NaN
|
||||
}
|
||||
return item
|
||||
})
|
||||
return getList.sort((a, b) => a.index - b.index)
|
||||
return item;
|
||||
});
|
||||
return getList.sort((a, b) => a.index - b.index);
|
||||
}
|
||||
// 筛选降温getDrawData
|
||||
export function getDrawData(type, allData = [], code, beginDate) {
|
||||
const getList = allData
|
||||
.map((rowBOSItem, index) => {
|
||||
const rowBOS = rowBOSItem.rowBOS
|
||||
const rowBOS = rowBOSItem.rowBOS;
|
||||
const cur =
|
||||
rowBOS.find((item) => {
|
||||
return item.typeCode === type
|
||||
}) || {}
|
||||
return item.typeCode === type;
|
||||
}) || {};
|
||||
return {
|
||||
index: getIndex(beginDate, cur.date, cur.times),
|
||||
date: cur.date + cur.times,
|
||||
value: (+cur.collectionMode === +code ? +cur.typeValue : null) || null
|
||||
}
|
||||
value: (+cur.collectionMode === +code ? +cur.typeValue : null) || null,
|
||||
};
|
||||
})
|
||||
.map((item) => {
|
||||
if (item.value) {
|
||||
// item.value = NaN
|
||||
}
|
||||
return item
|
||||
})
|
||||
return getList.sort((a, b) => a.index - b.index)
|
||||
return item;
|
||||
});
|
||||
return getList.sort((a, b) => a.index - b.index);
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询检验类型列表
|
||||
export function listInspectionType(query) {
|
||||
return request({
|
||||
url: '/system/inspection-type/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检验类型详细
|
||||
export function getInspectionType(inspectionTypeId) {
|
||||
return request({
|
||||
url: `/system/inspection-type/${inspectionTypeId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增检验类型
|
||||
export function addInspectionType(data) {
|
||||
return request({
|
||||
url: '/system/inspection-type',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改检验类型
|
||||
export function updateInspectionType(data) {
|
||||
return request({
|
||||
url: '/system/inspection-type',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除检验类型
|
||||
export function delInspectionType(inspectionTypeId) {
|
||||
return request({
|
||||
url: `/system/inspection-type/${inspectionTypeId}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检验套餐列表
|
||||
export function listInspectionPackage(query) {
|
||||
return request({
|
||||
url: '/system/inspection-package/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检验套餐详细
|
||||
export function getInspectionPackage(packageId) {
|
||||
return request({
|
||||
url: `/system/inspection-package/${packageId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增检验套餐
|
||||
export function addInspectionPackage(data) {
|
||||
return request({
|
||||
url: '/system/inspection-package',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改检验套餐
|
||||
export function updateInspectionPackage(data) {
|
||||
return request({
|
||||
url: '/system/inspection-package',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除检验套餐
|
||||
export function delInspectionPackage(packageId) {
|
||||
return request({
|
||||
url: `/system/inspection-package/${packageId}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -1,73 +1,98 @@
|
||||
import request from '@/utils/request'
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 获取追溯码
|
||||
export function searchTraceNo(data) {
|
||||
return request({
|
||||
url:'/app-common/search-trace-no',
|
||||
method: 'get',
|
||||
params: data,
|
||||
})
|
||||
return request({
|
||||
url: '/app-common/search-trace-no',
|
||||
method: 'get',
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取处方打印数据
|
||||
export function advicePrint(data) {
|
||||
return request({
|
||||
url:'/app-common/advice-print',
|
||||
method: 'get',
|
||||
params: data,
|
||||
})
|
||||
return request({
|
||||
url: '/app-common/advice-print',
|
||||
method: 'get',
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取全部科室列表
|
||||
export function getOrgList(data) {
|
||||
return request({
|
||||
url:'/app-common/department-list',
|
||||
method: 'get',
|
||||
params: 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,
|
||||
})
|
||||
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,
|
||||
})
|
||||
return request({
|
||||
url: '/app-common/supplier',
|
||||
method: 'get',
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目定价方式,批次售价/统一售价
|
||||
*/
|
||||
export function getAdjustPriceSwitchState(params) {
|
||||
return request({
|
||||
url: '/change/price/getAdjustPriceSwitchState',
|
||||
method: 'get',
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 批次号匹配
|
||||
*/
|
||||
export function lotNumberMatch(params) {
|
||||
return request({
|
||||
url: '/app-common/lot-number-match',
|
||||
method: 'get',
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
const env = import.meta.env.MODE;
|
||||
export function invokeYbPlugin(data) {
|
||||
|
||||
if(env == 'development'){
|
||||
return axios.create(
|
||||
{
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: '/ybplugin',//ybplugin
|
||||
// 超时
|
||||
timeout: 60000
|
||||
}
|
||||
).post('/api/data/', data);
|
||||
export function invokeYbPlugin5001(data) {
|
||||
|
||||
} else {
|
||||
return axios.create(
|
||||
{
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: '',
|
||||
// 超时
|
||||
timeout: 60000
|
||||
}
|
||||
).post('http://localhost:5000/api/data/', data);
|
||||
return axios
|
||||
.create({
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: '',
|
||||
// 超时
|
||||
timeout: 60000,
|
||||
})
|
||||
.post('http://localhost:5001/api/data/', data);
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
export function invokeYbPlugin5000(data) {
|
||||
return axios
|
||||
.create({
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: '',
|
||||
// 超时
|
||||
timeout: 60000,
|
||||
})
|
||||
.post('http://localhost:5000/api/data/', data);
|
||||
}
|
||||
|
||||
BIN
openhis-ui-vue3/src/assets/images/weixinzhifu.png
Normal file
BIN
openhis-ui-vue3/src/assets/images/weixinzhifu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
BIN
openhis-ui-vue3/src/assets/images/zhifubaozhifu.png
Normal file
BIN
openhis-ui-vue3/src/assets/images/zhifubaozhifu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -212,4 +212,4 @@ aside {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="recordBill">
|
||||
<div :id="'exeSheetTitle' + printData.id" class="printView_header">
|
||||
<div style="text-align: center; height: 60px">
|
||||
呼和浩特市第一医院医嘱执行单
|
||||
长春市朝阳区中医院医嘱执行单
|
||||
</div>
|
||||
<div>
|
||||
<span style="display: inline-block; width: 100px">床号:{{ printData.patientInfo.encounterLocationName }}</span>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="recordBill">
|
||||
<div id="div1" class="printView_header">
|
||||
<div style="text-align: center; font-size: 20px; height: 40px">
|
||||
呼和浩特市第一医院输液执行单
|
||||
长春市朝阳区中医院输液执行单
|
||||
</div>
|
||||
<div>
|
||||
<span>座位:{{ printData.patientInfo.encounterLocationName }}</span>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="printTicket">
|
||||
<p>xx人民医院</p>
|
||||
<p>长春市朝阳区中医院</p>
|
||||
<div>
|
||||
<span>姓名:</span>
|
||||
<span>{{ printData.patientName }}</span>
|
||||
@@ -21,11 +21,11 @@
|
||||
<span>分诊时间:</span>
|
||||
<span>{{ printData.triageTime }}</span>
|
||||
</div>
|
||||
<img ref="refQr" style="position: absolute; top: 10px; left: 100px">
|
||||
<img ref="refQr" style="position: absolute; top: 10px; left: 100px" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import JsBarcode from 'jsbarcode'
|
||||
import JsBarcode from 'jsbarcode';
|
||||
export default {
|
||||
name: 'TriageTicket',
|
||||
props: {
|
||||
@@ -37,41 +37,33 @@ export default {
|
||||
dept: '',
|
||||
triageLevel: '',
|
||||
triageTime: '',
|
||||
hisId: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
hisId: '',
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
return {};
|
||||
},
|
||||
updated() {
|
||||
JsBarcode(this.$refs.refQr,
|
||||
this.printData.hisId,
|
||||
{
|
||||
format: 'CODE128',
|
||||
lineColor: '#000',
|
||||
background: '#fff',
|
||||
displayValue: false,
|
||||
height: 30,
|
||||
margin: 2
|
||||
})
|
||||
JsBarcode(this.$refs.refQr, this.printData.hisId, {
|
||||
format: 'CODE128',
|
||||
lineColor: '#000',
|
||||
background: '#fff',
|
||||
displayValue: false,
|
||||
height: 30,
|
||||
margin: 2,
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
mounted() {},
|
||||
methods: {},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.printTicket{
|
||||
display: block;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
border: 1px solid #A3A3A3;
|
||||
}
|
||||
|
||||
.printTicket {
|
||||
display: block;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
border: 1px solid #a3a3a3;
|
||||
}
|
||||
</style>
|
||||
|
||||
51
openhis-ui-vue3/src/components/Layout/index.vue
Normal file
51
openhis-ui-vue3/src/components/Layout/index.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<div v-if="$slots.header" class="page-header">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<slot />
|
||||
</div>
|
||||
<div v-if="$slots.footer" class="page-footer">
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
.page-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.page-footer {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
}
|
||||
</style>
|
||||
12
openhis-ui-vue3/src/components/PatientList/api.js
Normal file
12
openhis-ui-vue3/src/components/PatientList/api.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取住院患者列表
|
||||
*/
|
||||
export function getPatientList(queryParams) {
|
||||
return request({
|
||||
url: '/reg-doctorstation/advice-manage/reg-patient-zk',
|
||||
method: 'get',
|
||||
params: queryParams,
|
||||
});
|
||||
}
|
||||
695
openhis-ui-vue3/src/components/PatientList/index.vue
Normal file
695
openhis-ui-vue3/src/components/PatientList/index.vue
Normal file
@@ -0,0 +1,695 @@
|
||||
<template>
|
||||
<div class="patientList-container" :class="{ 'patientList-container-unexpand': !currentExpand }">
|
||||
<div
|
||||
class="patientList-operate"
|
||||
:class="{ 'patientList-operate-unexpand': !currentExpand }"
|
||||
v-if="currentExpand"
|
||||
>
|
||||
<el-input
|
||||
class="patientList-search-input"
|
||||
placeholder="床号/住院号/姓名"
|
||||
v-model="searchKeyword"
|
||||
@keyup.enter="handleSearch"
|
||||
:prefix-icon="Search"
|
||||
/>
|
||||
<el-button class="icon-btn" circle @click="handleRefresh" type="text" plain>
|
||||
<el-icon icon-class="Refresh" size="24" :class="{ 'is-rotating': refreshing }">
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<transition name="patient-list-toggle" mode="out-in">
|
||||
<div key="expanded" class="patientList-list" v-if="currentExpand">
|
||||
<div class="patient-cards" v-loading="isLoading">
|
||||
<template v-if="filteredCardData && filteredCardData.length > 0">
|
||||
<el-scrollbar ref="expandScrollbarRef" class="patient-cards-scrollbar">
|
||||
<div
|
||||
class="patient-card"
|
||||
v-for="item in filteredCardData"
|
||||
:key="item.encounterId"
|
||||
:id="item.encounterId"
|
||||
@click="handleItemClick(item)"
|
||||
:class="{ actived: activeCardId === item.encounterId }"
|
||||
>
|
||||
<div class="patient-card-header">
|
||||
<div class="header-top">
|
||||
<div class="bed-container">
|
||||
<div class="bed">
|
||||
<div class="bed-info">
|
||||
<div v-if="item.houseName" class="house-name">{{ item.houseName }}</div>
|
||||
<div class="bed-name">{{ item.bedName || '未分床' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-space>
|
||||
<el-tag
|
||||
v-if="item.statusEnum_enumText"
|
||||
size="small"
|
||||
class="payer-tag-status"
|
||||
effect="light"
|
||||
:style="getStatusStyle(item.statusEnum)"
|
||||
>
|
||||
{{ item.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="item.contractName"
|
||||
size="small"
|
||||
class="payer-tag"
|
||||
effect="light"
|
||||
>
|
||||
{{ item.contractName }}
|
||||
</el-tag>
|
||||
</el-space>
|
||||
</div>
|
||||
|
||||
<div class="header-bottom">
|
||||
<span class="bus-no">住院号:{{ item.busNo || '-' }}</span>
|
||||
<span class="insurance-type" v-if="item.insutype_dictText">
|
||||
险种类型:{{ item.insutype_dictText }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="doctor-parent-line" />
|
||||
|
||||
<div class="patient-card-body">
|
||||
<div class="personal-info-container">
|
||||
<div class="name-container">
|
||||
<div class="name">
|
||||
<el-text :text="item.patientName" tclass="name" width="auto">
|
||||
{{ item.patientName || '-' }}
|
||||
</el-text>
|
||||
</div>
|
||||
<div class="age">
|
||||
<el-tag
|
||||
size="small"
|
||||
class="age-tag"
|
||||
effect="plain"
|
||||
:class="{ 'age-tag-female': item.genderEnum_enumText === '女性' }"
|
||||
>
|
||||
{{ item.genderEnum_enumText || '-' }}
|
||||
<span v-if="item.age"> · {{ item.age }}</span>
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
<el-empty v-else description="暂无数据" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
key="collapsed"
|
||||
class="patientList-list"
|
||||
v-else
|
||||
v-loading="isLoading"
|
||||
:class="{ 'patientList-list-unexpand': !currentExpand }"
|
||||
>
|
||||
<el-scrollbar ref="contractScrollbarRef" class="patient-cards-scrollbar">
|
||||
<template v-if="filteredCardData && filteredCardData.length > 0">
|
||||
<el-tooltip
|
||||
v-for="item in filteredCardData"
|
||||
:show-after="200"
|
||||
:key="item.encounterId"
|
||||
:show-arrow="true"
|
||||
placement="right"
|
||||
effect="light"
|
||||
:offset="4"
|
||||
>
|
||||
<template #content>
|
||||
<div class="card-tooltip">
|
||||
<div class="card-tooltip-main">
|
||||
<span class="card-tooltip-bed">{{ item.bedName }}</span>
|
||||
<span class="card-tooltip-name">{{ item.patientName }}</span>
|
||||
</div>
|
||||
<div class="card-tooltip-sex">
|
||||
<span class="card-tooltip-sex-text">
|
||||
{{ item.genderEnum_enumText || '-' }}
|
||||
<span v-if="item.age"> · {{ item.age }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<div
|
||||
class="card-small"
|
||||
:class="{ 'patient-active': activeCardId === item.encounterId }"
|
||||
@click="handleSmallCardClick(item)"
|
||||
:key="item.encounterId"
|
||||
>
|
||||
{{ item.bedName }}
|
||||
</div>
|
||||
<div class="patient-card-small-border"></div>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-empty v-else description="暂无数据" :image-size="50" />
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<div
|
||||
class="patientList-toggle-btn-wrap"
|
||||
:class="{ 'patientList-toggle-btn-wrap-unexpand': !currentExpand }"
|
||||
>
|
||||
<el-button class="icon-btn" circle @click="updateExpand">
|
||||
<el-icon class="svg-sty-menu" size="24">
|
||||
<Expand v-if="!currentExpand" />
|
||||
<Fold v-if="currentExpand" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { Search, Refresh, Expand, Fold } from '@element-plus/icons-vue';
|
||||
import type { ElScrollbar } from 'element-plus';
|
||||
|
||||
interface PatientCardItem {
|
||||
encounterId: string;
|
||||
bedName?: string;
|
||||
busNo?: string;
|
||||
patientName?: string;
|
||||
genderEnum_enumText?: string;
|
||||
age?: number | string;
|
||||
contractName?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
// 过滤后的卡片数据
|
||||
filteredCardData?: PatientCardItem[];
|
||||
// 当前激活的卡片ID
|
||||
activeCardId?: string;
|
||||
// 是否展开(不传则为不受控模式,组件内部自己管理)
|
||||
expand?: boolean;
|
||||
// 加载状态
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
filteredCardData: () => [],
|
||||
activeCardId: '',
|
||||
expand: undefined,
|
||||
loading: false,
|
||||
});
|
||||
|
||||
interface Emits {
|
||||
(e: 'item-click', item: PatientCardItem): void;
|
||||
(e: 'search', keyword: string): void;
|
||||
(e: 'refresh'): void;
|
||||
(e: 'update:expand', value: boolean): void;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const searchKeyword = ref<string>('');
|
||||
const refreshing = ref<boolean>(false);
|
||||
const refreshLoading = ref<boolean>(false);
|
||||
|
||||
const internalExpand = ref<boolean>(true);
|
||||
|
||||
const isControlled = computed<boolean>(() => props.expand !== undefined);
|
||||
|
||||
const currentExpand = computed<boolean>(() => {
|
||||
return isControlled.value ? props.expand! : internalExpand.value;
|
||||
});
|
||||
|
||||
const isLoading = computed<boolean>(() => {
|
||||
return props.loading || refreshLoading.value;
|
||||
});
|
||||
|
||||
const handleItemClick = (item: PatientCardItem): void => {
|
||||
emit('item-click', item);
|
||||
};
|
||||
|
||||
const handleSmallCardClick = (item: PatientCardItem): void => {
|
||||
emit('item-click', item);
|
||||
};
|
||||
|
||||
const handleSearch = (): void => {
|
||||
emit('search', searchKeyword.value);
|
||||
};
|
||||
|
||||
const handleRefresh = (): void => {
|
||||
if (refreshing.value) return;
|
||||
refreshing.value = true;
|
||||
refreshLoading.value = true;
|
||||
emit('refresh');
|
||||
setTimeout(() => {
|
||||
refreshing.value = false;
|
||||
}, 600);
|
||||
|
||||
setTimeout(() => {
|
||||
if (!props.loading) {
|
||||
refreshLoading.value = false;
|
||||
}
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const updateExpand = (): void => {
|
||||
const newValue = !currentExpand.value;
|
||||
if (isControlled.value) {
|
||||
emit('update:expand', newValue);
|
||||
} else {
|
||||
internalExpand.value = newValue;
|
||||
}
|
||||
};
|
||||
|
||||
// 根据状态枚举值返回文本颜色
|
||||
const getStatusColor = (statusEnum?: number): string => {
|
||||
if (statusEnum === undefined || statusEnum === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
switch (statusEnum) {
|
||||
case 2: // REGISTERED - 待入科
|
||||
return '#E6A23C'; // 橙色
|
||||
case 3: // AWAITING_DISCHARGE - 待出院
|
||||
return '#F56C6C'; // 红色
|
||||
case 4: // DISCHARGED_FROM_HOSPITAL - 待出院结算
|
||||
return '#909399'; // 灰色
|
||||
case 5: // ADMITTED_TO_THE_HOSPITAL - 已入院
|
||||
return '#67C23A'; // 绿色
|
||||
case 6: // PENDING_TRANSFER - 待转科
|
||||
return '#409EFF'; // 蓝色
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
// 根据状态枚举值返回带透明背景的样式
|
||||
const getStatusStyle = (statusEnum?: number): Record<string, string> => {
|
||||
const color = getStatusColor(statusEnum);
|
||||
if (!color) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// 不同状态对应的半透明背景色
|
||||
let backgroundColor = '';
|
||||
switch (statusEnum) {
|
||||
case 2: // 橙色
|
||||
backgroundColor = 'rgba(230, 162, 60, 0.12)';
|
||||
break;
|
||||
case 3: // 红色
|
||||
backgroundColor = 'rgba(245, 108, 108, 0.12)';
|
||||
break;
|
||||
case 4: // 灰色
|
||||
backgroundColor = 'rgba(144, 147, 153, 0.12)';
|
||||
break;
|
||||
case 5: // 绿色
|
||||
backgroundColor = 'rgba(103, 194, 58, 0.12)';
|
||||
break;
|
||||
case 6: // 蓝色
|
||||
backgroundColor = 'rgba(64, 158, 255, 0.12)';
|
||||
break;
|
||||
default:
|
||||
backgroundColor = 'rgba(148, 163, 184, 0.12)';
|
||||
}
|
||||
|
||||
return {
|
||||
color,
|
||||
backgroundColor,
|
||||
borderColor: 'transparent',
|
||||
};
|
||||
};
|
||||
|
||||
// 保险类型映射表
|
||||
const insuranceTypeMap: Record<number, string> = {
|
||||
310: '职工基本医疗保险',
|
||||
320: '公务员医疗补助',
|
||||
330: '大额医疗费用补助',
|
||||
340: '离休人员医疗保障',
|
||||
350: '一至六级残废军人医疗补助',
|
||||
360: '老红军医疗保障',
|
||||
370: '企业补充医疗保险',
|
||||
380: '新型农村合作医疗',
|
||||
390: '城乡居民基本医疗保险',
|
||||
391: '城镇居民基本医疗保险',
|
||||
392: '城乡居民大病医疗保险',
|
||||
399: '其他特殊人员医疗保障',
|
||||
410: '长期照护保险',
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.loading,
|
||||
(newLoading) => {
|
||||
if (!newLoading && refreshLoading.value) {
|
||||
refreshLoading.value = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.patient-card {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||
box-shadow: 0 2px 6px 0 rgba(15, 35, 52, 0.12);
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px rgba(15, 35, 52, 0.18);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&.actived {
|
||||
background-color: rgba(7, 155, 140, 0.06);
|
||||
border-color: var(--el-color-primary);
|
||||
box-shadow: 0 0 0 1px rgba(7, 155, 140, 0.3), 0 4px 14px rgba(7, 155, 140, 0.25);
|
||||
}
|
||||
|
||||
.patient-card-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 12px 4px;
|
||||
|
||||
.header-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
.bed-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
|
||||
.bed {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
min-width: 0;
|
||||
|
||||
.bed-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
line-height: 1.4;
|
||||
|
||||
.house-name {
|
||||
color: #1f2933;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.bed-name {
|
||||
color: #1f2933;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.payer-tag {
|
||||
max-width: 120px;
|
||||
font-size: 12px;
|
||||
border-radius: 999px;
|
||||
font-weight: bolder;
|
||||
}
|
||||
.payer-tag-status {
|
||||
font-weight: bolder;
|
||||
border-radius: 999px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-bottom {
|
||||
margin-top: 4px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 2px;
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
|
||||
.bus-no {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.insurance-type {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.doctor-parent-line {
|
||||
margin: 6px 12px 0;
|
||||
border-bottom: 1px dashed #e5e7eb;
|
||||
}
|
||||
|
||||
.patient-card-body {
|
||||
padding: 8px 12px 10px;
|
||||
|
||||
.personal-info-container {
|
||||
display: block;
|
||||
|
||||
.name-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
|
||||
.name {
|
||||
color: #111827;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.age {
|
||||
flex-shrink: 0;
|
||||
|
||||
.age-tag {
|
||||
border-radius: 999px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.age-tag-female {
|
||||
border-color: rgb(255, 55, 158);
|
||||
color: rgb(255, 126, 184);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.patientList-container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
border-right: 1px solid #ebeef5;
|
||||
background-color: #ffffff;
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
&-unexpand {
|
||||
width: 84px;
|
||||
min-width: 84px;
|
||||
}
|
||||
.patientList-operate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 44px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
flex: none;
|
||||
padding: 0 0 0 8px;
|
||||
|
||||
&-unexpand {
|
||||
justify-content: space-around;
|
||||
}
|
||||
}
|
||||
|
||||
.patientList-list {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
height: 0;
|
||||
width: 240px;
|
||||
&-unexpand {
|
||||
width: 84px;
|
||||
}
|
||||
|
||||
.search-operate {
|
||||
padding: 0 8px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.patient-cards {
|
||||
flex: 1;
|
||||
padding: 0 8px;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
:deep(.patient-cards-scrollbar) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.el-scrollbar__bar {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-small {
|
||||
height: 44px;
|
||||
padding: 0 10px 0 12px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
line-height: 44px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
border-right: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.patient-active {
|
||||
background-color: #e6f7ff;
|
||||
font-weight: 600;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.patient-card-small-border {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background-color: #f1faff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.patientList-toggle-btn-wrap {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 4px 16px 8px;
|
||||
&-unexpand {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.patient-list-toggle-enter-active,
|
||||
.patient-list-toggle-leave-active {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.patient-list-toggle-enter-from,
|
||||
.patient-list-toggle-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
|
||||
.card-tooltip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-width: 140px;
|
||||
max-width: 220px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 6px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.card-tooltip-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.card-tooltip-bed {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.card-tooltip-name {
|
||||
font-size: 13px;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.card-tooltip-sex {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.card-tooltip-sex-text {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.svg-gray {
|
||||
fill: var(--hip-color-text-unit);
|
||||
}
|
||||
|
||||
.icon-btn {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.is-rotating {
|
||||
animation: patient-refresh-rotate 0.6s linear;
|
||||
}
|
||||
|
||||
@keyframes patient-refresh-rotate {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.scrollbar) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.el-scrollbar__bar {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.f-16 {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.f-14 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
.empty-text-sty {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
110
openhis-ui-vue3/src/components/PatientList/patient-list.vue
Normal file
110
openhis-ui-vue3/src/components/PatientList/patient-list.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<BasePatientList
|
||||
:filtered-card-data="filteredCardData"
|
||||
:active-card-id="cardId"
|
||||
:loading="queryloading"
|
||||
@item-click="handleItemClick"
|
||||
@search="handleSearch"
|
||||
@refresh="getList"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
||||
import BasePatientList from './index.vue';
|
||||
import { getPatientList } from '@/views/inpatientDoctor/home/components/api';
|
||||
|
||||
defineOptions({
|
||||
name: 'PatientListWithData',
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
/** 接口 status 参数,默认 5(在院) */
|
||||
status: {
|
||||
type: [String, Number],
|
||||
default: undefined,
|
||||
},
|
||||
/** 首次加载自动选中第一条 */
|
||||
autoSelectFirst: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 外部已选中的患者信息(用于避免重复自动选中) */
|
||||
selectedPatient: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* 选中患者时回调(给你外部写 store 用)
|
||||
* (patient) => void
|
||||
*/
|
||||
onSelect: {
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['item-click']);
|
||||
|
||||
// 这段逻辑就是你说的 “@index.vue (4-11) 那套带数据的”
|
||||
const searchData = reactive({
|
||||
keyword: '',
|
||||
patientType: 1,
|
||||
type: 1,
|
||||
timeLimit: 3,
|
||||
});
|
||||
|
||||
const cardId = ref('');
|
||||
const cardAllData = ref([]);
|
||||
const isFirstLoad = ref(true);
|
||||
const queryloading = ref(false);
|
||||
|
||||
const filteredCardData = computed(() => cardAllData.value);
|
||||
|
||||
const getList = () => {
|
||||
queryloading.value = true;
|
||||
getPatientList({ status: props.status, searchKey: searchData.keyword })
|
||||
.then((res) => {
|
||||
cardAllData.value = res?.data?.records || [];
|
||||
})
|
||||
.finally(() => {
|
||||
queryloading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => filteredCardData.value,
|
||||
(newData) => {
|
||||
if (!props.autoSelectFirst) return;
|
||||
if (
|
||||
newData &&
|
||||
newData.length > 0 &&
|
||||
!cardId.value &&
|
||||
isFirstLoad.value &&
|
||||
!props.selectedPatient?.encounterId
|
||||
) {
|
||||
const firstPatient = newData[0];
|
||||
if (firstPatient?.encounterId) {
|
||||
handleItemClick(firstPatient);
|
||||
isFirstLoad.value = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const handleItemClick = (node) => {
|
||||
cardId.value = node.encounterId;
|
||||
props.onSelect?.(node);
|
||||
emit('item-click', node);
|
||||
};
|
||||
|
||||
const handleSearch = (keyword) => {
|
||||
searchData.keyword = keyword;
|
||||
getList();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
318
openhis-ui-vue3/src/components/PendingPatientList/index.vue
Normal file
318
openhis-ui-vue3/src/components/PendingPatientList/index.vue
Normal file
@@ -0,0 +1,318 @@
|
||||
<template>
|
||||
<div class="pending-patient-list">
|
||||
<div class="patient-cards" v-loading="loading">
|
||||
<template v-if="list && list.length > 0">
|
||||
<el-scrollbar class="patient-cards-scrollbar">
|
||||
<div
|
||||
class="patient-card"
|
||||
v-for="(item, index) in list"
|
||||
:key="item[idKey] ?? index"
|
||||
:class="{ actived: !!item.active || activeId === item[idKey] }"
|
||||
draggable="true"
|
||||
@click="emit('item-click', item, index)"
|
||||
@dblclick="emit('item-dblclick', item)"
|
||||
@dragstart="(e) => emit('dragstart', e, item)"
|
||||
@dragend="(e) => emit('dragend', e)"
|
||||
>
|
||||
<div class="patient-card-header">
|
||||
<div class="header-top">
|
||||
<div class="bed-container">
|
||||
<div class="bed">
|
||||
<el-text truncated tclass="bed-font" width="auto">
|
||||
{{ item.bedName || '-' }}
|
||||
</el-text>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-tags">
|
||||
<el-tag v-if="item.contractName" size="small" class="payer-tag" effect="light">
|
||||
{{ item.contractName }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="item.encounterStatus_enumText"
|
||||
size="small"
|
||||
class="status-tag"
|
||||
effect="light"
|
||||
:class="getStatusClass(item)"
|
||||
>
|
||||
{{ item.encounterStatus_enumText }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header-bottom">
|
||||
<span class="bus-no">住院号:{{ item.busNo || '-' }}</span>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<div class="meta-row">
|
||||
<span class="meta-label">入院时间:</span>
|
||||
<span class="meta-value">{{
|
||||
item.startTime ? formatDate(item.startTime) : '-'
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="meta-row">
|
||||
<span class="meta-label">入科时间:</span>
|
||||
<span class="meta-value">{{
|
||||
item.admissionTime ? formatDate(item.admissionTime) : '-'
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="doctor-parent-line" />
|
||||
|
||||
<div class="patient-card-body">
|
||||
<div class="personal-info-container">
|
||||
<div class="name-container">
|
||||
<div class="name">
|
||||
<el-text :text="item.patientName" tclass="name" width="auto">
|
||||
{{ item.patientName || '-' }}
|
||||
</el-text>
|
||||
</div>
|
||||
<div class="age">
|
||||
<el-tag
|
||||
size="small"
|
||||
class="age-tag"
|
||||
effect="plain"
|
||||
:class="{
|
||||
'age-tag-female': item.genderEnum_enumText === '女性',
|
||||
'age-tag-male': item.genderEnum_enumText === '男性',
|
||||
}"
|
||||
>
|
||||
{{ item.genderEnum_enumText || '-' }}
|
||||
<span v-if="item.age"> · {{ item.age }}</span>
|
||||
<span v-if="item.priorityEnum_enumText">
|
||||
· {{ item.priorityEnum_enumText }}</span
|
||||
>
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="meta"></div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
<el-empty v-else description="暂无数据" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { formatDate } from '@/utils/index';
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
list: any[];
|
||||
activeId?: string | number;
|
||||
idKey?: string;
|
||||
loading?: boolean;
|
||||
}>(),
|
||||
{
|
||||
list: () => [],
|
||||
activeId: '',
|
||||
idKey: 'id',
|
||||
loading: false,
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'item-click', item: any, index: number): void;
|
||||
(e: 'item-dblclick', item: any): void;
|
||||
(e: 'dragstart', event: DragEvent, item: any): void;
|
||||
(e: 'dragend', event: DragEvent): void;
|
||||
}>();
|
||||
|
||||
const getStatusClass = (item: any) => {
|
||||
if (item?.encounterStatus == 2) return 'status-tag--blue';
|
||||
if (item?.encounterStatus == 5) return 'status-tag--green';
|
||||
return '';
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss" name="PendingPatientList">
|
||||
.pending-patient-list {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
min-width: 240px;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.patient-cards {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
|
||||
:deep(.patient-cards-scrollbar) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.el-scrollbar__bar {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.patient-card {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||
box-shadow: 0 2px 6px 0 rgba(15, 35, 52, 0.12);
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px rgba(15, 35, 52, 0.18);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&.actived {
|
||||
background-color: rgba(7, 155, 140, 0.06);
|
||||
border-color: var(--el-color-primary);
|
||||
box-shadow: 0 0 0 1px rgba(7, 155, 140, 0.3), 0 4px 14px rgba(7, 155, 140, 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
.patient-card-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 12px 4px;
|
||||
|
||||
.header-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
.bed-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
|
||||
.bed {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
min-width: 0;
|
||||
|
||||
:deep(.bed-font) {
|
||||
color: #1f2933;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.payer-tag {
|
||||
max-width: 120px;
|
||||
font-size: 12px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.header-tags {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-end;
|
||||
gap: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-bottom {
|
||||
margin-top: 4px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
|
||||
.bus-no {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.doctor-parent-line {
|
||||
margin: 6px 12px 0;
|
||||
border-bottom: 1px dashed #e5e7eb;
|
||||
}
|
||||
|
||||
.patient-card-body {
|
||||
padding: 8px 12px 10px;
|
||||
}
|
||||
|
||||
.personal-info-container {
|
||||
display: block;
|
||||
|
||||
.name-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
|
||||
.name {
|
||||
color: #111827;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.age {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.age-tag {
|
||||
border-radius: 999px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.age-tag-female {
|
||||
border-color: rgb(255, 55, 158);
|
||||
color: rgb(255, 126, 184);
|
||||
}
|
||||
|
||||
.age-tag-male {
|
||||
border-color: #91d5ff;
|
||||
color: #1677ff;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
border-radius: 999px;
|
||||
padding: 0 8px;
|
||||
flex-shrink: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-tag--blue {
|
||||
border-color: #91d5ff;
|
||||
background-color: #1677ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.status-tag--green {
|
||||
border-color: #b7eb8f;
|
||||
background-color: #389e0d;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.meta {
|
||||
margin-top: 6px;
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.meta-row {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
338
openhis-ui-vue3/src/components/Print/AdvancePayment.json
Normal file
338
openhis-ui-vue3/src/components/Print/AdvancePayment.json
Normal file
@@ -0,0 +1,338 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 0,
|
||||
"name": 1,
|
||||
"paperType": "自定义",
|
||||
"height": 80,
|
||||
"width": 279,
|
||||
"paperList": {
|
||||
"type": "自定义",
|
||||
"width": 279,
|
||||
"height": 80
|
||||
},
|
||||
"panelPageRule": "none",
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 422.3622047244095,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.7,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "36px",
|
||||
"rotate": 25,
|
||||
"width": 413,
|
||||
"height": 310,
|
||||
"timestamp": true,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 15,
|
||||
"height": 16.5,
|
||||
"width": 792,
|
||||
"title": "长春市朝阳区中医院预交金收据",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontWeight": "bold",
|
||||
"letterSpacing": 0.75,
|
||||
"textAlign": "center",
|
||||
"qrCodeLevel": 0,
|
||||
"fontSize": 15,
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 46.5,
|
||||
"height": 14,
|
||||
"width": 151.5,
|
||||
"title": "姓名",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientName",
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 295.5,
|
||||
"top": 48,
|
||||
"height": 14,
|
||||
"width": 148.5,
|
||||
"title": "住院号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "encounterNosd",
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 480,
|
||||
"top": 48,
|
||||
"height": 14,
|
||||
"width": 162,
|
||||
"title": "科室",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "inHospitalOrgName",
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 73.5,
|
||||
"height": 14,
|
||||
"width": 153,
|
||||
"title": "ID号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientId",
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 295.5,
|
||||
"top": 73.5,
|
||||
"height": 14,
|
||||
"width": 147,
|
||||
"title": "医保类别",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "contractName",
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 480,
|
||||
"top": 73.5,
|
||||
"height": 14,
|
||||
"width": 163.5,
|
||||
"title": "时间",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "currentTime",
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 105,
|
||||
"height": 25,
|
||||
"width": 120,
|
||||
"title": "金额",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"textAlign": "center",
|
||||
"textContentVerticalAlign": "middle",
|
||||
"borderLeft": "solid",
|
||||
"borderTop": "solid",
|
||||
"borderRight": "solid",
|
||||
"borderBottom": "solid",
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 231,
|
||||
"top": 105,
|
||||
"height": 25,
|
||||
"width": 393,
|
||||
"title": "金额",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"textAlign": "center",
|
||||
"textContentVerticalAlign": "middle",
|
||||
"borderTop": "solid",
|
||||
"borderRight": "solid",
|
||||
"borderBottom": "solid",
|
||||
"qrCodeLevel": 0,
|
||||
"field": "balanceAmount",
|
||||
"hideTitle": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 129,
|
||||
"height": 30,
|
||||
"width": 120,
|
||||
"title": "人民币(大写)",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"textAlign": "center",
|
||||
"textContentVerticalAlign": "middle",
|
||||
"borderLeft": "solid",
|
||||
"borderTop": "solid",
|
||||
"borderRight": "solid",
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 231,
|
||||
"top": 129,
|
||||
"height": 30,
|
||||
"width": 393,
|
||||
"title": "金额",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"textAlign": "center",
|
||||
"textContentVerticalAlign": "middle",
|
||||
"borderTop": "solid",
|
||||
"borderRight": "solid",
|
||||
"qrCodeLevel": 0,
|
||||
"field": "amountInWords",
|
||||
"hideTitle": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 159,
|
||||
"height": 30,
|
||||
"width": 513,
|
||||
"title": " ",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"textAlign": "center",
|
||||
"textContentVerticalAlign": "middle",
|
||||
"borderLeft": "solid",
|
||||
"borderRight": "solid",
|
||||
"borderBottom": "solid",
|
||||
"qrCodeLevel": 0,
|
||||
"field": "paymentDetails",
|
||||
"hideTitle": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 198,
|
||||
"height": 14,
|
||||
"width": 120,
|
||||
"title": "签章",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientNamesfs",
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 297,
|
||||
"top": 198,
|
||||
"height": 14,
|
||||
"width": 132,
|
||||
"title": "交款人",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientNameada",
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 481.5,
|
||||
"top": 198,
|
||||
"height": 14,
|
||||
"width": 124.5,
|
||||
"title": "收款人",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "cashier",
|
||||
"fontFamily": "Microsoft YaHei"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
1692
openhis-ui-vue3/src/components/Print/DailyOutpatientSettlement.json
Normal file
1692
openhis-ui-vue3/src/components/Print/DailyOutpatientSettlement.json
Normal file
File diff suppressed because it is too large
Load Diff
454
openhis-ui-vue3/src/components/Print/Disposal copy.json
Normal file
454
openhis-ui-vue3/src/components/Print/Disposal copy.json
Normal file
@@ -0,0 +1,454 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 3,
|
||||
"paperType": "A5",
|
||||
"height": 210,
|
||||
"width": 148,
|
||||
"paperList": {
|
||||
"type": "A5",
|
||||
"width": 148,
|
||||
"height": 210
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 592.4409448818898,
|
||||
"orient": 1,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.01,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "10px",
|
||||
"rotate": 25,
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"timestamp": false,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 22.5,
|
||||
"height": 19.5,
|
||||
"width": 420,
|
||||
"title": "长春市朝阳区中医院",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 20.25,
|
||||
"qrCodeLevel": 0,
|
||||
"textAlign": "center",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 50,
|
||||
"height": 20,
|
||||
"width": 420,
|
||||
"title": "处置单",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 13.5,
|
||||
"textAlign": "center",
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 154.5,
|
||||
"top": 75,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "性别",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "genderEnum_enumText",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 288,
|
||||
"top": 75,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "年龄",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "age",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 76.5,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "姓名",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 288,
|
||||
"top": 100.5,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "开单医生",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 27,
|
||||
"top": 102,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "科室",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "departmentName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 154.5,
|
||||
"top": 102,
|
||||
"height": 13.5,
|
||||
"width": 120,
|
||||
"title": "费用性质",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "contractName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 130.5,
|
||||
"height": 13.5,
|
||||
"width": 174,
|
||||
"title": "门诊号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "encounterNo",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 222,
|
||||
"top": 130.5,
|
||||
"height": 13.5,
|
||||
"width": 165,
|
||||
"title": "日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "reqTime",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 156,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28,
|
||||
"top": 166.5,
|
||||
"height": 9.75,
|
||||
"width": 120,
|
||||
"title": "Rp",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true,
|
||||
"fontSize": 18,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 15,
|
||||
"top": 190.5,
|
||||
"height": 36,
|
||||
"width": 390,
|
||||
"title": "undefined+beforeDragIn",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"textAlign": "center",
|
||||
"tableBorder": "border",
|
||||
"tableHeaderFontWeight": "500",
|
||||
"field": "prescriptionList",
|
||||
"columns": [
|
||||
[
|
||||
{
|
||||
"title": "项目名",
|
||||
"width": 116.47241770689429,
|
||||
"field": "itemName",
|
||||
"checked": true,
|
||||
"columnId": "itemName",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "单价",
|
||||
"width": 95.6749835266735,
|
||||
"field": "unitPrice",
|
||||
"checked": true,
|
||||
"columnId": "unitPrice",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "数量",
|
||||
"width": 87.60415049837947,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "执行次数",
|
||||
"width": 90.24844826805275,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "表格",
|
||||
"type": "table",
|
||||
"editable": true,
|
||||
"columnDisplayEditable": true,
|
||||
"columnDisplayIndexEditable": true,
|
||||
"columnTitleEditable": true,
|
||||
"columnResizable": true,
|
||||
"columnAlignEditable": true,
|
||||
"isEnableEditField": true,
|
||||
"isEnableContextMenu": true,
|
||||
"isEnableInsertRow": true,
|
||||
"isEnableDeleteRow": true,
|
||||
"isEnableInsertColumn": true,
|
||||
"isEnableDeleteColumn": true,
|
||||
"isEnableMergeCell": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10.5,
|
||||
"top": 508.5,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "医师",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 509.0000066757202,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "发药:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 214.5,
|
||||
"top": 509.0000066757202,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "划价:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 319,
|
||||
"top": 509.0000066757202,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "调配:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 532.5,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 289,
|
||||
"top": 551.5,
|
||||
"height": 13.5,
|
||||
"width": 120,
|
||||
"title": "金额",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "medTotalAmount",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 236,
|
||||
"paperNumberTop": 573
|
||||
}
|
||||
]
|
||||
}
|
||||
454
openhis-ui-vue3/src/components/Print/Disposal.json
Normal file
454
openhis-ui-vue3/src/components/Print/Disposal.json
Normal file
@@ -0,0 +1,454 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 3,
|
||||
"paperType": "A5",
|
||||
"height": 210,
|
||||
"width": 148,
|
||||
"paperList": {
|
||||
"type": "A5",
|
||||
"width": 148,
|
||||
"height": 210
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 592.4409448818898,
|
||||
"orient": 1,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.01,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "10px",
|
||||
"rotate": 25,
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"timestamp": false,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 22.5,
|
||||
"height": 19.5,
|
||||
"width": 420,
|
||||
"title": "长春市红旗中医院",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 20.25,
|
||||
"qrCodeLevel": 0,
|
||||
"textAlign": "center",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 50,
|
||||
"height": 20,
|
||||
"width": 420,
|
||||
"title": "处置单",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 13.5,
|
||||
"textAlign": "center",
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 154.5,
|
||||
"top": 75,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "性别",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "genderEnum_enumText",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 288,
|
||||
"top": 75,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "年龄",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "age",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 76.5,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "姓名",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 288,
|
||||
"top": 100.5,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "开单医生",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 27,
|
||||
"top": 102,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "科室",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "departmentName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 154.5,
|
||||
"top": 102,
|
||||
"height": 13.5,
|
||||
"width": 120,
|
||||
"title": "费用性质",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "contractName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 130.5,
|
||||
"height": 13.5,
|
||||
"width": 174,
|
||||
"title": "门诊号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "encounterNo",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 222,
|
||||
"top": 130.5,
|
||||
"height": 13.5,
|
||||
"width": 165,
|
||||
"title": "日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "reqTime",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 156,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28,
|
||||
"top": 166.5,
|
||||
"height": 9.75,
|
||||
"width": 120,
|
||||
"title": "Rp",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true,
|
||||
"fontSize": 18,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 15,
|
||||
"top": 190.5,
|
||||
"height": 36,
|
||||
"width": 390,
|
||||
"title": "undefined+beforeDragIn",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"textAlign": "center",
|
||||
"tableBorder": "border",
|
||||
"tableHeaderFontWeight": "500",
|
||||
"field": "prescriptionList",
|
||||
"columns": [
|
||||
[
|
||||
{
|
||||
"title": "项目名",
|
||||
"width": 116.47241770689429,
|
||||
"field": "itemName",
|
||||
"checked": true,
|
||||
"columnId": "itemName",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "单价",
|
||||
"width": 95.6749835266735,
|
||||
"field": "unitPrice",
|
||||
"checked": true,
|
||||
"columnId": "unitPrice",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "数量",
|
||||
"width": 87.60415049837947,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "执行次数",
|
||||
"width": 90.24844826805275,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "表格",
|
||||
"type": "table",
|
||||
"editable": true,
|
||||
"columnDisplayEditable": true,
|
||||
"columnDisplayIndexEditable": true,
|
||||
"columnTitleEditable": true,
|
||||
"columnResizable": true,
|
||||
"columnAlignEditable": true,
|
||||
"isEnableEditField": true,
|
||||
"isEnableContextMenu": true,
|
||||
"isEnableInsertRow": true,
|
||||
"isEnableDeleteRow": true,
|
||||
"isEnableInsertColumn": true,
|
||||
"isEnableDeleteColumn": true,
|
||||
"isEnableMergeCell": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10.5,
|
||||
"top": 508.5,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "医师",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 509.0000066757202,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "发药:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 214.5,
|
||||
"top": 509.0000066757202,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "划价:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 319,
|
||||
"top": 509.0000066757202,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "调配:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 532.5,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 289,
|
||||
"top": 551.5,
|
||||
"height": 13.5,
|
||||
"width": 120,
|
||||
"title": "金额",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "medTotalAmount",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 236,
|
||||
"paperNumberTop": 573
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,701 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 3,
|
||||
"paperType": "A4",
|
||||
"height": 297,
|
||||
"width": 210,
|
||||
"paperList": {
|
||||
"type": "自定义",
|
||||
"width": 80,
|
||||
"height": 60
|
||||
},
|
||||
"paperHeader": 166.5,
|
||||
"paperFooter": 760.5,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"expandCss": "",
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.7,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "36px",
|
||||
"rotate": 25,
|
||||
"width": 413,
|
||||
"height": 310,
|
||||
"timestamp": true,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 22.5,
|
||||
"height": 19.5,
|
||||
"width": 595.5,
|
||||
"title": "长春市朝阳区中医院",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 20.25,
|
||||
"qrCodeLevel": 0,
|
||||
"textAlign": "center"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 54.5,
|
||||
"height": 20,
|
||||
"width": 595.5,
|
||||
"title": "门诊病历",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 13.5,
|
||||
"textAlign": "center",
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 235.5,
|
||||
"top": 81,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "性别",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "genderEnum_enumText"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 429,
|
||||
"top": 81,
|
||||
"height": 13.5,
|
||||
"width": 160.5,
|
||||
"title": "年龄",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "age"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 24,
|
||||
"top": 82.5,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "姓名",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 24,
|
||||
"top": 108,
|
||||
"height": 13.5,
|
||||
"width": 190.5,
|
||||
"title": "电话",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "phone"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 235.5,
|
||||
"top": 108,
|
||||
"height": 13.5,
|
||||
"width": 175.5,
|
||||
"title": "医保类型",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "contractName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 429,
|
||||
"top": 108,
|
||||
"height": 13.5,
|
||||
"width": 162,
|
||||
"title": "病历号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "busNo"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 24,
|
||||
"top": 132,
|
||||
"height": 13.5,
|
||||
"width": 200,
|
||||
"title": "就诊日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "onsetDate"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 235.5,
|
||||
"top": 132,
|
||||
"height": 13.5,
|
||||
"width": 175.5,
|
||||
"title": "就诊科室",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 429,
|
||||
"top": 132,
|
||||
"height": 13.5,
|
||||
"width": 162,
|
||||
"title": "接诊医生",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 163.5,
|
||||
"height": 9,
|
||||
"width": 576,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 171,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "主诉",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 187.5,
|
||||
"height": 33,
|
||||
"width": 550,
|
||||
"title": " ",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "complaint",
|
||||
"lHeight": 50
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 231,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "现病史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 253,
|
||||
"height": 42,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "presentIllness",
|
||||
"title": "无",
|
||||
"lHeight": 30
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 305,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "既往史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 324,
|
||||
"height": 30,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "pastIllness",
|
||||
"title": "无",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 366,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "过敏史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 384,
|
||||
"height": 22.5,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "allergyHistory",
|
||||
"title": "无",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 412.5,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "家族史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 432,
|
||||
"height": 22.5,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "familyHistory",
|
||||
"title": "无",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 465,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "个人史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 486,
|
||||
"height": 28.5,
|
||||
"width": 550,
|
||||
"title": " ",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "personalHistory",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 522.2500162124634,
|
||||
"height": 13.5,
|
||||
"width": 82.5,
|
||||
"title": "体格检查",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 544.7500162124634,
|
||||
"height": 30,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"title": "长文",
|
||||
"lHeight": 20,
|
||||
"formatter": "function(title, value, options, templateData, target, paperNo) {\n // 获取所有体检数据\n const bloodHigh = templateData.bloodHigh || '';\n const bloodLow = templateData.bloodLow || '';\n const breathe = templateData.breathe || '';\n const temperature = templateData.temperature || '';\n const pulse = templateData.pulse || '';\n \n // 格式化每个字段\n \n let formattedTemperature = '';\n if (temperature && !isNaN(temperature)) {\n formattedTemperature = 'T:' + temperature + '℃';\n }\n \n let formattedPulse = '';\n if (pulse && !isNaN(pulse)) {\n formattedPulse = 'P:' + pulse + '次/分';\n }\n let formattedR = '';\n if (breathe && !isNaN(breathe)) {\n formattedR = 'R:' + breathe + '次/分';\n }\n \n let formattedBP = '';\n if (bloodHigh && !isNaN(bloodHigh)) {\n formattedBP = 'BP:' + bloodHigh +'/'+bloodLow+ 'mmHg';\n }\n \n \n // 组合所有信息\n const result = [\n formattedR,\n formattedBP,\n formattedTemperature,\n formattedPulse\n ].filter(item => item !== '').join(' ');\n \n return result;\n}\n\n"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 582,
|
||||
"height": 13.5,
|
||||
"width": 79.5,
|
||||
"title": "辅助检查",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 601.5,
|
||||
"height": 30,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "auxiliaryExam",
|
||||
"title": "长文",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 640.5,
|
||||
"height": 13.5,
|
||||
"width": 79.5,
|
||||
"title": "诊断",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 661.5,
|
||||
"height": 28.5,
|
||||
"width": 550,
|
||||
"title": "无",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "diagnosisText",
|
||||
"lHeight": 30
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 694.7431640625,
|
||||
"height": 13.5,
|
||||
"width": 79.5,
|
||||
"title": "处置",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 720,
|
||||
"height": 28.5,
|
||||
"width": 550,
|
||||
"title": "无",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "treatment",
|
||||
"lHeight": 30
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 9,
|
||||
"top": 766.5,
|
||||
"height": 9,
|
||||
"width": 576,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28.5,
|
||||
"top": 787.5,
|
||||
"height": 13.5,
|
||||
"width": 223.5,
|
||||
"title": "医生签字:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 399,
|
||||
"top": 787.5,
|
||||
"height": 13.5,
|
||||
"width": 186,
|
||||
"title": "日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true,
|
||||
"field": "reqTime"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28.5,
|
||||
"top": 810,
|
||||
"height": 19.5,
|
||||
"width": 556.5,
|
||||
"title": "为了您和家人的健康,请勿吸烟!如需戒烟帮助,请到戒烟干预室咨询。",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true,
|
||||
"fontSize": 12,
|
||||
"letterSpacing": 1.5,
|
||||
"textAlign": "center"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 236,
|
||||
"paperNumberTop": 573
|
||||
}
|
||||
]
|
||||
}
|
||||
599
openhis-ui-vue3/src/components/Print/MedicinePrescription.json
Normal file
599
openhis-ui-vue3/src/components/Print/MedicinePrescription.json
Normal file
@@ -0,0 +1,599 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 3,
|
||||
"paperType": "A5",
|
||||
"height": 210,
|
||||
"width": 148,
|
||||
"paperList": {
|
||||
"type": "A5",
|
||||
"width": 148,
|
||||
"height": 210
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 592.4409448818898,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"expandCss": "",
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.01,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "10px",
|
||||
"rotate": 0,
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"timestamp": false,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 22.5,
|
||||
"height": 19.5,
|
||||
"width": 420,
|
||||
"title": "长春市朝阳区中医院",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 20.25,
|
||||
"qrCodeLevel": 0,
|
||||
"textAlign": "center",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 50,
|
||||
"height": 20,
|
||||
"width": 420,
|
||||
"title": "处方签",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 13.5,
|
||||
"textAlign": "center",
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 26,
|
||||
"top": 90,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "医保编号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 283,
|
||||
"top": 90,
|
||||
"height": 13.5,
|
||||
"width": 117,
|
||||
"title": "就诊类型",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "orgId_dictText",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 26,
|
||||
"top": 117,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "处方编号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "prescriptionNo",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 283,
|
||||
"top": 117,
|
||||
"height": 13.5,
|
||||
"width": 117,
|
||||
"title": "病人性质",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "contractName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 138,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 160.5,
|
||||
"top": 153,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "性别",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "genderEnum_enumText",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 288,
|
||||
"top": 153,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "年龄",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "age"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 26,
|
||||
"top": 154.5,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "姓名",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 27,
|
||||
"top": 177,
|
||||
"height": 13.5,
|
||||
"width": 132,
|
||||
"title": "地址:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 160.5,
|
||||
"top": 178.5,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "科室",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "departmentName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 288,
|
||||
"top": 178.5,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "电话",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 205.5,
|
||||
"height": 13.5,
|
||||
"width": 189,
|
||||
"title": "门诊号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "encounterNo"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 219,
|
||||
"top": 205.5,
|
||||
"height": 13.5,
|
||||
"width": 198,
|
||||
"title": "开具日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "reqTime"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 232.5,
|
||||
"height": 13.5,
|
||||
"width": 381,
|
||||
"title": "临床诊断",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "conditionName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 256.5,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28,
|
||||
"top": 282,
|
||||
"height": 9.75,
|
||||
"width": 120,
|
||||
"title": "Rp",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true,
|
||||
"fontSize": 18,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 15,
|
||||
"top": 306,
|
||||
"height": 36,
|
||||
"width": 390,
|
||||
"title": "undefined+beforeDragIn",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"textAlign": "center",
|
||||
"tableBorder": "border",
|
||||
"tableHeaderFontWeight": "500",
|
||||
"field": "prescriptionList",
|
||||
"columns": [
|
||||
[
|
||||
{
|
||||
"title": "名称",
|
||||
"width": 55.386224315781,
|
||||
"field": "itemName",
|
||||
"checked": true,
|
||||
"columnId": "itemName",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "规格",
|
||||
"width": 59.41840807183531,
|
||||
"field": "totalVolume",
|
||||
"checked": true,
|
||||
"columnId": "totalVolume",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "产地",
|
||||
"width": 79.59183673469389,
|
||||
"field": "manufacturerText",
|
||||
"checked": true,
|
||||
"columnId": "manufacturerText",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "单价",
|
||||
"width": 45.49640338326492,
|
||||
"field": "unitPrice",
|
||||
"checked": true,
|
||||
"columnId": "unitPrice",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "数量",
|
||||
"width": 41.658473534111906,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "金额",
|
||||
"width": 42.9159186212175,
|
||||
"field": "totalPrice",
|
||||
"checked": true,
|
||||
"columnId": "totalPrice",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "等级",
|
||||
"width": 65.53273533909551,
|
||||
"field": "contractName",
|
||||
"checked": true,
|
||||
"columnId": "contractName",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "表格",
|
||||
"type": "table",
|
||||
"editable": true,
|
||||
"columnDisplayEditable": true,
|
||||
"columnDisplayIndexEditable": true,
|
||||
"columnTitleEditable": true,
|
||||
"columnResizable": true,
|
||||
"columnAlignEditable": true,
|
||||
"isEnableEditField": true,
|
||||
"isEnableContextMenu": true,
|
||||
"isEnableInsertRow": true,
|
||||
"isEnableDeleteRow": true,
|
||||
"isEnableInsertColumn": true,
|
||||
"isEnableDeleteColumn": true,
|
||||
"isEnableMergeCell": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 379.5,
|
||||
"height": 13.5,
|
||||
"width": 241.5,
|
||||
"title": "用法",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 18,
|
||||
"top": 513,
|
||||
"height": 13.5,
|
||||
"width": 80,
|
||||
"title": "医师",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 124.5,
|
||||
"top": 513,
|
||||
"height": 13.5,
|
||||
"width": 80,
|
||||
"title": "发药",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 222,
|
||||
"top": 513,
|
||||
"height": 13.5,
|
||||
"width": 80,
|
||||
"title": "划价",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 310.5,
|
||||
"top": 513,
|
||||
"height": 13.5,
|
||||
"width": 80,
|
||||
"title": "调配",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 532.5,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 289,
|
||||
"top": 551.5,
|
||||
"height": 13.5,
|
||||
"width": 120,
|
||||
"title": "总金额",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "medTotalAmount"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 236,
|
||||
"paperNumberTop": 573
|
||||
}
|
||||
]
|
||||
}
|
||||
407
openhis-ui-vue3/src/components/Print/OperativeRecord.json
Normal file
407
openhis-ui-vue3/src/components/Print/OperativeRecord.json
Normal file
@@ -0,0 +1,407 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 3,
|
||||
"paperType": "A4",
|
||||
"height": 297,
|
||||
"width": 210,
|
||||
"paperList": {
|
||||
"type": "A4",
|
||||
"width": 210,
|
||||
"height": 297
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 837,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"expandCss": "",
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.7,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "36px",
|
||||
"rotate": 25,
|
||||
"width": 413,
|
||||
"height": 310,
|
||||
"timestamp": true,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 22.5,
|
||||
"height": 19.5,
|
||||
"width": 595.5,
|
||||
"title": "长春市朝阳区中医院",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 20.25,
|
||||
"qrCodeLevel": 0,
|
||||
"textAlign": "center"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 54.5,
|
||||
"height": 20,
|
||||
"width": 595.5,
|
||||
"title": "手术记录",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 13.5,
|
||||
"textAlign": "center",
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 247.5,
|
||||
"top": 81,
|
||||
"height": 13.5,
|
||||
"width": 190.5,
|
||||
"title": "性别",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "genderEnum_enumText"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 460.5,
|
||||
"top": 81,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "年龄",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "age"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 82.5,
|
||||
"height": 13.5,
|
||||
"width": 193.5,
|
||||
"title": "姓名",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 108,
|
||||
"height": 13.5,
|
||||
"width": 192,
|
||||
"title": "医保",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "contractName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 247.5,
|
||||
"top": 108,
|
||||
"height": 13.5,
|
||||
"width": 190.5,
|
||||
"title": "电话",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "phone"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 460.5,
|
||||
"top": 108,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "医生",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 460.5,
|
||||
"top": 132.99999618530273,
|
||||
"height": 13.5,
|
||||
"width": 124.5,
|
||||
"title": "科室",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "department"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 133.5,
|
||||
"height": 13.5,
|
||||
"width": 196.5,
|
||||
"title": "病历号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "busNo"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 247.5,
|
||||
"top": 133.5,
|
||||
"height": 13.5,
|
||||
"width": 200,
|
||||
"title": "手术日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "operationDate"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 157.5,
|
||||
"height": 61.5,
|
||||
"width": 550.5,
|
||||
"title": "诊断",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "busNosds"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 226.5,
|
||||
"height": 9,
|
||||
"width": 576,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 250.5,
|
||||
"height": 13.5,
|
||||
"width": 81,
|
||||
"title": "详细记录",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 271.5,
|
||||
"height": 493.5,
|
||||
"width": 550,
|
||||
"title": " ",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "surgicalDetails",
|
||||
"lHeight": 60,
|
||||
"formatter": "function(title, value, options, templateData, target, paperNo) {\n // 返回原始值,让组件自动处理高度\n return value;\n}",
|
||||
"styler": "function(value, options, target, templateData, paperNo) {\n return { \n 'word-wrap': 'break-word',\n 'word-break': 'break-all',\n 'white-space': 'normal',\n 'line-height': '1.4',\n 'overflow': 'visible'\n };\n}"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 9,
|
||||
"top": 774,
|
||||
"height": 9,
|
||||
"width": 576,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28.5,
|
||||
"top": 787.5,
|
||||
"height": 13.5,
|
||||
"width": 223.5,
|
||||
"title": "病人或家人签字:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 399,
|
||||
"top": 787.5,
|
||||
"height": 13.5,
|
||||
"width": 186,
|
||||
"title": "医生签字:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 399,
|
||||
"top": 811.5,
|
||||
"height": 13.5,
|
||||
"width": 186,
|
||||
"title": "日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "reqTime",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28.5,
|
||||
"top": 813,
|
||||
"height": 13.5,
|
||||
"width": 222,
|
||||
"title": "日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "reqTime",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 236,
|
||||
"paperNumberTop": 573
|
||||
}
|
||||
]
|
||||
}
|
||||
733
openhis-ui-vue3/src/components/Print/OutpatientBilling.json
Normal file
733
openhis-ui-vue3/src/components/Print/OutpatientBilling.json
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,290 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 2,
|
||||
"paperType": "自定义",
|
||||
"height": 60,
|
||||
"width": 80,
|
||||
"paperList": {
|
||||
"type": "自定义",
|
||||
"width": 80,
|
||||
"height": 60
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 166.5,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.7,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "36px",
|
||||
"rotate": 25,
|
||||
"width": 413,
|
||||
"height": 310,
|
||||
"timestamp": true,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 6,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 69,
|
||||
"title": "病区",
|
||||
"field": "patientName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 81,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 52.5,
|
||||
"title": "姓名",
|
||||
"field": "patientName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 147,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 72,
|
||||
"title": "床位号",
|
||||
"field": "bedNo",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 6,
|
||||
"top": 22,
|
||||
"height": 12,
|
||||
"width": 81,
|
||||
"title": "频次 qd",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"fontSize": 8.25,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 147,
|
||||
"top": 24,
|
||||
"height": 10,
|
||||
"width": 70.5,
|
||||
"title": "日期",
|
||||
"field": "date",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 4.5,
|
||||
"top": 45,
|
||||
"height": 30,
|
||||
"width": 216,
|
||||
"title": "undefined+beforeDragIn",
|
||||
"field": "infuseData",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"tableHeaderBackground": "#ffffff",
|
||||
"tableBodyCellBorder": "noBorder",
|
||||
"rowsColumnsMerge": "function(data, col, colIndex, rowIndex, tableData, printData){ \n // 合并前三列 (columnIndex 0-2)\n if (colIndex >= 0 && colIndex <= 2) {\n // 第一列显示合并后的单元格\n if (colIndex === 0) {\n return [1, 3]; // rowspan=1, colspan=3\n } \n // 其他两列不显示(被合并)\n else {\n return [0, 0]; // rowspan=0, colspan=0\n }\n }\n // 其他列正常显示\n return [1, 1]; // rowspan=1, colspan=1\n}",
|
||||
"tableBodyRowBorder": "topBottomBorder",
|
||||
"fontSize": 7.5,
|
||||
"tableHeaderRepeat": "first",
|
||||
"maxRows": 3,
|
||||
"tableHeaderRowHeight": 6,
|
||||
"tableHeaderFontSize": 6.75,
|
||||
"columns": [
|
||||
[
|
||||
{
|
||||
"title": "用法",
|
||||
"titleSync": false,
|
||||
"halign": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 51.988373079128756,
|
||||
"field": "data",
|
||||
"checked": true,
|
||||
"columnId": "data",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "剂量",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 55.016471480350916,
|
||||
"checked": true,
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "滴速",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 55.31961796101854,
|
||||
"field": "",
|
||||
"checked": true,
|
||||
"columnId": "",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "数量",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"formatter2": "function(value,row,index,options,rowIndex,column){ return value + ' ' + row.unitCode_dictText; }",
|
||||
"width": 53.6755374795018,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "表格",
|
||||
"type": "table",
|
||||
"editable": true,
|
||||
"columnDisplayEditable": true,
|
||||
"columnDisplayIndexEditable": true,
|
||||
"columnTitleEditable": true,
|
||||
"columnResizable": true,
|
||||
"columnAlignEditable": true,
|
||||
"isEnableEditField": true,
|
||||
"isEnableContextMenu": true,
|
||||
"isEnableInsertRow": true,
|
||||
"isEnableDeleteRow": true,
|
||||
"isEnableInsertColumn": true,
|
||||
"isEnableDeleteColumn": true,
|
||||
"isEnableMergeCell": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 144,
|
||||
"height": 9,
|
||||
"width": 210,
|
||||
"borderWidth": "0.75",
|
||||
"title": "undefined+beforeDragIn",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 153,
|
||||
"height": 9.75,
|
||||
"width": 82.5,
|
||||
"title": "执行人",
|
||||
"field": "prepareName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 153,
|
||||
"height": 9.75,
|
||||
"width": 82.5,
|
||||
"title": "时间",
|
||||
"field": "date",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 151.5,
|
||||
"paperNumberTop": 91
|
||||
}
|
||||
]
|
||||
}
|
||||
245
openhis-ui-vue3/src/components/Print/OutpatientInfusion.json
Normal file
245
openhis-ui-vue3/src/components/Print/OutpatientInfusion.json
Normal file
@@ -0,0 +1,245 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 2,
|
||||
"paperType": "自定义",
|
||||
"height": 34,
|
||||
"width": 58,
|
||||
"paperList": {
|
||||
"type": "自定义",
|
||||
"width": 60,
|
||||
"height": 40
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 91.5,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"expandCss": "",
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.01,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "10px",
|
||||
"rotate": 25,
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"timestamp": false,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 6,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 51,
|
||||
"title": "文本",
|
||||
"field": "patientName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 70,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 33,
|
||||
"title": "文本",
|
||||
"field": "genderEnum_enumText",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 119,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 45,
|
||||
"title": "文本",
|
||||
"field": "age",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold",
|
||||
"textAlign": "right"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 6,
|
||||
"top": 19.5,
|
||||
"height": 12,
|
||||
"width": 81,
|
||||
"title": "频次 qd",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"fontSize": 8.25,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 93,
|
||||
"top": 19.5,
|
||||
"height": 10,
|
||||
"width": 70.5,
|
||||
"title": "文本",
|
||||
"field": "date",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold",
|
||||
"textAlign": "right"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 4.5,
|
||||
"top": 36,
|
||||
"height": 30,
|
||||
"width": 156,
|
||||
"title": "undefined+beforeDragIn",
|
||||
"field": "infuseData",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"tableHeaderBackground": "#ffffff",
|
||||
"tableBodyCellBorder": "noBorder",
|
||||
"rowsColumnsMerge": "function(data, col, colIndex, rowIndex, tableData, printData){ \n // 合并前三列 (columnIndex 0-2)\n if (colIndex >= 0 && colIndex <= 2) {\n // 第一列显示合并后的单元格\n if (colIndex === 0) {\n return [1, 3]; // rowspan=1, colspan=3\n } \n // 其他两列不显示(被合并)\n else {\n return [0, 0]; // rowspan=0, colspan=0\n }\n }\n // 其他列正常显示\n return [1, 1]; // rowspan=1, colspan=1\n}",
|
||||
"tableBodyRowBorder": "topBottomBorder",
|
||||
"fontSize": 7.5,
|
||||
"tableHeaderRepeat": "first",
|
||||
"maxRows": 3,
|
||||
"tableHeaderRowHeight": 6,
|
||||
"tableHeaderFontSize": 6.75,
|
||||
"columns": [
|
||||
[
|
||||
{
|
||||
"title": "用法",
|
||||
"titleSync": false,
|
||||
"halign": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 37.54715833492632,
|
||||
"field": "data",
|
||||
"checked": true,
|
||||
"columnId": "data",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "剂量",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 39.4492016246979,
|
||||
"checked": true,
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "速度",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 40.23797408295783,
|
||||
"checked": true,
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "数量",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"formatter2": "function(value,row,index,options,rowIndex,column){ return value + ' ' + row.unitCode_dictText; }",
|
||||
"width": 38.765665957417966,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "表格",
|
||||
"type": "table",
|
||||
"editable": true,
|
||||
"columnDisplayEditable": true,
|
||||
"columnDisplayIndexEditable": true,
|
||||
"columnTitleEditable": true,
|
||||
"columnResizable": true,
|
||||
"columnAlignEditable": true,
|
||||
"isEnableEditField": true,
|
||||
"isEnableContextMenu": true,
|
||||
"isEnableInsertRow": true,
|
||||
"isEnableDeleteRow": true,
|
||||
"isEnableInsertColumn": true,
|
||||
"isEnableDeleteColumn": true,
|
||||
"isEnableMergeCell": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 151.5,
|
||||
"paperNumberTop": 91
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,734 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 3,
|
||||
"paperType": "A4",
|
||||
"height": 297,
|
||||
"width": 210,
|
||||
"paperList": {
|
||||
"type": "A4",
|
||||
"width": 210,
|
||||
"height": 297
|
||||
},
|
||||
"paperHeader": 217.5,
|
||||
"paperFooter": 771,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.7,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "36px",
|
||||
"rotate": 25,
|
||||
"width": 413,
|
||||
"height": 310,
|
||||
"timestamp": true,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 22.5,
|
||||
"height": 19.5,
|
||||
"width": 595.5,
|
||||
"title": "长春市朝阳区中医院",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 20.25,
|
||||
"qrCodeLevel": 0,
|
||||
"textAlign": "center"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 54.5,
|
||||
"height": 20,
|
||||
"width": 595.5,
|
||||
"title": "门诊病历",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 13.5,
|
||||
"textAlign": "center",
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 247.5,
|
||||
"top": 81,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "性别",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "genderEnum_enumText"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 460.5,
|
||||
"top": 81,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "年龄",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "age"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 82.5,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "姓名",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 108,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "医保",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "contractName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 247.5,
|
||||
"top": 108,
|
||||
"height": 13.5,
|
||||
"width": 190.5,
|
||||
"title": "电话",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "phone"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 460.5,
|
||||
"top": 108,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "医生",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 133.5,
|
||||
"height": 13.5,
|
||||
"width": 196.5,
|
||||
"title": "病历号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "busNo"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 247.5,
|
||||
"top": 133.5,
|
||||
"height": 13.5,
|
||||
"width": 200,
|
||||
"title": "发病日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "onsetDate"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 159,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "诊断",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "vxc"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 174,
|
||||
"height": 30,
|
||||
"width": 550,
|
||||
"hideTitle": true,
|
||||
"field": "diagnosisText",
|
||||
"title": "无",
|
||||
"lHeight": 20,
|
||||
"formatter": "function(title, value, options, templateData, target, paperNo) {\n return value || '无';\n}",
|
||||
"styler": "function(value, options, target, templateData, paperNo) {\n return { \n 'word-wrap': 'break-word',\n 'word-break': 'break-all',\n 'white-space': 'normal',\n 'line-height': '1.4'\n };\n}",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 210,
|
||||
"height": 9,
|
||||
"width": 576,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 217.5,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "主诉",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 235.5,
|
||||
"height": 33,
|
||||
"width": 550,
|
||||
"title": " ",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "complaint",
|
||||
"lHeight": 50
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 277.5,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "现病史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 299.5,
|
||||
"height": 31.5,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "presentIllness",
|
||||
"title": "无",
|
||||
"lHeight": 30
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 341,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "既往史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 360,
|
||||
"height": 25.5,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "pastIllness",
|
||||
"title": "无",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 396,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "过敏史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 414,
|
||||
"height": 33,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "allergyHistory",
|
||||
"title": "无",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 462,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "家族史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 481.5,
|
||||
"height": 22.5,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "familyHistory",
|
||||
"title": "无",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 514.5,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "个人史",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 535.5,
|
||||
"height": 28.5,
|
||||
"width": 550,
|
||||
"title": " ",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "personalHistory",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 571.7500162124634,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "体检",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 594.2500162124634,
|
||||
"height": 30,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"title": "长文",
|
||||
"lHeight": 20,
|
||||
"formatter": "function(title, value, options, templateData, target, paperNo) {\n // 获取所有体检数据\n const height = templateData.height || '';\n const weight = templateData.weight || '';\n const temperature = templateData.temperature || '';\n const pulse = templateData.pulse || '';\n \n // 格式化每个字段\n let formattedHeight = '';\n if (height && !isNaN(height)) {\n formattedHeight = '身高:' + height + 'cm';\n }\n \n let formattedWeight = '';\n if (weight && !isNaN(weight)) {\n formattedWeight = '体重:' + weight + 'kg';\n }\n \n let formattedTemperature = '';\n if (temperature && !isNaN(temperature)) {\n formattedTemperature = '体温:' + temperature + '℃';\n }\n \n let formattedPulse = '';\n if (pulse && !isNaN(pulse)) {\n formattedPulse = '脉搏:' + pulse + '次/分';\n }\n \n // 组合所有信息\n const result = [\n formattedHeight,\n formattedWeight,\n formattedTemperature,\n formattedPulse\n ].filter(item => item !== '').join(' ');\n \n return result;\n}\n\n"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 631.5,
|
||||
"height": 13.5,
|
||||
"width": 79.5,
|
||||
"title": "辅助检查",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 651,
|
||||
"height": 22.5,
|
||||
"width": 550,
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "auxiliaryExam",
|
||||
"title": "长文",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 678.2431640625,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "处置",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 700.5,
|
||||
"height": 21,
|
||||
"width": 550,
|
||||
"title": "无",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "treatment",
|
||||
"lHeight": 30
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 730,
|
||||
"height": 13.5,
|
||||
"width": 50,
|
||||
"title": "治疗",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "physicalExamdsd",
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 747,
|
||||
"height": 25.5,
|
||||
"width": 550,
|
||||
"title": "无",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"hideTitle": true,
|
||||
"field": "physicalExam",
|
||||
"lHeight": 20
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "长文",
|
||||
"type": "longText"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 9,
|
||||
"top": 774,
|
||||
"height": 9,
|
||||
"width": 576,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28.5,
|
||||
"top": 787.5,
|
||||
"height": 13.5,
|
||||
"width": 223.5,
|
||||
"title": "病人或家人签字:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 399,
|
||||
"top": 787.5,
|
||||
"height": 13.5,
|
||||
"width": 186,
|
||||
"title": "医生签字:",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 399,
|
||||
"top": 811.5,
|
||||
"height": 13.5,
|
||||
"width": 186,
|
||||
"title": "日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "reqTime"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28.5,
|
||||
"top": 813,
|
||||
"height": 13.5,
|
||||
"width": 222,
|
||||
"title": "日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "reqTime"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 236,
|
||||
"paperNumberTop": 573
|
||||
}
|
||||
]
|
||||
}
|
||||
717
openhis-ui-vue3/src/components/Print/OutpatientRegistration.json
Normal file
717
openhis-ui-vue3/src/components/Print/OutpatientRegistration.json
Normal file
File diff suppressed because one or more lines are too long
1174
openhis-ui-vue3/src/components/Print/Pharmacy copy 2.json
Normal file
1174
openhis-ui-vue3/src/components/Print/Pharmacy copy 2.json
Normal file
File diff suppressed because it is too large
Load Diff
1176
openhis-ui-vue3/src/components/Print/Pharmacy copy.json
Normal file
1176
openhis-ui-vue3/src/components/Print/Pharmacy copy.json
Normal file
File diff suppressed because it is too large
Load Diff
1175
openhis-ui-vue3/src/components/Print/Pharmacy.json
Normal file
1175
openhis-ui-vue3/src/components/Print/Pharmacy.json
Normal file
File diff suppressed because it is too large
Load Diff
632
openhis-ui-vue3/src/components/Print/Prescription.json
Normal file
632
openhis-ui-vue3/src/components/Print/Prescription.json
Normal file
@@ -0,0 +1,632 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 3,
|
||||
"paperType": "A5",
|
||||
"height": 210,
|
||||
"width": 148,
|
||||
"paperList": {
|
||||
"type": "A5",
|
||||
"width": 148,
|
||||
"height": 210
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 592.4409448818898,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.01,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "10px",
|
||||
"rotate": 0,
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"timestamp": false,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 22.5,
|
||||
"height": 19.5,
|
||||
"width": 420,
|
||||
"title": "长春市朝阳区中医院",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 20.25,
|
||||
"qrCodeLevel": 0,
|
||||
"textAlign": "center",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 0,
|
||||
"top": 50,
|
||||
"height": 20,
|
||||
"width": 420,
|
||||
"title": "处方签",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 13.5,
|
||||
"textAlign": "center",
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 26,
|
||||
"top": 90,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "医保编号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 283,
|
||||
"top": 90,
|
||||
"height": 13.5,
|
||||
"width": 117,
|
||||
"title": "就诊类型",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "orgId_dictText",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 26,
|
||||
"top": 117,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "处方编号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "prescriptionNo",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 283,
|
||||
"top": 117,
|
||||
"height": 13.5,
|
||||
"width": 117,
|
||||
"title": "病人性质",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "contractName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 138,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 142.5,
|
||||
"top": 153,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "性别",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "genderEnum_enumText",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 288,
|
||||
"top": 153,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "年龄",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "age",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 26,
|
||||
"top": 154.5,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "姓名",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "patientName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 142.5,
|
||||
"top": 178.5,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "科室",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "departmentName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 288,
|
||||
"top": 178.5,
|
||||
"height": 13.5,
|
||||
"width": 99,
|
||||
"title": "电话",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 180,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "门诊号",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "encounterNo",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 205.5,
|
||||
"height": 13.5,
|
||||
"width": 141,
|
||||
"title": "地址",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 195,
|
||||
"top": 205.5,
|
||||
"height": 13.5,
|
||||
"width": 210,
|
||||
"title": "开具日期",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "reqTime",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 232.5,
|
||||
"height": 13.5,
|
||||
"width": 367.5,
|
||||
"title": "临床诊断",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "conditionName"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 256.5,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 28,
|
||||
"top": 282,
|
||||
"height": 9.75,
|
||||
"width": 120,
|
||||
"title": "Rp",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true,
|
||||
"fontSize": 18,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 15,
|
||||
"top": 306,
|
||||
"height": 36,
|
||||
"width": 390,
|
||||
"title": "undefined+beforeDragIn",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"textAlign": "center",
|
||||
"tableBorder": "border",
|
||||
"tableHeaderFontWeight": "500",
|
||||
"field": "prescriptionList",
|
||||
"columns": [
|
||||
[
|
||||
{
|
||||
"title": "名称",
|
||||
"width": 55.386224315781,
|
||||
"field": "itemName",
|
||||
"checked": true,
|
||||
"columnId": "itemName",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "规格",
|
||||
"width": 59.41840807183531,
|
||||
"field": "totalVolume",
|
||||
"checked": true,
|
||||
"columnId": "totalVolume",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "厂家",
|
||||
"width": 79.59183673469389,
|
||||
"checked": true,
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "单价",
|
||||
"width": 45.49640338326492,
|
||||
"field": "unitPrice",
|
||||
"checked": true,
|
||||
"columnId": "unitPrice",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "数量",
|
||||
"width": 41.658473534111906,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "金额",
|
||||
"width": 42.9159186212175,
|
||||
"field": "totalPrice",
|
||||
"checked": true,
|
||||
"columnId": "totalPrice",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "等级",
|
||||
"width": 65.53273533909551,
|
||||
"field": "contractName",
|
||||
"checked": true,
|
||||
"columnId": "contractName",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "表格",
|
||||
"type": "table",
|
||||
"editable": true,
|
||||
"columnDisplayEditable": true,
|
||||
"columnDisplayIndexEditable": true,
|
||||
"columnTitleEditable": true,
|
||||
"columnResizable": true,
|
||||
"columnAlignEditable": true,
|
||||
"isEnableEditField": true,
|
||||
"isEnableContextMenu": true,
|
||||
"isEnableInsertRow": true,
|
||||
"isEnableDeleteRow": true,
|
||||
"isEnableInsertColumn": true,
|
||||
"isEnableDeleteColumn": true,
|
||||
"isEnableMergeCell": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 25.5,
|
||||
"top": 379.5,
|
||||
"height": 13.5,
|
||||
"width": 241.5,
|
||||
"title": "用法",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 8.996109008789062,
|
||||
"top": 510,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "医师",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "doctorName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 113,
|
||||
"top": 510,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "发药",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 217,
|
||||
"top": 510,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "划价",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 318,
|
||||
"top": 510,
|
||||
"height": 13.5,
|
||||
"width": 100,
|
||||
"title": "调配",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "nickName",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 532.5,
|
||||
"height": 9,
|
||||
"width": 400,
|
||||
"borderWidth": "1.5",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 26,
|
||||
"top": 551.5,
|
||||
"height": 13.5,
|
||||
"width": 120,
|
||||
"title": "制表人",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "1",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 289,
|
||||
"top": 551.5,
|
||||
"height": 13.5,
|
||||
"width": 120,
|
||||
"title": "金额",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 12,
|
||||
"qrCodeLevel": 0,
|
||||
"field": "medTotalAmount",
|
||||
"fixed": true
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 236,
|
||||
"paperNumberTop": 573
|
||||
}
|
||||
]
|
||||
}
|
||||
14
openhis-ui-vue3/src/components/Print/README.md
Normal file
14
openhis-ui-vue3/src/components/Print/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
处方签 Prescription.json
|
||||
处置单 Disposal.json
|
||||
门诊日结 DailyOutpatientSettlement.json
|
||||
门诊挂号 OutpatientRegistration.json
|
||||
门诊收费 OutpatientBilling.json
|
||||
门诊病历 OutpatientMedicalRecord.json
|
||||
手术记录 OperativeRecord.json
|
||||
|
||||
门诊输液贴 OutpatientInfusion.json
|
||||
药房打印 Pharmacy.json
|
||||
红旗门诊病历 HQOutpatientMedicalRecord.json
|
||||
预交金 AdvancePayment.json
|
||||
中药药房处方单 ChineseMedicinePrescription.json
|
||||
中药医生处方单 DocChineseMedicinePrescription.json
|
||||
60
openhis-ui-vue3/src/components/TableLayout/EditTable.vue
Normal file
60
openhis-ui-vue3/src/components/TableLayout/EditTable.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div class="table-section" v-loading="loading">
|
||||
<EditableTable ref="editableTableRef" v-bind="$attrs" class="editable-table">
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</EditableTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import EditableTable from './EditableTable.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'EditTable',
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const editableTableRef = ref(null);
|
||||
|
||||
defineExpose({
|
||||
get formRef() {
|
||||
return editableTableRef.value?.formRef;
|
||||
},
|
||||
get tableRef() {
|
||||
return editableTableRef.value?.tableRef;
|
||||
},
|
||||
validate: (...args) => editableTableRef.value?.validate(...args),
|
||||
validateField: (...args) => editableTableRef.value?.validateField(...args),
|
||||
resetFields: (...args) => editableTableRef.value?.resetFields(...args),
|
||||
clearValidate: (...args) => editableTableRef.value?.clearValidate(...args),
|
||||
get tableData() {
|
||||
return editableTableRef.value?.tableData;
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-section {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.editable-table {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
567
openhis-ui-vue3/src/components/TableLayout/EditableTable.vue
Normal file
567
openhis-ui-vue3/src/components/TableLayout/EditableTable.vue
Normal file
@@ -0,0 +1,567 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="{ tableData }" :rules="rules" class="editable-table-form">
|
||||
<div
|
||||
v-if="showAddButton || showDeleteButton || searchFields.length > 0"
|
||||
class="editable-table-toolbar"
|
||||
>
|
||||
<div class="toolbar-left">
|
||||
<el-button v-if="showAddButton" type="primary" icon="Plus" @click="handleToolbarAdd">
|
||||
添加行
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showDeleteButton"
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
:disabled="selectedRows.length === 0"
|
||||
@click="handleToolbarDelete"
|
||||
>
|
||||
删除行
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="toolbar-right">
|
||||
<el-input
|
||||
v-if="searchFields.length > 0"
|
||||
v-model="searchKeyword"
|
||||
:placeholder="searchPlaceholder"
|
||||
clearable
|
||||
style="width: 300px"
|
||||
@input="handleSearch"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="filteredTableData"
|
||||
:border="border"
|
||||
:stripe="stripe"
|
||||
:max-height="maxHeight || undefined"
|
||||
:min-height="minHeight || undefined"
|
||||
:height="!maxHeight && !minHeight ? '100%' : undefined"
|
||||
:row-key="getRowKey"
|
||||
:virtualized="useVirtualized"
|
||||
v-bind="$attrs"
|
||||
@selection-change="handleSelectionChange"
|
||||
class="editable-table-inner"
|
||||
>
|
||||
<el-table-column v-if="showSelection" type="selection" width="55" align="center" />
|
||||
<el-table-column
|
||||
v-if="showRowActions"
|
||||
:width="rowActionsColumnWidth"
|
||||
align="center"
|
||||
fixed="left"
|
||||
>
|
||||
<template #header>
|
||||
<div
|
||||
v-if="showSelection && selectedRows.length > 0 && !showDeleteButton"
|
||||
style="display: flex; align-items: center; justify-content: center; gap: 4px"
|
||||
>
|
||||
<el-button type="danger" size="small" icon="Delete" link @click="handleDeleteSelected">
|
||||
删除选中({{ selectedRows.length }})
|
||||
</el-button>
|
||||
</div>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="showRowAddButton"
|
||||
type="primary"
|
||||
link
|
||||
icon="CirclePlus"
|
||||
class="action-btn"
|
||||
@click="handleAdd(scope.$index)"
|
||||
title="增加"
|
||||
/>
|
||||
<el-button
|
||||
v-if="showRowDeleteButton"
|
||||
type="danger"
|
||||
link
|
||||
icon="Delete"
|
||||
class="action-btn"
|
||||
@click="handleDelete(scope.$index)"
|
||||
title="删除"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
v-for="col in filteredColumns"
|
||||
:key="col.prop"
|
||||
:prop="col.prop"
|
||||
:label="col.label"
|
||||
:width="col.width"
|
||||
:min-width="col.minWidth"
|
||||
:fixed="col.fixed"
|
||||
:align="col.align || 'center'"
|
||||
:formatter="col.formatter"
|
||||
>
|
||||
<template #default="scope">
|
||||
<template v-if="col.type === 'input'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<el-input
|
||||
v-model="scope.row[col.prop]"
|
||||
:placeholder="col.placeholder || `请输入${col.label}`"
|
||||
:disabled="col.disabled"
|
||||
:clearable="col.clearable !== false"
|
||||
@blur="col.onBlur && col.onBlur(scope.row, scope.$index)"
|
||||
@input="col.onInput && col.onInput(scope.row, scope.$index)"
|
||||
@change="col.onChange && col.onChange(scope.row, scope.$index)"
|
||||
>
|
||||
<template v-if="col.suffix" #suffix>{{ col.suffix }}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="col.type === 'number'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="scope.row[col.prop]"
|
||||
:placeholder="col.placeholder || `请输入${col.label}`"
|
||||
:disabled="col.disabled"
|
||||
:min="col.min"
|
||||
:max="col.max"
|
||||
:precision="col.precision"
|
||||
:controls="false"
|
||||
style="width: 100%"
|
||||
@change="col.onChange && col.onChange(scope.row, scope.$index)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="col.type === 'select'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<el-select
|
||||
v-model="scope.row[col.prop]"
|
||||
:placeholder="col.placeholder || `请选择${col.label}`"
|
||||
:disabled="col.disabled"
|
||||
:clearable="col.clearable !== false"
|
||||
:filterable="col.filterable"
|
||||
:multiple="col.multiple"
|
||||
style="width: 100%"
|
||||
:class="scope.row.error ? 'error-border' : ''"
|
||||
@change="
|
||||
async (value) => {
|
||||
const checkBeforeChange = col.extraprops?.checkBeforeChange;
|
||||
if (checkBeforeChange && typeof checkBeforeChange === 'function') {
|
||||
const result = await checkBeforeChange(scope.row, scope.$index, value);
|
||||
if (result === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (col.onChange) {
|
||||
col.onChange(scope.row, scope.$index, value);
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in typeof col.options === 'function'
|
||||
? col.options(scope.row, scope.$index)
|
||||
: col.options || []"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
@click="option.onClick && option.onClick(scope.row, option)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="col.type === 'date'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="scope.row[col.prop]"
|
||||
:type="col.dateType || 'date'"
|
||||
:placeholder="col.placeholder || `请选择${col.label}`"
|
||||
:disabled="col.disabled"
|
||||
:clearable="col.clearable !== false"
|
||||
:value-format="col.valueFormat || 'YYYY-MM-DD'"
|
||||
style="width: 100%"
|
||||
@change="col.onChange && col.onChange(scope.row, scope.$index)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="col.type === 'slot'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<slot :name="col.slot || col.prop" :row="scope.row" :index="scope.$index" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<span>{{
|
||||
col.formatter
|
||||
? col.formatter(scope.row, scope.column, scope.row[col.prop])
|
||||
: scope.row[col.prop]
|
||||
}}</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="$slots.footer" class="editable-table-footer">
|
||||
<slot name="footer" :tableData="tableData" />
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, nextTick, computed } from 'vue';
|
||||
import { Search } from '@element-plus/icons-vue';
|
||||
import type { EditableTableProps } from '../types/EditableTable.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'EditableTable',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<EditableTableProps>(), {
|
||||
modelValue: () => [],
|
||||
rules: () => ({}),
|
||||
defaultRow: () => ({}),
|
||||
border: true,
|
||||
stripe: false,
|
||||
showSelection: false,
|
||||
showAddButton: false,
|
||||
showDeleteButton: false,
|
||||
showRowActions: true,
|
||||
showRowAddButton: true,
|
||||
showRowDeleteButton: true,
|
||||
searchFields: () => [],
|
||||
virtualizedThreshold: 100,
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: Record<string, any>[]];
|
||||
add: [row: Record<string, any>, index: number];
|
||||
delete: [row: Record<string, any>, index: number, isClear: boolean];
|
||||
'selection-change': [selection: Record<string, any>[]];
|
||||
'toolbar-add': [];
|
||||
'toolbar-delete': [rows: Record<string, any>[]];
|
||||
}>();
|
||||
|
||||
const formRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
const tableRef = ref<InstanceType<typeof import('element-plus').ElTable> | null>(null);
|
||||
const selectedRows = ref<Record<string, any>[]>([]);
|
||||
const searchKeyword = ref('');
|
||||
|
||||
const tableData = ref([...props.modelValue]);
|
||||
|
||||
// 行唯一 key(用于虚拟滚动等)
|
||||
const autoRowId = ref(0);
|
||||
const getRowKey = (row: Record<string, any>) => {
|
||||
if (row.rowKey !== undefined && row.rowKey !== null) return row.rowKey;
|
||||
if (row.id !== undefined && row.id !== null) return row.id;
|
||||
if (!row._etKey) {
|
||||
row._etKey = `et-${autoRowId.value++}`;
|
||||
}
|
||||
return row._etKey;
|
||||
};
|
||||
|
||||
// 是否开启虚拟滚动:优先使用外部传入,其次根据数据量自动开启
|
||||
const useVirtualized = computed(() => {
|
||||
if (typeof props.virtualized === 'boolean') {
|
||||
return props.virtualized;
|
||||
}
|
||||
const threshold = props.virtualizedThreshold ?? 100;
|
||||
return tableData.value.length > threshold;
|
||||
});
|
||||
|
||||
// 过滤列(支持条件显示)
|
||||
const filteredColumns = computed(() => {
|
||||
return props.columns.filter((col) => !col.vIf || col.vIf());
|
||||
});
|
||||
|
||||
// 行操作列宽度:同时显示“增加+删除”则宽一点;只显示一个则缩窄
|
||||
const rowActionsColumnWidth = computed(() => {
|
||||
const showAdd = !!props.showRowAddButton;
|
||||
const showDel = !!props.showRowDeleteButton;
|
||||
if (showAdd && showDel) return 100;
|
||||
if (showAdd || showDel) return 60;
|
||||
// 如果两者都不显示,列也不会渲染;这里给个兜底
|
||||
return 0;
|
||||
});
|
||||
|
||||
const searchPlaceholder = computed(() => {
|
||||
if (props.searchFields.length === 0) {
|
||||
return '请输入搜索关键词';
|
||||
}
|
||||
|
||||
const fieldLabels = props.searchFields
|
||||
.map((field) => {
|
||||
const column = props.columns.find((col) => col.prop === field);
|
||||
return column?.label || field;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
if (fieldLabels.length === 0) {
|
||||
return '请输入搜索关键词';
|
||||
}
|
||||
|
||||
if (fieldLabels.length === 1) {
|
||||
return `请输入${fieldLabels[0]}`;
|
||||
}
|
||||
|
||||
return `请输入${fieldLabels.join('|')}`;
|
||||
});
|
||||
|
||||
// 根据搜索关键词过滤表格数据
|
||||
const filteredTableData = computed(() => {
|
||||
if (!searchKeyword.value || props.searchFields.length === 0) {
|
||||
return tableData.value;
|
||||
}
|
||||
|
||||
const keyword = searchKeyword.value.toLowerCase();
|
||||
return tableData.value.filter((row) => {
|
||||
return props.searchFields.some((field) => {
|
||||
const value = row[field];
|
||||
if (value === null || value === undefined) {
|
||||
return false;
|
||||
}
|
||||
return String(value).toLowerCase().includes(keyword);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
if (newVal !== tableData.value) {
|
||||
tableData.value = [...newVal];
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
tableData,
|
||||
(newVal) => {
|
||||
emit('update:modelValue', newVal);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const handleAdd = (index) => {
|
||||
const newRow = { ...props.defaultRow };
|
||||
tableData.value.splice(index + 1, 0, newRow);
|
||||
nextTick(() => {
|
||||
emit('add', newRow, index + 1);
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelete = (index) => {
|
||||
if (tableData.value.length === 1) {
|
||||
Object.keys(tableData.value[0]).forEach((key) => {
|
||||
tableData.value[0][key] = '';
|
||||
});
|
||||
Object.assign(tableData.value[0], { ...props.defaultRow });
|
||||
emit('delete', tableData.value[0], index, true);
|
||||
} else {
|
||||
const deletedRow = tableData.value.splice(index, 1)[0];
|
||||
emit('delete', deletedRow, index, false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (selection) => {
|
||||
selectedRows.value = selection;
|
||||
emit('selection-change', selection);
|
||||
};
|
||||
|
||||
// 删除所有选中的行
|
||||
const handleDeleteSelected = () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取选中行的索引
|
||||
const selectedIndexes = selectedRows.value.map((row) => tableData.value.indexOf(row));
|
||||
// 从后往前删除,避免索引变化问题
|
||||
selectedIndexes.sort((a, b) => b - a);
|
||||
|
||||
// 如果选中了所有行且只剩一行,清空数据而不是删除
|
||||
if (tableData.value.length === selectedRows.value.length && tableData.value.length === 1) {
|
||||
Object.keys(tableData.value[0]).forEach((key) => {
|
||||
tableData.value[0][key] = '';
|
||||
});
|
||||
Object.assign(tableData.value[0], { ...props.defaultRow });
|
||||
emit('delete', tableData.value[0], 0, true);
|
||||
} else {
|
||||
// 删除选中的行
|
||||
selectedIndexes.forEach((index) => {
|
||||
if (index !== -1 && tableData.value.length > 1) {
|
||||
const deletedRow = tableData.value.splice(index, 1)[0];
|
||||
emit('delete', deletedRow, index, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 清空选中状态
|
||||
if (tableRef.value) {
|
||||
tableRef.value.clearSelection();
|
||||
}
|
||||
selectedRows.value = [];
|
||||
};
|
||||
|
||||
// 工具栏新增按钮
|
||||
const handleToolbarAdd = () => {
|
||||
const newRow = { ...props.defaultRow };
|
||||
tableData.value.push(newRow);
|
||||
nextTick(() => {
|
||||
emit('toolbar-add');
|
||||
emit('add', newRow, tableData.value.length - 1);
|
||||
});
|
||||
};
|
||||
|
||||
// 工具栏删除按钮
|
||||
const handleToolbarDelete = () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
emit('toolbar-delete', selectedRows.value);
|
||||
handleDeleteSelected();
|
||||
};
|
||||
|
||||
// 搜索处理
|
||||
const handleSearch = () => {
|
||||
// 搜索逻辑已在 computed 中处理
|
||||
};
|
||||
|
||||
const validate = (callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validate(callback);
|
||||
}
|
||||
};
|
||||
|
||||
const validateField = (props, callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validateField(props, callback);
|
||||
}
|
||||
};
|
||||
|
||||
const resetFields = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
const clearValidate = (props) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.clearValidate(props);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
formRef,
|
||||
tableRef,
|
||||
validate,
|
||||
validateField,
|
||||
resetFields,
|
||||
clearValidate,
|
||||
tableData,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.editable-table-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.editable-table-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding: 0 4px;
|
||||
|
||||
.toolbar-left {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.toolbar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table.editable-table-inner) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table__body-wrapper {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.el-table__cell {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
vertical-align: top;
|
||||
|
||||
.cell {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__cell) {
|
||||
overflow: visible;
|
||||
vertical-align: top;
|
||||
|
||||
.cell {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
// 错误信息往下撑开行高,不影响上面布局
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 0;
|
||||
|
||||
.el-form-item__error {
|
||||
position: static;
|
||||
line-height: 1.5;
|
||||
padding-top: 4px;
|
||||
font-size: 12px;
|
||||
color: var(--el-color-danger);
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
margin: 4px;
|
||||
:deep(.el-icon) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.editable-table-footer {
|
||||
flex-shrink: 0;
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
157
openhis-ui-vue3/src/components/TableLayout/Filter.vue
Normal file
157
openhis-ui-vue3/src/components/TableLayout/Filter.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div v-if="show" class="query-form-wrapper">
|
||||
<el-form
|
||||
ref="queryFormRef"
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
class="query-form"
|
||||
:label-width="labelWidth"
|
||||
>
|
||||
<template v-for="item in displayedFormItems" :key="item.prop">
|
||||
<FormItem
|
||||
:item="item"
|
||||
:model-value="queryParams[item.prop]"
|
||||
:on-enter="handleQuery"
|
||||
@update:model-value="(value) => (queryParams[item.prop] = value)"
|
||||
@change="(value) => item.onChange && item.onChange(value)"
|
||||
>
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</FormItem>
|
||||
</template>
|
||||
<el-form-item v-if="showDefaultButtons" style="margin-left: 20px">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button v-if="needCollapse" type="text" @click="toggleExpand" style="margin-left: 16px">
|
||||
{{ isExpanded ? '收起' : '展开' }}
|
||||
<el-icon class="el-icon--right">
|
||||
<DArrowLeft v-if="isExpanded" class="collapse-arrow collapse-arrow--up" />
|
||||
<DArrowRight v-else class="collapse-arrow collapse-arrow--down" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import FormItem from './FormItem.vue';
|
||||
import type { FilterProps } from '../types/Filter.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'Filter'
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<FilterProps>(), {
|
||||
formItems: () => [],
|
||||
show: true,
|
||||
showDefaultButtons: true,
|
||||
labelWidth: '120px',
|
||||
showLabelColon: true,
|
||||
});
|
||||
|
||||
|
||||
const emit = defineEmits<{
|
||||
query: [queryParams: Record<string, any>];
|
||||
reset: [];
|
||||
}>();
|
||||
|
||||
const queryFormRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
const isExpanded = ref(true);
|
||||
|
||||
const itemsPerRow = 4;
|
||||
|
||||
const normalizedFormItems = computed(() =>
|
||||
(props.formItems || []).map((item) => ({
|
||||
...item,
|
||||
labelSuffix: item.labelSuffix ?? (props.showLabelColon ? ':' : ''),
|
||||
}))
|
||||
);
|
||||
|
||||
const needCollapse = computed(() => {
|
||||
if (!normalizedFormItems.value || normalizedFormItems.value.length === 0) return false;
|
||||
|
||||
let totalWidth = 0;
|
||||
normalizedFormItems.value.forEach((item) => {
|
||||
if (item.type === 'custom' || item.type === 'daterange') {
|
||||
totalWidth += 2;
|
||||
} else {
|
||||
totalWidth += 1;
|
||||
}
|
||||
});
|
||||
|
||||
return totalWidth > itemsPerRow * 2;
|
||||
});
|
||||
|
||||
const displayedFormItems = computed(() => {
|
||||
if (!needCollapse.value || isExpanded.value) {
|
||||
return normalizedFormItems.value;
|
||||
}
|
||||
|
||||
const maxItems = itemsPerRow * 2;
|
||||
let count = 0;
|
||||
const result: any[] = [];
|
||||
|
||||
for (const item of normalizedFormItems.value) {
|
||||
const itemWidth = item.type === 'custom' || item.type === 'daterange' ? 2 : 1;
|
||||
|
||||
if (count + itemWidth > maxItems) {
|
||||
break;
|
||||
}
|
||||
|
||||
result.push(item);
|
||||
count += itemWidth;
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
const toggleExpand = () => {
|
||||
isExpanded.value = !isExpanded.value;
|
||||
};
|
||||
|
||||
const handleQuery = () => {
|
||||
emit('query', props.queryParams);
|
||||
};
|
||||
|
||||
const resetQuery = () => {
|
||||
if (queryFormRef.value) {
|
||||
queryFormRef.value.resetFields();
|
||||
}
|
||||
if (props.queryParams && Object.prototype.hasOwnProperty.call(props.queryParams, 'pageNum')) {
|
||||
props.queryParams.pageNum = 1;
|
||||
}
|
||||
emit('reset');
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
queryFormRef,
|
||||
handleQuery,
|
||||
resetQuery,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.query-form-wrapper {
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
|
||||
.query-form {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-arrow {
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&.collapse-arrow--up {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
&.collapse-arrow--down {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
115
openhis-ui-vue3/src/components/TableLayout/Form.vue
Normal file
115
openhis-ui-vue3/src/components/TableLayout/Form.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="model"
|
||||
:rules="rules"
|
||||
:label-width="labelWidth"
|
||||
:inline="inline"
|
||||
:label-position="labelPosition"
|
||||
class="table-layout-form"
|
||||
>
|
||||
<template v-for="item in normalizedFormItems" :key="item.prop">
|
||||
<FormItem
|
||||
:item="item"
|
||||
:model-value="model[item.prop]"
|
||||
@update:model-value="(value) => (model[item.prop] = value)"
|
||||
@change="(value) => item.onChange && item.onChange(value)"
|
||||
>
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</FormItem>
|
||||
</template>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import FormItem from './FormItem.vue';
|
||||
import type { FormProps } from '../types/Form.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'Form'
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<FormProps>(), {
|
||||
formItems: () => [],
|
||||
rules: () => ({}),
|
||||
labelWidth: '120px',
|
||||
inline: false,
|
||||
labelPosition: 'right',
|
||||
showLabelColon: true,
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
validate: [callback?: (valid: boolean) => void];
|
||||
}>();
|
||||
|
||||
const formRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
|
||||
const normalizedFormItems = computed(() =>
|
||||
(props.formItems || []).map((item) => ({
|
||||
...item,
|
||||
labelSuffix: item.labelSuffix ?? (props.showLabelColon ? ':' : ''),
|
||||
}))
|
||||
);
|
||||
|
||||
// 表单验证
|
||||
const validate = (callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validate(callback);
|
||||
}
|
||||
};
|
||||
|
||||
// 验证指定字段
|
||||
const validateField = (props, callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validateField(props, callback);
|
||||
}
|
||||
};
|
||||
|
||||
// 重置表单
|
||||
const resetFields = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
// 清除验证
|
||||
const clearValidate = (props) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.clearValidate(props);
|
||||
}
|
||||
};
|
||||
|
||||
// 滚动到指定字段
|
||||
const scrollToField = (prop) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.scrollToField(prop);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
formRef,
|
||||
validate,
|
||||
validateField,
|
||||
resetFields,
|
||||
clearValidate,
|
||||
scrollToField,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-layout-form {
|
||||
width: 100%;
|
||||
|
||||
// 非内联表单样式
|
||||
&:not(.el-form--inline) {
|
||||
:deep(.el-form-item) {
|
||||
display: flex;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
196
openhis-ui-vue3/src/components/TableLayout/FormItem.vue
Normal file
196
openhis-ui-vue3/src/components/TableLayout/FormItem.vue
Normal file
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<el-form-item
|
||||
:label="labelWithSuffix"
|
||||
:prop="item.prop"
|
||||
:required="item.required"
|
||||
:class="{ 'form-item-double': item.type === 'custom' || item.type === 'daterange' }"
|
||||
>
|
||||
<el-input
|
||||
v-if="item.type === 'input'"
|
||||
:model-value="modelValue"
|
||||
:placeholder="item.placeholder || `请输入${item.label}`"
|
||||
:clearable="item.clearable !== false"
|
||||
:style="item.style || { width: item.width || '200px' }"
|
||||
v-bind="item.extraprops || {}"
|
||||
@keyup.enter="handleEnter"
|
||||
@update:model-value="handleUpdate"
|
||||
/>
|
||||
<el-select
|
||||
v-else-if="item.type === 'select'"
|
||||
:model-value="modelValue"
|
||||
:placeholder="item.placeholder || `请选择${item.label}`"
|
||||
:clearable="item.clearable !== false"
|
||||
:style="item.style || { width: item.width || '200px' }"
|
||||
:disabled="item.disabled"
|
||||
v-bind="item.extraprops || {}"
|
||||
:multiple="item.multiple !== false"
|
||||
:filterable="item.filterable !== false"
|
||||
:collapse-tags="item.collapseTags !== false"
|
||||
@change="handleChange"
|
||||
@update:model-value="(value) => handleUpdateWithCheck(value, item.checkBeforeChange)"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in item.options || []"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-radio-group
|
||||
v-else-if="item.type === 'radio'"
|
||||
:model-value="modelValue"
|
||||
v-bind="item.extraprops || {}"
|
||||
@change="handleChange"
|
||||
@update:model-value="handleUpdate"
|
||||
>
|
||||
<el-radio v-for="option in item.options || []" :key="option.value" :label="option.value">
|
||||
{{ option.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- 单独日期 -->
|
||||
<el-date-picker
|
||||
v-else-if="item.type === 'date'"
|
||||
:model-value="modelValue"
|
||||
type="date"
|
||||
:placeholder="item.placeholder || `请选择${item.label}`"
|
||||
:clearable="item.clearable !== false"
|
||||
:value-format="item.valueFormat || 'YYYY-MM-DD'"
|
||||
:style="item.style || { width: item.width || '200px' }"
|
||||
:disabled="item.disabled"
|
||||
v-bind="item.extraprops || {}"
|
||||
@change="handleChange"
|
||||
@update:model-value="handleUpdate"
|
||||
/>
|
||||
<!-- 日期区间 -->
|
||||
<QuickDateRange
|
||||
v-else-if="item.type === 'daterange'"
|
||||
:model-value="daterangeValue"
|
||||
:start-placeholder="item.startPlaceholder || '开始日期'"
|
||||
:end-placeholder="item.endPlaceholder || '结束日期'"
|
||||
:value-format="item.valueFormat || 'YYYY-MM-DD'"
|
||||
:clearable="item.clearable !== false"
|
||||
:date-picker-style="daterangeStyle"
|
||||
:attrs="item.extraprops || {}"
|
||||
@change="handleChange"
|
||||
@update:model-value="handleUpdate"
|
||||
/>
|
||||
<!-- 纯文本展示 -->
|
||||
<span
|
||||
v-else-if="item.type === 'text'"
|
||||
:style="item.style || { width: item.width || '200px' }"
|
||||
class="form-item-text"
|
||||
>
|
||||
{{ item.formatter ? item.formatter(modelValue) : modelValue ?? '' }}
|
||||
</span>
|
||||
<slot
|
||||
v-else-if="item.type === 'custom'"
|
||||
:name="item.slot || item.prop"
|
||||
:item="item"
|
||||
:modelValue="modelValue"
|
||||
:updateModelValue="handleUpdate"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { FormItemProps } from '../types/FormItem.d';
|
||||
import QuickDateRange from './QuickDateRange.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'FormItem',
|
||||
});
|
||||
|
||||
const props = defineProps<FormItemProps>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: any];
|
||||
change: [value: any];
|
||||
}>();
|
||||
|
||||
const labelWithSuffix = computed(() => {
|
||||
const suffix = props.item.labelSuffix || '';
|
||||
return `${props.item.label || ''}${suffix}`;
|
||||
});
|
||||
|
||||
// 日期区间组件的值处理
|
||||
const daterangeValue = computed<string[]>(() => {
|
||||
if (props.item.type === 'daterange') {
|
||||
if (Array.isArray(props.modelValue)) {
|
||||
return props.modelValue.map((v: any) => String(v));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
// 日期区间组件的样式处理
|
||||
const daterangeStyle = computed(() => {
|
||||
if (props.item.type === 'daterange') {
|
||||
if (
|
||||
typeof props.item.style === 'object' &&
|
||||
props.item.style !== null &&
|
||||
!Array.isArray(props.item.style)
|
||||
) {
|
||||
return props.item.style;
|
||||
}
|
||||
return { width: props.item.width || 'calc(316px + 7em)' };
|
||||
}
|
||||
return {};
|
||||
});
|
||||
|
||||
const handleUpdate = (value: any) => {
|
||||
emit('update:modelValue', value);
|
||||
};
|
||||
|
||||
const handleUpdateWithCheck = async (value: any, shouldCheck = false) => {
|
||||
if (shouldCheck) {
|
||||
if (props.item.onChange && typeof props.item.onChange === 'function') {
|
||||
const result = await props.item.onChange(value);
|
||||
if (result === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
handleUpdate(value);
|
||||
};
|
||||
|
||||
const handleChange = (value: any) => {
|
||||
emit('change', value);
|
||||
};
|
||||
|
||||
const handleEnter = () => {
|
||||
if (props.onEnter && typeof props.onEnter === 'function') {
|
||||
props.onEnter();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 16px;
|
||||
display: inline-flex;
|
||||
align-items: flex-start;
|
||||
vertical-align: top;
|
||||
margin-right: 16px;
|
||||
|
||||
.el-form-item__label {
|
||||
width: 7em !important;
|
||||
min-width: 7em;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
line-height: 1.5;
|
||||
padding-right: 8px;
|
||||
text-align: right;
|
||||
padding-top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.el-form-item__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
143
openhis-ui-vue3/src/components/TableLayout/FormLayout.vue
Normal file
143
openhis-ui-vue3/src/components/TableLayout/FormLayout.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="model"
|
||||
:rules="rules"
|
||||
:label-width="labelWidth"
|
||||
:label-position="labelPosition"
|
||||
class="form-layout-form"
|
||||
>
|
||||
<div class="form-items-container" :class="columns > 0 ? `form-layout-${columns}col` : ''">
|
||||
<template v-for="(item, index) in normalizedFormItems" :key="item.prop">
|
||||
<FormItem
|
||||
:item="item"
|
||||
:model-value="model[item.prop]"
|
||||
@update:model-value="
|
||||
async (value) => {
|
||||
if (item.onChange && typeof item.onChange === 'function') {
|
||||
const result = await item.onChange(value);
|
||||
if (result === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
model[item.prop] = value;
|
||||
}
|
||||
"
|
||||
>
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</FormItem>
|
||||
<span
|
||||
v-if="
|
||||
columns > 0 &&
|
||||
index > 0 &&
|
||||
(index + 1) % columns === 0 &&
|
||||
index < normalizedFormItems.length - 1
|
||||
"
|
||||
class="form-item-break"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import FormItem from './FormItem.vue';
|
||||
import type { FormLayoutProps } from '../types/FormLayout.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'FormLayout',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<FormLayoutProps>(), {
|
||||
formItems: () => [],
|
||||
rules: () => ({}),
|
||||
labelWidth: '120px',
|
||||
labelPosition: 'right',
|
||||
showLabelColon: true,
|
||||
columns: 0,
|
||||
});
|
||||
|
||||
const formRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
|
||||
const normalizedFormItems = computed(() =>
|
||||
(props.formItems || []).map((item) => ({
|
||||
...item,
|
||||
labelSuffix: item.labelSuffix ?? (props.showLabelColon ? ':' : ''),
|
||||
}))
|
||||
);
|
||||
|
||||
const validate = (callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validate(callback);
|
||||
}
|
||||
};
|
||||
|
||||
const validateField = (props, callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validateField(props, callback);
|
||||
}
|
||||
};
|
||||
|
||||
const resetFields = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
const clearValidate = (props) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.clearValidate(props);
|
||||
}
|
||||
};
|
||||
|
||||
const scrollToField = (prop) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.scrollToField(prop);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
formRef,
|
||||
validate,
|
||||
validateField,
|
||||
resetFields,
|
||||
clearValidate,
|
||||
scrollToField,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form-layout-form {
|
||||
width: 100%;
|
||||
|
||||
.form-items-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
column-gap: 16px;
|
||||
row-gap: 16px;
|
||||
|
||||
.form-item-break {
|
||||
flex-basis: 100%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 0;
|
||||
justify-content: flex-start;
|
||||
flex: 0 0 auto;
|
||||
|
||||
.el-form-item__content {
|
||||
justify-content: flex-start;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
18
openhis-ui-vue3/src/components/TableLayout/FormSection.vue
Normal file
18
openhis-ui-vue3/src/components/TableLayout/FormSection.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div class="form-section">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: 'FormSection',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form-section {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="form-section">
|
||||
<FormLayout ref="formLayoutRef" v-bind="$attrs">
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</FormLayout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import FormLayout from './FormLayout.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'FormSectionLayout',
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const formLayoutRef = ref(null);
|
||||
|
||||
defineExpose({
|
||||
get formRef() {
|
||||
return formLayoutRef.value?.formRef;
|
||||
},
|
||||
validate: (...args) => formLayoutRef.value?.validate(...args),
|
||||
validateField: (...args) => formLayoutRef.value?.validateField(...args),
|
||||
resetFields: (...args) => formLayoutRef.value?.resetFields(...args),
|
||||
clearValidate: (...args) => formLayoutRef.value?.clearValidate(...args),
|
||||
scrollToField: (...args) => formLayoutRef.value?.scrollToField(...args),
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form-section {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
136
openhis-ui-vue3/src/components/TableLayout/NumberInput.vue
Normal file
136
openhis-ui-vue3/src/components/TableLayout/NumberInput.vue
Normal file
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<el-input
|
||||
:model-value="displayValue"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:clearable="clearable"
|
||||
@input="handleInput"
|
||||
@blur="handleBlur"
|
||||
@change="handleChange"
|
||||
>
|
||||
<template v-if="suffix" #suffix>{{ suffix }}</template>
|
||||
</el-input>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: [Number, String],
|
||||
placeholder: String,
|
||||
disabled: Boolean,
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
suffix: String,
|
||||
precision: Number, // 小数位数
|
||||
min: Number,
|
||||
max: Number,
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'blur', 'change']);
|
||||
|
||||
const displayValue = computed(() => {
|
||||
if (props.modelValue === null || props.modelValue === undefined || props.modelValue === '') {
|
||||
return '';
|
||||
}
|
||||
return String(props.modelValue);
|
||||
});
|
||||
|
||||
const handleInput = (value) => {
|
||||
// 只允许数字、小数点和负号
|
||||
let newValue = value.replace(/[^\d.-]/g, '');
|
||||
|
||||
// 只允许一个小数点
|
||||
const parts = newValue.split('.');
|
||||
if (parts.length > 2) {
|
||||
newValue = parts[0] + '.' + parts.slice(1).join('');
|
||||
}
|
||||
|
||||
// 只允许一个负号,且必须在开头
|
||||
if (newValue.indexOf('-') > 0) {
|
||||
newValue = newValue.replace(/-/g, '');
|
||||
}
|
||||
if (newValue.startsWith('-') && newValue.split('-').length > 2) {
|
||||
newValue = '-' + newValue.replace(/-/g, '');
|
||||
}
|
||||
|
||||
// 如果为空,直接返回空字符串
|
||||
if (newValue === '' || newValue === '-') {
|
||||
emit('update:modelValue', '');
|
||||
return;
|
||||
}
|
||||
|
||||
// 转换为数字
|
||||
const numValue = parseFloat(newValue);
|
||||
if (isNaN(numValue)) {
|
||||
emit('update:modelValue', '');
|
||||
return;
|
||||
}
|
||||
|
||||
// 限制最小值
|
||||
if (props.min !== undefined && numValue < props.min) {
|
||||
newValue = String(props.min);
|
||||
}
|
||||
|
||||
// 限制最大值
|
||||
if (props.max !== undefined && numValue > props.max) {
|
||||
newValue = String(props.max);
|
||||
}
|
||||
|
||||
// 处理精度
|
||||
if (props.precision !== undefined && newValue.includes('.')) {
|
||||
const parts = newValue.split('.');
|
||||
if (parts[1] && parts[1].length > props.precision) {
|
||||
parts[1] = parts[1].substring(0, props.precision);
|
||||
newValue = parts.join('.');
|
||||
}
|
||||
}
|
||||
|
||||
emit('update:modelValue', newValue);
|
||||
};
|
||||
|
||||
const handleBlur = (event) => {
|
||||
const value = event.target.value;
|
||||
if (value === '' || value === '-') {
|
||||
emit('update:modelValue', '');
|
||||
emit('blur', event);
|
||||
return;
|
||||
}
|
||||
|
||||
const numValue = parseFloat(value);
|
||||
if (isNaN(numValue)) {
|
||||
emit('update:modelValue', '');
|
||||
emit('blur', event);
|
||||
return;
|
||||
}
|
||||
|
||||
// 应用精度
|
||||
let finalValue = numValue;
|
||||
if (props.precision !== undefined) {
|
||||
finalValue = parseFloat(numValue.toFixed(props.precision));
|
||||
}
|
||||
|
||||
// 限制范围
|
||||
if (props.min !== undefined && finalValue < props.min) {
|
||||
finalValue = props.min;
|
||||
}
|
||||
if (props.max !== undefined && finalValue > props.max) {
|
||||
finalValue = props.max;
|
||||
}
|
||||
|
||||
emit('update:modelValue', String(finalValue));
|
||||
emit('blur', event);
|
||||
};
|
||||
|
||||
const handleChange = (value) => {
|
||||
emit('change', value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-input__inner) {
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
29
openhis-ui-vue3/src/components/TableLayout/PageLayout.vue
Normal file
29
openhis-ui-vue3/src/components/TableLayout/PageLayout.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<Layout>
|
||||
<template #default>
|
||||
<div class="page-wrapper">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="$slots.footer" #footer>
|
||||
<slot name="footer" />
|
||||
</template>
|
||||
</Layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Layout from '@/components/Layout/index.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'PageLayout',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
20
openhis-ui-vue3/src/components/TableLayout/PageWrapper.vue
Normal file
20
openhis-ui-vue3/src/components/TableLayout/PageWrapper.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div class="page-wrapper">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: 'PageWrapper',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
171
openhis-ui-vue3/src/components/TableLayout/QuickDateRange.vue
Normal file
171
openhis-ui-vue3/src/components/TableLayout/QuickDateRange.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<div class="quick-date-range">
|
||||
<el-select v-model="quickType" class="quick-select" @change="handleQuickChange">
|
||||
<el-option label="自定义时间段" value="custom" />
|
||||
<el-option label="今天" value="today" />
|
||||
<el-option label="昨天" value="yesterday" />
|
||||
<el-option label="本周" value="thisWeek" />
|
||||
<el-option label="上周" value="lastWeek" />
|
||||
<el-option label="最近30日" value="last30Days" />
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
v-model="innerValue"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
:start-placeholder="startPlaceholder || '开始日期'"
|
||||
:end-placeholder="endPlaceholder || '结束日期'"
|
||||
:value-format="valueFormat"
|
||||
:clearable="clearable"
|
||||
:style="datePickerStyle"
|
||||
v-bind="attrs"
|
||||
@change="handleDateChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, computed } from 'vue';
|
||||
import type { QuickDateRangeProps } from '../types/QuickDateRange.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'QuickDateRange'
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<QuickDateRangeProps>(), {
|
||||
modelValue: () => [],
|
||||
startPlaceholder: '',
|
||||
endPlaceholder: '',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
clearable: true,
|
||||
datePickerStyle: () => ({}),
|
||||
attrs: () => ({}),
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string[]];
|
||||
change: [value: string[]];
|
||||
}>();
|
||||
|
||||
const innerValue = ref<string[]>(props.modelValue && props.modelValue.length ? [...props.modelValue] : []);
|
||||
const quickType = ref<string>('custom');
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
if (!val || !val.length) {
|
||||
innerValue.value = [];
|
||||
quickType.value = 'custom';
|
||||
} else {
|
||||
innerValue.value = [...val];
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const datePickerStyle = computed(() => {
|
||||
return Object.assign({ width: '300px' }, props.datePickerStyle || {});
|
||||
});
|
||||
|
||||
function formatDate(date) {
|
||||
const y = date.getFullYear();
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const d = String(date.getDate()).padStart(2, '0');
|
||||
return `${y}-${m}-${d}`;
|
||||
}
|
||||
|
||||
function getToday() {
|
||||
const today = new Date();
|
||||
const d = new Date(today.getFullYear(), today.getMonth(), today.getDate());
|
||||
const s = formatDate(d);
|
||||
return [s, s];
|
||||
}
|
||||
|
||||
function getYesterday() {
|
||||
const today = new Date();
|
||||
const d = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
|
||||
const s = formatDate(d);
|
||||
return [s, s];
|
||||
}
|
||||
|
||||
function getThisWeek() {
|
||||
const today = new Date();
|
||||
const day = today.getDay() || 7; // 周日返回 7
|
||||
const monday = new Date(today);
|
||||
monday.setDate(today.getDate() - day + 1);
|
||||
const sunday = new Date(monday);
|
||||
sunday.setDate(monday.getDate() + 6);
|
||||
return [formatDate(monday), formatDate(sunday)];
|
||||
}
|
||||
|
||||
function getLastWeek() {
|
||||
const today = new Date();
|
||||
const day = today.getDay() || 7;
|
||||
const lastMonday = new Date(today);
|
||||
lastMonday.setDate(today.getDate() - day - 6);
|
||||
const lastSunday = new Date(lastMonday);
|
||||
lastSunday.setDate(lastMonday.getDate() + 6);
|
||||
return [formatDate(lastMonday), formatDate(lastSunday)];
|
||||
}
|
||||
|
||||
function getLast30Days() {
|
||||
const today = new Date();
|
||||
const end = new Date(today.getFullYear(), today.getMonth(), today.getDate());
|
||||
const start = new Date(end);
|
||||
start.setDate(end.getDate() - 29);
|
||||
return [formatDate(start), formatDate(end)];
|
||||
}
|
||||
|
||||
function handleQuickChange(val: string) {
|
||||
if (val === 'custom') {
|
||||
// 自定义时间段,清空日期值
|
||||
innerValue.value = [];
|
||||
emit('update:modelValue', []);
|
||||
emit('change', []);
|
||||
return;
|
||||
}
|
||||
let range: string[] = [];
|
||||
switch (val) {
|
||||
case 'today':
|
||||
range = getToday();
|
||||
break;
|
||||
case 'yesterday':
|
||||
range = getYesterday();
|
||||
break;
|
||||
case 'thisWeek':
|
||||
range = getThisWeek();
|
||||
break;
|
||||
case 'lastWeek':
|
||||
range = getLastWeek();
|
||||
break;
|
||||
case 'last30Days':
|
||||
range = getLast30Days();
|
||||
break;
|
||||
default:
|
||||
range = [];
|
||||
}
|
||||
innerValue.value = range;
|
||||
emit('update:modelValue', range);
|
||||
emit('change', range);
|
||||
}
|
||||
|
||||
function handleDateChange(val: string[] | null) {
|
||||
// 用户手动选择时间段时,将预设切换为自定义
|
||||
quickType.value = 'custom';
|
||||
innerValue.value = val || [];
|
||||
emit('update:modelValue', innerValue.value);
|
||||
emit('change', innerValue.value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.quick-date-range {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.quick-select {
|
||||
width: 130px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
373
openhis-ui-vue3/src/components/TableLayout/Table.vue
Normal file
373
openhis-ui-vue3/src/components/TableLayout/Table.vue
Normal file
@@ -0,0 +1,373 @@
|
||||
<template>
|
||||
<div class="table-container">
|
||||
<div ref="tableWrapperRef" class="table-wrapper">
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
v-loading="loading"
|
||||
:data="computedTableData"
|
||||
:border="border"
|
||||
:stripe="stripe"
|
||||
:size="size"
|
||||
:height="computedTableHeight"
|
||||
:row-key="rowKey"
|
||||
:highlight-current-row="highlightCurrentRow"
|
||||
@row-click="handleRowClick"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange"
|
||||
style="width: 100%; height: 100%"
|
||||
>
|
||||
<!-- 通过配置数组生成的列 -->
|
||||
<template v-for="column in tableColumns" :key="column.prop || column.type">
|
||||
<el-table-column
|
||||
v-if="column.type && column.type !== 'expand'"
|
||||
:type="column.type"
|
||||
:width="column.width"
|
||||
:min-width="column.minWidth"
|
||||
:align="column.align || 'center'"
|
||||
:fixed="
|
||||
column.type === 'selection'
|
||||
? column.fixed !== undefined
|
||||
? column.fixed
|
||||
: 'left'
|
||||
: column.fixed
|
||||
"
|
||||
:selectable="column.selectable"
|
||||
/>
|
||||
<!-- 展开列,支持自定义插槽内容 -->
|
||||
<el-table-column
|
||||
v-else-if="column.type === 'expand'"
|
||||
type="expand"
|
||||
:width="column.width"
|
||||
:min-width="column.minWidth"
|
||||
:fixed="column.fixed"
|
||||
>
|
||||
<template #default="scope">
|
||||
<slot :name="column.slot || 'expand'" :row="scope.row" :scope="scope" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 普通数据列 -->
|
||||
<el-table-column
|
||||
v-else
|
||||
:prop="column.prop"
|
||||
:label="column.label"
|
||||
:width="column.width"
|
||||
:min-width="column.minWidth"
|
||||
:align="column.align || 'left'"
|
||||
:fixed="column.fixed"
|
||||
:show-overflow-tooltip="column.showOverflowTooltip !== false"
|
||||
>
|
||||
<template v-if="column.slot" #default="scope">
|
||||
<slot :name="column.slot" :row="scope.row" :scope="scope" />
|
||||
</template>
|
||||
<template v-else-if="column.formatter" #default="scope">
|
||||
{{
|
||||
column.formatter(
|
||||
scope.row,
|
||||
scope.column,
|
||||
column.prop ? scope.row[column.prop] : undefined,
|
||||
scope.$index
|
||||
)
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<!-- 通过插槽自定义的列 -->
|
||||
<slot name="table" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div v-if="showPagination" ref="paginationWrapperRef" class="pagination-wrapper">
|
||||
<div
|
||||
class="pagination-content"
|
||||
:class="{ 'has-left-content': paginationLeftText || $slots.paginationLeft }"
|
||||
>
|
||||
<div v-if="paginationLeftText || $slots.paginationLeft" class="pagination-left">
|
||||
<slot name="paginationLeft">
|
||||
{{ paginationLeftText }}
|
||||
</slot>
|
||||
</div>
|
||||
<pagination
|
||||
v-show="computedTotal > 0"
|
||||
:total="computedTotal"
|
||||
:page="computedPageNo"
|
||||
:limit="computedPageSize"
|
||||
v-bind="paginationProps"
|
||||
@pagination="handlePagination"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue';
|
||||
import Pagination from '@/components/Pagination/index.vue';
|
||||
import type { TableProps } from '../types/Table.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'Table',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<TableProps>(), {
|
||||
tableData: () => [],
|
||||
loading: false,
|
||||
border: true,
|
||||
stripe: false,
|
||||
size: 'default',
|
||||
highlightCurrentRow: false,
|
||||
tableColumns: () => [],
|
||||
showPagination: false,
|
||||
total: 0,
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
isAllData: false,
|
||||
paginationLeftText: '',
|
||||
paginationProps: () => ({}),
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
'row-click': [row: Record<string, any>, column: any, event: Event];
|
||||
'selection-change': [selection: Record<string, any>[]];
|
||||
'sort-change': [sortInfo: { column: any; prop: string; order: string }];
|
||||
pagination: [pagination: { page: number; limit: number }];
|
||||
}>();
|
||||
|
||||
const internalPageNo = ref(props.pageNo);
|
||||
const internalPageSize = ref(props.pageSize);
|
||||
|
||||
watch(
|
||||
() => [props.pageNo, props.pageSize],
|
||||
([newPageNo, newPageSize]) => {
|
||||
if (!props.isAllData) {
|
||||
internalPageNo.value = newPageNo;
|
||||
internalPageSize.value = newPageSize;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.isAllData,
|
||||
(isAllData) => {
|
||||
if (isAllData) {
|
||||
internalPageNo.value = props.pageNo;
|
||||
internalPageSize.value = props.pageSize;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const computedPageNo = computed(() => {
|
||||
return props.isAllData ? internalPageNo.value : props.pageNo;
|
||||
});
|
||||
|
||||
const computedPageSize = computed(() => {
|
||||
return props.isAllData ? internalPageSize.value : props.pageSize;
|
||||
});
|
||||
|
||||
const computedTotal = computed(() => {
|
||||
return props.isAllData ? props.tableData.length : props.total;
|
||||
});
|
||||
|
||||
const computedTableData = computed(() => {
|
||||
if (!props.isAllData) {
|
||||
return props.tableData;
|
||||
}
|
||||
const start = (computedPageNo.value - 1) * computedPageSize.value;
|
||||
const end = start + computedPageSize.value;
|
||||
return props.tableData.slice(start, end);
|
||||
});
|
||||
|
||||
const handlePagination = (pagination: { page: number; limit: number }) => {
|
||||
if (props.isAllData) {
|
||||
internalPageNo.value = pagination.page;
|
||||
internalPageSize.value = pagination.limit;
|
||||
} else {
|
||||
emit('pagination', pagination);
|
||||
}
|
||||
nextTick(() => {
|
||||
calculateTableHeight();
|
||||
});
|
||||
};
|
||||
|
||||
const tableRef = ref<InstanceType<typeof import('element-plus').ElTable> | null>(null);
|
||||
const tableWrapperRef = ref<HTMLDivElement | null>(null);
|
||||
const paginationWrapperRef = ref<HTMLDivElement | null>(null);
|
||||
const dynamicTableHeight = ref<number | null>(null);
|
||||
const paginationHeight = ref<number>(0);
|
||||
|
||||
const computedTableHeight = computed(() => {
|
||||
if (props.tableHeight) {
|
||||
return props.tableHeight;
|
||||
}
|
||||
if (props.maxHeight) {
|
||||
return props.maxHeight;
|
||||
}
|
||||
if (dynamicTableHeight.value) {
|
||||
const height = dynamicTableHeight.value - paginationHeight.value;
|
||||
return height > 0 ? height : dynamicTableHeight.value;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
const calculateTableHeight = () => {
|
||||
nextTick(() => {
|
||||
if (tableWrapperRef.value) {
|
||||
const tableContainer = tableWrapperRef.value.parentElement;
|
||||
if (tableContainer) {
|
||||
const containerRect = tableContainer.getBoundingClientRect();
|
||||
let height = containerRect.height;
|
||||
|
||||
if (props.showPagination && paginationWrapperRef.value && computedTotal.value > 0) {
|
||||
const paginationRect = paginationWrapperRef.value.getBoundingClientRect();
|
||||
paginationHeight.value = paginationRect.height;
|
||||
height -= paginationRect.height;
|
||||
} else {
|
||||
paginationHeight.value = 0;
|
||||
}
|
||||
|
||||
if (height > 0) {
|
||||
dynamicTableHeight.value = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let resizeObserver: ResizeObserver | null = null;
|
||||
let paginationObserver: ResizeObserver | null = null;
|
||||
|
||||
onMounted(() => {
|
||||
calculateTableHeight();
|
||||
const tableContainer = tableWrapperRef.value?.parentElement;
|
||||
if (tableContainer && window.ResizeObserver) {
|
||||
resizeObserver = new ResizeObserver(() => {
|
||||
calculateTableHeight();
|
||||
});
|
||||
resizeObserver.observe(tableContainer);
|
||||
} else {
|
||||
window.addEventListener('resize', calculateTableHeight);
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.showPagination && computedTotal.value > 0 && paginationWrapperRef.value,
|
||||
(shouldObserve) => {
|
||||
if (shouldObserve && paginationWrapperRef.value && window.ResizeObserver) {
|
||||
if (!paginationObserver) {
|
||||
paginationObserver = new ResizeObserver(() => {
|
||||
calculateTableHeight();
|
||||
});
|
||||
}
|
||||
paginationObserver.observe(paginationWrapperRef.value);
|
||||
} else if (paginationObserver && paginationWrapperRef.value) {
|
||||
paginationObserver.unobserve(paginationWrapperRef.value);
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect();
|
||||
}
|
||||
if (paginationObserver) {
|
||||
paginationObserver.disconnect();
|
||||
}
|
||||
if (!resizeObserver) {
|
||||
window.removeEventListener('resize', calculateTableHeight);
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.tableData,
|
||||
() => {
|
||||
calculateTableHeight();
|
||||
if (props.isAllData && internalPageNo.value !== 1) {
|
||||
internalPageNo.value = 1;
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => [props.showPagination, computedTotal.value],
|
||||
() => {
|
||||
calculateTableHeight();
|
||||
}
|
||||
);
|
||||
|
||||
const handleRowClick = (row: Record<string, any>, column: any, event: Event) => {
|
||||
emit('row-click', row, column, event);
|
||||
};
|
||||
|
||||
const handleSelectionChange = (selection: Record<string, any>[]) => {
|
||||
emit('selection-change', selection);
|
||||
};
|
||||
|
||||
const handleSortChange = ({
|
||||
column,
|
||||
prop,
|
||||
order,
|
||||
}: {
|
||||
column: any;
|
||||
prop: string;
|
||||
order: string;
|
||||
}) => {
|
||||
emit('sort-change', { column, prop, order });
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
tableRef,
|
||||
tableWrapperRef,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
flex-shrink: 0;
|
||||
margin-top: 8px;
|
||||
padding-bottom: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.pagination-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
|
||||
&.has-left-content {
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-left {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
color: var(--el-text-color-regular);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.pagination-content :deep(.pagination-container) {
|
||||
.el-pagination {
|
||||
margin-right: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
27
openhis-ui-vue3/src/components/TableLayout/TableSection.vue
Normal file
27
openhis-ui-vue3/src/components/TableLayout/TableSection.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div class="table-section">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: 'TableSection',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-section {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
:deep(.editable-table) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
411
openhis-ui-vue3/src/components/TableLayout/index.vue
Normal file
411
openhis-ui-vue3/src/components/TableLayout/index.vue
Normal file
@@ -0,0 +1,411 @@
|
||||
<template>
|
||||
<div class="table-layout-container">
|
||||
<div class="card-content-wrapper">
|
||||
<div
|
||||
v-if="showSideQuery"
|
||||
class="side-query-wrapper"
|
||||
:class="{ collapsed: sideQueryCollapsed }"
|
||||
>
|
||||
<div v-if="!sideQueryCollapsed" class="side-query-header">
|
||||
<el-input v-model="sideSearchKeyword" placeholder="搜索树节点" clearable size="small">
|
||||
<template #prefix>
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div v-if="!sideQueryCollapsed" class="side-query-content">
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="treeDataWithAll"
|
||||
:props="defaultProps"
|
||||
:node-key="treeNodeKey"
|
||||
:expand-on-click-node="false"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
@node-click="handleNodeClick"
|
||||
@current-change="handleCurrentChange"
|
||||
></el-tree>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showSideQuery" class="collapse-divider">
|
||||
<el-button
|
||||
circle
|
||||
size="small"
|
||||
class="collapse-btn"
|
||||
@click="sideQueryCollapsed = !sideQueryCollapsed"
|
||||
>
|
||||
<el-icon>
|
||||
<ArrowRight v-if="sideQueryCollapsed" />
|
||||
<ArrowLeft v-else />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<div
|
||||
class="main-content-wrapper"
|
||||
:class="{ 'with-side-query': showSideQuery && !sideQueryCollapsed }"
|
||||
>
|
||||
<Filter
|
||||
v-if="showTopQuery"
|
||||
ref="queryFormComponentRef"
|
||||
:query-params="queryParams"
|
||||
:form-items="formItems"
|
||||
:show-default-buttons="showDefaultButtons"
|
||||
@query="handleQuery"
|
||||
@reset="resetQuery"
|
||||
>
|
||||
<template
|
||||
v-for="item in customFormItems"
|
||||
:key="item.prop"
|
||||
v-slot:[item.slotName]="slotProps"
|
||||
>
|
||||
<slot :name="item.slotName" :item="slotProps.item" :queryParams="props.queryParams" />
|
||||
</template>
|
||||
<template #default="{ queryParams, handleQuery, resetQuery }">
|
||||
<slot
|
||||
name="topQuery"
|
||||
:queryParams="queryParams"
|
||||
:handleQuery="handleQuery"
|
||||
:resetQuery="resetQuery"
|
||||
/>
|
||||
</template>
|
||||
</Filter>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operation-bar">
|
||||
<slot name="operations" />
|
||||
</div>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<Table
|
||||
:table-data="tableData"
|
||||
:loading="loading"
|
||||
:border="border"
|
||||
:stripe="stripe"
|
||||
:size="size"
|
||||
:table-height="tableHeight"
|
||||
:max-height="maxHeight"
|
||||
:row-key="rowKey"
|
||||
:highlight-current-row="highlightCurrentRow"
|
||||
:table-columns="tableColumns"
|
||||
:show-pagination="showPagination"
|
||||
:total="total"
|
||||
:page-no="props.queryParams.pageNo"
|
||||
:page-size="props.queryParams.pageSize"
|
||||
@row-click="handleRowClick"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange"
|
||||
@pagination="handlePagination"
|
||||
>
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import Filter from './Filter.vue';
|
||||
import Table from './Table.vue';
|
||||
import type { TableLayoutProps, TreeNodeData } from '../types/TableLayout.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'TableLayout',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<TableLayoutProps>(), {
|
||||
tableData: () => [],
|
||||
loading: false,
|
||||
total: 0,
|
||||
queryParams: () => ({
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
}),
|
||||
sideQueryParams: () => ({}),
|
||||
formItems: () => [],
|
||||
showTopQuery: true,
|
||||
showSideQuery: false,
|
||||
showPagination: true,
|
||||
showDefaultButtons: true,
|
||||
sideWidth: 6,
|
||||
border: true,
|
||||
stripe: false,
|
||||
size: 'default',
|
||||
highlightCurrentRow: false,
|
||||
siderData: () => [],
|
||||
treeNodeKey: 'id',
|
||||
tableColumns: () => [],
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
query: [queryParams: Record<string, any>];
|
||||
reset: [];
|
||||
pagination: [pagination: { page: number; limit: number }];
|
||||
'row-click': [row: Record<string, any>, column: any, event: Event];
|
||||
'selection-change': [selection: Record<string, any>[]];
|
||||
'sort-change': [sortInfo: { column: any; prop: string; order: string }];
|
||||
'side-query': [node: TreeNodeData];
|
||||
'reset-side-query': [];
|
||||
}>();
|
||||
|
||||
const queryFormRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
import type { FilterExpose } from '../types/Filter.d';
|
||||
const queryFormComponentRef = ref<FilterExpose | null>(null);
|
||||
const sideSearchKeyword = ref<string>('');
|
||||
const treeRef = ref<InstanceType<typeof import('element-plus').ElTree> | null>(null);
|
||||
const currentTreeNode = ref<TreeNodeData | null>(null);
|
||||
const sideQueryCollapsed = ref<boolean>(false);
|
||||
|
||||
const customFormItems = computed(() => {
|
||||
return props.formItems
|
||||
.filter((item) => item.type === 'custom')
|
||||
.map((item) => ({
|
||||
...item,
|
||||
slotName: item.slot || item.prop,
|
||||
}));
|
||||
});
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
};
|
||||
|
||||
const filteredSiderData = computed(() => {
|
||||
if (!sideSearchKeyword.value || !props.siderData || props.siderData.length === 0) {
|
||||
return props.siderData;
|
||||
}
|
||||
|
||||
const keyword = sideSearchKeyword.value.toLowerCase();
|
||||
|
||||
const filterTree = (nodes: TreeNodeData[]): TreeNodeData[] => {
|
||||
if (!nodes || nodes.length === 0) return [];
|
||||
|
||||
return nodes
|
||||
.map((node: TreeNodeData) => {
|
||||
const label = (node[defaultProps.label] || '').toLowerCase();
|
||||
const match = label.includes(keyword);
|
||||
const children = node[defaultProps.children];
|
||||
|
||||
let filteredChildren: TreeNodeData[] | null = null;
|
||||
if (children && children.length > 0) {
|
||||
filteredChildren = filterTree(children);
|
||||
}
|
||||
|
||||
if (match || (filteredChildren && filteredChildren.length > 0)) {
|
||||
return {
|
||||
...node,
|
||||
[defaultProps.children]: filteredChildren,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.filter(Boolean) as TreeNodeData[];
|
||||
};
|
||||
|
||||
return filterTree(props.siderData);
|
||||
});
|
||||
|
||||
const treeDataWithAll = computed(() => {
|
||||
const children = filteredSiderData.value || [];
|
||||
return [
|
||||
{
|
||||
[props.treeNodeKey]: '__ALL__',
|
||||
[defaultProps.label]: '全部',
|
||||
[defaultProps.children]: children || [],
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const handleQuery = () => {
|
||||
props.queryParams.pageNo = 1;
|
||||
emit('query', props.queryParams);
|
||||
if (currentTreeNode.value) {
|
||||
emit('side-query', currentTreeNode.value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNodeClick = (data: TreeNodeData, node: any) => {
|
||||
currentTreeNode.value = data;
|
||||
if (treeRef.value && data && data[props.treeNodeKey]) {
|
||||
treeRef.value.setCurrentKey(data[props.treeNodeKey]);
|
||||
}
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
const handleCurrentChange = (data: TreeNodeData, node: any) => {
|
||||
currentTreeNode.value = data;
|
||||
};
|
||||
|
||||
const resetQuery = () => {
|
||||
if (queryFormComponentRef.value?.queryFormRef) {
|
||||
queryFormComponentRef.value.queryFormRef.resetFields();
|
||||
}
|
||||
if (props.queryParams) {
|
||||
Object.keys(props.queryParams).forEach((key) => {
|
||||
if (key !== 'pageNo' && key !== 'pageSize') {
|
||||
if (Array.isArray(props.queryParams[key])) {
|
||||
props.queryParams[key] = [];
|
||||
} else if (typeof props.queryParams[key] === 'object' && props.queryParams[key] !== null) {
|
||||
props.queryParams[key] = null;
|
||||
} else {
|
||||
props.queryParams[key] = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
if (Object.prototype.hasOwnProperty.call(props.queryParams, 'pageNo')) {
|
||||
props.queryParams.pageNo = 1;
|
||||
}
|
||||
}
|
||||
emit('reset');
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
const handlePagination = (pagination) => {
|
||||
if (props.queryParams) {
|
||||
props.queryParams.pageNo = pagination.page;
|
||||
props.queryParams.pageSize = pagination.limit;
|
||||
}
|
||||
emit('pagination', pagination);
|
||||
emit('query', props.queryParams);
|
||||
if (currentTreeNode.value) {
|
||||
emit('side-query', currentTreeNode.value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRowClick = (row, column, event) => {
|
||||
emit('row-click', row, column, event);
|
||||
};
|
||||
|
||||
const handleSelectionChange = (selection) => {
|
||||
emit('selection-change', selection);
|
||||
};
|
||||
|
||||
const handleSortChange = ({ column, prop, order }) => {
|
||||
emit('sort-change', { column, prop, order });
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
queryFormRef: computed(() => queryFormComponentRef.value?.queryFormRef),
|
||||
handleQuery,
|
||||
resetQuery,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-layout-container {
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
|
||||
.main-content-card {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow: visible;
|
||||
|
||||
:deep(.el-card__body) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px 16px 8px 16px;
|
||||
min-height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.card-content-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 0;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.collapse-divider {
|
||||
flex-shrink: 0;
|
||||
width: 1px;
|
||||
background-color: #ebeef5;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
margin: 0 12px;
|
||||
|
||||
.collapse-btn {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 18px;
|
||||
transform: translateX(-50%);
|
||||
background-color: #fff;
|
||||
border: 1px solid #ebeef5;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
||||
z-index: 10;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
&:hover {
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.side-query-wrapper {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: width 0.3s, opacity 0.3s;
|
||||
overflow: hidden;
|
||||
|
||||
&.collapsed {
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.side-query-header {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.side-query-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
|
||||
:deep(.el-tree--highlight-current) {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main-content-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-operation-bar {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,188 +1,125 @@
|
||||
<!--
|
||||
* @Author: sjjh
|
||||
* @Date: 2025-04-07 20:42:45
|
||||
* @Description:住院患者信息,给医生用,带折叠
|
||||
-->
|
||||
<template>
|
||||
<div class="inPatientBarDoctorFold-container">
|
||||
<div class="basic_info">
|
||||
<div class="patient-header white-bg">
|
||||
<div class="select_wrapper_div">
|
||||
<b class="bedNumber" style="margin-left: 12px">{{ patientInfo?.bedName }}</b>
|
||||
<label class="content-text-color" style="margin-left: 12px; color: #a15209">
|
||||
{{ patientInfo?.patientName }}
|
||||
<span class="sex-age"> {{ patientInfo?.sexName }}/{{ patientInfo?.age }} </span>
|
||||
<b class="bedNumber">{{ patientInfo?.bedName || '未分床' }}</b>
|
||||
<label class="patient-name">
|
||||
{{ patientInfo?.patientName || '-' }}
|
||||
<span class="sex-age">
|
||||
{{ formatSexAge(patientInfo?.sexName, patientInfo?.age) }}
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div style="display: flex; margin-left: 8px">
|
||||
<!-- 状态展示// TODO 后端给状态,前段 -->
|
||||
<div class="tag-list" v-if="patientInfo?.list && patientInfo.list.length > 0">
|
||||
<ball-tag
|
||||
style="margin-right: 4px"
|
||||
v-for="item in patientInfo?.list"
|
||||
v-for="item in patientInfo.list"
|
||||
:key="item"
|
||||
:tagId="item"
|
||||
class="tag-item"
|
||||
></ball-tag>
|
||||
</div>
|
||||
<div
|
||||
class="gray-border"
|
||||
v-show="patientInfo?.feeTypeName && patientInfo?.feeTypeName !== ''"
|
||||
>
|
||||
{{ patientInfo?.feeTypeName }}
|
||||
<div class="gray-border" v-if="patientInfo?.feeTypeName">
|
||||
{{ patientInfo.feeTypeName }}
|
||||
</div>
|
||||
<label style="margin-left: 24px">
|
||||
<label class="info-label">
|
||||
<span class="label-text-color">住院:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.inHospitalDays + '天' }}</span>
|
||||
<span class="content-text-color">{{ formatDays(patientInfo?.inHospitalDays) }}</span>
|
||||
</label>
|
||||
<label style="margin-left: 24px">
|
||||
<label class="info-label" v-if="patientInfo?.inOrgTime">
|
||||
<span class="label-text-color">入科:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.inDeptDate }}</span>
|
||||
<span class="content-text-color">{{ patientInfo.inOrgTime }}</span>
|
||||
</label>
|
||||
<label style="margin-left: 24px">
|
||||
<label class="info-label" v-if="patientInfo?.inHospitalTime">
|
||||
<span class="label-text-color">入院时间:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.inHospitalTime }}</span>
|
||||
<span class="content-text-color">{{ patientInfo.inHospitalTime }}</span>
|
||||
</label>
|
||||
<label style="margin-left: 24px">
|
||||
<span class="label-text-color">住院号:{{ patientInfo?.busNo }}</span>
|
||||
<label class="info-label" v-if="patientInfo?.busNo">
|
||||
<span class="label-text-color">住院号:</span>
|
||||
<span class="content-text-color">{{ patientInfo.busNo }}</span>
|
||||
</label>
|
||||
<svg-icon icon-class="hipCopy" height="20px" width="20px" class="copy-svg" />
|
||||
<label style="margin-left: 30px">
|
||||
<label class="info-label diagnosis-label" v-if="patientInfo?.regDiagnosisName">
|
||||
<span class="label-text-color">诊断:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.regDiagnosisName }}</span>
|
||||
<span class="content-text-color">{{ patientInfo.regDiagnosisName }}</span>
|
||||
</label>
|
||||
<label class="info-label">
|
||||
<span class="label-text-color">费用:</span>
|
||||
<span class="content-text-color">{{ formatMoney(patientInfo?.totalAmount) }}</span>
|
||||
</label>
|
||||
<label class="info-label">
|
||||
<span class="label-text-color">余额:</span>
|
||||
<span class="content-text-color">{{ formatMoney(patientInfo?.balanceAmount) }}</span>
|
||||
</label>
|
||||
<!-- <div style="margin-left: auto">
|
||||
<el-icon v-if="expand" @click="toggleExpand"><ArrowUpBold /></el-icon>
|
||||
<el-icon v-else @click="toggleExpand"><ArrowDownBold /></el-icon>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="expand" class="expand_more">
|
||||
<div style="background-color: #ffffff">
|
||||
<div style="margin-top: -10px">
|
||||
<label style="font-size: 14px">
|
||||
<div class="expand-content">
|
||||
<div class="expand-section">
|
||||
<label class="expand-label">
|
||||
<span class="primary-text">过敏:</span>
|
||||
<span class="primary-text">{{ patientInfo?.allergies || '无过敏史' }}</span>
|
||||
</label>
|
||||
<label style="font-size: 14px; margin-left: 32px" v-show="patientInfo?.insuplcAdmdvsName">
|
||||
<span class="primary-text">医保统筹区:</span>
|
||||
<span class="primary-text">{{ patientInfo?.insuplcAdmdvsName }}</span>
|
||||
<label class="expand-label" v-if="patientInfo?.insuplcAdmdvsName">
|
||||
<span class="primary-text">医保统筹区:</span>
|
||||
<span class="primary-text">{{ patientInfo.insuplcAdmdvsName }}</span>
|
||||
</label>
|
||||
|
||||
<label style="font-size: 14px; margin-left: 32px" v-show="patientInfo?.ciType">
|
||||
<label class="expand-label" v-if="patientInfo?.ciType">
|
||||
<span class="primary-text">商保信息:</span>
|
||||
<span class="primary-text">{{ patientInfo?.ciType }}</span>
|
||||
<span class="primary-text">{{ patientInfo.ciType }}</span>
|
||||
</label>
|
||||
<div style="display: flex; flex-wrap: nowrap; margin-top: 8px; white-space: nowrap">
|
||||
<div
|
||||
class="blue-bg"
|
||||
style="background-color: #f1faff; flex-shrink: 0; min-width: fit-content"
|
||||
>
|
||||
<div class="info-tags">
|
||||
<div class="blue-bg">
|
||||
<span class="content-text-color">
|
||||
{{
|
||||
patientInfo?.height && patientInfo?.weight
|
||||
? `${patientInfo?.height}cm/${patientInfo?.weight}kg`
|
||||
: '身高/体重'
|
||||
}}
|
||||
{{ formatHeightWeight(patientInfo?.height, patientInfo?.weight) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="blue-bg"
|
||||
style="
|
||||
margin-left: 24px;
|
||||
background-color: #f1faff;
|
||||
flex-shrink: 0;
|
||||
min-width: fit-content;
|
||||
"
|
||||
v-show="patientInfo?.postoperativeDays"
|
||||
>
|
||||
<span class="content-text-color">术后{{ patientInfo?.postoperativeDays }}天</span>
|
||||
<div class="blue-bg" v-if="patientInfo?.postoperativeDays">
|
||||
<span class="content-text-color">术后{{ patientInfo.postoperativeDays }}天</span>
|
||||
</div>
|
||||
<div
|
||||
class="blue-bg"
|
||||
style="
|
||||
margin-left: 16px;
|
||||
background-color: #f1faff;
|
||||
flex-shrink: 0;
|
||||
min-width: fit-content;
|
||||
"
|
||||
v-show="patientInfo?.poorTypeName"
|
||||
>
|
||||
<span class="label-text-color">贫困类型:</span>
|
||||
<span class="content-text-color" style="margin-left: 4px">{{
|
||||
patientInfo?.poorTypeName
|
||||
}}</span>
|
||||
<div class="blue-bg" v-if="patientInfo?.poorTypeName">
|
||||
<span class="label-text-color">贫困类型:</span>
|
||||
<span class="content-text-color">{{ patientInfo.poorTypeName }}</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="blue-bg"
|
||||
style="
|
||||
margin-left: 16px;
|
||||
background-color: #f1faff;
|
||||
flex-shrink: 0;
|
||||
min-width: fit-content;
|
||||
"
|
||||
v-show="patientInfo?.pathwayName"
|
||||
>
|
||||
<span class="label-text-color">路径情况:</span>
|
||||
<span class="content-text-color" style="margin-left: 4px">{{
|
||||
patientInfo?.pathwayName
|
||||
}}</span>
|
||||
<div class="blue-bg" v-if="patientInfo?.pathwayName">
|
||||
<span class="label-text-color">路径情况:</span>
|
||||
<span class="content-text-color">{{ patientInfo.pathwayName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="background-color: #ffffff">
|
||||
<div style="margin-top: -10px">
|
||||
<div class="expand-content">
|
||||
<div class="expand-section">
|
||||
<div class="patient-board">
|
||||
<div class="item-center">
|
||||
<div class="line-block">
|
||||
<div class="line-block-top">
|
||||
<span class="label-text-color">科室:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.admissionDeptName }}</span>
|
||||
<span class="content-text-color">{{
|
||||
patientInfo?.admissionDeptName || '-'
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="line-block-bottom">
|
||||
<span class="label-text-color">病区:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.deptNurseName }}</span>
|
||||
<span class="content-text-color">{{ patientInfo?.deptNurseName || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-block">
|
||||
<div class="line-block-top">
|
||||
<span class="label-text-color">主治医生:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.masterDoctorName }}</span>
|
||||
<span class="content-text-color">{{ patientInfo?.masterDoctorName || '-' }}</span>
|
||||
</div>
|
||||
<div class="line-block-bottom">
|
||||
<span class="label-text-color">责任护士:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.masterNurseName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-blockMoney">
|
||||
<div class="line-blockMoney-top">
|
||||
<span class="label-text-color">费用</span>
|
||||
</div>
|
||||
<div class="line-blockMoney-bottom">
|
||||
<b class="money-content size-15">{{
|
||||
patientInfo?.totalAmount ? patientInfo?.totalAmount : 0
|
||||
}}</b>
|
||||
<span class="content-text-color">{{ patientInfo?.masterNurseName || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="line-blockMoney">
|
||||
<div class="line-blockMoney-top">
|
||||
<span class="label-text-color">预交金</span>
|
||||
</div>
|
||||
<div class="line-blockMoney-bottom">
|
||||
<b class="money-content size-15">{{
|
||||
patientInfo?.prepayAmount ? patientInfo?.prepayAmount : 0
|
||||
}}</b>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-blockMoney">
|
||||
<div class="line-blockMoney-top">
|
||||
<span class="label-text-color">余额</span>
|
||||
</div>
|
||||
<div class="line-blockMoney-bottom">
|
||||
<b class="money-content size-15">{{
|
||||
patientInfo?.balance ? patientInfo?.balance : 0
|
||||
}}</b>
|
||||
<b class="money-content size-15">{{ formatMoney(patientInfo?.prepayAmount) }}</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -192,45 +129,57 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import BallTag from './components/BallTag.vue';
|
||||
import { patientInfo } from '@/views/inpatientDoctor/home/store/patient.js';
|
||||
// import { ElMessage } from 'element-plus'
|
||||
|
||||
const expand = ref(false);
|
||||
|
||||
const showDividers = ref(true);
|
||||
|
||||
// 示例方法:切换显示状态
|
||||
const toggleDividers = () => {
|
||||
showDividers.value = !showDividers.value;
|
||||
};
|
||||
const iconClass = ref('hipBarDown');
|
||||
|
||||
// 切换展开状态的方法
|
||||
function toggleExpand() {
|
||||
expand.value = !expand.value;
|
||||
iconClass.value = expand.value ? 'hipBarUp' : 'hipBarDown';
|
||||
toggleDividers();
|
||||
interface Props {
|
||||
visitCode?: string;
|
||||
}
|
||||
|
||||
const fetchPatientInfoById = async (patientId) => {
|
||||
// 查询患者信息
|
||||
console.log(patientId);
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
visitCode: '',
|
||||
});
|
||||
watch(
|
||||
() => props.visitCode,
|
||||
(val) => {
|
||||
if (val !== null && val !== '') {
|
||||
fetchPatientInfoById(val);
|
||||
}
|
||||
|
||||
const expand = ref<boolean>(false);
|
||||
|
||||
// 格式化性别和年龄
|
||||
const formatSexAge = (sexName?: string, age?: number | string): string => {
|
||||
const sex = sexName || '';
|
||||
const ageStr = age !== undefined && age !== null ? String(age) : '';
|
||||
if (sex && ageStr) {
|
||||
return `${sex}/${ageStr}`;
|
||||
} else if (sex) {
|
||||
return sex;
|
||||
} else if (ageStr) {
|
||||
return ageStr;
|
||||
}
|
||||
);
|
||||
return '-';
|
||||
};
|
||||
|
||||
// 格式化天数
|
||||
const formatDays = (days?: number | string): string => {
|
||||
if (days === undefined || days === null || days === '') {
|
||||
return '-';
|
||||
}
|
||||
return `${days}天`;
|
||||
};
|
||||
|
||||
// 格式化身高体重
|
||||
const formatHeightWeight = (height?: number | string, weight?: number | string): string => {
|
||||
if (height && weight) {
|
||||
return `${height}cm/${weight}kg`;
|
||||
}
|
||||
return '身高/体重';
|
||||
};
|
||||
|
||||
// 格式化金额
|
||||
const formatMoney = (amount?: number | string): number => {
|
||||
if (amount === undefined || amount === null || amount === '') {
|
||||
return 0;
|
||||
}
|
||||
return Number(amount) || 0;
|
||||
};
|
||||
|
||||
defineOptions({
|
||||
name: 'NurserDoctorPatientBarminimal',
|
||||
@@ -240,27 +189,77 @@ defineOptions({
|
||||
<style lang="scss" scoped>
|
||||
.inPatientBarDoctorFold-container {
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
background-color: #ffffff;
|
||||
align-items: center;
|
||||
.basic_info {
|
||||
height: 43px;
|
||||
min-height: 44px;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
/* expand_more */
|
||||
|
||||
.expand_more {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.expand-content {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.expand-section {
|
||||
margin-top: -10px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.patient-header {
|
||||
width: 100%;
|
||||
padding: 6px 0;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
|
||||
.select_wrapper_div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bedNumber {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
margin-left: 12px;
|
||||
color: #1f2933;
|
||||
}
|
||||
|
||||
.patient-name {
|
||||
margin-left: 12px;
|
||||
color: #a15209;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sex-age {
|
||||
margin-left: 20px;
|
||||
margin-left: 8px;
|
||||
color: var(--hip-color-text-description);
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.tag-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 8px;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.tag-item {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.gray-border {
|
||||
@@ -270,43 +269,66 @@ defineOptions({
|
||||
align-items: center;
|
||||
border: 1px solid var(--hip-color-text-description);
|
||||
border-radius: 20px;
|
||||
padding: 0px 8px;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
margin-left: 24px;
|
||||
white-space: nowrap;
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.diagnosis-label {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.copy-svg {
|
||||
fill: var(--hip-color-primary);
|
||||
cursor: pointer;
|
||||
margin-left: 4px;
|
||||
transition: opacity 0.2s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.expand-label {
|
||||
font-size: 14px;
|
||||
margin-right: 32px;
|
||||
white-space: nowrap;
|
||||
|
||||
&:first-child {
|
||||
margin-right: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-tags {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
margin-top: 8px;
|
||||
white-space: nowrap;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.size-15 {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.bedNumber {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.primary-text {
|
||||
color: var(--hip-color-primary);
|
||||
}
|
||||
|
||||
.flex-between {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.item-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.patient-board {
|
||||
margin-left: 20px;
|
||||
|
||||
@@ -330,10 +352,8 @@ defineOptions({
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.money-content {
|
||||
color: #ff8616;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
&-bottom {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,7 +374,7 @@ defineOptions({
|
||||
}
|
||||
|
||||
&-top {
|
||||
margin-bottom: 0px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.money-content {
|
||||
@@ -378,13 +398,24 @@ defineOptions({
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #f1faff;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
border-radius: 4px; /*圆角*/
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
min-width: fit-content;
|
||||
white-space: nowrap;
|
||||
|
||||
.content-text-color {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.label-text-color {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.label-text-color {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.content-text-color {
|
||||
|
||||
42
openhis-ui-vue3/src/components/types/Dialog.d.ts
vendored
Normal file
42
openhis-ui-vue3/src/components/types/Dialog.d.ts
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Dialog 尺寸类型
|
||||
*/
|
||||
export type DialogSize = 'small' | 'medium' | 'large';
|
||||
|
||||
/**
|
||||
* Dialog 组件的 Props 类型
|
||||
*/
|
||||
export interface DialogProps {
|
||||
/** 对话框标题 */
|
||||
title?: string;
|
||||
/** 对话框尺寸 */
|
||||
size?: DialogSize;
|
||||
/** 自定义宽度 */
|
||||
width?: string | number;
|
||||
/** 自定义高度 */
|
||||
height?: string | number;
|
||||
/** 是否显示对话框 */
|
||||
modelValue?: boolean;
|
||||
/** 是否在关闭时销毁子元素 */
|
||||
destroyOnClose?: boolean;
|
||||
/** 是否将对话框追加到 body 上 */
|
||||
appendToBody?: boolean;
|
||||
/** 是否可以通过点击遮罩层关闭对话框 */
|
||||
closeOnClickModal?: boolean;
|
||||
/** 是否可以通过按下 ESC 关闭对话框 */
|
||||
closeOnPressEscape?: boolean;
|
||||
/** 是否显示关闭按钮 */
|
||||
showClose?: boolean;
|
||||
/** 是否在对话框出现时将 body 滚动锁定 */
|
||||
lockScroll?: boolean;
|
||||
/** 自定义类名 */
|
||||
customClass?: string;
|
||||
/** 是否可拖拽 */
|
||||
draggable?: boolean;
|
||||
/** 是否全屏 */
|
||||
fullscreen?: boolean;
|
||||
/** 是否显示加载状态 */
|
||||
loading?: boolean;
|
||||
/** 对话框打开前的回调 */
|
||||
beforeClose?: (done: () => void) => void;
|
||||
}
|
||||
99
openhis-ui-vue3/src/components/types/EditableTable.d.ts
vendored
Normal file
99
openhis-ui-vue3/src/components/types/EditableTable.d.ts
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
import type { FormItemOption } from './FormItem.d';
|
||||
|
||||
/**
|
||||
* 可编辑表格列配置类型
|
||||
*/
|
||||
export interface EditableTableColumn {
|
||||
/** 列字段名 */
|
||||
prop: string;
|
||||
/** 列标签 */
|
||||
label: string;
|
||||
/** 列宽度 */
|
||||
width?: string | number;
|
||||
/** 最小宽度 */
|
||||
minWidth?: string | number;
|
||||
/** 是否固定列 */
|
||||
fixed?: boolean | 'left' | 'right';
|
||||
/** 对齐方式 */
|
||||
align?: 'left' | 'center' | 'right';
|
||||
/** 列类型 */
|
||||
type?: 'input' | 'number' | 'select' | 'date' | 'slot';
|
||||
/** 占位符 */
|
||||
placeholder?: string;
|
||||
/** 是否禁用 */
|
||||
disabled?: boolean | ((row: Record<string, any>, index: number) => boolean);
|
||||
/** 是否可清空 */
|
||||
clearable?: boolean;
|
||||
/** 是否可搜索(select 类型) */
|
||||
filterable?: boolean;
|
||||
/** 是否多选(select 类型) */
|
||||
multiple?: boolean;
|
||||
/** 最小值(number 类型) */
|
||||
min?: number;
|
||||
/** 最大值(number 类型) */
|
||||
max?: number;
|
||||
/** 精度(number 类型) */
|
||||
precision?: number;
|
||||
/** 日期类型(date 类型) */
|
||||
dateType?: 'date' | 'datetime' | 'daterange';
|
||||
/** 日期格式 */
|
||||
valueFormat?: string;
|
||||
/** 选项列表(select 类型) */
|
||||
options?: FormItemOption[] | ((row: Record<string, any>, index: number) => FormItemOption[]);
|
||||
/** 自定义插槽名称(slot 类型) */
|
||||
slot?: string;
|
||||
/** 格式化函数 */
|
||||
formatter?: (row: Record<string, any>, column: any, cellValue: any) => string;
|
||||
/** 验证规则 */
|
||||
rules?: any;
|
||||
/** 后缀文本(input 类型) */
|
||||
suffix?: string;
|
||||
/** 条件显示 */
|
||||
vIf?: () => boolean;
|
||||
/** 失焦回调 */
|
||||
onBlur?: (row: Record<string, any>, index: number) => void;
|
||||
/** 输入回调 */
|
||||
onInput?: (row: Record<string, any>, index: number) => void;
|
||||
/** 变更回调 */
|
||||
onChange?: (row: Record<string, any>, index: number, value?: any) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* EditableTable 组件的 Props 类型
|
||||
*/
|
||||
export interface EditableTableProps {
|
||||
/** 表格数据 */
|
||||
modelValue: Record<string, any>[];
|
||||
/** 列配置 */
|
||||
columns: EditableTableColumn[];
|
||||
/** 表单验证规则 */
|
||||
rules?: Record<string, any>;
|
||||
/** 默认行数据 */
|
||||
defaultRow?: Record<string, any>;
|
||||
/** 是否显示边框 */
|
||||
border?: boolean;
|
||||
/** 是否显示斑马纹 */
|
||||
stripe?: boolean;
|
||||
/** 最大高度 */
|
||||
maxHeight?: string | number;
|
||||
/** 最小高度 */
|
||||
minHeight?: string | number;
|
||||
/** 是否开启虚拟滚动(不传则根据数据量自动开启) */
|
||||
virtualized?: boolean;
|
||||
/** 自动开启虚拟滚动的行数阈值,默认 100 */
|
||||
virtualizedThreshold?: number;
|
||||
/** 是否显示选择列 */
|
||||
showSelection?: boolean;
|
||||
/** 是否显示新增按钮 */
|
||||
showAddButton?: boolean;
|
||||
/** 是否显示删除按钮 */
|
||||
showDeleteButton?: boolean;
|
||||
/** 是否显示行级增删按钮 */
|
||||
showRowActions?: boolean;
|
||||
/** 是否显示行级“增加”按钮 */
|
||||
showRowAddButton?: boolean;
|
||||
/** 是否显示行级“删除”按钮 */
|
||||
showRowDeleteButton?: boolean;
|
||||
/** 搜索字段列表(用于筛选,不为空时自动显示搜索框) */
|
||||
searchFields?: string[];
|
||||
}
|
||||
30
openhis-ui-vue3/src/components/types/Filter.d.ts
vendored
Normal file
30
openhis-ui-vue3/src/components/types/Filter.d.ts
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import type { FormItemConfig } from './FormItem.d';
|
||||
import type { DefineComponent } from 'vue';
|
||||
|
||||
/**
|
||||
* Filter 组件的 Props 类型
|
||||
*/
|
||||
export interface FilterProps {
|
||||
/** 查询参数对象 */
|
||||
queryParams: Record<string, any>;
|
||||
/** 表单项配置数组 */
|
||||
formItems: FormItemConfig[];
|
||||
/** 是否显示 */
|
||||
show?: boolean;
|
||||
/** 是否显示默认按钮 */
|
||||
showDefaultButtons?: boolean;
|
||||
/** 标签宽度 */
|
||||
labelWidth?: string;
|
||||
/** 标签后是否添加冒号 */
|
||||
showLabelColon?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter 组件暴露的方法
|
||||
*/
|
||||
export interface FilterExpose {
|
||||
queryFormRef: InstanceType<typeof import('element-plus').ElForm> | null;
|
||||
handleQuery: () => void;
|
||||
resetQuery: () => void;
|
||||
}
|
||||
|
||||
21
openhis-ui-vue3/src/components/types/Form.d.ts
vendored
Normal file
21
openhis-ui-vue3/src/components/types/Form.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { FormItemConfig } from './FormItem.d';
|
||||
|
||||
/**
|
||||
* Form 组件的 Props 类型
|
||||
*/
|
||||
export interface FormProps {
|
||||
/** 表单数据对象 */
|
||||
model: Record<string, any>;
|
||||
/** 表单项配置数组 */
|
||||
formItems: FormItemConfig[];
|
||||
/** 表单验证规则 */
|
||||
rules?: Record<string, any>;
|
||||
/** 标签宽度 */
|
||||
labelWidth?: string;
|
||||
/** 是否内联表单 */
|
||||
inline?: boolean;
|
||||
/** 标签位置 */
|
||||
labelPosition?: 'left' | 'right' | 'top';
|
||||
/** 标签后是否添加冒号 */
|
||||
showLabelColon?: boolean;
|
||||
}
|
||||
82
openhis-ui-vue3/src/components/types/FormItem.d.ts
vendored
Normal file
82
openhis-ui-vue3/src/components/types/FormItem.d.ts
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
import type { CSSProperties } from 'vue';
|
||||
|
||||
/**
|
||||
* 表单项选项类型
|
||||
*/
|
||||
export interface FormItemOption {
|
||||
/** 选项标签 */
|
||||
label: string;
|
||||
/** 选项值 */
|
||||
value: string | number | boolean | null | undefined;
|
||||
/** 是否禁用该选项 */
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* onChange 回调函数类型
|
||||
* @param value - 新的值
|
||||
* @returns 返回 false 时阻止更新,返回其他值或 undefined 时允许更新
|
||||
*/
|
||||
export type OnChangeCallback = (
|
||||
value: string | number | Array<string | number> | Date | null | undefined
|
||||
) => Promise<boolean | void> | boolean | void;
|
||||
|
||||
/**
|
||||
* 表单项配置类型
|
||||
*/
|
||||
export interface FormItemConfig {
|
||||
/** 表单项类型 */
|
||||
type: 'input' | 'select' | 'radio' | 'date' | 'daterange' | 'custom' | 'text';
|
||||
/** 表单项标签 */
|
||||
label: string;
|
||||
/** 表单项字段名(对应 queryParams 的 key) */
|
||||
prop: string;
|
||||
/** 占位符文本 */
|
||||
placeholder?: string;
|
||||
/** 开始日期占位符(仅 daterange 类型) */
|
||||
startPlaceholder?: string;
|
||||
/** 结束日期占位符(仅 daterange 类型) */
|
||||
endPlaceholder?: string;
|
||||
/** 是否可清空 */
|
||||
clearable?: boolean;
|
||||
/** 自定义样式对象或字符串 */
|
||||
style?: CSSProperties | string | { width?: string; [key: string]: any };
|
||||
/** 表单项宽度(字符串,如 '200px') */
|
||||
width?: string;
|
||||
/** 额外的属性(会通过 v-bind 传递给组件) */
|
||||
extraprops?: Record<string, any>;
|
||||
/** 是否多选(仅 select 类型) */
|
||||
multiple?: boolean;
|
||||
/** 是否可搜索(仅 select 类型) */
|
||||
filterable?: boolean;
|
||||
/** 多选时是否折叠标签(仅 select 类型) */
|
||||
collapseTags?: boolean;
|
||||
/** 选项列表(select 和 radio 类型) */
|
||||
options?: FormItemOption[];
|
||||
/** 日期格式(date 和 daterange 类型) */
|
||||
valueFormat?: string;
|
||||
/** 自定义插槽名称(custom 类型) */
|
||||
slot?: string;
|
||||
/** 是否必填 */
|
||||
required?: boolean;
|
||||
/** 标签后缀 */
|
||||
labelSuffix?: string;
|
||||
/** 值变更时的回调函数 */
|
||||
onChange?: OnChangeCallback;
|
||||
/** 是否在变更前进行检查(仅 select 类型,为 true 时会执行 onChange 回调) */
|
||||
checkBeforeChange?: boolean;
|
||||
/** 格式化函数(text 类型,用于格式化显示的文本) */
|
||||
formatter?: (value: any) => string;
|
||||
}
|
||||
|
||||
/**
|
||||
* FormItem 组件的 Props 类型
|
||||
*/
|
||||
export interface FormItemProps {
|
||||
/** 表单项配置对象 */
|
||||
item: FormItemConfig;
|
||||
/** 表单项的值 */
|
||||
modelValue?: string | number | Array<string | number> | Date | null;
|
||||
/** 回车键按下时的回调函数 */
|
||||
onEnter?: () => void;
|
||||
}
|
||||
21
openhis-ui-vue3/src/components/types/FormLayout.d.ts
vendored
Normal file
21
openhis-ui-vue3/src/components/types/FormLayout.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { FormItemConfig } from './FormItem.d';
|
||||
|
||||
/**
|
||||
* FormLayout 组件的 Props 类型
|
||||
*/
|
||||
export interface FormLayoutProps {
|
||||
/** 表单数据对象 */
|
||||
model: Record<string, any>;
|
||||
/** 表单项配置数组 */
|
||||
formItems: FormItemConfig[];
|
||||
/** 表单验证规则 */
|
||||
rules?: Record<string, any>;
|
||||
/** 标签宽度 */
|
||||
labelWidth?: string;
|
||||
/** 标签位置 */
|
||||
labelPosition?: 'left' | 'right' | 'top';
|
||||
/** 标签后是否添加冒号 */
|
||||
showLabelColon?: boolean;
|
||||
/** 列数(0 表示不限制) */
|
||||
columns?: number;
|
||||
}
|
||||
21
openhis-ui-vue3/src/components/types/Pagination.d.ts
vendored
Normal file
21
openhis-ui-vue3/src/components/types/Pagination.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { DefineComponent } from 'vue';
|
||||
|
||||
/**
|
||||
* Pagination 组件的 Props 类型
|
||||
*/
|
||||
export interface PaginationProps {
|
||||
/** 总记录数 */
|
||||
total: number;
|
||||
/** 当前页码 */
|
||||
page: number;
|
||||
/** 每页条数 */
|
||||
limit: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为 Pagination.vue 组件提供类型声明
|
||||
*/
|
||||
declare module '@/components/Pagination/index.vue' {
|
||||
const component: DefineComponent<PaginationProps>;
|
||||
export default component;
|
||||
}
|
||||
21
openhis-ui-vue3/src/components/types/QuickDateRange.d.ts
vendored
Normal file
21
openhis-ui-vue3/src/components/types/QuickDateRange.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { DefineComponent } from 'vue';
|
||||
|
||||
/**
|
||||
* QuickDateRange 组件的 Props 类型
|
||||
*/
|
||||
export interface QuickDateRangeProps {
|
||||
/** 日期范围值(字符串数组,如 ['2024-01-01', '2024-01-31']) */
|
||||
modelValue?: string[];
|
||||
/** 开始日期占位符 */
|
||||
startPlaceholder?: string;
|
||||
/** 结束日期占位符 */
|
||||
endPlaceholder?: string;
|
||||
/** 日期格式 */
|
||||
valueFormat?: string;
|
||||
/** 是否可清空 */
|
||||
clearable?: boolean;
|
||||
/** 日期选择器的样式 */
|
||||
datePickerStyle?: Record<string, any>;
|
||||
/** 透传给日期选择器的其他属性 */
|
||||
attrs?: Record<string, any>;
|
||||
}
|
||||
48
openhis-ui-vue3/src/components/types/Table.d.ts
vendored
Normal file
48
openhis-ui-vue3/src/components/types/Table.d.ts
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { TableColumn } from './TableLayout.d';
|
||||
|
||||
/**
|
||||
* Table 组件的 Props 类型
|
||||
*/
|
||||
export interface TableProps {
|
||||
/** 表格数据 */
|
||||
tableData: Record<string, any>[];
|
||||
/** 加载状态 */
|
||||
loading?: boolean;
|
||||
/** 是否显示边框 */
|
||||
border?: boolean;
|
||||
/** 是否显示斑马纹 */
|
||||
stripe?: boolean;
|
||||
/** 表格尺寸 */
|
||||
size?: 'large' | 'default' | 'small';
|
||||
/** 表格高度 */
|
||||
tableHeight?: string | number;
|
||||
/** 最大高度 */
|
||||
maxHeight?: string | number;
|
||||
/** 行键 */
|
||||
rowKey?: string | ((row: Record<string, any>) => string);
|
||||
/** 是否高亮当前行 */
|
||||
highlightCurrentRow?: boolean;
|
||||
/** 表格列配置 */
|
||||
tableColumns?: TableColumn[];
|
||||
/** 是否显示分页 */
|
||||
showPagination?: boolean;
|
||||
/** 总记录数 */
|
||||
total?: number;
|
||||
/** 当前页码 */
|
||||
pageNo?: number;
|
||||
/** 每页条数 */
|
||||
pageSize?: number;
|
||||
/** 是否所有数据都在客户端,如果是则在组件内部进行分页 */
|
||||
isAllData?: boolean;
|
||||
/** 分页左侧自定义文案 */
|
||||
paginationLeftText?: string;
|
||||
/** 分页组件自定义属性 */
|
||||
paginationProps?: {
|
||||
pageSizes?: number[];
|
||||
pagerCount?: number;
|
||||
layout?: string;
|
||||
background?: boolean;
|
||||
autoScroll?: boolean;
|
||||
hidden?: boolean;
|
||||
};
|
||||
}
|
||||
89
openhis-ui-vue3/src/components/types/TableLayout.d.ts
vendored
Normal file
89
openhis-ui-vue3/src/components/types/TableLayout.d.ts
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
import type { FormItemConfig } from './FormItem.d';
|
||||
|
||||
/**
|
||||
* 表格列配置类型
|
||||
*/
|
||||
export interface TableColumn {
|
||||
/** 列类型 */
|
||||
type?: 'selection' | 'index' | 'expand';
|
||||
/** 列字段名 */
|
||||
prop?: string;
|
||||
/** 列标签 */
|
||||
label?: string;
|
||||
/** 列宽度 */
|
||||
width?: string | number;
|
||||
/** 最小宽度 */
|
||||
minWidth?: string | number;
|
||||
/** 是否固定列 */
|
||||
fixed?: boolean | 'left' | 'right';
|
||||
/** 对齐方式 */
|
||||
align?: 'left' | 'center' | 'right';
|
||||
/** 是否显示溢出提示 */
|
||||
showOverflowTooltip?: boolean;
|
||||
/** 自定义插槽名称 */
|
||||
slot?: string;
|
||||
/** 格式化函数 */
|
||||
formatter?: (row: Record<string, any>, column: any, cellValue: any, index?: number) => string;
|
||||
/** 是否可选(selection 类型) */
|
||||
selectable?: (row: Record<string, any>, index: number) => boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 树节点数据类型
|
||||
*/
|
||||
export interface TreeNodeData {
|
||||
[key: string]: any;
|
||||
children?: TreeNodeData[];
|
||||
}
|
||||
|
||||
/**
|
||||
* TableLayout 组件的 Props 类型
|
||||
*/
|
||||
export interface TableLayoutProps {
|
||||
/** 表格数据 */
|
||||
tableData: Record<string, any>[];
|
||||
/** 加载状态 */
|
||||
loading?: boolean;
|
||||
/** 总记录数 */
|
||||
total?: number;
|
||||
/** 查询参数对象 */
|
||||
queryParams: {
|
||||
pageNo: number;
|
||||
pageSize: number;
|
||||
[key: string]: any;
|
||||
};
|
||||
/** 侧边查询参数 */
|
||||
sideQueryParams?: Record<string, any>;
|
||||
/** 表单项配置数组 */
|
||||
formItems?: FormItemConfig[];
|
||||
/** 是否显示顶部查询 */
|
||||
showTopQuery?: boolean;
|
||||
/** 是否显示侧边查询 */
|
||||
showSideQuery?: boolean;
|
||||
/** 是否显示分页 */
|
||||
showPagination?: boolean;
|
||||
/** 是否显示默认按钮 */
|
||||
showDefaultButtons?: boolean;
|
||||
/** 侧边栏宽度 */
|
||||
sideWidth?: number;
|
||||
/** 是否显示边框 */
|
||||
border?: boolean;
|
||||
/** 是否显示斑马纹 */
|
||||
stripe?: boolean;
|
||||
/** 表格尺寸 */
|
||||
size?: 'large' | 'default' | 'small';
|
||||
/** 表格高度 */
|
||||
tableHeight?: string | number;
|
||||
/** 最大高度 */
|
||||
maxHeight?: string | number;
|
||||
/** 行键 */
|
||||
rowKey?: string | ((row: Record<string, any>) => string);
|
||||
/** 是否高亮当前行 */
|
||||
highlightCurrentRow?: boolean;
|
||||
/** 侧边栏数据 */
|
||||
siderData?: TreeNodeData[];
|
||||
/** 树节点键名 */
|
||||
treeNodeKey?: string;
|
||||
/** 表格列配置 */
|
||||
tableColumns?: TableColumn[];
|
||||
}
|
||||
13
openhis-ui-vue3/src/components/types/index.d.ts
vendored
Normal file
13
openhis-ui-vue3/src/components/types/index.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* TableLayout 组件相关的类型定义
|
||||
*/
|
||||
|
||||
export * from './FormItem.d';
|
||||
export * from './QuickDateRange.d';
|
||||
export * from './EditableTable.d';
|
||||
export * from './Filter.d';
|
||||
export * from './FormLayout.d';
|
||||
export * from './Form.d';
|
||||
export * from './Table.d';
|
||||
export * from './TableLayout.d';
|
||||
export * from './Dialog.d';
|
||||
90
openhis-ui-vue3/src/directive/common/arrowNavigate.js
Normal file
90
openhis-ui-vue3/src/directive/common/arrowNavigate.js
Normal file
@@ -0,0 +1,90 @@
|
||||
const KEY_DELTA_MAP = {
|
||||
ArrowLeft: -1,
|
||||
ArrowUp: -1,
|
||||
ArrowRight: 1,
|
||||
ArrowDown: 1,
|
||||
}
|
||||
|
||||
const FOCUSABLE_SELECTORS = [
|
||||
'input:not([type="hidden"]):not([disabled])',
|
||||
'textarea:not([disabled])',
|
||||
'select:not([disabled])',
|
||||
'.el-input__inner',
|
||||
'.el-input-number',
|
||||
'.el-select',
|
||||
'.el-tree-select',
|
||||
'[tabindex]:not([tabindex="-1"])',
|
||||
]
|
||||
|
||||
function focusControl(container) {
|
||||
if (!container) return
|
||||
|
||||
const focus = (el) => {
|
||||
if (!el) return
|
||||
el.focus?.()
|
||||
if (el.select && !el.readOnly) {
|
||||
el.select()
|
||||
}
|
||||
}
|
||||
|
||||
if (container.matches?.('input, textarea, select')) {
|
||||
focus(container)
|
||||
return
|
||||
}
|
||||
|
||||
const directTarget = container.querySelector(FOCUSABLE_SELECTORS.join(', '))
|
||||
if (directTarget) {
|
||||
focusControl(directTarget)
|
||||
return
|
||||
}
|
||||
|
||||
focus(container)
|
||||
}
|
||||
|
||||
function getFormItems(root) {
|
||||
const propItems = Array.from(root.querySelectorAll('[data-prop]'))
|
||||
if (propItems.length) {
|
||||
return propItems
|
||||
}
|
||||
return Array.from(root.querySelectorAll('.el-form-item'))
|
||||
}
|
||||
|
||||
function createHandler(root) {
|
||||
return function handleKeyDown(event) {
|
||||
const delta = KEY_DELTA_MAP[event.key]
|
||||
if (!delta) return
|
||||
|
||||
const currentItem = event.target.closest('[data-prop], .el-form-item')
|
||||
if (!currentItem || !root.contains(currentItem)) return
|
||||
|
||||
const items = getFormItems(root)
|
||||
if (!items.length) return
|
||||
|
||||
const currentIndex = items.indexOf(currentItem)
|
||||
if (currentIndex === -1) return
|
||||
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
const nextIndex = (currentIndex + delta + items.length) % items.length
|
||||
const targetItem = items[nextIndex]
|
||||
if (targetItem) {
|
||||
focusControl(targetItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
mounted(el) {
|
||||
const handler = createHandler(el)
|
||||
el.__arrowNavigateHandler = handler
|
||||
el.addEventListener('keydown', handler, true)
|
||||
},
|
||||
beforeUnmount(el) {
|
||||
if (el.__arrowNavigateHandler) {
|
||||
el.removeEventListener('keydown', el.__arrowNavigateHandler, true)
|
||||
delete el.__arrowNavigateHandler
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import hasPermi from './permission/hasPermi'
|
||||
import copyText from './common/copyText'
|
||||
import horizontalScroll from './common/horizontalScroll'
|
||||
import clickOutsideRow from './common/clickOutsideRow'
|
||||
import arrowNavigate from './common/arrowNavigate'
|
||||
|
||||
export default function directive(app){
|
||||
app.directive('hasRole', hasRole)
|
||||
@@ -10,4 +11,5 @@ export default function directive(app){
|
||||
app.directive('copyText', copyText)
|
||||
app.directive('horizontal-scroll', horizontalScroll)
|
||||
app.directive('click-outside-row', clickOutsideRow)
|
||||
app.directive('arrow-navigate', arrowNavigate)
|
||||
}
|
||||
@@ -1,51 +1,70 @@
|
||||
<template>
|
||||
<div class="navbar">
|
||||
<!-- <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> -->
|
||||
<!-- <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!settingsStore.topNav" /> -->
|
||||
<!-- <top-nav id="topmenu-container" class="topmenu-container" style="border: 1px solid blue;"/> -->
|
||||
|
||||
<div class="right-menu">
|
||||
<template v-if="appStore.device !== 'mobile'">
|
||||
<header-search id="header-search" class="right-menu-item" />
|
||||
|
||||
<!-- <el-tooltip content="源码地址" effect="dark" placement="bottom">
|
||||
<ruo-yi-git id="openhis-git" class="right-menu-item hover-effect" />
|
||||
</el-tooltip> -->
|
||||
|
||||
<!-- <el-tooltip content="文档地址" effect="dark" placement="bottom">
|
||||
<ruo-yi-doc id="openhis-doc" class="right-menu-item hover-effect" />
|
||||
</el-tooltip> -->
|
||||
|
||||
<!-- <screenfull id="screenfull" class="right-menu-item hover-effect" /> -->
|
||||
|
||||
<el-tooltip content="布局大小" effect="dark" placement="bottom">
|
||||
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<div class="avatar-container">
|
||||
<el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="userStore.avatar" class="user-avatar" />
|
||||
<span class="nick-name">{{ userStore.nickName }}</span>
|
||||
<!-- <el-icon><caret-bottom /></el-icon> -->
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<router-link to="/user/profile">
|
||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||
</router-link>
|
||||
<el-dropdown-item command="switch">
|
||||
<span>切换科室</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
||||
<span>布局设置</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided command="logout">
|
||||
<span>退出登录</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<div class="avatar-wrapper">
|
||||
<el-dropdown
|
||||
@command="handleCommand"
|
||||
class="user-info-dropdown hover-effect"
|
||||
trigger="click"
|
||||
teleported
|
||||
popper-class="navbar-dropdown"
|
||||
:popper-options="{
|
||||
modifiers: [
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: [0, 12],
|
||||
},
|
||||
},
|
||||
],
|
||||
}"
|
||||
>
|
||||
<div class="user-info">
|
||||
<img :src="userStore.avatar" class="user-avatar" />
|
||||
<span class="nick-name">{{ userStore.nickName }}</span>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<router-link to="/user/profile">
|
||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||
</router-link>
|
||||
<!-- <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
||||
<span>布局设置</span>
|
||||
</el-dropdown-item> -->
|
||||
<el-dropdown-item divided command="logout">
|
||||
<span>退出登录</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<span class="divider">|</span>
|
||||
<el-dropdown
|
||||
@command="handleOrgSwitch"
|
||||
trigger="click"
|
||||
teleported
|
||||
popper-class="navbar-dropdown"
|
||||
:placement="'bottom-start'"
|
||||
>
|
||||
<span class="org-name">{{ userStore.orgName }}</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in orgOptions"
|
||||
:key="item.orgId"
|
||||
:command="item.orgId"
|
||||
:class="{ 'is-active': item.orgId === userStore.orgId }"
|
||||
>
|
||||
{{ item.orgName }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<span class="divider" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog title="切换科室" v-model="showDialog" width="400px" append-to-body destroy-on-close>
|
||||
@@ -68,6 +87,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import Breadcrumb from '@/components/Breadcrumb';
|
||||
import TopNav from '@/components/TopNav';
|
||||
@@ -86,8 +106,39 @@ const settingsStore = useSettingsStore();
|
||||
const orgOptions = ref([]);
|
||||
const showDialog = ref(false);
|
||||
const orgId = ref('');
|
||||
function toggleSideBar() {
|
||||
appStore.toggleSideBar();
|
||||
|
||||
function loadOrgList() {
|
||||
getOrg().then((res) => {
|
||||
orgOptions.value = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadOrgList();
|
||||
});
|
||||
|
||||
function handleOrgSwitch(selectedOrgId) {
|
||||
if (selectedOrgId === userStore.orgId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedOrg = orgOptions.value.find((item) => item.orgId === selectedOrgId);
|
||||
const orgName = selectedOrg ? selectedOrg.orgName : '该科室';
|
||||
|
||||
ElMessageBox.confirm(`确定要切换到科室"${orgName}"吗?`, '切换科室', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
orgId.value = selectedOrgId;
|
||||
switchOrg(selectedOrgId).then((res) => {
|
||||
if (res.code === 200) {
|
||||
userStore.logOut().then(() => {
|
||||
location.href = '/index';
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleCommand(command) {
|
||||
@@ -98,13 +149,6 @@ function handleCommand(command) {
|
||||
case 'logout':
|
||||
logout();
|
||||
break;
|
||||
case 'switch':
|
||||
orgId.value = userStore.orgId;
|
||||
getOrg().then((res) => {
|
||||
orgOptions.value = res.data;
|
||||
showDialog.value = true;
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -143,29 +187,35 @@ function setLayout() {
|
||||
<style lang='scss' scoped>
|
||||
.navbar {
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding-right: 10px;
|
||||
flex-shrink: 0;
|
||||
min-width: 200px;
|
||||
z-index: 1002;
|
||||
|
||||
.right-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.right-menu-item {
|
||||
display: inline-block;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 6px;
|
||||
height: 100%;
|
||||
font-size: 16px;
|
||||
color: #606266;
|
||||
vertical-align: text-bottom;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.hover-effect {
|
||||
cursor: pointer;
|
||||
@@ -180,25 +230,70 @@ function setLayout() {
|
||||
.avatar-container {
|
||||
margin-right: 0;
|
||||
margin-left: 5px;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
z-index: 1003;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.avatar-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
gap: 8px;
|
||||
position: relative;
|
||||
|
||||
.user-info-dropdown {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
cursor: pointer;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.nick-name {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
width: 80px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.divider {
|
||||
color: #dcdfe6;
|
||||
font-size: 14px;
|
||||
margin: 0 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.org-name {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 120px;
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
@@ -210,5 +305,99 @@ function setLayout() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
min-width: 150px;
|
||||
padding-right: 5px;
|
||||
|
||||
.right-menu {
|
||||
.avatar-container {
|
||||
.avatar-wrapper {
|
||||
gap: 4px;
|
||||
|
||||
.nick-name {
|
||||
max-width: 60px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.org-name {
|
||||
max-width: 80px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 0 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
min-width: 120px;
|
||||
padding-right: 5px;
|
||||
|
||||
.right-menu {
|
||||
.avatar-container {
|
||||
.avatar-wrapper {
|
||||
.nick-name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.org-name {
|
||||
max-width: 80px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.navbar-dropdown {
|
||||
margin-bottom: 8px !important;
|
||||
z-index: 10010 !important;
|
||||
|
||||
.el-dropdown-menu {
|
||||
margin-bottom: 0 !important;
|
||||
z-index: 10010 !important;
|
||||
max-height: 300px !important;
|
||||
overflow-y: auto !important;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.el-dropdown-menu__item.is-active {
|
||||
color: #409eff !important;
|
||||
font-weight: 500 !important;
|
||||
background-color: #ecf5ff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,32 +1,36 @@
|
||||
<template>
|
||||
<div
|
||||
:class="{ 'has-logo': showLogo }"
|
||||
:style="{
|
||||
backgroundColor:
|
||||
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground,
|
||||
}"
|
||||
class="sidebar-layout"
|
||||
>
|
||||
:class="{ 'has-logo': showLogo }"
|
||||
class="sidebar-wrapper"
|
||||
:style="{
|
||||
backgroundColor:
|
||||
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground,
|
||||
}"
|
||||
>
|
||||
<!-- <logo v-if="showLogo" :collapse="isCollapse" /> -->
|
||||
<el-menu
|
||||
:default-active="activeMenu"
|
||||
:collapse="isCollapse"
|
||||
:background-color="
|
||||
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground
|
||||
"
|
||||
:text-color="sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
|
||||
:unique-opened="true"
|
||||
:active-text-color="theme"
|
||||
:collapse-transition="false"
|
||||
mode="horizontal"
|
||||
>
|
||||
<sidebar-item
|
||||
v-for="(route, index) in sidebarRouters"
|
||||
:key="route.path + index"
|
||||
:item="route"
|
||||
:base-path="route.path"
|
||||
/>
|
||||
</el-menu>
|
||||
<div class="menu-container">
|
||||
<div class="menu-scrollbar">
|
||||
<el-menu
|
||||
:default-active="activeMenu"
|
||||
:collapse="isCollapse"
|
||||
:background-color="
|
||||
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground
|
||||
"
|
||||
:text-color="sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
|
||||
:unique-opened="true"
|
||||
:active-text-color="theme"
|
||||
:collapse-transition="false"
|
||||
mode="horizontal"
|
||||
>
|
||||
<sidebar-item
|
||||
v-for="(route, index) in sidebarRouters"
|
||||
:key="route.path + index"
|
||||
:item="route"
|
||||
:base-path="route.path"
|
||||
/>
|
||||
</el-menu>
|
||||
</div>
|
||||
</div>
|
||||
<navbar @setLayout="setLayout" class="navbar-container" />
|
||||
<settings ref="settingRef" />
|
||||
</div>
|
||||
@@ -69,16 +73,61 @@ function setLayout() {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 移除滚动条样式 */
|
||||
.sidebar-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.menu-container {
|
||||
flex: 1;
|
||||
height: 50px;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menu-scrollbar {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar:vertical {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu--horizontal {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
border-bottom: none !important;
|
||||
background-color: transparent !important;
|
||||
min-width: auto;
|
||||
flex-wrap: nowrap;
|
||||
overflow: hidden !important;
|
||||
white-space: nowrap;
|
||||
height: 50px;
|
||||
|
||||
& > .el-menu-item,
|
||||
& > .el-sub-menu {
|
||||
@@ -87,8 +136,11 @@ function setLayout() {
|
||||
color: #fff;
|
||||
padding: 0 15px !important;
|
||||
font-size: 14px;
|
||||
min-width: auto !important;
|
||||
min-width: 120px !important;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.svg-icon) {
|
||||
@@ -98,7 +150,9 @@ function setLayout() {
|
||||
|
||||
:deep(.el-sub-menu__title) {
|
||||
padding-right: 25px !important;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
:deep(.el-sub-menu__icon-arrow) {
|
||||
@@ -110,28 +164,37 @@ function setLayout() {
|
||||
}
|
||||
}
|
||||
|
||||
/* 水平布局,并与 Navbar 正确配合 */
|
||||
.sidebar-layout {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
.navbar-container {
|
||||
flex-shrink: 0;
|
||||
height: 50px;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
z-index: 1002;
|
||||
}
|
||||
|
||||
& > .el-menu {
|
||||
/* 响应式处理 */
|
||||
@media (max-width: 768px) {
|
||||
.menu-container {
|
||||
flex: 1;
|
||||
height: 50px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
&.has-logo {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
.el-menu--horizontal {
|
||||
& > .el-menu-item,
|
||||
& > .el-sub-menu {
|
||||
padding: 0 12px !important;
|
||||
min-width: 80px !important;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.el-menu--horizontal {
|
||||
& > .el-menu-item,
|
||||
& > .el-sub-menu {
|
||||
padding: 0 8px !important;
|
||||
min-width: 60px !important;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -105,6 +105,7 @@ function setLayout() {
|
||||
left: 0;
|
||||
z-index: 1001;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.35);
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.sidebar-container {
|
||||
|
||||
@@ -1,123 +1,112 @@
|
||||
import { createApp } from 'vue'
|
||||
import { createApp } from 'vue';
|
||||
|
||||
// 修复 util._extend 已弃用警告(仅在 Node.js 环境中需要)
|
||||
if (typeof process !== 'undefined' && process.versions && process.versions.node) {
|
||||
try {
|
||||
import('util').then(util => {
|
||||
if (!util._extend) {
|
||||
util._extend = function(destination, source) {
|
||||
for (var key in source) {
|
||||
if (source.hasOwnProperty(key)) {
|
||||
destination[key] = source[key];
|
||||
}
|
||||
}
|
||||
return destination;
|
||||
};
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('util._extend 补丁加载失败:', e);
|
||||
}
|
||||
}
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import Cookies from 'js-cookie'
|
||||
// 导入 hiprint 并挂载到全局 window 对象
|
||||
import { hiprint } from 'vue-plugin-hiprint';
|
||||
window.hiprint = hiprint;
|
||||
|
||||
import ElementPlus from 'element-plus'
|
||||
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
||||
import 'element-plus/dist/index.css'
|
||||
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';
|
||||
|
||||
import '@/assets/styles/index.scss' // global css
|
||||
import '@/assets/styles/index.scss'; // global css
|
||||
|
||||
import App from './App'
|
||||
import store from './store'
|
||||
import router from './router'
|
||||
import directive from './directive' // directive
|
||||
import App from './App';
|
||||
import store from './store';
|
||||
import router from './router';
|
||||
import directive from './directive'; // directive
|
||||
|
||||
// 注册指令
|
||||
import plugins from './plugins' // plugins
|
||||
import { download, downloadGet } from '@/utils/request'
|
||||
import plugins from './plugins'; // plugins
|
||||
import { download, downloadGet } from '@/utils/request';
|
||||
|
||||
// svg图标
|
||||
import 'virtual:svg-icons-register'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import elementIcons from '@/components/SvgIcon/svgicon'
|
||||
import 'virtual:svg-icons-register';
|
||||
import SvgIcon from '@/components/SvgIcon';
|
||||
import elementIcons from '@/components/SvgIcon/svgicon';
|
||||
|
||||
import './permission' // permission control
|
||||
import './permission'; // permission control
|
||||
|
||||
import { useDict } from '@/utils/dict'
|
||||
import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels} from '@/utils/openhis'
|
||||
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'
|
||||
import Pagination from '@/components/Pagination';
|
||||
// 自定义表格工具组件
|
||||
import RightToolbar from '@/components/RightToolbar'
|
||||
import RightToolbar from '@/components/RightToolbar';
|
||||
// 富文本组件
|
||||
import Editor from "@/components/Editor"
|
||||
import Editor from '@/components/Editor';
|
||||
// 文件上传组件
|
||||
import FileUpload from "@/components/FileUpload"
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
// 图片上传组件
|
||||
import ImageUpload from "@/components/ImageUpload"
|
||||
import ImageUpload from '@/components/ImageUpload';
|
||||
// 图片预览组件
|
||||
import ImagePreview from "@/components/ImagePreview"
|
||||
import ImagePreview from '@/components/ImagePreview';
|
||||
// 自定义树选择组件
|
||||
import TreeSelect from '@/components/TreeSelect'
|
||||
import TreeSelect from '@/components/TreeSelect';
|
||||
// 字典标签组件
|
||||
import DictTag from '@/components/DictTag'
|
||||
import DictTag from '@/components/DictTag';
|
||||
|
||||
// 导入请求工具
|
||||
import request from './utils/request'
|
||||
|
||||
import { ElDialog, ElMessage } from 'element-plus';
|
||||
|
||||
import {registerComponents} from './template';
|
||||
import { registerComponents } from './template';
|
||||
const app = createApp(App);
|
||||
|
||||
if(chrome.webview !== undefined) {
|
||||
if (chrome.webview !== undefined) {
|
||||
// 如果是webview环境,挂载CSharpAccessor对象到vue实例上
|
||||
const csAccessor = chrome.webview.hostObjects.CSharpAccessor;
|
||||
app.config.globalProperties.csAccessor = csAccessor;
|
||||
}
|
||||
|
||||
// 全局方法挂载
|
||||
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
|
||||
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.component('DictTag', DictTag)
|
||||
app.component('Pagination', Pagination)
|
||||
app.component('TreeSelect', TreeSelect)
|
||||
app.component('FileUpload', FileUpload)
|
||||
app.component('ImageUpload', ImageUpload)
|
||||
app.component('ImagePreview', ImagePreview)
|
||||
app.component('RightToolbar', RightToolbar)
|
||||
app.component('Editor', Editor)
|
||||
app.component('DictTag', DictTag);
|
||||
app.component('Pagination', Pagination);
|
||||
app.component('TreeSelect', TreeSelect);
|
||||
app.component('FileUpload', FileUpload);
|
||||
app.component('ImageUpload', ImageUpload);
|
||||
app.component('ImagePreview', ImagePreview);
|
||||
app.component('RightToolbar', RightToolbar);
|
||||
app.component('Editor', Editor);
|
||||
app.use(registerComponents);
|
||||
app.use(ElMessage);
|
||||
app.use(router);
|
||||
app.use(store);
|
||||
app.use(plugins);
|
||||
app.use(elementIcons);
|
||||
app.component('svg-icon', SvgIcon);
|
||||
directive(app);
|
||||
// 全局禁止点击遮罩层关闭弹窗
|
||||
ElDialog.props.closeOnClickModal.default = false;
|
||||
// 使用element-plus 并且设置全局的大小
|
||||
app.use(ElementPlus, {
|
||||
locale: zhCn,
|
||||
// 支持 large、default、small
|
||||
size: Cookies.get('size') || 'default'
|
||||
})
|
||||
app.use(ElMessage)
|
||||
app.use(registerComponents)
|
||||
app.use(router)
|
||||
app.use(store)
|
||||
app.use(plugins)
|
||||
app.use(elementIcons)
|
||||
app.component('svg-icon', SvgIcon)
|
||||
directive(app)
|
||||
// 全局禁止点击遮罩层关闭弹窗
|
||||
ElDialog.props.closeOnClickModal.default = false;
|
||||
size: Cookies.get('size') || 'default',
|
||||
});
|
||||
|
||||
app.mount('#app')
|
||||
app.mount('#app');
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createWebHistory, createRouter } from 'vue-router'
|
||||
import { createWebHistory, createRouter } from 'vue-router';
|
||||
/* Layout */
|
||||
import Layout from '@/layout'
|
||||
import Layout from '@/layout';
|
||||
import { path } from 'd3';
|
||||
|
||||
/**
|
||||
* Note: 路由配置项说明
|
||||
@@ -34,27 +35,31 @@ 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,
|
||||
},
|
||||
// 401权限不足路由
|
||||
{
|
||||
path: '/401',
|
||||
component: () => import('@/views/error/401'),
|
||||
hidden: true
|
||||
hidden: true,
|
||||
},
|
||||
// 首页路由
|
||||
{
|
||||
@@ -66,11 +71,10 @@ 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,
|
||||
@@ -81,38 +85,15 @@ export const constantRoutes = [
|
||||
path: 'profile',
|
||||
component: () => import('@/views/system/user/profile/index'),
|
||||
name: 'Profile',
|
||||
meta: { title: '个人中心', icon: 'user' }
|
||||
}
|
||||
]
|
||||
meta: { title: '个人中心', icon: 'user' },
|
||||
},
|
||||
],
|
||||
},
|
||||
// 套餐管理相关路由 - 添加到公共路由确保始终可用
|
||||
{
|
||||
path: '/maintainSystem/Inspection/PackageManagement',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
||||
name: 'DirectPackageManagement',
|
||||
meta: { title: '套餐管理' }
|
||||
}
|
||||
]
|
||||
path: '/tpr',
|
||||
component: () => import('@/views/inpatientNurse/tprSheet/index.vue'),
|
||||
},
|
||||
// {
|
||||
// path: '/reservationRecord2/appoinmentmanage',
|
||||
// component: Layout,
|
||||
// hidden: true,
|
||||
// children: [
|
||||
// {
|
||||
// path: '',
|
||||
// component: () => import('@/views/appoinmentmanage/clinicRoom/index.vue'),
|
||||
// name: 'DirectClinicRoom',
|
||||
// meta: { title: '门诊出诊医生诊室设置' }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
];
|
||||
|
||||
// 动态路由 - 基于用户权限动态加载的路由
|
||||
export const dynamicRoutes = [
|
||||
@@ -257,9 +238,9 @@ export const dynamicRoutes = [
|
||||
path: 'set/:tenantId(\\d+)',
|
||||
component: () => import('@/views/system/tenant/setUser'),
|
||||
name: 'SetUser',
|
||||
meta: { title: '所属用户', activeMenu: '/system/tenant' }
|
||||
}
|
||||
]
|
||||
meta: { title: '所属用户', activeMenu: '/system/basicmanage/tenant' },
|
||||
},
|
||||
],
|
||||
},
|
||||
//租户合同管理路由
|
||||
{
|
||||
@@ -272,130 +253,81 @@ export const dynamicRoutes = [
|
||||
path: 'set/:tenantId(\\d+)',
|
||||
component: () => import('@/views/system/tenant/setContract'),
|
||||
name: 'SetContract',
|
||||
meta: { title: '合同管理', activeMenu: '/system/tenant' }
|
||||
}
|
||||
]
|
||||
meta: { title: '合同管理', activeMenu: '/system/basicmanage/tenant' },
|
||||
},
|
||||
],
|
||||
},
|
||||
// 用户角色分配路由
|
||||
// {
|
||||
// path: '/system/user-auth',
|
||||
// component: Layout,
|
||||
// hidden: true,
|
||||
// permissions: ['system:user:edit'],
|
||||
// children: [
|
||||
// {
|
||||
// path: 'role/:userId(\\d+)',
|
||||
// component: () => import('@/views/system/user/authRole'),
|
||||
// name: 'AuthRole',
|
||||
// meta: { title: '分配角色', activeMenu: '/system/user' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// // 角色用户分配路由
|
||||
// {
|
||||
// path: '/system/role-auth',
|
||||
// component: Layout,
|
||||
// hidden: true,
|
||||
// permissions: ['system:role:edit'],
|
||||
// children: [
|
||||
// {
|
||||
// path: 'user/:roleId(\\d+)',
|
||||
// component: () => import('@/views/system/role/authUser'),
|
||||
// name: 'AuthUser',
|
||||
// meta: { title: '分配用户', activeMenu: '/system/role' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// // 字典数据路由
|
||||
// {
|
||||
// path: '/system/dict-data',
|
||||
// component: Layout,
|
||||
// hidden: true,
|
||||
// permissions: ['system:dict:list'],
|
||||
// children: [
|
||||
// {
|
||||
// path: 'index/:dictId(\\d+)',
|
||||
// component: () => import('@/views/system/dict/data'),
|
||||
// name: 'Data',
|
||||
// meta: { title: '字典数据', activeMenu: '/system/dict' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// 系统监控路由
|
||||
// {
|
||||
// path: '/monitor',
|
||||
// component: Layout,
|
||||
// redirect: '/monitor/operlog',
|
||||
// name: 'Monitor',
|
||||
// meta: { title: '系统监控', icon: 'monitor' },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'operlog', // 操作日志路由
|
||||
// component: () => import('@/views/monitor/operlog/index.vue'),
|
||||
// name: 'Operlog',
|
||||
// meta: { title: '操作日志', icon: 'operlog', permissions: ['monitor:operlog:list'] }
|
||||
// },
|
||||
// {
|
||||
// path: 'logininfor', // 登录日志路由
|
||||
// component: () => import('@/views/monitor/logininfor/index.vue'),
|
||||
// name: 'Logininfor',
|
||||
// meta: { title: '登录日志', icon: 'logininfor', permissions: ['monitor:logininfor:list'] }
|
||||
// },
|
||||
// {
|
||||
// path: 'job', // 定时任务路由
|
||||
// component: () => import('@/views/monitor/job/index.vue'),
|
||||
// name: 'Job',
|
||||
// meta: { title: '定时任务', icon: 'job', permissions: ['monitor:job:list'] }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// 系统工具路由
|
||||
// {
|
||||
// path: '/tool',
|
||||
// component: Layout,
|
||||
// redirect: '/tool/gen',
|
||||
// name: 'Tool',
|
||||
// meta: { title: '系统工具', icon: 'tool' },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'gen', // 代码生成路由
|
||||
// component: () => import('@/views/tool/gen/index.vue'),
|
||||
// name: 'Gen',
|
||||
// meta: { title: '代码生成', icon: 'gen', permissions: ['tool:gen:list'] }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// 定时任务日志路由
|
||||
// {
|
||||
// path: '/monitor/job-log',
|
||||
// component: Layout,
|
||||
// hidden: true,
|
||||
// permissions: ['monitor:job:list'],
|
||||
// children: [
|
||||
// {
|
||||
// path: 'index/:jobId(\\d+)',
|
||||
// component: () => import('@/views/monitor/job/log'),
|
||||
// name: 'JobLog',
|
||||
// meta: { title: '调度日志', activeMenu: '/monitor/job' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// 代码生成编辑路由
|
||||
// {
|
||||
// path: '/tool/gen-edit',
|
||||
// component: Layout,
|
||||
// hidden: true,
|
||||
// permissions: ['tool:gen:edit'],
|
||||
// children: [
|
||||
// {
|
||||
// path: 'index/:tableId(\\d+)',
|
||||
// component: () => import('@/views/tool/gen/editTable'),
|
||||
// name: 'GenEdit',
|
||||
// meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
{
|
||||
path: '/system/user-auth',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:user:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'role/:userId(\\d+)',
|
||||
component: () => import('@/views/system/user/authRole'),
|
||||
name: 'AuthRole',
|
||||
meta: { title: '分配角色', activeMenu: '/system/user' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/system/role-auth',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:role:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'user/:roleId(\\d+)',
|
||||
component: () => import('@/views/system/role/authUser'),
|
||||
name: 'AuthUser',
|
||||
meta: { title: '分配用户', activeMenu: '/system/role' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/system/dict-data',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:dict:list'],
|
||||
children: [
|
||||
{
|
||||
path: 'index/:dictId(\\d+)',
|
||||
component: () => import('@/views/system/dict/data'),
|
||||
name: 'Data',
|
||||
meta: { title: '字典数据', activeMenu: '/system/dict' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/monitor/job-log',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['monitor:job:list'],
|
||||
children: [
|
||||
{
|
||||
path: 'index/:jobId(\\d+)',
|
||||
component: () => import('@/views/monitor/job/log'),
|
||||
name: 'JobLog',
|
||||
meta: { title: '调度日志', activeMenu: '/monitor/job' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/tool/gen-edit',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['tool:gen:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'index/:tableId(\\d+)',
|
||||
component: () => import('@/views/tool/gen/editTable'),
|
||||
name: 'GenEdit',
|
||||
meta: { title: '修改生成配置', activeMenu: '/tool/gen' },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// 合并常量路由和动态路由,确保所有路由都能被访问
|
||||
const allRoutes = [...constantRoutes, ...dynamicRoutes];
|
||||
@@ -414,9 +346,9 @@ const router = createRouter({
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
// 页面滚动行为:如果有保存的位置则恢复,否则滚动到顶部
|
||||
if (savedPosition) {
|
||||
return savedPosition
|
||||
return savedPosition;
|
||||
} else {
|
||||
return { top: 0 }
|
||||
return { top: 0 };
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,8 +19,7 @@ const useUserStore = defineStore(
|
||||
roles: [],
|
||||
permissions: [],
|
||||
tenantId: '',
|
||||
hospitalName:'',
|
||||
status: '' // 用户状态:0-启用(管理员), 1-禁用(普通人员)
|
||||
hospitalName:''
|
||||
}),
|
||||
actions: {
|
||||
// 登录
|
||||
@@ -65,7 +64,6 @@ const useUserStore = defineStore(
|
||||
this.avatar = avatar
|
||||
this.hospitalName = res.optionJson.hospitalName
|
||||
|
||||
this.status = user.status // 保存用户状态
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
|
||||
449
openhis-ui-vue3/src/template/DischargeDiagnosisCertificate.vue
Normal file
449
openhis-ui-vue3/src/template/DischargeDiagnosisCertificate.vue
Normal file
@@ -0,0 +1,449 @@
|
||||
<template>
|
||||
<div class="medical-form">
|
||||
<div class="patient-name">
|
||||
患者姓名:{{ patient?.patientName || '未知' }} 病历号:{{
|
||||
patient?.busNo || '未知'
|
||||
}}
|
||||
</div>
|
||||
<h2 style="text-align: center">长春市朝阳区中医院</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="patientName" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input
|
||||
disabled
|
||||
v-model="formData.patientName"
|
||||
type="text"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="年龄" prop="age" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input disabled v-model="formData.age" type="text" placeholder="请输入" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input v-model="formData.gender" type="text" placeholder="请输入" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="住院号" prop="busNo" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input disabled v-model="formData.busNo" type="text" placeholder="请输入" />
|
||||
</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="请输入" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="入院日期" prop="admissionDate" class="row-item">
|
||||
<el-date-picker
|
||||
v-model="formData.admissionDate"
|
||||
type="date"
|
||||
placeholder="选择入院日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="出院日期" prop="dischargeDate" class="row-item">
|
||||
<el-date-picker
|
||||
v-model="formData.dischargeDate"
|
||||
type="date"
|
||||
placeholder="选择出院日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="住院天数" prop="hospitalDays" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input disabled v-model="formData.hospitalDays" placeholder="请输入" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<h4 class="section-title">二、诊断</h4>
|
||||
<!-- 3. 出院诊断(必填) -->
|
||||
<el-form-item label="出院诊断" prop="DischargeDiagnosis" class="required form-item-single">
|
||||
<el-input
|
||||
v-model="formData.DischargeDiagnosis"
|
||||
type="textarea"
|
||||
placeholder="请输入出院诊断"
|
||||
:autosize="{ minRows: 1 }"
|
||||
style="resize: none; padding-right: 10px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- 4. 出院病情摘要及诊疗经过 -->
|
||||
<el-form-item
|
||||
label="出院病情摘要及诊疗经过"
|
||||
prop="SummaryAndDiagnosisAndTreatmentProcess"
|
||||
class="form-item-single"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.SummaryAndDiagnosisAndTreatmentProcess"
|
||||
type="textarea"
|
||||
placeholder="请输入出院病情摘要及诊疗经过"
|
||||
:autosize="{ minRows: 1 }"
|
||||
style="resize: none; padding-right: 10px"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
label="出院后要求及注意事项"
|
||||
prop="RequirementsAndPrecautionsAfterDischarge"
|
||||
class="form-item-single"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.RequirementsAndPrecautionsAfterDischarge"
|
||||
type="textarea"
|
||||
placeholder="请输入出院后要求及注意事项"
|
||||
:autosize="{ minRows: 1 }"
|
||||
style="resize: none; padding-right: 10px"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
label="中医调护"
|
||||
prop="TraditionalChineseMedicineNursing"
|
||||
class="form-item-single"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.TraditionalChineseMedicineNursing"
|
||||
type="textarea"
|
||||
placeholder="请输入中医调护"
|
||||
:autosize="{ minRows: 1 }"
|
||||
style="resize: none; padding-right: 10px"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<DisDiagnMedicalRecord v-if="isShowprintDom" ref="recordPrintRef"></DisDiagnMedicalRecord>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted, watch, nextTick } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
import DisDiagnMedicalRecord from '../views/hospitalRecord/components/disDiagnMedicalRecord.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'DischargeDiagnosisCertificate',
|
||||
});
|
||||
|
||||
// Props与事件
|
||||
const props = defineProps({
|
||||
patientInfo: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const recordPrintRef = ref();
|
||||
const isShowprintDom = ref(false);
|
||||
|
||||
const patient = props.patientInfo;
|
||||
|
||||
// const props = defineProps({});
|
||||
const emits = defineEmits(['submitOk']);
|
||||
|
||||
// 数据初始化
|
||||
// const patient = ref(null);
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
patientName: '', // 姓名
|
||||
age: '', // 年龄
|
||||
gender: '', // 性别
|
||||
busNo: '', // 住院号
|
||||
admissionDate: '', // 入院日期
|
||||
dischargeDate: '', // 出院日期
|
||||
hospitalDays: '', // 住院天数
|
||||
DischargeDiagnosis: '', // 出院诊断
|
||||
SummaryAndDiagnosisAndTreatmentProcess: '', // 出院病情摘要及诊疗经过
|
||||
RequirementsAndPrecautionsAfterDischarge: '', // 出院后要求及注意事项
|
||||
TraditionalChineseMedicineNursing: '', // 中医调护
|
||||
});
|
||||
|
||||
// 表单校验规则
|
||||
const rules = reactive({
|
||||
dischargeDiagnosis: [
|
||||
{
|
||||
required: true,
|
||||
message: '请填写出院诊断',
|
||||
trigger: ['blur', 'submit'],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// 提交函数
|
||||
const submit = () => {
|
||||
emits('submitOk', formData);
|
||||
};
|
||||
// 表单数据赋值
|
||||
const setFormData = (data) => {
|
||||
if (data) {
|
||||
Object.assign(formData, data);
|
||||
}
|
||||
};
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
// patient.value = patientInfo.value;
|
||||
// 组件挂载时自动填充患者信息
|
||||
// fillPatientInfo(patientInfo.value);
|
||||
if (!formData.patientName) {
|
||||
formData.patientName = patient?.patientName || '';
|
||||
}
|
||||
if (!formData.gender) {
|
||||
formData.gender = patient?.genderEnum_enumText || '';
|
||||
}
|
||||
if (!formData.age) {
|
||||
formData.age = patient?.age || '';
|
||||
}
|
||||
if (!formData.department) {
|
||||
formData.department = patient?.inHospitalOrgName || '';
|
||||
}
|
||||
if (!formData.bedNo) {
|
||||
formData.bedNo = patient?.houseName + '-' + patient?.bedName;
|
||||
}
|
||||
if (!formData.busNo) {
|
||||
formData.busNo = patient?.busNo || '';
|
||||
}
|
||||
if (!formData.admissionDate) {
|
||||
formData.admissionDate = patient?.inHospitalTime || '';
|
||||
}
|
||||
if (!formData.hospitalDays) {
|
||||
formData.hospitalDays = patient?.inHospitalDays;
|
||||
}
|
||||
console.log('patientInfo========>', JSON.stringify(props.patientInfo));
|
||||
});
|
||||
|
||||
// 监听患者信息变化,实现联动显示和自动填充
|
||||
// watch(
|
||||
// () => patientInfo.value,
|
||||
// (newPatientInfo) => {
|
||||
// patient.value = newPatientInfo;
|
||||
// // 患者信息变化时自动填充
|
||||
// fillPatientInfo(newPatientInfo);
|
||||
// },
|
||||
// { deep: true }
|
||||
// );
|
||||
|
||||
// 自动填充患者信息到表单
|
||||
const fillPatientInfo = (patientData) => {
|
||||
if (!patientData) {
|
||||
ElMessage.warning('未获取到患者信息,请确保已选择患者');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 填充基本信息,处理可能的数据缺失情况
|
||||
formData.patientName = patientData.patientName || '';
|
||||
formData.age = patientData.age || '';
|
||||
formData.gender = patientData.genderEnum_enumText || '';
|
||||
formData.busNo = patientData.busNo || '';
|
||||
formData.hospitalDays = patientData.inHospitalDays || '';
|
||||
} catch (error) {
|
||||
console.error('填充患者信息时发生错误:', error);
|
||||
ElMessage.error('自动填充患者信息失败,请检查数据源格式');
|
||||
}
|
||||
};
|
||||
|
||||
// 打印方法
|
||||
const printFun = () => {
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData(formData);
|
||||
nextTick(() => {
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露接口
|
||||
defineExpose({ formData, submit, setFormData, fillPatientInfo, printFun });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 表单外层容器 */
|
||||
.medical-form {
|
||||
max-width: 1200px;
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
height: auto;
|
||||
margin: 15px auto;
|
||||
padding: 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
font-family: Arial, sans-serif;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden; /* 防止内部内容溢出 */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 顶部姓名样式 */
|
||||
.patient-name {
|
||||
display: inline-block;
|
||||
margin-bottom: 15px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 滚动内容容器 */
|
||||
.form-scroll-container {
|
||||
width: 100%;
|
||||
max-height: 55vh;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #ccc #f5f5f5;
|
||||
position: relative;
|
||||
}
|
||||
.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%;
|
||||
min-width: 0; /* 防止内容强制拉伸容器 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 区域通用样式 */
|
||||
.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; /* 统一元素间距 */
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.row-item {
|
||||
margin-bottom: 0; /* 取消底部间距,避免换行重叠 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 基础信息项:适配短输入框 */
|
||||
.row-item:not(.history-item) {
|
||||
min-width: 160px; /* 基础信息项最小宽度 */
|
||||
}
|
||||
|
||||
/* 带单位的输入框样式 */
|
||||
.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: 18px 0;
|
||||
}
|
||||
|
||||
/* 必填项红色星号 */
|
||||
.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;
|
||||
}
|
||||
|
||||
/* 确保textarea的rows属性生效 */
|
||||
.el-textarea__inner {
|
||||
min-height: auto !important;
|
||||
height: auto !important;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
/* 根据rows属性设置高度 */
|
||||
.el-input--textarea {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.medical-form {
|
||||
height: 80vh;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.form-scroll-container {
|
||||
height: calc(100% - 35px);
|
||||
max-height: none;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,24 +1,17 @@
|
||||
<template>
|
||||
<!-- 跌倒/坠床评估护理记录单主容器 -->
|
||||
<div>
|
||||
<div class="business">
|
||||
<!-- 已有记录展示表格 -->
|
||||
<el-table
|
||||
<!-- <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
|
||||
@@ -37,18 +30,15 @@
|
||||
@click="handleDelete(scope.row)"
|
||||
:disabled="admissionDataForm !== undefined"
|
||||
>
|
||||
删除
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</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="
|
||||
@@ -64,12 +54,10 @@
|
||||
</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"
|
||||
@@ -79,7 +67,6 @@
|
||||
style="width: 800px"
|
||||
:disabled="admissionDataForm !== undefined"
|
||||
/>
|
||||
<!-- 时间选择器被注释掉 -->
|
||||
<!-- <span style="margin-left: 5px">时间:</span>
|
||||
<el-time-picker
|
||||
v-model="form.ZKTIME"
|
||||
@@ -90,7 +77,6 @@
|
||||
/> -->
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- 新增/保存按钮 -->
|
||||
<el-col :span="5">
|
||||
<el-button
|
||||
v-if="!updateFlag"
|
||||
@@ -114,7 +100,6 @@
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 危险因素评估表格 -->
|
||||
<el-form-item style="padding-top: 10px; margin: 0px !important">
|
||||
<el-table
|
||||
:data="dangerData"
|
||||
@@ -122,7 +107,6 @@
|
||||
:span-method="handleSpan"
|
||||
style="text-align: center"
|
||||
>
|
||||
<!-- 动态生成表格列 -->
|
||||
<el-table-column
|
||||
v-for="column in dangerColumns"
|
||||
:key="column.key"
|
||||
@@ -131,7 +115,6 @@
|
||||
: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)" />
|
||||
@@ -140,7 +123,6 @@
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 总分显示 -->
|
||||
<el-form-item
|
||||
style="text-align: center; margin-bottom: 0px; padding: 0px"
|
||||
class="changeMajorFromItem"
|
||||
@@ -153,7 +135,6 @@
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 护理措施表格 -->
|
||||
<el-form-item style="padding-top: 10px">
|
||||
<el-table
|
||||
:data="nursingData"
|
||||
@@ -161,7 +142,6 @@
|
||||
:span-method="arraySpanMethod"
|
||||
style="width: 100%"
|
||||
>
|
||||
<!-- 动态生成表格列 -->
|
||||
<el-table-column
|
||||
v-for="column in nursingColumns"
|
||||
:key="column.key"
|
||||
@@ -170,7 +150,6 @@
|
||||
: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)" />
|
||||
@@ -179,7 +158,6 @@
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 护士签字输入框 -->
|
||||
<el-form-item
|
||||
style="text-align: center; margin-bottom: 0px; padding: 0px"
|
||||
class="changeMajorFromItem"
|
||||
@@ -199,7 +177,6 @@
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 备注信息 -->
|
||||
<el-form-item>
|
||||
<el-row :span="20">
|
||||
<el-col :span="5">
|
||||
@@ -220,24 +197,30 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 组件选项定义
|
||||
defineOptions({
|
||||
name: '跌倒/坠床评估护理记录单',
|
||||
name: 'FallBedFallAssessment',
|
||||
});
|
||||
|
||||
// 导入所需模块
|
||||
import { ref, reactive, computed, onMounted } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { patientInfo } from '../views/doctorstation/components/store/patient';
|
||||
|
||||
// 使用路由相关功能
|
||||
// 定义props和emits
|
||||
const props = defineProps({
|
||||
patientInfo: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(['submitOk']);
|
||||
|
||||
// 响应式数据
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
// 定义引用变量
|
||||
const queryRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 基本数据变量
|
||||
const wardCode = ref('');
|
||||
const patientId = ref('');
|
||||
const visitId = ref('');
|
||||
@@ -251,18 +234,17 @@ const totalScore = ref(0);
|
||||
const lastSubmit = ref('');
|
||||
const admissionDataForm = ref(route.params.admissionData);
|
||||
|
||||
// 表单数据模型
|
||||
const form = reactive({
|
||||
ZKDATE: '', // 日期
|
||||
ZKTIME: '', // 时间
|
||||
recordTime: '', // 记录时间
|
||||
totalScore: 0, // 总分
|
||||
bedFallRiskAssessmentList: [], // 跌倒风险评估列表
|
||||
nurseSignature: '', // 护士签名
|
||||
patientCareSessionsCheckedList: [], // 护理措施选中列表
|
||||
ZKDATE: '',
|
||||
ZKTIME: '',
|
||||
recordTime: '',
|
||||
totalScore: 0,
|
||||
bedFallRiskAssessmentList: [],
|
||||
nurseSignature: '',
|
||||
patientCareSessionsCheckedList: [],
|
||||
});
|
||||
|
||||
// 危险因素表格列配置
|
||||
// 危险因素表格列
|
||||
const dangerColumns = [
|
||||
{
|
||||
key: 'content',
|
||||
@@ -327,7 +309,7 @@ const dangerData = ref([
|
||||
{ id: '27', evalContent: '麻醉止痛剂', score: 2, checked: false },
|
||||
]);
|
||||
|
||||
// 护理措施表格列配置
|
||||
// 护理措施表格列
|
||||
const nursingColumns = [
|
||||
{
|
||||
key: 'content',
|
||||
@@ -364,21 +346,21 @@ const instructions = [
|
||||
'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
|
||||
@@ -386,14 +368,12 @@ const handleDangerChange = (row) => {
|
||||
.map((item) => item.id);
|
||||
};
|
||||
|
||||
// 护理措施选择变化处理函数
|
||||
const handleNursingChange = (row) => {
|
||||
form.patientCareSessionsCheckedList = nursingData.value
|
||||
.filter((item) => item.checked)
|
||||
.map((item) => item.id);
|
||||
};
|
||||
|
||||
// 初始化函数:加载模拟数据
|
||||
const init = async () => {
|
||||
// 使用模拟数据,不再调用后端API
|
||||
try {
|
||||
@@ -455,7 +435,6 @@ const init = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 危险因素表格合并单元格处理函数
|
||||
const handleSpan = ({ row, column, rowIndex, columnIndex }) => {
|
||||
if (columnIndex === 0) {
|
||||
if (rowIndex === 0) {
|
||||
@@ -502,7 +481,6 @@ const handleSpan = ({ row, column, rowIndex, columnIndex }) => {
|
||||
return [1, 1];
|
||||
};
|
||||
|
||||
// 护理措施表格合并单元格处理函数
|
||||
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
||||
// 护理措施
|
||||
if (columnIndex === 0) {
|
||||
@@ -519,9 +497,8 @@ const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
||||
return [1, 1];
|
||||
};
|
||||
|
||||
// 提交表单处理函数
|
||||
const onSubmit = async () => {
|
||||
// 检查上次提交时间,防止重复提交
|
||||
// 检查上次提交时间
|
||||
if (lastSubmit.value && new Date() - lastSubmit.value < 2000) {
|
||||
ElMessage.error('禁止重复提交!');
|
||||
return;
|
||||
@@ -546,29 +523,48 @@ const onSubmit = async () => {
|
||||
|
||||
if (isFormEmpty.value) {
|
||||
ElMessage.error('请填写跌倒/坠床评估护理记录单后再进行操作');
|
||||
} else {
|
||||
form.totalScore = totalScore.value;
|
||||
return;
|
||||
}
|
||||
|
||||
// 模拟保存数据,不再调用后端API
|
||||
console.log('保存的数据:', form);
|
||||
// 表单验证通过,收集数据
|
||||
form.totalScore = totalScore.value;
|
||||
|
||||
try {
|
||||
// 准备保存的数据
|
||||
const saveData = {
|
||||
...form,
|
||||
// 添加患者相关信息
|
||||
patientId: patientId.value,
|
||||
visitId: visitId.value,
|
||||
wardCode: wardCode.value,
|
||||
// 确保选中项数组存在
|
||||
bedFallRiskAssessmentList: form.bedFallRiskAssessmentList || [],
|
||||
patientCareSessionsCheckedList: form.patientCareSessionsCheckedList || [],
|
||||
};
|
||||
|
||||
// 提交表单数据
|
||||
console.log('提交保存的数据:', saveData);
|
||||
emits('submitOk', saveData);
|
||||
|
||||
// 更新本地数据
|
||||
if (updateFlag.value) {
|
||||
// 模拟更新操作
|
||||
// 更新操作
|
||||
const updatedIndex = tableDataSource.value.findIndex((item) => item.id === updateId.value);
|
||||
if (updatedIndex !== -1) {
|
||||
tableDataSource.value[updatedIndex].content = { ...form };
|
||||
}
|
||||
ElMessage.success('模拟更新成功');
|
||||
ElMessage.success('更新成功');
|
||||
} else {
|
||||
// 模拟新增操作
|
||||
// 新增操作
|
||||
const newRecord = {
|
||||
id: Date.now().toString(),
|
||||
content: { ...form },
|
||||
};
|
||||
tableDataSource.value.unshift(newRecord);
|
||||
ElMessage.success('模拟新增成功');
|
||||
ElMessage.success('保存成功');
|
||||
}
|
||||
|
||||
// 处理返回逻辑
|
||||
if (admissionDataForm.value !== undefined) {
|
||||
const admissionDataBack = JSON.parse(admissionDataForm.value);
|
||||
admissionDataBack.project2 = totalScore.value;
|
||||
@@ -589,11 +585,14 @@ const onSubmit = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
reset();
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error);
|
||||
ElMessage.error('保存失败,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
// 编辑记录处理函数
|
||||
const handleUpdate = (row) => {
|
||||
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
|
||||
|
||||
@@ -623,7 +622,6 @@ const handleUpdate = (row) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 重置表单函数
|
||||
const reset = () => {
|
||||
Object.assign(form, {
|
||||
ZKDATE: '',
|
||||
@@ -656,7 +654,6 @@ const reset = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 删除记录处理函数
|
||||
const handleDelete = (row) => {
|
||||
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
|
||||
|
||||
@@ -680,7 +677,6 @@ const handleDelete = (row) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 打印预览函数(暂未实现)
|
||||
const dc_ajax_preview = () => {
|
||||
var args = {
|
||||
report: urlAddRandomNo('./grf/NurseRecord_Pressure_208.grf'),
|
||||
@@ -691,7 +687,6 @@ const dc_ajax_preview = () => {
|
||||
webapp_ws_ajax_run(args);
|
||||
};
|
||||
|
||||
// 数据转换函数,用于报表打印
|
||||
const transformData = () => {
|
||||
const jsonDate = [...tableDataSource.value];
|
||||
|
||||
@@ -838,7 +833,7 @@ const transformData = () => {
|
||||
return transformedData;
|
||||
};
|
||||
|
||||
// 组件挂载后执行的生命周期函数
|
||||
// 生命周期钩子
|
||||
onMounted(() => {
|
||||
try {
|
||||
// 安全获取用户信息
|
||||
@@ -851,7 +846,13 @@ onMounted(() => {
|
||||
wardCode.value = window.localStorage.getItem('wardInfo') || '';
|
||||
admissionDataForm.value = route.params.admissionData;
|
||||
|
||||
// 自动初始化表格数据,不再依赖患者ID参数
|
||||
// 获取患者信息
|
||||
if (patientInfo.value) {
|
||||
patientId.value = patientInfo.value.patientId || '';
|
||||
visitId.value = patientInfo.value.visitId || '';
|
||||
}
|
||||
|
||||
// 自动初始化表格数据
|
||||
// 延迟执行,确保所有数据都已初始化
|
||||
setTimeout(() => {
|
||||
init();
|
||||
@@ -864,15 +865,17 @@ onMounted(() => {
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
||||
// 暴露接口
|
||||
defineExpose({ form, submit: onSubmit, reset });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 页面样式定义 */
|
||||
.business {
|
||||
background: white;
|
||||
border-radius: 5px;
|
||||
padding: 10px 16px;
|
||||
height: calc(100vh - var(--barHeight) * 1px - 50px);
|
||||
height: calc(100vh - 250px);
|
||||
overflow: auto;
|
||||
display: grid;
|
||||
grid-row-gap: 16px;
|
||||
@@ -931,10 +934,4 @@ onMounted(() => {
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 备注信息列表样式 */
|
||||
.instructions-list {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -2,20 +2,34 @@
|
||||
<div class="hospital-record-form">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="病案首页(一)" name="first">
|
||||
<medicalRecordFirst :formData="formData"></medicalRecordFirst>
|
||||
<medicalRecordFirst
|
||||
ref="firstRef"
|
||||
:formData="formData"
|
||||
@onCaseFirst="updateCaseFirstDatas"
|
||||
></medicalRecordFirst>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="病案首页(二)" name="second">
|
||||
<medicalRecordSecond :formData="formData"></medicalRecordSecond>
|
||||
<medicalRecordSecond
|
||||
:formData="formData"
|
||||
@onCaseSecond="updateCaseFirstDatas"
|
||||
></medicalRecordSecond>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="病案附页(一)" name="third">
|
||||
<medicalRecordThird :formData="formData"></medicalRecordThird>
|
||||
<el-tab-pane label="病案附页(三)" name="third">
|
||||
<medicalRecordThird
|
||||
:formData="formData"
|
||||
@onCaseThird="updateCaseFirstDatas"
|
||||
></medicalRecordThird>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="form-footer">
|
||||
<button @click="printForm" class="print-btn">打印表单</button>
|
||||
<!-- <button @click="printForm" class="print-btn">打印表单</button> -->
|
||||
<button @click="resetForm" class="reset-btn">重置表单</button>
|
||||
</div>
|
||||
<medicalRecordPrint v-if="isShowprintDom" ref="recordPrintRef"></medicalRecordPrint>
|
||||
<!-- <el-drawer v-model="drawer" size="100%">
|
||||
<medicalRecordPrint ref="recordPrintRef"></medicalRecordPrint>
|
||||
</el-drawer> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -23,7 +37,8 @@
|
||||
defineOptions({
|
||||
name: 'HospitalRecordForm',
|
||||
});
|
||||
import { ref, reactive } from 'vue';
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
// import medicalRecordFirst from './components/medicalRecordFirst.vue';
|
||||
import medicalRecordFirst from '@/views/hospitalRecord/components/medicalRecordFirst.vue';
|
||||
import medicalRecordSecond from '@/views/hospitalRecord/components/medicalRecordSecond.vue';
|
||||
@@ -31,119 +46,615 @@ import medicalRecordThird from '@/views/hospitalRecord/components/medicalRecordT
|
||||
import medicalRecordFirstPrint from '@/views/hospitalRecord/components/medicalRecordFirstPrint.json';
|
||||
import medicalRecordSecondPrint from '@/views/hospitalRecord/components/medicalRecordSecondPrint.json';
|
||||
import medicalRecordThirdPrint from '@/views/hospitalRecord/components/medicalRecordThirdPrint.json';
|
||||
|
||||
import formDataJs from '../views/doctorstation/components/store/medicalpage';
|
||||
import medicalRecordPrint from '../views/hospitalRecord/components/medicalRecordPrint.vue';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
import {
|
||||
getEncounterDiagnosis,
|
||||
getTcmDiagnosis,
|
||||
} from '../views/inpatientDoctor/home/components/api';
|
||||
import { cloneDeep } from 'lodash';
|
||||
const firstRef = ref();
|
||||
const commpoentType = 'medicalRecord';
|
||||
const emit = defineEmits(['submitOk']);
|
||||
const drawer = ref(false);
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
hospital: {
|
||||
orgCode: '41275054-7',
|
||||
paymentMethod: '城乡居民基本医疗保险'
|
||||
//医院信息
|
||||
hospitalInfo: {
|
||||
//组织机构代码
|
||||
orgCode: '41275054-700000',
|
||||
//医疗付款方式
|
||||
medicalPaymentCode: '',
|
||||
},
|
||||
patient: {
|
||||
//患者信息
|
||||
patientInfo: {
|
||||
// 健康卡号
|
||||
healthCardNo: '',
|
||||
name: '',
|
||||
// 患者姓名
|
||||
patientName: '',
|
||||
// 患者性别
|
||||
gender: '',
|
||||
// 出生日期
|
||||
birthDate: '',
|
||||
// 年龄
|
||||
age: '',
|
||||
// 国籍
|
||||
nationality: '中国',
|
||||
// 籍贯
|
||||
nativePlace: '',
|
||||
// 民族
|
||||
ethnicity: '汉族',
|
||||
// 身份证号
|
||||
idCardNo: '',
|
||||
// 户口住址
|
||||
householdAddress: '',
|
||||
workUnit: '',
|
||||
// 工作单位地址
|
||||
workUnitAddress: '',
|
||||
// 联系人姓名
|
||||
contactName: '',
|
||||
// 关系
|
||||
contactRelation: '',
|
||||
// 联系人地址
|
||||
contactAddress: '',
|
||||
contactPhone: ''
|
||||
// 联系人电话
|
||||
contactPhone: '',
|
||||
},
|
||||
// 住院信息
|
||||
admission: {
|
||||
// 第几次住院
|
||||
times: 1,
|
||||
// 住院号
|
||||
hospitalNo: '',
|
||||
recordNo: '',
|
||||
channel: '',
|
||||
// 病案号
|
||||
medicalRecordNo: '',
|
||||
// 入院途径
|
||||
admissionRoute: '',
|
||||
// 入院时间
|
||||
admitTime: '',
|
||||
// 入院科室
|
||||
department: '',
|
||||
// 病房
|
||||
ward: '',
|
||||
// 确诊日期
|
||||
confirmDate: '',
|
||||
// 出院时间
|
||||
dischargeTime: '',
|
||||
// 出院科室
|
||||
dischargeDepartment: '',
|
||||
// 病房
|
||||
dischargeWard: '',
|
||||
hospitalDays: ''
|
||||
// 实际住院天数
|
||||
hospitalDays: '',
|
||||
},
|
||||
// 诊断信息
|
||||
diagnosis: {
|
||||
// 主要诊断
|
||||
mainDiagnosis: '',
|
||||
otherDiagnosis: ''
|
||||
// 其他诊断
|
||||
otherDiagnosis: '',
|
||||
},
|
||||
// 医疗信息
|
||||
medicalInfo: {
|
||||
// 是否输血
|
||||
bloodTransfusion: '2',
|
||||
// 血型
|
||||
bloodType: '',
|
||||
// rh类型
|
||||
rhType: '',
|
||||
drugAllergy: '1'
|
||||
// 药物过敏史
|
||||
drugAllergy: '1',
|
||||
},
|
||||
// 医师信息
|
||||
doctorInfo: {
|
||||
// 科主任
|
||||
departmentDirector: '',
|
||||
// 副主任
|
||||
chiefPhysician: '',
|
||||
// 主治医师
|
||||
attendingPhysician: '',
|
||||
// 住院医师
|
||||
residentPhysician: '',
|
||||
// 责任护士
|
||||
chargeNurse: '',
|
||||
// 住院总医师
|
||||
chiefResident: '',
|
||||
// 实习医师
|
||||
intern: '',
|
||||
// 病案质量
|
||||
recordQuality: '1',
|
||||
// 编码员
|
||||
coder: '',
|
||||
qualityControlDate: ''
|
||||
}
|
||||
// 控制日期
|
||||
qualityControlDate: '',
|
||||
},
|
||||
// 病案首页2
|
||||
medicalSecond: {
|
||||
// 手术方式
|
||||
surgeryType: '',
|
||||
// 离院方式
|
||||
leaveType: '',
|
||||
// 是否计划出院
|
||||
isPlan: '',
|
||||
// 目的
|
||||
purpose: '',
|
||||
//昏迷时间---入院前
|
||||
comaDurationTime_before: '',
|
||||
//昏迷时间---入院后
|
||||
comaDurationTime_after: '',
|
||||
// 肿瘤分期
|
||||
tumorStaging: '',
|
||||
// T
|
||||
tumor_T: '',
|
||||
// N
|
||||
tumor_N: '',
|
||||
// M
|
||||
tumor_M: '',
|
||||
// 判断依据
|
||||
judgmentBase: '',
|
||||
// 分化程度
|
||||
degreeDifferentiation: '',
|
||||
// 临床路径
|
||||
enterPath: '',
|
||||
// 变异
|
||||
mutation: '',
|
||||
// 退出路径
|
||||
outPath: '',
|
||||
// 特级护理
|
||||
nursingLevel_spec: '',
|
||||
// 1级护理
|
||||
nursingLevel_1: '',
|
||||
// 2级护理
|
||||
nursingLevel_2: '',
|
||||
// 3级护理
|
||||
nursingLevel_3: '',
|
||||
// 呼吸机使用
|
||||
ventilatorUse: '',
|
||||
// 有创呼吸机使用小时
|
||||
ventilatorUseTime: '',
|
||||
// 手术表
|
||||
tableData_top: [],
|
||||
},
|
||||
// 病案首页3
|
||||
// 住院费用
|
||||
hospitalization: {
|
||||
// 总费用
|
||||
hosCharges: '',
|
||||
// 自付金额
|
||||
hosCharges_self: '',
|
||||
},
|
||||
// 综合医疗服务类
|
||||
medicalServices: {
|
||||
// 一般医疗服务类
|
||||
medicalServices_1: '',
|
||||
// 一般治疗操作费
|
||||
medicalServices_2: '',
|
||||
// 护理费
|
||||
medicalServices_3: '',
|
||||
// 其他费用
|
||||
medicalServices_4: '',
|
||||
},
|
||||
// 诊断类
|
||||
diagnosisClass: {
|
||||
// 病理诊断
|
||||
diagnosis_5: '',
|
||||
// 实验室诊断
|
||||
diagnosis_6: '',
|
||||
// 影像学诊断
|
||||
diagnosis_7: '',
|
||||
// 临床诊断
|
||||
diagnosis_8: '',
|
||||
},
|
||||
// 治疗类
|
||||
treatmentClass: {
|
||||
// 非手术治疗项目费
|
||||
treatment_9: '',
|
||||
// 临床物理治疗
|
||||
treatment_9_1: '',
|
||||
// 手术治疗费
|
||||
treatment_10: '',
|
||||
// 麻醉费
|
||||
treatment_10_1: '',
|
||||
// 手术费
|
||||
treatment_10_2: '',
|
||||
},
|
||||
// 康复类
|
||||
recoveryClass: {
|
||||
// 康复费
|
||||
recovery_11: '',
|
||||
},
|
||||
// 中医类
|
||||
TCMClass: {
|
||||
// 中医治疗费
|
||||
TCM_12: '',
|
||||
},
|
||||
// 西药类
|
||||
WesternClass: {
|
||||
// 西药费
|
||||
Western_13: '',
|
||||
// 抗菌药物费
|
||||
Western_13_1: '',
|
||||
},
|
||||
// 中药类
|
||||
chineseClass: {
|
||||
//中成药
|
||||
chinese_14: '',
|
||||
// 中草药
|
||||
chinese_15: '',
|
||||
},
|
||||
// 血液和血液制品类
|
||||
bloodClass: {
|
||||
// 血费
|
||||
blood_16: '',
|
||||
// 蛋白类制品费
|
||||
blood_17: '',
|
||||
// 球蛋白制品费
|
||||
blood_18: '',
|
||||
// 凝血因子制品费
|
||||
blood_19: '',
|
||||
// 细胞因子制品费
|
||||
blood_20: '',
|
||||
},
|
||||
// 耗材类
|
||||
consumablesClass: {
|
||||
// 检查用一次性医用材料费
|
||||
consumables_21: '',
|
||||
// 治疗用一次性医用材料费
|
||||
consumables_22: '',
|
||||
// 手术用一次性医用材料费
|
||||
consumables_23: '',
|
||||
},
|
||||
// 其他类
|
||||
otherClass: {
|
||||
// 其他费用
|
||||
other_24: '',
|
||||
},
|
||||
// 其他诊断及手术附加页
|
||||
tableData_sub: [],
|
||||
// 手术操作数组
|
||||
tableData_top: [],
|
||||
});
|
||||
|
||||
// Props与事件
|
||||
const props = defineProps({
|
||||
patientInfo: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const activeName = ref('first');
|
||||
const recordPrintRef = ref();
|
||||
const isShowprintDom = ref(false);
|
||||
|
||||
// 打印表单
|
||||
const printForm = () => {
|
||||
// 创建一个新的打印窗口
|
||||
const printWindow = window.open('', '_blank');
|
||||
let printContent
|
||||
// 获取模板字符串并替换转义的插值标记
|
||||
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();
|
||||
}
|
||||
drawer.value = true;
|
||||
// // 创建一个新的打印窗口
|
||||
// const printWindow = window.open('', '_blank');
|
||||
// let printContent;
|
||||
// // 获取模板字符串并替换转义的插值标记
|
||||
// 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();
|
||||
};
|
||||
|
||||
function handleClick() {
|
||||
|
||||
console.log('112313413');
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
Object.keys(formData).forEach(key => {
|
||||
if (typeof formData[key] === 'object') {
|
||||
Object.keys(formData[key]).forEach(subKey => {
|
||||
formData[key][subKey] = '';
|
||||
});
|
||||
const resetFun = (data) => {
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (data[key] instanceof Array) {
|
||||
data[key].length = 0;
|
||||
} else {
|
||||
formData[key] = '';
|
||||
data[key] = '';
|
||||
}
|
||||
});
|
||||
|
||||
// 重置默认值
|
||||
formData.hospital.orgCode = '41275054-7';
|
||||
formData.hospital.paymentMethod = '城乡居民基本医疗保险';
|
||||
formData.patient.nationality = '中国';
|
||||
formData.patient.ethnicity = '汉族';
|
||||
formData.admission.times = 1;
|
||||
formData.medicalInfo.bloodTransfusion = '2';
|
||||
formData.medicalInfo.drugAllergy = '1';
|
||||
formData.doctorInfo.recordQuality = '1';
|
||||
};
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
if (activeName.value == 'first') {
|
||||
// resetFun(firstRef.value.formData.hospitalInfo);
|
||||
// resetFun(firstRef.value.formData.patientInfo);
|
||||
firstRef.value.formData.patientInfo.napl = ''; //籍贯
|
||||
firstRef.value.formData.patientInfo.certno = ''; //身份证号
|
||||
firstRef.value.formData.patientInfo.resd_addr = ''; //户口地址
|
||||
firstRef.value.formData.patientInfo.empr_addr = ''; //工作单位
|
||||
firstRef.value.formData.patientInfo.coner_name = ''; //联系人
|
||||
firstRef.value.formData.patientInfo.coner_rlts_code = ''; //关系
|
||||
firstRef.value.formData.patientInfo.coner_addr = ''; //联系人地址
|
||||
firstRef.value.formData.patientInfo.coner_tel = ''; //联系人电话
|
||||
resetFun(firstRef.value.formData.admission);
|
||||
resetFun(firstRef.value.formData.diagnosis);
|
||||
resetFun(firstRef.value.formData.medicalInfo);
|
||||
resetFun(firstRef.value.formData.doctorInfo);
|
||||
} else if (activeName.value == 'second') {
|
||||
resetFun(firstRef.value.formData.medicalSecond);
|
||||
} else {
|
||||
resetFun(firstRef.value.formData.hospitalization);
|
||||
resetFun(firstRef.value.formData.medicalServices);
|
||||
resetFun(firstRef.value.formData.diagnosisClass);
|
||||
resetFun(firstRef.value.formData.treatmentClass);
|
||||
resetFun(firstRef.value.formData.recoveryClass);
|
||||
resetFun(firstRef.value.formData.TCMClass);
|
||||
resetFun(firstRef.value.formData.WesternClass);
|
||||
resetFun(firstRef.value.formData.chineseClass);
|
||||
resetFun(firstRef.value.formData.bloodClass);
|
||||
resetFun(firstRef.value.formData.consumablesClass);
|
||||
resetFun(firstRef.value.formData.otherClass);
|
||||
firstRef.value.formData.tableData_sub.length = 0;
|
||||
firstRef.value.formData.tableData_top.length = 0;
|
||||
}
|
||||
};
|
||||
//自定义事件更新主数据
|
||||
const updateCaseFirstDatas = (newDatas) => {
|
||||
Object.assign(formData, newDatas);
|
||||
};
|
||||
|
||||
const getList = () => {
|
||||
getEncounterDiagnosis(props.patientInfo.encounterId).then((res) => {
|
||||
if (res.code == 200) {
|
||||
console.log('getEncounterDiagnosis=======>', JSON.stringify(res.data));
|
||||
formDataJs.diagnosisList = res.data;
|
||||
}
|
||||
});
|
||||
getTcmDiagnosis({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
||||
if (res.code == 200) {
|
||||
// if (res.data.illness.length > 0) {
|
||||
// diagnosisNetDatas.value = res.data.illness;
|
||||
// res.data.illness.forEach((item, index) => {
|
||||
// form.value.diagnosisList.push({
|
||||
// name: item.name + '-' + res.data.symptom[index].name,
|
||||
// ybNo: item.ybNo,
|
||||
// medTypeCode: item.medTypeCode,
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
}
|
||||
});
|
||||
};
|
||||
// 点击历史数据回传布局
|
||||
const setFormData = (data) => {
|
||||
if (Object.keys(data).length > 0) {
|
||||
Object.assign(firstRef.value.formData, data);
|
||||
} else {
|
||||
resetForm();
|
||||
}
|
||||
getList();
|
||||
};
|
||||
//保存数据方法
|
||||
const submit = () => {
|
||||
/*
|
||||
{
|
||||
"encounterId": "1987758365116919809",
|
||||
"statusEnum": 5,
|
||||
"busNo": "ZY202511100001",
|
||||
"inHospitalTime": "2025-11-10 13:47:08",
|
||||
"outHospitalTime": null,
|
||||
"patientId": "1981311362744872962",
|
||||
"patientName": "王海明",
|
||||
"genderEnum": 0,
|
||||
"genderEnum_enumText": "男性",
|
||||
"birthDate": "1999-06-18 00:00:00",
|
||||
"age": "26岁",
|
||||
"wardName": "内科病区1",
|
||||
"houseName": "内科病房2",
|
||||
"bedName": "002",
|
||||
"inOrgTime": "2025-11-10 19:36:28",
|
||||
"inHospitalDays": 2,
|
||||
"inHospitalOrgId": "1950367917287616513",
|
||||
"inHospitalOrgName": "住院内科",
|
||||
"contractNo": "0000",
|
||||
"contractName": "自费",
|
||||
"regDiagnosisName": "感冒",
|
||||
"accountId": "1987759000528809985"
|
||||
}
|
||||
*/
|
||||
// const isOk = verifyMethod(formDataJs);
|
||||
if (1) {
|
||||
const cloneParams = cloneDeep(formDataJs);
|
||||
|
||||
// 病例二表
|
||||
const medicalSecondTable = cloneParams.medicalSecond.surgery_tableData.filter((obj) => {
|
||||
return obj.isChoose;
|
||||
});
|
||||
// 病例三表第一张表
|
||||
const other_tableData = cloneParams.other_tableData.filter((obj) => {
|
||||
return obj.isChoose;
|
||||
});
|
||||
// 病例三表第二张表
|
||||
const surgery_tableData = cloneParams.surgery_tableData.filter((obj) => {
|
||||
return obj.isChoose;
|
||||
});
|
||||
// 数据整理
|
||||
let params = {
|
||||
...cloneParams,
|
||||
other_tableData,
|
||||
surgery_tableData,
|
||||
};
|
||||
params.medicalSecond.surgery_tableData = medicalSecondTable;
|
||||
console.log('cloneParams========>', JSON.stringify(params));
|
||||
emit('submitOk', params);
|
||||
}
|
||||
};
|
||||
|
||||
// 公共校验方法
|
||||
const verifyMethod = (data) => {
|
||||
let message = '';
|
||||
if (!data) return false;
|
||||
if (!data.hospitalInfo.orgCode) {
|
||||
message = '请填写组织机构代码';
|
||||
} else if (!data.hospitalInfo.medicalPaymentCode) {
|
||||
message = '请选择医疗付费方式';
|
||||
} else if (!data.patientInfo.healthCardNo) {
|
||||
message = '请填写健康卡号';
|
||||
} else if (!data.patientInfo.patientName) {
|
||||
message = '请填患者姓名';
|
||||
} else if (!data.patientInfo.gender) {
|
||||
message = '请选择患者性别';
|
||||
} else if (!data.patientInfo.birthDate) {
|
||||
message = '请选择出生日期';
|
||||
} else if (!data.patientInfo.age) {
|
||||
message = '请填写患者年龄';
|
||||
} else if (!data.patientInfo.nationality) {
|
||||
message = '请填写国籍';
|
||||
} else if (!data.patientInfo.nativePlace) {
|
||||
message = '请填写籍贯';
|
||||
} else if (!data.patientInfo.ethnicity) {
|
||||
message = '请填写民族';
|
||||
} else if (!data.patientInfo.idCardNo) {
|
||||
message = '请填写身份证号';
|
||||
} else if (!data.patientInfo.householdAddress) {
|
||||
message = '请填写户口地址';
|
||||
} else if (!data.patientInfo.workUnitAddress) {
|
||||
message = '请填写工作单位及地址';
|
||||
} else if (!data.patientInfo.contactName) {
|
||||
message = '请填写联系人姓名';
|
||||
} else if (!data.patientInfo.contactRelation) {
|
||||
message = '请填写与联系人关系';
|
||||
} else if (!data.patientInfo.contactAddress) {
|
||||
message = '请填写地址';
|
||||
} else if (!data.patientInfo.contactPhone) {
|
||||
message = '请填写电话';
|
||||
} else if (!data.admission.times) {
|
||||
message = '请填写第几次住院';
|
||||
} else if (!data.admission.hospitalNo) {
|
||||
message = '请填写住院号';
|
||||
} else if (!data.admission.medicalRecordNo) {
|
||||
message = '请填写病案号';
|
||||
} else if (!data.admission.admissionRoute) {
|
||||
message = '请填写入院途径';
|
||||
} else if (!data.admission.admitTime) {
|
||||
message = '请填写入院时间';
|
||||
} else if (!data.admission.department) {
|
||||
message = '请填写入院科室';
|
||||
} else if (!data.admission.ward) {
|
||||
message = '请填写病房';
|
||||
} else if (!data.admission.confirmDate) {
|
||||
message = '请填写确诊日期';
|
||||
} else if (!data.admission.dischargeTime) {
|
||||
message = '请填写出院时间';
|
||||
} else if (!data.admission.dischargeDepartment) {
|
||||
message = '请填写出院科室';
|
||||
} else if (!data.admission.dischargeWard) {
|
||||
message = '请填写病房';
|
||||
} else if (!data.admission.hospitalDays) {
|
||||
message = '请填写实际住院天数';
|
||||
} else if (!data.diagnosis.mainDiagnosis) {
|
||||
message = '请填写主要诊断';
|
||||
} else if (!data.diagnosis.otherDiagnosis) {
|
||||
message = '请填写其他诊断';
|
||||
} else if (!data.medicalInfo.bloodTransfusion) {
|
||||
message = '请选择是否输血';
|
||||
} else if (!data.medicalInfo.bloodType) {
|
||||
message = '请选择血型';
|
||||
} else if (!data.medicalInfo.rhType) {
|
||||
message = '请选择rh类型';
|
||||
} else if (!data.medicalInfo.drugAllergy) {
|
||||
message = '请选择药物过敏史';
|
||||
} else if (!data.doctorInfo.departmentDirector) {
|
||||
message = '请填写科主任';
|
||||
} else if (!data.doctorInfo.chiefPhysician) {
|
||||
message = '请填写主任(副主任)医师';
|
||||
} else if (!data.doctorInfo.attendingPhysician) {
|
||||
message = '请填写主治医师';
|
||||
} else if (!data.doctorInfo.residentPhysician) {
|
||||
message = '请填写住院医师';
|
||||
} else if (!data.doctorInfo.chargeNurse) {
|
||||
message = '请填写责任护士';
|
||||
} else if (!data.doctorInfo.chiefResident) {
|
||||
message = '请填写住院总医师';
|
||||
} else if (!data.doctorInfo.intern) {
|
||||
message = '请填写实习医师';
|
||||
} else if (!data.doctorInfo.recordQuality) {
|
||||
message = '请填写病案质量';
|
||||
} else if (!data.doctorInfo.coder) {
|
||||
message = '请填写编码员';
|
||||
} else if (!data.doctorInfo.qualityControlDate) {
|
||||
message = '请选择质控日期';
|
||||
} else if (!data.medicalSecond.tableData_top) {
|
||||
message = '请添加手术操作表';
|
||||
} else if (!data.medicalSecond.surgeryType) {
|
||||
message = '请填写手术方式';
|
||||
} else if (!data.medicalSecond.leaveType) {
|
||||
message = '请选择离院方式';
|
||||
} else if (!data.medicalSecond.isPlan) {
|
||||
message = '请选择是否有出院31天内再住院计划';
|
||||
} else if (!data.medicalSecond.purpose) {
|
||||
message = '请填写目的';
|
||||
} else if (!data.medicalSecond.comaDurationTime_before) {
|
||||
message = '请选择颅脑损伤患者昏迷时间-入院前';
|
||||
} else if (!data.medicalSecond.comaDurationTime_after) {
|
||||
message = '请选择颅脑损伤患者昏迷时间-入院后';
|
||||
} else if (!data.medicalSecond.tumorStaging) {
|
||||
message = '请填写肿瘤分期';
|
||||
} else if (!data.medicalSecond.tumor_T) {
|
||||
message = '请填写T';
|
||||
} else if (!data.medicalSecond.tumor_N) {
|
||||
message = '请填写N';
|
||||
} else if (!data.medicalSecond.tumor_M) {
|
||||
message = '请填写M';
|
||||
} else if (!data.medicalSecond.judgmentBase) {
|
||||
message = '请填写判断依据';
|
||||
} else if (!data.medicalSecond.degreeDifferentiation) {
|
||||
message = '请选择分化程度';
|
||||
} else if (!data.medicalSecond.enterPath) {
|
||||
message = '请填写临床路径-进入路径';
|
||||
} else if (!data.medicalSecond.mutation) {
|
||||
message = '请选择是否变异';
|
||||
} else if (!data.medicalSecond.outPath) {
|
||||
message = '请选择退出路径';
|
||||
} else if (!data.medicalSecond.nursingLevel_spec) {
|
||||
message = '请填写特级护理';
|
||||
} else if (!data.medicalSecond.nursingLevel_1) {
|
||||
message = '请填写1级护理';
|
||||
} else if (!data.medicalSecond.nursingLevel_2) {
|
||||
message = '请填写2级护理';
|
||||
} else if (!data.medicalSecond.nursingLevel_3) {
|
||||
message = '请填写3级护理';
|
||||
} else if (!data.medicalSecond.ventilatorUse) {
|
||||
message = '请选择是否使用呼吸机使用';
|
||||
} else if (!data.medicalSecond.ventilatorUseTime) {
|
||||
message = '请填写有创呼吸机使用时间(小时)';
|
||||
}
|
||||
if (message.length > 0) {
|
||||
ElMessage({
|
||||
message,
|
||||
type: 'error',
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
// 打印方法
|
||||
const printFun = () => {
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData();
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
submit,
|
||||
commpoentType,
|
||||
setFormData,
|
||||
printFun,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -213,7 +724,9 @@ label {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
input, select, textarea {
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border: 1px solid #ccc;
|
||||
@@ -234,7 +747,8 @@ textarea {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.print-btn, .reset-btn {
|
||||
.print-btn,
|
||||
.reset-btn {
|
||||
padding: 10px 20px;
|
||||
margin: 0 10px;
|
||||
border: none;
|
||||
@@ -244,7 +758,7 @@ textarea {
|
||||
}
|
||||
|
||||
.print-btn {
|
||||
background-color: #4CAF50;
|
||||
background-color: #4caf50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@@ -275,4 +789,4 @@ textarea {
|
||||
margin: 2cm;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
393
openhis-ui-vue3/src/template/ProgressNoteform.vue
Normal file
393
openhis-ui-vue3/src/template/ProgressNoteform.vue
Normal file
@@ -0,0 +1,393 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
// 1. 基础信息(复用已有变量,补充一致性格式)
|
||||
const patientInfo = ref({
|
||||
name: '',
|
||||
department: '',
|
||||
bed: '',
|
||||
inpatientNo: '',
|
||||
});
|
||||
|
||||
defineOptions({
|
||||
name: 'ProgressNoteform',
|
||||
});
|
||||
|
||||
// 2. 首次病程记录(复用已有变量,补充文本格式)
|
||||
const firstRecordTime = ref('');
|
||||
const firstRecordIntro = ref(
|
||||
''
|
||||
);
|
||||
const caseFeatures =
|
||||
ref('');
|
||||
|
||||
const chinaDiscussion = ref('');
|
||||
|
||||
const westDiscussion = ref('');
|
||||
|
||||
const preliminaryDiagnosis = ref('');
|
||||
|
||||
const treatmentPlan = ref(''); // 添加缺失的变量
|
||||
|
||||
// 3. 后续查房/会诊记录(新增,还原PDF所有章节)
|
||||
const roundRecords = ref([
|
||||
{
|
||||
title: '',
|
||||
time: '',
|
||||
content: '',
|
||||
signature: { doctor: '', physician: '主治医师签名:' }, // 区分普通医师和主治医师签名
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
time: '',
|
||||
content: '',
|
||||
signature: { doctor: '', physician: '副主任医师签名:' },
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
time: '',
|
||||
content: '',
|
||||
signature: { doctor: '', physician: '' },
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
time: '',
|
||||
content: '',
|
||||
signature: { doctor: '', physician: '' },
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
time: '',
|
||||
content: '',
|
||||
signature: { doctor: '', physician: '' },
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
time: '',
|
||||
content: '',
|
||||
signature: { doctor: '', physician: '' },
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
time: '',
|
||||
content: '',
|
||||
signature: { doctor: '', physician: '' },
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
time: '',
|
||||
content: '',
|
||||
signature: { doctor: '', physician: '' },
|
||||
},
|
||||
]);
|
||||
|
||||
// 4. 签名变量(支持所有记录的签名输入)
|
||||
interface Signatures {
|
||||
firstDoctor: string;
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
const signatures = ref<Signatures>({
|
||||
firstDoctor: '', // 首次病程记录医师签名
|
||||
...roundRecords.value.reduce((acc, record, index) => {
|
||||
acc[`round${index}Doctor`] = '';
|
||||
acc[`round${index}Physician`] = '';
|
||||
return acc;
|
||||
}, {} as Record<string, string>),
|
||||
});
|
||||
|
||||
// 5. 打印功能:控制打印范围+样式
|
||||
const handlePrint = () => {
|
||||
// 1. 触发浏览器打印
|
||||
window.print();
|
||||
};
|
||||
|
||||
// 暴露接口
|
||||
defineExpose({ patientInfo, firstRecordTime, firstRecordIntro, caseFeatures, chinaDiscussion, westDiscussion, preliminaryDiagnosis, treatmentPlan, roundRecords, signatures });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="medical-record-container">
|
||||
<!-- 打印按钮:固定在顶部,非打印内容 -->
|
||||
<div class="print-btn-container no-print">
|
||||
<el-button type="primary" @click="handlePrint">打印病历</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 病历主体:打印核心内容 -->
|
||||
<div class="medical-record">
|
||||
<!-- 1. 医院头部(每一页PDF均包含,复用已有样式) -->
|
||||
<div class="hospital-header">
|
||||
<img src="./imgs/logo.png" alt="长春市朝阳区中医院Logo" class="header-logo" />
|
||||
<h1 class="hospital-name">长春市朝阳区中医院</h1>
|
||||
</div>
|
||||
|
||||
<!-- 2. 患者信息栏(每一页PDF均包含,下划线样式) -->
|
||||
<div class="patient-info">
|
||||
<span class="info-item">姓名:{{ patientInfo.name }}</span>
|
||||
<span class="info-item">科室:{{ patientInfo.department }}</span>
|
||||
<span class="info-item">床号:{{ patientInfo.bed }}</span>
|
||||
<span class="info-item">住院号:{{ patientInfo.inpatientNo }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 3. 首次病程记录 -->
|
||||
<div class="record-section">
|
||||
<h2 class="section-main-title">首 次 病 程 记 录</h2>
|
||||
<div class="record-time">{{ firstRecordTime }}</div>
|
||||
<el-input v-model="firstRecordIntro" autosize type="textarea" class="clean-textarea" />
|
||||
|
||||
<!-- 病例特点 -->
|
||||
<h3 class="section-sub-title">一、病例特点</h3>
|
||||
<el-input v-model="caseFeatures" autosize type="textarea" class="clean-textarea" />
|
||||
|
||||
<!-- 拟诊讨论 -->
|
||||
<h3 class="section-sub-title">二、拟诊讨论</h3>
|
||||
<el-input v-model="chinaDiscussion" autosize type="textarea" class="clean-textarea" />
|
||||
<el-input v-model="westDiscussion" autosize type="textarea" class="clean-textarea" />
|
||||
|
||||
<!-- 初步诊断 -->
|
||||
<el-input v-model="preliminaryDiagnosis" autosize type="textarea" class="clean-textarea" />
|
||||
|
||||
<!-- 诊疗计划 -->
|
||||
<el-input v-model="treatmentPlan" autosize type="textarea" class="clean-textarea" />
|
||||
|
||||
<!-- 首次病程记录签名 -->
|
||||
<div class="signature-group">
|
||||
<span class="signature-label">医师签名:</span>
|
||||
<el-input v-model="signatures.firstDoctor" autosize type="textarea" class="clean-textarea signature-input"
|
||||
:rows="1" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 分页分隔线(模拟PDF分页,打印时自动分页) -->
|
||||
<div class="page-break"></div>
|
||||
|
||||
<!-- 5. 后续查房/会诊记录(按时间顺序) -->
|
||||
<div v-for="(record, index) in roundRecords" :key="index" class="record-section">
|
||||
<!-- 重复患者信息(与PDF一致) -->
|
||||
<div class="patient-info page-repeated-info">
|
||||
<span class="info-item">姓名:{{ patientInfo.name }}</span>
|
||||
<span class="info-item">科室:{{ patientInfo.department }}</span>
|
||||
<span class="info-item">床号:{{ patientInfo.bed }}</span>
|
||||
<span class="info-item">住院号:{{ patientInfo.inpatientNo }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 查房标题+时间 -->
|
||||
<h2 class="section-main-title">{{ record.title }}</h2>
|
||||
<div class="record-time">{{ record.time }}</div>
|
||||
|
||||
<!-- 查房内容 -->
|
||||
<el-input v-model="record.content" autosize type="textarea" class="clean-textarea" />
|
||||
|
||||
<!-- 查房签名(区分普通医师/上级医师) -->
|
||||
<div class="signature-group">
|
||||
<span class="signature-label">医师签名:</span>
|
||||
<el-input v-model="signatures[`round${index}Doctor`]" autosize type="textarea"
|
||||
class="clean-textarea signature-input" :rows="1" />
|
||||
|
||||
<span v-if="record.signature.physician" class="signature-label ml-20">
|
||||
{{ record.signature.physician }}
|
||||
</span>
|
||||
<el-input v-if="record.signature.physician" v-model="signatures[`round${index}Physician`]" autosize
|
||||
type="textarea" class="clean-textarea signature-input" :rows="1" />
|
||||
</div>
|
||||
|
||||
<!-- 分页分隔线(最后一条记录无需分页) -->
|
||||
<div v-if="index !== roundRecords.length - 1" class="page-break"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 1. 容器基础样式 */
|
||||
.medical-record-container {
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.print-btn-container {
|
||||
margin-bottom: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* 2. 病历主体样式(模拟A4纸) */
|
||||
.medical-record {
|
||||
max-width: 210mm;
|
||||
/* A4宽度 */
|
||||
min-height: 297mm;
|
||||
/* A4高度 */
|
||||
margin: 0 auto;
|
||||
padding: 20mm;
|
||||
/* A4页边距 */
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
font-family: 'SimSun', '宋体', serif;
|
||||
/* 病历标准字体 */
|
||||
}
|
||||
|
||||
/* 3. 医院头部样式 */
|
||||
.hospital-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.hospital-name {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 4. 患者信息样式 */
|
||||
.patient-info {
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 5px 0;
|
||||
margin-bottom: 15px;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
margin-right: 30px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 5. 记录章节样式 */
|
||||
.record-section {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.section-main-title {
|
||||
text-align: center;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.section-sub-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.record-time {
|
||||
font-size: 14px;
|
||||
margin-bottom: 15px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 6. 签名区域样式 */
|
||||
.signature-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-top: 20px;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.signature-label {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.signature-input {
|
||||
width: 200px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.ml-20 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
/* 7. 分页分隔线(模拟PDF分页) */
|
||||
.page-break {
|
||||
height: 1px;
|
||||
background-color: #eee;
|
||||
margin: 30px 0;
|
||||
page-break-after: always;
|
||||
/* 打印时强制分页 */
|
||||
}
|
||||
|
||||
/* 8. 重复信息样式(后续页面的患者信息) */
|
||||
.page-repeated-info {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* 9. 清洁输入框样式(复用已有,确保无边框) */
|
||||
:deep(.clean-textarea .el-textarea__wrapper) {
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
:deep(.clean-textarea .el-textarea__inner) {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
resize: none;
|
||||
word-break: break-word;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
font-family: inherit;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
/* 病历标准行高 */
|
||||
color: #000;
|
||||
}
|
||||
|
||||
:deep(.clean-textarea .el-textarea__inner:focus) {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* 10. 打印专属样式:控制打印效果 */
|
||||
@media print {
|
||||
|
||||
/* 隐藏非打印内容(如打印按钮) */
|
||||
.no-print {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 强制A4尺寸+无边距 */
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 15mm;
|
||||
/* 打印页边距,匹配PDF */
|
||||
}
|
||||
|
||||
/* 确保背景色打印(部分浏览器默认不打印背景) */
|
||||
body {
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 病历主体无边框阴影,仅打印内容 */
|
||||
.medical-record {
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 文本不换行优化 */
|
||||
.info-item {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
/* 确保输入框内容正常打印 */
|
||||
:deep(.el-textarea__inner) {
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
openhis-ui-vue3/src/template/img/logo.png
Normal file
BIN
openhis-ui-vue3/src/template/img/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
openhis-ui-vue3/src/template/imgs/logo.png
Normal file
BIN
openhis-ui-vue3/src/template/imgs/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
289
openhis-ui-vue3/src/template/inHospitalCaseForm.vue
Normal file
289
openhis-ui-vue3/src/template/inHospitalCaseForm.vue
Normal file
@@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<div class="assessment-page">
|
||||
<div class="page-container">
|
||||
<!-- 医院头部 -->
|
||||
<div class="hospital-header">
|
||||
<h1 class="hospital-name">
|
||||
<span class="hospital-text">长春市朝阳区中医院</span>
|
||||
</h1>
|
||||
</div>
|
||||
<!-- 页面标题 -->
|
||||
<h2 class="form-title">住院病人风险评估表</h2>
|
||||
|
||||
<!-- 表单卡片 -->
|
||||
<el-form :model="formData" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="科室" label-position="top">
|
||||
<el-input v-model="formData.department" readonly="true"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="床号" label-position="top" class="comment-padding">
|
||||
<el-input v-model="formData.bedNo" readonly="true"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="住院号" label-position="top" class="comment-padding">
|
||||
<el-input v-model="formData.busNo" readonly="true"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="姓名" label-position="top">
|
||||
<el-input
|
||||
v-model="formData.patientName"
|
||||
readonly="true"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="性别" label-position="top" class="comment-padding">
|
||||
<el-input
|
||||
v-model="formData.gender"
|
||||
readonly="true"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="年龄" label-position="top" class="comment-padding">
|
||||
<el-input v-model="formData.age" readonly="true" class="auto-resize-input"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="病情简介" label-position="top">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="formData.adm_cond"
|
||||
:autosize="{ minRows: 1, maxRows: 100 }"
|
||||
class="full-width-textarea"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="可能发生的不良后果及预后" label-position="top">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="formData.effectless"
|
||||
:autosize="{ minRows: 1, maxRows: 100 }"
|
||||
class="full-width-textarea"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="评估等级" label-position="top">
|
||||
<el-radio-group v-model="formData.evalLevel">
|
||||
<el-radio label="一般">一般</el-radio>
|
||||
<el-radio label="病重">病重</el-radio>
|
||||
<el-radio label="病危">病危</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="护理等级" label-position="top">
|
||||
<el-radio-group v-model="formData.nurseLevel">
|
||||
<el-radio label="特级护理">特级护理</el-radio>
|
||||
<el-radio label="一级护理">一级护理</el-radio>
|
||||
<el-radio label="二级护理">二级护理</el-radio>
|
||||
<el-radio label="三级护理">三级护理</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="收集资料时间:">
|
||||
<span class="date-display">{{ currentDate }}</span>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="评估医师签名:">
|
||||
<el-input
|
||||
disabled
|
||||
v-model="formData.sign_doc"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="主治医师签名:" class="comment-padding">
|
||||
<el-input
|
||||
v-model="formData.sign_maindoc"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="科主任签名:" class="comment-padding">
|
||||
<el-input
|
||||
v-model="formData.sign_leader"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<inAssessmentForm v-if="isShowprintDom" ref="recordPrintRef"></inAssessmentForm>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, nextTick, reactive, ref } from 'vue';
|
||||
import inAssessmentForm from '../views/hospitalRecord/components/inAssessmentForm.vue';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
defineOptions({
|
||||
name: 'InHospitalCaseForm',
|
||||
});
|
||||
const isShowprintDom = ref(false);
|
||||
const recordPrintRef = ref();
|
||||
const props = defineProps({
|
||||
patientInfo: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const patient = props.patientInfo;
|
||||
const userStore = useUserStore();
|
||||
|
||||
// 表单数据 - 修复:将 formData 定义移到 patient 之后
|
||||
const formData = reactive({
|
||||
department: patient?.inHospitalOrgName || '',
|
||||
bedNo: patient?.bedName || '',
|
||||
busNo: patient?.busNo || '',
|
||||
patientName: patient?.patientName || '',
|
||||
gender: patient?.genderEnum_enumText || '',
|
||||
age: patient?.age || '',
|
||||
adm_cond: '',
|
||||
effectless: '',
|
||||
evalLevel: '',
|
||||
nurseLevel: '',
|
||||
sign_doc: userStore.nickName || '',
|
||||
sign_maindoc: '',
|
||||
sign_leader: '',
|
||||
});
|
||||
|
||||
// 当前日期(YYYY-MM-DD)
|
||||
const currentDate = computed(() => {
|
||||
const d = new Date();
|
||||
const yyyy = d.getFullYear();
|
||||
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const dd = String(d.getDate()).padStart(2, '0');
|
||||
return `${yyyy}-${mm}-${dd}`;
|
||||
});
|
||||
|
||||
//表单引用
|
||||
const formRef = ref(null);
|
||||
|
||||
//提交表单
|
||||
const submit = () => {
|
||||
// 如果需要表单验证,可以使用以下代码
|
||||
// formRef.value.validate((valid) => {
|
||||
// if (valid) {
|
||||
// emits('submitOk', formData);
|
||||
// }
|
||||
// });
|
||||
// 简化版本:
|
||||
emits('submitOk', formData);
|
||||
};
|
||||
|
||||
//表单数据赋值
|
||||
const setFormData = (data) => {
|
||||
if (data) {
|
||||
Object.assign(formData, data);
|
||||
}
|
||||
};
|
||||
|
||||
// 定义 emits
|
||||
const emits = defineEmits(['submitOk']);
|
||||
|
||||
onMounted(() => {
|
||||
// 页面加载完成后触发一次 resize 事件,确保输入框高度正确
|
||||
setTimeout(() => {
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}, 100);
|
||||
console.log('@@@@@=======>', JSON.stringify(props.patientInfo));
|
||||
});
|
||||
// 打印方法
|
||||
const printFun = () => {
|
||||
console.log('入院记录打印');
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData(formData);
|
||||
nextTick(() => {
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
//暴露接口
|
||||
defineExpose({ formData, submit, setFormData, printFun });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* ===== 页面容器与背景 ===== */
|
||||
.comment-padding {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.assessment-page {
|
||||
font-family: 'Microsoft YaHei', 宋体, sans-serif;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ===== 医院头部 ===== */
|
||||
.hospital-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.hospital-name {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: #1f2937;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.hospital-text {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* ===== 表单标题与操作 ===== */
|
||||
.form-title {
|
||||
margin-top: 10px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
margin: 1.25rem 0;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
/* ===== 表单卡片 ===== */
|
||||
.form-card {
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* ===== Textarea 自动扩展样式 ===== */
|
||||
.full-width-textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.full-width-textarea textarea) {
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
/* ===== 日期显示 ===== */
|
||||
.date-display {
|
||||
font-size: 0.95rem;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div class="medical-form">
|
||||
<h2 style="text-align: center;">{{ userStore.hospitalName || '长春市朝阳区中医院' }} -入院记录</h2>
|
||||
|
||||
<h2 style="text-align: center">
|
||||
{{ userStore.hospitalName || '长春市朝阳区中医院' }} -入院记录
|
||||
</h2>
|
||||
|
||||
<!-- 滚动内容区域 -->
|
||||
<div class="form-scroll-container">
|
||||
<el-form
|
||||
@@ -16,90 +18,67 @@
|
||||
<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-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-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-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
|
||||
/>
|
||||
<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-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-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-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-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="选择入院时间"
|
||||
<el-date-picker
|
||||
v-model="formData.admissionTime"
|
||||
type="datetime"
|
||||
placeholder="选择入院时间"
|
||||
value-format="YYYY-MM-DD HH:mm"
|
||||
style="width: 100%;"
|
||||
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="选择记录时间"
|
||||
<el-date-picker
|
||||
v-model="formData.recordTime"
|
||||
type="datetime"
|
||||
placeholder="选择记录时间"
|
||||
value-format="YYYY-MM-DD HH:mm"
|
||||
style="width: 100%;"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="病史陈述者" prop="historyReporter" class="grid-item">
|
||||
<el-input
|
||||
v-model="formData.historyReporter"
|
||||
placeholder="请输入陈述者"
|
||||
clearable
|
||||
/>
|
||||
<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-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>
|
||||
@@ -111,76 +90,76 @@
|
||||
<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="请输入主诉"
|
||||
<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="请详细描述现病史"
|
||||
<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="请输入既往史"
|
||||
<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="请输入个人史"
|
||||
<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="请输入婚育史"
|
||||
<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="请输入月经史"
|
||||
<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="请输入家族史"
|
||||
<el-input
|
||||
v-model="formData.familyHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入家族史"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
@@ -192,10 +171,10 @@
|
||||
<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="请输入中医望闻问切结果"
|
||||
<el-input
|
||||
v-model="formData.tcmInfo"
|
||||
type="textarea"
|
||||
placeholder="请输入中医望闻问切结果"
|
||||
autosize
|
||||
maxlength="600"
|
||||
show-word-limit
|
||||
@@ -209,138 +188,134 @@
|
||||
<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"
|
||||
<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"
|
||||
<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"
|
||||
<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"
|
||||
<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"
|
||||
<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"
|
||||
<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
|
||||
/>
|
||||
<el-input v-model="formData.bmi" placeholder="如29.02" readonly />
|
||||
<span class="unit">kg/m²</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-form-item label="一般情况" prop="general" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.general"
|
||||
type="textarea"
|
||||
placeholder="请输入一般情况"
|
||||
<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="请输入皮肤粘膜情况"
|
||||
<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="请输入胸部检查结果"
|
||||
<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="请输入腹部检查结果"
|
||||
<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="请输入四肢及神经系统检查结果"
|
||||
<el-input
|
||||
v-model="formData.limbsNervous"
|
||||
type="textarea"
|
||||
placeholder="请输入四肢及神经系统检查结果"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
@@ -352,10 +327,10 @@
|
||||
<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="请输入辅助检查结果"
|
||||
<el-input
|
||||
v-model="formData.auxExam"
|
||||
type="textarea"
|
||||
placeholder="请输入辅助检查结果"
|
||||
autosize
|
||||
maxlength="1000"
|
||||
show-word-limit
|
||||
@@ -367,21 +342,21 @@
|
||||
<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="如:胸痹心痛(气阴两虚证)"
|
||||
<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.冠状动脉粥样硬化性心脏病"
|
||||
<el-input
|
||||
v-model="formData.westernDiagnosis"
|
||||
type="textarea"
|
||||
placeholder="如:1.冠状动脉粥样硬化性心脏病"
|
||||
autosize
|
||||
maxlength="800"
|
||||
show-word-limit
|
||||
@@ -391,30 +366,22 @@
|
||||
|
||||
<!-- 7. 签名信息(三列布局) -->
|
||||
<h4 class="section-title">签名信息</h4>
|
||||
<div class="adaptive-grid form-section" style="grid-template-columns: repeat(3, 1fr);">
|
||||
<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-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-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="选择日期"
|
||||
<el-date-picker
|
||||
v-model="formData.signDate"
|
||||
type="datetime"
|
||||
placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD HH:mm"
|
||||
style="width: 100%;"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
@@ -426,16 +393,30 @@
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<admissionRecord v-if="isShowprintDom" ref="recordPrintRef"></admissionRecord>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted } from 'vue';
|
||||
import { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElMessage, ElMessageBox, ElForm, ElFormItem } from 'element-plus';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
import admissionRecord from '../views/hospitalRecord/components/admissionRecord.vue';
|
||||
import {
|
||||
ElInput,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
ElDatePicker,
|
||||
ElButton,
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
} from 'element-plus';
|
||||
import useUserStore from '../store/modules/user';
|
||||
|
||||
const isShowprintDom = ref(false);
|
||||
const recordPrintRef = ref();
|
||||
defineOptions({
|
||||
name: 'InHospitalRecord',
|
||||
components: { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElForm, ElFormItem }
|
||||
components: { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElForm, ElFormItem },
|
||||
});
|
||||
|
||||
// Props与事件
|
||||
@@ -461,26 +442,26 @@ const formData = reactive({
|
||||
gender: patient?.genderEnum_enumText || '',
|
||||
age: patient?.age || '',
|
||||
nation: '',
|
||||
occupation: '',// 职业
|
||||
marriage: '',// 婚姻状况
|
||||
birthplace: '',// 出生地
|
||||
admissionTime: '',// 入院时间
|
||||
recordTime: '',// 记录时间
|
||||
historyReporter: '',// 病史陈述者
|
||||
reliability: '可靠',// 可靠程度
|
||||
occupation: '', // 职业
|
||||
marriage: '', // 婚姻状况
|
||||
birthplace: '', // 出生地
|
||||
admissionTime: '', // 入院时间
|
||||
recordTime: '', // 记录时间
|
||||
historyReporter: '', // 病史陈述者
|
||||
reliability: '可靠', // 可靠程度
|
||||
// 病史信息
|
||||
complaint: '',// 主诉
|
||||
presentIllness: '',// 现病史
|
||||
pastIllness: '',// 既往史
|
||||
personalHistory: '',// 个人史
|
||||
allergyHistory: '',// 过敏史
|
||||
pastHistory: '',// 既往史
|
||||
familyHistory: '',// 家族史
|
||||
maritalHistory: '',// 婚姻史
|
||||
menstrualHistory: '',// 月经史
|
||||
complaint: '', // 主诉
|
||||
presentIllness: '', // 现病史
|
||||
pastIllness: '', // 既往史
|
||||
personalHistory: '', // 个人史
|
||||
allergyHistory: '', // 过敏史
|
||||
pastHistory: '', // 既往史
|
||||
familyHistory: '', // 家族史
|
||||
maritalHistory: '', // 婚姻史
|
||||
menstrualHistory: '', // 月经史
|
||||
// 中医信息
|
||||
tcmInfo: '',
|
||||
|
||||
|
||||
// 体格检查
|
||||
temp: '',
|
||||
pulse: '',
|
||||
@@ -494,44 +475,38 @@ const formData = reactive({
|
||||
chest: '',
|
||||
abdomen: '',
|
||||
limbsNervous: '',
|
||||
|
||||
|
||||
// 辅助检查
|
||||
auxExam: '',
|
||||
|
||||
|
||||
// 诊断信息
|
||||
tcmDiagnosis: '',
|
||||
westernDiagnosis: '',
|
||||
|
||||
|
||||
// 签名信息
|
||||
doctorSign: '',
|
||||
superiorSign: '',
|
||||
signDate: ''
|
||||
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'] }
|
||||
],
|
||||
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'] }
|
||||
{
|
||||
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'] }
|
||||
]
|
||||
admissionTime: [{ required: true, message: '请选择入院时间', trigger: ['change', 'submit'] }],
|
||||
recordTime: [{ required: true, message: '请选择记录时间', trigger: ['change', 'submit'] }],
|
||||
chiefComplaint: [{ required: true, message: '请填写主诉', trigger: ['blur', 'submit'] }],
|
||||
});
|
||||
|
||||
// 生命周期
|
||||
@@ -548,11 +523,11 @@ onMounted(() => {
|
||||
}
|
||||
if (!formData.patientName) {
|
||||
formData.patientName = patient?.patientName || '';
|
||||
}
|
||||
if (!formData.gender) {
|
||||
}
|
||||
if (!formData.gender) {
|
||||
formData.gender = patient?.genderEnum_enumText || '';
|
||||
}
|
||||
if (!formData.age) {
|
||||
}
|
||||
if (!formData.age) {
|
||||
formData.age = patient?.age || '';
|
||||
}
|
||||
if (!formData.hospitalNo) {
|
||||
@@ -571,21 +546,22 @@ watch([() => formData.height, () => formData.weight], ([newHeight, newWeight]) =
|
||||
});
|
||||
|
||||
// 入院时间变化处理
|
||||
watch(() => formData.admissionTime, (val) => {
|
||||
if (val && !formData.recordTime) {
|
||||
ElMessageBox.confirm(
|
||||
'是否将记录时间同步为入院时间?',
|
||||
'时间同步提示',
|
||||
{
|
||||
watch(
|
||||
() => formData.admissionTime,
|
||||
(val) => {
|
||||
if (val && !formData.recordTime) {
|
||||
ElMessageBox.confirm('是否将记录时间同步为入院时间?', '时间同步提示', {
|
||||
confirmButtonText: '同步',
|
||||
cancelButtonText: '手动设置',
|
||||
type: 'info'
|
||||
}
|
||||
).then(() => {
|
||||
formData.recordTime = val;
|
||||
}).catch(() => {});
|
||||
type: 'info',
|
||||
})
|
||||
.then(() => {
|
||||
formData.recordTime = val;
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
// 血压格式校验
|
||||
const validateBloodPressure = () => {
|
||||
@@ -607,7 +583,6 @@ const submit = () => {
|
||||
validateBloodPressure();
|
||||
if (!formData.bp) return; // 格式错误时终止提交
|
||||
}
|
||||
|
||||
emits('submitOk', formData);
|
||||
ElMessage.success('记录保存成功!');
|
||||
}
|
||||
@@ -616,35 +591,33 @@ const submit = () => {
|
||||
|
||||
// 新增:重置表单方法(带确认提示)
|
||||
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('已取消表单重置');
|
||||
});
|
||||
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('已取消表单重置');
|
||||
});
|
||||
};
|
||||
|
||||
// 表单数据赋值
|
||||
@@ -664,8 +637,21 @@ const formatDateTime = (date) => {
|
||||
return `${year}-${month}-${day} ${hour}:${minute}`;
|
||||
};
|
||||
|
||||
// 打印方法
|
||||
const printFun = () => {
|
||||
console.log('入院记录打印');
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData(formData);
|
||||
nextTick(() => {
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露接口
|
||||
defineExpose({ formData, submit, setFormData, handleReset });
|
||||
defineExpose({ formData, submit, setFormData, handleReset, printFun });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -673,8 +659,7 @@ defineExpose({ formData, submit, setFormData, handleReset });
|
||||
.medical-form {
|
||||
max-width: 1200px;
|
||||
width: 100%;
|
||||
height: 700px;
|
||||
margin: 15px auto;
|
||||
height: 28000px;
|
||||
padding: 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
@@ -810,7 +795,8 @@ defineExpose({ formData, submit, setFormData, handleReset });
|
||||
.adaptive-grid {
|
||||
grid-template-columns: 1fr; /* 小屏幕下单列显示 */
|
||||
}
|
||||
.grid-item, .history-item {
|
||||
.grid-item,
|
||||
.history-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
/* 小屏幕按钮居中 */
|
||||
@@ -825,4 +811,4 @@ defineExpose({ formData, submit, setFormData, handleReset });
|
||||
grid-template-columns: repeat(2, 1fr); /* 中等屏幕下两列显示 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
label-width="120px"
|
||||
label-align="left"
|
||||
class="doc-content"
|
||||
style="height: 60vh; overflow: scroll;"
|
||||
style="height: 60vh; overflow: scroll"
|
||||
>
|
||||
<!-- 患者与手术基础信息 -->
|
||||
<section class="doc-section">
|
||||
@@ -23,29 +23,28 @@
|
||||
<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="请输入年龄" />
|
||||
<el-input v-model.number="formData.age" 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"
|
||||
@@ -64,23 +63,23 @@
|
||||
<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>
|
||||
@@ -90,11 +89,15 @@
|
||||
<!-- 手术详情 -->
|
||||
<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-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="开放手术" />
|
||||
@@ -102,12 +105,20 @@
|
||||
<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-input
|
||||
v-model="formData.surgicalApproach"
|
||||
placeholder="如:右上腹经腹直肌切口"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="术中发现" prop="intraoperativeFindings" class="full-width-item required">
|
||||
|
||||
<el-form-item
|
||||
label="术中发现"
|
||||
prop="intraoperativeFindings"
|
||||
class="full-width-item required"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.intraoperativeFindings"
|
||||
type="textarea"
|
||||
@@ -117,7 +128,6 @@
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手术过程" prop="operationProcess" class="full-width-item required">
|
||||
<el-input
|
||||
v-model="formData.operationProcess"
|
||||
@@ -136,26 +146,34 @@
|
||||
<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="请输入出血量" />
|
||||
<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-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"
|
||||
@@ -164,7 +182,6 @@
|
||||
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" />
|
||||
@@ -177,24 +194,25 @@
|
||||
<!-- 签署区域 -->
|
||||
<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));">
|
||||
<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%;"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
@@ -208,16 +226,30 @@
|
||||
<el-button type="warning" @click="handleReset">重置表单</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<intOperRecordSheet v-if="isShowprintDom" ref="recordPrintRef"></intOperRecordSheet>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ElMessage, ElMessageBox, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElDatePicker, ElButton } from 'element-plus';
|
||||
|
||||
import intOperRecordSheet from '../views/hospitalRecord/components/intOperRecordSheet.vue';
|
||||
import {
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
ElDatePicker,
|
||||
ElButton,
|
||||
} from 'element-plus';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
const isShowprintDom = ref(false);
|
||||
const recordPrintRef = ref();
|
||||
// 医院名称
|
||||
const hospitalName = '长春市朝阳区中医院';
|
||||
defineOptions({
|
||||
name: 'iInHospitalSurgicalRecord'
|
||||
name: 'iInHospitalSurgicalRecord',
|
||||
});
|
||||
// 表单引用
|
||||
const formRef = ref(null);
|
||||
@@ -231,113 +263,93 @@ const formData = reactive({
|
||||
age: '',
|
||||
department: '',
|
||||
bedNo: '',
|
||||
operationDateTime: '',// 手术日期时间
|
||||
|
||||
operationDateTime: '', // 手术日期时间
|
||||
|
||||
// 手术团队信息
|
||||
surgeon: '',// 主刀医师
|
||||
firstAssistant: '',// 第一助手
|
||||
secondAssistant: '',// 第二助手
|
||||
anesthesiologist: '',// 麻醉医师
|
||||
circulatingNurse: '',// 巡回护士
|
||||
scrubNurse: '',// 器械护士
|
||||
|
||||
surgeon: '', // 主刀医师
|
||||
firstAssistant: '', // 第一助手
|
||||
secondAssistant: '', // 第二助手
|
||||
anesthesiologist: '', // 麻醉医师
|
||||
circulatingNurse: '', // 巡回护士
|
||||
scrubNurse: '', // 器械护士
|
||||
|
||||
// 手术详情
|
||||
operationName: '',// 规范手术名称
|
||||
operationMethod: '',// 手术方式
|
||||
surgicalApproach: '',// 手术入路
|
||||
intraoperativeFindings: '',// 术中发现
|
||||
operationProcess: '',// 手术过程
|
||||
|
||||
operationName: '', // 规范手术名称
|
||||
operationMethod: '', // 手术方式
|
||||
surgicalApproach: '', // 手术入路
|
||||
intraoperativeFindings: '', // 术中发现
|
||||
operationProcess: '', // 手术过程
|
||||
|
||||
// 术后情况
|
||||
bloodLoss: '',// 术中出血量
|
||||
bloodTransfusion: '',// 输血情况
|
||||
drainageTube: '',// 引流管放置
|
||||
specimenDisposal: '',// 标本处理
|
||||
operationEndTime: '',// 手术结束时间
|
||||
patientDestination: '',// 患者去向
|
||||
|
||||
bloodLoss: '', // 术中出血量
|
||||
bloodTransfusion: '', // 输血情况
|
||||
drainageTube: '', // 引流管放置
|
||||
specimenDisposal: '', // 标本处理
|
||||
operationEndTime: '', // 手术结束时间
|
||||
patientDestination: '', // 患者去向
|
||||
|
||||
// 签署信息
|
||||
surgeonSignature: '',// 手术者签名
|
||||
recorderSignature: '',// 记录者签名
|
||||
recordDate: ''// 记录日期
|
||||
surgeonSignature: '', // 手术者签名
|
||||
recorderSignature: '', // 记录者签名
|
||||
recordDate: '', // 记录日期
|
||||
});
|
||||
|
||||
// Props与事件
|
||||
const props = defineProps({
|
||||
patientInfo: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const patient = props.patientInfo;
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
busNo: [
|
||||
{ required: true, message: '请填写住院号', trigger: ['blur', 'submit'] }
|
||||
],
|
||||
patientName: [
|
||||
{ required: true, message: '请填写患者姓名', trigger: ['blur', 'submit'] }
|
||||
],
|
||||
gender: [
|
||||
{ required: true, message: '请选择性别', trigger: ['change', 'submit'] }
|
||||
],
|
||||
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'] }
|
||||
{ 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'] }
|
||||
{ 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'] }
|
||||
{ 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'] }
|
||||
{ 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'] }
|
||||
{ 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'] }
|
||||
{ type: 'number', min: 0, message: '出血量不能为负数', trigger: ['blur', 'submit'] },
|
||||
],
|
||||
specimenDisposal: [
|
||||
{ required: true, message: '请填写标本处理方式', trigger: ['blur', 'submit'] }
|
||||
{ required: true, message: '请填写标本处理方式', trigger: ['blur', 'submit'] },
|
||||
],
|
||||
operationEndTime: [
|
||||
{ required: true, message: '请选择手术结束时间', trigger: ['change', 'submit'] }
|
||||
{ required: true, message: '请选择手术结束时间', trigger: ['change', 'submit'] },
|
||||
],
|
||||
patientDestination: [
|
||||
{ required: true, message: '请选择患者去向', trigger: ['change', 'submit'] }
|
||||
{ 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'] }
|
||||
]
|
||||
surgeonSignature: [{ required: true, message: '请手术者签名', trigger: ['blur', 'submit'] }],
|
||||
recorderSignature: [{ required: true, message: '请记录者签名', trigger: ['blur', 'submit'] }],
|
||||
recordDate: [{ required: true, message: '请选择记录日期', trigger: ['change', 'submit'] }],
|
||||
});
|
||||
|
||||
// 生命周期
|
||||
@@ -347,18 +359,49 @@ onMounted(() => {
|
||||
formData.operationDateTime = formatDateTime(today);
|
||||
formData.operationEndTime = formatDateTime(today);
|
||||
formData.recordDate = formatDate(today);
|
||||
if (!formData.patientName) {
|
||||
formData.patientName = patient?.patientName || '';
|
||||
}
|
||||
if (!formData.gender) {
|
||||
formData.gender = patient?.genderEnum_enumText || '';
|
||||
}
|
||||
if (!formData.age) {
|
||||
formData.age = patient?.age || '';
|
||||
}
|
||||
if (!formData.department) {
|
||||
formData.department = patient?.inHospitalOrgName || '';
|
||||
}
|
||||
if (!formData.bedNo) {
|
||||
formData.bedNo = patient?.houseName + '-' + patient?.bedName;
|
||||
}
|
||||
if (!formData.busNo) {
|
||||
formData.busNo = patient?.busNo || '';
|
||||
}
|
||||
});
|
||||
|
||||
const emits = defineEmits(['submitOk']);
|
||||
|
||||
// 提交表单
|
||||
const submit = () => {
|
||||
formRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
ElMessage.success('手术记录保存成功');
|
||||
console.log('手术记录数据:', formData);
|
||||
emits('submitOk', formData);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 表单数据赋值
|
||||
const setFormData = (data) => {
|
||||
if (data) {
|
||||
Object.assign(formData, data);
|
||||
if (!formData.busNo) {
|
||||
formData.busNo = patient?.busNo || '';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 打印功能
|
||||
const handlePrint = () => {
|
||||
formRef.value.validate((valid) => {
|
||||
@@ -372,15 +415,11 @@ const handlePrint = () => {
|
||||
|
||||
// 重置表单
|
||||
const handleReset = () => {
|
||||
ElMessageBox.confirm(
|
||||
'确定要重置表单吗?所有已填写内容将被清空',
|
||||
'确认重置',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
ElMessageBox.confirm('确定要重置表单吗?所有已填写内容将被清空', '确认重置', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
formRef.value.resetFields();
|
||||
const today = new Date();
|
||||
formData.operationDateTime = formatDateTime(today);
|
||||
@@ -406,17 +445,31 @@ const formatDateTime = (date) => {
|
||||
const minute = String(date.getMinutes()).padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hour}:${minute}`;
|
||||
};
|
||||
const printFun = () => {
|
||||
console.log('入院记录打印');
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData(formData);
|
||||
nextTick(() => {
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
defineExpose({ submit, setFormData, printFun });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 样式与原代码保持一致,无需修改 */
|
||||
/* 核心容器:PC端限制合理最大宽度,避免超宽屏内容过散 */
|
||||
.medical-document {
|
||||
max-width: 1200px;
|
||||
max-width: 1440px; /* PC端最优宽度,兼顾大屏和常规屏 */
|
||||
width: 98%; /* 占满父容器98%,保留少量边距 */
|
||||
margin: 20px auto;
|
||||
padding: 30px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
font-family: 'SimSun', '宋体', serif;
|
||||
box-sizing: border-box; /* 确保内边距不撑大容器 */
|
||||
}
|
||||
|
||||
.doc-header {
|
||||
@@ -455,11 +508,14 @@ const formatDateTime = (date) => {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 自适应网格:PC端优先展示多列,优化列宽比例 */
|
||||
.adaptive-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
/* PC端最小列宽220px,保证每列内容不拥挤,自动适配列数 */
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 15px 20px;
|
||||
margin-bottom: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
@@ -513,43 +569,58 @@ const formatDateTime = (date) => {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* 仅针对小屏设备做基础适配,优先保证PC端体验 */
|
||||
@media (max-width: 768px) {
|
||||
.medical-document {
|
||||
max-width: 100%;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
|
||||
.adaptive-grid {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-columns: 1fr; /* 移动端强制单列 */
|
||||
}
|
||||
|
||||
|
||||
.doc-title {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 超宽屏(≥1920px)优化:适度增大间距,提升视觉体验 */
|
||||
@media (min-width: 1920px) {
|
||||
.medical-document {
|
||||
max-width: 1600px;
|
||||
padding: 40px;
|
||||
}
|
||||
.adaptive-grid {
|
||||
gap: 20px 25px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 打印样式保留 */
|
||||
@media print {
|
||||
.btn-group {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.medical-document {
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.el-input__inner, .el-select__input, .el-textarea__inner {
|
||||
|
||||
.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>
|
||||
</style>
|
||||
|
||||
@@ -22,29 +22,28 @@
|
||||
<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="请输入年龄" />
|
||||
<el-input v-model.number="formData.age" placeholder="请输入年龄" clearable />
|
||||
<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"
|
||||
@@ -63,11 +62,11 @@
|
||||
<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>
|
||||
@@ -77,7 +76,6 @@
|
||||
<!-- 病情与诊断 -->
|
||||
<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"
|
||||
@@ -88,7 +86,6 @@
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<div class="diagnosis-container">
|
||||
<el-form-item label="中医诊断" prop="tcmDiagnosis" class="diagnosis-item">
|
||||
<el-input
|
||||
@@ -100,7 +97,6 @@
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="西医诊断" prop="westernDiagnosis" class="diagnosis-item">
|
||||
<el-input
|
||||
v-model="formData.westernDiagnosis"
|
||||
@@ -117,7 +113,6 @@
|
||||
<!-- 治疗与检查计划 -->
|
||||
<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"
|
||||
@@ -128,8 +123,12 @@
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="进一步检查项目" prop="examinationItems" class="full-width-item required">
|
||||
|
||||
<el-form-item
|
||||
label="进一步检查项目"
|
||||
prop="examinationItems"
|
||||
class="full-width-item required"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.examinationItems"
|
||||
type="textarea"
|
||||
@@ -159,38 +158,44 @@
|
||||
<!-- 签署区域(优化后:三列自适应+细节样式) -->
|
||||
<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));">
|
||||
<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-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%;"
|
||||
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%;"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
@@ -208,13 +213,53 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ElMessage, ElMessageBox, ElForm, ElFormItem, ElInput, ElSelect, ElOption, ElDatePicker, ElButton } from 'element-plus';
|
||||
import {
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
ElDatePicker,
|
||||
ElButton,
|
||||
} from 'element-plus';
|
||||
|
||||
// 医院名称
|
||||
const hospitalName = '长春市朝阳区中医院';
|
||||
defineOptions({
|
||||
name: 'InHospitalCommunicate'
|
||||
name: 'InHospitalCommunicate',
|
||||
});
|
||||
// Props与事件
|
||||
const props = defineProps({
|
||||
patientInfo: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
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 || '';
|
||||
}
|
||||
if (!formData.department) {
|
||||
formData.department = patient?.inHospitalOrgName || '';
|
||||
}
|
||||
if (!formData.bedNo) {
|
||||
formData.bedNo = patient?.houseName + '-' + patient?.bedName;
|
||||
}
|
||||
});
|
||||
const patient = props.patientInfo;
|
||||
console.log('patient1111=======>', JSON.stringify(patient));
|
||||
// 表单引用
|
||||
const formRef = ref(null);
|
||||
|
||||
@@ -228,89 +273,57 @@ const formData = reactive({
|
||||
department: '',
|
||||
bedNo: '',
|
||||
admissionDate: '',
|
||||
|
||||
// 医疗团队
|
||||
treatingDoctor: '',
|
||||
attendingDoctor: '',
|
||||
departmentHead: '',
|
||||
|
||||
// 病情诊断
|
||||
condition: '',
|
||||
tcmDiagnosis: '',
|
||||
westernDiagnosis: '',
|
||||
|
||||
|
||||
// 治疗检查
|
||||
treatmentPlan: '',
|
||||
examinationItems: '',
|
||||
|
||||
|
||||
// 风险告知
|
||||
riskNotification: '',
|
||||
|
||||
|
||||
// 签署信息
|
||||
patientSignature: '',
|
||||
relationship: '',
|
||||
signatureDate: '',
|
||||
doctorSignature: '',
|
||||
communicationDate: ''
|
||||
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'] }
|
||||
],
|
||||
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'] }
|
||||
{ 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'] }
|
||||
{ required: true, message: '请填写风险告知内容', trigger: ['blur', 'submit'] },
|
||||
],
|
||||
patientSignature: [
|
||||
{ required: true, message: '请填写患者或家属签字', trigger: ['blur', 'submit'] }
|
||||
{ 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'] }
|
||||
]
|
||||
signatureDate: [{ required: true, message: '请选择签字日期', trigger: ['change', 'submit'] }],
|
||||
doctorSignature: [{ required: true, message: '请填写医师签字', trigger: ['blur', 'submit'] }],
|
||||
communicationDate: [{ required: true, message: '请选择沟通日期', trigger: ['change', 'submit'] }],
|
||||
});
|
||||
|
||||
// 生命周期
|
||||
@@ -322,16 +335,26 @@ onMounted(() => {
|
||||
formData.communicationDate = formatDateTime(today);
|
||||
});
|
||||
|
||||
const emits = defineEmits(['submitOk']);
|
||||
|
||||
// 提交表单
|
||||
const submit = () => {
|
||||
formRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
ElMessage.success('记录保存成功');
|
||||
console.log('表单数据:', formData);
|
||||
emits('submitOk', formData);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 表单数据赋值
|
||||
const setFormData = (data) => {
|
||||
if (data) {
|
||||
Object.assign(formData, data);
|
||||
}
|
||||
};
|
||||
|
||||
// 打印功能
|
||||
const handlePrint = () => {
|
||||
formRef.value.validate((valid) => {
|
||||
@@ -345,15 +368,11 @@ const handlePrint = () => {
|
||||
|
||||
// 重置表单
|
||||
const handleReset = () => {
|
||||
ElMessageBox.confirm(
|
||||
'确定要重置表单吗?所有已填写内容将被清空',
|
||||
'确认重置',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
ElMessageBox.confirm('确定要重置表单吗?所有已填写内容将被清空', '确认重置', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
formRef.value.resetFields();
|
||||
const today = new Date();
|
||||
formData.admissionDate = formatDate(today);
|
||||
@@ -379,6 +398,8 @@ const formatDateTime = (date) => {
|
||||
const minute = String(date.getMinutes()).padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hour}:${minute}`;
|
||||
};
|
||||
|
||||
defineExpose({ submit, setFormData });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -510,19 +531,19 @@ const formatDateTime = (date) => {
|
||||
.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;
|
||||
}
|
||||
@@ -533,21 +554,21 @@ const formatDateTime = (date) => {
|
||||
.btn-group {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.medical-document {
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.el-input__inner, .el-select__input, .el-textarea__inner {
|
||||
|
||||
.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>
|
||||
</style>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h2 class="title">乾安县人民医院</h2>
|
||||
<h2 class="title">长春市朝阳区中医院</h2>
|
||||
<h3 class="subtitle">患者护理记录单</h3>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
<template>
|
||||
<!-- 门诊病历表单主容器 -->
|
||||
<div class="medical-form">
|
||||
<!-- 患者基本信息展示区域 -->
|
||||
<div class="patient-name">
|
||||
患者姓名:{{ patient?.patientName || '未知' }} 病历号:{{
|
||||
patient?.busNo || '未知'
|
||||
}}
|
||||
</div>
|
||||
<!-- 医院名称和标题 -->
|
||||
<h2 style="text-align: center">{{ userStore.hospitalName }}</h2>
|
||||
<h2 style="text-align: center">门诊病历</h2>
|
||||
|
||||
<!-- 滚动内容区域 -->
|
||||
<div class="form-scroll-container">
|
||||
<!-- Element Plus表单组件 -->
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
@@ -22,40 +18,34 @@
|
||||
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"
|
||||
@@ -68,13 +58,10 @@
|
||||
</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"
|
||||
@@ -83,11 +70,9 @@
|
||||
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"
|
||||
@@ -96,7 +81,6 @@
|
||||
autosize
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- 过敏史输入项 -->
|
||||
<el-form-item label="过敏史" prop="allergyHistory" class="row-item history-item">
|
||||
<el-input
|
||||
v-model="formData.allergyHistory"
|
||||
@@ -105,7 +89,6 @@
|
||||
autosize
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- 家族史输入项 -->
|
||||
<el-form-item label="家族史" prop="familyHistory" class="row-item history-item">
|
||||
<el-input
|
||||
v-model="formData.familyHistory"
|
||||
@@ -116,8 +99,6 @@
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 主诉、查体(治疗)、处置、辅助检查区域标题 -->
|
||||
<h4 class="section-title">主诉、查体(治疗)、处置、辅助检查</h4>
|
||||
<!-- 3. 主诉(必填) -->
|
||||
<el-form-item label="主诉" prop="complaint" class="required form-item-single">
|
||||
@@ -130,7 +111,6 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- 4. 查体、处理、辅助检查 -->
|
||||
<!-- 查体(治疗)输入项 -->
|
||||
<el-form-item label="查体(治疗)" prop="physicalExam" class="form-item-single">
|
||||
<el-input
|
||||
v-model="formData.physicalExam"
|
||||
@@ -141,7 +121,6 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 处置输入项 -->
|
||||
<el-form-item label="处置" prop="treatment" class="form-item-single">
|
||||
<el-input
|
||||
v-model="formData.treatment"
|
||||
@@ -152,7 +131,6 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 辅助检查输入项 -->
|
||||
<el-form-item label="辅助检查" prop="auxiliaryExam" class="form-item-single">
|
||||
<el-input
|
||||
v-model="formData.auxiliaryExam"
|
||||
@@ -168,62 +146,51 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 导入Vue相关功能和组件
|
||||
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获取
|
||||
// // Props与事件, 去掉props.patientInfo改为直接从store获取
|
||||
// const props = defineProps({
|
||||
// patientInfo: {
|
||||
// type: Object,
|
||||
// required: true,
|
||||
// },
|
||||
// });
|
||||
|
||||
// 定义组件接收的属性(目前为空)
|
||||
const props = defineProps({});
|
||||
|
||||
// 定义组件触发的事件
|
||||
const emits = defineEmits(['submitOk']);
|
||||
|
||||
// 数据初始化
|
||||
// 获取用户store实例,用于获取医院名称等全局信息
|
||||
const userStore = useUserStore();
|
||||
// 患者信息引用,存储当前就诊患者的基本信息
|
||||
const patient = ref(null);
|
||||
// 表单引用,用于访问表单实例进行验证等操作
|
||||
const formRef = ref(null);
|
||||
|
||||
// 表单数据(全部字符类型)
|
||||
// 存储门诊病历表单的所有字段数据
|
||||
const formData = reactive({
|
||||
height: '', // 身高(cm)
|
||||
weight: '', // 体重(kg)
|
||||
temperature: '', // 体温(℃)
|
||||
pulse: '', // 脉搏(次/分)
|
||||
height: '', // 身高
|
||||
weight: '', // 体重
|
||||
temperature: '', // 体温
|
||||
pulse: '', // 脉搏
|
||||
onsetDate: '', // 发病日期
|
||||
complaint: '', // 主诉(必填项)
|
||||
complaint: '', // 主诉(必填)
|
||||
presentIllness: '', // 现病史
|
||||
pastIllness: '', // 既往史
|
||||
personalHistory: '', // 个人史
|
||||
allergyHistory: '', // 过敏史
|
||||
physicalExam: '', // 查体结果
|
||||
treatment: '', // 处理方案
|
||||
auxiliaryExam: '', // 辅助检查结果
|
||||
physicalExam: '', // 查体
|
||||
treatment: '', // 处理
|
||||
auxiliaryExam: '', // 辅助检查
|
||||
familyHistory: '', // 家族史
|
||||
});
|
||||
|
||||
// 表单校验规则
|
||||
// 定义表单字段的验证规则,目前仅主诉为必填项
|
||||
const rules = reactive({
|
||||
complaint: [
|
||||
{
|
||||
@@ -235,21 +202,14 @@ const rules = reactive({
|
||||
});
|
||||
|
||||
// 提交函数
|
||||
// 用于触发表单验证并提交数据到父组件
|
||||
const submit = () => {
|
||||
// 表单验证
|
||||
formRef.value.validate((isValid) => {
|
||||
if (isValid) {
|
||||
// 触发submitOk事件,传递表单数据
|
||||
emits('submitOk', formData);
|
||||
// 显示成功消息
|
||||
ElMessage.success('提交成功');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 日期格式化工具函数
|
||||
// 将Date对象格式化为 YYYY-MM-DD HH:mm 格式的字符串
|
||||
// 日期格式化工具
|
||||
const formatDateTime = (date) => {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
@@ -258,23 +218,17 @@ const formatDateTime = (date) => {
|
||||
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);
|
||||
// 从store获取患者信息
|
||||
patient.value = patientInfo.value;
|
||||
// 初始化发病日期为当前时间
|
||||
if (!formData.onsetDate) {
|
||||
@@ -283,7 +237,6 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
// 监听患者信息变化,实现联动显示
|
||||
// 当patientInfo发生变化时更新本地patient引用
|
||||
watch(
|
||||
() => patientInfo.value,
|
||||
(newPatientInfo) => {
|
||||
@@ -292,8 +245,7 @@ watch(
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 暴露接口供父组件调用
|
||||
// 将formData、submit方法和setFormData方法暴露给父组件使用
|
||||
// 暴露接口
|
||||
defineExpose({ formData, submit, setFormData });
|
||||
</script>
|
||||
|
||||
@@ -303,14 +255,15 @@ defineExpose({ formData, submit, setFormData });
|
||||
max-width: 1200px;
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
height: 900px;
|
||||
height: auto;
|
||||
margin: 15px auto;
|
||||
padding: 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
font-family: Arial, sans-serif;
|
||||
box-sizing: border-box;
|
||||
overflow: visible;
|
||||
overflow: hidden; /* 防止内部内容溢出 */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 顶部姓名样式 */
|
||||
@@ -325,11 +278,12 @@ defineExpose({ formData, submit, setFormData });
|
||||
/* 滚动内容容器 */
|
||||
.form-scroll-container {
|
||||
width: 100%;
|
||||
max-height: 80vh;
|
||||
max-height: 55vh;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #ccc #f5f5f5;
|
||||
position: relative;
|
||||
}
|
||||
.form-scroll-container::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
@@ -345,6 +299,8 @@ defineExpose({ formData, submit, setFormData });
|
||||
/* 完整表单容器 */
|
||||
.medical-full-form {
|
||||
width: 100%;
|
||||
min-width: 0; /* 防止内容强制拉伸容器 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 区域通用样式 */
|
||||
@@ -366,6 +322,8 @@ defineExpose({ formData, submit, setFormData });
|
||||
flex-wrap: wrap; /* 自动换行 */
|
||||
align-items: flex-start; /* 顶部对齐,适配文本域高度 */
|
||||
gap: 15px; /* 统一元素间距 */
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.row-item {
|
||||
margin-bottom: 0; /* 取消底部间距,避免换行重叠 */
|
||||
@@ -436,9 +394,11 @@ defineExpose({ formData, submit, setFormData });
|
||||
.medical-form {
|
||||
height: 80vh;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.form-scroll-container {
|
||||
height: calc(100% - 35px);
|
||||
max-height: none;
|
||||
}
|
||||
.el-form {
|
||||
label-width: 70px !important;
|
||||
@@ -457,4 +417,4 @@ defineExpose({ formData, submit, setFormData });
|
||||
--el-input-textarea-min-height: 80px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
455
openhis-ui-vue3/src/template/outpatientMedicalRecord1.1.vue
Normal file
455
openhis-ui-vue3/src/template/outpatientMedicalRecord1.1.vue
Normal file
@@ -0,0 +1,455 @@
|
||||
<template>
|
||||
<div class="medical-form">
|
||||
<div class="patient-name">
|
||||
患者姓名:{{ patient?.patientName || '未知' }} 病历号:{{
|
||||
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="breathe" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input v-model="formData.breathe" type="text" placeholder="请输入" />
|
||||
<span class="unit">次/分</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="血压" prop="blood" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input v-model="formData.blood" type="text" placeholder="请输入" />
|
||||
<span class="unit">mmHg</span>
|
||||
</div>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="血压" prop="blood" class="row-item">
|
||||
<div class="input-with-unit blood-input-group">
|
||||
<el-input
|
||||
v-model="formData.bloodHigh"
|
||||
type="text"
|
||||
placeholder="高压"
|
||||
style="width: 80px"
|
||||
/>
|
||||
<span class="divider">/</span>
|
||||
<el-input
|
||||
v-model="formData.bloodLow"
|
||||
type="text"
|
||||
placeholder="低压"
|
||||
style="width: 80px"
|
||||
/>
|
||||
<span class="unit">(高/低)mmHg</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: 'OutpatientMedicalRecord1.1',
|
||||
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({
|
||||
breathe: '', // 呼吸
|
||||
bloodHigh: '', //高压
|
||||
bloodLow: '', //低压
|
||||
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);
|
||||
}
|
||||
});
|
||||
};
|
||||
// 日期格式化工具
|
||||
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;
|
||||
}
|
||||
.blood-input-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.blood-input-group .el-input {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.divider {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.unit {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 基础信息项:适配短输入框 */
|
||||
.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>
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="surgicalPatientHandover-container">
|
||||
<div class="handover-form">
|
||||
<div class="form-header">
|
||||
<h1 class="hospital-name">**医院</h1>
|
||||
<h1 class="hospital-name">长春市朝阳区中医院</h1>
|
||||
<h2 class="form-title">手术患者交接单</h2>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -501,4 +501,33 @@ export function getGroupMarkers(tableData) {
|
||||
}
|
||||
});
|
||||
return tableData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化库存数量显示(大单位情况) 示例 1盒5片
|
||||
* @param quantity 小单位库存数量
|
||||
* @param partPercent 拆零比
|
||||
* @param unitCode 大单位label
|
||||
* @param minUnitCode 小单位label
|
||||
*/
|
||||
export function formatInventory(quantity, partPercent, unitCode, minUnitCode) {
|
||||
// 处理负数情况
|
||||
const isNegative = quantity < 0;
|
||||
const absQuantity = Math.abs(quantity);
|
||||
|
||||
if (absQuantity % partPercent !== 0) {
|
||||
const integerPart = Math.floor(absQuantity / partPercent);
|
||||
const decimalPart = absQuantity % partPercent;
|
||||
|
||||
let result = integerPart.toString() + ' ' + unitCode;
|
||||
if (decimalPart > 0) {
|
||||
result += decimalPart.toString() + ' ' + minUnitCode;
|
||||
}
|
||||
|
||||
return isNegative ? '-' + result : result;
|
||||
}
|
||||
|
||||
// 整除情况
|
||||
const result = absQuantity / partPercent;
|
||||
return isNegative ? '-' + result : result + ' ' + unitCode;
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* 集中管理所有打印相关功能
|
||||
*/
|
||||
|
||||
// 打印模板映射表
|
||||
// 打印模板映射表 .
|
||||
const TEMPLATE_MAP = {
|
||||
// CLINIC_CHARGE: () => import('@/views/charge/cliniccharge/components/template.json'),
|
||||
// DISPOSAL: () => import('@/views/clinicmanagement/disposal/components/disposalTemplate.json'),
|
||||
@@ -21,6 +21,25 @@ const TEMPLATE_MAP = {
|
||||
OUTPATIENT_REGISTRATION: () => import('@/components/Print/OutpatientRegistration.json'),
|
||||
//门诊收费
|
||||
OUTPATIENT_CHARGE: () => import('@/components/Print/OutpatientBilling.json'),
|
||||
//门诊病历
|
||||
OUTPATIENT_MEDICAL_RECORD: () => import('@/components/Print/OutpatientMedicalRecord.json'),
|
||||
//门诊输液贴
|
||||
OUTPATIENT_INFUSION: () => import('@/components/Print/OutpatientInfusion.json'),
|
||||
//手术记录
|
||||
OPERATIVE_RECORD: () => import('@/components/Print/OperativeRecord.json'),
|
||||
|
||||
//红旗门诊病历
|
||||
HQOUTPATIENT_MEDICAL_RECORD: () => import('@/components/Print/HQOutpatientMedicalRecord.json'),
|
||||
//预交金
|
||||
ADVANCE_PAYMENT: () => import('@/components/Print/AdvancePayment.json'),
|
||||
//中药处方单
|
||||
CHINESE_MEDICINE_PRESCRIPTION: () =>
|
||||
import('@/components/Print/ChineseMedicinePrescription.json'),
|
||||
//药房处方单
|
||||
PHARMACY_PRESCRIPTION: () => import('@/components/Print/Pharmacy.json'),
|
||||
//中药医生处方单
|
||||
DOC_CHINESE_MEDICINE_PRESCRIPTION: () =>
|
||||
import('@/components/Print/DocChineseMedicinePrescription.json'),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -108,6 +127,22 @@ export const PRINT_TEMPLATE = {
|
||||
PRESCRIPTION: 'PRESCRIPTION',
|
||||
//处置单
|
||||
DISPOSAL: 'DISPOSAL',
|
||||
//门诊病历
|
||||
OUTPATIENT_MEDICAL_RECORD: 'OUTPATIENT_MEDICAL_RECORD',
|
||||
//门诊输液贴
|
||||
OUTPATIENT_INFUSION: 'OUTPATIENT_INFUSION',
|
||||
//手术记录
|
||||
OPERATIVE_RECORD: 'OPERATIVE_RECORD',
|
||||
//红旗门诊病历
|
||||
HQOUTPATIENT_MEDICAL_RECORD: 'HQOUTPATIENT_MEDICAL_RECORD',
|
||||
//预交金
|
||||
ADVANCE_PAYMENT: 'ADVANCE_PAYMENT',
|
||||
//中药处方单
|
||||
CHINESE_MEDICINE_PRESCRIPTION: 'CHINESE_MEDICINE_PRESCRIPTION',
|
||||
//药房处方单
|
||||
PHARMACY_PRESCRIPTION: 'PHARMACY_PRESCRIPTION',
|
||||
//中药医生处方单
|
||||
DOC_CHINESE_MEDICINE_PRESCRIPTION: 'DOC_CHINESE_MEDICINE_PRESCRIPTION',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -128,6 +163,7 @@ export function getPrinterList() {
|
||||
}
|
||||
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
/**
|
||||
* 获取当前登录用户ID
|
||||
@@ -280,6 +316,22 @@ export async function selectPrinterAndPrint(
|
||||
}
|
||||
}
|
||||
|
||||
// 预览打印
|
||||
export function previewPrint(elementDom) {
|
||||
if (elementDom) {
|
||||
//初始化
|
||||
window.hiprint.init();
|
||||
const hiprintTemplate = new window.hiprint.PrintTemplate();
|
||||
// printByHtml为预览打印
|
||||
hiprintTemplate.printByHtml(elementDom, {});
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '加载模版失败',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 默认导出简化的打印方法
|
||||
export default {
|
||||
print: simplePrint,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* 判断url是否是http或https
|
||||
* 判断url是否是http或https
|
||||
* @param {string} path
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isHttp(url) {
|
||||
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
|
||||
export function isHttp(url) {
|
||||
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -12,8 +12,8 @@
|
||||
* @param {string} path
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path)
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -21,8 +21,8 @@
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validUsername(str) {
|
||||
const valid_map = ['admin', 'editor']
|
||||
return valid_map.indexOf(str.trim()) >= 0
|
||||
const valid_map = ['admin', 'editor'];
|
||||
return valid_map.indexOf(str.trim()) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,8 +30,9 @@ export function validUsername(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validURL(url) {
|
||||
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
||||
return reg.test(url)
|
||||
const reg =
|
||||
/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
|
||||
return reg.test(url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,8 +40,8 @@ export function validURL(url) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validLowerCase(str) {
|
||||
const reg = /^[a-z]+$/
|
||||
return reg.test(str)
|
||||
const reg = /^[a-z]+$/;
|
||||
return reg.test(str);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,8 +49,8 @@ export function validLowerCase(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validUpperCase(str) {
|
||||
const reg = /^[A-Z]+$/
|
||||
return reg.test(str)
|
||||
const reg = /^[A-Z]+$/;
|
||||
return reg.test(str);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,8 +58,8 @@ export function validUpperCase(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validAlphabets(str) {
|
||||
const reg = /^[A-Za-z]+$/
|
||||
return reg.test(str)
|
||||
const reg = /^[A-Za-z]+$/;
|
||||
return reg.test(str);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,8 +67,9 @@ export function validAlphabets(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validEmail(email) {
|
||||
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
return reg.test(email)
|
||||
const reg =
|
||||
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
return reg.test(email);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,9 +78,9 @@ export function validEmail(email) {
|
||||
*/
|
||||
export function isString(str) {
|
||||
if (typeof str === 'string' || str instanceof String) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +89,39 @@ export function isString(str) {
|
||||
*/
|
||||
export function isArray(arg) {
|
||||
if (typeof Array.isArray === 'undefined') {
|
||||
return Object.prototype.toString.call(arg) === '[object Array]'
|
||||
return Object.prototype.toString.call(arg) === '[object Array]';
|
||||
}
|
||||
return Array.isArray(arg)
|
||||
return Array.isArray(arg);
|
||||
}
|
||||
// 手机号正则
|
||||
export function isValidCNPhoneNumber(phone) {
|
||||
const regex = /^1[3-9]\d{9}$/;
|
||||
return regex.test(phone);
|
||||
}
|
||||
// 身份证号正则
|
||||
export function isValidCNidCardNumber(idCard) {
|
||||
const regex = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
|
||||
return regex.test(idCard);
|
||||
}
|
||||
// 根据身份证号获取性别和年龄
|
||||
export function getGenderAndAge(idCard) {
|
||||
// 确保身份证号码是18位
|
||||
if (idCard.length !== 18) {
|
||||
return { error: '身份证号码必须是18位' };
|
||||
}
|
||||
// 提取出生年月日
|
||||
const birthDate = idCard.substr(6, 8); // YYYYMMDD
|
||||
const year = birthDate.substr(0, 4);
|
||||
const month = birthDate.substr(4, 2);
|
||||
const day = birthDate.substr(6, 2);
|
||||
const dateOfBirth = new Date(`${year}-${month}-${day}`);
|
||||
// 计算年龄
|
||||
let age = new Date().getFullYear() - dateOfBirth.getFullYear();
|
||||
const m = new Date().getMonth() - dateOfBirth.getMonth();
|
||||
if (m < 0 || (m === 0 && new Date().getDate() < dateOfBirth.getDate())) {
|
||||
age--;
|
||||
}
|
||||
// 提取性别
|
||||
const gender = idCard.charAt(16) % 2 === 0 ? 1 : 0;
|
||||
return { age, gender };
|
||||
}
|
||||
|
||||
39
openhis-ui-vue3/src/views/appoinmentmanage/deptManage/api.js
Normal file
39
openhis-ui-vue3/src/views/appoinmentmanage/deptManage/api.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 添加医生排班
|
||||
* @param {Object} data - 排班数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function addDoctorSchedule(data) {
|
||||
return request({
|
||||
url: '/doctor-schedule/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除医生排班
|
||||
* @param {String|Number} id - 排班记录ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteDoctorSchedule(id) {
|
||||
return request({
|
||||
url: '/doctor-schedule/delete/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存医生排班
|
||||
* @param {Array} data - 排班数据数组
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function batchSaveDoctorSchedule(data) {
|
||||
return request({
|
||||
url: '/doctor-schedule/batch-save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
@@ -79,6 +79,9 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="属性代码" prop="code">
|
||||
<el-input v-model="form.code" placeholder="请输入属性代码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="体温单类型编码" prop="typeCode">
|
||||
<el-input v-model="form.typeCode" placeholder="请输入体温单属性编码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位顺序" prop="displayOrder">
|
||||
<el-input-number v-model="form.displayOrder" controls-position="right" :min="0" />
|
||||
@@ -197,6 +200,7 @@ function reset() {
|
||||
displayOrder: 0, // 显示顺序
|
||||
dictName: '', //字典名称
|
||||
dictType: '', //字典类型
|
||||
typeCode:'',//体温单类型编码
|
||||
};
|
||||
proxy.resetForm('statisticsRef');
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<PopoverList @search="handleSearch" :width="800" :modelValue="scope.row.name">
|
||||
<template #popover-content="{}">
|
||||
<DeviceList
|
||||
v-if="scope.row.type == '2' || props.tab == 2 "
|
||||
v-if="scope.row.type == '2' || props.tab == 2"
|
||||
@selectRow="(row) => selectRow(row, scope.$index)"
|
||||
:searchKey="searchKey"
|
||||
/>
|
||||
@@ -171,7 +171,7 @@
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import { reactive, watch } from 'vue';
|
||||
import { bind, deleteBind, init } from './api';
|
||||
@@ -345,6 +345,5 @@ function selectRow(row, index) {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -79,8 +79,12 @@ import { getActivityList, getBindList, getRegistrationfeeList } from './componen
|
||||
import ConsumablesList from './components/consumablesList.vue';
|
||||
|
||||
const activityList = ref([]);
|
||||
const queryParams = ref({});
|
||||
const queryParamsRegistration = ref({});
|
||||
const queryParams = ref({
|
||||
statusEnum: 2,
|
||||
});
|
||||
const queryParamsRegistration = ref({
|
||||
activeFlag: 1,
|
||||
});
|
||||
const bindList = ref([]);
|
||||
const bindInfo = ref({});
|
||||
const activeTab = ref(1);
|
||||
@@ -91,19 +95,18 @@ const { proxy } = getCurrentInstance();
|
||||
const { method_code } = proxy.useDict('method_code');
|
||||
|
||||
getList();
|
||||
getRegistrationList()
|
||||
getRegistrationList();
|
||||
function getList() {
|
||||
// queryParams.value.typeEnum = activeTab.value;
|
||||
getActivityList(queryParams.value).then((res) => {
|
||||
activityList.value = res.data.records;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function getRegistrationList() {
|
||||
getRegistrationfeeList(queryParamsRegistration.value).then(res => {
|
||||
getRegistrationfeeList(queryParamsRegistration.value).then((res) => {
|
||||
RegistrationfeeList.value = res.data.records;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 点击诊疗列表 获取绑定的耗材
|
||||
@@ -119,5 +122,4 @@ function clickRow(row) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
>
|
||||
<!-- <el-table-column type="selection" width="50" align="center" /> -->
|
||||
<el-table-column
|
||||
label="取药科室"
|
||||
label="开立科室"
|
||||
align="center"
|
||||
key="name"
|
||||
prop="name"
|
||||
@@ -64,6 +64,29 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="项目类型"
|
||||
align="center"
|
||||
key="itemCode"
|
||||
prop="itemCode"
|
||||
:show-overflow-tooltip="true"
|
||||
width="300"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div style="display: flex; align-items: center; justify-content: center">
|
||||
<el-select
|
||||
v-model="scope.row.itemCode"
|
||||
placeholder="项目类型"
|
||||
clearable
|
||||
style="width: 100px"
|
||||
:class="{ 'error-border': scope.row.error }"
|
||||
>
|
||||
<el-option label="药品" value="1" />
|
||||
<el-option label="耗材" value="2" />
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="药品类别"
|
||||
align="center"
|
||||
@@ -81,12 +104,22 @@
|
||||
style="width: 200px"
|
||||
:class="{ 'error-border': scope.row.error }"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in med_category_code"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
<template v-if="scope.row.itemCode == '1'">
|
||||
<el-option
|
||||
v-for="dict in med_category_code"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="scope.row.itemCode == '2'">
|
||||
<el-option
|
||||
v-for="dict in device_category_code"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
@@ -184,7 +217,11 @@ import {
|
||||
deletePharmacyDepartment,
|
||||
} from './components/pharmacyDepartment';
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { med_category_code } = proxy.useDict('med_category_code');
|
||||
const { distribution_category_code, med_category_code, device_category_code } = proxy.useDict(
|
||||
'distribution_category_code',
|
||||
'med_category_code',
|
||||
'device_category_code'
|
||||
);
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
const diagnosisTreatmentList = ref([]);
|
||||
@@ -293,10 +330,6 @@ function handleSelectionChange(selection) {
|
||||
}
|
||||
|
||||
function openAddPharmacyDepartment() {
|
||||
if (data.isAdding) {
|
||||
proxy.$message.warning('请先保存当前行后再新增!');
|
||||
return;
|
||||
}
|
||||
const newRow = {
|
||||
id: '',
|
||||
organizationId: '',
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<span style="vertical-align: middle">病区</span>
|
||||
</template>
|
||||
<div style="width: 100%">
|
||||
<el-button type="primary" @click="open = true" class="mb8"> 新增 </el-button>
|
||||
<el-button type="primary" @click="onIncrease" class="mb8"> 新增 </el-button>
|
||||
<el-button type="success" plain @click="handleEnableBatch('wardRef')" class="mb8">
|
||||
批量启用
|
||||
</el-button>
|
||||
@@ -16,7 +16,7 @@
|
||||
<el-table
|
||||
max-height="630"
|
||||
:data="wardList"
|
||||
@cell-click="(row) => clickRow(row, 10)"
|
||||
@cell-click="(row) => clickRow(row, 10, 0)"
|
||||
highlight-current-row
|
||||
ref="wardRef"
|
||||
>
|
||||
@@ -95,7 +95,7 @@
|
||||
<el-table
|
||||
height="280"
|
||||
:data="houseList"
|
||||
@cell-click="(row) => clickRow(row, 8)"
|
||||
@cell-click="(row) => clickRow(row, 8, 0, 1)"
|
||||
highlight-current-row
|
||||
v-loading="loading"
|
||||
ref="hourseRef"
|
||||
@@ -134,7 +134,7 @@
|
||||
@click.stop="
|
||||
() => {
|
||||
handleUnable(scope.row).then(() => {
|
||||
clickRow(houseRow, 10);
|
||||
getHouseList();
|
||||
});
|
||||
}
|
||||
"
|
||||
@@ -153,7 +153,7 @@
|
||||
@click.stop="
|
||||
() => {
|
||||
handleEnable(scope.row).then(() => {
|
||||
clickRow(houseRow, 10);
|
||||
getHouseList();
|
||||
});
|
||||
}
|
||||
"
|
||||
@@ -206,7 +206,7 @@
|
||||
@click.stop="
|
||||
() => {
|
||||
handleUnable(scope.row, 10).then(() => {
|
||||
clickRow(bedRow, 8);
|
||||
getBedList();
|
||||
});
|
||||
}
|
||||
"
|
||||
@@ -225,7 +225,7 @@
|
||||
@click.stop="
|
||||
() => {
|
||||
handleEnable(scope.row, 10).then(() => {
|
||||
clickRow(bedRow, 8);
|
||||
getBedList();
|
||||
});
|
||||
}
|
||||
"
|
||||
@@ -255,7 +255,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="type + '名称'" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入科室名称" />
|
||||
<el-input v-model="form.name" :placeholder="'请输入' + type + '名称'" />
|
||||
</el-form-item>
|
||||
<el-col>
|
||||
<el-form-item :label="upLabel" prop="busNoParent">
|
||||
@@ -304,8 +304,9 @@
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup name="Ward">
|
||||
import { onMounted, ref } from 'vue';
|
||||
import {
|
||||
getList,
|
||||
addLocation,
|
||||
@@ -315,33 +316,65 @@ import {
|
||||
unableLocation,
|
||||
enableLocation,
|
||||
} from './components/api';
|
||||
import { ElMessage } from 'element-plus';
|
||||
const { proxy } = getCurrentInstance();
|
||||
// 病区参数
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
formEnum: 4,
|
||||
formEnum: 4, //4 病区 10 病房 8床位
|
||||
// locationFormList: [4],
|
||||
});
|
||||
// 病房参数
|
||||
const queryHouseParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
formEnum: 10, //4 病区 10 病房 8床位
|
||||
// locationFormList: [4],
|
||||
});
|
||||
// 病床参数
|
||||
const querybedParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
formEnum: 8, //4 病区 10 病房 8床位
|
||||
// locationFormList: [4],
|
||||
});
|
||||
// 病区、病房、病床类型
|
||||
const type = ref('病区');
|
||||
// 病区列表
|
||||
const wardList = ref([]);
|
||||
// 床位列表
|
||||
const bedList = ref([]);
|
||||
// 病房列表
|
||||
const houseList = ref([]);
|
||||
const wardListOption = ref([]);
|
||||
const organization = ref([]);
|
||||
const loading = ref(false);
|
||||
const isEdit = ref(false);
|
||||
const open = ref(false);
|
||||
// 病区row
|
||||
const wardRow = ref({});
|
||||
// 床位row
|
||||
const bedRow = ref({});
|
||||
// 病房row
|
||||
const houseRow = ref({});
|
||||
// 记录点击的是启用
|
||||
const clickType = ref(0);
|
||||
const orgRef = ref();
|
||||
// 新增数据参数
|
||||
const form = reactive({
|
||||
formEnum: 4,
|
||||
busNoParent: '',
|
||||
organizationId: '',
|
||||
name: '',
|
||||
busNo: '',
|
||||
});
|
||||
const upLabel = ref('关联科室');
|
||||
const title = ref('新增');
|
||||
const rules = ref({
|
||||
name: [
|
||||
{ required: true, message: '请输入科室名称', trigger: 'blur' },
|
||||
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
|
||||
{ required: true, message: '请输入名称', trigger: 'blur' },
|
||||
{ required: true, min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
|
||||
],
|
||||
busNoParent: [
|
||||
{
|
||||
@@ -351,23 +384,76 @@ const rules = ref({
|
||||
},
|
||||
],
|
||||
});
|
||||
/**
|
||||
* 病区列表
|
||||
*/
|
||||
function getWardList() {
|
||||
queryParams.value.formEnum = 4;
|
||||
getList(queryParams.value).then((res) => {
|
||||
wardList.value = res.data.records;
|
||||
});
|
||||
}
|
||||
|
||||
// 获取科室下啦树
|
||||
function init() {
|
||||
getOrgList().then((res) => {
|
||||
organization.value = res.data.records;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 病区列表
|
||||
*/
|
||||
function getWardList() {
|
||||
houseList.value = [];
|
||||
bedList.value = [];
|
||||
getList(queryParams.value).then((res) => {
|
||||
wardList.value = res.data.records;
|
||||
});
|
||||
}
|
||||
// 获取病房列表
|
||||
const getHouseList = () => {
|
||||
// 4病区 10病房 8床位
|
||||
loading.value = true;
|
||||
// 病区号
|
||||
queryHouseParams.value.busNo = wardRow.value.busNo;
|
||||
bedList.value = [];
|
||||
getList(queryHouseParams.value).then((res) => {
|
||||
houseList.value = res.data.records;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
// 获取床位列表
|
||||
const getBedList = () => {
|
||||
// 4病区 10病房 8床位
|
||||
loading.value = true;
|
||||
querybedParams.value.busNo = houseRow.value.busNo;
|
||||
bedList.value = [];
|
||||
getList(querybedParams.value).then((res) => {
|
||||
bedList.value = res.data.records;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
// 点击新增按钮
|
||||
const onIncrease = () => {
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
// 查询病房和病区的下拉选
|
||||
const getHomeOrBed = (formEnum) => {
|
||||
const params = {
|
||||
formEnum,
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
};
|
||||
getList(params).then((res) => {
|
||||
if (formEnum == 10) {
|
||||
const datas = res.data?.records || [];
|
||||
const optionsList = datas.map((item) => {
|
||||
let obj = {
|
||||
...item,
|
||||
};
|
||||
obj.name = item.parentName + '-' + item.name;
|
||||
return obj;
|
||||
});
|
||||
wardListOption.value = optionsList;
|
||||
} else {
|
||||
wardListOption.value = res.data?.records || [];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function handleRadioChange(val) {
|
||||
let formEnum = 4;
|
||||
if (val == 4) {
|
||||
type.value = '病区';
|
||||
upLabel.value = '关联科室';
|
||||
@@ -375,38 +461,56 @@ function handleRadioChange(val) {
|
||||
} else if (val == 10) {
|
||||
type.value = '病房';
|
||||
upLabel.value = '所属病区';
|
||||
queryParams.value.formEnum = 4;
|
||||
formEnum = 4;
|
||||
// queryParams.value.formEnum = 4;
|
||||
} else {
|
||||
type.value = '床位';
|
||||
upLabel.value = '所属病房';
|
||||
queryParams.value.formEnum = 10;
|
||||
formEnum = 10;
|
||||
// queryParams.value.formEnum = 10;
|
||||
}
|
||||
getList(queryParams.value).then((res) => {
|
||||
wardListOption.value = res.data.records;
|
||||
});
|
||||
form.organizationId = '';
|
||||
form.busNo = '';
|
||||
form.busNoParent = '';
|
||||
form.name = '';
|
||||
getHomeOrBed(formEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击患者列表行 获取处方列表
|
||||
*/
|
||||
function clickRow(row, val) {
|
||||
loading.value = true;
|
||||
queryParams.value.formEnum = val;
|
||||
queryParams.value.busNo = row.busNo;
|
||||
bedList.value = [];
|
||||
getList(queryParams.value).then((res) => {
|
||||
if (val == 10) {
|
||||
houseList.value = res.data.records;
|
||||
houseRow.value = row;
|
||||
} else if (val == 8) {
|
||||
bedRow.value = row;
|
||||
bedList.value = res.data.records;
|
||||
}
|
||||
setTimeout(() => {
|
||||
queryParams.value.busNo = undefined;
|
||||
loading.value = false;
|
||||
}, 100);
|
||||
});
|
||||
function clickRow(row, val, type) {
|
||||
// 1点击了启用
|
||||
clickType.value = type;
|
||||
console.log('val=====>', JSON.stringify(row));
|
||||
console.log('type=====>', JSON.stringify(type));
|
||||
console.log('val=====>', JSON.stringify(val));
|
||||
// if (type !== 1) {
|
||||
// if (val == 10) {
|
||||
// wardRow.value = row;
|
||||
// getHouseList();
|
||||
// } else if (val == 8) {
|
||||
// houseRow.value = row;
|
||||
// getBedList();
|
||||
// }
|
||||
// } else {
|
||||
// if (val == 10) {
|
||||
// houseRow.value = row;
|
||||
// getHouseList();
|
||||
// } else if (val == 8) {
|
||||
// bedRow.value = row;
|
||||
// getBedList();
|
||||
// }
|
||||
// }
|
||||
if (val == 10) {
|
||||
wardRow.value = row;
|
||||
getHouseList();
|
||||
} else if (val == 8) {
|
||||
houseRow.value = row;
|
||||
console.log('houseRow=====>', houseRow.value);
|
||||
|
||||
getBedList();
|
||||
}
|
||||
}
|
||||
|
||||
function checkSelectable(row, index) {
|
||||
@@ -459,38 +563,113 @@ function handleUnableBatch(tableRef) {
|
||||
});
|
||||
}
|
||||
|
||||
// 新增病床拆分"busNo": "LOC055.LOC056",
|
||||
const splitBusNo = (busNo) => {
|
||||
const busNoArr = busNo.split('.') || [];
|
||||
let busNoParent = '';
|
||||
if (busNoArr.length > 1) {
|
||||
busNoParent = busNoArr[0];
|
||||
}
|
||||
return busNoParent;
|
||||
};
|
||||
function submitForm() {
|
||||
if (form.busNoParent) {
|
||||
if (form.formEnum == 4) {
|
||||
form.organizationId = form.busNoParent;
|
||||
} else {
|
||||
form.busNo = form.busNoParent;
|
||||
if (!orgRef) return;
|
||||
const params = {
|
||||
...form,
|
||||
};
|
||||
console.log('form========>', JSON.stringify(form));
|
||||
console.log('params11========>', JSON.stringify(params));
|
||||
orgRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
console.log('99999999');
|
||||
|
||||
if (form.busNoParent) {
|
||||
if (form.formEnum == 4) {
|
||||
params.organizationId = form.busNoParent;
|
||||
} else {
|
||||
if (!isEdit.value) {
|
||||
params.busNo = form.busNoParent;
|
||||
// params.busNoParent = splitBusNo(form.busNoParent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (form.formEnum == 4) {
|
||||
if (!(params.organizationId && params.organizationId.length > 0)) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请选择关联科室!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else if (form.formEnum == 10) {
|
||||
if (!(params.busNo && params.busNo.length > 0)) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请选择所属病区!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!(params.busNo && params.busNo.length > 8)) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请选择所属病房!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log('params========>', JSON.stringify(form));
|
||||
console.log('params========>', JSON.stringify(params));
|
||||
// console.log('params========>', isEdit.value);
|
||||
if (!isEdit.value) {
|
||||
addLocation(params).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
if (params.formEnum == 4) {
|
||||
cancel();
|
||||
getWardList();
|
||||
} else if (params.formEnum == 10) {
|
||||
getHouseList();
|
||||
open.value = false;
|
||||
} else if (params.formEnum == 8) {
|
||||
getBedList();
|
||||
open.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
editLocation(params).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
if (params.formEnum == 4) {
|
||||
cancel();
|
||||
getWardList();
|
||||
} else if (params.formEnum == 10) {
|
||||
getHouseList();
|
||||
open.value = false;
|
||||
} else if (params.formEnum == 8) {
|
||||
getBedList();
|
||||
open.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(form);
|
||||
if (!isEdit.value) {
|
||||
addLocation(form).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
cancel();
|
||||
getWardList();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
editLocation(form).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
cancel();
|
||||
getWardList();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete(row) {
|
||||
deleteLocation(row.busNo).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
if (row.formEnum == 4) {
|
||||
getWardList();
|
||||
} else if (row.formEnum == 10) {
|
||||
getHouseList();
|
||||
} else {
|
||||
getBedList();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -501,24 +680,27 @@ function getLastPartOfString(str) {
|
||||
}
|
||||
|
||||
function handleEdit(row, val) {
|
||||
console.log('editRow=========>', JSON.stringify(row));
|
||||
|
||||
form.id = row.id;
|
||||
form.name = row.name;
|
||||
form.formEnum = row.formEnum;
|
||||
form.busNo = row.busNo;
|
||||
if (row.organizationId) {
|
||||
form.busNoParent = row.organizationId;
|
||||
form.organizationId = row.organizationId;
|
||||
} else {
|
||||
form.busNoParent = row.busNo.split('.').slice(0, -1).join('.');
|
||||
}
|
||||
isEdit.value = true;
|
||||
title.value = '编辑';
|
||||
if (val) {
|
||||
queryParams.value.formEnum = val;
|
||||
getList(queryParams.value).then((res) => {
|
||||
wardListOption.value = res.data.records;
|
||||
});
|
||||
}
|
||||
open.value = true;
|
||||
console.log('editRow1=========>', JSON.stringify(form));
|
||||
if (val == 4) {
|
||||
getHomeOrBed(4);
|
||||
} else if (val == 10) {
|
||||
getHomeOrBed(10);
|
||||
}
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
@@ -532,10 +714,13 @@ function cancel() {
|
||||
isEdit.value = false;
|
||||
title.value = '新增';
|
||||
}
|
||||
|
||||
init();
|
||||
getWardList();
|
||||
// 页面挂在成功
|
||||
onMounted(() => {
|
||||
// 获取所有科室
|
||||
init();
|
||||
// 获取病区列表
|
||||
getWardList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -36,7 +36,8 @@ export function updateWarehouse(data) {
|
||||
// 删除
|
||||
export function deleteWarehouse(data) {
|
||||
return request({
|
||||
url: '/base-data-manage/location/location',
|
||||
// url: '/base-data-manage/location/location?locationId=' + data.locationId,
|
||||
url: '/base-data-manage/location/location?busNo=' + data.busNo,
|
||||
method: 'delete',
|
||||
params: {
|
||||
locationId: data.locationId,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user