医药采购项目问题汇总

1 请描述一下这个系统?
系统概述:
系统背景、系统概述。
本系统是一个市级的医药采购系统,由市卫生局指导 开发的,通过本系统实现医院上网采购药品,供货商上网销售/供应药品,监管单位网上监管,达到目标:药品交易的自动化、网络化、透明化。

系统包括模块:
本系统包括:药品目录模块、采购单模块、退货单模块、结算单模块、统计分析模块、系统管理。

系统业务流程:(如果面试不问不用直接说业务流程)
核心业务流程是医院采购流程:
第一步:医院创建采购单
填写采购单基本信息
填写采购药品明细信息
提交 采购单
第二步:监管单位审核采购单
监管单位查看采购单详细信息
如果有问题给出审核意见,审核不通过
如果正常,就审核通过
第三步:采购单审核通过后由供货商进行供货
手动在页面选择要发货的药品执行发货
线下整理一个发货的清单,导入系统执行批量发货
第四步:医院接收到药品进行入库
医院接收到药品后,填写入库信息,执行入 库操作,表示医院收到药品了。

扩展问题:
你做了哪些模块?

2 说说系统的架构?

本系统架构采用maven构建。
如何构建:
将系统分成4个子工程。
 技术架构模块:springmybtais
包括:spirng3.1.4(包括springmvc)、mybaits3.2.3及依赖的jar包。

 工具类模块(yycgutil)
包括系统所用到所有工具类。
 主工程模块
包括系统基础模块(base)、系统业务模块(business)

 聚合模块(父工程模块)
对各各子模块进行聚合

扩展问题:
为什么要聚合?
由maven自动识别各各子模块之间的依赖关系,最终打成一个war包,将war包考到到集成测试环境中。方便系统集成测试。

在公司是如何使用maven仓库的?
在公司局域网中单独有一台服务器,作为maven私服(里边有从互联网上下载的jar包,还有自己上传的jar)。

对于互联网上下载不到的jar,要将本地的jar导入到仓库中。参考:向maven本地仓库导入jar包.docx

3 本系统如何用maven开发?

 技术架构模块:springmybtais
包括:spirng3.1.4(包括springmvc)、mybaits3.2.3及依赖的jar包。

 主工程模块
系统基础模块(base):包括系统管理相关的功能,用户管理、数据字典配置、系统参数配置等。。
系统业务模块(business):包括药品目录 模块、采购单模块、统计分析等
 工具类模块(yycgutil)
包括系统所用到所有工具类。

 聚合模块(父工程模块)
对各各子模块进行聚合

仓库:
在公司局域网中单独有一台服务器,作为maven私服(里边有从互联网上下载的jar包,还有自己上传的jar)。

使用开发工具:
Maven3.2.1版本
Eclipse-kepler(自带maven插件)

4 这个系统异常处理是怎么做的?(重点)
包括:
异常信息定义:
通常做法:对每一个异常信息单独创建一个类,继承Exception,定义异常类比较多,繁琐。
本系统就定义一个自定义异常类ExceptionResultInfo,继承Exception,ExceptionResultInfo中有一个resultInfo属性,resultInfo中定义异常信息、异常代码,这样此类就可以存储任何异常信息。

异常信息配置文件:
在messages.properties文件定义了所有异常信息,以异常代码=异常信息方式进行定义,使用国际化的工具类读取该配置文件的内容,将读取到内容使用resultInfo类存储。

异常处理:
系统定义一个全局异常处理器,统一解析处理action所抛出的异常。
统一异常处理器采用springmvc框架提供的机制进行异常处理,springmvc的前端 控制器在调用Action时,所发生的异常全局交给异常处理器进行异常处理。

异常处理流程(掌握):
医药采购项目问题汇总_第1张图片

5 本系统实现国际化了吗?是怎么做?

本系统没有实现国际化,但是本系统使用国际化资源文件将系统所有提示信息配置起来,使用国际化的方法读取配置信息。

Java操作国际化方法:

Java国际化主要通过如下3个类完成
java.util.ResourceBundle:用于加载一个资源(配置文件)
java.util.Locale:对应一个特定的国家/区域、语言环境。
java.text.MessageFormat:用于将消息格式化

在messages.properties文件定义了所有异常信息,以异常代码=异常信息方式进行定义,使用国际化的工具类读取该配置文件的内容,将读取到内容使用resultInfo类存储。

6 这个系统mybatis是怎么用的?或这个系统持久层如何实现的?
本系统使用mybatis提供的动态代理方法开发mapper。

针对单表的增、删、改、查、使用mybatis提供的逆向工程生成mapper文件,不用程序员针对单表写sql及mapper文件,提高了开发效率。

针对多表的查询,需要自定义mapper。

扩展问题:
mybatis提供的动态代理方法是怎么用的?

开发mapper地遵循一些规则:
Mapper接口地址和mapper.xml映射文件中namespace致。
Mapper接口的名称和mapper.xml映射文件中的statement的id一致。
Mapper接口的输入参数类型和mapper.xml映射文件中的statement的parametertype一致
Mapper接口的输出结果类型和mapper.xml映射文件中的statement的resulttype一致

生成mapper代理对象?
使用mybatis和spring的整合包中的mapper扫描器生成 mapper代理对象,生成的mapper代理对象自动注册到spring容器。

7 这个系统springmvc是怎么用的?
使用springmvc注解开发。

针对需要返回页面,统一action方法返回string(逻辑视图名)。

针对提交的操作,统一返回json结果,使用@responseBody注解将系统统一的结果类型submitResultInfo转为json在客户端输出。
提交类的操作,统一采用ajax+json方式。

针对查询列表,统一返回json结果,因为查询列表在页面使用jquery easyui的datagrid展示,使用@responseBody注解将系统统一的结果类型DatagridResultInfo 转为json在客户端输出datagrid.

8 本系统ajax+json具体是怎么做的?action的方法返回的json是如何实现的?
Ajax+json:

请求内容:
普通表单数据key/value(注意:请求的不是json)
采用jquery提供的ajax的form请求组件,进行提交。提交 的是普通表单数据key/value
参考代码:
医药采购项目问题汇总_第2张图片

响应内容:
在action使用@responseBody响应json数据。

9 这个系统都用到jquery easy ui的哪些组件?
页面布局: layout
菜单 :accordion
窗口标签:tabs
数据列表:datagrid
弹出窗口:window
提示消息。。。。。。。。

10 这个系统的用户认证是怎么实现的?
使用用户名和密码方式进行认证。

用户认证流程:

11 本系统用户授权是怎么实现的?
用户授权(用户权限分配):
用户角色、系统模块(一级菜单和二级菜单 )、系统操作(点击菜单 进入页面中所有的url链接)、角色操作表。。

给用户授权范围:
将用户可操作的菜单页面中所有的链接都 给用户授权,用户点击菜单 进入页面,可以操作页面中每个链接。
如果不给用户授权该菜单 ,该菜单 页面上的所有地址,用户无法访问!!!

采用url拦截方式进行权限拦截。
用户请求url(action地址),通过拦截器校验用户是否有权限。如果没有权限提示“无权操作。”

参考用户认证拦截流程:
权限拦截:
使用过虑器、 springmvc的拦截器械
医药采购项目问题汇总_第3张图片

公共权限:每个用户都有的操作权限,这时不用给每一个用户授权此类权限。只需要在单独的配置文件中将公共权限配置起来,在拦截器获取到,如果用户请求的是公共权限就放行。
比如:管理信息系统的首页,用户中心页面。

和上边的用户认证拦截器,组成一个链接的链:
医药采购项目问题汇总_第4张图片

通过用户授权达到目标:
没有权限的菜单在用户登陆后不显示
如果用户直接输入菜单 地址提示“无权限操作”

补充知识:
有些系统可能需要针对用户授权,对每个用户进行授权。
实现方法:
可以采用角色和用户关系 ,给每个用户定义一个角色,还是针对角色授权。
不需要定义角色,创建一张表用户权限表,由业务用户操作而不是系统管理员。

12 系统使用数据字典了吗?怎么用的?

数据字典:将具体相同类型的配置项统一在数据字典表中进行配置,如果要修改配置项只需要修改数据字典而不需要代码,增强代码可维护性。

配置项:分成两种,
一是业务代码,业务代码系统中固定的代码,不受用户需求控制的。比如:用户状态(正常、暂停)、药品交易状态(正常、暂停)、用户类型(1,2,3,4,0),业务代码可能要在系统中硬编码。

二是普通配置项,普通配置项变化灵活,受用户需求控制,比如药品类型、医院级别。

数据字典表:
分为两张表,一张表是数据字典类型表,dicttype,一张表是数据字典明细表,dictinfo(外键typecode)
业务代码、普通配置项,类型都需要在dicttype配置,且配置方法一样。
业务代码、普通配置项,明细在dictinfo配置,方法不一样。

业务代码在dictinfo数据字典明细表配置,将业务代码写到dictinfo表中的dictcode字段,如果查询一个业务代码对应的名称?根据typecode+dictcode查询dictinfo表,只能查询出一条记录。

普通配置项在dictinfo数据字典明细表配置,不需要在dictcode字段配置内容,因为普通配置项没有业务代码。只需要在info字段配置项目名称即可。
如果关联查询出普通配置项的名称?
在业务表(范范的概念,业务功能相关表统称为业务表)中将普通配置项的id(dictinfo的主键)存放在业务表字段中,根据id(dictinfo的主键)关联查询dictinfo 表的记录。

上边业务代码、普通配置项,如果查询该类型下的项目,查询方式是一致的,根据typecode查询dictinfo表的记录。
比如查询用户类型下的项目,select id,info,dictcode from dictinfo where typecode=’s01’

13 系统中有导入、导出功能吗?怎么实现的?

系统有导入导出功能,对药品目录实现导入和导出,还有一些用户常用的查询实现了导出,还有每一个统计分析实现导出。

药品目录导入:使用Apache POI组件完成导入,采用HSSF事件驱动模式进行excel文件导入。系统中对HSSF事件驱动模式进行封装。
封装的思路:封装类包括一个抽象类,工具类(继承抽象类)、数据导入接口。
抽象类是一个底层类不是面向用户的,完成了对excel数据的解析,解析完一条记录调用一个抽象方法,此抽象方法在工具类中有具体的实现.
工具类是面向用户的,工具对抽象方法具体实现,内容是调用数据导入接口执行导入操作,统计导入的结果(导入成功数量、失败数量、导入失败原因、导入失败的记录)。
具体使用时需要根据业务需求开发不同的数据导入接口,将此接口注入工具类中,程序员只要调用工具的导入方法即可完成数据的导入。
药品目录导入开发,就是使用此封装类,开发了一个药品目录的导入接口。

药品目录导出:使用apache POI组件完成导出,采用XSSF完成数据导出,XSSF可以完成大数据导出,XSSF实现一边向内存创建对象,一边向磁盘写临时文件,一边对内存对象进行清理,最终对生成临时文件进行合并输出最终导出文件。
本系统对XSSF完成大数据导出封装使用,封装类原理:使用时需要定义导出数据列表的title,还要定义导出数据列表每一列对应的pojo的属性,从数据查询出要导出的数据List,封装通过java反射自动取出pojo中的属性值,使用XSSF向内存创建对象,完成数据导出。

14 系统中都包括哪些系统配置方式?

系统配置包括哪些?
对于系统运行参数配置在系统参数配置表(basicinfo)
维护方式:由管理员登陆系统后台进行维护。

将具体相同的类型的配置项配置在数据字典表。
维护方式:
由管理员登陆系统后台维护所有配置项(业务代码、普通配置项)主要维护的是业务代码。
建议将普通配置项的维护权限交给业务用户进行维护。

系统配置文件:
1、 对系统所有提示信息(成功、异常)统一配置在message.properties文件中。
2、 对数据的连接参数配置在db.properties中
3、 日志参数配置在log4j.properties(配置日志策略,主要是日志级别、日志文件路径、日志分割策略)
4、 系统公开访问地址(无需要登录即可访问)配置在anonymousActions.properties
5、 系统公共访问地址(需要登录,但无需要授权)配置在commonActions.properties

15 请描述药品目录模块?

模块功能描述,本模块包括哪些功能:

药品目录维护,卫生局通过批量导入将市平台所用的药品目录信息导入系统,对药品信息进行修改、删除操作。
供货商药品目录维护,供货商对自己供应的药品进行维护,供货商向供货商药品目录添加要供应的药品,删除不再供应的药品。
供货商药品目录控制,监督单位对供货商的药品目录进行控制,允许供货商供货或暂停供货商供货。

业务流程:
1、 卫生局建立本系统的药品总目录。
2、 供货商从系统药品总目录挑选药品加入自己的供货商药品目录表示供货商要供应药品。
3、 供货商将药品从自己的供货商药品目录删除表示不再供应删除的药品。
4、 监督单位查询供货商供应的药品信息,对其的供货状态进行控制,允许供货商供货或暂停供货商供货。

16 请描述采购单模块?

功能描述:提供医院管理采购单、监督单位审核采购单、供货商受理采购单、药品入库等部分功能。

业务流程:
1、 医院创建采购单
填写采购单基本信息(采购单的基本信息,下单人的联系方式,采购单编号,下单日期等)
维护采购药品明细信息(指定采购单采购哪些药品)
2、 医院提交采购单
3、 监督单位审核采购单
4、 供货商受理采购单
5、 医院执行入库操作

17 你在开发中有没有遇到什么问题,是如何解决的?分表存储怎么做的?

系统中对采购单信息进行分表存储。
为什么进行分表存储?因为对于一个省会城市每一年的采购单信息达到千万级,时间长了对采购单信息查询、统计速度就会降低,单纯从数据库级别进行优化治标不治本,彻底的解决办法对数据进行分表存储。

如何进行分表存储?
采购单包括两张表采购单基本信息表和采购药品明细表,其中采购药品明细表数量很大,如果单纯对采购药品明细表进行分表,开发中对采购单业务处理思路不统一,所以要对采购单两张表及表相关的对象全部进行分表,
采用按年分表,表名命名规则:
Yycgd+4位年份
Yycgdmx+4位年份
….等表相关对象也采用固定名称+4位年份。

分表操作方法:
采用系统定时任务定时执行存储过程进行动态表创建。定时任务采用是操作系统的定时任务,因为操作系统的定时任务稳定且和软件是分开的,操作系统定时任务不仅仅是动态分表,还有系统备份、临时文件清理。。
存储过程里边就是动态分表的逻辑,对采购单、统计分析、退货单数据库对象进行创建。

18 动态表如何创建?

通过定时任务调用存储过程,存储过程创建动态表及相关的数据库对象。
定时任务:采用操作系统的定时任务,通常java程序在linux运行,需要在/etc/crontab配置定时任务。

Win 中要在系统与安全中新建计划任务选择程序然后引入脚本
创建方法:
编写shell脚本,内容是连接数据库,调用存储过程。

sqlplus yycg/yycg@yycg_127.0.0.1 @c:\test.sql

sql文件的内容:

call create_tableJob();---调用存储过程
create or replace procedure create_tableJob Authid Current_User as year1 varchar2(4);
   year2 varchar2(4);
begin --一次性创建两年的表 --获得当前年份 select to_char(sysdate,'yyyy')into year1 from dual;

  --获得下年年份
  select to_char(to_char(sysdate,'yyyy')+1)into year2 from dual;

  --创建今年的表
  create_businesstable(year1);
  --创建明年的表
  create_businesstable(year2);

end create_tableJob;


create_businesstable:在该存储过程中创建各各动态表及相关的对象(索引、触 发器。。。)。

create or replace procedure create_businesstable(year in varchar2) Authid Current_User as begin create_businesscgd(year);--创建采购单主表
      create_business(year);--创建交易明细表
      create_businesscgdmx(year);--创建采购单明细表
      create_businesscgdrk(year);--创建采购单入库表
      create_businessthd(year);--创建退货单表
      create_businessthdmx(year);--创建退货单明细表
      create_businessjsd(year);--创建结算单表
      create_businessjsdmx(year);--创建结算单明细表

end create_businesstable;

创建表及相关对象方法:
将创建表及相关对象的sql,在存储过程中使用字符串拼接起来,通过execute immediate执行这个sql,完成创建!!!

执行或调试存储过程:
Call调用存储过程。

可以通过pl/sql工具调试存储过程,方便,可以加断点,可以跟踪变量的值 。。

19 供货商如何进行采购单受理?或说说供货商受理采购单的流程?
供货商受理采购单功能描述:
医院创建有采购单由监督单位审核通过后,由供货商进行受理,供货商根据医院采购药品数量等信息进行发货操作。

选择确认发货:
针对发货量少的药品可以采用选择确认发货方式,供货商登录系统查询待受理的发货清单,选择要发货的药品进行确认发货。

批量发货:
针对发货量大的药品,供货商将要发货的药品整理成excel文件,通过系统提供的导入发货清单,清单中存在药品明细系统自动执行发货操作。

20 说说药品入库流程?

药品入库功能描述:
医院采购药品,供货商对采购的药品发后后,医院就可以执行入库操作,药品入库后表示医院收到所采购的药品了。

操作流程:
医院登录系统查询待入库的药品明细信息
选择要入库药品,填写入库信息(入库量、发票号、药品批号 。。)
确认入库提交

21 说说退货和结算流程?

退货流程:
1、 医院创建退货单
填写退货单的基本信息
向退货单中加入要退货的药品,所加入的退货的药品是以前采购的药品
2、 提交退货单
3、 供货商受理退货单

结算流程:
1、 医院创建结算单
填写结算单的基本信息
向结算单中加入要结算的药品,所加入的结算的药品是以前的采购的药品
2、 提交结算单
3、 供货商受理结算

22 系统中有打印功能吗?怎么实现的?

系统中有打印功能。
导出的列表要打印,怎么实现?
采购单信息打印,怎么实现?

b/s系统下打印功能实现方式:
1、 使用浏览器的打印功能

用户在浏览器中浏览的网页,通过浏览器提供的打印功能,点击“打印”菜单即可将当前网页打印。
浏览器打印出效果就是页面浏览的效果,通常使用使用浏览器打印,需要单独作一个打印的页面,这个打印的页面将超级链接、按钮等不需要打印的内容全部去掉,打印页面中只留下需要打印出来的东西。

浏览器打印出来内容默认在打印页面最下边显示当前url地址,通过设置浏览器打印选项可以去掉这个url。

总结:使用浏览器打印非常方便。

2、 间接打印

比如:需要打印供货商的药品目录,要求用户将列表导出成excel,由用户自行打印。

3、 套打

什么套打:所打印出来效果(布局),是提前印刷好的打印模版,打印模版中是没有数据的,需要有数据的地方空白了,系统按照设计模版要求将所需要数据及数据位置对应模版打印出来。

比如;

医药采购项目问题汇总_第5张图片
进行套打:
1、 连接打印驱动程序
需要在浏览器上安装打印插件(.exe文件)
2、 使用js访问打印插件的方法,执行打印
使用js方法访问打印插件,通常将上边的数据和数据位置的规则定义在一个js文件中,数据及数据位置通过js变量(数组,json)记录。

网上提供了免费的b/s系统打印插件。
比较好用的lodop???

23 你在开发中有没有遇到什么问题?或统计分析是如何设计开发?

系统统计分析功能,有交易明细查询,有按药品、按医院等分类统计功能,有按药品、按医院等分类统计是在交易明细查询基础上进行分类统计,问题是交易明细查询需要三张大数据量的表关联查询,为了提高查询及统计的性能,单独创建了一个交易明细表。

将采购药品信息、入库信息、退货信息、结算信息都聚合到交易明细表。
交易明细查询、分类统计都是从一个表(单表)进行统计查询。提交查询统计的性能。

24 你是如何和测试人员配合工作的?

系统的测试过程:

开发人员将系统开发完成,首先进行系统集成测试。
集成测试完成开发人员提供两个文档:“系统集成测试报告”“系统部署配置说明”

将系统提交给测试 人员
测试人员从svn上下载系统所有代码及系统相关文档
测试人员根据“系统集成测试报告”“系统部署配置说明”进行系统集成测试。

测试 人员集成测试通过,测试进行详细系统功能测试。

开发人员在测试人员进行详细功能测试时,需要长时间的(和开发时间相等甚至多于开发时间)进行缺陷修改。

缺陷修改过程:
测试人员进行功能测试
测试出来bug提交到专门 的项目管理平台(测试管理平台是项目管理平台一部分)
提交bug时并没有指定修改bug的程序员,指定给了项目经理
项目经理登陆测试管理平台,将提交的 bug指派给开发人员
开发人员每天定时登陆测试管理平台,可看自己名下的bug,根据测试人员提交 bug信息进行修改bug
提交 bug信息包括:测试场景、测试数据、测试步骤
如果开发人员修改bug完成,提交bug到测试管理平台(bug状态是未修改)
测试人员 天定时登陆测试管理平台,可看自己名下的bug,对开发人员已提交的bug进行回归测试
如果测试通过,将bug关闭,
如果测试 不通过,将bug驳回。
如果开发人员发现bug驳回,详细查看测试场景、测试数据、测试步骤,根据这些进行测试,通过几次测试bug重现不了,找到测试人员进行沟通。

测试 人员将功能测试完成后,进行系统性能测试。
测试完成后,测试编写文档:系统测试报告。
项目经理、产品经理根据测试报告,讨论该系统是否可以上线。

25 你参与过系统维护吗?系统维护的流程是?

参与过系统维护。
医药采购项目问题汇总_第6张图片

你可能感兴趣的:(医药采购项目问题汇总)