l CRM主要功能需求:主要用来管理公司(集成商)与客户、用户单位、供应商、集成商、合作伙伴等之间的关系,以及带有审批流程的各商机、立项项目、执行项目等的系统化,自动化管理。
l CRM系统的框架主要可分为:页面框架、权限架构(页面权限、数据权限)、工作流框框架、后台业务逻辑框架、任务调度框架等。
l B/S请求基本时序图:
l 页面框架:采用ExtJs+自定义标签库的方式做页面框架。所有页面都引入了Struts和JSTL标签库。并采用自定义标签库的方式,封装常用操作,如:
1. 动态展现字典表中的数据为Select或Checkbox。
2. 通过标签展现符合ExtJs风格的Panel,input box等等。
3. 自动根据访问者的权限,动态展现其在该页面有权使用的按钮。
4. 提供常用操作的java方法调用,如将 Java 对象转换成 Json 对象格式字符串。${myFn:toJsonArrayEscapeHtml(object)}。
l 页面权限架构:涉及用户、角色、权限等表
权限采用树形结构,分为菜单权限和按钮权限,如图
当某用户登录时,系统将加载该用户的所有权限,及该用户所拥有角色的所有权限,并去除该用户的禁用权限。此权限集合作为用户一属性存于Session中。需要判断是否展现某按钮或菜单时,与该用户权限集合进行比对。
l 数据权限架构
//TODO
l 后端架构
Struts1.2 + Spring2.5 + Spring JDBC (jBPM3.2部分采用Hibernate作持久层框架)。
采用接口模式;包结构最上层按模块划分,分为CRM(业务逻辑),System(系统:用户、角色、机构、权限),jBPM(工作流),Email以及一个核心模块(定义了一系列的抽象类、接口,以供继承,包括BaseObject, BaseBean,BaseBlg,BaseDao,BaseEntity,Exception,分页模块,一系列基于apache.commons.xxUtils的通用辅助类,以及名为SpringHelper的Spring容器辅助类)。
每个模块,然后按照实体类(bean),业务逻辑层(blg),持久化层(Dao),展现层(WebApp)以及一个工具包(Util)分为多个包。包下再分为接口层和实现层。
SpringHelper是Spring的辅助类:包括初始化Spring容器及Action层(不由Spring管理)用getBean(name)的方式获得Spring管理的对象。该系统中Spring不是在启动web时初始化,是当访问第一个Action时发生的。Action调用SpringHelper的静态方法getBean(name)之后才在构造SpringHelper时初始化了Spring容器。
l 工作流动态表单框架:
动态表单框架:
第一种方式(静态表),需自己写符合标准的页面及新建数据库对应表,且对应表的字段名与页面参数的那么必须保持一致。
新增动态表单:当将自定义好的符合标准的jsp页面在系统的表单设计模块下提交后,系统将自动按Json方式解析。每个参数作为”动态表单属性表fcoe_form_attribute”的一条记录。每条参数按以下四项解析后存入数据库:name,title(页面显示名称),type(Long,String,Datetime),xtype(hidden,textfield,trigger,datefield)。
动态生成表单:当需要时传入动态表单ID, 系统从数据库的”动态表单属性表”中读取所有该表单的属性,进行显示。
存储动态表单中的数据:再次通过动态表单ID得到所有属性列表,遍历列表,同时将各属性存于一属性实例AttributeInstance列表中。如是新增流程(如:新增的商机报备流程),则通过DynamicDataDao的Long addStaticTableData(final List<AttributeInstance> attributeInstances, final String tableName)动态生成SQL语句,在对应业务表中(如:商机),增加一条记录。否则生成update语句。
动态表单展现:通过“表名”,“表中字段名”,“主键”调用dynamicDataDao的List<AttributeInstance> getStaticTableDataList(List<FormAttribute> attributes, String tableName, Object value)得到键值对的列表后,进行展现。
第二种方式(动态表, CRM系统中未使用),需写符合标准的页面,数据库内无需存在对应表。
展现:通过传入的“formInstanceId”调用attributeInstanceDao中的List<AttributeInstance> getAttributeInstances(formInstanceId)即可得到位于fcoe_attribute_instance表中属于该动态表的键值对列表。
存储:通过调用attributeInstanceDao的saveAttributeInstance(List<AttributeInstance> attributeInstances, Long formInstanceId)新建或updateAttributeInstance更新动态表单。
l 导出Excel表格模块:采用Apache poi组件,并用反射机制加以封装。 使传入某JavaBean的List,就可按表格方式一条记录为一个行,将该JavaBean的所有属性进行输出。
(导出manufacture.xls流程:Action根据传入id在dao层查找出对应厂商表记录并转换为“厂商输出的DTO类”的List。然后将此List交给Excel导出封装类进行导出)。
l 导入Excel表格模块:采用Apache poi组件
(导出manufacture.xls流程: 将上传的Excel文件转换为String数组,即每一行变成一逗号分隔的String表达式。后将此String数组循环导入一临时表中。验证与主表无重复后,再导入主表。以保证一次导入事务的原子性)