fix(common): 统一异常处理并迁移打印功能到hiprint
- 替换所有System.out.println和printStackTrace为slf4j日志记录 - 在BeanUtils、AuditFieldUtil、DateUtils、ServletUtils等工具类中添加Logger实例 - 在Flowable相关控制器和服务中统一错误日志记录格式 - 在代码生成器中添加日志记录功能 - 将前端打印组件从Lodop迁移到hiprint打印方案 - 更新体温单打印功能使用hiprint预览打印 - 移除调试用的console.log语句 - 修复打印模板中线条元素类型定义
This commit is contained in:
22
openhis-ui-vue3/src/components/Print/BedCard.json
Normal file
22
openhis-ui-vue3/src/components/Print/BedCard.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"height": 60,
|
||||||
|
"index": 1,
|
||||||
|
"name": "床头卡",
|
||||||
|
"paperFooter": 170,
|
||||||
|
"paperHeader": 0,
|
||||||
|
"paperList": {"height": 60, "type": "自定义", "width": 100},
|
||||||
|
"paperNumberDisabled": true,
|
||||||
|
"paperType": "自定义",
|
||||||
|
"printElements": [
|
||||||
|
{"options": {"field": "bedName", "fontSize": 10, "fontWeight": "bold", "height": 10, "left": 45, "title": "床号:", "top": 5, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "patientName", "fontSize": 10, "fontWeight": "bold", "height": 10, "left": 45, "title": "姓名:", "top": 17, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "hisId", "fontSize": 10, "fontWeight": "bold", "height": 10, "left": 45, "title": "患者编号:", "top": 29, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "dept", "fontSize": 10, "fontWeight": "bold", "height": 10, "left": 45, "title": "分诊科室:", "top": 41, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "triageLevel", "fontSize": 10, "fontWeight": "bold", "height": 10, "left": 45, "title": "分诊等级:", "top": 53, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}}
|
||||||
|
],
|
||||||
|
"width": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
38
openhis-ui-vue3/src/components/Print/ChangeShiftBill.json
Normal file
38
openhis-ui-vue3/src/components/Print/ChangeShiftBill.json
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"height": 210,
|
||||||
|
"index": 1,
|
||||||
|
"name": "护理交接班",
|
||||||
|
"paperFooter": 595.5,
|
||||||
|
"paperHeader": 0,
|
||||||
|
"paperList": {"height": 210, "type": "A4", "width": 297},
|
||||||
|
"paperNumberDisabled": true,
|
||||||
|
"paperType": "A4",
|
||||||
|
"printElements": [
|
||||||
|
{"options": {"fontSize": 14, "fontWeight": "bold", "height": 15, "left": 0, "textAlign": "center", "title": "护理交接班", "top": 5, "width": 210}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "date", "fontSize": 10, "height": 10, "left": 5, "title": "日期:", "top": 25, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "initiatorName", "fontSize": 10, "height": 10, "left": 60, "title": "发起人:", "top": 25, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "heirName", "fontSize": 10, "height": 10, "left": 120, "title": "接收人:", "top": 25, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {
|
||||||
|
"columns": [[
|
||||||
|
{"align": "center", "field": "typeDisplay", "title": "类别", "width": 20},
|
||||||
|
{"align": "center", "field": "bedName", "title": "床号", "width": 25},
|
||||||
|
{"align": "center", "field": "patientName", "title": "姓名", "width": 30},
|
||||||
|
{"align": "center", "field": "mainSuit", "title": "主诉", "width": 45},
|
||||||
|
{"align": "center", "field": "previousHistory", "title": "既往史", "width": 45},
|
||||||
|
{"align": "center", "field": "diagnosis", "title": "诊断", "width": 45},
|
||||||
|
{"align": "center", "field": "content", "title": "交接信息", "width": 60}
|
||||||
|
]],
|
||||||
|
"field": "shiftRecordItems",
|
||||||
|
"fontSize": 9,
|
||||||
|
"height": 150,
|
||||||
|
"left": 5,
|
||||||
|
"top": 40,
|
||||||
|
"width": 200
|
||||||
|
}, "printElementType": {"title": "表格", "type": "table"}}
|
||||||
|
],
|
||||||
|
"width": 210
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
27
openhis-ui-vue3/src/components/Print/Consultation.json
Normal file
27
openhis-ui-vue3/src/components/Print/Consultation.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"height": 210,
|
||||||
|
"index": 1,
|
||||||
|
"name": "会诊申请单",
|
||||||
|
"paperFooter": 595.5,
|
||||||
|
"paperHeader": 0,
|
||||||
|
"paperList": {"height": 210, "type": "A4", "width": 210},
|
||||||
|
"paperNumberDisabled": true,
|
||||||
|
"paperType": "A4",
|
||||||
|
"printElements": [
|
||||||
|
{"options": {"fontSize": 14, "fontWeight": "bold", "height": 15, "left": 0, "textAlign": "center", "title": "会诊申请单", "top": 5, "width": 180}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "hospitalName", "fontSize": 10, "height": 10, "left": 0, "textAlign": "center", "title": "医院名称", "top": 22, "width": 180}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "patientName", "fontSize": 10, "height": 10, "left": 5, "title": "姓名:", "top": 40, "width": 60, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "gender", "fontSize": 10, "height": 10, "left": 70, "title": "性别:", "top": 40, "width": 30, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "age", "fontSize": 10, "height": 10, "left": 105, "title": "年龄:", "top": 40, "width": 40, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "deptName", "fontSize": 10, "height": 10, "left": 150, "title": "科室:", "top": 40, "width": 30, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "diagnosis", "fontSize": 10, "height": 20, "left": 5, "title": "初步诊断:", "top": 55, "width": 170, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "consultationReason", "fontSize": 10, "height": 40, "left": 5, "title": "会诊目的:", "top": 80, "width": 170, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "applyTime", "fontSize": 10, "height": 10, "left": 5, "title": "申请时间:", "top": 130, "width": 80, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "applyDoctor", "fontSize": 10, "height": 10, "left": 100, "title": "申请医生:", "top": 130, "width": 75, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}}
|
||||||
|
],
|
||||||
|
"width": 180
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
41
openhis-ui-vue3/src/components/Print/ExeOrderSheet.json
Normal file
41
openhis-ui-vue3/src/components/Print/ExeOrderSheet.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"height": 210,
|
||||||
|
"index": 1,
|
||||||
|
"name": "医嘱执行单",
|
||||||
|
"paperFooter": 595.5,
|
||||||
|
"paperHeader": 0,
|
||||||
|
"paperList": {"height": 210, "type": "A4", "width": 297},
|
||||||
|
"paperNumberDisabled": true,
|
||||||
|
"paperType": "A4",
|
||||||
|
"printElements": [
|
||||||
|
{"options": {"fontSize": 14, "fontWeight": "bold", "height": 15, "left": 0, "textAlign": "center", "title": "医嘱执行单", "top": 5, "width": 210}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "hospitalName", "fontSize": 12, "fontWeight": "bold", "height": 12, "left": 0, "textAlign": "center", "title": "医院名称", "top": 20, "width": 210}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "bedName", "fontSize": 9, "height": 10, "left": 5, "title": "床号:", "top": 35, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "patientName", "fontSize": 9, "height": 10, "left": 60, "title": "姓名:", "top": 35, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "patientAge", "fontSize": 9, "height": 10, "left": 115, "title": "年龄:", "top": 35, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "diag", "fontSize": 9, "height": 10, "left": 5, "title": "诊断:", "top": 47, "width": 200, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {
|
||||||
|
"columns": [[
|
||||||
|
{"align": "center", "field": "moTime", "title": "医嘱日期", "width": 25},
|
||||||
|
{"align": "center", "field": "orderName", "title": "医嘱", "width": 40},
|
||||||
|
{"align": "center", "field": "flag", "title": "标记", "width": 15},
|
||||||
|
{"align": "center", "field": "remark", "title": "嘱托", "width": 25},
|
||||||
|
{"align": "center", "field": "doseOnceUnit", "title": "用量", "width": 20},
|
||||||
|
{"align": "center", "field": "usageName", "title": "用法", "width": 20},
|
||||||
|
{"align": "center", "field": "frequency", "title": "频次", "width": 20},
|
||||||
|
{"align": "center", "field": "moDocName", "title": "开立医生", "width": 25}
|
||||||
|
]],
|
||||||
|
"field": "recordData",
|
||||||
|
"fontSize": 8,
|
||||||
|
"height": 140,
|
||||||
|
"left": 5,
|
||||||
|
"top": 60,
|
||||||
|
"width": 200
|
||||||
|
}, "printElementType": {"title": "表格", "type": "table"}}
|
||||||
|
],
|
||||||
|
"width": 210
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
39
openhis-ui-vue3/src/components/Print/InjectLabel.json
Normal file
39
openhis-ui-vue3/src/components/Print/InjectLabel.json
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"height": 80,
|
||||||
|
"index": 1,
|
||||||
|
"name": "输液标签",
|
||||||
|
"paperFooter": 226.8,
|
||||||
|
"paperHeader": 0,
|
||||||
|
"paperList": {"height": 80, "type": "自定义", "width": 100},
|
||||||
|
"paperNumberDisabled": true,
|
||||||
|
"paperType": "自定义",
|
||||||
|
"printElements": [
|
||||||
|
{"options": {"fontSize": 12, "fontWeight": "bold", "height": 12, "left": 0, "textAlign": "center", "title": "急诊输液贴", "top": 5, "width": 60}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "qrCode", "height": 30, "left": 65, "qrCodeLevel": 0, "title": "二维码", "top": 5, "width": 30}, "printElementType": {"title": "二维码", "type": "text"}},
|
||||||
|
{"options": {"field": "hisNo", "fontSize": 9, "height": 10, "left": 5, "title": "病历号:", "top": 20, "width": 25, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "name", "fontSize": 9, "height": 10, "left": 30, "title": "姓名:", "top": 20, "width": 20, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "sexName", "fontSize": 9, "height": 10, "left": 50, "title": "性别:", "top": 20, "width": 15, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "patientAge", "fontSize": 9, "height": 10, "left": 65, "title": "年龄:", "top": 20, "width": 30, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {
|
||||||
|
"columns": [[
|
||||||
|
{"align": "center", "field": "orderName", "title": "药品名称", "width": 35},
|
||||||
|
{"align": "center", "field": "doseOnceUnit", "title": "用量", "width": 15},
|
||||||
|
{"align": "center", "field": "flag", "title": "标记", "width": 10},
|
||||||
|
{"align": "center", "field": "frequency", "title": "频次", "width": 15},
|
||||||
|
{"align": "center", "field": "usageName", "title": "用法", "width": 15}
|
||||||
|
]],
|
||||||
|
"field": "orderDetail",
|
||||||
|
"fontSize": 8,
|
||||||
|
"height": 35,
|
||||||
|
"left": 5,
|
||||||
|
"top": 35,
|
||||||
|
"width": 90
|
||||||
|
}, "printElementType": {"title": "表格", "type": "table"}},
|
||||||
|
{"options": {"field": "printDate", "fontSize": 8, "height": 8, "left": 5, "title": "日期:", "top": 72, "width": 90, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}}
|
||||||
|
],
|
||||||
|
"width": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
39
openhis-ui-vue3/src/components/Print/TemperatureSheet.json
Normal file
39
openhis-ui-vue3/src/components/Print/TemperatureSheet.json
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"height": 180,
|
||||||
|
"index": 1,
|
||||||
|
"name": "体温单",
|
||||||
|
"paperFooter": 510,
|
||||||
|
"paperHeader": 0,
|
||||||
|
"paperList": {"height": 180, "type": "A4", "width": 210},
|
||||||
|
"paperNumberDisabled": true,
|
||||||
|
"paperType": "A4",
|
||||||
|
"printElements": [
|
||||||
|
{"options": {"fontSize": 12, "fontWeight": "bold", "height": 15, "left": 0, "textAlign": "center", "title": "体温单", "top": 5, "width": 180}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "patientName", "fontSize": 9, "height": 10, "left": 5, "title": "姓名:", "top": 25, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "bedName", "fontSize": 9, "height": 10, "left": 60, "title": "床号:", "top": 25, "width": 50, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "hospitalName", "fontSize": 9, "height": 10, "left": 115, "title": "科室:", "top": 25, "width": 60, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {
|
||||||
|
"columns": [[
|
||||||
|
{"align": "center", "field": "date", "title": "日期", "width": 25},
|
||||||
|
{"align": "center", "field": "time", "title": "时间", "width": 20},
|
||||||
|
{"align": "center", "field": "temperature", "title": "体温", "width": 20},
|
||||||
|
{"align": "center", "field": "pulse", "title": "脉搏", "width": 20},
|
||||||
|
{"align": "center", "field": "breath", "title": "呼吸", "width": 20},
|
||||||
|
{"align": "center", "field": "bloodPressure", "title": "血压", "width": 25},
|
||||||
|
{"align": "center", "field": "bloodOxygen", "title": "血氧", "width": 20},
|
||||||
|
{"align": "center", "field": "nurseName", "title": "签名", "width": 30}
|
||||||
|
]],
|
||||||
|
"field": "tprData",
|
||||||
|
"fontSize": 8,
|
||||||
|
"height": 130,
|
||||||
|
"left": 5,
|
||||||
|
"top": 40,
|
||||||
|
"width": 180
|
||||||
|
}, "printElementType": {"title": "表格", "type": "table"}}
|
||||||
|
],
|
||||||
|
"width": 180
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
35
openhis-ui-vue3/src/components/Print/TriageTicket.json
Normal file
35
openhis-ui-vue3/src/components/Print/TriageTicket.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"height": 100,
|
||||||
|
"index": 1,
|
||||||
|
"name": "分诊条",
|
||||||
|
"paperFooter": 283.5,
|
||||||
|
"paperHeader": 0,
|
||||||
|
"paperList": {"height": 100, "type": "自定义", "width": 80},
|
||||||
|
"paperNumberDisabled": true,
|
||||||
|
"paperType": "自定义",
|
||||||
|
"printElements": [
|
||||||
|
{"options": {"fontSize": 14, "fontWeight": "bold", "height": 15, "left": 0, "textAlign": "center", "title": "分诊单", "top": 5, "width": 80}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "hisId", "height": 40, "left": 15, "qrCodeLevel": 0, "textAlign": "center", "title": "病历号二维码", "top": 25, "width": 50}, "printElementType": {"title": "二维码", "type": "text"}},
|
||||||
|
{"options": {"field": "hisId", "fontSize": 10, "height": 10, "left": 0, "textAlign": "center", "title": "病历号:", "top": 70, "width": 80, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "triageLevel", "fontSize": 10, "height": 10, "left": 0, "textAlign": "center", "title": "分级(科室)", "top": 82, "width": 80, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "patientName", "fontSize": 10, "height": 10, "left": 5, "title": "姓名:", "top": 100, "width": 35, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "sex", "fontSize": 10, "height": 10, "left": 40, "title": "性别:", "top": 100, "width": 15, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "age", "fontSize": 10, "height": 10, "left": 55, "title": "年龄:", "top": 100, "width": 20, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "temperature", "fontSize": 9, "height": 10, "left": 5, "title": "体温:", "top": 115, "width": 35, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "sphygmus", "fontSize": 9, "height": 10, "left": 40, "title": "脉搏:", "top": 115, "width": 35, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "breath", "fontSize": 9, "height": 10, "left": 5, "title": "呼吸:", "top": 127, "width": 35, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "bloodPressure", "fontSize": 9, "height": 10, "left": 40, "title": "血压:", "top": 127, "width": 35, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "bloodOxygen", "fontSize": 9, "height": 10, "left": 5, "title": "血氧:", "top": 139, "width": 70, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "triageTime", "fontSize": 9, "height": 10, "left": 5, "title": "分诊时间:", "top": 155, "width": 70, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "tel", "fontSize": 9, "height": 10, "left": 5, "title": "联系电话:", "top": 167, "width": 70, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"fontSize": 9, "fontWeight": "bold", "height": 10, "left": 5, "title": "请仔细核对个人信息后进行挂号", "top": 185, "width": 70}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"fontSize": 8, "height": 8, "left": 5, "title": "为了您家人和其他患者的健康", "top": 197, "width": 70}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"fontSize": 8, "height": 8, "left": 5, "title": "请您保持就诊秩序保持诊区安静", "top": 207, "width": 70}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"fontSize": 8, "height": 8, "left": 5, "title": "祝您早日康复", "top": 217, "width": 70}, "printElementType": {"title": "文本", "type": "text"}}
|
||||||
|
],
|
||||||
|
"width": 80
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
25
openhis-ui-vue3/src/components/Print/WristBand.json
Normal file
25
openhis-ui-vue3/src/components/Print/WristBand.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"height": 25,
|
||||||
|
"index": 1,
|
||||||
|
"name": "腕带",
|
||||||
|
"paperFooter": 94.5,
|
||||||
|
"paperHeader": 0,
|
||||||
|
"paperList": {"height": 25, "type": "自定义", "width": 100},
|
||||||
|
"paperNumberContinue": true,
|
||||||
|
"paperNumberDisabled": true,
|
||||||
|
"paperType": "自定义",
|
||||||
|
"printElements": [
|
||||||
|
{"options": {"field": "patientName", "fontSize": 8, "fontWeight": "bold", "height": 9, "left": 5, "title": "姓名:", "top": 3, "width": 40, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "hisId", "fontSize": 8, "fontWeight": "bold", "height": 9, "left": 50, "title": "病历号:", "top": 3, "width": 45, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "gender", "fontSize": 8, "fontWeight": "bold", "height": 9, "left": 5, "title": "性别:", "top": 13, "width": 40, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "dept", "fontSize": 8, "fontWeight": "bold", "height": 9, "left": 50, "title": "科室:", "top": 13, "width": 45, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "bedName", "fontSize": 8, "fontWeight": "bold", "height": 9, "left": 5, "title": "床号:", "top": 23, "width": 40, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "triageLevel", "fontSize": 8, "fontWeight": "bold", "height": 9, "left": 50, "title": "分级:", "top": 23, "width": 45, "hideTitle": false}, "printElementType": {"title": "文本", "type": "text"}},
|
||||||
|
{"options": {"field": "hisId", "height": 18, "left": 80, "qrCodeLevel": 0, "textAlign": "center", "title": "腕带二维码", "top": 5, "width": 18}, "printElementType": {"title": "二维码", "type": "text"}}
|
||||||
|
],
|
||||||
|
"width": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
108
openhis-ui-vue3/src/views/cardmanagement/api.js
Normal file
108
openhis-ui-vue3/src/views/cardmanagement/api.js
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 统计数据
|
||||||
|
*/
|
||||||
|
export function getCardStatistics() {
|
||||||
|
return request({
|
||||||
|
url: '/card-management/statistics',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 分页列表
|
||||||
|
*/
|
||||||
|
export function getCardList(params) {
|
||||||
|
return request({
|
||||||
|
url: '/card-management/page',
|
||||||
|
method: 'get',
|
||||||
|
params: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 获取报卡详情
|
||||||
|
*/
|
||||||
|
export function getCardDetail(cardNo) {
|
||||||
|
return request({
|
||||||
|
url: `/card-management/detail/${cardNo}`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 获取审核记录
|
||||||
|
*/
|
||||||
|
export function getAuditRecords(cardNo) {
|
||||||
|
return request({
|
||||||
|
url: `/card-management/audit-records/${cardNo}`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 批量审核
|
||||||
|
*/
|
||||||
|
export function batchAudit(data) {
|
||||||
|
return request({
|
||||||
|
url: '/card-management/batch-audit',
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 批量退回
|
||||||
|
*/
|
||||||
|
export function batchReturn(data) {
|
||||||
|
return request({
|
||||||
|
url: '/card-management/batch-return',
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 单条审核通过
|
||||||
|
*/
|
||||||
|
export function auditPass(data) {
|
||||||
|
return request({
|
||||||
|
url: '/card-management/audit-pass',
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 单条退回
|
||||||
|
*/
|
||||||
|
export function auditReturn(data) {
|
||||||
|
return request({
|
||||||
|
url: '/card-management/audit-return',
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 导出
|
||||||
|
*/
|
||||||
|
export function exportCards(params) {
|
||||||
|
return request({
|
||||||
|
url: '/card-management/export',
|
||||||
|
method: 'get',
|
||||||
|
params: params,
|
||||||
|
responseType: 'blob',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报卡管理 - 获取科室列表(树形)
|
||||||
|
*/
|
||||||
|
export function getDeptTree() {
|
||||||
|
return request({
|
||||||
|
url: '/card-management/dept-tree',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,483 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer
|
||||||
|
:model-value="visible"
|
||||||
|
:title="mode === 'audit' ? '审核报卡' : '查看报卡'"
|
||||||
|
direction="rtl"
|
||||||
|
size="700px"
|
||||||
|
:before-close="handleClose"
|
||||||
|
>
|
||||||
|
<div class="drawer-content">
|
||||||
|
<!-- 报卡表单 -->
|
||||||
|
<div class="card-form-section">
|
||||||
|
<h3 class="section-title">中华人民共和国传染病报告卡</h3>
|
||||||
|
|
||||||
|
<el-form :model="cardData" label-width="100px" class="card-form">
|
||||||
|
<!-- 卡片编号 -->
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="卡片编号">
|
||||||
|
<el-input v-model="cardData.cardNo" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 患者基本信息 -->
|
||||||
|
<div class="form-divider">患者基本信息</div>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="患者姓名">
|
||||||
|
<el-input v-model="cardData.patName" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="家长姓名">
|
||||||
|
<el-input v-model="cardData.parentName" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="身份证号">
|
||||||
|
<el-input v-model="cardData.idNo" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="性别">
|
||||||
|
<el-input :value="getSexName(cardData.sex)" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="出生日期">
|
||||||
|
<el-input v-model="cardData.birthday" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="实足年龄">
|
||||||
|
<el-input :value="cardData.age + getAgeUnit(cardData.ageUnit)" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="联系电话">
|
||||||
|
<el-input v-model="cardData.phone" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="紧急电话">
|
||||||
|
<el-input v-model="cardData.contactPhone" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="现住地址">
|
||||||
|
<el-input :value="getFullAddress(cardData)" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="病人属于">
|
||||||
|
<el-input v-model="cardData.patientbelong" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="职业">
|
||||||
|
<el-input v-model="cardData.occupation" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 临床信息 -->
|
||||||
|
<div class="form-divider">临床信息</div>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="病例分类">
|
||||||
|
<el-input :value="getCaseTypeName(cardData.diseaseType)" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="发病日期">
|
||||||
|
<el-input :value="formatDate(cardData.onsetDate)" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="诊断日期">
|
||||||
|
<el-input :value="formatDate(cardData.diagDate)" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="疾病名称">
|
||||||
|
<el-input :value="cardData.diseaseName || cardData.diseaseCode" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="分型">
|
||||||
|
<el-input v-model="cardData.diseaseSubtype" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 上报信息 -->
|
||||||
|
<div class="form-divider">上报信息</div>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="报告单位">
|
||||||
|
<el-input v-model="cardData.reportOrg" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="报告医生">
|
||||||
|
<el-input v-model="cardData.reportDoc" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="填卡日期">
|
||||||
|
<el-input :value="formatDate(cardData.reportDate)" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="登记来源">
|
||||||
|
<el-input :value="getSourceName(cardData.registrationSource)" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 审核记录 -->
|
||||||
|
<div class="audit-records-section" v-if="auditRecords.length > 0">
|
||||||
|
<h3 class="section-title">审核记录</h3>
|
||||||
|
<el-timeline>
|
||||||
|
<el-timeline-item
|
||||||
|
v-for="record in auditRecords"
|
||||||
|
:key="record.auditId"
|
||||||
|
:timestamp="record.auditTime"
|
||||||
|
placement="top"
|
||||||
|
:type="getAuditType(record.auditStatusTo)"
|
||||||
|
>
|
||||||
|
<el-card>
|
||||||
|
<div class="record-content">
|
||||||
|
<div class="record-header">
|
||||||
|
<span class="auditor">{{ record.auditorName }}</span>
|
||||||
|
<el-tag size="small" :type="getAuditType(record.auditStatusTo)">
|
||||||
|
{{ getAuditTypeName(record.auditType) }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
<div class="record-detail">
|
||||||
|
<span v-if="record.auditOpinion">审核意见:{{ record.auditOpinion }}</span>
|
||||||
|
<span v-if="record.reasonForReturn">退回原因:{{ record.reasonForReturn }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="record-status">
|
||||||
|
{{ getStatusName(record.auditStatusFrom) }} → {{ getStatusName(record.auditStatusTo) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-timeline-item>
|
||||||
|
</el-timeline>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 审核操作区域 -->
|
||||||
|
<div class="audit-action-section" v-if="mode === 'audit'">
|
||||||
|
<h3 class="section-title">审核操作</h3>
|
||||||
|
<el-form :model="auditForm" label-width="100px">
|
||||||
|
<el-form-item label="审核意见" required>
|
||||||
|
<el-input
|
||||||
|
v-model="auditForm.auditOpinion"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="请填写审核意见"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="退回原因">
|
||||||
|
<el-input
|
||||||
|
v-model="auditForm.returnReason"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="如需退回,请填写退回原因"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<div class="drawer-footer">
|
||||||
|
<el-button @click="handleClose">关闭</el-button>
|
||||||
|
<template v-if="mode === 'audit'">
|
||||||
|
<el-button type="warning" @click="handleReturn" :disabled="!auditForm.returnReason">
|
||||||
|
退回修改
|
||||||
|
</el-button>
|
||||||
|
<el-button type="success" @click="handlePass" :disabled="!auditForm.auditOpinion">
|
||||||
|
审核通过
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'view', // view | audit
|
||||||
|
},
|
||||||
|
cardData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
auditRecords: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['close', 'submit']);
|
||||||
|
|
||||||
|
const auditForm = ref({
|
||||||
|
auditOpinion: '',
|
||||||
|
returnReason: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 状态映射
|
||||||
|
const statusMap = {
|
||||||
|
'0': '暂存',
|
||||||
|
'1': '待审核',
|
||||||
|
'2': '审核通过',
|
||||||
|
'3': '已上报',
|
||||||
|
'4': '失败',
|
||||||
|
'5': '审核失败',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 审核类型映射
|
||||||
|
const auditTypeMap = {
|
||||||
|
'1': '批量审核',
|
||||||
|
'2': '审核通过',
|
||||||
|
'3': '批量退回',
|
||||||
|
'4': '退回修改',
|
||||||
|
'5': '其他',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 病例分类映射
|
||||||
|
const caseTypeMap = {
|
||||||
|
'1': '疑似病例',
|
||||||
|
'2': '临床诊断病例',
|
||||||
|
'3': '确诊病例',
|
||||||
|
'4': '病原携带者',
|
||||||
|
'5': '阳性检测结果',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 年龄单位映射
|
||||||
|
const ageUnitMap = {
|
||||||
|
'1': '岁',
|
||||||
|
'2': '月',
|
||||||
|
'3': '天',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 来源映射
|
||||||
|
const sourceMap = {
|
||||||
|
1: '门诊',
|
||||||
|
2: '住院',
|
||||||
|
3: '急诊',
|
||||||
|
4: '体检',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取状态名称
|
||||||
|
function getStatusName(status) {
|
||||||
|
return statusMap[status] || '未知';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取审核类型名称
|
||||||
|
function getAuditTypeName(type) {
|
||||||
|
return auditTypeMap[type] || '未知';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取审核类型样式
|
||||||
|
function getAuditType(status) {
|
||||||
|
if (status === '2') return 'success';
|
||||||
|
if (status === '5') return 'warning';
|
||||||
|
return 'primary';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取性别名称
|
||||||
|
function getSexName(sex) {
|
||||||
|
if (sex === '1') return '男';
|
||||||
|
if (sex === '2') return '女';
|
||||||
|
return '未知';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取年龄单位
|
||||||
|
function getAgeUnit(unit) {
|
||||||
|
return ageUnitMap[unit] || '岁';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取病例分类名称
|
||||||
|
function getCaseTypeName(type) {
|
||||||
|
return caseTypeMap[type] || '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取来源名称
|
||||||
|
function getSourceName(source) {
|
||||||
|
return sourceMap[source] || '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取完整地址
|
||||||
|
function getFullAddress(data) {
|
||||||
|
const parts = [
|
||||||
|
data.addressProv,
|
||||||
|
data.addressCity,
|
||||||
|
data.addressCounty,
|
||||||
|
data.addressTown,
|
||||||
|
data.addressVillage,
|
||||||
|
data.addressHouse,
|
||||||
|
].filter(Boolean);
|
||||||
|
return parts.join('') || '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化日期
|
||||||
|
function formatDate(date) {
|
||||||
|
if (!date) return '-';
|
||||||
|
if (typeof date === 'string') return date.split('T')[0];
|
||||||
|
return new Date(date).toISOString().split('T')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭抽屉
|
||||||
|
function handleClose() {
|
||||||
|
emit('close');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审核通过
|
||||||
|
function handlePass() {
|
||||||
|
if (!auditForm.value.auditOpinion) {
|
||||||
|
ElMessage.warning('请填写审核意见');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit('submit', {
|
||||||
|
type: 'pass',
|
||||||
|
cardNo: props.cardData.cardNo,
|
||||||
|
auditOpinion: auditForm.value.auditOpinion,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退回修改
|
||||||
|
function handleReturn() {
|
||||||
|
if (!auditForm.value.returnReason) {
|
||||||
|
ElMessage.warning('请填写退回原因');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit('submit', {
|
||||||
|
type: 'return',
|
||||||
|
cardNo: props.cardData.cardNo,
|
||||||
|
returnReason: auditForm.value.returnReason,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听visible变化,重置表单
|
||||||
|
watch(() => props.visible, (val) => {
|
||||||
|
if (val) {
|
||||||
|
auditForm.value = {
|
||||||
|
auditOpinion: '',
|
||||||
|
returnReason: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.drawer-content {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #303133;
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 2px solid #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-form-section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-form {
|
||||||
|
padding: 16px;
|
||||||
|
background: #fafafa;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-divider {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #606266;
|
||||||
|
margin: 16px 0 12px 0;
|
||||||
|
padding-left: 8px;
|
||||||
|
border-left: 3px solid #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audit-records-section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-content {
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auditor {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-detail {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #606266;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-status {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audit-action-section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audit-action-section .el-form {
|
||||||
|
padding: 16px;
|
||||||
|
background: #fafafa;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-drawer__footer) {
|
||||||
|
padding: 16px 20px;
|
||||||
|
border-top: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
810
openhis-ui-vue3/src/views/cardmanagement/index.vue
Normal file
810
openhis-ui-vue3/src/views/cardmanagement/index.vue
Normal file
@@ -0,0 +1,810 @@
|
|||||||
|
<template>
|
||||||
|
<div class="card-management-container">
|
||||||
|
<!-- 统计卡片区域 -->
|
||||||
|
<div class="statistics-section">
|
||||||
|
<div class="stat-card" @click="handleStatClick('todayPending')">
|
||||||
|
<div class="stat-icon pending">
|
||||||
|
<el-icon><Clock /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="stat-content">
|
||||||
|
<div class="stat-value">{{ statistics.todayPending || 0 }}</div>
|
||||||
|
<div class="stat-label">今日待审核</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card" @click="handleStatClick('monthFailed')">
|
||||||
|
<div class="stat-icon failed">
|
||||||
|
<el-icon><CircleClose /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="stat-content">
|
||||||
|
<div class="stat-value">{{ statistics.monthFailed || 0 }}</div>
|
||||||
|
<div class="stat-label">本月审核失败</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card" @click="handleStatClick('monthSuccess')">
|
||||||
|
<div class="stat-icon success">
|
||||||
|
<el-icon><CircleCheck /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="stat-content">
|
||||||
|
<div class="stat-value">{{ statistics.monthSuccess || 0 }}</div>
|
||||||
|
<div class="stat-label">本月审核成功</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card" @click="handleStatClick('monthReported')">
|
||||||
|
<div class="stat-icon reported">
|
||||||
|
<el-icon><Upload /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="stat-content">
|
||||||
|
<div class="stat-value">{{ statistics.monthReported || 0 }}</div>
|
||||||
|
<div class="stat-label">本月已上报</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 筛选控制区 -->
|
||||||
|
<div class="filter-section">
|
||||||
|
<el-form :model="queryParams" :inline="true" class="filter-form">
|
||||||
|
<el-form-item label="登记来源">
|
||||||
|
<el-select v-model="queryParams.registrationSource" placeholder="全部" clearable style="width: 120px">
|
||||||
|
<el-option label="全部" value="" />
|
||||||
|
<el-option label="门诊" value="1" />
|
||||||
|
<el-option label="住院" value="2" />
|
||||||
|
<el-option label="急诊" value="3" />
|
||||||
|
<el-option label="体检" value="4" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="上报时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.reportTimeRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
style="width: 240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="患者姓名">
|
||||||
|
<el-input v-model="queryParams.patientName" placeholder="请输入患者姓名" clearable style="width: 150px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="审核状态">
|
||||||
|
<el-select v-model="queryParams.status" placeholder="全部" clearable style="width: 120px">
|
||||||
|
<el-option label="全部" value="" />
|
||||||
|
<el-option label="待审核" value="1" />
|
||||||
|
<el-option label="审核通过" value="2" />
|
||||||
|
<el-option label="审核失败" value="5" />
|
||||||
|
<el-option label="已上报" value="3" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="上报科室">
|
||||||
|
<el-tree-select
|
||||||
|
v-model="queryParams.deptId"
|
||||||
|
:data="deptTreeData"
|
||||||
|
:props="{ value: 'id', label: 'name', children: 'children' }"
|
||||||
|
placeholder="全部科室"
|
||||||
|
clearable
|
||||||
|
check-strictly
|
||||||
|
style="width: 180px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleQuery">
|
||||||
|
<el-icon><Search /></el-icon>
|
||||||
|
查询
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="handleReset">
|
||||||
|
<el-icon><Refresh /></el-icon>
|
||||||
|
重置
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 操作按钮区 -->
|
||||||
|
<div class="action-section">
|
||||||
|
<el-button type="primary" :disabled="selectedRows.length === 0" @click="handleBatchAudit">
|
||||||
|
<el-icon><Check /></el-icon>
|
||||||
|
批量审核
|
||||||
|
</el-button>
|
||||||
|
<el-button type="warning" :disabled="selectedRows.length === 0" @click="handleBatchReturn">
|
||||||
|
<el-icon><Close /></el-icon>
|
||||||
|
批量退回
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="handleExport">
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
导出当前
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 报卡列表区 -->
|
||||||
|
<div class="table-section">
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="cardList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
:row-class-name="getRowClassName"
|
||||||
|
border
|
||||||
|
stripe
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="报卡名称" prop="cardName" min-width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getCardName(row.cardNameCode) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="病种名称" prop="diseaseName" min-width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.diseaseName || getDiseaseName(row.diseaseCode) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="报卡编号" prop="cardNo" min-width="150" />
|
||||||
|
<el-table-column label="患者姓名" prop="patName" width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ maskName(row.patName) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" prop="sex" width="60" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.sex === '1' ? '男' : row.sex === '2' ? '女' : '未知' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="年龄" prop="age" width="70" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.age ? row.age + getAgeUnit(row.ageUnit) : '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="上报科室" prop="deptName" min-width="100" />
|
||||||
|
<el-table-column label="登记来源" prop="registrationSource" width="90" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getSourceName(row.registrationSource) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="上报时间" prop="createTime" width="160" align="center" />
|
||||||
|
<el-table-column label="状态" prop="status" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="getStatusType(row.status)" size="small">
|
||||||
|
{{ getStatusName(row.status) }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button
|
||||||
|
v-if="row.status !== '2' && row.status !== '3'"
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
@click="handleAudit(row)"
|
||||||
|
>
|
||||||
|
审核
|
||||||
|
</el-button>
|
||||||
|
<el-button type="default" link size="small" @click="handleView(row)">
|
||||||
|
查看
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页 -->
|
||||||
|
<div class="pagination-section">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="queryParams.pageNo"
|
||||||
|
v-model:page-size="queryParams.pageSize"
|
||||||
|
:page-sizes="[5, 10, 20, 50]"
|
||||||
|
:total="total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="getList"
|
||||||
|
@current-change="getList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 审核抽屉 -->
|
||||||
|
<AuditDrawer
|
||||||
|
ref="auditDrawerRef"
|
||||||
|
:visible="drawerVisible"
|
||||||
|
:mode="drawerMode"
|
||||||
|
:card-data="currentCard"
|
||||||
|
:audit-records="currentAuditRecords"
|
||||||
|
@close="handleDrawerClose"
|
||||||
|
@submit="handleAuditSubmit"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 批量审核弹窗 -->
|
||||||
|
<el-dialog v-model="batchAuditVisible" title="批量审核" width="500px">
|
||||||
|
<el-form :model="batchForm" label-width="100px">
|
||||||
|
<el-form-item label="审核意见" required>
|
||||||
|
<el-input
|
||||||
|
v-model="batchForm.auditOpinion"
|
||||||
|
type="textarea"
|
||||||
|
:rows="4"
|
||||||
|
placeholder="请填写审核意见(必填)"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="选中数量">
|
||||||
|
<span>{{ selectedRows.length }} 条</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="batchAuditVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmBatchAudit" :disabled="!batchForm.auditOpinion">
|
||||||
|
确认审核
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 批量退回弹窗 -->
|
||||||
|
<el-dialog v-model="batchReturnVisible" title="批量退回" width="500px">
|
||||||
|
<el-form :model="batchForm" label-width="100px">
|
||||||
|
<el-form-item label="退回原因" required>
|
||||||
|
<el-input
|
||||||
|
v-model="batchForm.returnReason"
|
||||||
|
type="textarea"
|
||||||
|
:rows="4"
|
||||||
|
placeholder="请填写退回原因(必填)"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="选中数量">
|
||||||
|
<span>{{ selectedRows.length }} 条</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="batchReturnVisible = false">取消</el-button>
|
||||||
|
<el-button type="warning" @click="confirmBatchReturn" :disabled="!batchForm.returnReason">
|
||||||
|
确认退回
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import {
|
||||||
|
Clock, CircleClose, CircleCheck, Upload, Search, Refresh,
|
||||||
|
Check, Close, Download
|
||||||
|
} from '@element-plus/icons-vue';
|
||||||
|
import {
|
||||||
|
getCardStatistics, getCardList, getCardDetail, getAuditRecords,
|
||||||
|
batchAudit, batchReturn, auditPass, auditReturn, exportCards, getDeptTree
|
||||||
|
} from './api';
|
||||||
|
import AuditDrawer from './components/AuditDrawer.vue';
|
||||||
|
|
||||||
|
// 状态定义
|
||||||
|
const loading = ref(false);
|
||||||
|
const cardList = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const selectedRows = ref([]);
|
||||||
|
const statistics = ref({
|
||||||
|
todayPending: 0,
|
||||||
|
monthFailed: 0,
|
||||||
|
monthSuccess: 0,
|
||||||
|
monthReported: 0,
|
||||||
|
});
|
||||||
|
const deptTreeData = ref([]);
|
||||||
|
|
||||||
|
// 查询参数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
registrationSource: '',
|
||||||
|
reportTimeRange: [],
|
||||||
|
patientName: '',
|
||||||
|
status: '',
|
||||||
|
deptId: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 抽屉相关
|
||||||
|
const drawerVisible = ref(false);
|
||||||
|
const drawerMode = ref('view'); // view | audit
|
||||||
|
const currentCard = ref({});
|
||||||
|
const currentAuditRecords = ref([]);
|
||||||
|
const auditDrawerRef = ref(null);
|
||||||
|
|
||||||
|
// 批量操作弹窗
|
||||||
|
const batchAuditVisible = ref(false);
|
||||||
|
const batchReturnVisible = ref(false);
|
||||||
|
const batchForm = reactive({
|
||||||
|
auditOpinion: '',
|
||||||
|
returnReason: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 状态映射
|
||||||
|
const statusMap = {
|
||||||
|
'0': { name: '暂存', type: 'info' },
|
||||||
|
'1': { name: '待审核', type: 'warning' },
|
||||||
|
'2': { name: '审核通过', type: 'success' },
|
||||||
|
'3': { name: '已上报', type: 'primary' },
|
||||||
|
'4': { name: '失败', type: 'danger' },
|
||||||
|
'5': { name: '审核失败', type: 'danger' },
|
||||||
|
};
|
||||||
|
|
||||||
|
// 报卡名称映射
|
||||||
|
const cardNameMap = {
|
||||||
|
1: '传染病报告卡',
|
||||||
|
2: '肺结核报告卡',
|
||||||
|
3: '艾滋病报告卡',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 登记来源映射
|
||||||
|
const sourceMap = {
|
||||||
|
1: '门诊',
|
||||||
|
2: '住院',
|
||||||
|
3: '急诊',
|
||||||
|
4: '体检',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 年龄单位映射
|
||||||
|
const ageUnitMap = {
|
||||||
|
'1': '岁',
|
||||||
|
'2': '月',
|
||||||
|
'3': '天',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取状态名称
|
||||||
|
function getStatusName(status) {
|
||||||
|
return statusMap[status]?.name || '未知';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态类型
|
||||||
|
function getStatusType(status) {
|
||||||
|
return statusMap[status]?.type || 'info';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取报卡名称
|
||||||
|
function getCardName(code) {
|
||||||
|
return cardNameMap[code] || '传染病报告卡';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取登记来源名称
|
||||||
|
function getSourceName(source) {
|
||||||
|
return sourceMap[source] || '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取年龄单位
|
||||||
|
function getAgeUnit(unit) {
|
||||||
|
return ageUnitMap[unit] || '岁';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 脱敏姓名
|
||||||
|
function maskName(name) {
|
||||||
|
if (!name || name.length <= 2) return name;
|
||||||
|
return name[0] + '*'.repeat(name.length - 2) + name[name.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取疾病名称(从代码映射)
|
||||||
|
function getDiseaseName(code) {
|
||||||
|
// 实际应从字典获取
|
||||||
|
const diseaseMap = {
|
||||||
|
'0203': '病毒性肝炎',
|
||||||
|
'0206': '麻疹',
|
||||||
|
'0213': '肺结核',
|
||||||
|
'0222': '梅毒',
|
||||||
|
'0311': '手足口病',
|
||||||
|
};
|
||||||
|
return diseaseMap[code] || code || '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取行样式类名
|
||||||
|
function getRowClassName({ row }) {
|
||||||
|
if (row.status === '2') return 'row-success';
|
||||||
|
if (row.status === '5') return 'row-warning';
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取统计数据
|
||||||
|
async function getStatistics() {
|
||||||
|
try {
|
||||||
|
const res = await getCardStatistics();
|
||||||
|
if (res.code === 200) {
|
||||||
|
statistics.value = res.data || {};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取统计数据失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取列表数据
|
||||||
|
async function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const params = { ...queryParams };
|
||||||
|
if (params.reportTimeRange && params.reportTimeRange.length === 2) {
|
||||||
|
params.startDate = params.reportTimeRange[0];
|
||||||
|
params.endDate = params.reportTimeRange[1];
|
||||||
|
}
|
||||||
|
delete params.reportTimeRange;
|
||||||
|
|
||||||
|
const res = await getCardList(params);
|
||||||
|
if (res.code === 200) {
|
||||||
|
cardList.value = res.data?.list || [];
|
||||||
|
total.value = res.data?.total || 0;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取列表失败:', error);
|
||||||
|
ElMessage.error('获取数据失败,请检查网络');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取科室树
|
||||||
|
async function getDeptTreeData() {
|
||||||
|
try {
|
||||||
|
const res = await getDeptTree();
|
||||||
|
if (res.code === 200) {
|
||||||
|
deptTreeData.value = res.data || [];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取科室树失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.pageNo = 1;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
function handleReset() {
|
||||||
|
queryParams.pageNo = 1;
|
||||||
|
queryParams.pageSize = 10;
|
||||||
|
queryParams.registrationSource = '';
|
||||||
|
queryParams.reportTimeRange = [];
|
||||||
|
queryParams.patientName = '';
|
||||||
|
queryParams.status = '';
|
||||||
|
queryParams.deptId = '';
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计卡片点击
|
||||||
|
function handleStatClick(type) {
|
||||||
|
const today = new Date();
|
||||||
|
const todayStr = today.toISOString().split('T')[0];
|
||||||
|
const monthStart = new Date(today.getFullYear(), today.getMonth(), 1).toISOString().split('T')[0];
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'todayPending':
|
||||||
|
queryParams.reportTimeRange = [todayStr, todayStr];
|
||||||
|
queryParams.status = '1';
|
||||||
|
break;
|
||||||
|
case 'monthFailed':
|
||||||
|
queryParams.reportTimeRange = [monthStart, todayStr];
|
||||||
|
queryParams.status = '5';
|
||||||
|
break;
|
||||||
|
case 'monthSuccess':
|
||||||
|
queryParams.reportTimeRange = [monthStart, todayStr];
|
||||||
|
queryParams.status = '2';
|
||||||
|
break;
|
||||||
|
case 'monthReported':
|
||||||
|
queryParams.reportTimeRange = [monthStart, todayStr];
|
||||||
|
queryParams.status = '3';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择变化
|
||||||
|
function handleSelectionChange(selection) {
|
||||||
|
selectedRows.value = selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量审核
|
||||||
|
function handleBatchAudit() {
|
||||||
|
const invalidRows = selectedRows.value.filter(row => row.status === '2' || row.status === '3');
|
||||||
|
if (invalidRows.length > 0) {
|
||||||
|
ElMessage.warning('只能选择待审核或审核失败的报卡');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
batchForm.auditOpinion = '';
|
||||||
|
batchAuditVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认批量审核
|
||||||
|
async function confirmBatchAudit() {
|
||||||
|
if (!batchForm.auditOpinion) {
|
||||||
|
ElMessage.warning('请填写审核意见');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const cardNos = selectedRows.value.map(row => row.cardNo);
|
||||||
|
const res = await batchAudit({
|
||||||
|
cardNos,
|
||||||
|
auditOpinion: batchForm.auditOpinion,
|
||||||
|
});
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success('批量审核成功');
|
||||||
|
batchAuditVisible.value = false;
|
||||||
|
getStatistics();
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '审核失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('审核失败,请检查网络');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量退回
|
||||||
|
function handleBatchReturn() {
|
||||||
|
const invalidRows = selectedRows.value.filter(row => row.status === '2' || row.status === '3');
|
||||||
|
if (invalidRows.length > 0) {
|
||||||
|
ElMessage.warning('只能选择待审核或审核失败的报卡');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
batchForm.returnReason = '';
|
||||||
|
batchReturnVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认批量退回
|
||||||
|
async function confirmBatchReturn() {
|
||||||
|
if (!batchForm.returnReason) {
|
||||||
|
ElMessage.warning('请填写退回原因');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const cardNos = selectedRows.value.map(row => row.cardNo);
|
||||||
|
const res = await batchReturn({
|
||||||
|
cardNos,
|
||||||
|
returnReason: batchForm.returnReason,
|
||||||
|
});
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success('批量退回成功');
|
||||||
|
batchReturnVisible.value = false;
|
||||||
|
getStatistics();
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '退回失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('退回失败,请检查网络');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出
|
||||||
|
async function handleExport() {
|
||||||
|
try {
|
||||||
|
const res = await exportCards(queryParams);
|
||||||
|
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = `报卡列表_${new Date().toISOString().split('T')[0]}.xlsx`;
|
||||||
|
link.click();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('导出失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审核(单条)
|
||||||
|
async function handleAudit(row) {
|
||||||
|
try {
|
||||||
|
const [cardRes, auditRes] = await Promise.all([
|
||||||
|
getCardDetail(row.cardNo),
|
||||||
|
getAuditRecords(row.cardNo),
|
||||||
|
]);
|
||||||
|
if (cardRes.code === 200) {
|
||||||
|
currentCard.value = cardRes.data || {};
|
||||||
|
currentAuditRecords.value = auditRes.code === 200 ? (auditRes.data || []) : [];
|
||||||
|
drawerMode.value = 'audit';
|
||||||
|
drawerVisible.value = true;
|
||||||
|
} else {
|
||||||
|
ElMessage.error('数据加载失败,请重试');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('数据加载失败,请重试');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看
|
||||||
|
async function handleView(row) {
|
||||||
|
try {
|
||||||
|
const [cardRes, auditRes] = await Promise.all([
|
||||||
|
getCardDetail(row.cardNo),
|
||||||
|
getAuditRecords(row.cardNo),
|
||||||
|
]);
|
||||||
|
if (cardRes.code === 200) {
|
||||||
|
currentCard.value = cardRes.data || {};
|
||||||
|
currentAuditRecords.value = auditRes.code === 200 ? (auditRes.data || []) : [];
|
||||||
|
drawerMode.value = 'view';
|
||||||
|
drawerVisible.value = true;
|
||||||
|
} else {
|
||||||
|
ElMessage.error('数据加载失败,请重试');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('数据加载失败,请重试');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭抽屉
|
||||||
|
function handleDrawerClose() {
|
||||||
|
drawerVisible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审核提交
|
||||||
|
async function handleAuditSubmit(data) {
|
||||||
|
try {
|
||||||
|
let res;
|
||||||
|
if (data.type === 'pass') {
|
||||||
|
res = await auditPass({
|
||||||
|
cardNo: data.cardNo,
|
||||||
|
auditOpinion: data.auditOpinion,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res = await auditReturn({
|
||||||
|
cardNo: data.cardNo,
|
||||||
|
returnReason: data.returnReason,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success(data.type === 'pass' ? '审核通过' : '已退回');
|
||||||
|
drawerVisible.value = false;
|
||||||
|
getStatistics();
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '操作失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('操作失败,请检查网络');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
onMounted(() => {
|
||||||
|
// 设置默认时间范围为最近一个月
|
||||||
|
const today = new Date();
|
||||||
|
const monthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
|
||||||
|
queryParams.reportTimeRange = [
|
||||||
|
monthAgo.toISOString().split('T')[0],
|
||||||
|
today.toISOString().split('T')[0],
|
||||||
|
];
|
||||||
|
|
||||||
|
getStatistics();
|
||||||
|
getList();
|
||||||
|
getDeptTreeData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.card-management-container {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
min-height: calc(100vh - 84px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统计卡片区域 */
|
||||||
|
.statistics-section {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-icon {
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-icon.pending {
|
||||||
|
background: rgba(64, 158, 255, 0.1);
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-icon.failed {
|
||||||
|
background: rgba(245, 108, 108, 0.1);
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-icon.success {
|
||||||
|
background: rgba(103, 194, 58, 0.1);
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-icon.reported {
|
||||||
|
background: rgba(144, 147, 153, 0.1);
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #303133;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #909399;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 筛选区域 */
|
||||||
|
.filter-section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px 20px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-form {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 操作区域 */
|
||||||
|
.action-section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px 20px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格区域 */
|
||||||
|
.table-section {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-section {
|
||||||
|
margin-top: 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 行样式 */
|
||||||
|
:deep(.row-success) {
|
||||||
|
background-color: rgba(103, 194, 58, 0.05) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.row-warning) {
|
||||||
|
background-color: rgba(230, 162, 60, 0.05) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式 */
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.statistics-section {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.statistics-section {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user