shicf
2024-09-30 00ad6b598edbaf878fbddb8a3bae8ba15b636736
doc/ϵͳÉè¼Æ
@@ -1,975 +1,1016 @@
版本控制:
    å½“前产品版本1.0.0
    è¡ç”Ÿé¡¹ç›®ç‰ˆæœ¬
        1.1.0       picc(绵阳人保)
        1.2.0       xn
    è¯¦ç»†è§£é‡Š
        ï¼ˆ1)目前的版本号共有3级,标准版按照1.0.0
        ï¼ˆ2)第一位作为产品大版本
        ï¼ˆ3)第二位作为对应项目的版本
        ï¼ˆ4)第三位作为小版本升级
        ï¼ˆ5)例如,当前版本为1.0.0,由该版本衍生的A项目,则A项目版本为1.1.0;继续衍生的B项目,版本为1.2.0;若是A项目升级,则可以将版本更新为1.1.1。
        ï¼ˆ6)但凡项目占用之后,该数字就一直归该项目使用
        ï¼ˆ7)当产品版本升级到2.0.0之后,衍生的项目版本则为2.x.0
1.数据源
   å¿…须配置默认的数据源,名称必须为default,见application.properties
   sourceName=default
2.表设计
   id字段: ç±»åž‹=bigint ï¼Œé•¿åº¦11
   uuid字段、uuid引用字段:,长度都是80
   å­—段类型除了通用String...外,还有一个类型:parentuuid,用此字段表示主子表的关系,
   åŒæ—¶è¿˜å¿…须配关联的父表名称,同一个关联父表,只能配一个parentuuid类型的字段,如果是普通主外键关联,就不用parentuuid
   æ¯”如:button表 çš„字段定义,父表function
   å­—段名                                             å­—段类型                           å…³è”主表
   id
   uuid
   ......
   function_uuid      parentuuid     mrbase_sys_datamodel_table(保存表的uuid,显示表的名称,默认关联主表的uuid)
   å­—段的长度为下拉选择,根据不同的数据类型,定义不同的长度选项,如:10、20、50、100等
   å­—段类型:
   é™¤æ ‡å‡†çš„string datetime int double ,还有特殊:parentuuid(主子表关系,记录父表uuid)、code(编码字段 000-000-002)、serialNumber(GXD201209020001)
   å­—段类型=parentuuid时,必须field_relation_table字段填写父表的uuid否则也不能作为主子表保存
   æ‰€æœ‰ç±»åž‹ï¼šstring、int、number(小数)、datetime、parentuuid、code、serialNumber、idcard、url、ip、mac、email、userid、orgUuid、file、flowStatus、table_name
3.缓存数据
 *    ç¼“存配置表:SYS_CACHE_CONFIG
 *    å­—段:ID、uuid、cache_name、TABLENAME(S200)、CACHEFIELD(分级缓存字段,逗号分隔),FIELDS(S4000,字段名,逗号分隔)、filter(S4000)、备注说明....
 *  cache_name:唯一
 *    å¸¸ç”¨æ•°æ®ã€åŸºç¡€æ•°æ®ç¼“å­˜
 *    é€šç”¨ç¼“存:通过配置表、字段(多个)、查询条件来指定要缓存的数据内容,采用Map封装,key=cache_name,值=DataTableEntity
 *    ç‰¹æ®Šç¼“存:单独写方法加载数据并处理数据,封装同通用缓存一样
 *    æ”¯æŒåˆ†ç»„缓存,无限级,分组字段必须在缓存字段里面
    æ”¯æŒåŠ è½½å­è¡¨æ•°æ®
 *    ç¼“存数据,存在数据不一致问题,当两个进程同时对一个表的缓存进行读和写时---------------
 *   æ–°å¢žã€ä¿®æ”¹ã€åˆ é™¤ç¼“存表时,要更新缓存-------------------------------------
 *    åˆå§‹æ•°æ®
   table_name=mrbase_sys_datamodel_table
   table_name=mrbase_sys_datamodel_field |  cache_fields=*  |  group_field=table_uuid
   table_name=mrbase_sys_datamodel_field        |  cache_fields=*  |  filter=field_type='parentUuid'
   table_name=mrbase_function_permission |  cache_fields=role_uuid,function_uuid,button_uuid | group_field=role_uuid
*缓存刷新,数据新增、修改、删除时都会刷新对应的该表的所有缓存配置,还可以调自定义的代码进行刷新(bean_name、bean_method(String uuid) å‚数是操作数据的uuid ,bean_method() å¯åŠ¨æ—¶ä¼šè°ƒæ­¤æ–¹æ³•ï¼Œå¿…é¡»å®šä¹‰ä¸¤ä¸ªæ–¹æ³•       ï¼‰
*缓存的使用查询方法:
   æœ‰åˆ†ç»„,分组字段,对应值
    å¯¹åº”缓存中对应的分组字段,整个参数为这,表示没有分组,只能后面不为空,不能前面为空,例如:
   ç¼“存的分组字段:field1、field2、field3 ,获取时参数值,只能三种情况:{value1,null,null}、{value1,value2,null}、{value1,value2,value2},
   ä¸èƒ½å‡ºçް {value1,null,value3} ã€{null,null,value3}  ã€{null,value2,value3} ç­‰æƒ…况
   å¦‚:
   DataTableEntity dt=DataPoolCacheImpl.getInstance().getCacheData("所有字段信息并按表分组",new String[] {tableUuid});
   æœªåˆ†ç»„:
   DataTableEntity table=DataPoolCacheImpl.getInstance().getCacheData("所有表信息");
   ï¼ˆ1)redis工具类
   é…ç½®æ–‡ä»¶ï¼šlx-base-server\lx-base-server-cache\src\main\resource\cache.properties
   ç±»ï¼šcom.lx.base.cache.util.RedisUtil
   ä»‹ç»ï¼š
       å…¨éƒ¨ä¸ºé™æ€æ–¹æ³•,无需注入,包含了对key以及5种基本类型(string,hash,list,set,zset)的操作,方法名称经过简化和归一化,与原生命令稍有不同;
       æŒ‰ç…§key,string,hash,list,set,zset的顺序排列方法,不同类型间存在注释分割,若是后续有新增,应当写在对应的范围内;
       æ–°å¢ž/修改类的方法以add/set开头,后面紧跟类型,最后跟方法特性;
       èŽ·å–ç±»æ–¹æ³•ä»¥get开头,后面紧跟类型,最后跟方法特性;(特殊的,求取交差并集并存储返回的是个数);
       åˆ¤å®šæ˜¯å¦å­˜åœ¨ä¸ºexists开头,后面紧跟类型;
       åˆ é™¤ç±»æ–¹æ³•以del开头,后面紧跟类型,最后跟方法特性;
       ç›¸å¯¹ç‰¹æ®Šçš„命名-clearOutTime(移除超时时间),replaceListAimValue(list-替换指定下标的值),moveSet(set-移动值到指定key的set中)
   æµ‹è¯•类:com.lx.base.cache.TestRedisUtil
   ä»‹ç»ï¼š
       é™¤ç¬¬ä¸€ä¸ªä¸ºèŽ·å–æ•°æ®æ–¹æ³•å¤–ï¼ŒåŽé¢å‡ä¸ºå•å…ƒæµ‹è¯•ï¼Œå¯ä»¥åœ¨è¿™é‡Œæ‰¾åˆ°å¯¹åº”çš„ç¤ºä¾‹ä»£ç ï¼›
       é™¤éƒ¨åˆ†ç±»è½¬æ¢çš„重载方法没有写单元测试,有些重载的方法放在一个单元测试内,基础的获取类方法没有单独写单元测试;
       æ¯ä¸€ä¸ªå•元测试均已通过,但是一次性全开时,本地卡在约一半处;
       å•元测试的方法名为test + å®žé™…方法名(首字母转大写);
       é™¤RedisUtil新增方法或者测试方法存在错误,尽量不更新该类,更新时,需要注释所有单元测试方法;
4.json数据中,字段~type~,不是字段名,是子表数据在修改时候的操作类型,新增、修改、删除
   æ–°å¢žï¼Œuuid没有值, å¯èƒ½ä¸å†™~type~=xxx
   ä¿®æ”¹,uuid有值, å¯èƒ½ä¸å†™~type~=xxx
   åªæœ‰åˆ é™¤æ—¶ç”¨è¿™ä¸ªå­—段来区分,即~type~=del
   ä¿®æ”¹ä¸»å­è¡¨æ•°æ® ä¸»è¡¨å¿…须有uuid字段,子表数据中三个种情况:新增 ~type~="",uuid="",修改:~type~="",uuid="不为空",删除:~type~="del",uuid="不为空"
   å­è¡¨åˆ—数要一致
5.所有实体类型,都必须有个字段 table_name,存表名称 ,可以实体类中定义成常量
6.API请求参数
   API请求json的参数名称:formData,   Token参数封装在json中,名称:accessToken
   RequestParameterEntity å°è£…所有参数请求,详细见该类
   Object bean=request.getAttribute("requestPara");
   String accessToken = null;
   if(bean !=null)   {
      RequestParameterEntity reqp=(RequestParameterEntity)bean;
      accessToken=reqp.getToken();
   }
   -----获取表单数据------
   public FieldSetEntity getFormData() {
      return formData;
   }
7.所有controller å¿…须继承  AbstractBaseController
   ä¿®æ”¹ã€åˆ é™¤ è¿”回
   OK()
   ç™»å½•返回
   OK_login
   æ–°å¢žè¿”回
   OK_Add(String uuid)
   æŸ¥è¯¢è¿”回
   OK_List(FieldSetEntity fs)
   OK_List(DataTableEntity dt)
   é€šç”¨é”™è¯¯è¿”回, æ–°å¢žã€ä¿®æ”¹ã€åˆ é™¤ã€æŸ¥è¯¢å¤±è´¥
   public String error(String code,String msg )
9.所有service å¿…须继承  AbstractBaseService
   /**
    * æ•°æ®æŸ¥è¯¢ ,spring æ³¨å…¥
    */
   @Autowired
   public BaseDao baseDao = null;
10.~table~ å‚数在新增、修改接口时必须放到数据的前面,以此来首先获取到
13.高级参照下拉框接口数据
{
   "code":200,
   "~table~":"xxxxx",
   "data":[{"value_field":"xxxx","view_fields":"xxxx","f1":"xxx","f2":"xxxx","f3":"xxx","code":"xxx"}
   ,{"value_field":"xxxx","view_fields":"xxxx","f1":"xxx","f2":"xxxx","f3":"xxx","code":"xxx"}],
   "pagesize":20,
   "cpage":4,
   "totalCount":343,
   "status":"success",
   "msg":"成功"
}
普通下拉框接口
{
   "code":200,
   "~table~":"mrbase_sys_dict",
   "data":[{"dict_value":"xxxx","dict_label":"xxxx"}
   ,{"dict_value":"xxxx","dict_label":"xxxx"}],
   "pagesize":0,
   "cpage":0,
   "totalCount":0,
   "status":"success",
   "msg":"成功"
}
14.下拉参照配置,保存时select_fields必须处理生成,value_field+" value_field,"+view_fields+" view_fields "+prompt_fieldxxxxx
   prompt_fieldxxxxx,是由prompt_field字段处理而成,如:field1,field2,field3 ,处理后变成    ,field1 f1,field2 f2,field3 f3,org_level_code code
   æœ€åŽselect_fields=xxxx value_field,xxxx view_fields,field1 f1,field2 f2,field3 f3,其中 value_field、view_fields、f1、f2、f3 æ˜¯å›ºå®šå­—段
   å…¶ä¸­filter字段,是配置人员手写的sql条件,字符串中可能配置动态参数,格式为:~参数名称~,前端调用此参照时,也必须传对应的参数值 ï¼Œä¾‹å¦‚:
   é…ç½®filter: uuid=~cust_uuid~ and name like '%~cust_name~%'
   å‰ç«¯å‚数:{cust_uuid="sdgeasge",cust_name="中国"}
   filter字段中还可以配置系统变量,如:is_used=1 and uuid in (select  language_uuid from mrbase_sys_company_language where org_level_uuid='{{COMPANY_UUID}}')
   {{COMPANY_UUID}}:当前登录人员的公司UUID.
   display_type: 1:列表  2:树结构,当等于2表示此参照数据显示树型,同时  code_field、parent_code_field ã€delay_load要必填,
   code_field:上下级关系表中的 ç¼–码字段:001,此字段也处理后放到select_fields字段中去:生成   xxxxx  code,此前端在点击一个节点时,取code的值传给接口,接返回其下面的子数据
   parent_code_field:父编码字段:001
   org_filter_field:根据表中的公司字段进行数据过滤,多个以逗号分隔
   usr_filter_field:人员数据过滤条件字段,必须是数据源表中的人员字段,可以多个,逗号分隔,
14.1 ä¸‹æ‹‰å‚ç…§(高级参照、数据字典)在列表中显示:
   é…ç½®mrbase_sys_datamodel_field.field_reference字段,配参照名称或数据字典名称,如果是数据字典名称加书名号括起来,如:《gender》
   åœ¨åˆ—表的查询方法,对列表数据进行封装一次:baseDao.loadPromptData(dt);
15.token参数  token=xxxxxxxx,放到json数据中,整个json作为一个参数 formData={"token"="xxxxxxxx",xxxxxxxxx}
16.创建单位管理员,使用mrbase_sys_user表,is_manamger默认为是
   åˆ›å»ºç®¡ç†å‘˜æ—¶ï¼Œåˆ†é…ï¼Œåªèƒ½ç»™ä¸‹çº§ç®¡ç†å‘˜åˆ†é…è‡ªå·²èŒƒå›´å†…的权限,初始一个超级管理员,初始一个超级管理员角色。分给超级管员
   åˆ›å»ºå•位管理员,只能创建下级单位的管理员,可以关联多个下级单位,对每个单位进行单独的权限设置,必须先选角色权限,
   åŠŸèƒ½ä¸­æ ‡è¯†æ˜¯å¦æ˜¯åŽå°ç®¡ç†åŠŸèƒ½ ï¼Œç®¡ç†å‘˜è‡ªèº«çš„æƒé™å¿…须是后台功能,为普通人员分配权限时,必须是非后台管理功能
17.功能与按钮api合成一个,采用主子表方式操作
18.开发功能参照system工程中的代码
19.获取application中的配置参数,使用:
   String path = Global.getSystemConfig("upload.file.path", "d:");
20.开发模式
   ä¸€ä¸ªè´Ÿè´£ä¸€ä¸ªåŠŸèƒ½æ¨¡å—çš„å¼€å‘ï¼ŒåŒ…æ‹¬æŽ¥å£å±‚ã€æœåŠ¡å±‚
20.包名规则,以com.lx.+模块名称+.controller(service、entity)
21.全部在lx__Server下面创建maven模块,不是maven工程
   <groupId>com.lx</groupId>   ä¸ç”¨æ”¹
    <artifactId>-server</artifactId> ä»¥å¼€å¤´ï¼ŒåŽé¢æ˜¯æ¨¡å—名称
    <version>1.0.0-SNAPSHOT</version> ä¸ç”¨æ”¹
22.如果要引用jar,单独在pom中添加依赖,内部工程 ä¹Ÿæ˜¯è¿™ä¹ˆç›¸å¼•
23.spring bean引用
private static MenuService menuService = SpringContextHolder.getBean(MenuService.class);
24.获取当前登录用户
   SystemUser user = SpringMVCContextHolder.getCurrentUser();
25.获取当前request、reponse、session等
   SpringMVCContextHolder.getHttpxxxx()
26.对数据的操作,可以参考代码:JsonUtil,如何生成的 FieldSetEnttiy,如何在fs中获取子表(DataTableEntity),如何获取fs中的字段值,如何在DataTableEntity中获取一条记录,和一条记录中的字段值
27.对一条记录的读写操作
28.对数据集的读写操作
   ä»Žç¼“存中获取到数据集
   DataTableEntity dt=DataPoolCacheImpl.getInstance().getCacheData("所有字段信息并按表分组");
      DataTableEntity table=DataPoolCacheImpl.getInstance().getCacheData("mrbase_sys_datamodel_table");
      String tableUuid=null;
      String subTableUUid=null;
      å¾ªçŽ¯æ¯ä¸€æ¡æ•°æ®
      for(int i=0;i<table.getRows();i++) {
         if(tableUuid != null && subTableUUid != null )
            break;
            èŽ·å–ä¸€æ¡è®°å½•ä¸­çš„ä¸€ä¸ªå­—æ®µå€¼
         if(tableName.equals(table.getString(i,"table_name"))){
            tableUuid=table.getString(i, "uuid");
         }
         if(subTableName.equals(table.getString(i,"table_name"))){
            subTableUUid=table.getString(i, "uuid");
         }
      }
29.事务操作
      æ‰€æœ‰æ–°å¢žã€ä¿®æ”¹ã€åˆ é™¤éƒ½è¦åšäº‹åŠ¡
      ç†è®ºä¸Šäº‹åŠ¡å»ºç«‹åœ¨Service层,不在controller层
       å®žçŽ°æ–¹å¼ï¼š
      ----------------------------------------------------------------
      service类中要做事务的方法添加注解:@Transactional,如下:
      /***
        * æ–°å¢žå®¢æˆ·æ•°æ®äº‹åŠ¡å¤„ç†(并且在组织架构中新增一条最顶级的数据)
     * @param fse å®¢æˆ·å•位数据
     * @return
     * @throws BaseException
     */
    @Transactional
    public String addClient(FieldSetEntity fse) throws BaseException{
      -----------------------------------------------------------------
      æ·»åŠ service类的接口类,接口类必须定义要做事务的方法
      controller必须继承AbstractBaseController
      -----------------------------------------------------------------
      controller中的具体调用:
      æŠŠ systemClientsService.addClient(fse); æ”¹æˆä»¥ä¸‹ä»£ç 
       /**事务处理实现**/
        ISystemClientsService service=(ISystemClientsService)getProxyInstance(systemClientsService);
        String uuid = service.addClient(fse);
      ISystemClientsService ï¼šservice类的接口类
      systemClientsService:spring注入的serviceç±»
    -------------------------------------------------------------------
30.查询列表中包含子表数据
   /**
    *
    * @param tableName
    * @param filter
    * @param para
    * @param fields
    * @param orderby
    * @param psize
    * @param pindex
    * @param isMoreSubData æ˜¯å¦åŒæ—¶æŸ¥è¯¢æ‰€æœ‰å­è¡¨çš„对应数据
    * @return
    * @throws BaseException
    */
   public  DataTableEntity listTable(String tableName,String filter,Object para[],String fields[],String orderby, int psize,int pindex,boolean isMoreSubData)
   /**
    * @ æŸ¥è¯¢åˆ—表数据的所有子表数据 String 1=每条记录uuid,String 2= å­è¡¨åç§°
    * @param uuids é€—号分隔 çˆ¶åˆ—表uuids
    * @param table_name
    * @return
    */
   public Map <String,Map<String,DataTableEntity>> listSubData(String uuids,String tableName ) throws BaseException;
31.关于附件获取操作
   RequestParameterEntity.getFormData().getString(附件字段);//上传的原始文件名,多个以逗号分隔
   RequestParameterEntity.getFiles().get(原始文件名); //对应的文件,文件名:uuid+"_"+文件的原始名称  ï¼Œä¸€æ¬¡åªèƒ½èŽ·å–ä¸€ä¸ª
32.关于手写sql语句查询和分页的要求
    select TIMESTAMPDIFF(YEAR,aciwe.start_datetime,aciwe.end_datetime) AS start_datetime from a,b where f1=f2 æˆ– a left join b on f1=f2
         å­—段别名必须是表中的字段,否则无法获取到对应字段的表名和字段信息定义,如:
   start_datetime å¿…须是 a表或b表中的一个字段
         å¤šè¡¨å…³è”查询,表定义:a,b æˆ– a left join b on f1=f2 æ•´ä¸ªåšä¸ºè¡¨
                                    æ¡ä»¶å®šä¹‰ï¼Œwhere åŽé¢ ï¼š f1=f2
 33.如查sql语句中没有uuid字段,无法查询出子表
 34.系统错误说明
      ç³»ç»Ÿé”™è¯¯åˆ†ä¸ºä¸¤ç§ï¼šä¸»åŠ¨æŠ›å‡ºé”™è¯¯ã€æ•èŽ·é”™è¯¯
      ä¸»åŠ¨æŠ›å‡ºï¼š
      /**
    * æž„造函数---主动抛出的错误
    * @param code  é”™è¯¯ç ä»£ç 
    * @param error é”™è¯¯ä¿¡æ¯
    * @param c     é”™è¯¯å‘生的类
    * @param method é”™è¯¯å‘生方法
    */
   public  BaseException(String code,String error,Class c,String method);
      æ•获错误:
      /**
    * æž„造函数,记录错误到库---捕获的错误
    * @param code  é”™è¯¯ç ä»£ç 
    * @param exc   æ•获的错误
    */
   public  BaseException(String code,String error,Class c,String method,Exception sysExc)
35.licese支持
     ç¡¬ä»¶ä¿¡æ¯è¯»å–库文件,下载地址:http://sigar.hyperic.com/
        windows版                                                                  mac版                                                            linux版
     sigar-x86-winnt.dll                 xxxxx                  xxxxxxxxxx
     sigar-amd64-winnt.dll               xxxxxx                 xxxxxxxxx
   åŒæ—¶å°†å¯¹åº”çš„dll文件或者so文件添加到系统目录。例如:windows下把sigar-x86-winnt.dll添加到c:\WINDOWS\system32或者jdk的bin目录。
36.关于通用编码 001-002-003
   è¡¨ä¸­å­˜æ”¾ç¼–码的字段,必须在mrbase_sys_datamodel_field表中该字段的field_type=code
   ç•Œé¢è°ƒç”¨æŽ¥å£èŽ·å–ç¼–ç ï¼š/api/common/createCode,见测试类CodeTest
   å¦‚果界面没有调用接口生成编码,则可以在业务controller中可调以下代码获取
   String code=codeService.createCode(fse.getString("table_name"), fse.getString("field_name"), fse.getString("parentCode")==null?"":fse.getString("parentCode"));
   åœ¨æ–°å¢žçš„controller中调用,在底层Dao中的保存方法中获取获取的临时编码去验证是否被占用,占用则重新生成,保证唯一性
   è¿”回json值中code的值即为生成的编码值
37.通用参数验证、数据保存验证
   å‚数验证:com.lx..module.sys.config.RegistValidateç±»
   åœ¨registValidateParameter方法中添加验证代码,如:
   DataValidateInterceptor.registValidatPara("/api/prompt/findPrompt","client_uuid",VerifyRegularUtil.VALIDATE_REQUIRED);
   å‚æ•°1:接口
   å‚æ•°2:验证字段
   å‚æ•°3:验证类型
   æ•°æ®ä¿å­˜éªŒè¯ï¼Œåœ¨core包中的dao中自动根据数据表字段的配置验证,通常不用配,但如果有其它验证,也可以在保存和修改接口中配置,否则保存和修改接口不用配
   æ ¹æ®å­—段类型进行验证,如:字段是mail,mrbase_sys_datamodel_field.field_type=email,现只支持:
   int、number(小数)、idcard、url、ip、mac、datetime、length、email
38.properties配置文件参数获取
   è°ƒç”¨ï¼š
   Global.getPropertyToBoolean("druid.datasource.testOnBorrow", "false")
   æ–¹æ³•:
   /**
    * èŽ·å–é…ç½®,如果获取不到配置,则传默认值
    * @key key值
    * @defaultValue ä¸ºç©ºæ—¶çš„默认值
    */
   public static String getSystemConfig(String key,String defaultValue)
   public static Integer getPropertyToInteger(String key, String defValue)
   public static Long getPropertyToLong(String key, String defValue)
   public static Boolean getPropertyToBoolean(String key, String defValue)
39.数据权限
   åœ¨åˆ—表中添加数据权限条件的获取,添加到列表查询方法中。
   /**
    * èŽ·å–äººå‘˜çš„æ•°æ®æƒé™ï¼Œæ€»å…¥å£ ï¼Œä¸è¿‡æ»¤äººå‘˜ï¼Œåªè¿‡æ»¤å…¬å¸
    * æŒ‡å®šè¦è¿‡æ»¤çš„ å…¬å¸å­—段  ä½¿ç”¨é»˜è®¤å…¬å¸å­—段进行过滤-org_level_uuid
    * @return
    */
   public  String getDataFilter();
   /**
    * èŽ·å–äººå‘˜çš„æ•°æ®æƒé™ï¼Œæ€»å…¥å£ ï¼Œä¸è¿‡æ»¤äººå‘˜ï¼Œåªè¿‡æ»¤å…¬å¸
    * @param org_fields   æŒ‡å®šè¦è¿‡æ»¤çš„公司字段,为空则,使用默认公司字段进行过滤-org_level_uuid
    * @return
    */
   public  String getDataFilter(String org_fields)
   /**
    * èŽ·å–äººå‘˜çš„æ•°æ®æƒé™ï¼Œæ€»å…¥å£ ï¼Œè¿‡æ»¤æŒ‡å®šäººå‘˜å­—段,使用默认公司字段进行过滤-org_level_uuid
    * @tableName äººå‘˜è¿‡æ»¤çš„表
    * @param staff_fields
    * @return
    */
   public  String getDataFilter(String tableName,String staff_fields)
   /**
    * èŽ·å–äººå‘˜çš„æ•°æ®æƒé™ï¼Œæ€»å…¥å£ ,人员 å…¬å¸åŒæ—¶è¿‡æ»¤
    * @param tableName   æŒ‡å®šæ˜¯å“ªå¼ è¡¨çš„æ•°æ® æƒé™è¿‡æ»¤
    * @param staff_fields æŒ‡å®šè¦è¿‡æ»¤çš„人员字段 ï¼Œä¸ºç©ºåˆ™ï¼Œä¸ç”¨äººå‘˜è¿‡æ»¤
    * @param org_fields   æŒ‡å®šè¦è¿‡æ»¤çš„ å…¬å¸å­—段,为空则,使用默认公司字段进行过滤-org_level_uuid
    * @return
    */
   public  String getDataFilter(String tableName,String staff_fields,String org_fields)
 40.关于流水号
    åªéœ€è¦åœ¨é…ç½®ä¸­é…ç½®æµæ°´å·,见表mrbase_sys_swift_config
   è¡¨ä¸­å­˜æ”¾æµæ°´å·çš„字段,必须在mrbase_sys_datamodel_field表中该字段的field_type=serialNumber ï¼Œç¤ºä¾‹è§test表
   ç•Œé¢è°ƒç”¨æŽ¥å£èŽ·å–ç¼–ç ï¼š/api/common/createSerialNumber,见测试类CodeTest,必传参数:serialNumberName,对应表流水号配置表中的swift_config_name字段值
   è¿”回json值中serialNumber的值即为生成的流水号
   å¦‚果界面没有调用接口生成编码,则可以在业务controller中可调以下代码获取
   String serialNumber=serialNumberService.createSerialNumber(serialNumberName);
   åœ¨æ–°å¢žçš„controller中调用,在底层Dao中的保存方法中获取获取的临时编码去验证是否被占用,占用则重新生成,保证唯一性
   æŽ¥
    é…ç½®æ”¯æŒæ ¼å¼ï¼š
     [YYYY]:年
     [MM] ï¼šæœˆ
     [DD] ï¼šæ—¥
     [COMPANY_NAME]:公司名称,对应org_level_name
     [COMPANY_CODE]:公司编码  org_level_code
     [DEPT_NAME]:部门名称org_level_name
     [DEPT_CODE]:部门编码org_level_code
41.接口签名认证
      ç³»ç»Ÿå‚数文件中可配置:
    #是否启用接口签名认证
   signature.isEnable=false
   #在启用接口签名认证时,排除指定接口无需签名认证
   signature.exclude.path=/login,/logout,/relogin
   #接口签名认证有效期,单位秒,签名认证有效期=空或0,则表示不验证
   signature.expire=10
   -------------
   ä½¿ç”¨MD5加密,加密内容:参数formData的值+KEY(单独指定)
   å‰ç«¯åŠ å¯†åŽçš„å­—ç¬¦ä¸²è¦å¤§å†™ï¼šsign=GEGSTLLSEGEL
   formData中要包含timestamp时间戳的值,格式为:yyyyMMddHHmmss
42.通用删除验证
   è°ƒç”¨ï¼š
      æ¨¡å— system
      ç±»     SystemDeleteValidationService
      æ–¹æ³• public  boolean  deleteValidation(String tableName, String uuids,String delete_filter) throws BaseException {
   å‚数说明:
       tableName删除数据表表名
       uuids要删除数据的uuid,多个用逗号分隔
       delete_filter删除条件  fields='name'
   è¿”回说明:
      éªŒè¯é€šè¿‡æ²¡æœ‰å…³è”任何数据返回true
      å‚数缺失返回false
      éªŒè¯æ²¡é€šè¿‡å…³è”了其他表数据抛出异常,异常信息中提示关联数据表,多个用逗号分隔
43.国际化
   label:
      ç”¨æˆ·ç™»å½•成功后,调接口:
      /api/language/load-international-info/{version}
      åŠ è½½æŒ‡å®šå®¢æˆ·ç«¯ã€ç‰ˆæœ¬å·ã€é»˜è®¤è¯­è¨€çš„æ‰€æœ‰å›½é™…åŒ–æ•°æ®
      å®¢æˆ·ç«¯ã€ç‰ˆæœ¬å·ã€é»˜è®¤è¯­è¨€æŽ¥å£å‚数上传
   value:
      1、首先配置表、字段为国际化字段
      2、前端调接口获取哪些表有哪些国际化字段,在界面的中对应元素后面添加地球图标,点图标弹出国际化录入
             æŽ¥å£:/api/language/list-international-fields-info/{version}
      3、新增保存数据json格式:
      {
      Â Â Â Â "token":"11111-新增提交数据",
      Â Â Â Â "system_language_code":"ZH",
      Â Â Â Â "system_client_type":"PC",
      Â Â Â Â "system_client_version":"iphome X 13.1.3",
      Â Â Â Â "app_version":"V2.0.0",
      Â Â Â Â "time_zone_offset":"240",
      Â Â Â Â "sign":"eyJhbGciOiJIUzI1N",
      Â Â Â Â "~table~":"mrbase_sys_users",
      Â Â Â Â "name":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "en":"internationalization"
      Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "zh":"国际化"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "address":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "en":"zhuhai"
      Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "zh":"珠海"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "phone":"18123938722",
      Â Â Â Â "sub_table_name":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "filed1":"value1",
      Â Â Â Â Â Â Â Â Â Â Â Â "filed2":"value2",
      Â Â Â Â Â Â Â Â Â Â Â Â "name":[
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "en":"internationalization"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "zh":"国际化"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
      Â Â Â Â Â Â Â Â Â Â Â Â ],
      Â Â Â Â Â Â Â Â Â Â Â Â "address":[
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "en":"zhuhai"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "zh":"珠海"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
      Â Â Â Â Â Â Â Â Â Â Â Â ]
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ]
      }
      4、查询列表数据
      é¦–先查询出所有业务数据,再调
      /**
       * ä¸šåŠ¡ä»£ç å±‚è°ƒç”¨
       * èŽ·å–ä¸šåŠ¡å¯¹åº”å­—æ®µçš„å›½é™…åŒ–æ•°æ®,如果language_code不为空,表明是手机端
       * @param dt ä¸šåŠ¡è¡¨æ•°æ®
       * @param language_code ä¸ä¸ºç©ºåˆ™ä¸ºæ‰‹æœºç«¯
       * @return
       */
      DataTableEntity baseDao.listInternationDataTable(DataTableEntity dt,String language_code ) å°è£…国际化数据到每条记录的每个国际化字段。
      FieldSetEntity  baseDao.listInternationDataTable(FieldSetEntity fs,String language_code )  å°è£…国际化数据到单条记录的每个国际化字段。
      //baseDao.processInternationDataTable(DataTableEntity dt,String language_code ),国际化字段不是数组格式
      //baseDao.processInternationDataTable(FieldSetEntity fs,String language_code ) å›½é™…化字段不是数组格式
      è¿”回json格式:
      {
      Â Â Â Â "code":"200",
      Â Â Â Â "data":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"100001",
      Â Â Â Â Â Â Â Â Â Â Â Â "name":[
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "en":"internat"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "zh":"国际化"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
      Â Â Â Â Â Â Â Â Â Â Â Â ],
      Â Â Â Â Â Â Â Â Â Â Â Â "address":[
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "en":"zhuhai"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "zh":"珠海"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
      Â Â Â Â Â Â Â Â Â Â Â Â ],
      Â Â Â Â Â Â Â Â Â Â Â Â "phone":"18123938729"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "msg":"成功",
      Â Â Â Â "status":"success"
      }
      5、修改保存数据json格式:
      {
      Â Â Â Â "token":"11111-新增提交数据",
      Â Â Â Â "language_code":"zh",
      Â Â Â Â "client_type":"PC",
      Â Â Â Â "client_version":"iphome X 13.1.3",
      Â Â Â Â "app_version":"V2.0.0",
      Â Â Â Â "time_zone_offset":"240",
      Â Â Â Â "sign":"eyJhbGciOiJIUzI1N",
      Â Â Â Â "~table~":"mrbase_sys_users",
      Â Â Â Â "uuid":"100001",
      Â Â Â Â "name":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â "en":"internationalization"
      Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â "zh":"国际化"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "address":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â "en":"zhuhai"
      Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â "zh":"珠海"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "phone":"18123938722"
      }
      6.不能国际化的表:
      mrbase_sys_cache_config ç¼“存配置
      mrbase_sys_data_sources æ•°æ®åº“连接配置
      mrbase_sys_datamodel_field æ•°æ®ç»“构字段信息
      mrbase_sys_datamodel_table æ•°æ®ç»“构表信息
      mrbase_sys_language_code
      mrbase_sys_language_cont_values
      mrbase_sys_language_master
      mrbase_sys_language_values
      mrbase_sys_message_exchange
      mrbase_sys_message_message_exchange
      mrbase_sys_message_template
      mrbase_sys_message_template_language
      mrbase_sys_message_user_exchange
      mrbase_sys_prompt
      mrbase_sys_swift_config
      mrbase_sys_tree_config
      mrbase_sys_version_buttons_mapping
      å®šæ—¶ä»»åŠ¡æ‰€æœ‰è¡¨
44.文件上传--第三方文件服务器
    1)获取客户上传的文件总大小:com.lx.base.file.service.FileManagerService
        /**
         * èŽ·å–å®¢æˆ·ä¸Šä¼ çš„æ–‡ä»¶æ€»å¤§å°
         * @param clientUUID        å®¢æˆ·UUID
         * @return                  å·²ä¸Šä¼ æ–‡ä»¶æ€»å¤§å°
         * @throws BaseException    åŸºæœ¬å¼‚常
         */
        public int findClientFileUsedCapacity(String clientUUID) throws BaseException
    2)获取客户剩余的文件总大小:com.lx.base.file.service.FileManagerService
        /**
         * èŽ·å–å®¢æˆ·å‰©ä½™çš„æ–‡ä»¶æ€»å¤§å°
         * @param clientUUID    å®¢æˆ·UUID
         * @return              å‰©ä½™ç©ºé—´å¤§å°
         */
        public int findClientFileResidueCapacity(String clientUUID) throws BaseException
        /**
         * èŽ·å–å®¢æˆ·å‰©ä½™çš„æ–‡ä»¶æ€»å¤§å°
         * @param fse           å®¢æˆ·fse
         * @return              å‰©ä½™ç©ºé—´å¤§å°
         */
        public int findClientFileResidueCapacity(FieldSetEntity fse) throws BaseException
    3)上传文件
        1>前端上传文件,返回文件信息给后端,调用请求前缀/api/fileManager/add-file-record-plan/{version},详情见showdoc中14-1、文件新增准备,后端返回fse
        ä¼ å…¥json示例:
        {
          "org_level_uuid": "b8631dad-6cc1-4d5a-9f6f-e8c76e6a5464",
          "~table~": "mrbase_sys_attachments",
          "attachment_title": "test_202006221036.doc",
          "client_uuid": "06f959c8-4f41-407c-9bcc-8137a8b22f50",
          "language": "mslc1112",
          "function_uuid": "97779f8b-9657-47e7-8915-2f51113210fe",
          "client_type": "web",
          "attachment_data_table": "test_project",
          "version": "v1",
          "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsImlhdCI6MTU5Mjc5MzY3OSwic3ViIjoic2hpX2Nob25nZnVAMTYzLmNvbSIsImlzcyI6Ind3dy5tcmMuY29tIiwiZXhwIjoxNTkyODY1Njc5fQ.kgffR0iYgjKhFSNI-ak5hPCf3453aOYXIrwHte7pRAY",
          "product_uuid": "001",
          "staff_uuid": "e2f158ec-a6c7-40e0-a201-4fd7eb2e0e98",
          "attachment_data_field": "attachment",
          "attachment_size": "1"
        }
        2>前端得到后端返回后拼接url,调用至服务器端上传文件,根据服务器端状态返回调用请求前缀/api/fileManager/add-file-callback/{version},详情见showdoc中14-2、文件新增结果回调。服务端新增成功本地执行修改,变更文件记录状态为上传成功,返回update;服务端新增失败本地执行删除,还原记录,返回del
        ä¼ å…¥json示例:
        {
          "result": "1",
          "uuid": "c48c0147-8b2f-4a8d-9d5b-46c55ceb725b",
          "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsImlhdCI6MTU5Mjc5NjMzNiwic3ViIjoic2hpX2Nob25nZnVAMTYzLmNvbSIsImlzcyI6Ind3dy5tcmMuY29tIiwiZXhwIjoxNTkyODY4MzM2fQ.LiUeajNzZAHWuT5O_YdPh5IOp7geVjklBGrWUBz79fo"
        }
    4)删除文件
        1>前端删除文件,返回文件信息给后端,调用请求前缀/api/fileManager/del-file-record-plan/{version},详情见showdoc中14-3、文件删除准备,后端返回fse
        ä¼ å…¥json示例:
        {
          "uuid": "c48c0147-8b2f-4a8d-9d5b-46c55ceb725b",
          "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsImlhdCI6MTU5MjgwNDMyOSwic3ViIjoic2hpX2Nob25nZnVAMTYzLmNvbSIsImlzcyI6Ind3dy5tcmMuY29tIiwiZXhwIjoxNTkyODc2MzI5fQ.Fsau5aHByePG7E-p68Y8_Py6yGAcYwbxQLwhkz20MGQ"
        }
        2>前端得到后端返回后拼接url,调用至服务器端删除文件,根据服务器端状态返回调用请求前缀/api/fileManager/del-file-callback/{version},详情见showdoc中14-4、文件删除结果回调。服务端删除成功本地执行删除,返回del;服务端删除失败本地执行修改,还原文件记录状态,返回update
        ä¼ å…¥json示例:
        {
          "result": "0",
          "uuid": "c48c0147-8b2f-4a8d-9d5b-46c55ceb725b",
          "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsImlhdCI6MTU5MjgwNTg4OSwic3ViIjoic2hpX2Nob25nZnVAMTYzLmNvbSIsImlzcyI6Ind3dy5tcmMuY29tIiwiZXhwIjoxNTkyODc3ODg5fQ.0x7xmEM2G8qXq7jiYQiy6iDm48tYEqVS9UqhlHUB9xk"
        }
45.本地文件上传--系统服务器
    æ ¸å¿ƒï¼šéœ€è¦sigar-amd64-winnt.dll或者sigar-x86-winnt.dll文件置于jdk的bin中或者c盘windows/system32
   ä¸Šä¼ ç›®å½•配置,见properties文件中的upload.file。xxxx å‡ ä¸ªç›¸å…³å‚æ•°
   ä¸Šä¼ æ–‡ä»¶è‡ªåŠ¨å­˜åˆ°ç›®å½•ä¸‹ï¼Œåœ¨controller或service层中读取操作。
46.消息服务
    1.新建队列
     public static void createQueue(String queue_name)
     æ— è¿”回值
    2.删除队列
     public static void deleteQueue(String queue_name)
     æ— è¿”回值
    3.新建交换机
    messageService.addExchange
    å‚æ•°
    "exchange_uuid":"新建交换机"
    è¿”回值:交换机uuid
    4.绑定交换机
    messageService.bindExchange
    å‚数:
    {"user_uuid":"用户uuid",
    "exchange_uuid":"交换机uuid"}
    è¿”回值:Boolean
    5.解绑交换机
     messageService.unbindExchange
     å‚数:
     {"user_uuid":"用户uuid",
     "exchange_uuid":"交换机uuid"}
     è¿”回值:boolean
     6.添加消息且添加消息记录
     messageService.addMessage
     å‚数:
       {
       "exchange_uuid":"交换机uuid"
       "message_uuid":"用户uuid"
       "message":"消息内容"
       "template_id":"模板id"
       "create_by":"操作人uuid"
       "virtual_hosts":"虚拟机名"
        }
47.综合搜索:
    findService.listUuid
    å‚数:
    {
    ~table~:[“”,””,””,””]   //数据库表
    Conditions:[{condition:value},{},{}...]   //条件
    language:value    //国际化语言
    }
    è¿”回值:list<String> uuids
    å½“查询语名,使用多表联合查询,并使用了别名时,需要添加表别名、字段别名设置,并把sql语句使用select * from (查询语句+数据权限条件+高级查询条件)  b æ‹¬èµ·æ¥ï¼Œæ³¨æ„
 48.以下内容变更
 1.core包引入变更
<dependency>
   <groupId>com.lx</groupId>
   <artifactId>base-server-core</artifactId>
   <version>1.0.0-releases</version>
</dependency>
2.所有引入core包中类的路径含有全部替换成base,如:
import com.product..core.dao.BaseDao;    ->  import com.product.base.core.dao.BaseDao;
3.获取当前登录用户对应员工信息:
   æ”¹æˆgetCurrentStaff()  FieldSetEntity
4.获取当前登录用户对应员工所属公司信息
   getCurrentCompany()  FieldSetEntity
单独获取公司的uuid、org_level_name(公司名称) org_level_code(公司编码)
4.获取当前登录用户对应员工所属部门信息
   getCurrentDept()  FieldSetEntity
单独获取部门uuid
5.获取当前登录用户对应员工所属客户信息
   getCurrentCustomer()
单独获取客户uuid ã€å®¢æˆ·åç§°ã€å®¢æˆ·ç¼–码
6.获取当前登录用户对应管理员信息
   getCurrentManager()
7.获取查询数据集的所有uuid
   public String DataTableEntity.getUuids()  åŽŸ ï¼Œæ”¹ä¸ºä»¥ä¸‹
   æŒ‡å®šè¡¨çš„æ‰€æœ‰uuid,返回数组
   -> public Object[] getUuids(Object tableName)
   æŒ‡å®šè¡¨çš„æ‰€æœ‰uuid,返回逗号分隔的字符串
   -> public String getUuidsToString(Object tableName)
   è¿”回默认表的所有uuid,返回数组
   -> public Object[] getUuids()
   è¿”回默认表的所有uuid,返回逗号分隔的字符串
   -> public String getUuidsToString()
8.登录上传固定参数
   system_language_code è¯­è¨€ç¼–码 zh en
   system_client_type   å®¢æˆ·ç±»åž‹
   system_client_version ä»£ç ç‰ˆæœ¬
9.接口版本号大写V再加3个数字如下:
所有接口必须上传版本号
http://{IP}:{PORT}/{ProjectName}/api/app/homepage/get-home-page-list/v1 æˆ–v2
10.new FieldSetEntity()后,首先要设置表名,才能调setValue(String fieldName,Object fieldValue), å¦åˆ™åªèƒ½è°ƒsetValue(String fieldName,Object fieldValue,Object tableName)
11.public FieldSetEntity getLeaderStaff() throws BaseException  SystemUser.getLeaderStaff()获取当前人所直属领导信息
12.public FieldSetEntity getJobPost() throws BaseException   SystemUser.getJobPost()获取当前人所岗位信息
13.public DataTableEntity loadDirectSubordinate(String staffUuid) throws BaseException     StaffManagerService.loadDirectSubordinate()    èŽ·å–æŒ‡å®šäººå‘˜çš„ç›´æŽ¥ä¸‹å±ž
14.public DataTableEntity loadAllSubordinate(String staffUuid) throws BaseException   StaffManagerService.loadAllSubordinate()      èŽ·å–æŒ‡å®šäººå‘˜çš„æ‰€æœ‰ç›´æŽ¥ä¸‹å±ž
15.public FieldSetEntity loadStaffLeader(Integer userid)    StaffManagerService.loadStaffLeader()                                     èŽ·å–äººå‘˜çš„ç›´å±žé¢†å¯¼
16.public FieldSetEntity loadStaffLeader(String staffUuid)    StaffManagerService.loadStaffLeader()                                     èŽ·å–äººå‘˜çš„ç›´å±žé¢†å¯¼
17.查询出来的数据集DataTableEntity æˆ–FieldSetEntity ä¸­èŽ·å–åˆ°FieldMetaEntity,调public void addAliasField(String tableName_fieldName,String alias)添加查询中使用的国际化这段别名。
tableName_fieldName: è¡¨åä¸Žå­—段名组合,中间以点分隔  table.field
Alias: sql中对应的字段别名
18.如果多表联合查询,要取国际化值的表,必须取该表uuid字段,有重复uuid,自动添加别名,查询出来的uuid会在后面添加数据递增,如:uuid1,uuid2,第一个uuid不会变,如果要手动对重复的uuid取别名,也应按此规则进行,否则可能出现国际获取不到数据等情况
19.如果多表联合查询,其它字段重复与uuid重复类似,
多表联合查询,同一个表,同一个字段,使用两次,需要select * from () b æŠŠæŸ¥è¯¢ä¸»ä½“括起来同时表必须设置别名
20.FeildSetEntity中获取Object时有两个方法:getValue(String fieldName)和getObject(String fieldName),区别在于,getValue(String fieldName)会把国际化字段值转成JSONObject对象,而getObject(String fieldName)只是返回基础数据
48.手机端JSON数据格式的调用
   è¯­è¨€ç¼–码获取
   String language_code=reqp.getOther().get(com.lx.base.core.config.CmnConst.SYSTEM_LANGUAGE_CODE ).toString();
   String client_type=reqp.getOther().get(com.lx.base.core.config.CmnConst.SYSTEM_CLIENT_TYPE ).toString();
   æ•°æ®ä¿å­˜ï¼š
      baseDao.add(FieldSetEntityfse,String language_code);
      baseDao.add(FieldSetEntity fs,boolean subData,String language_code)
      baseDao.add(DataTableEntity fs,String language_code)
   æ•°æ®ä¿®æ”¹ï¼š
      baseDao.update(FieldSetEntity fs,String language_code)
        baseDao.update(FieldSetEntity fs,boolean subData,String language_code)
       baseDao.update(DataTableEntity fs,String language_code)
       æ•°æ®æŸ¥è¯¢ï¼š
          FieldSetEntity listInternationDataTable(FieldSetEntity fs,String language_code )
          DataTableEntity listInternationDataTable(DataTableEntity dt,String language_code )
49.后端错误信息国际化
   1)错误信息枚举类注入,启动类中添加注入代码:
   DataPoolCacheImpl.getInstance()
         .appendErrorEnumClass("com.lx.base.core.config.ErrorCode")
         .appendErrorEnumClass("com.lx.base.module.sys.config.SystemCode")
         .appendErrorEnumClass("com.lx.base.module.sys.config.SystemErrorCode");
   2)特殊情况调用(AbstractBaseController.error()、BaseException.getMessage()、getMessageInfo()已实现)
   String message=DataPoolCacheImpl.getInstance().getErrorLanguageInternation(code, language_code);
50.高级参照数据返回规则
    1)所有单位高级参照数据 f1 å…¨ç§° f2 çŸ­ç¼–码
    2)所有部门高级参照数据 f1 å…¨ç§° f2 çŸ­ç¼–码
    3)所有岗位高级参照数据 f1 å…¨ç§°
    4)所有岗位等级高级参照数据 f1 ç­‰çº§çº§åˆ« f2 ç»„名
    5)所有模块高级参照数据 f1 çŸ­ç¼–码
    6)所有功能高级参照数据 f1 çŸ­ç¼–码
    7)所有客户高级参照数据 f1 çŸ­ç¼–码
51.高级参照配置
    æ•°æ®æºè¡¨å­—段更改为后端接口,从DataPoolCacheImpl.getInstance().getCacheData("所有表信息");中获取所有表
    è¡¨åˆ«åï¼šä»¥ "a"+table_id为表别名
    é‡å¤å…³è”表配置:SystemPromptService.getPromptRepetitionJoinTable() ï¼Œåœºæ™¯ å…¬å¸ join éƒ¨é—¨ ã€å‘˜å·¥join下属
    å…³è”类型 left join  , inner join , right join
    å•表:
        æ•°æ®æºè¡¨å¤šå‡ºåˆ«å
        å­—段:表别名 "."字段名
    å¤šè¡¨
        is_multiple = 1
        relate_filter(多表关联条件)
        relate_type(关联类型)
        åœ¨é€‰æ‹©äº†æ•°æ®æºè¡¨  a ï¼Œb, c , d表别名分别为 a1,a2,a3,a4
        å…³è”类型= left join(根据业务需求定,目前只能选择1种关联方式)
        å¤šè¡¨å…³è”条件 = a1.uuid=a2.uuid,a3.uuid=a1.uuid,a2.uuid=a4.uuid å¤šä¸ªè¡¨çš„关联条件 ç”¨ "," åˆ†éš”,
        å¤šè¡¨å…³è”条件填写顺序应与表顺序对应不可颠倒
        æ¯ä¸ªè¡¨å…³è”必须在对应的一组关联条件中用到   è¡¨åˆ«å"."字段
        é”™è¯¯ç¤ºèŒƒï¼šâ€œa1.uuid=a2.uuid,a3.uuid=a1.uuid”  ï¼Œé«˜çº§å‚照表关联个数与条件个数不匹配
52.功能权限验证
   å¿…须配置mrbase_sys_function_buttons.api_url配置按钮对应后端接口地址,多个逗号分隔,不能含版本号,如:
   æŽ¥å£åœ°å€ï¼š/api/management/delete-user/v1 é…ç½®åœ°å€ï¼š/api/management/delete-user
53.数据操作权限验证
   ä¸»è¦é’ˆå¯¹å•条数据的删 ã€æ”¹ ã€æŸ¥æ“ä½œï¼Œåœ¨åˆ  ã€æ”¹ ã€æŸ¥çš„相应接口调用
   å¿…须设置mrbase_sys_datamodel_field.field_type,userid:存放人员的字段类型,orgUuid:存放组织机构的字段类型
   1)Controller接口层调用
   2)调法
      /**
       * å¯¹å•条数据进行操作的权限验证
       * @param tableName è¡¨å
       * @param uuid uuid
       * @param type éªŒè¯ç±»åž‹ 1=人员验证 2= ç»„织机构验证 3 ä¸¤è€…都验证
       * @return
       */
      public boolean validDataPermission(String tableName,String uuid ,int type)
      /**
       * å¯¹å•条数据进行操作的权限验证
       * @param fs  ä¸Šä¼ æ•°æ®ï¼Œå¿…须包含表名 uuid ,否一律通过
       * @param type éªŒè¯ç±»åž‹ 1=人员验证 2= çº§ç»‡æœºæž„验证 3 ä¸¤è€…都验证
       * @return
       */
      public boolean validDataPermission(FieldSetEntity fs ,int type)
      /**
       * å¯¹å•条数据进行操作的权限验证 ,特殊权限条件 ï¼Œä¸æ ¹æ®äºº ç»„织机构过滤
       * @param tableName è¡¨å
       * @param uuid uuid
       * @param filter ç‰¹æ®Šæƒé™æ¡ä»¶
       * @return
       */
      public boolean validDataPermission(String tableName,String uuid,String filter)
      /**
       * å¯¹å•条数据进行操作的权限验证 ,特殊权限条件 ï¼Œä¸æ ¹æ®äºº ç»„织机构过滤
       * @param fs  ä¸Šä¼ æ•°æ®ï¼Œå¿…须包含表名 uuid ,否一律通过
       * @param filter ç‰¹æ®Šæƒé™æ¡ä»¶
       * @return
       */
      public boolean validDataPermission(FieldSetEntity fs ,String filter)
   3)数据操作的权限验证,特殊条件调用示例
   if(!permissionService.validDataPermission(fse, "(client_uuid is null or client_uuid='') or client_uuid='"
   +SpringMVCContextHolder.getCurrentUser().getClient_uuid()+"'")) {
      SpringMVCContextHolder.getSystemLogger().error(SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getValue(),
            SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getText());
      return this.error(SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getValue(), SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getText());
   }
   4)按人员、组织机构验证数据权限调用示例
      å¿…须设置mrbase_sys_datamodel_field.field_type,userid:存放人员的字段类型,orgUuid:存放组织机构的字段类型
      if(!permissionService.validDataPermission(fse,CoreConst.DATA_PERMISSION_VALID_TYPE_ALL)) {
         SpringMVCContextHolder.getSystemLogger().error(SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getValue(),
               SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getText());
         return this.error(SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getValue(), SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getText());
      }
54.业务代码逻辑处理
   è§„则是业务代码类必须注册成spring的bean,被调用的方法只能有一个FieldSetEntity参数,里面封装业务代码中需要的值,如:
  public void addBalance(FieldSetEntity fs)
  {
    this.logger.info("   ");
    this.staffBusinessService.addBalance(fs);
    this.logger.info(" ");
  }
54.消息生成
   /**
    * æ‰€æœ‰åº”用服务生成消息调些方法去添加消息
    * æ ¹æ®message.server.ip参数判断是否等于127.0.0.1
    * æ˜¯ï¼šåˆ™ç›´æŽ¥è°ƒwriteUserMessage本机方法添加消息
    * å¦ï¼šåˆ™è°ƒæ¶ˆæ¯æœåŠ¡å™¨æŽ¥å£æ·»åŠ æ¶ˆæ¯
    * @param userids      æ¶ˆæ¯æŽ¥æ”¶äºº               å¿…å¡«
    * @param content      æ¶ˆæ¯å†…容                 ä¸å¿…å¡«
    * @param title        æ¶ˆæ¯æ ‡é¢˜                 å¿…å¡«
    * @param send_user_id æ¶ˆæ¯å‘送人               å¿…å¡«
    * @param message_type æ¶ˆæ¯ç±»åž‹                 å¿…å¡«
    * @param url         æ¶ˆæ¯é“¾æŽ¥åœ°å€             ä¸å¿…å¡«
    * @param source_table ä¸šåŠ¡æ•°æ®è¡¨               ä¸å¿…å¡«
    * @param source_uuid  ä¸šåŠ¡æ•°æ®è¡¨uuid           ä¸å¿…å¡«
    * @param create_by    åˆ›å»ºäºº       userid      å¿…å¡«
    * @param is_send_mail æ˜¯å¦å‘送邮件 0:否 1:是   å¿…å¡«
    * @param is_send_sms  æ˜¯å¦å‘送短信 0:否 1:是   å¿…å¡«
    */
   WebsocketMesssageServiceThread.getInstance().appendMessage(String ....);
   //消息类型
   //表名常量定义
   public static final int MESSAGE_TOP_TYPE_SYSTEM =1; //"系统消息";
   public static final int MESSAGE_TYPE_ANNOUNCEMENT =11; //"公告消息";
   public static final int MESSAGE_TOP_TYPE_TASK =2; //"任务消息";
   public static final int MESSAGE_TYPE_APPROVE =21; //"待办消息";
   public static final int MESSAGE_TYPE_COORDINATION =22; //"协同消息";
    public static final int MESSAGE_TYPE_TASK = 23;// "任务模块消息";
   public static final int MESSAGE_TOP_TYPE_WARNING =3; //"预警消息";
   public static final int MESSAGE_TYPE_WARNING =31; //"预警消息";
55.子表排序规则,中括号内表示子表排序 æ”¾åˆ°orderby参数中
String s="main_field1,main_field2,{sub_table1:sub_table1_field1 desc,sub_table1_field2},{sub_table2:sub_table2_field1 desc,sub_table2_field2}"
56.错误信息中的动态变量替换
替则使用{}把变量名括起来,此变量名将在Exception中获取:DATA_VERIFY_UNIQUE_ERROR("数据不是唯一:{value}", ModuleEnum.CORE.getValue() + "097"),
示例:
   be.setMessagePara("fieldxxxx","未获取到登录Token信息");
   be.setMessagePara("fieldxxxx",fs.getString("field"));
"fieldxxxx"对应错误定义中的{fieldxxxx}
56.反射引用bean :com.product.core.util.ReflectUtil
   /**
    *
    * @param beanName è¢«ä»£ç†å¯¹åƒbean åç§°
    * @param methodName æ–¹æ³•名称
    * @param objects  å‚æ•°
    * @return
    * @throws BaseException
    */
   public static  Object invoke(String beanName,String methodName,Object[] objects) throws BaseException
57.产生消息的表,必须在对应表的produce_msg字段中值为1
58.自动发起流程
    com.lx.tool.flow.service.FlowService#autoSendFlow
    æè¿°ï¼š
        ï¼ˆ1)service方法,非接口方法
        ï¼ˆ2)根据传入的参数,自动发起流程,创建流程的第一步,直接到【开始】环节
    ä¼ å…¥å‚数:fse
        {
            "type_code": "5a1dd74e-5b69-479c-afa0-a7db3e7fd6b2",
            "~table~": "lx_oa_conference_apply",
            "accepters": "376",
            "uuid": "5aadc03d-6ae3-470c-8507-4aaf660d9495",
            "flow_title": "6c测试自动发起流程"
        }
    å‚数描述:
        ï¼ˆ1)type_code:类型uuid,类型唯一识别
        ï¼ˆ2)~table~:业务表名
        ï¼ˆ3)accepters:接收人,只能为一个
        ï¼ˆ4)uuid:业务表uuid
        ï¼ˆ5)flow_title:流程标题
59.产中打包部署
   jar部署:打开工程的pom.mxl,右键->Run as -> Maven install->进入工程目录->target目录->copy æŠŠå®ŒåŒ…的工程jar,放到服务器的运行目录下的lib目录下(例如200上:D:\LXServer\product-server\lib)
   å‰ç«¯æ–‡ä»¶éƒ¨ç½²ï¼šè¿›å…¥lx-web并运行packed.bat,重新生成dist目录->进入dist目录copy除baseUrl.js以外的所有文件,放到服务器的运行目录下的web目录下。
   é‡å¯ï¼ˆè¿è¡Œæ¡Œé¢å¿«æ·é”®ï¼‰
60.分页查询sql
   select  '6973' as staff_uuid  è¿™ç§æ²¡æœ‰from的语句,要添加 from dual,否则分页查询会出错
61.查询单条记录,getFieldSet... ä¸Ž getFieldSetEntity...的区别: å‰é¢æ–¹æ³•在没有查到数据时返回不为空,后面方法在没有查到数据时返回null
62.配置报表
   å‡è®¾è¿‡æ»¤æ¡ä»¶ä¸º"start_time>=('2021-12-01 00:00:00','%Y-%m-%d %H:%i:%s')"
   {$$} ç±»åž‹ä¸º0,只取值,即为"2021-12-01 00:00:00"
   {^^} ç±»åž‹ä¸º1,取除开字段外的所有内容,即为">=('2021-12-01 00:00:00','%Y-%m-%d %H:%i:%s')"
   {&&} ç±»åž‹ä¸º2,取所有内容,包含字段,即为"start_time>=('2021-12-01 00:00:00','%Y-%m-%d %H:%i:%s')"
   [[]] è‹¥æ˜¯æ ¹æ®ä¸Šé¢çš„æ‰€æœ‰æ–¹å¼æ›¿æ¢ä¹‹åŽä¾ç„¶å­˜åœ¨ä»»æ„ä¸€ç§ï¼Œå‰”除包含在内的过滤条件
版本控制:
    å½“前产品版本1.0.0
    è¡ç”Ÿé¡¹ç›®ç‰ˆæœ¬
        1.1.0       picc(绵阳人保)
        1.2.0       xn
    è¯¦ç»†è§£é‡Š
        ï¼ˆ1)目前的版本号共有3级,标准版按照1.0.0
        ï¼ˆ2)第一位作为产品大版本
        ï¼ˆ3)第二位作为对应项目的版本
        ï¼ˆ4)第三位作为小版本升级
        ï¼ˆ5)例如,当前版本为1.0.0,由该版本衍生的A项目,则A项目版本为1.1.0;继续衍生的B项目,版本为1.2.0;若是A项目升级,则可以将版本更新为1.1.1。
        ï¼ˆ6)但凡项目占用之后,该数字就一直归该项目使用
        ï¼ˆ7)当产品版本升级到2.0.0之后,衍生的项目版本则为2.x.0
1.数据源
   å¿…须配置默认的数据源,名称必须为default,见application.properties
   sourceName=default
2.表设计
   id字段: ç±»åž‹=bigint ï¼Œé•¿åº¦11
   uuid字段、uuid引用字段:,长度都是80
   å­—段类型除了通用String...外,还有一个类型:parentuuid,用此字段表示主子表的关系,
   åŒæ—¶è¿˜å¿…须配关联的父表名称,同一个关联父表,只能配一个parentuuid类型的字段,如果是普通主外键关联,就不用parentuuid
   æ¯”如:button表 çš„字段定义,父表function
   å­—段名                                             å­—段类型                           å…³è”主表
   id
   uuid
   ......
   function_uuid      parentuuid     mrbase_sys_datamodel_table(保存表的uuid,显示表的名称,默认关联主表的uuid)
   å­—段的长度为下拉选择,根据不同的数据类型,定义不同的长度选项,如:10、20、50、100等
   å­—段类型:
   é™¤æ ‡å‡†çš„string datetime int double ,还有特殊:parentuuid(主子表关系,记录父表uuid)、code(编码字段 000-000-002)、serialNumber(GXD201209020001)
   å­—段类型=parentuuid时,必须field_relation_table字段填写父表的uuid否则也不能作为主子表保存
   æ‰€æœ‰ç±»åž‹ï¼šstring、int、number(小数)、datetime、parentuuid、code、serialNumber、idcard、url、ip、mac、email、userid、orgUuid、file、flowStatus、table_name
3.缓存数据
 *    ç¼“存配置表:SYS_CACHE_CONFIG
 *    å­—段:ID、uuid、cache_name、TABLENAME(S200)、CACHEFIELD(分级缓存字段,逗号分隔),FIELDS(S4000,字段名,逗号分隔)、filter(S4000)、备注说明....
 *  cache_name:唯一
 *    å¸¸ç”¨æ•°æ®ã€åŸºç¡€æ•°æ®ç¼“å­˜
 *    é€šç”¨ç¼“存:通过配置表、字段(多个)、查询条件来指定要缓存的数据内容,采用Map封装,key=cache_name,值=DataTableEntity
 *    ç‰¹æ®Šç¼“存:单独写方法加载数据并处理数据,封装同通用缓存一样
 *    æ”¯æŒåˆ†ç»„缓存,无限级,分组字段必须在缓存字段里面
    æ”¯æŒåŠ è½½å­è¡¨æ•°æ®
 *    ç¼“存数据,存在数据不一致问题,当两个进程同时对一个表的缓存进行读和写时---------------
 *   æ–°å¢žã€ä¿®æ”¹ã€åˆ é™¤ç¼“存表时,要更新缓存-------------------------------------
 *    åˆå§‹æ•°æ®
   table_name=mrbase_sys_datamodel_table
   table_name=mrbase_sys_datamodel_field |  cache_fields=*  |  group_field=table_uuid
   table_name=mrbase_sys_datamodel_field        |  cache_fields=*  |  filter=field_type='parentUuid'
   table_name=mrbase_function_permission |  cache_fields=role_uuid,function_uuid,button_uuid | group_field=role_uuid
*缓存刷新,数据新增、修改、删除时都会刷新对应的该表的所有缓存配置,还可以调自定义的代码进行刷新(bean_name、bean_method(String uuid) å‚数是操作数据的uuid ,bean_method() å¯åŠ¨æ—¶ä¼šè°ƒæ­¤æ–¹æ³•ï¼Œå¿…é¡»å®šä¹‰ä¸¤ä¸ªæ–¹æ³•       ï¼‰
*缓存的使用查询方法:
   æœ‰åˆ†ç»„,分组字段,对应值
    å¯¹åº”缓存中对应的分组字段,整个参数为这,表示没有分组,只能后面不为空,不能前面为空,例如:
   ç¼“存的分组字段:field1、field2、field3 ,获取时参数值,只能三种情况:{value1,null,null}、{value1,value2,null}、{value1,value2,value2},
   ä¸èƒ½å‡ºçް {value1,null,value3} ã€{null,null,value3}  ã€{null,value2,value3} ç­‰æƒ…况
   å¦‚:
   DataTableEntity dt=DataPoolCacheImpl.getInstance().getCacheData("所有字段信息并按表分组",new String[] {tableUuid});
   æœªåˆ†ç»„:
   DataTableEntity table=DataPoolCacheImpl.getInstance().getCacheData("所有表信息");
   ï¼ˆ1)redis工具类
   é…ç½®æ–‡ä»¶ï¼šlx-base-server\lx-base-server-cache\src\main\resource\cache.properties
   ç±»ï¼šcom.lx.base.cache.util.RedisUtil
   ä»‹ç»ï¼š
       å…¨éƒ¨ä¸ºé™æ€æ–¹æ³•,无需注入,包含了对key以及5种基本类型(string,hash,list,set,zset)的操作,方法名称经过简化和归一化,与原生命令稍有不同;
       æŒ‰ç…§key,string,hash,list,set,zset的顺序排列方法,不同类型间存在注释分割,若是后续有新增,应当写在对应的范围内;
       æ–°å¢ž/修改类的方法以add/set开头,后面紧跟类型,最后跟方法特性;
       èŽ·å–ç±»æ–¹æ³•ä»¥get开头,后面紧跟类型,最后跟方法特性;(特殊的,求取交差并集并存储返回的是个数);
       åˆ¤å®šæ˜¯å¦å­˜åœ¨ä¸ºexists开头,后面紧跟类型;
       åˆ é™¤ç±»æ–¹æ³•以del开头,后面紧跟类型,最后跟方法特性;
       ç›¸å¯¹ç‰¹æ®Šçš„命名-clearOutTime(移除超时时间),replaceListAimValue(list-替换指定下标的值),moveSet(set-移动值到指定key的set中)
   æµ‹è¯•类:com.lx.base.cache.TestRedisUtil
   ä»‹ç»ï¼š
       é™¤ç¬¬ä¸€ä¸ªä¸ºèŽ·å–æ•°æ®æ–¹æ³•å¤–ï¼ŒåŽé¢å‡ä¸ºå•å…ƒæµ‹è¯•ï¼Œå¯ä»¥åœ¨è¿™é‡Œæ‰¾åˆ°å¯¹åº”çš„ç¤ºä¾‹ä»£ç ï¼›
       é™¤éƒ¨åˆ†ç±»è½¬æ¢çš„重载方法没有写单元测试,有些重载的方法放在一个单元测试内,基础的获取类方法没有单独写单元测试;
       æ¯ä¸€ä¸ªå•元测试均已通过,但是一次性全开时,本地卡在约一半处;
       å•元测试的方法名为test + å®žé™…方法名(首字母转大写);
       é™¤RedisUtil新增方法或者测试方法存在错误,尽量不更新该类,更新时,需要注释所有单元测试方法;
4.json数据中,字段~type~,不是字段名,是子表数据在修改时候的操作类型,新增、修改、删除
   æ–°å¢žï¼Œuuid没有值, å¯èƒ½ä¸å†™~type~=xxx
   ä¿®æ”¹,uuid有值, å¯èƒ½ä¸å†™~type~=xxx
   åªæœ‰åˆ é™¤æ—¶ç”¨è¿™ä¸ªå­—段来区分,即~type~=del
   ä¿®æ”¹ä¸»å­è¡¨æ•°æ® ä¸»è¡¨å¿…须有uuid字段,子表数据中三个种情况:新增 ~type~="",uuid="",修改:~type~="",uuid="不为空",删除:~type~="del",uuid="不为空"
   å­è¡¨åˆ—数要一致
5.所有实体类型,都必须有个字段 table_name,存表名称 ,可以实体类中定义成常量
6.API请求参数
   API请求json的参数名称:formData,   Token参数封装在json中,名称:accessToken
   RequestParameterEntity å°è£…所有参数请求,详细见该类
   Object bean=request.getAttribute("requestPara");
   String accessToken = null;
   if(bean !=null)   {
      RequestParameterEntity reqp=(RequestParameterEntity)bean;
      accessToken=reqp.getToken();
   }
   -----获取表单数据------
   public FieldSetEntity getFormData() {
      return formData;
   }
7.所有controller å¿…须继承  AbstractBaseController
   ä¿®æ”¹ã€åˆ é™¤ è¿”回
   OK()
   ç™»å½•返回
   OK_login
   æ–°å¢žè¿”回
   OK_Add(String uuid)
   æŸ¥è¯¢è¿”回
   OK_List(FieldSetEntity fs)
   OK_List(DataTableEntity dt)
   é€šç”¨é”™è¯¯è¿”回, æ–°å¢žã€ä¿®æ”¹ã€åˆ é™¤ã€æŸ¥è¯¢å¤±è´¥
   public String error(String code,String msg )
9.所有service å¿…须继承  AbstractBaseService
   /**
    * æ•°æ®æŸ¥è¯¢ ,spring æ³¨å…¥
    */
   @Autowired
   public BaseDao baseDao = null;
10.~table~ å‚数在新增、修改接口时必须放到数据的前面,以此来首先获取到
13.高级参照下拉框接口数据
{
   "code":200,
   "~table~":"xxxxx",
   "data":[{"value_field":"xxxx","view_fields":"xxxx","f1":"xxx","f2":"xxxx","f3":"xxx","code":"xxx"}
   ,{"value_field":"xxxx","view_fields":"xxxx","f1":"xxx","f2":"xxxx","f3":"xxx","code":"xxx"}],
   "pagesize":20,
   "cpage":4,
   "totalCount":343,
   "status":"success",
   "msg":"成功"
}
普通下拉框接口
{
   "code":200,
   "~table~":"mrbase_sys_dict",
   "data":[{"dict_value":"xxxx","dict_label":"xxxx"}
   ,{"dict_value":"xxxx","dict_label":"xxxx"}],
   "pagesize":0,
   "cpage":0,
   "totalCount":0,
   "status":"success",
   "msg":"成功"
}
14.下拉参照配置,保存时select_fields必须处理生成,value_field+" value_field,"+view_fields+" view_fields "+prompt_fieldxxxxx
   prompt_fieldxxxxx,是由prompt_field字段处理而成,如:field1,field2,field3 ,处理后变成    ,field1 f1,field2 f2,field3 f3,org_level_code code
   æœ€åŽselect_fields=xxxx value_field,xxxx view_fields,field1 f1,field2 f2,field3 f3,其中 value_field、view_fields、f1、f2、f3 æ˜¯å›ºå®šå­—段
   å…¶ä¸­filter字段,是配置人员手写的sql条件,字符串中可能配置动态参数,格式为:~参数名称~,前端调用此参照时,也必须传对应的参数值 ï¼Œä¾‹å¦‚:
   é…ç½®filter: uuid=~cust_uuid~ and name like '%~cust_name~%'
   å‰ç«¯å‚数:{cust_uuid="sdgeasge",cust_name="中国"}
   filter字段中还可以配置系统变量,如:is_used=1 and uuid in (select  language_uuid from mrbase_sys_company_language where org_level_uuid='{{COMPANY_UUID}}')
   {{COMPANY_UUID}}:当前登录人员的公司UUID.
   display_type: 1:列表  2:树结构,当等于2表示此参照数据显示树型,同时  code_field、parent_code_field ã€delay_load要必填,
   code_field:上下级关系表中的 ç¼–码字段:001,此字段也处理后放到select_fields字段中去:生成   xxxxx  code,此前端在点击一个节点时,取code的值传给接口,接返回其下面的子数据
   parent_code_field:父编码字段:001
   org_filter_field:根据表中的公司字段进行数据过滤,多个以逗号分隔
   usr_filter_field:人员数据过滤条件字段,必须是数据源表中的人员字段,可以多个,逗号分隔,
14.1 ä¸‹æ‹‰å‚ç…§(高级参照、数据字典)在列表中显示:
   é…ç½®mrbase_sys_datamodel_field.field_reference字段,配参照名称或数据字典名称,如果是数据字典名称加书名号括起来,如:《gender》
   åœ¨åˆ—表的查询方法,对列表数据进行封装一次:baseDao.loadPromptData(dt);
15.token参数  token=xxxxxxxx,放到json数据中,整个json作为一个参数 formData={"token"="xxxxxxxx",xxxxxxxxx}
16.创建单位管理员,使用mrbase_sys_user表,is_manamger默认为是
   åˆ›å»ºç®¡ç†å‘˜æ—¶ï¼Œåˆ†é…ï¼Œåªèƒ½ç»™ä¸‹çº§ç®¡ç†å‘˜åˆ†é…è‡ªå·²èŒƒå›´å†…的权限,初始一个超级管理员,初始一个超级管理员角色。分给超级管员
   åˆ›å»ºå•位管理员,只能创建下级单位的管理员,可以关联多个下级单位,对每个单位进行单独的权限设置,必须先选角色权限,
   åŠŸèƒ½ä¸­æ ‡è¯†æ˜¯å¦æ˜¯åŽå°ç®¡ç†åŠŸèƒ½ ï¼Œç®¡ç†å‘˜è‡ªèº«çš„æƒé™å¿…须是后台功能,为普通人员分配权限时,必须是非后台管理功能
17.功能与按钮api合成一个,采用主子表方式操作
18.开发功能参照system工程中的代码
19.获取application中的配置参数,使用:
   String path = Global.getSystemConfig("upload.file.path", "d:");
20.开发模式
   ä¸€ä¸ªè´Ÿè´£ä¸€ä¸ªåŠŸèƒ½æ¨¡å—çš„å¼€å‘ï¼ŒåŒ…æ‹¬æŽ¥å£å±‚ã€æœåŠ¡å±‚
20.包名规则,以com.lx.+模块名称+.controller(service、entity)
21.全部在lx__Server下面创建maven模块,不是maven工程
   <groupId>com.lx</groupId>   ä¸ç”¨æ”¹
    <artifactId>-server</artifactId> ä»¥å¼€å¤´ï¼ŒåŽé¢æ˜¯æ¨¡å—名称
    <version>1.0.0-SNAPSHOT</version> ä¸ç”¨æ”¹
22.如果要引用jar,单独在pom中添加依赖,内部工程 ä¹Ÿæ˜¯è¿™ä¹ˆç›¸å¼•
23.spring bean引用
private static MenuService menuService = SpringContextHolder.getBean(MenuService.class);
24.获取当前登录用户
   SystemUser user = SpringMVCContextHolder.getCurrentUser();
25.获取当前request、reponse、session等
   SpringMVCContextHolder.getHttpxxxx()
26.对数据的操作,可以参考代码:JsonUtil,如何生成的 FieldSetEnttiy,如何在fs中获取子表(DataTableEntity),如何获取fs中的字段值,如何在DataTableEntity中获取一条记录,和一条记录中的字段值
27.对一条记录的读写操作
28.对数据集的读写操作
   ä»Žç¼“存中获取到数据集
   DataTableEntity dt=DataPoolCacheImpl.getInstance().getCacheData("所有字段信息并按表分组");
      DataTableEntity table=DataPoolCacheImpl.getInstance().getCacheData("mrbase_sys_datamodel_table");
      String tableUuid=null;
      String subTableUUid=null;
      å¾ªçŽ¯æ¯ä¸€æ¡æ•°æ®
      for(int i=0;i<table.getRows();i++) {
         if(tableUuid != null && subTableUUid != null )
            break;
            èŽ·å–ä¸€æ¡è®°å½•ä¸­çš„ä¸€ä¸ªå­—æ®µå€¼
         if(tableName.equals(table.getString(i,"table_name"))){
            tableUuid=table.getString(i, "uuid");
         }
         if(subTableName.equals(table.getString(i,"table_name"))){
            subTableUUid=table.getString(i, "uuid");
         }
      }
29.事务操作
      æ‰€æœ‰æ–°å¢žã€ä¿®æ”¹ã€åˆ é™¤éƒ½è¦åšäº‹åŠ¡
      ç†è®ºä¸Šäº‹åŠ¡å»ºç«‹åœ¨Service层,不在controller层
       å®žçŽ°æ–¹å¼ï¼š
      ----------------------------------------------------------------
      service类中要做事务的方法添加注解:@Transactional,如下:
      /***
        * æ–°å¢žå®¢æˆ·æ•°æ®äº‹åŠ¡å¤„ç†(并且在组织架构中新增一条最顶级的数据)
     * @param fse å®¢æˆ·å•位数据
     * @return
     * @throws BaseException
     */
    @Transactional
    public String addClient(FieldSetEntity fse) throws BaseException{
      -----------------------------------------------------------------
      æ·»åŠ service类的接口类,接口类必须定义要做事务的方法
      controller必须继承AbstractBaseController
      -----------------------------------------------------------------
      controller中的具体调用:
      æŠŠ systemClientsService.addClient(fse); æ”¹æˆä»¥ä¸‹ä»£ç 
       /**事务处理实现**/
        ISystemClientsService service=(ISystemClientsService)getProxyInstance(systemClientsService);
        String uuid = service.addClient(fse);
      ISystemClientsService ï¼šservice类的接口类
      systemClientsService:spring注入的serviceç±»
    -------------------------------------------------------------------
30.查询列表中包含子表数据
   /**
    *
    * @param tableName
    * @param filter
    * @param para
    * @param fields
    * @param orderby
    * @param psize
    * @param pindex
    * @param isMoreSubData æ˜¯å¦åŒæ—¶æŸ¥è¯¢æ‰€æœ‰å­è¡¨çš„对应数据
    * @return
    * @throws BaseException
    */
   public  DataTableEntity listTable(String tableName,String filter,Object para[],String fields[],String orderby, int psize,int pindex,boolean isMoreSubData)
   /**
    * @ æŸ¥è¯¢åˆ—表数据的所有子表数据 String 1=每条记录uuid,String 2= å­è¡¨åç§°
    * @param uuids é€—号分隔 çˆ¶åˆ—表uuids
    * @param table_name
    * @return
    */
   public Map <String,Map<String,DataTableEntity>> listSubData(String uuids,String tableName ) throws BaseException;
31.关于附件获取操作
   RequestParameterEntity.getFormData().getString(附件字段);//上传的原始文件名,多个以逗号分隔
   RequestParameterEntity.getFiles().get(原始文件名); //对应的文件,文件名:uuid+"_"+文件的原始名称  ï¼Œä¸€æ¬¡åªèƒ½èŽ·å–ä¸€ä¸ª
32.关于手写sql语句查询和分页的要求
    select TIMESTAMPDIFF(YEAR,aciwe.start_datetime,aciwe.end_datetime) AS start_datetime from a,b where f1=f2 æˆ– a left join b on f1=f2
         å­—段别名必须是表中的字段,否则无法获取到对应字段的表名和字段信息定义,如:
   start_datetime å¿…须是 a表或b表中的一个字段
         å¤šè¡¨å…³è”查询,表定义:a,b æˆ– a left join b on f1=f2 æ•´ä¸ªåšä¸ºè¡¨
                                    æ¡ä»¶å®šä¹‰ï¼Œwhere åŽé¢ ï¼š f1=f2
 33.如查sql语句中没有uuid字段,无法查询出子表
 34.系统错误说明
      ç³»ç»Ÿé”™è¯¯åˆ†ä¸ºä¸¤ç§ï¼šä¸»åŠ¨æŠ›å‡ºé”™è¯¯ã€æ•èŽ·é”™è¯¯
      ä¸»åŠ¨æŠ›å‡ºï¼š
      /**
    * æž„造函数---主动抛出的错误
    * @param code  é”™è¯¯ç ä»£ç 
    * @param error é”™è¯¯ä¿¡æ¯
    * @param c     é”™è¯¯å‘生的类
    * @param method é”™è¯¯å‘生方法
    */
   public  BaseException(String code,String error,Class c,String method);
      æ•获错误:
      /**
    * æž„造函数,记录错误到库---捕获的错误
    * @param code  é”™è¯¯ç ä»£ç 
    * @param exc   æ•获的错误
    */
   public  BaseException(String code,String error,Class c,String method,Exception sysExc)
35.licese支持
     ç¡¬ä»¶ä¿¡æ¯è¯»å–库文件,下载地址:http://sigar.hyperic.com/
        windows版                                                                  mac版                                                            linux版
     sigar-x86-winnt.dll                 xxxxx                  xxxxxxxxxx
     sigar-amd64-winnt.dll               xxxxxx                 xxxxxxxxx
   åŒæ—¶å°†å¯¹åº”çš„dll文件或者so文件添加到系统目录。例如:windows下把sigar-x86-winnt.dll添加到c:\WINDOWS\system32或者jdk的bin目录。
36.关于通用编码 001-002-003
   è¡¨ä¸­å­˜æ”¾ç¼–码的字段,必须在mrbase_sys_datamodel_field表中该字段的field_type=code
   ç•Œé¢è°ƒç”¨æŽ¥å£èŽ·å–ç¼–ç ï¼š/api/common/createCode,见测试类CodeTest
   å¦‚果界面没有调用接口生成编码,则可以在业务controller中可调以下代码获取
   String code=codeService.createCode(fse.getString("table_name"), fse.getString("field_name"), fse.getString("parentCode")==null?"":fse.getString("parentCode"));
   åœ¨æ–°å¢žçš„controller中调用,在底层Dao中的保存方法中获取获取的临时编码去验证是否被占用,占用则重新生成,保证唯一性
   è¿”回json值中code的值即为生成的编码值
37.通用参数验证、数据保存验证
   å‚数验证:com.lx..module.sys.config.RegistValidateç±»
   åœ¨registValidateParameter方法中添加验证代码,如:
   DataValidateInterceptor.registValidatPara("/api/prompt/findPrompt","client_uuid",VerifyRegularUtil.VALIDATE_REQUIRED);
   å‚æ•°1:接口
   å‚æ•°2:验证字段
   å‚æ•°3:验证类型
   æ•°æ®ä¿å­˜éªŒè¯ï¼Œåœ¨core包中的dao中自动根据数据表字段的配置验证,通常不用配,但如果有其它验证,也可以在保存和修改接口中配置,否则保存和修改接口不用配
   æ ¹æ®å­—段类型进行验证,如:字段是mail,mrbase_sys_datamodel_field.field_type=email,现只支持:
   int、number(小数)、idcard、url、ip、mac、datetime、length、email
38.properties配置文件参数获取
   è°ƒç”¨ï¼š
   Global.getPropertyToBoolean("druid.datasource.testOnBorrow", "false")
   æ–¹æ³•:
   /**
    * èŽ·å–é…ç½®,如果获取不到配置,则传默认值
    * @key key值
    * @defaultValue ä¸ºç©ºæ—¶çš„默认值
    */
   public static String getSystemConfig(String key,String defaultValue)
   public static Integer getPropertyToInteger(String key, String defValue)
   public static Long getPropertyToLong(String key, String defValue)
   public static Boolean getPropertyToBoolean(String key, String defValue)
39.数据权限
   åœ¨åˆ—表中添加数据权限条件的获取,添加到列表查询方法中。
   /**
    * èŽ·å–äººå‘˜çš„æ•°æ®æƒé™ï¼Œæ€»å…¥å£ ï¼Œä¸è¿‡æ»¤äººå‘˜ï¼Œåªè¿‡æ»¤å…¬å¸
    * æŒ‡å®šè¦è¿‡æ»¤çš„ å…¬å¸å­—段  ä½¿ç”¨é»˜è®¤å…¬å¸å­—段进行过滤-org_level_uuid
    * @return
    */
   public  String getDataFilter();
   /**
    * èŽ·å–äººå‘˜çš„æ•°æ®æƒé™ï¼Œæ€»å…¥å£ ï¼Œä¸è¿‡æ»¤äººå‘˜ï¼Œåªè¿‡æ»¤å…¬å¸
    * @param org_fields   æŒ‡å®šè¦è¿‡æ»¤çš„公司字段,为空则,使用默认公司字段进行过滤-org_level_uuid
    * @return
    */
   public  String getDataFilter(String org_fields)
   /**
    * èŽ·å–äººå‘˜çš„æ•°æ®æƒé™ï¼Œæ€»å…¥å£ ï¼Œè¿‡æ»¤æŒ‡å®šäººå‘˜å­—段,使用默认公司字段进行过滤-org_level_uuid
    * @tableName äººå‘˜è¿‡æ»¤çš„表
    * @param staff_fields
    * @return
    */
   public  String getDataFilter(String tableName,String staff_fields)
   /**
    * èŽ·å–äººå‘˜çš„æ•°æ®æƒé™ï¼Œæ€»å…¥å£ ,人员 å…¬å¸åŒæ—¶è¿‡æ»¤
    * @param tableName   æŒ‡å®šæ˜¯å“ªå¼ è¡¨çš„æ•°æ® æƒé™è¿‡æ»¤
    * @param staff_fields æŒ‡å®šè¦è¿‡æ»¤çš„人员字段 ï¼Œä¸ºç©ºåˆ™ï¼Œä¸ç”¨äººå‘˜è¿‡æ»¤
    * @param org_fields   æŒ‡å®šè¦è¿‡æ»¤çš„ å…¬å¸å­—段,为空则,使用默认公司字段进行过滤-org_level_uuid
    * @return
    */
   public  String getDataFilter(String tableName,String staff_fields,String org_fields)
 40.关于流水号
    åªéœ€è¦åœ¨é…ç½®ä¸­é…ç½®æµæ°´å·,见表mrbase_sys_swift_config
   è¡¨ä¸­å­˜æ”¾æµæ°´å·çš„字段,必须在mrbase_sys_datamodel_field表中该字段的field_type=serialNumber ï¼Œç¤ºä¾‹è§test表
   ç•Œé¢è°ƒç”¨æŽ¥å£èŽ·å–ç¼–ç ï¼š/api/common/createSerialNumber,见测试类CodeTest,必传参数:serialNumberName,对应表流水号配置表中的swift_config_name字段值
   è¿”回json值中serialNumber的值即为生成的流水号
   å¦‚果界面没有调用接口生成编码,则可以在业务controller中可调以下代码获取
   String serialNumber=serialNumberService.createSerialNumber(serialNumberName);
   åœ¨æ–°å¢žçš„controller中调用,在底层Dao中的保存方法中获取获取的临时编码去验证是否被占用,占用则重新生成,保证唯一性
   æŽ¥
    é…ç½®æ”¯æŒæ ¼å¼ï¼š
     [YYYY]:年
     [MM] ï¼šæœˆ
     [DD] ï¼šæ—¥
     [COMPANY_NAME]:公司名称,对应org_level_name
     [COMPANY_CODE]:公司编码  org_level_code
     [DEPT_NAME]:部门名称org_level_name
     [DEPT_CODE]:部门编码org_level_code
41.接口签名认证
      ç³»ç»Ÿå‚数文件中可配置:
    #是否启用接口签名认证
   signature.isEnable=false
   #在启用接口签名认证时,排除指定接口无需签名认证
   signature.exclude.path=/login,/logout,/relogin
   #接口签名认证有效期,单位秒,签名认证有效期=空或0,则表示不验证
   signature.expire=10
   -------------
   ä½¿ç”¨MD5加密,加密内容:参数formData的值+KEY(单独指定)
   å‰ç«¯åŠ å¯†åŽçš„å­—ç¬¦ä¸²è¦å¤§å†™ï¼šsign=GEGSTLLSEGEL
   formData中要包含timestamp时间戳的值,格式为:yyyyMMddHHmmss
42.通用删除验证
   è°ƒç”¨ï¼š
      æ¨¡å— system
      ç±»     SystemDeleteValidationService
      æ–¹æ³• public  boolean  deleteValidation(String tableName, String uuids,String delete_filter) throws BaseException {
   å‚数说明:
       tableName删除数据表表名
       uuids要删除数据的uuid,多个用逗号分隔
       delete_filter删除条件  fields='name'
   è¿”回说明:
      éªŒè¯é€šè¿‡æ²¡æœ‰å…³è”任何数据返回true
      å‚数缺失返回false
      éªŒè¯æ²¡é€šè¿‡å…³è”了其他表数据抛出异常,异常信息中提示关联数据表,多个用逗号分隔
43.国际化
   label:
      ç”¨æˆ·ç™»å½•成功后,调接口:
      /api/language/load-international-info/{version}
      åŠ è½½æŒ‡å®šå®¢æˆ·ç«¯ã€ç‰ˆæœ¬å·ã€é»˜è®¤è¯­è¨€çš„æ‰€æœ‰å›½é™…åŒ–æ•°æ®
      å®¢æˆ·ç«¯ã€ç‰ˆæœ¬å·ã€é»˜è®¤è¯­è¨€æŽ¥å£å‚数上传
   value:
      1、首先配置表、字段为国际化字段
      2、前端调接口获取哪些表有哪些国际化字段,在界面的中对应元素后面添加地球图标,点图标弹出国际化录入
             æŽ¥å£:/api/language/list-international-fields-info/{version}
      3、新增保存数据json格式:
      {
      Â Â Â Â "token":"11111-新增提交数据",
      Â Â Â Â "system_language_code":"ZH",
      Â Â Â Â "system_client_type":"PC",
      Â Â Â Â "system_client_version":"iphome X 13.1.3",
      Â Â Â Â "app_version":"V2.0.0",
      Â Â Â Â "time_zone_offset":"240",
      Â Â Â Â "sign":"eyJhbGciOiJIUzI1N",
      Â Â Â Â "~table~":"mrbase_sys_users",
      Â Â Â Â "name":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "en":"internationalization"
      Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "zh":"国际化"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "address":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "en":"zhuhai"
      Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "zh":"珠海"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "phone":"18123938722",
      Â Â Â Â "sub_table_name":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "filed1":"value1",
      Â Â Â Â Â Â Â Â Â Â Â Â "filed2":"value2",
      Â Â Â Â Â Â Â Â Â Â Â Â "name":[
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "en":"internationalization"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "zh":"国际化"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
      Â Â Â Â Â Â Â Â Â Â Â Â ],
      Â Â Â Â Â Â Â Â Â Â Â Â "address":[
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "en":"zhuhai"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "zh":"珠海"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
      Â Â Â Â Â Â Â Â Â Â Â Â ]
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ]
      }
      4、查询列表数据
      é¦–先查询出所有业务数据,再调
      /**
       * ä¸šåŠ¡ä»£ç å±‚è°ƒç”¨
       * èŽ·å–ä¸šåŠ¡å¯¹åº”å­—æ®µçš„å›½é™…åŒ–æ•°æ®,如果language_code不为空,表明是手机端
       * @param dt ä¸šåŠ¡è¡¨æ•°æ®
       * @param language_code ä¸ä¸ºç©ºåˆ™ä¸ºæ‰‹æœºç«¯
       * @return
       */
      DataTableEntity baseDao.listInternationDataTable(DataTableEntity dt,String language_code ) å°è£…国际化数据到每条记录的每个国际化字段。
      FieldSetEntity  baseDao.listInternationDataTable(FieldSetEntity fs,String language_code )  å°è£…国际化数据到单条记录的每个国际化字段。
      //baseDao.processInternationDataTable(DataTableEntity dt,String language_code ),国际化字段不是数组格式
      //baseDao.processInternationDataTable(FieldSetEntity fs,String language_code ) å›½é™…化字段不是数组格式
      è¿”回json格式:
      {
      Â Â Â Â "code":"200",
      Â Â Â Â "data":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"100001",
      Â Â Â Â Â Â Â Â Â Â Â Â "name":[
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "en":"internat"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "zh":"国际化"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
      Â Â Â Â Â Â Â Â Â Â Â Â ],
      Â Â Â Â Â Â Â Â Â Â Â Â "address":[
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "en":"zhuhai"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "zh":"珠海"
      Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
      Â Â Â Â Â Â Â Â Â Â Â Â ],
      Â Â Â Â Â Â Â Â Â Â Â Â "phone":"18123938729"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "msg":"成功",
      Â Â Â Â "status":"success"
      }
      5、修改保存数据json格式:
      {
      Â Â Â Â "token":"11111-新增提交数据",
      Â Â Â Â "language_code":"zh",
      Â Â Â Â "client_type":"PC",
      Â Â Â Â "client_version":"iphome X 13.1.3",
      Â Â Â Â "app_version":"V2.0.0",
      Â Â Â Â "time_zone_offset":"240",
      Â Â Â Â "sign":"eyJhbGciOiJIUzI1N",
      Â Â Â Â "~table~":"mrbase_sys_users",
      Â Â Â Â "uuid":"100001",
      Â Â Â Â "name":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â "en":"internationalization"
      Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â "zh":"国际化"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "address":[
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â "en":"zhuhai"
      Â Â Â Â Â Â Â Â },
      Â Â Â Â Â Â Â Â {
      Â Â Â Â Â Â Â Â Â Â Â Â "uuid":"xxxxx",
      Â Â Â Â Â Â Â Â Â Â Â Â "zh":"珠海"
      Â Â Â Â Â Â Â Â }
      Â Â Â Â ],
      Â Â Â Â "phone":"18123938722"
      }
      6.不能国际化的表:
      mrbase_sys_cache_config ç¼“存配置
      mrbase_sys_data_sources æ•°æ®åº“连接配置
      mrbase_sys_datamodel_field æ•°æ®ç»“构字段信息
      mrbase_sys_datamodel_table æ•°æ®ç»“构表信息
      mrbase_sys_language_code
      mrbase_sys_language_cont_values
      mrbase_sys_language_master
      mrbase_sys_language_values
      mrbase_sys_message_exchange
      mrbase_sys_message_message_exchange
      mrbase_sys_message_template
      mrbase_sys_message_template_language
      mrbase_sys_message_user_exchange
      mrbase_sys_prompt
      mrbase_sys_swift_config
      mrbase_sys_tree_config
      mrbase_sys_version_buttons_mapping
      å®šæ—¶ä»»åŠ¡æ‰€æœ‰è¡¨
44.文件上传--第三方文件服务器
    1)获取客户上传的文件总大小:com.lx.base.file.service.FileManagerService
        /**
         * èŽ·å–å®¢æˆ·ä¸Šä¼ çš„æ–‡ä»¶æ€»å¤§å°
         * @param clientUUID        å®¢æˆ·UUID
         * @return                  å·²ä¸Šä¼ æ–‡ä»¶æ€»å¤§å°
         * @throws BaseException    åŸºæœ¬å¼‚常
         */
        public int findClientFileUsedCapacity(String clientUUID) throws BaseException
    2)获取客户剩余的文件总大小:com.lx.base.file.service.FileManagerService
        /**
         * èŽ·å–å®¢æˆ·å‰©ä½™çš„æ–‡ä»¶æ€»å¤§å°
         * @param clientUUID    å®¢æˆ·UUID
         * @return              å‰©ä½™ç©ºé—´å¤§å°
         */
        public int findClientFileResidueCapacity(String clientUUID) throws BaseException
        /**
         * èŽ·å–å®¢æˆ·å‰©ä½™çš„æ–‡ä»¶æ€»å¤§å°
         * @param fse           å®¢æˆ·fse
         * @return              å‰©ä½™ç©ºé—´å¤§å°
         */
        public int findClientFileResidueCapacity(FieldSetEntity fse) throws BaseException
    3)上传文件
        1>前端上传文件,返回文件信息给后端,调用请求前缀/api/fileManager/add-file-record-plan/{version},详情见showdoc中14-1、文件新增准备,后端返回fse
        ä¼ å…¥json示例:
        {
          "org_level_uuid": "b8631dad-6cc1-4d5a-9f6f-e8c76e6a5464",
          "~table~": "mrbase_sys_attachments",
          "attachment_title": "test_202006221036.doc",
          "client_uuid": "06f959c8-4f41-407c-9bcc-8137a8b22f50",
          "language": "mslc1112",
          "function_uuid": "97779f8b-9657-47e7-8915-2f51113210fe",
          "client_type": "web",
          "attachment_data_table": "test_project",
          "version": "v1",
          "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsImlhdCI6MTU5Mjc5MzY3OSwic3ViIjoic2hpX2Nob25nZnVAMTYzLmNvbSIsImlzcyI6Ind3dy5tcmMuY29tIiwiZXhwIjoxNTkyODY1Njc5fQ.kgffR0iYgjKhFSNI-ak5hPCf3453aOYXIrwHte7pRAY",
          "product_uuid": "001",
          "staff_uuid": "e2f158ec-a6c7-40e0-a201-4fd7eb2e0e98",
          "attachment_data_field": "attachment",
          "attachment_size": "1"
        }
        2>前端得到后端返回后拼接url,调用至服务器端上传文件,根据服务器端状态返回调用请求前缀/api/fileManager/add-file-callback/{version},详情见showdoc中14-2、文件新增结果回调。服务端新增成功本地执行修改,变更文件记录状态为上传成功,返回update;服务端新增失败本地执行删除,还原记录,返回del
        ä¼ å…¥json示例:
        {
          "result": "1",
          "uuid": "c48c0147-8b2f-4a8d-9d5b-46c55ceb725b",
          "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsImlhdCI6MTU5Mjc5NjMzNiwic3ViIjoic2hpX2Nob25nZnVAMTYzLmNvbSIsImlzcyI6Ind3dy5tcmMuY29tIiwiZXhwIjoxNTkyODY4MzM2fQ.LiUeajNzZAHWuT5O_YdPh5IOp7geVjklBGrWUBz79fo"
        }
    4)删除文件
        1>前端删除文件,返回文件信息给后端,调用请求前缀/api/fileManager/del-file-record-plan/{version},详情见showdoc中14-3、文件删除准备,后端返回fse
        ä¼ å…¥json示例:
        {
          "uuid": "c48c0147-8b2f-4a8d-9d5b-46c55ceb725b",
          "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsImlhdCI6MTU5MjgwNDMyOSwic3ViIjoic2hpX2Nob25nZnVAMTYzLmNvbSIsImlzcyI6Ind3dy5tcmMuY29tIiwiZXhwIjoxNTkyODc2MzI5fQ.Fsau5aHByePG7E-p68Y8_Py6yGAcYwbxQLwhkz20MGQ"
        }
        2>前端得到后端返回后拼接url,调用至服务器端删除文件,根据服务器端状态返回调用请求前缀/api/fileManager/del-file-callback/{version},详情见showdoc中14-4、文件删除结果回调。服务端删除成功本地执行删除,返回del;服务端删除失败本地执行修改,还原文件记录状态,返回update
        ä¼ å…¥json示例:
        {
          "result": "0",
          "uuid": "c48c0147-8b2f-4a8d-9d5b-46c55ceb725b",
          "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsImlhdCI6MTU5MjgwNTg4OSwic3ViIjoic2hpX2Nob25nZnVAMTYzLmNvbSIsImlzcyI6Ind3dy5tcmMuY29tIiwiZXhwIjoxNTkyODc3ODg5fQ.0x7xmEM2G8qXq7jiYQiy6iDm48tYEqVS9UqhlHUB9xk"
        }
45.本地文件上传--系统服务器
    æ ¸å¿ƒï¼šéœ€è¦sigar-amd64-winnt.dll或者sigar-x86-winnt.dll文件置于jdk的bin中或者c盘windows/system32
   ä¸Šä¼ ç›®å½•配置,见properties文件中的upload.file。xxxx å‡ ä¸ªç›¸å…³å‚æ•°
   ä¸Šä¼ æ–‡ä»¶è‡ªåŠ¨å­˜åˆ°ç›®å½•ä¸‹ï¼Œåœ¨controller或service层中读取操作。
46.消息服务
    1.新建队列
     public static void createQueue(String queue_name)
     æ— è¿”回值
    2.删除队列
     public static void deleteQueue(String queue_name)
     æ— è¿”回值
    3.新建交换机
    messageService.addExchange
    å‚æ•°
    "exchange_uuid":"新建交换机"
    è¿”回值:交换机uuid
    4.绑定交换机
    messageService.bindExchange
    å‚数:
    {"user_uuid":"用户uuid",
    "exchange_uuid":"交换机uuid"}
    è¿”回值:Boolean
    5.解绑交换机
     messageService.unbindExchange
     å‚数:
     {"user_uuid":"用户uuid",
     "exchange_uuid":"交换机uuid"}
     è¿”回值:boolean
     6.添加消息且添加消息记录
     messageService.addMessage
     å‚数:
       {
       "exchange_uuid":"交换机uuid"
       "message_uuid":"用户uuid"
       "message":"消息内容"
       "template_id":"模板id"
       "create_by":"操作人uuid"
       "virtual_hosts":"虚拟机名"
        }
47.综合搜索:
    findService.listUuid
    å‚数:
    {
    ~table~:[“”,””,””,””]   //数据库表
    Conditions:[{condition:value},{},{}...]   //条件
    language:value    //国际化语言
    }
    è¿”回值:list<String> uuids
    å½“查询语名,使用多表联合查询,并使用了别名时,需要添加表别名、字段别名设置,并把sql语句使用select * from (查询语句+数据权限条件+高级查询条件)  b æ‹¬èµ·æ¥ï¼Œæ³¨æ„
 48.以下内容变更
 1.core包引入变更
<dependency>
   <groupId>com.lx</groupId>
   <artifactId>base-server-core</artifactId>
   <version>1.0.0-releases</version>
</dependency>
2.所有引入core包中类的路径含有全部替换成base,如:
import com.product..core.dao.BaseDao;    ->  import com.product.base.core.dao.BaseDao;
3.获取当前登录用户对应员工信息:
   æ”¹æˆgetCurrentStaff()  FieldSetEntity
4.获取当前登录用户对应员工所属公司信息
   getCurrentCompany()  FieldSetEntity
单独获取公司的uuid、org_level_name(公司名称) org_level_code(公司编码)
4.获取当前登录用户对应员工所属部门信息
   getCurrentDept()  FieldSetEntity
单独获取部门uuid
5.获取当前登录用户对应员工所属客户信息
   getCurrentCustomer()
单独获取客户uuid ã€å®¢æˆ·åç§°ã€å®¢æˆ·ç¼–码
6.获取当前登录用户对应管理员信息
   getCurrentManager()
7.获取查询数据集的所有uuid
   public String DataTableEntity.getUuids()  åŽŸ ï¼Œæ”¹ä¸ºä»¥ä¸‹
   æŒ‡å®šè¡¨çš„æ‰€æœ‰uuid,返回数组
   -> public Object[] getUuids(Object tableName)
   æŒ‡å®šè¡¨çš„æ‰€æœ‰uuid,返回逗号分隔的字符串
   -> public String getUuidsToString(Object tableName)
   è¿”回默认表的所有uuid,返回数组
   -> public Object[] getUuids()
   è¿”回默认表的所有uuid,返回逗号分隔的字符串
   -> public String getUuidsToString()
8.登录上传固定参数
   system_language_code è¯­è¨€ç¼–码 zh en
   system_client_type   å®¢æˆ·ç±»åž‹
   system_client_version ä»£ç ç‰ˆæœ¬
9.接口版本号大写V再加3个数字如下:
所有接口必须上传版本号
http://{IP}:{PORT}/{ProjectName}/api/app/homepage/get-home-page-list/v1 æˆ–v2
10.new FieldSetEntity()后,首先要设置表名,才能调setValue(String fieldName,Object fieldValue), å¦åˆ™åªèƒ½è°ƒsetValue(String fieldName,Object fieldValue,Object tableName)
11.public FieldSetEntity getLeaderStaff() throws BaseException  SystemUser.getLeaderStaff()获取当前人所直属领导信息
12.public FieldSetEntity getJobPost() throws BaseException   SystemUser.getJobPost()获取当前人所岗位信息
13.public DataTableEntity loadDirectSubordinate(String staffUuid) throws BaseException     StaffManagerService.loadDirectSubordinate()    èŽ·å–æŒ‡å®šäººå‘˜çš„ç›´æŽ¥ä¸‹å±ž
14.public DataTableEntity loadAllSubordinate(String staffUuid) throws BaseException   StaffManagerService.loadAllSubordinate()      èŽ·å–æŒ‡å®šäººå‘˜çš„æ‰€æœ‰ç›´æŽ¥ä¸‹å±ž
15.public FieldSetEntity loadStaffLeader(Integer userid)    StaffManagerService.loadStaffLeader()                                     èŽ·å–äººå‘˜çš„ç›´å±žé¢†å¯¼
16.public FieldSetEntity loadStaffLeader(String staffUuid)    StaffManagerService.loadStaffLeader()                                     èŽ·å–äººå‘˜çš„ç›´å±žé¢†å¯¼
17.查询出来的数据集DataTableEntity æˆ–FieldSetEntity ä¸­èŽ·å–åˆ°FieldMetaEntity,调public void addAliasField(String tableName_fieldName,String alias)添加查询中使用的国际化这段别名。
tableName_fieldName: è¡¨åä¸Žå­—段名组合,中间以点分隔  table.field
Alias: sql中对应的字段别名
18.如果多表联合查询,要取国际化值的表,必须取该表uuid字段,有重复uuid,自动添加别名,查询出来的uuid会在后面添加数据递增,如:uuid1,uuid2,第一个uuid不会变,如果要手动对重复的uuid取别名,也应按此规则进行,否则可能出现国际获取不到数据等情况
19.如果多表联合查询,其它字段重复与uuid重复类似,
多表联合查询,同一个表,同一个字段,使用两次,需要select * from () b æŠŠæŸ¥è¯¢ä¸»ä½“括起来同时表必须设置别名
20.FeildSetEntity中获取Object时有两个方法:getValue(String fieldName)和getObject(String fieldName),区别在于,getValue(String fieldName)会把国际化字段值转成JSONObject对象,而getObject(String fieldName)只是返回基础数据
48.手机端JSON数据格式的调用
   è¯­è¨€ç¼–码获取
   String language_code=reqp.getOther().get(com.lx.base.core.config.CmnConst.SYSTEM_LANGUAGE_CODE ).toString();
   String client_type=reqp.getOther().get(com.lx.base.core.config.CmnConst.SYSTEM_CLIENT_TYPE ).toString();
   æ•°æ®ä¿å­˜ï¼š
      baseDao.add(FieldSetEntityfse,String language_code);
      baseDao.add(FieldSetEntity fs,boolean subData,String language_code)
      baseDao.add(DataTableEntity fs,String language_code)
   æ•°æ®ä¿®æ”¹ï¼š
      baseDao.update(FieldSetEntity fs,String language_code)
        baseDao.update(FieldSetEntity fs,boolean subData,String language_code)
       baseDao.update(DataTableEntity fs,String language_code)
       æ•°æ®æŸ¥è¯¢ï¼š
          FieldSetEntity listInternationDataTable(FieldSetEntity fs,String language_code )
          DataTableEntity listInternationDataTable(DataTableEntity dt,String language_code )
49.后端错误信息国际化
   1)错误信息枚举类注入,启动类中添加注入代码:
   DataPoolCacheImpl.getInstance()
         .appendErrorEnumClass("com.lx.base.core.config.ErrorCode")
         .appendErrorEnumClass("com.lx.base.module.sys.config.SystemCode")
         .appendErrorEnumClass("com.lx.base.module.sys.config.SystemErrorCode");
   2)特殊情况调用(AbstractBaseController.error()、BaseException.getMessage()、getMessageInfo()已实现)
   String message=DataPoolCacheImpl.getInstance().getErrorLanguageInternation(code, language_code);
50.高级参照数据返回规则
    1)所有单位高级参照数据 f1 å…¨ç§° f2 çŸ­ç¼–码
    2)所有部门高级参照数据 f1 å…¨ç§° f2 çŸ­ç¼–码
    3)所有岗位高级参照数据 f1 å…¨ç§°
    4)所有岗位等级高级参照数据 f1 ç­‰çº§çº§åˆ« f2 ç»„名
    5)所有模块高级参照数据 f1 çŸ­ç¼–码
    6)所有功能高级参照数据 f1 çŸ­ç¼–码
    7)所有客户高级参照数据 f1 çŸ­ç¼–码
51.高级参照配置
    æ•°æ®æºè¡¨å­—段更改为后端接口,从DataPoolCacheImpl.getInstance().getCacheData("所有表信息");中获取所有表
    è¡¨åˆ«åï¼šä»¥ "a"+table_id为表别名
    é‡å¤å…³è”表配置:SystemPromptService.getPromptRepetitionJoinTable() ï¼Œåœºæ™¯ å…¬å¸ join éƒ¨é—¨ ã€å‘˜å·¥join下属
    å…³è”类型 left join  , inner join , right join
    å•表:
        æ•°æ®æºè¡¨å¤šå‡ºåˆ«å
        å­—段:表别名 "."字段名
    å¤šè¡¨
        is_multiple = 1
        relate_filter(多表关联条件)
        relate_type(关联类型)
        åœ¨é€‰æ‹©äº†æ•°æ®æºè¡¨  a ï¼Œb, c , d表别名分别为 a1,a2,a3,a4
        å…³è”类型= left join(根据业务需求定,目前只能选择1种关联方式)
        å¤šè¡¨å…³è”条件 = a1.uuid=a2.uuid,a3.uuid=a1.uuid,a2.uuid=a4.uuid å¤šä¸ªè¡¨çš„关联条件 ç”¨ "," åˆ†éš”,
        å¤šè¡¨å…³è”条件填写顺序应与表顺序对应不可颠倒
        æ¯ä¸ªè¡¨å…³è”必须在对应的一组关联条件中用到   è¡¨åˆ«å"."字段
        é”™è¯¯ç¤ºèŒƒï¼šâ€œa1.uuid=a2.uuid,a3.uuid=a1.uuid”  ï¼Œé«˜çº§å‚照表关联个数与条件个数不匹配
52.功能权限验证
   å¿…须配置mrbase_sys_function_buttons.api_url配置按钮对应后端接口地址,多个逗号分隔,不能含版本号,如:
   æŽ¥å£åœ°å€ï¼š/api/management/delete-user/v1 é…ç½®åœ°å€ï¼š/api/management/delete-user
53.数据操作权限验证
   ä¸»è¦é’ˆå¯¹å•条数据的删 ã€æ”¹ ã€æŸ¥æ“ä½œï¼Œåœ¨åˆ  ã€æ”¹ ã€æŸ¥çš„相应接口调用
   å¿…须设置mrbase_sys_datamodel_field.field_type,userid:存放人员的字段类型,orgUuid:存放组织机构的字段类型
   1)Controller接口层调用
   2)调法
      /**
       * å¯¹å•条数据进行操作的权限验证
       * @param tableName è¡¨å
       * @param uuid uuid
       * @param type éªŒè¯ç±»åž‹ 1=人员验证 2= ç»„织机构验证 3 ä¸¤è€…都验证
       * @return
       */
      public boolean validDataPermission(String tableName,String uuid ,int type)
      /**
       * å¯¹å•条数据进行操作的权限验证
       * @param fs  ä¸Šä¼ æ•°æ®ï¼Œå¿…须包含表名 uuid ,否一律通过
       * @param type éªŒè¯ç±»åž‹ 1=人员验证 2= çº§ç»‡æœºæž„验证 3 ä¸¤è€…都验证
       * @return
       */
      public boolean validDataPermission(FieldSetEntity fs ,int type)
      /**
       * å¯¹å•条数据进行操作的权限验证 ,特殊权限条件 ï¼Œä¸æ ¹æ®äºº ç»„织机构过滤
       * @param tableName è¡¨å
       * @param uuid uuid
       * @param filter ç‰¹æ®Šæƒé™æ¡ä»¶
       * @return
       */
      public boolean validDataPermission(String tableName,String uuid,String filter)
      /**
       * å¯¹å•条数据进行操作的权限验证 ,特殊权限条件 ï¼Œä¸æ ¹æ®äºº ç»„织机构过滤
       * @param fs  ä¸Šä¼ æ•°æ®ï¼Œå¿…须包含表名 uuid ,否一律通过
       * @param filter ç‰¹æ®Šæƒé™æ¡ä»¶
       * @return
       */
      public boolean validDataPermission(FieldSetEntity fs ,String filter)
   3)数据操作的权限验证,特殊条件调用示例
   if(!permissionService.validDataPermission(fse, "(client_uuid is null or client_uuid='') or client_uuid='"
   +SpringMVCContextHolder.getCurrentUser().getClient_uuid()+"'")) {
      SpringMVCContextHolder.getSystemLogger().error(SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getValue(),
            SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getText());
      return this.error(SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getValue(), SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getText());
   }
   4)按人员、组织机构验证数据权限调用示例
      å¿…须设置mrbase_sys_datamodel_field.field_type,userid:存放人员的字段类型,orgUuid:存放组织机构的字段类型
      if(!permissionService.validDataPermission(fse,CoreConst.DATA_PERMISSION_VALID_TYPE_ALL)) {
         SpringMVCContextHolder.getSystemLogger().error(SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getValue(),
               SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getText());
         return this.error(SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getValue(), SystemErrorCode.SYSTEM_NOT_OPER_PERMISSION.getText());
      }
54.业务代码逻辑处理
   è§„则是业务代码类必须注册成spring的bean,被调用的方法只能有一个FieldSetEntity参数,里面封装业务代码中需要的值,如:
  public void addBalance(FieldSetEntity fs)
  {
    this.logger.info("   ");
    this.staffBusinessService.addBalance(fs);
    this.logger.info(" ");
  }
54.消息生成
   /**
    * ä¸æ”¯æŒæ‰‹æœºç«¯
    * æ‰€æœ‰åº”用服务生成消息调些方法去添加消息
    * æ ¹æ®message.server.ip参数判断是否等于127.0.0.1
    * æ˜¯ï¼šåˆ™ç›´æŽ¥è°ƒwriteUserMessage本机方法添加消息
    * å¦ï¼šåˆ™è°ƒæ¶ˆæ¯æœåŠ¡å™¨æŽ¥å£æ·»åŠ æ¶ˆæ¯
    * @param userids      æ¶ˆæ¯æŽ¥æ”¶äºº               å¿…å¡«
    * @param content      æ¶ˆæ¯å†…容                 ä¸å¿…å¡«
    * @param title        æ¶ˆæ¯æ ‡é¢˜                 å¿…å¡«
    * @param send_user_id æ¶ˆæ¯å‘送人               å¿…å¡«
    * @param message_type æ¶ˆæ¯ç±»åž‹                 å¿…å¡«
    * @param url         æ¶ˆæ¯é“¾æŽ¥åœ°å€             ä¸å¿…å¡«
    * @param source_table ä¸šåŠ¡æ•°æ®è¡¨               ä¸å¿…å¡«
    * @param source_uuid  ä¸šåŠ¡æ•°æ®è¡¨uuid           ä¸å¿…å¡«
    * @param create_by    åˆ›å»ºäºº       userid      å¿…å¡«
    * @param is_send_mail æ˜¯å¦å‘送邮件 0:否 1:是   å¿…å¡«
    * @param is_send_sms  æ˜¯å¦å‘送短信 0:否 1:是   å¿…å¡«
    */
   WebsocketMesssageServiceThread.getInstance().appendMessage(String ....);
   /**
    * æ”¯æŒæ‰‹æœºç«¯ï¼Œæ–¹æ³•重载,多了一个mobile_url参数
    * æ‰€æœ‰åº”用服务生成消息调些方法去添加消息
    * æ ¹æ®message.server.ip参数判断是否等于127.0.0.1
    * æ˜¯ï¼šåˆ™ç›´æŽ¥è°ƒwriteUserMessage本机方法添加消息
    * å¦ï¼šåˆ™è°ƒæ¶ˆæ¯æœåŠ¡å™¨æŽ¥å£æ·»åŠ æ¶ˆæ¯
    * @param userids      æ¶ˆæ¯æŽ¥æ”¶äºº
    * @param content      æ¶ˆæ¯å†…容
    * @param title        æ¶ˆæ¯æ ‡é¢˜
    * @param send_user_id æ¶ˆæ¯å‘送人
    * @param message_type æ¶ˆæ¯ç±»åž‹
    * @param url         æ¶ˆæ¯é“¾æŽ¥åœ°å€
    * @param source_table æ•°æ®è¡¨
    * @param source_uuid  æ•°æ®è¡¨uuid
    * @param create_by    åˆ›å»ºäºº
    * @param is_send_mail æ˜¯å¦å‘送邮件
    * @param is_send_sms  æ˜¯å¦å‘送短信
    * @param mobile_url   æ‰‹æœºç«¯URL
    * @throws BaseException
    */
   WebsocketMesssageServiceThread.getInstance().appendMessage(String ....);
   //消息类型
   //表名常量定义
   public static final int MESSAGE_TOP_TYPE_SYSTEM =1; //"系统消息";
   public static final int MESSAGE_TYPE_ANNOUNCEMENT =11; //"公告消息";
   public static final int MESSAGE_TOP_TYPE_TASK =2; //"任务消息";
   public static final int MESSAGE_TYPE_APPROVE =21; //"待办消息";
   public static final int MESSAGE_TYPE_COORDINATION =22; //"协同消息";
    public static final int MESSAGE_TYPE_TASK = 23;// "任务模块消息";
   public static final int MESSAGE_TOP_TYPE_WARNING =3; //"预警消息";
   public static final int MESSAGE_TYPE_WARNING =31; //"预警消息";
55.子表排序规则,中括号内表示子表排序 æ”¾åˆ°orderby参数中
String s="main_field1,main_field2,{sub_table1:sub_table1_field1 desc,sub_table1_field2},{sub_table2:sub_table2_field1 desc,sub_table2_field2}"
56.错误信息中的动态变量替换
替则使用{}把变量名括起来,此变量名将在Exception中获取:DATA_VERIFY_UNIQUE_ERROR("数据不是唯一:{value}", ModuleEnum.CORE.getValue() + "097"),
示例:
   be.setMessagePara("fieldxxxx","未获取到登录Token信息");
   be.setMessagePara("fieldxxxx",fs.getString("field"));
"fieldxxxx"对应错误定义中的{fieldxxxx}
56.反射引用bean :com.product.core.util.ReflectUtil
   /**
    *
    * @param beanName è¢«ä»£ç†å¯¹åƒbean åç§°
    * @param methodName æ–¹æ³•名称
    * @param objects  å‚æ•°
    * @return
    * @throws BaseException
    */
   public static  Object invoke(String beanName,String methodName,Object[] objects) throws BaseException
57.产生消息的表,必须在对应表的produce_msg字段中值为1
58.自动发起流程
    com.lx.tool.flow.service.FlowService#autoSendFlow
    æè¿°ï¼š
        ï¼ˆ1)service方法,非接口方法
        ï¼ˆ2)根据传入的参数,自动发起流程,创建流程的第一步,直接到【开始】环节
    ä¼ å…¥å‚数:fse
        {
            "type_code": "5a1dd74e-5b69-479c-afa0-a7db3e7fd6b2",
            "~table~": "lx_oa_conference_apply",
            "accepters": "376",
            "uuid": "5aadc03d-6ae3-470c-8507-4aaf660d9495",
            "flow_title": "6c测试自动发起流程"
        }
    å‚数描述:
        ï¼ˆ1)type_code:类型uuid,类型唯一识别
        ï¼ˆ2)~table~:业务表名
        ï¼ˆ3)accepters:接收人,只能为一个
        ï¼ˆ4)uuid:业务表uuid
        ï¼ˆ5)flow_title:流程标题
59.产中打包部署
   jar部署:打开工程的pom.mxl,右键->Run as -> Maven install->进入工程目录->target目录->copy æŠŠå®ŒåŒ…的工程jar,放到服务器的运行目录下的lib目录下(例如200上:D:\LXServer\product-server\lib)
   å‰ç«¯æ–‡ä»¶éƒ¨ç½²ï¼šè¿›å…¥lx-web并运行packed.bat,重新生成dist目录->进入dist目录copy除baseUrl.js以外的所有文件,放到服务器的运行目录下的web目录下。
   é‡å¯ï¼ˆè¿è¡Œæ¡Œé¢å¿«æ·é”®ï¼‰
60.分页查询sql
   select  '6973' as staff_uuid  è¿™ç§æ²¡æœ‰from的语句,要添加 from dual,否则分页查询会出错
61.查询单条记录,getFieldSet... ä¸Ž getFieldSetEntity...的区别: å‰é¢æ–¹æ³•在没有查到数据时返回不为空,后面方法在没有查到数据时返回null
62.配置报表
   å‡è®¾è¿‡æ»¤æ¡ä»¶ä¸º"start_time>=('2021-12-01 00:00:00','%Y-%m-%d %H:%i:%s')"
   {$$} ç±»åž‹ä¸º0,只取值,即为"2021-12-01 00:00:00"
   {^^} ç±»åž‹ä¸º1,取除开字段外的所有内容,即为">=('2021-12-01 00:00:00','%Y-%m-%d %H:%i:%s')"
   {&&} ç±»åž‹ä¸º2,取所有内容,包含字段,即为"start_time>=('2021-12-01 00:00:00','%Y-%m-%d %H:%i:%s')"
   [[]] è‹¥æ˜¯æ ¹æ®ä¸Šé¢çš„æ‰€æœ‰æ–¹å¼æ›¿æ¢ä¹‹åŽä¾ç„¶å­˜åœ¨ä»»æ„ä¸€ç§ï¼Œå‰”除包含在内的过滤条件
63.有未知错误写法
      catch (BaseException e) {
            throw e;
        }
        catch (Exception e) {
           BaseException be=new BaseException(FlowCode.SIGN_FAIL);
           //SIGN_FAIL("签章失败:{error}", ModuleEnum.ADMINISTRAT.getValue() + "080"),
           //原错误的信息作为参数传过去,一并显示
           be.setMessagePara("error", e.getMessage());
            throw be;
        }
64.数据建模规则
   å­—段显示名称,4-6个字,精练,描述才是写备注类型文字
   å­—段类型,用户选UserId,多人选UserIds,组织机构选orgUuid,多个选orgUuids,不能选String, ä¸»é”®pk,引用外键表字段选uuid
   æ˜¯å‚照的,一定要加上参照名,高级参照名和数据字典名,数据字典要加《xxx》来区分
   å¼•用外键表,一定要选,且对应的字段类型一定要是UUID