shichongfu
2023-05-20 83ba984df6f7572e2d5bf15ac656c746c9c25d82
项目开发说明文档
已添加3个文件
987 ■■■■■ 文件已修改
doc/系统设计 987 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/系统部署.docx 补丁 | 查看 | 原始文档 | blame | 历史
doc/错误代码详细说明.docx 补丁 | 查看 | 原始文档 | blame | 历史
doc/ϵͳÉè¼Æ
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,987 @@
版本控制:
    å½“前产品版本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')"
    [[]] è‹¥æ˜¯æ ¹æ®ä¸Šé¢çš„æ‰€æœ‰æ–¹å¼æ›¿æ¢ä¹‹åŽä¾ç„¶å­˜åœ¨ä»»æ„ä¸€ç§ï¼Œå‰”除包含在内的过滤条件
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;
        }
doc/ϵͳ²¿Êð.docx
Binary files differ
doc/´íÎó´úÂëÏêϸ˵Ã÷.docx
Binary files differ