武警医院系统设计说明书
武警医院自助服务终端
系统概要详细设计说明书
1. 前言.............................................................................................................................................. 3
1.1. 文档目的 .......................................................................................................................... 3 1.2. 文档的范围 ...................................................................................................................... 3 1.3. 读者对象 .......................................................................................................................... 3 1.4. 参考资料 .......................................................................................................................... 3
2. 终端管理系统架构 ...................................................................................................................... 4 2.1. 总体设计 .......................................................................................................................... 4
2.1.1. 系统前台 ................................................................................................................ 4
2.1.2. 系统后台管理系统 ................................................................................................ 4 2.2. 设计流程 .......................................................................................................................... 5 2.3. 医院就诊卡现金充值交易 .............................................................................................. 5 2.4. 充值机通过HIS系统接口实现功能 .............................................................................. 6
2.5. 需求规定 .......................................................................................................................... 7
2.5.1. 基本要求 ................................................................................................................ 7
2.5.2. 功能要求 ................................................................................................................ 7
2.5.3. 精度 ...................................................................................................................... 11
2.5.4. 时间特性 .............................................................................................................. 11
2.5.5. 其他专门要求 ...................................................................................................... 11 2.6. 运行环境 ........................................................................................................................ 12
3. 详细设计 .................................................................................................................................... 12
3.1创办诊疗卡 ....................................................................................................................... 12 3.2充值业务 ........................................................................................................................... 16
3.3挂号业务 ........................................................................................................................... 21
3.3.1功能描述 ................................................................................................................ 21
3.3.2业务逻辑和数据库设计 ........................................................................................ 21 3.4缴费业务 ........................................................................................................................... 35
3.5 终端管理模块 ................................................................................................................. 41 3.6 日志管理模块 .................................................................................................................. 45 3.7 充值管理模块 .................................................................................................................. 52 3.8 终端设置模块 .................................................................................................................. 57
1. 前言
武警医院自助服务是集合了终端机、终端管理、中行交易三大板块网络系统。每个系统都包含着管理系统,终端作为与用户的交互界面,对其管理尤为重要。
终端管理系统是增值业务系统的辅助管理系统之一,主要包含了终端基本信息的管理、终端日志的管理、终端程序版本的管理、对终端监控管理、对终端报警的管理。
终端安全的管理也是一个重要的方面,对终端的认证、维护等在安全系统里有详细的介绍。
1.1. 文档目的
本文作为终端管理系统的开发基础;可作为终端规范的参考文档,文档为武警医院自助服务终端项目的详细设计。可作为终端管理系统的项目评估参考文档。
1.2. 文档的范围
武警医院自助服务终端系统详细设计包含了发放诊疗卡、充值、挂号、交费、打印诊疗单(化验单)等;
1.3. 读者对象
武警医院,承接商,项目评估小组成员,程序员。
1.4. 参考资料
《系统需求说明书》
2. 终端管理系统架构
2.1. 总体设计
2.1.1. 系统前台
, 创办诊疗卡模块
可以通过自助终端为医院创办个人诊卡。填写个人详细信息.
, 诊疗卡充值模块
进行充值的功能,包含了两种类型的交易:现金充值,中行充值。
, 挂号模块
可以在自助终端上挂号也可预约挂号,可以凭诊疗卡在自助终端上领号。
, 缴费模块
可以凭借诊疗卡在自助终端上查询未交费的项目,如果有未交费的信息,可以在自助终端上缴费。
2.1.2. 系统后台管理系统
, 终端管理模块
, 日志管理模块
, 充值管理模块
, 终端设置模块
2.2. 设计流程
医院HIS系统 充值机后台管理系统
医院局域网
住院门诊收费窗口 充值机充值机 门诊医生、住院部医生、收费人员,取药窗口自助服务,提供给患者或家属对就诊卡进行等通过客户端软件连接到HIS系统中进行相应 现金充值,从而可以在门诊,住院部等进行的功能操作。就诊。
2.3. 医院就诊卡现金充值交易
缔邦充值机自助充值系统医院信息管理系统自助终端
1 : 插入医院就诊卡()
上送查询余额交易()2 :
上送查询余额交易()3 :
返回帐户信息()4 :
返回帐户信息()5 :
显示帐户余额()6 :
插入现金(50、100元等)()7 :
上送现金充值交易()8 :
上送现金充值交易()9 :
返回交易结果()10 : 返回交易结果()11 :
显示交易结果()12 :
打印凭条()13 :
2.4. 充值机通过HIS系统接口实现功能
读取就诊 自卡 助 现金充值 终接 口 端 实 充 查询充值记现 HIS系统值 录 数据库 机 查询余额
预缴金
查询日清单
2.5. 需求规定
2.5.1. 基本要求
, B/S模式。
, 通信使用TCP/IP协议。
, 页面由freemaker 实现。
, 简单管理(增删查改)用minilang实现。
, 数据库操作使用Hipay实体引擎。
, 通讯服务程序使用Hipay服务引擎。
2.5.2. 功能要求
详情请见《系统需求说明书》,《系统需求规格说明书》。 前台自助服务终端系统:
1. 办诊疗卡功能:用户可以通过扫描二代身份证或银行卡的方式在自助终端办理诊疗卡。
A. 通过扫描仪读取二代身份证信息获取用户真实的个人资料。
B(如果扫描失败,用户可以通过窗口办卡系统,办理诊疗卡。
C(第一次办卡必须给卡里充值,如不充值则办卡失败,充值分为现金充值和联充值。
D(通过钱箱系统识别现金及其对现金其他操作。
E(插入银联卡后,通过调用银联系统进行充值处理。
F(办卡成功从自助终端设备弹出办理好的诊疗卡。
具体流程图如下:
2.医保卡缴费:使用自助终端医保结算缴费方式。 A. 插入诊疗卡后,输入诊疗卡密码。
B. 选择查询缴费信息
C. 进入缴费信息详情页面查看药品或检查价格与数量。 D. 选择要缴费的单据插入医保卡。
E. 选择缴费,扣费成功取走缴费单据。
充值流程图如下 图 1-2所示:
图 1-2
3. 诊疗卡挂号功能:使用诊疗卡可以在自助终端上自行挂号。 A. 插入诊疗卡,系统识别后方可进行挂号业务操作。 B. 挂号分为:诊疗卡挂号,中行诊疗卡挂号
C. 输入诊疗卡密码,密码错误从新插卡
D. 选择科室,选择挂号
E. 选择好号后弹出确认挂号信息界面,确认完毕,挂号成功。 挂号流程图如下 图 1-3 所示:
4 查询机
A:插入诊疗卡,选择查询缴费信息,进入查询缴费信息页面显示过去所有消费充值信息。
B:选择药品信息查询,进入药品查询信息后输入药品名称,可具体查询药品详细信息与价格
5 化验单打印
A:插入诊疗卡,输入诊疗卡密码,显示分别黑白打印机(化验单打印)彩色打印机(pacs打印)。
B:选择打印的化验单,打印化验单,取走化验单。
后台终端管理系统:
输入 处理 输出
终端号、ip地址、联系人、
终端号 查询 联系电话、终端类型、创
建时间
终端号 查询 终端号、状态、ip
终端号 查询 终端、事件、时间
用户名、密码、真实姓名、用户名 查询 用户角色、备注
终端要求:100台以上同时缴费功能。
终端故障报警:并发交易满足100台。
2.5.3. 精度
该软件在输入、输出时保留到小数点后两位,在传输过程中保存到小数点后三位。
2.5.4. 时间特性
1. 页面响应时间:小于1s。
2. 更新处理时间:小于1s。
3. 数据的转换和处理时间:小于1s。
2.5.5. 其他专门要求
1.安全性:前台终端设备前后有锁,钱箱有锁。
后台系统在登录后,有管理权限的设定。
2.可维护性:可维护。
3.易操作性:易操作。
4.GUI界面:颜色绿色
2.6. 运行环境
硬件环境:。自助终端为公共自助智能终端。管理终端为PC机。
软件环境:
操作系统:系统自带。
自助终端:嵌入式操作系统。
管理终端:WIN2008。
应用系统:应用系统为HiPay系统,
数据库系统:ORACLE或DB2或INFORMIX。
网络环境:ADSL网络或其他电信的网络系统。
3. 详细设计
3.1创办诊疗卡
, 参数设置
函数返回值:boolean true/false
参数名称 数据类型 是否可为空 说明 IDCard String 是 身份证号 Name String 否 姓名 Sex String 否 性别 Birthday Date 否 出生日期 MedicalCardID String 否 医疗卡号 FillingMoney double 否 充钱(办卡的时候不
充钱是不吐卡的)
, 部分代码
public Response createCard(Patient patient,
MedicalCard medicalCard, String terminalNo, String flag) {
Response response = new Response();
try {
Timestamp createDate = new Timestamp(new Date().getTime());
String idNo = patient.getIdNo(); //身份证号
String name = patient.getName(); //姓名
Date birthday = patient.getBirthday(); //出生日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //格式化出生日期
patient.setBirthday(sdf.parse(sdf.format(birthday)));
patient.setOperator(terminalNo.trim());
//根据卡号判断卡是否存在,若存在,判断状态
MedicalCard card = baseService.queryMedicalCard(medicalCard.getCardNo());
if(card != null && card.getStatus() != 2){ //若状态不等于注销,该卡不可用,予以回收
response.setResult("F");
response.setErrorInfo("卡未注销");
}else { //卡存在且状态等于注销,该卡回收利用,更新卡信息,再次发出
medicalCard.setCreateDate(createDate);
medicalCard.setBalance(0);
//medicalCard.setPassword(MD5Util.MD5(medicalCard.
getPassword()));
medicalCard.setPassword(MD5Util.MD5("123456"));
medicalCard.setPat_birthday(sdf.parse(sdf.format(birthday)));
medicalCard.setPat_idNo(idNo);
medicalCard.setPat_name(name);
medicalCard.setPat_sex(patient.getSex());
medicalCard.setStatus(0);
medicalCard.setTelphone(patient.getPhone());
MedicalCard medcard = baseService.createCard(patient, medicalCard, flag);
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
medcard.setCreateTime(sdf1.format(medcard.getCreateDate()));
response.setData(medcard);
response.setResult("S");
}
} catch (Exception e) {
loger.error("\n");
e.printStackTrace();
loger.error("============================建卡失败
===========================");
loger.error(e,e);
System.out.println(e.getMessage());
response.setResult("F");
response.setErrorInfo("建卡失败,请联系工作人员"); //response.setErrorInfo("建卡失败,服务器异常,请重试
或联系工作人员");
//保存异常信息
ExceptionInfo info = new ExceptionInfo(); Timestamp exceptionDate = new Timestamp(new
Date().getTime());
info.setExceptionDate(exceptionDate);
info.setDescription(e.getMessage());
info.setCardNo(medicalCard.getCardNo()); info.setTerminalNo(terminalNo);
info.setSummary("创建诊疗卡异常");
try {
baseService.saveException(info);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return response;
}
3.2充值业务
, 参数设置
功能:充值:fillingMoney();
函数调用:现金充值 ---- usePaperMoney();
银联充值 ---- useBankCard();
函数返回值:boolean true/false(是否充值成功)
参数名称 数据类型 是否可为空 说明
否 医疗卡号 medicalCardID String
否 银行卡号 bankCardID String
否 充值类型 addMoneyType int
否 充值金额 amount double
, 描述
, 充值服务包括现金充值和银联充值,用户可以选择其中的任
意一种方式来完成充值业务。
, 用户在进行现金充值操作时,存放现金时必须每次只放一张
50元或100元面值的人民币,可存放多张。
, 用户在进行银联充值操作时,在选择要充值的金额时,如果
终端上得金额显示菜单不能满足用户的需求,用户可以手动输入充值
金额进行充值。
, 部分代码
public Response recharge(MedicalCard card, String
terminalNo, String transactionType,
double amount, User user){
Response response = new Response();
try {
SelfTerminal terminal = baseService.queryTerminalByNo(terminalNo);
if(terminal != null){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
card.setPat_birthday(sdf.parse(sdf.format(card.getPat_birthday())));
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
card.setCreateDate(sdf1.parse(card.getCreateTime()));
double balance = new BigDecimal(Double.toString(card.getBalance() + amount)).setScale(2,
BigDecimal.ROUND_HALF_UP).doubleValue();
card.setBalance(balance); //更新诊疗卡余额
Timestamp transactionDate = new Timestamp(new Date().getTime());
TransactionRecord record = new TransactionRecord(); record.setAmount(amount);
record.setCardNo(card.getCardNo()); record.setSelfTerminal(terminal);
record.setTransactionDate(transactionDate); record.setTransactionType(transactionType); record.setPatientId(card.getPat_id()); record.setUser(user);
//插入住院预交金明细记录表
PrePaymentRcpt rcpt = new PrePaymentRcpt(); rcpt.setAmount(new
BigDecimal(Double.toString(amount)).setScale(2,
BigDecimal.ROUND_HALF_UP));
rcpt.setOperator_no(user.getUserId()); rcpt.setPat_id(card.getPat_id());
if("转账存款".equals(transactionType)){ rcpt.setPay_way("转账存款");
}else {
rcpt.setPay_way("现金");
}
rcpt.setRefunded_rcpt_no(null);
rcpt.setTransact_date(transactionDate);
rcpt.setTransact_type("交款");
rcpt.setTransact_class("充值");
rcpt.setTerm_window_no(terminal.getWindowNo()); loger.info("诊疗卡: " + card.getCardNo() + "\t充值:
" + amount + "元");
baseService.recharge(card, record, rcpt); response.setResult("S");
response.setData(card);
}else {
response.setErrorInfo("该终端信息有误,请联系工作人员
核对终端信息");
response.setResult("F");
}
} catch (Exception e) {
loger.error("\n");
e.printStackTrace();
loger.error("============================充值失败
==========================");
loger.error(e,e);
System.out.println(e.getMessage());
response.setResult("F");
response.setErrorInfo("充值失败,请联系工作人员");
//response.setErrorInfo("充值失败,服务器异常,请重试
或联系工作人员");
//保存异常信息
ExceptionInfo info = new ExceptionInfo(); Timestamp exceptionDate = new Timestamp(new
Date().getTime());
info.setExceptionDate(exceptionDate); info.setDescription(e.getMessage()); info.setCardNo(card.getCardNo()); info.setTerminalNo(terminalNo); info.setAmount(amount);
info.setSummary("诊疗卡充值异常"); try {
baseService.saveException(info); } catch (Exception e1) {
e1.printStackTrace();
}
}
return response;
}
3.3挂号业务
3.3.1功能描述
用户在正确插入医疗卡的前提下,能够查询到医院能够挂号的科室门诊;选择要挂号的科室门诊之后,会自动查询出该科室能够挂号的具体专科信息;选择挂号的专科之后,系统会从数据库的挂号安排表中得出该专科的挂号情况(比如:时间、专家名称、已挂数量等等信息);当用户按照提示一步步操作并且确认进行挂号(其中系统会从用户的医疗卡中扣取挂号费)并且能够挂号成功,会显示出该用户挂号的信息,用户可以打印出挂号的凭条(具体格式待于讨论)。
3.3.2业务逻辑和数据库设计
(一)后台程序设计,从整体上会按照Action---Service---Dao的多层来架构,这样能分工明确,方便程序的可维护性以及可扩展性,严格遵守web程序设计的MVC原则。以下介绍在本模块中较为重要功能的实现方法或接口。
queryMainDept() 此服务方法会从数据库中检索到科室的信息,
并返回前台界面显示。科室比如用:外科门诊、内
科门诊等等,在此不一一列举。
queryRegisterInfo(String 参数就是用户要选择的科室的代码,比如外科dept_code) 门诊的代码为030115。此方法会从数据库中查询出
相应专科信息、医生信息、挂号安排信息。由于数
据库这些信息不都是全部在一张表中,所以要进行
多表查询的关联。
regDept(Map regMap) 参数是放在一个map类型中,里面大致包含用
户选择挂号的科室、挂号类别(普通号或者专家号
等)、挂号时间等。这个方法就实现挂号,中间会扣
取挂号费。由于此方法的数据库操作接口具体实现
是由院方提供oracle数据库的存储过程,所以目前
包括参数在内的一些具体细节还需跟院方详细的
讨论
(二)数据表的设计,本系统是采用双数据库。一个是院方HIS系统的oracle数据库,此数据库不会修改太多,如需修改也是在本项目组和院方相关技术人员经过详细讨论之后才会由院方技术人员实行HIS数据库的修改操作,在此就不进行过多的描述;另一个是本系统的专有数据库,是mysql数据库,而针对本功能模块,在mysql中会具体会用到的挂号的科室表registerdepartment。当然此模块中有较多相关的javabean类,但没有具体地映射到数据库中,在此也不多介绍。
字段名称 数据类型 是否为说明
空
Id Int 否 主键
Dept_code String 否 科室代码
Dept_name String 否 科室名称
Order Int 否 顺序,为扩展考虑,
方法在程序界面中自由
排序的显示
, 部分代码
/**
* 诊疗卡挂号,更新当前号和已挂号数,向就诊主表插入数据,从诊疗卡扣费,插入交易记录
*/
public Response registrationByCard(ClinicForRegist
clinicForRegist, MedicalCard card, String terminalNo,
User user){
Response response = new Response();
double amount = 0; //交易金额(挂号费用)
try {
SelfTerminal terminal =
baseService.queryTerminalByNo(terminalNo);
if(terminal != null){
String pat_id = card.getPat_id();
PatsInHospital pih =
baseService.queryPatsInHospital(pat_id);
boolean flag = false; //病人是否在院的标识 if(pih == null){
flag = true; //不在院
}else {
BigDecimal result =
baseService.queryInpBillDetail(pat_id);
if(result.compareTo(BigDecimal.ZERO) == 0){ flag = true; //不在院且已结算完成
}else {
flag = false; //不在院但未结算完成
}
}
//若病人为住院状态,门诊停用该诊疗卡
if(flag){
//查询病人所选号信息
ClinicForRegist regist =
baseService.queryClinicForRegist(clinicForRegist.getClinicDate(),
clinicForRegist.getTimeDesc(),
clinicForRegist.getClinicLabel());
if(regist != null){
//已挂号数
Integer registrationNum = regist.getRegistrationNum();
if(registrationNum == null){
registrationNum = 0;
}
//当前号
Integer current_no = regist.getCurrentNo();
if(current_no == null){
current_no = 1;
}
//限号数
int registrationLimits = 0;
//判断限号数是否为空或等于0,若为空或等于0,则不限号。若小于0,则该号已停诊。
if(regist.getRegistrationLimits() == null){
registrationLimits = 1000000;
}else {
if(regist.getRegistrationLimits() > 0){ registrationLimits =
regist.getRegistrationLimits();
}else if (regist.getRegistrationLimits() == 0) { registrationLimits = 1000000;
}else {
response.setResult("F");
response.setErrorInfo("该号已经停诊"); }
}
//开始挂号
if(registrationNum < registrationLimits){if(registrationNum == 0){
registrationNum = 1;
current_no = 2; //更新当前号
}else {
registrationNum += 1;
current_no += 1; //更新当前号
}
//更新当天已挂号数
regist.setRegistrationNum(registrationNum);
regist.setCurrentNo(current_no);
String patientId = card.getPat_id();
Patient patient = baseService.queryPatient(patientId);
//总挂号费(挂号费+诊疗费+其它费)
double price = 0;
//计算挂号费(ClinicPrice的查询结果可以为空,具体参照ChargeTypeDict和ClinicPrice两张表)
ClinicPrice clinicPrice = baseService.queryClinicPrice(patient.getChargeType());
String clinic_type = regist.getClinicLabel().getClinicType();//号类
String charge_type = patient.getChargeType();//费别
//计算诊疗费
List registPrices = baseService.queryRegistPrice(clinic_type,
charge_type);
if(registPrices != null && registPrices.size() > 0){
SpecialRegistPrice srp = registPrices.get(0);
if(clinicPrice != null){
price = srp.getPrice() + clinicPrice.getPrice();
}else {
price = srp.getPrice();
}
}else if(clinicPrice != null){
price = clinicPrice.getPrice();
}else {
price = 0;
}
amount = price;
//卡内余额
double balance = card.getBalance();
//更新卡内余额
card.setBalance(new
BigDecimal(Double.toString(balance - price)).
setScale(2,
BigDecimal.ROUND_HALF_UP).doubleValue());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
card.setPat_birthday(sdf.parse(sdf.format(card.getPat_birthday())));
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
card.setCreateDate(sdf1.parse(card.getCreateTime()));
//插入交易记录
Timestamp transactionDate = new Timestamp(new Date().getTime());
TransactionRecord record = new TransactionRecord();
record.setAmount(clinicForRegist.getRegistPrice().doubleValue());
record.setCardNo(card.getCardNo());
record.setTransactionDate(transactionDate);
record.setTransactionType("挂号");
record.setSelfTerminal(terminal);
record.setPatientId(card.getPat_id());
record.setUser(user);
//向就诊记录表插入数据
ClinicMaster clinicMaster = new ClinicMaster();
clinicMaster.setVisitDate(regist.getClinicDate());
clinicMaster.setClinicLabel(regist.getClinicLabel().getClinicLabel());
clinicMaster.setVisitTimeDesc(regist.getTimeDesc());
clinicMaster.setSerialNo(current_no - 1);
clinicMaster.setPatientId(patient.getPatientId()); clinicMaster.setName(patient.getName()); clinicMaster.setNamePhonetic(patient.getNamePhonet
ic());
clinicMaster.setSex(patient.getSex()); Calendar cal = Calendar.getInstance(); int yearNow = cal.get(Calendar.YEAR); int monthNow = cal.get(Calendar.MONTH); int dayNow = cal.get(Calendar.DAY_OF_MONTH); cal.setTime(patient.getBirthday()); int yearBirth = cal.get(Calendar.YEAR); int monthBirth = cal.get(Calendar.MONTH); int dayBirth = cal.get(Calendar.DAY_OF_MONTH); int age = yearNow - yearBirth;
if(monthNow <= monthBirth){
if(monthNow == monthBirth){
if(dayNow < dayBirth){
age--;
}
}else {
age--;
}
}
clinicMaster.setAge(age);
clinicMaster.setIdentity(patient.getIdentity());
clinicMaster.setChargeType(patient.getChargeType());
clinicMaster.setClinicType(regist.getClinicLabel().getClinicType());
clinicMaster.setVisitDept(regist.getClinicLabel().getDept());
clinicMaster.setDoctor(regist.getClinicLabel().getDoctorName());
clinicMaster.setMrProvideIndicator(0);
clinicMaster.setRegistrationStatus(1);
clinicMaster.setFirstVisitIndicator(1);
clinicMaster.setOtherFee(0);
clinicMaster.setRegisteringDate(new Timestamp(new Date().getTime()));
if(registPrices != null && registPrices.size() > 0){
clinicMaster.setRegistFee(registPrices.get(0).getPrice());
}else {
clinicMaster.setRegistFee(0.00);
}
if(clinicPrice.getPrice() != null
&& !"".equals(clinicPrice.getPrice())){ clinicMaster.setClinicFee(clinicPrice.getPrice()); }else {
clinicMaster.setClinicFee(0.00);
}
clinicMaster.setClinicCharge(price); clinicMaster.setPayWay("预交金");
clinicMaster.setOperator(user.getUserName()); //插入住院预交金明细记录表
PrePaymentRcpt rcpt = new PrePaymentRcpt(); rcpt.setAmount(new
BigDecimal(Double.toString(price)).setScale(2,
BigDecimal.ROUND_HALF_UP).negate());
rcpt.setOperator_no(user.getUserId()); rcpt.setPat_id(card.getPat_id());
rcpt.setPay_way("预交金");
rcpt.setRefunded_rcpt_no(null);
rcpt.setTransact_date(transactionDate); rcpt.setTransact_type("结算");
rcpt.setTransact_class("挂号");
rcpt.setTerm_window_no(terminal.getWindowNo());
baseService.registrationByCard(regist, card, record, clinicMaster, rcpt);
CardPKClinicMaster info = new CardPKClinicMaster();
info.setMedicalCard(card);
if(regist.getClinicLabel().getDoctorTitle() != null){
clinicMaster.setTitleName(regist.getClinicLabel().getDoctorTitle().getTitleName());
}else {
clinicMaster.setTitleName(null);
}
SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss");
String registerTime = sdf2.format(new Date()); //挂号时间,用于病人排队
clinicMaster.setRegisterTime(registerTime);
info.setClinicMaster(clinicMaster);
response.setResult("S");
response.setData(info);
}else {
response.setResult("F");
response.setErrorInfo("号已经挂完");
}
}else {
response.setErrorInfo("该号暂时停诊,暂无该号信息"); response.setResult("F");
}
}else {
response.setErrorInfo("住院期间,该卡暂不能在门诊挂号
");
response.setResult("F");
}
}else {
response.setErrorInfo("该终端信息有误,请联系工作人员
核对终端信息");
response.setResult("F");
}
} catch (Exception e) {
loger.error("\n");
e.printStackTrace();
loger.error("============================诊疗卡挂号
失败==========================");
loger.error(e,e);
System.out.println(e.getMessage()); response.setResult("F");
response.setErrorInfo("诊疗卡挂号失败,请联系工作人员
");
//response.setErrorInfo("诊疗卡挂号失败,服务器异常,
请重试或联系工作人员");
//保存异常信息
ExceptionInfo info = new ExceptionInfo(); Timestamp exceptionDate = new Timestamp(new
Date().getTime());
info.setExceptionDate(exceptionDate); info.setDescription(e.getMessage()); info.setCardNo(card.getCardNo()); info.setTerminalNo(terminalNo);
info.setAmount(amount);
info.setSummary("诊疗卡挂号异常"); try {
baseService.saveException(info);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return response;
}
3.4缴费业务
功能描述:插卡后,系统会识别磁卡所有人是否有尚未缴费的信息存在。如果存在,将会显示近一个月的缴费信息,用户可以直接在终端机上缴费。如果没有,将不会显示信息。
, 部分代码
/**
* 自费缴费模块(按每张单子结算,金额为合计金额)
*/
public Response payment(MedicalCard card, PrescriptionInfo[] infos, String terminalNo, User user){
Response response = new Response();
try {
SelfTerminal terminal = baseService.queryTerminalByNo(terminalNo);
if(terminal != null){
String pat_id = card.getPat_id();
PatsInHospital pih = baseService.queryPatsInHospital(pat_id);
boolean flag = false; //病人是否在院的标识
if(pih == null){
flag = true; //不在院
}else {
BigDecimal result = baseService.queryInpBillDetail(pat_id);
if(result.compareTo(BigDecimal.ZERO) == 0){
flag = true; //不在院且已结算完成
}else {
flag = false; //不在院但未结算完成
}
}
//若病人为住院状态,门诊停用该诊疗卡
if(flag){
//获取病人ID,查询病人信息
MedicalCard medicalCard = baseService.queryMedicalCard(card.getCardNo());
String patientId = medicalCard.getPat_id();
Patient patient = baseService.queryPatient(patientId); //查询病人信息
if(!patient.getChargeType().equals("自费")){
response.setResult("F");
response.setErrorInfo("暂不支持医保用户缴费,如需缴费,请去收费窗口办理");
}else {
medicalCard = baseService.payment(medicalCard, patient, infos, terminalNo, user, terminal);
PaymentsList payments = new PaymentsList();
payments.setCard(medicalCard);
payments.setInfos(infos);
response.setData(payments);
response.setResult("S");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
int i = 1;
loger.info("\n");
loger.info("--------------------开始缴费------------------------");
for(PrescriptionInfo logPrescription : infos){
loger.info("\t" + sdf.format(new Date()) +" 第" + i +"张缴费单子信息:");
loger.info("病人ID:" + logPrescription.getPatientId() + "\t就诊日期:" + logPrescription.getVisitDate() +
"\t单号:" + logPrescription.getRcptNo() + "\t就诊序号:" + logPrescription.getVisitNo() +
"\t开单科室:" + logPrescription.getOrderedBy().getDeptName() + "\t开单医生:" + logPrescription.getDoctor() +
"\t应收总价:" + logPrescription.getTotalCosts() + "\t实收总价:" + logPrescription.getTotalCharges());
OrdersCosts[] details = logPrescription.getDetails();
loger.info("\t" + sdf.format(new Date()) + " 第" + i +"张缴费单子明细:");
for(OrdersCosts detail : details){
loger.info("病人ID:"+ detail.getPatientId() + "\t就诊日期:" + detail.getVisitDate() +
"\t收据号:" + logPrescription.getRcptNo() +"\t就诊序号:" + detail.getVisitNo() + "\t就诊序列号:" + detail.getSerialNo() +
"\t项目序号:" + detail.getItemNo() + "\t诊疗项目分类编码:" + detail.getItemClass().getClassName() +
"\t项目名称:" + detail.getItemName() + "\t项目代码:" + detail.getItemCode() +
"\t规格:" + detail.getItemSpec() + " \t单位:" + detail.getUnits() + " \t付:" + detail.getRepetition() +
"\t数量:" + detail.getAmount() + "\t开单科室:" +
detail.getDeptCode().getDeptName() +
"\t开单医生:" + detail.getByDoctor() + "\t单价:" + detail.getPrice() +
"\t应收:" + detail.getCosts() + "\t实收:" + detail.getCharges());
}
loger.info("\n");
loger.info("\n");
i++;
}
}
}else {
response.setErrorInfo("住院期间,该卡暂不能在门诊缴费");
response.setResult("F");
}
}else {
response.setErrorInfo("该终端信息有误,请联系工作人员核对终端信息");
response.setResult("F");
}
} catch (Exception e) {
loger.error("\n");
e.printStackTrace();
loger.error("============================缴费失败
========================");
loger.error(e,e);
System.out.println(e.getMessage());
response.setResult("F");
response.setErrorInfo("缴费失败,请联系工作人员"); //response.setErrorInfo("缴费失败,服务器异常,请重试
或联系工作人员");
loger.error(e);
//保存异常信息
ExceptionInfo info = new ExceptionInfo(); Timestamp exceptionDate = new Timestamp(new
Date().getTime());
info.setExceptionDate(exceptionDate);
info.setDescription(e.getMessage());
info.setCardNo(card.getCardNo());
info.setTerminalNo(terminalNo);
double amount = 0; //缴费金额
for(PrescriptionInfo info2 : infos){
amount += info2.getTotalCharges();
}
info.setAmount(amount);
info.setSummary("缴费异常");
try {
baseService.saveException(info);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return response;
}
3.5 终端管理模块
可以查询终端运行情况,交易量等信息。
, 部分代码
public Response queryTerminal(Map
terminalMap, int firstResult, int maxResults){ Response response = new Response(); response.setOperType("queryTerminal"); try {
DetachedCriteria detachedCriteria =
DetachedCriteria.forClass(SelfTerminal.class); if(terminalMap.get("terminalNo") != null)
detachedCriteria.add(Restrictions.like("terminalNo", "%" + terminalMap.get("terminalNo") + "%"));
if(terminalMap.get("terminalType") != null)
detachedCriteria.add(Restrictions.eq("terminalType", terminalMap.get("terminalType")));
if(terminalMap.get("isOnline") != null)
detachedCriteria.add(Restrictions.eq("isOnline", terminalMap.get("isOnline")));
if(terminalMap.get("status") != null)
detachedCriteria.add(Restrictions.eq("status", terminalMap.get("status")));
detachedCriteria.addOrder(Order.desc("createDate"));
detachedCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List list =
baseDao.find(detachedCriteria, firstResult, maxResults);
if(list.size() > 0){
List terminals = new
ArrayList();
for(SelfTerminal selfTerminal : list){
SelfTerminal terminal = selfTerminal; if(terminalMap.get("terminalNo") != null){ if(terminalMap.get("terminalNo").equals(terminal.g
etTerminalNo())){
terminals.add(terminal);
list.remove(terminal);
for(SelfTerminal selfTerminal2 : list){ terminals.add(selfTerminal2);
}
response.setArrayData(terminals); response.setResult("S");
break;
}else {
response.setArrayData(list);
response.setResult("S");
}
}else {
response.setArrayData(list);
response.setResult("S");
}
}
}else{
response.setResult("F");
response.setErrorInfo("没有查询到符合条件的结果");
}
} catch (Exception e) {
e.printStackTrace();
logger.error("========================TMS查询终端失
败==========================");
logger.error(e,e);
System.out.println(e.getMessage()); response.setResult("F");
response.setErrorInfo("查询终端信息操作失败,服务器异
常,请重试或联系管理员");
ExceptionInfo info = new ExceptionInfo(); Timestamp exceptionDate = new Timestamp(new
Date().getTime());
info.setExceptionDate(exceptionDate); info.setDescription(e.getMessage()); info.setSummary("TMS查询终端异常");
try {
baseDao.save(info);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return response;
}
}
3.6 日志管理模块
, 部分代码
public Response queryOperateLog(Map
logMap,
int firstResult, int maxResults) { Response response = new Response(); response.setOperType("queryOperateLog"); SimpleDateFormat sdf = new
SimpleDateFormat("yyyy-MM-dd");
DetachedCriteria detachedCriteria =
DetachedCriteria
.forClass(OperateLog.class);
try {
Date startDate = null;
Date endDate = null;
if (logMap.get("startDate") != null)
startDate = sdf.parse(logMap.get("startDate").toString());
if (logMap.get("endDate") != null) {
endDate = sdf.parse(logMap.get("endDate").toString());
Calendar c = Calendar.getInstance();
c.setTime(endDate);
c.add(Calendar.DATE, 1);
endDate = c.getTime();
}
if (startDate != null)
detachedCriteria.add(Restrictions.ge("operateTime", startDate));
if (endDate != null)
detachedCriteria.add(Restrictions.le("operateTime", endDate));
if (logMap.get("operator") != null)
detachedCriteria.createAlias("operator", "o").add(
Restrictions.like("o.loginName",
"%" + logMap.get("operator") + "%"));
detachedCriteria.addOrder(Order.desc("operateTime"));
detachedCriteria
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTIT
Y);
List logList = baseDao.find(detachedCriteria,
firstResult, maxResults);
if (null != logList && logList.size() > 0) {
response.setArrayData(logList);
response.setResult("S");
} else {
response.setErrorInfo("没有查询到符合条件的结果");
response.setResult("F");
}
} catch (Exception e) {
e.printStackTrace();
logger.error("========================TMS查询操作日志失败==========================");
logger.error(e, e);
System.out.println(e.getMessage());
response.setErrorInfo("查询操作记录失败,服务器异常,请重试或联系管理员");
response.setResult("F");
ExceptionInfo info = new ExceptionInfo(); Timestamp exceptionDate = new Timestamp(new
Date().getTime());
info.setExceptionDate(exceptionDate);
info.setDescription(e.getMessage());
info.setSummary("TMS查询操作日志异常");
try {
baseDao.save(info);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return response;
}
public Response queryTransactionLog(Map logMap,
int firstResult, int maxResults) {
Response response = new Response();
response.setOperType("queryTransactionLog"); SimpleDateFormat sdf = new
SimpleDateFormat("yyyy-MM-dd");
DetachedCriteria detachedCriteria =
DetachedCriteria
.forClass(TransactionLog.class);
try {
Date startDate = null;
Date endDate = null;
if (logMap.get("startDate") != null)
startDate = sdf.parse(logMap.get("startDate").toString());
if (logMap.get("endDate") != null) {
endDate = sdf.parse(logMap.get("endDate").toString());
Calendar c = Calendar.getInstance();
c.setTime(endDate);
c.add(Calendar.DATE, 1);
endDate = c.getTime();
}
if (startDate != null)
detachedCriteria.add(Restrictions.ge("transactionD
ate",
startDate));
if (endDate != null)
detachedCriteria.add(Restrictions
.le("transactionDate", endDate));
if (logMap.get("transactionType") != null && !"".equals(logMap.get("transactionType"))) detachedCriteria.add(Restrictions.eq("transactionT
ype",
logMap.get("transactionType")));
if (logMap.get("medicalCardNo") != null && !"".equals(logMap.get("medicalCardNo"))) detachedCriteria.add(Restrictions.like("cardNo", "%" + logMap.get("medicalCardNo") + "%")); if (logMap.get("terminalNo") != null
&& !"".equals(logMap.get("terminalNo"))) detachedCriteria.createAlias("selfTerminal",
"st").add(
Restrictions.like("st.terminalNo",
"%" + logMap.get("terminalNo") + "%")); if (logMap.get("operator") != null
&& !"".equals(logMap.get("operator")))
detachedCriteria.createAlias("operator", "o").add( Restrictions.like("o.loginName",
"%" + logMap.get("operator") + "%"));
detachedCriteria.addOrder(Order.desc("transactionD
ate"));
detachedCriteria
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTIT
Y);
List logList = baseDao.find(detachedCriteria,
firstResult, maxResults);
if (null != logList && logList.size() > 0) {
response.setArrayData(logList);
response.setResult("S");
} else {
response.setErrorInfo("没有查询到符合条件的结果");
response.setResult("F");
}
} catch (Exception e) {
e.printStackTrace();
logger.error("========================TMS查询交易日志失败==========================");
logger.error(e, e);
System.out.println(e.getMessage());
response.setErrorInfo("查询交易日志操作失败,服务器异常,请重试或联系管理员");
response.setResult("F");
ExceptionInfo info = new ExceptionInfo(); Timestamp exceptionDate = new Timestamp(new
Date().getTime());
info.setExceptionDate(exceptionDate); info.setDescription(e.getMessage()); info.setCardNo(logMap.get("medicalCardNo").toStrin
g());
info.setTerminalNo(logMap.get("terminalNo").toStri
ng());
info.setSummary("TMS查询交易日志异常"); try {
baseDao.save(info);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return response;
}
3.7 充值管理模块
, 部分代码
public Response countTransaction(Map tranMap) {
Response response = new Response();
response.setOperType("countTransaction");
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
DecimalFormat df = new DecimalFormat("0.00");
DetachedCriteria detachedCriteria = DetachedCriteria
.forClass(TransactionLog.class);
if (tranMap != null && tranMap.size() > 0) {
Date startDate = null;
Date endDate = null;
if (tranMap.get("startDate") != null) {
startDate = sdf.parse(tranMap.get("startDate").toString());
}
if (tranMap.get("endDate") != null) {
endDate = sdf.parse(tranMap.get("endDate").toString());
Calendar c = Calendar.getInstance();
c.setTime(endDate);
c.add(Calendar.DATE, 1);
endDate = c.getTime();
}
if (startDate != null) {
detachedCriteria.add(Restrictions.ge("transactionD
ate",
startDate));
}
if (endDate != null) {
detachedCriteria.add(Restrictions.le("transactionD
ate",
endDate));
}
detachedCriteria.add(Restrictions.eq("transactionT
ype",
tranMap.get("transactionType")));
if (tranMap.get("terminalNo") != null
&& !"".equals(tranMap.get("terminalNo"))) {
detachedCriteria.createAlias("selfTerminal", "st").add(
Restrictions.like("st.terminalNo",
"%" + tranMap.get("terminalNo") + "%")); }
if (tranMap.get("operator") != null
&& !"".equals(tranMap.get("operator"))) { detachedCriteria.createAlias("operator", "o").add( Restrictions.like("o.loginName",
"%" + tranMap.get("operator") + "%")); }
detachedCriteria
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTIT
Y);
List tranList =
baseDao.find(detachedCriteria);
if (null != tranList && tranList.size() > 0) { double money = 0;
for (int i = 0; i < tranList.size(); i++) { money += tranList.get(i).getAmount(); }
response.setData(df.format(money));
response.setResult("S");
} else {
response.setData(0);
response.setResult("S");
}
} else {
response.setResult("F");
response.setErrorInfo("统计交易额操作失败,请重新选择交易类型");
}
} catch (Exception e) {
e.printStackTrace();
logger.error("========================TMS统计交易额失败==========================");
logger.error(e, e);
System.out.println(e.getMessage());
response.setResult("F");
response.setErrorInfo("统计交易额操作失败,服务器异常,请重试或联系管理员");
ExceptionInfo info = new ExceptionInfo();
Timestamp exceptionDate = new Timestamp(new Date().getTime());
info.setExceptionDate(exceptionDate);
info.setDescription(e.getMessage());
info.setSummary("TMS统计交易额异常");
try {
baseDao.save(info);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return response;
}
3.8 终端设置模块
, 部分代码
public Response addTerminal(Map
terminalMap, Map operatorMap){ Response response = new Response();
response.setOperType("addTerminal");
try {
SelfTerminal terminal =
BeanUtil.mapToBean(SelfTerminal.class, terminalMap); terminal.setCreateDate(new Date());
baseDao.save(terminal);
operatorMap.remove("role");
User operator = BeanUtil.mapToBean(User.class,
operatorMap);
OperateLog log = new OperateLog();
log.setOperator(operator);
log.setOperateTime(new Date());
StringBuilder builder = new StringBuilder();
builder.append("添加终端:终端号-");
builder.append(terminal.getTerminalNo());
log.setOperateDesc(builder.toString());
baseDao.save(log);
response.setResult("S");
} catch (Exception e) {
e.printStackTrace();
logger.error("========================TMS添加终端失败==========================");
logger.error(e,e);
System.out.println(e.getMessage());
response.setResult("F");
response.setErrorInfo("添加终端操作失败,服务器异常,请重试或联系管理员");
ExceptionInfo info = new ExceptionInfo();
Timestamp exceptionDate = new Timestamp(new Date().getTime());
info.setExceptionDate(exceptionDate); info.setDescription(e.getMessage()); info.setSummary("TMS添加终端异常"); try {
baseDao.save(info);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return response;
}