Skip to main content

后端开发教程

触发器

一、介绍

触发器是在特定数据操作事件发生之前或之后执行的Java代码,例如在将对象记录插入数据库之前,或在删除记录之后。

1.进入触发器开发页面

  • 登录系统,点击右上角人头像,选择开发者平台按钮,此按钮目前只开放给管理员简档用户。
  • 选择左侧:扩展——》触发器

2.说明及语法介绍

  • 名称:汉字说明,触发器完成的功能
  • 触发对象:在什么对象上执行触发器操作
  • 触发时间:
    • beforeInsert:当新建、复制记录行满足触发器条件,执行触发器操作
    • beforeUpdate:编辑记录行满足触发器条件,执行触发器操作
    • beforeUpsert:新建和编辑、复制记录行满足触发器条件,执行触发器操作
    • beforeDelete:删除记录行满足触发器条件,执行触发器操作
    • afterInsert:新建、复制记录行满足触发器条件,执行触发器操作
    • afterUpdate:修改记录行满足触发器条件,执行触发器操作
    • afterUpsert:新建或编辑、复制记录行满足触发器条件,执行触发器操作
    • afterDelete:删除记录行满足触发器条件,执行触发器操作
    • afterInsertCommit:插入提交后,报错不会回滚
    • afterUpdateCommit:更新提交后,报错不会回滚
    • afterUpsertCommit:保存提交后,报错不会回滚
    • afterDeleteCommit:删除提交后,报错不会回滚
    • approval:审批
💡
注:before是本记录生成之前触发,after是本记录生成之后可以取到记录id进行其他相关列表的带值操作
  • 基本语法:
语法 返回值 含义
record_new.get("字段API") String 获取记录中字段的最新值
record_new.put("字段API","字段值") 为记录的某字段赋值
record_old.get("字段API") String 获取记录中字段的前一个值
record_old==null 可在触发时间=beforUpsert或afterUpsert时,识别为新建操作
trigger.addErrorMessage("提示内容") 在记录中保存前用于提示

3.如何创建触发器?

  • 创建触发器有如下二种方式创建:
    • 方法一:通过点击系统右上角 “ 齿轮设置图标 ” 进入系统管理后台,在扩展—》触发器—》点击 新建
    • 方法二:进入要创建触发器对象的后台设置,将滚动条下拉到最底部,可在触发器部分,点击 新建

4.案例

  • 案例1:
    • 查询赋值需求:将项目对象中的当前项目经理的邮箱信息带入本对象中
    • 触发事件:beforeUpsert
    • 代码逻辑:
String managerId=record_new.get("project_manager")==null?"":record_new.get("project_manager")+"";//获取字段新值
String managerId_old=record_old==null||record_old.get("project_manager")==null?"":record_old.get("project_manager")+"";//获取字段的前一个值
//项目经理字段新值和老值不相同时判定为该字段值发生改变,需重新查询用户表获取邮箱带到本记录中
if(!managerId.equals(managerId_old)){
  List<CCObject> userlist=cquery("User","id='"+managerId+"'");
  if(userlist.size()>0){
    String email=userlist.get(0).get("email")==null?"":userlist.get(0).get("email")+"";
    record_new.put("email",email);
  }
}
  • 案例2:
    • 复杂校验需求:项目经理不为空的时候,项目开始日期、项目结束日期必填
    • 触发时间:beforeUpsert
    • 代码逻辑:
String managerId=record_new.get("project_manager")==null?"":record_new.get("project_manager")+"";//获取字段新值
String start_date=record_new.get("start_date")==null?"":record_new.get("start_date")+""; //项目开始日期
String end_date=record_new.get("end_date")==null?"":record_new.get("end_date")+"";//项目结束日期
if(!"".equals(managerId)&&("".equals(start_date)||"".equals(end_date))){
   trigger.addErrorMessage("请填写项目开始日期及项目结束日期");
}

二、进阶:触发器

1.可以直接引用的参数:

   (UserInfo)userInfo 、(Map)record_old、(Map)record_new

  • 取记录值的时候直接get字段的API名称: record_new.get("name");

2.循环调用

触发器可以循环调用,循环次数限制为三次,如果超过三次系统将会出现错误提示!

  • 在客户的update触发器中更新业务机会,在业务机会的update触发器中更新客户同时又触发客户的update触发器,如果在触发器中不加条件控制,那么系统最多允许执行3次这样的循环调用!

3.触发器发邮件通知

SendEmail sendEmail = new SendEmail(userInfo);

sendEmail.sendMailFromSystem(
String []toAddress,
String []ccAddress,
String []bccAddress,
String subject,
String content,
boolean isText);

sendEmail.sendEmailNew(
String emailtemplateid,
String []toAddress,
String []ccAddress,
String []bccAddress,
String recordId);

4.获取邮件模板信息

 /**
  * lang:语言
  * emailtemplateid:邮件模板ID
  * id:记录id
  */
Map<String,String> m = this.getMessageByTemplateId(String lang,String emailtemplateid,String ...id)

// 邮件标题
m.get("subject");
// 邮件内容
m.get("context");
// 邮件类型是否文本
m.get("istext")

5.TimeUtil

  • 日期时间类型数据多时区支持。

由于java.util.Date和Calendar是基于本地时区的,因此在涉及到跨时区的数据处理时,可能会出现错误。为了解决这个问题,可以使用TimeUtil工具类中的getNowDate(userInfo)方法来获取当前时间。getNowDate(userInfo)方法会根据用户信息中的时区来获取当前时间,因此可以保证数据的准确性。

例如,在将日期保存到数据库时,可以将new Date()改为调用TimeUtil.getNowDate(userInfo):

TpSysTask task = new TpSysTask();
task.setBeginTime(TimeUtil.getNowDate(userInfo));
  • 使用SimpleDateFormat来对Date进行格式化时,应给SimpleDateFormat类实例设置时区,

例如:

SimpleDateFormat myDateFormat=new SimpleDateFormat("yyyy-MM-dd");
myDateFormat.setTimeZone(TimeUtil.getUserTimeZone(userInfo));
// 或者使用TimeUtil提供的工具方法获取实例
SimpleDateFormat myDateFormat=TimeUtil.getSimpleDateFormat("yyyy-MM-dd",userInfo);
  • 使用Calendar类处理日期时,应给Calendar实例设置时区,获取Calendar对象的方法可任选以下两种,
Calendar cal=Calendar.getInstance(TimeUtil.getUserTimeZone(userInfo))
Calendar cal=TimeUtil.getCalendar(userInfo);

6.CCService

  • 在类中使用CCService

在类中使用CCService类中的方法,需要先实例化CCService对象。实例化方法如下:

CCService cs = new CCService((UserInfo)userInfo);

6.1 新增记录:insert

新增记录时,使用CCObject对象,CCObject有两个构造方法:

  • 传入对象API名称,构造一个数据对象:
CCObject opp = new CCObject("Opportunity");
  • 传入对象API名称和共享标志,构造一个对象的共享表对象:
CCObject oppshare = new CCObject("Opportunity", CCObject.IS_SHARED);

给CCObject赋值时,可以直接使用中文字段名称,无需转换为API名称。要将CCobject保存到数据库,调用方法 cs.insert(opp)

💡
注意:ID,自动编号,创建人,创建时间等系统字段不需要赋值!

6.2 查询记录:cquery

查询记录时,使用cs.cquery方法。cs.cquery方法有三个重载方法:

  • 返回所有记录:
List<CCObject> opps = cs.cquery("Opportunity");
  • 按条件返回记录,支持常用的where条件:
List<CCObject> opps = cs.cquery("Opportunity", "khmc__c = '" + record_new.get("id") + "'");
  • 按条件返回并排序:
List<CCObject> opps = cs.cquery("Opportunity", "khmc__c = '" + record_new.get("id") + "'", "jine__c desc");
💡
注意:exp和ordering条件中的字段API名称后一定要加"__c"。

6.3 修改记录:update

修改记录时,使用cs.update方法。cs.update方法需要传入一个CCObject对象。

CCObject opp = cs.query("Opportunity", "id = '" + record_id + "'").get(0);

opp.put("name", "修改后的机会名称");

cs.update(opp);

6.4 删除记录:delete

删除记录时,使用cs.delete方法。cs.delete方法需要传入一个CCObject对象。

CCObject opp = cs.query("Opportunity", "id = '" + record_id + "'").get(0);

cs.delete(opp);

6.5 操作共享表:

  • 查询共享表
List<CCObject> cquery(String objectApiName,String expression,boolean isDataObject);isDataObject 需要传入 false;
  • 新增共享表记录:见新增记录。
  • 删除共享表
deleteShareObjectBySql(String objectApiName,String expression)
💡
注意:共享表的表达式中字段不需要加"__c"

6.6 使用自定义设置 customSetting

  • 查询“列表”类型的自定义设置数据,返回对应apiName的全部数据
Map map = cs.getListCustomSetting(String apiName);
  • 查询“列表”类型的自定义设置数据,返回对应apiName和Name的单条数据
Map map = cs.getListCustomSetting(String apiName, String Name);
  • 查询“层次结构”类型的自定义设置数据,返回对应apiName和权限(id为简档id或用户id)的单条数据
Map map = cs.getCustomSetting(String apiName, String id);

7.CCObject

  • 构造函数
// 构造一个数据对象,需传入对象API名称: 
CCObject opp = new CCObject("Opportunity");

// 构造一个对象的共享表对象,需传入对象API名称及共享标志: 
CCObject oppshare = new CCObject("Opportunity",CCObject.IS_SHARED);

// 给CCObject赋值直接用put,name 为对象的字段API名称
opp.put("name","value");

8.DevLogger

  • 使用自定义log日志 DevLogger
// 初始化日志类
DevLogger cclogger = new DevLogger(userInfo);
// 打印info级别日志
cclogger.devLogInfo(String log);
// 打印error级别日志
cclogger.devLogError(String log);
// 打印error级别异常日志
cclogger.devLogError(String log, Throwable throwable);