前面写过两篇关于“保存信息修改记录”的内容,分别如下:

JeeSite | 保存信息修改记录

JeeSite | 保存信息修改记录续

回顾

        第一篇文章通过类字段的比较返回一个有字段值不同的 List,然后自己构造表字段和字典的 Map 来生成修改前和修改后的差异字符串。从而实现“信息”修改“前”和修改“后”的对比记录。

        第二篇文章不再自己构造表字段和字典的 Map,而是直接使用了 JeeSite 自带的 GenTable 类取代了自己构造表字段和字典的 Map,只是需要将“代码生成”中的“业务表配置”模块维护好就可以了。第二篇文章对第一篇文章进行了改进。

 

        对于保存信息修改记录这个功能会在很多表单中进行使用,那么按照前面的解决方法,需要在每个表单对应的 Controller 中增加相同的代码来完成同样的事情,这样代码就重复了。因此,本篇就将这个功能封装为一个类,这样每次使用的时候只要实例化这个类,就可以完成“信息”修改“前”和修改“后”对比记录的功能了。

 

        代码的具体功能前面都介绍过了,因此不进行太多的介绍了,只是介绍一下具体如何的封装。

差异字段列表生成

        在 JeeSite 下的 src\main\java\com\thinkgem\jeesite\common\utils\ (该目录下存放了 JeeSite 项目的通用工具类,比如文件操作类、字符串操作类、日期操作类等)下新建一个CompareClassUtils.java 的类文件。

        该文件的代码如下:

  1. public class CompareClassUtils {
  2. /**
  3. * 获取两个对象同名属性内容不相同的列表
  4. *
  5. * @param class1
  6. * 对象1
  7. * @param class2
  8. * 对象2
  9. * @return
  10. * @throws ClassNotFoundException
  11. * @throws IllegalAccessException
  12. */
  13. public static List<Map<String, Object>> compareTwoClass(Object class1, Object class2) {
  14. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  15. // 获取对象的class
  16. Class<?> clazz1 = class1.getClass();
  17. Class<?> clazz2 = class2.getClass();
  18. // 获取对象的属性列表
  19. Field[] field1 = clazz1.getDeclaredFields();
  20. Field[] field2 = clazz2.getDeclaredFields();
  21. // 遍历属性列表field1
  22. for (int i = 0; i < field1.length; i++) {
  23. // 遍历属性列表field2
  24. for (int j = 0; j < field2.length; j++) {
  25. // 如果field1[i]属性名与field2[j]属性名内容相同
  26. if (field1[i].getName().equals(field2[j].getName())) {
  27. if (field1[i].getName().equals(field2[j].getName())) {
  28. field1[i].setAccessible(true);
  29. field2[j].setAccessible(true);
  30. // 如果field1[i]属性值与field2[j]属性值内容不相同
  31. try {
  32. if (!compareTwo(field1[i].get(class1), field2[j].get(class2))) {
  33. Map<String, Object> map2 = new HashMap<String, Object>();
  34. map2.put("name", field1[i].getName());
  35. map2.put("old", field1[i].get(class1));
  36. map2.put("new", field2[j].get(class2));
  37. list.add(map2);
  38. }
  39. } catch (IllegalArgumentException e) {
  40. // TODO Auto-generated catch block
  41. e.printStackTrace();
  42. } catch (IllegalAccessException e) {
  43. // TODO Auto-generated catch block
  44. e.printStackTrace();
  45. }
  46. break;
  47. }
  48. }
  49. }
  50. }
  51.  
  52. return list;
  53. }
  54.  
  55. /**
  56. * 对比两个数据是否内容相同
  57. *
  58. * @param object1,object2
  59. * @return boolean类型
  60. */
  61. public boolean compareTwo(Object object1, Object object2) {
  62.  
  63. if (object1 == null && object2 == null) {
  64. return true;
  65. }
  66. if (object1 == null && object2 != null) {
  67. return false;
  68. }
  69. if (object1.equals(object2)) {
  70. return true;
  71. }
  72. return false;
  73. }
  74. }

差异信息的拼接

        差异信息的拼接需要使用数据表中字段的注释,如果代码中使用了字典则需要维护好对应的字典。在前面的文章中,在 GenTableService.java 增加了两个方法,并在 GenTableDao.xml 和 GenTableColumnDao.xml 增加了相应的 SQL。前面文章中,拼接差异信息定义在了表单对应的 Controller 中,即 catModifyInfo() 方法写在了各个表单的 Controller 中,而这里只需要将 catModifyInfo() 方法移动到 GenTableService.java 文件中即可。

        在 GenTableService.java 下添加如下代码:

  1. public String catModifyInfo(List<Map<String, Object>> list, String className) {
  2. // 根据类名获得对应的表信息
  3. GenTable genTable = getTableByClass(className.toString());
  4.  
  5. if ( genTable == null ) {
  6. return "";
  7. }
  8.  
  9. // 根据表id获取表相应的字段信息
  10. List<GenTableColumn> columnList = getColumnByTable(genTable.getId());
  11. if ( columnList == null ) {
  12. return "";
  13. }
  14.  
  15. Map<String, String> mapField = new HashMap<String, String>();
  16. Map<String, String> mapDict = new HashMap<String, String>();
  17.  
  18. // 获得字段对应的Java属性和字段注释
  19. for( GenTableColumn gtc : columnList ) {
  20. mapField.put(gtc.getJavaField(), gtc.getComments());
  21. }
  22.  
  23. // 获得字段对应的注释和对应的字典
  24. for ( GenTableColumn gtc : columnList ) {
  25. if ( StringUtils.isNotEmpty(gtc.getDictType())
  26. && StringUtils.isNotBlank(gtc.getDictType()) ) {
  27. mapDict.put(gtc.getComments(), gtc.getDictType());
  28. }
  29. }
  30.  
  31. // 构造的修改字符串
  32. String modInfo = "";
  33.  
  34. for ( Map<String, Object> mp : list) {
  35. System.out.println(mp.get("name") + "---" + mp.get("old") + "---" + mp.get("new"));
  36. System.out.println(mapField.get(mp.get("name")));
  37.  
  38. // 判断修改的值是否为字典
  39. if ( mapDict.containsKey(mapField.get(mp.get("name"))) ) {
  40. String oldValue = mp.get("old").toString();
  41. String newValue = mp.get("new").toString();
  42. String type = mapDict.get(mapField.get(mp.get("name")));
  43. String oldStr = DictUtils.getDictLabel(oldValue, type, "");
  44. String newStr = DictUtils.getDictLabel(newValue, type, "");
  45. System.out.println(mapField.get(mp.get("name")) + ":(" + oldStr + ") => (" + newStr + ");");
  46. modInfo += mapField.get(mp.get("name")) + ":(" + oldStr + ") => (" + newStr + ");";
  47. } else {
  48. modInfo += mapField.get(mp.get("name")) + ":(" + mp.get("old") + ") => (" + mp.get("new") + ");";
  49. }
  50. }
  51.  
  52. return modInfo;
  53. }

       上面的代码不再进行解释,前面已经有过具体的说明了。

封装后的调用

        在 JeeSite 中,新建和修改的“保存”调用的都是 Controller 中的 "save" 方法,具体是修改还是新建,只要通过判断对象是否存在 id 即可,代码如下:

  1. /*
  2. * 如果id不为空,则表示为修改
  3. */
  4. if ( StringUtils.isNotBlank(sellContract.getId()) ) {
  5. SellContract sc = new SellContract();
  6. // 获取原来的信息
  7. sc = sellContractService.get(sellContract.getId());
  8.  
  9. // 比较修改后的信息和未修改的信息
  10. List<Map<String, Object>> modList = CompareClassUtils.compareTwoClass(sc, sellContract);
  11. // 生成差异信息
  12. String strModifyInfo = genTableService.catModifyInfo(modList, "SellContract");
  13. // 输出差异字符串
  14. System.out.println(strModifyInfo);
  15.  
  16. // 记录修改信息
  17. ContractModifyInformation cmi = new ContractModifyInformation();
  18. cmi.setContractId(sellContract.getId());
  19. cmi.setModifyContent(strModifyInfo);
  20. cmi.setModifyDept(UserUtils.getUser().getOffice().getId());
  21. cmi.setModifyUser(UserUtils.getUser().getId());
  22. cmi.setModifyDate(new Date());
  23. contractModifyInformationService.save(cmi);
  24. }

        到此,具体的封装就完成了。


我的微信公众号:“码农UP2U”

JeeSite | 保存信息修改记录封装的更多相关文章

  1. JeeSite | 保存信息修改记录

    需求点 在很多场景中信息是不能轻易被修改的,修改时要么需要具备权限,要么需要审批,但是无论是哪种方式,修改前后的数据都是需要留有“案底”的,也就是说关键的信息被修改后是有修改记录的,一般修改记录会记录 ...

  2. JeeSite | 保存信息修改记录续

    遗留问题 上篇文章中遗留了一个问题,就是为了要关联类属性与注释,注释与字典的地方使用了两个map来逐个添加了相关的信息,如下所示: Map<String, String> mapField ...

  3. ASP.NET保存信息总结(Application、Session、Cookie、ViewState和Cache等) ZT

    http://www.cnblogs.com/ranran/p/4065619.html http://www.cnblogs.com/jxlsomnus/p/4450911.html 以下是关于AS ...

  4. [ASP.net教程]ASP.NET保存信息总结(Application、Session、Cookie、ViewState和Cache等)

    以下是关于ASP.NET中保存各种信息的对象的比较,理解这些对象的原理,对制作完善的程序来说是相当有必要的(摘至互联网,并非原创--xukunping)在ASP.NET中,有很多种保存信息的对象.例如 ...

  5. 玩转web之servlet(六)---session介绍及简单使用(登录验证中保存信息)

    在浏览器与服务器进行交互时,往往需要把涉及到的一些数据保存下来,这时就需要使用cookie或session进行状态管理. 这篇文章先来说说session怎么用,首先在servlet中创建一个sessi ...

  6. WMI 获取硬件信息的封装函数与获取联想台式机的出厂编号方法

    原文:WMI 获取硬件信息的封装函数与获取联想台式机的出厂编号方法 今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都是可以提取出来的,就自己把那些公共部分提出出来,以后如果要获取 某部分的 ...

  7. mybatis源码- 反射模块一(跟着MyBatis学反射):类级别信息的封装

    目录 1 JavaBean 规范 2 Reflector和ReflectorFactory 2.1 Reflector 属性 2.1.1 属性 2.1.2 Invoker 接口 2.2 Reflect ...

  8. ASP.NET保存信息总结(Application、Session、Cookie、ViewState和Cache等)

    以下是关于ASP.NET中保存各种信息的对象的比较,理解这些对象的原理,对制作完善的程序来说是相当有必要的(摘至互联网,并非原创--xukunping) 在ASP.NET中,有很多种保存信息的对象.例 ...

  9. C#实现在注册表中保存信息

    C#实现在注册表中保存信息 最近做的项目需要在注册表中记录一些用户设置,方便在程序下次启动时读取设置,应用上次用户保存的设置,挺简单的. 写出来,方便记忆,以后要用,可以直接改改就能用. 1 usin ...

随机推荐

  1. ansible部署apache

    Ansible 配置Apache(加粗的字体是要执行的命令) 配置免密登录 [root@localhost ansible]# vim /etc/ansible/hosts //用来配置目标主机 加入 ...

  2. C# DataTable 某一列取算

    1. 列为数字类型double total= Convert.ToDouble(datatable.Compute("SUM(需要求和的参数)", "")); ...

  3. GHOST CMS - Ghost Handlebars主题 Ghost Handlebars Themes

    Ghost Handlebars主题 Ghost Handlebars Themes Ghost主题层被设计为让开发人员和设计人员能够灵活地构建由Ghost平台支持的自定义发布 The Ghost t ...

  4. uni-app实现多端开发

    多端开发,听名字就感觉不一样,一套代码.多端使用,适用于各个平台.市面上很多关于多端开发的框架,比较常用,流行的框架 uni-app,Chameleon(变色龙),taro这些,都可以支持多端,一套代 ...

  5. 深入理解 Java 枚举

  6. 基于V6的中移动物联测试例子,当前测试还挺稳定

    下载: 链接:https://pan.baidu.com/s/1Gz8mEffDGXNSK8lIsAIUEg   提取码:2sur 测试步骤看此贴,跟V7开发板是一样的: 基于H7的中移动物联例子以及 ...

  7. ES6 学习之 let

    关于闭包: <html> <body> <div> <div> <button >aaa</button> <button ...

  8. IT兄弟连 HTML5教程 CSS3属性特效 文字描边

    用CSS3实现的文字描边效果,一个CSS3文字特效实例,字体可以自己随意改,字体颜色也可以自己改.IE9以下浏览器无效果,所以提醒大家测试时候要使用Google Chrome.-webkit-text ...

  9. UWP 使用FontIcon

    通常在设置按钮内容的时候,我们一般会写上文字,比如 <Button Content="OK"/> 但是有一些特殊情况,比如我们的按钮需要一个图标, 这个时候就需要一些特 ...

  10. 为用户分配有效期程序-更新数据库的TRY使用

    REPORT ZPMRP030. TABLES:USR02. DATA: L_ERROR TYPE REF TO CX_SY_OPEN_SQL_DB, L_ERROR_TEXT TYPE STRING ...