后端SDK参考
CCObject
- java.util.HashMap
- com.g3cloud.platform.publik.CCObject
类说明(Class)
CloudCC对象类
构造方法(Constructors)
public CCObject()
public CCObject(String ccobj) // 指定对象 API 名称
public CCObject(String ccobj, String isShared) // 共享对象
常量
| 常量 | 值 | 说明 |
|---|---|---|
OBJECT_API |
"CCObjectAPI" |
对象 API Key |
IS_SHARED |
"isShared" |
共享标识 Key |
SUM |
"sum" |
汇总字段前缀 |
常用方法
| 方法 | 说明 |
|---|---|
getObjectApiName() |
获取对象 API 名称 |
put(String apiName, String value) |
设置字段值 |
putSumValue(String key, String val) |
设置汇总字段值 |
getSumValue(String key) |
获取汇总字段值 |
UserInfo
com.g3cloud.common.UserInfo
当前登录用户的会话信息,在触发器和自定义类中由平台注入。
常用方法
| 方法 | 返回类型 | 说明 |
|---|---|---|
getUserId() |
String | 用户 ID |
getOrgId() |
String | 组织 ID |
getRoleId() |
String | 角色 ID |
getProfileId() |
String | 简档 ID |
getLoginName() |
String | 登录名 |
getUserName() |
String | 用户姓名 |
getEmail() |
String | 邮箱 |
getTimeZone() |
String | 时区标识 |
getLanguage() |
String | 语言 |
getOrgName() |
String | 组织名称 |
isAdmin() |
boolean | 是否为管理员 |
isIspartner() |
boolean | 是否为合作伙伴用户 |
getDbIndex() |
String | 数据库分片索引 |
SendEmail
- java.lang.Object
- com.g3cloud.platform.common.service.emailservice
用于在触发器或自定义类中发送邮件。
构造方法
public SendEmail(UserInfo userInfo)
sendMailFromSystem
直接发送邮件(不依赖邮件模板)。
public boolean sendMailFromSystem(
String[] toAddress,
String[] ccAddress,
String[] bccAddress,
String subject,
String content,
boolean isText
)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| toAddress | String[] | 是 | 收件人地址数组 |
| ccAddress | String[] | 是 | 抄送人地址数组,无则传 new String[0] |
| bccAddress | String[] | 是 | 密送人地址数组,无则传 new String[0] |
| subject | String | 是 | 邮件标题 |
| content | String | 是 | 邮件正文 |
| isText | boolean | 是 | true = 纯文本;false = HTML 邮件 |
返回:boolean,true 表示发送成功。
示例
SendEmail sendEmail = new SendEmail(userInfo);
boolean result = sendEmail.sendMailFromSystem(
new String[]{"user@example.com"},
new String[]{"cc@example.com"},
new String[0],
"系统通知:订单处理完成",
"<h2>订单已完成</h2><p>您的订单 <b>#20251224001</b> 已成功处理。</p>",
false
);
sendEmailNew
使用邮件模板发送,支持模板变量自动合并。
public ServiceResult sendEmailNew(
String emailtemplateid,
String[] toaddress,
String[] ccaddress,
String[] bcaddress,
String id
)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| emailtemplateid | String | 是 | 邮件模板 ID |
| toaddress | String[] | 是 | 收件人地址数组 |
| ccaddress | String[] | 是 | 抄送人地址数组 |
| bcaddress | String[] | 是 | 密送人地址数组 |
| id | String | 是 | 关联记录 ID(用于模板变量合并) |
示例
SendEmail sendEmail = new SendEmail(userInfo);
ServiceResult sr = sendEmail.sendEmailNew(
"TPL_ORDER_DONE",
new String[]{"user@example.com"},
new String[0],
new String[0],
"a252025B79C1B99R62Nf"
);
DevLogger
com.cloudcc.core.DevLogger
运行日志采集工具,日志内容可在平台"开发日志"页面查看。
构造方法
public DevLogger(UserInfo userInfo)
方法
| 方法签名 | 说明 |
|---|---|
devLogInfo(String log) |
打印 INFO 级别日志 |
devLogError(String log) |
打印 ERROR 级别日志 |
devLogError(String log, Exception e) |
打印 ERROR 日志并附带异常 |
示例
DevLogger logger = new DevLogger(userInfo);
logger.devLogInfo("开始处理订单: " + orderId);
try {
// 业务逻辑
} catch (Exception e) {
logger.devLogError("处理订单失败: " + orderId, e);
}
TimeUtil
com.cloudcc.core.TimeUtil
时区感知的日期工具类。平台部署支持多时区,禁止直接 new Date(),统一使用此工具。
方法
getNowDate
获取当前时间(已按用户时区转换)。
public static Date getNowDate(UserInfo userInfo)
getSimpleDateFormat
获取已设置用户时区的 SimpleDateFormat 实例。
public static SimpleDateFormat getSimpleDateFormat(String format, UserInfo userInfo)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| format | String | 是 | "yyyy-MM-dd" |
日期格式 |
| userInfo | UserInfo | 是 | — | 用户对象 |
getUserTimeZone
获取用户时区对象。
public static TimeZone getUserTimeZone(UserInfo userInfo)
示例
// 获取当前时间
Date now = TimeUtil.getNowDate(userInfo);
// 格式化日期
SimpleDateFormat sdf = TimeUtil.getSimpleDateFormat("yyyy-MM-dd HH:mm:ss", userInfo);
String dateStr = sdf.format(now);
// Calendar 带时区
Calendar cal = Calendar.getInstance(TimeUtil.getUserTimeZone(userInfo));
ServiceResult
com.cloudcc.core.ServiceResult extends HashMap<String, Object>
CRUD 操作的统一返回对象。
| 方法 | 返回类型 | 说明 |
|---|---|---|
isSuccess() |
boolean | 是否操作成功 |
setSuccess(boolean) |
void | 设置成功标志 |
getId() |
String | 获取新增/修改记录的 ID |
getMessage() |
String | 获取错误消息 |
getRtnInfo() |
String | 获取返回信息 |
setRtnInfo(String) |
void | 设置返回信息 |
getRtnCode() |
String | 获取返回码 |
addErrorMessage(String) |
void | 写入错误消息并抛出异常 |
getString(String key) |
String | 获取 Map 中指定 key 的字符串值 |
CCService
构造方法
public CCService(UserInfo userInfo)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| userInfo | UserInfo | 是 | 当前执行用户信息,从上下文传入 |
第1章 数据查询 API
1.1 cquery — 基础查询
功能介绍
查询指定对象下的记录列表,不校验用户角色权限,直接走数据库查询。内部根据系统配置自动决定是否翻译多语言字段。
适用场景
触发器内部逻辑、后台计算、系统级数据同步等不需要权限控制的内部调用场景,性能优先。
方法签名
List<CCObject> cquery(String objectApiName, String expression)
List<CCObject> cquery(String objectApiName, String expression, String ordings)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称,如 "Account"、"Contact",标准对象 User 自动映射为 ccuser,Case 自动映射为 cloudcccase |
expression |
String | 是 | 查询条件,SQL WHERE 子句格式。查全部记录时可传 "1=1"。支持 =、!=、>、<、LIKE、IN、AND、OR 等标准 SQL 运算符 |
ordings |
String | 否 | 排序子句,格式为 ORDER BY 字段名 ASC|DESC,支持多字段排序 |
返回值
List<CCObject>:匹配的记录列表,无结果时返回空列表,不返回 null。
示例
// 查询状态为"启用"的客户
List<CCObject> activeAccounts = ccService.cquery("Account", "status__c = '启用'");
// 查询全部(使用恒真条件)
List<CCObject> allAccounts = ccService.cquery("Account", "1=1");
// 查询并按创建时间倒序
List<CCObject> sortedAccounts = ccService.cquery(
"Account",
"status__c = '启用'",
"ORDER BY createdate DESC"
);
// 读取字段值
for (CCObject obj : sortedAccounts) {
String id = (String) obj.get("id");
String name = (String) obj.get("name__c");
}
1.2 cqueryByFields — 指定字段查询
功能介绍
在条件查询基础上,限定只返回指定字段,减少数据传输量,提升查询性能。
适用场景
明确知道需要哪些字段时,优先使用此方法替代全字段 cquery,避免全字段返回造成的性能浪费。
方法签名
List<CCObject> cqueryByFields(String objectApiName, String expression, String fields)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称 |
expression |
String | 是 | 查询条件,无条件时传 "1=1" |
fields |
String | 是 | 逗号分隔的字段 API 名列表,id 字段始终会返回 |
返回值
List<CCObject>:只包含指定字段的记录列表。
示例
// 只返回 id、名称、电话三个字段
List<CCObject> list = ccService.cqueryByFields(
"Account",
"status__c = '启用'",
"id,name__c,phone__c"
);
for (CCObject obj : list) {
System.out.println(obj.get("name__c") + " - " + obj.get("phone__c"));
}
1.3 cqueryNoLang — 不翻译多语言查询
功能介绍
查询时跳过多语言字段翻译,直接返回字段存储值(如选项列表返回原始 key 而非翻译后的文本)。
适用场景
需要获取字段原始值(如数据迁移、后台逻辑比对、条件判断等),不希望被多语言翻译影响结果时使用。
方法签名
List<CCObject> cqueryNoLang(String objectApiName, String expression, String fields, String ordings)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称 |
expression |
String | 否 | 查询条件,传 null 则查全部 |
fields |
String | 否 | 指定返回字段,传 null 返回全部字段 |
ordings |
String | 否 | 排序子句,传 null 不排序 |
返回值
List<CCObject>:不含多语言翻译的原始数据列表。
示例
// 不翻译多语言,只返回 id 和 status__c 的原始值
List<CCObject> list = ccService.cqueryNoLang(
"Account",
"id = 'a001000001AbCdE'",
"id,status__c",
null
);
// status__c 返回原始 key,如 "Enable" 而非 "启用"
String rawStatus = (String) list.get(0).get("status__c");
1.4 cqueryWithRoleRight — 带权限查询
功能介绍
在查询前自动校验当前用户的对象权限、字段权限及记录级共享规则权限,只返回用户有权查看的数据。
适用场景
对外暴露的接口、用户主动触发的查询操作,凡是需要遵守数据权限的场景,必须使用此系列方法。
方法签名
// 重载1:基础带权限查询
List<CCObject> cqueryWithRoleRight(String objectApiName, String expression)
// 重载2:控制是否返回已删除记录
List<CCObject> cqueryWithRoleRight(String objectApiName, String expression, String isAddDeleteHttp)
// 重载3:指定返回字段
List<CCObject> cqueryWithRoleRight(String objectApiName, String expression, String isAddDeleteHttp, String fields)
// 重载4:完整参数(含多货币 + 多语言)
List<CCObject> cqueryWithRoleRight(String objectApiName, String expression, String isAddDeleteHttp, String fields, String iscurrency, String islang)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称 |
expression |
String | 是 | 查询条件,不传条件时传 "1=1" |
isAddDeleteHttp |
String | 否 | "true" 返回结果中包含删除权限标记;"false" 不包含,默认 "false" |
fields |
String | 否 | 指定字段,null 返回全部有权限的字段 |
iscurrency |
String | 否 | "true" 启用多货币 |
islang |
String | 否 | 语言码 |
返回值
List<CCObject>:仅包含当前用户有权查看的记录,无权限时返回空列表。
此方法会抛出 Exception,调用方需 try-catch 或声明 throws。示例
try {
// 带权限查询客户列表
List<CCObject> list = ccService.cqueryWithRoleRight(
"Account", "status__c = '启用'"
);
// 带权限 + 指定字段
List<CCObject> list2 = ccService.cqueryWithRoleRight(
"Account", "status__c = '启用'",
"false", "id,name__c,phone__c"
);
} catch (Exception e) {
// 处理权限异常
e.printStackTrace();
}
1.5 cqueryWithRoleRightNoLang — 带权限不翻译多语言查询
功能介绍
在带权限查询基础上,跳过多语言翻译,返回字段原始存储值。
适用场景
需要带权限控制且需要拿到字段原始值(如选项值比对、数据导出)的场景。
方法签名
List<CCObject> cqueryWithRoleRightNoLang(String objectApiName, String expression, String fields)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称 |
expression |
String | 是 | 查询条件 |
fields |
String | 否 | 指定返回字段,null 返回全部 |
示例
List<CCObject> list = ccService.cqueryWithRoleRightNoLang(
"Account", "id = 'a001000001AbCdE'", "id,status__c,type__c"
);
1.6 cqlQuery — CQL 语句查询
功能介绍
CloudCC Query Language(CQL)查询,类似 SQL,直接传入查询语句执行。支持单对象查询(返回 List<CCObject>)和多对象联查(返回 List<Map>)。
适用场景
复杂联查、需要精确控制 SQL 语句的场景,如跨对象关联查询等。
方法签名
// 单对象查询,返回 CCObject 列表
List<CCObject> cqlQuery(String objectApiName, String cql)
// 多对象联查,返回 Map 列表
List<Map> cqlQuery(String cql)
// 抛出异常版本(需要精确错误信息时)
List<CCObject> cqlQueryThrowException(String objectApiName, String cql)
// 含日志级别控制
List<CCObject> cqlQueryWithLogInfo(String objectApiName, String cql, String logLevel)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是(联查时不需要) | 主对象 API 名称,多对象联查时传逗号分隔的对象名,如 "Account,Contact" |
cql |
String | 是 | CQL 查询语句,语法参考 SQL SELECT,字段名使用对象字段 API 名 |
logLevel |
String | 否 | 日志级别,"DEBUG"、"INFO"、"ERROR" |
返回值
- 单对象:
List<CCObject> - 联查:
List<Map>,Map 的 key 为查询别名
注意:CQL 语句会经过合法性校验,禁止 DDL 操作(DROP、CREATE、ALTER 等),违反则返回 null 或抛出异常。示例
// 单对象 CQL 查询
List<CCObject> list = ccService.cqlQuery(
"Account",
"SELECT id, name__c, phone__c FROM Account WHERE status__c = '启用'"
);
// 多对象联查(联系人关联客户)
List<Map> list2 = ccService.cqlQuery(
"SELECT a.id, a.name__c, c.name__c AS contactName " +
"FROM Account a, Contact c " +
"WHERE a.id = c.accountid__c AND a.status__c = '启用'"
);
// 需要抛出异常时使用
try {
List<CCObject> list3 = ccService.cqlQueryThrowException(
"Account",
"SELECT id, name__c FROM Account WHERE id = 'xxx'"
);
} catch (Exception e) {
System.out.println("CQL 执行失败:" + e.getMessage());
}
1.7 pagedQuery — 分页查询
功能介绍
按页码和每页大小进行分页查询,不校验权限。
适用场景
列表页面的后端分页加载、批量数据处理分批读取等场景。
方法签名
// 基础分页
List<CCObject> pagedQuery(String objectApiName, String expression, String pageNUM, String pageSize)
// 带删除权限标记
List<CCObject> pagedQuery(String objectApiName, String expression, String pageNUM, String pageSize, String isAddDelete)
// 指定字段
List<CCObject> pagedQuery(String objectApiName, String expression, String pageNUM, String pageSize, String isAddDelete, String fields)
// 完整参数(含多语言)
List<CCObject> pagedQuery(String objectApiName, String expression, String pageNUM, String pageSize, String isAddDelete, String fields, String islang)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称 |
expression |
String | 是 | 查询条件,无条件时传 "1=1" |
pageNUM |
String | 是 | 当前页码,从 "1" 开始,传 String 类型 |
pageSize |
String | 是 | 每页记录数,如 "20"、"50",传 String 类型 |
isAddDelete |
String | 否 | "true" 附带删除权限标记 |
fields |
String | 否 | 指定返回字段 |
islang |
String | 否 | 语言码,如 "zh_CN" |
返回值
List<CCObject>:当前页的记录列表。
示例
// 基础分页,第1页,每页20条
List<CCObject> page1 = ccService.pagedQuery(
"Account", "status__c = '启用'", "1", "20"
);
// 第2页,带删除权限标记,指定字段
List<CCObject> page2 = ccService.pagedQuery(
"Account", "status__c = '启用'",
"2", "20",
"true",
"id,name__c,phone__c"
);
1.8 pagedQueryWithRoleRight — 带权限分页查询
功能介绍
分页查询 + 权限校验,只返回当前用户有权查看的分页数据。
适用场景
列表页面的分页加载,需要遵守数据权限(共享规则、角色层级)的场景。
方法签名
List<CCObject> pagedQueryWithRoleRight(String objectApiName, String expression, String pageNUM, String pageSize)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称 |
expression |
String | 是 | 查询条件 |
pageNUM |
String | 是 | 页码(从 "1" 开始) |
pageSize |
String | 是 | 每页记录数 |
示例
List<CCObject> page = ccService.pagedQueryWithRoleRight(
"Opportunity", "stage__c != '已关闭'", "1", "50"
);
1.9 getTotalRecordSize / pageQuery — 统计与简化分页
getTotalRecordSize — 获取记录总数
功能介绍
根据条件统计记录总数,用于分页时计算总页数。
方法签名
// 基础统计(不含已删除记录)
long getTotalRecordSize(String objectApiName, String expression)
// 控制是否包含已删除记录
long getTotalRecordSize(String objectApiName, String expression, String isAddDelete)
// 带权限统计(只统计当前用户有权查看的记录)
long getTotalRecordSizeWithRoleRight(String objectApiName, String expression)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称 |
expression |
String | 是 | 查询条件 |
isAddDelete |
String | 否 | "true" 统计时包含已软删除的记录 |
返回值
long:满足条件的记录总数。
示例
// 获取启用状态客户总数
long total = ccService.getTotalRecordSize("Account", "status__c = '启用'");
// 配合分页使用
int pageSize = 20;
long total2 = ccService.getTotalRecordSize("Account", "status__c = '启用'");
int totalPage = (int) Math.ceil((double) total2 / pageSize);
// 带权限统计
long myTotal = ccService.getTotalRecordSizeWithRoleRight(
"Opportunity", "stage__c != '已关闭'"
);
pageQuery — 简化分页(返回 Map)
功能介绍
分页查询的简化版本,直接返回包含 total(总数)和 list(当前页数据)的 Map,免去单独调用 getTotalRecordSize 的步骤。
方法签名
Map pageQuery(String objectApiName, String expression, String pageNUM, String pageSize)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称 |
expression |
String | 是 | 查询条件 |
pageNUM |
String | 是 | 页码(从 "1" 开始) |
pageSize |
String | 是 | 每页记录数 |
返回值
Map:包含以下两个 key:
total(long):满足条件的记录总数list(List<CCObject>):当前页的记录列表
示例
Map result = ccService.pageQuery("Account", "status__c = '启用'", "1", "20");
long total = (long) result.get("total");
List<CCObject> list = (List<CCObject>) result.get("list");
System.out.println("总记录数:" + total);
System.out.println("当前页记录数:" + list.size());
第2章 数据写入 API
2.1 insert — 基础新增
功能介绍
向指定对象新增一条记录。默认执行触发器(Before/After),不触发工作流,不校验权限,不执行校验规则和查重规则。
适用场景
触发器内部、后台系统级新增,性能优先且不需要权限检查的场景。
方法签名
// 标准新增(执行触发器,不执行工作流,不校验权限)
ServiceResult insert(CCObject ccobj)
// 批量新增(事务处理)
ServiceResult insert(List<CCObject> ccobjs)
// 完整参数控制
ServiceResult insert(CCObject ccobj, boolean isRight, boolean isWorkFlow,
boolean isBeforeTrigger, boolean isAfterTrigger,
boolean isValidAndDuplication)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
ccobj |
CCObject |
是 | 待新增的对象实例,需先设置对象 API 名,再 put 字段值 |
ccobjs |
List<CCObject> |
是(批量时) | 待新增的对象列表,在同一事务中批量执行 |
isRight |
boolean | 是 | true 校验用户操作权限;false 跳过权限校验 |
isWorkFlow |
boolean | 是 | true 新增后触发工作流;false 不触发 |
isBeforeTrigger |
boolean | 是 | true 执行 Before 触发器;false 跳过 |
isAfterTrigger |
boolean | 是 | true 执行 After 触发器;false 跳过 |
isValidAndDuplication |
boolean | 是 | true 执行校验规则和查重规则;false 跳过 |
返回值
ServiceResult:操作结果,调用 result.isSuccess() 判断是否成功,result.getId() 获取新记录 ID。
示例
// 构建对象
CCObject account = new CCObject("Account");
account.put("name__c", "测试公司");
account.put("phone__c", "13800000000");
account.put("status__c", "启用");
// 标准新增
ServiceResult result = ccService.insert(account);
if (result.isSuccess()) {
String newId = result.getId();
System.out.println("新增成功,ID:" + newId);
} else {
System.out.println("新增失败:" + result.getMessage());
}
// 完整控制参数(触发器中防递归:关闭所有开关)
ServiceResult result2 = ccService.insert(account,
false, // 不校验权限
false, // 不触发工作流
false, // 不执行 Before 触发器
false, // 不执行 After 触发器
false // 不执行校验规则
);
2.2 insertWithRoleRight — 带权限新增
功能介绍
新增前校验当前用户是否有对该对象的创建权限,执行触发器,不触发工作流。
适用场景
对外接口中用户主动创建记录的场景,需要遵守系统权限配置。
方法签名
ServiceResult insertWithRoleRight(CCObject ccobj)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
ccobj |
CCObject |
是 | 待新增的对象实例 |
示例
CCObject contact = new CCObject("Contact");
contact.put("firstname__c", "张");
contact.put("lastname__c", "三");
contact.put("accountid__c", "001000001AbCdEfGh");
ServiceResult result = ccService.insertWithRoleRight(contact);
if (result == null || !result.isSuccess()) {
throw new BusiException("创建联系人失败:" +
(result != null ? result.getMessage() : "未知错误"));
}
String contactId = result.getId();
2.3 insertWithWorkflow — 带工作流新增
功能介绍
新增记录后触发工作流规则,不校验权限,执行触发器。
适用场景
需要新增后自动触发工作流(如发送通知、创建任务、字段更新)的场景。
方法签名
ServiceResult insertWithWorkflow(CCObject ccobj)
示例
CCObject lead = new CCObject("Lead");
lead.put("firstname__c", "李");
lead.put("lastname__c", "四");
lead.put("leadsource__c", "网络");
ServiceResult result = ccService.insertWithWorkflow(lead);
2.4 insertLt — 轻量新增
功能介绍
跳过触发器(Before/After)和工作流的轻量级新增,不校验权限,不校验规则,直接写库。
适用场景
大批量数据导入、初始化数据填充等对性能要求极高且确定不需要触发器的场景。
方法签名
ServiceResult insertLt(CCObject ccobj)
注意:此方法跳过所有联动逻辑,慎用。若数据完整性依赖触发器,请使用 insert() 而非此方法。示例
CCObject obj = new CCObject("Product");
obj.put("name__c", "产品A");
obj.put("price__c", 100.00);
// 轻量写入,不触发任何联动
ServiceResult result = ccService.insertLt(obj);
2.5 insertWithValidationAndDuplication — 带校验规则+查重新增
功能介绍
新增时同时执行校验规则(Validation Rule)和查重规则(Duplication Rule),校验通过后才写库。
适用场景
业务数据录入时需要保证数据质量,执行平台配置的校验和查重规则。
方法签名
ServiceResult insertWithValidationAndDuplication(CCObject ccobj)
示例
CCObject account = new CCObject("Account");
account.put("name__c", "新公司");
account.put("phone__c", "400-123-4567");
ServiceResult result = ccService.insertWithValidationAndDuplication(account);
if (!result.isSuccess()) {
// 校验失败或查重命中
System.out.println("提示:" + result.getMessage());
}
2.6 insertNoException — 批量新增不抛异常
功能介绍
批量新增时,单条记录失败不中断整个批次,每条记录独立返回结果。
适用场景
导入场景中允许部分失败、需要逐条返回成功/失败结果的批量写入。
方法签名
ServiceResult insertNoException(List<CCObject> ccobjs)
返回值
ServiceResult:result.get("resultlist") 为 List<Map>,每条 Map 包含:
isSuccess(boolean):该条是否成功id(String):成功时的新记录 IDerrormessage(String):失败时的错误信息
示例
List<CCObject> objs = new ArrayList<>();
for (int i = 0; i < 100; i++) {
CCObject obj = new CCObject("Account");
obj.put("name__c", "公司" + i);
objs.add(obj);
}
ServiceResult result = ccService.insertNoException(objs);
List<Map> resultList = (List<Map>) result.get("resultlist");
long successCount = resultList.stream()
.filter(m -> Boolean.TRUE.equals(m.get("isSuccess")))
.count();
System.out.println("成功:" + successCount + " / " + objs.size());
2.7 upsert — 新增/更新二合一
功能介绍
根据 CCObject 中是否包含 id 字段自动路由:有 id 则更新,无 id 则新增。
适用场景
同步数据时不确定记录是否已存在,使用 upsert 简化逻辑判断。
方法签名
ServiceResult upsert(CCObject ccobj) // 标准版
ServiceResult upsertLt(CCObject ccobj) // 轻量版(跳过联动)
ServiceResult upsertWithRoleRight(CCObject ccobj) // 带权限版
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
ccobj |
CCObject |
是 | 若含 id 字段则更新该记录,否则新增 |
示例
CCObject account = new CCObject("Account");
// 场景1:更新(有 id)
account.put("id", "001000001AbCdEfGh");
account.put("name__c", "更新后的公司名");
// 场景2:新增(无 id)
// account.put("name__c", "全新公司");
ServiceResult result = ccService.upsert(account);
if (result.isSuccess()) {
String id = result.getId(); // 新增时返回新 ID,更新时返回原 ID
}
2.8 update — 基础更新
功能介绍
更新指定记录,CCObject 中必须包含 id 字段。默认执行触发器,不触发工作流,不校验权限。
方法签名
// 标准更新
ServiceResult update(CCObject ccobj)
// 完整控制参数
ServiceResult update(CCObject ccobj, boolean isRight, boolean isWorkFlow,
boolean isBeforeTrigger, boolean isAfterTrigger)
// 带校验规则 + 查重
ServiceResult update(CCObject ccobj, boolean isRight, boolean isWorkFlow,
boolean isBeforeTrigger, boolean isAfterTrigger,
boolean isValidAndDuplication)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
ccobj |
CCObject |
是 | 必须包含 id 字段,其余字段为待更新值 |
isRight |
boolean | 是(完整版) | 是否校验权限 |
isWorkFlow |
boolean | 是(完整版) | 是否触发工作流 |
isBeforeTrigger |
boolean | 是(完整版) | 是否执行 Before 触发器 |
isAfterTrigger |
boolean | 是(完整版) | 是否执行 After 触发器 |
isValidAndDuplication |
boolean | 否(完整版) | 是否执行校验规则和查重规则 |
示例
CCObject account = new CCObject("Account");
account.put("id", "001000001AbCdEfGh");
account.put("name__c", "新公司名称");
account.put("status__c", "禁用");
// 标准更新
ServiceResult result = ccService.update(account);
// 触发器中更新其他对象,关闭触发器防递归
CCObject related = new CCObject("Opportunity");
related.put("id", "006000001XyZaBc");
related.put("syncstatus__c", "已同步");
ccService.update(related, false, false, false, false);
2.9 updateWithRoleRight — 带权限更新
功能介绍
更新前校验当前用户是否有对该记录的编辑权限(包含对象权限和记录级权限),通过后执行更新。
方法签名
String updateWithRoleRight(CCObject ccobj)
返回值
String:"success" 表示成功,"failure:错误信息" 表示失败。
示例
CCObject obj = new CCObject("Contact");
obj.put("id", "003000001AbCdE");
obj.put("title__c", "技术总监");
String result = ccService.updateWithRoleRight(obj);
if (!"success".equals(result)) {
System.out.println("更新失败:" + result);
}
2.10 updateWithWorkFlow — 带工作流更新
功能介绍
更新记录后触发工作流规则,不校验权限,执行触发器。
方法签名
ServiceResult updateWithWorkFlow(CCObject ccobj)
示例
CCObject opp = new CCObject("Opportunity");
opp.put("id", "006000001AbCdE");
opp.put("stage__c", "已赢单");
ServiceResult result = ccService.updateWithWorkFlow(opp);
2.11 updateWithValidationAndDuplication — 带校验规则+查重更新
功能介绍
更新时执行校验规则和查重规则,不通过则返回失败信息。
方法签名
ServiceResult updateWithValidationAndDuplication(CCObject ccobj)
示例
CCObject account = new CCObject("Account");
account.put("id", "001000001AbCdE");
account.put("name__c", "可能重复的公司名");
ServiceResult result = ccService.updateWithValidationAndDuplication(account);
if (!result.isSuccess()) {
System.out.println("校验失败:" + result.getMessage());
}
2.12 delete — 删除
功能介绍
删除指定记录(软删除,移入回收站)。CCObject 中必须包含 id 字段。
方法签名
// 标准删除(不校验权限)
ServiceResult delete(CCObject ccobj)
// 带权限删除(返回 String)
String deleteWithRoleRight(CCObject ccobj)
// 批量删除(返回 boolean)
boolean delete(List<CCObject> ccobjs)
// 按条件删除共享记录
void deleteShareObjectBySql(String objectApiName, String expression)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
ccobj |
CCObject |
是 | 必须包含 id 字段 |
ccobjs |
List<CCObject> |
是(批量时) | 批量待删除对象列表,每条必须有 id |
返回值
ServiceResult:操作结果String(带权限版):"success"或错误信息boolean(批量版):是否全部成功
示例
// 删除单条记录
CCObject toDelete = new CCObject("Account");
toDelete.put("id", "001000001AbCdE");
ServiceResult result = ccService.delete(toDelete);
// 带权限删除
String delResult = ccService.deleteWithRoleRight(toDelete);
if (!"success".equals(delResult)) {
System.out.println("删除失败:" + delResult);
}
// 批量删除
List<CCObject> toDeleteList = new ArrayList<>();
for (String id : idList) {
CCObject obj = new CCObject("Contact");
obj.put("id", id);
toDeleteList.add(obj);
}
boolean success = ccService.delete(toDeleteList);
第3章 批量操作 API
3.1 batchInsert — 批量新增
功能介绍
在单个事务中批量新增多条记录,性能优于循环调用 insert(),失败时整体回滚。
方法签名
// 标准批量新增(不校验权限,执行触发器,不触发工作流)
ServiceResult batchInsert(List<CCObject> ccobjs)
// 完整控制参数
ServiceResult batchInsert(List<CCObject> ccobjs, boolean isRight, boolean isWorkFlow,
boolean isTrigger, boolean isValidAndDuplication)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
ccobjs |
List<CCObject> |
是 | 待新增的对象列表,同一对象类型 |
isRight |
boolean | 否 | 是否校验权限 |
isWorkFlow |
boolean | 否 | 是否触发工作流 |
isTrigger |
boolean | 否 | 是否执行触发器(Before + After) |
isValidAndDuplication |
boolean | 否 | 是否执行校验规则和查重规则 |
返回值
ServiceResult:整体操作结果,单条失败时整个事务回滚。
示例
List<CCObject> products = new ArrayList<>();
for (int i = 1; i <= 1000; i++) {
CCObject p = new CCObject("Product");
p.put("name__c", "产品" + i);
p.put("price__c", i * 10.0);
products.add(p);
}
// 批量新增(推荐,一次事务)
ServiceResult result = ccService.batchInsert(products);
if (result.isSuccess()) {
System.out.println("批量新增成功");
}
3.2 batchUpdate — 批量更新
功能介绍
在单个事务中批量更新多条记录,每条记录必须包含 id 字段。
方法签名
ServiceResult batchUpdate(List<CCObject> ccobjs)
ServiceResult batchUpdate(List<CCObject> ccobjs, boolean isRight, boolean isWorkFlow,
boolean isTrigger, boolean isValidAndDuplication)
入参说明
同 batchInsert,每条 CCObject 必须含 id 字段。
示例
List<CCObject> toUpdate = new ArrayList<>();
for (CCObject obj : queryResult) {
CCObject update = new CCObject("Account");
update.put("id", obj.get("id"));
update.put("syncstatus__c", "已处理");
toUpdate.add(update);
}
ServiceResult result = ccService.batchUpdate(toUpdate);
3.3 batchDelete — 批量删除
功能介绍
在单个事务中批量删除多条记录。
方法签名
ServiceResult batchDelete(List<CCObject> ccobjs)
ServiceResult batchDelete(List<CCObject> ccobjs, boolean isRight)
示例
List<CCObject> toDelete = objs.stream().map(obj -> {
CCObject d = new CCObject("TempRecord");
d.put("id", obj.get("id"));
return d;
}).collect(Collectors.toList());
ServiceResult result = ccService.batchDelete(toDelete);
3.4 insertWithRoleRightForBatch — 带权限批量新增(逐条返回结果)
功能介绍
带权限校验的批量新增,每条记录独立处理并返回结果,单条失败不影响其他记录。
方法签名
List<Map> insertWithRoleRightForBatch(List<CCObject> ccobjs)
// 完整控制
List<Map> insertForBatch(List<CCObject> ccobjs, boolean isRight, boolean isWorkFlow,
boolean isBeforeTrigger, boolean isAfterTrigger,
boolean isValidAndDuplication)
返回值
List<Map>:每条记录的处理结果,Map 包含:
isSuccess(boolean)id(String):成功时的新记录 IDerrormessage(String):失败时的错误信息
示例
List<Map> results = ccService.insertWithRoleRightForBatch(objs);
results.forEach(r -> {
if (Boolean.TRUE.equals(r.get("isSuccess"))) {
System.out.println("成功,ID:" + r.get("id"));
} else {
System.out.println("失败:" + r.get("errormessage"));
}
});
3.5 updateWithRoleRightForBatch — 带权限批量更新(逐条返回结果)
方法签名
List<Map> updateWithRoleRightForBatch(List<CCObject> ccobjs)
List<Map> updateForBatch(List<CCObject> ccobjs, boolean isRight, boolean isWorkFlow,
boolean isBeforeTrigger, boolean isAfterTrigger,
boolean isValidAndDuplication)
示例
List<Map> results = ccService.updateWithRoleRightForBatch(toUpdateList);
long failCount = results.stream()
.filter(r -> !Boolean.TRUE.equals(r.get("isSuccess")))
.count();
System.out.println("失败条数:" + failCount);
第4章 审批流程 API
4.1 submitForApproval — 提交审批
功能介绍
将指定记录提交到审批流程,触发审批流,向审批人发送待办通知。
方法签名
String submitForApproval(String relateId, String fprId, String appPath)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
relateId |
String | 是 | 待审批记录的 ID |
fprId |
String | 是 | 提交人(发起人)的用户 ID,通常为 userInfo.getUserId() |
appPath |
String | 是 | 审批流程入口路径,用于生成审批链接,通常传系统配置值 |
返回值
String:"success" 或错误信息。
示例
String recordId = "006000001AbCdEfGh";
String submitterId = userInfo.getUserId();
String appPath = "/approval/process";
String result = ccService.submitForApproval(recordId, submitterId, appPath);
4.2 process — 审批处理
功能介绍
处理审批工作项,支持通过、拒绝、转交等操作。
方法签名
String process(String processType, String workItemId, String fprId,
String comments, String appPath)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
processType |
String | 是 | 操作类型:"approve" 通过,"reject" 拒绝,"transfer" 转交 |
workItemId |
String | 是 | 审批工作项 ID(从待审批列表获取) |
fprId |
String | 是 | 操作人用户 ID |
comments |
String | 否 | 审批意见,可为 null |
appPath |
String | 是 | 审批流程路径 |
示例
// 通过审批
String result = ccService.process(
"approve",
"workitem001AbCdE",
userInfo.getUserId(),
"同意,质量符合标准",
"/approval/process"
);
// 拒绝审批
ccService.process("reject", workItemId, userId, "不符合要求,请修改后重新提交", appPath);
4.3 recall — 撤回审批
功能介绍
撤回已提交的审批申请,将审批状态重置为草稿。
方法签名
String recall(String relateId, String comments)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
relateId |
String | 是 | 被撤回的记录 ID |
comments |
String | 否 | 撤回原因说明 |
示例
String result = ccService.recall(
"006000001AbCdEfGh",
"发现数据填写有误,需要修改"
);
4.4 showPendingHis — 查询待审批列表
功能介绍
查询指定用户当前的待处理审批项目列表。
方法签名
List<Map> showPendingHis(String userId)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
userId |
String | 是 | 待审批用户 ID,传 null 或空字符串则使用当前用户 |
返回值
List<Map>:每条 Map 包含 objtype(对象类型)、objid(记录 ID)、objname(记录名称)、workItemid(工作项 ID)、comments(摘要)、actdate(提交时间)等字段。
示例
List<Map> pendingList = ccService.showPendingHis(userInfo.getUserId());
for (Map item : pendingList) {
System.out.println("记录:" + item.get("objname"));
System.out.println("工作项ID:" + item.get("workItemid"));
}
4.5 getApprovalPendingSize — 获取待审批数量
功能介绍
获取当前用户待处理的审批数量,通常用于首页待办角标。
方法签名
String getApprovalPendingSize()
返回值
String:待审批数量字符串,如 "5"。
示例
String count = ccService.getApprovalPendingSize();
System.out.println("待审批:" + count + " 条");
第5章 动态消息 Chatter API
5.1 addMicroPost — 发布动态
功能介绍
向 Chatter 动态流发布一条消息,支持纯文本、链接、附件、地理位置等多种内容类型。
方法签名
// 基础发布
String addMicroPost(String feedType, String linkName, String linkValue,
String fileName, String fileType, InputStream fileStream,
File file, String bodyType, String body,
String targetType, String targetId, String recordId)
// 带地理位置
String addMicroPost(String feedType, String linkName, String linkValue,
String fileName, String fileType, InputStream fileStream,
File file, String bodyType, String body,
String targetType, String targetId, String recordId,
String longitude, String latitude, String address,
String taskIdOrEventId)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
feedType |
String | 是 | 动态类型,纯文字传 "TextPost" |
linkName |
String | 否 | 链接名称,无链接传 null |
linkValue |
String | 否 | 链接 URL,无链接传 null |
fileName |
String | 否 | 附件文件名,无附件传 null |
fileType |
String | 否 | 附件 MIME 类型,如 "image/png" |
fileStream |
InputStream | 否 | 附件文件流,无附件传 null |
file |
File | 否 | 附件 File 对象,无附件传 null |
bodyType |
String | 是 | 内容类型,传 "text" |
body |
String | 是 | 动态正文内容 |
targetType |
String | 是 | 目标类型:"record" 关联记录,"user" 关联用户 |
targetId |
String | 是 | 目标 ID(记录 ID 或用户 ID) |
recordId |
String | 否 | 关联记录 ID |
longitude |
String | 否 | 经度 |
latitude |
String | 否 | 纬度 |
address |
String | 否 | 地理位置文字描述 |
taskIdOrEventId |
String | 否 | 关联任务或事件 ID |
返回值
String:新动态的 Feed ID。
示例
String feedId = ccService.addMicroPost(
"TextPost",
null, null,
null, null, null, null,
"text",
"这个机会已完成初步沟通,客户反馈积极!",
"record",
"006000001AbCdE",
"006000001AbCdE"
);
System.out.println("动态 ID:" + feedId);
5.2 addMicroComment — 发布评论
功能介绍
对已有动态发布评论,支持附带附件。
方法签名
String addMicroComment(String feedid, String fileName, String fileType,
InputStream fileStream, String body)
String addMicroComment(String feedid, String fileName, String fileType,
InputStream fileStream, String body,
String longitude, String latitude, String address)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
feedid |
String | 是 | 被评论的动态 Feed ID |
fileName |
String | 否 | 附件文件名,无附件传 null |
fileType |
String | 否 | 附件类型 |
fileStream |
InputStream | 否 | 附件流 |
body |
String | 是 | 评论内容 |
示例
String commentId = ccService.addMicroComment(
feedId,
null, null, null,
"已安排会议,下周一上午10点"
);
5.3 getChatters — 查询动态列表
功能介绍
查询动态流列表,支持按类型、记录、用户等维度过滤。
方法签名
List<Map> getChatters(String queryType, String userId, String feedid,
String recordId, String feedsort, String limit, String skip)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
queryType |
String | 是 | "all" 全部,"self" 当前用户发布的 |
userId |
String | 否 | 过滤指定用户的动态 |
feedid |
String | 否 | 过滤指定 Feed(用于获取评论) |
recordId |
String | 否 | 过滤关联指定记录的动态 |
feedsort |
String | 否 | 排序方式,"asc" 或 "desc" |
limit |
String | 是 | 最多返回条数 |
skip |
String | 是 | 跳过条数(分页偏移) |
示例
List<Map> chatters = ccService.getChatters(
"all",
null,
null,
"006000001AbCdE",
"desc",
"10",
"0"
);
5.4 praiseFeed — 点赞/取消点赞
方法签名
String praiseFeed(String feedid, String type, String iscomments)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
feedid |
String | 是 | 动态 Feed ID |
type |
String | 是 | "praise" 点赞,"cancel" 取消点赞 |
iscomments |
String | 是 | "true" 表示是对评论点赞,"false" 表示对动态点赞 |
示例
ccService.praiseFeed(feedId, "praise", "false");
ccService.praiseFeed(feedId, "cancel", "false");
第6章 文件操作 API
6.1 uploadFile / insertFile — 上传文件
功能介绍
上传文件到平台文件存储,返回文件 ID 用于后续关联。
方法签名
String uploadFile(Map fileInfo, InputStream inputStream)
String insertFile(Map fileInfo, InputStream inputStream)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
fileInfo |
Map | 是 | 文件元信息,包含 name(文件名)、type(MIME 类型)、size(文件大小,字节)、relatedId(关联记录 ID)等 |
inputStream |
InputStream | 是 | 文件输入流 |
返回值
String:上传成功后的文件 ID。
示例
Map<String, Object> fileInfo = new HashMap<>();
fileInfo.put("name", "合同附件.pdf");
fileInfo.put("type", "application/pdf");
fileInfo.put("size", fileBytes.length);
fileInfo.put("relatedId", "001000001AbCdE");
InputStream is = new ByteArrayInputStream(fileBytes);
String fileId = ccService.uploadFile(fileInfo, is);
System.out.println("文件 ID:" + fileId);
6.2 downloadFile / getFile — 下载文件
功能介绍
根据文件 ID 下载文件,返回包含文件流和文件名的 Map。
方法签名
Map downloadFile(String fileId)
Map getFile(String fileId)
返回值
Map:包含以下字段:
filename(String):文件名stream(InputStream):文件内容流type(String):MIME 类型size(Long):文件大小
示例
Map fileData = ccService.downloadFile("file_id_001AbCdE");
String filename = (String) fileData.get("filename");
InputStream stream = (InputStream) fileData.get("stream");
try (FileOutputStream fos = new FileOutputStream("/tmp/" + filename)) {
byte[] buffer = new byte[4096];
int len;
while ((len = stream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
6.3 queryFileList — 查询文件列表
功能介绍
按条件查询文件记录列表。
方法签名
List<Map> queryFileList(Map conditionMap)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
conditionMap |
Map | 是 | 过滤条件 Map,如 {"relatedId": "001xxx"} |
示例
Map conditions = new HashMap<>();
conditions.put("relatedId", "001000001AbCdE");
List<Map> files = ccService.queryFileList(conditions);
files.forEach(f -> System.out.println(f.get("name") + " - " + f.get("size")));
6.4 cqueryFileField — 查询文件字段
功能介绍
查询指定记录上某个文件字段包含的文件列表。
方法签名
List<CCObject> cqueryFileField(String recordId, String fieldApiName)
示例
List<CCObject> avatars = ccService.cqueryFileField(
"003000001AbCdE",
"avatar__c"
);
第7章 邮件 API
7.1 sendEmail — 发送邮件
功能介绍
发送邮件,支持模板邮件和自定义内容邮件,支持 CC/BCC/附件/开信追踪等能力。
方法签名
// 模板邮件
String sendEmail(String templateId, String toaddress, String ccaddress,
String bcaddress, String relatedid)
// 自定义内容(无 CC)
String sendEmail(String name, String htmlbody, String toaddress, String relatedid)
// 带 CC
String sendEmailWithccaddress(String name, String htmlbody, String toaddress,
String relatedid, String ccaddress)
// 带附件
String sendEmailWithAttachment(String name, String htmlbody, String toaddress,
String relatedid, Object attachment)
// 完整参数
String sendEmail(String name, String htmlbody, String toaddress, String relatedid,
String ccaddress, String bccaddress, Object attachment,
String istrackopen, String singleSend)
// 带 File 附件
ServiceResult sendEmailWithFile(String content, String subject, String toaddress,
String ccaddress, String bcaddress,
List<File> fileList, List<InputStream> inputList,
List<byte[]> byteList)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
templateId |
String | 是(模板版) | 邮件模板 ID |
name |
String | 是(自定义版) | 邮件主题 |
htmlbody |
String | 是(自定义版) | 邮件正文(支持 HTML) |
toaddress |
String | 是 | 收件人地址,多个用逗号分隔 |
ccaddress |
String | 否 | 抄送地址,多个用逗号分隔 |
bccaddress / bcaddress |
String | 否 | 密送地址 |
relatedid |
String | 否 | 关联记录 ID,邮件将归档到该记录 |
attachment |
Object | 否 | 附件对象 |
istrackopen |
String | 否 | "true" 追踪收件人是否开信 |
singleSend |
String | 否 | "true" 逐人单独发送(每封邮件只有一个收件人) |
返回值
String:"success" 或错误信息。
示例
String result = ccService.sendEmail(
"合同到期提醒",
"<h2>您好</h2><p>您的合同将于30天后到期,请及时续签。</p>",
"customer@example.com",
"contract_id_001"
);
String result2 = ccService.sendEmail(
"email_template_id_xxx",
"to@example.com",
"cc@example.com",
"bcc@example.com",
"lead_id_001"
);
String result3 = ccService.sendEmail(
"季度报告",
"<p>请查收本季度报告...</p>",
"manager@example.com",
"opportunity_id_001",
null, null, null,
"true",
"true"
);
7.2 queryEmailIn / queryEmailOut — 查询邮件记录
功能介绍
查询收件箱或发件箱中的邮件记录。
方法签名
List<Map> queryEmailIn(String startDate, String endDate)
List<Map> queryEmailIn(List<String> userIds, List<String> emails, String startDate, String endDate)
List<Map> queryEmailOut(String startDate, String endDate)
List<Map> queryEmail(String incoming, List<String> userIds, List<String> emails, String startDate, String endDate)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
startDate |
String | 是 | 开始时间,格式 "yyyy-MM-dd" |
endDate |
String | 是 | 结束时间,格式 "yyyy-MM-dd" |
userIds |
List | 否 | 过滤指定用户 ID 列表 |
emails |
List | 否 | 过滤指定邮件地址列表 |
incoming |
String | 是 | "1" 收件,"0" 发件 |
示例
List<Map> inbox = ccService.queryEmailIn("2026-04-01", "2026-04-30");
List<Map> outbox = ccService.queryEmailOut("2026-04-01", "2026-04-30");
第8章 视图操作 API
8.1 getViewList — 获取视图列表
功能介绍
获取指定对象下当前用户有权限访问的视图列表。
方法签名
List<Map> getViewList(String objectApiName)
List<Map> getViewListNew(String objectApiName)
示例
List<Map> views = ccService.getViewList("Account");
views.forEach(v -> System.out.println(v.get("id") + " - " + v.get("name")));
8.2 queryByViewId — 按视图查询数据
功能介绍
按视图 ID 查询数据,自动应用视图的过滤条件、字段显示配置、排序设置。
方法签名
Map queryByViewId(String viewId, String pages, String pageSize,
String sort, String dir, String keyWord, String fieldApis)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
viewId |
String | 是 | 视图 ID |
pages |
String | 是 | 页码(从 "1" 开始) |
pageSize |
String | 是 | 每页记录数 |
sort |
String | 否 | 排序字段 API 名 |
dir |
String | 否 | 排序方向:"ASC" 或 "DESC" |
keyWord |
String | 否 | 搜索关键词 |
fieldApis |
String | 否 | 指定返回字段,逗号分隔 |
返回值
Map:包含 total(总数)和 list(记录列表)。
示例
Map result = ccService.queryByViewId(
"view_id_001",
"1", "20",
"createdate", "DESC",
null, null
);
long total = (long) result.get("total");
List<CCObject> list = (List<CCObject>) result.get("list");
8.3 searchByViewId — 视图关键词搜索
功能介绍
在视图基础条件上叠加关键词搜索和自定义过滤条件。
方法签名
Map searchByViewId(String viewId, String pages, String pageSize, String sort,
String dir, String keyword, String fieldApis, String expression)
Map searchByViewId(String objid, String viewId, String pages, String pageSize,
String sort, String dir, String keyword, String fieldApis,
String expression)
示例
Map result = ccService.searchByViewId(
"view_id_001",
"1", "20", "createdate", "DESC",
"张三",
"id,name__c",
"status__c='启用'"
);
第9章 自定义设置 API
9.1 getListCustomSetting — 获取列表型自定义设置
功能介绍
获取在"自定义设置"(Custom Setting)中配置的参数值,支持列表型设置的全量获取和按 key 查询。
方法签名
Map getListCustomSetting(String objectApiName)
Map getListCustomSetting(String objectApiName, String key)
Map getCustomSetting(String objectApiName, String id)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 自定义设置对象的 API 名称 |
key |
String | 否 | 记录的名称(Name 字段值),不传则返回全部 |
id |
String | 是(按 ID 版) | 记录 ID |
返回值
Map:自定义设置的字段键值对。
示例
Map allConfig = ccService.getListCustomSetting("SystemConfig__c");
Map smtpConfig = ccService.getListCustomSetting("EmailConfig__c", "SMTP_SERVER");
String smtpHost = (String) smtpConfig.get("host__c");
int smtpPort = Integer.parseInt((String) smtpConfig.get("port__c"));
System.out.println("SMTP 地址:" + smtpHost + ":" + smtpPort);
第10章 工具方法 API
10.1 getPicklistValue — 获取下拉选项值
功能介绍
获取指定字段的下拉选项(Picklist)值列表,支持按记录类型过滤。
方法签名
List<Map> getPicklistValue(String objectApiName, String fieldApi, String recordtype)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
objectApiName |
String | 是 | 对象 API 名称 |
fieldApi |
String | 是 | 字段 API 名称 |
recordtype |
String | 否 | 记录类型 ID,null 返回所有选项 |
返回值
List<Map>:每条 Map 包含 value(选项值/key)和 label(显示文本)。
示例
List<Map> statusOptions = ccService.getPicklistValue(
"Account", "status__c", null
);
statusOptions.forEach(opt ->
System.out.println(opt.get("value") + " -> " + opt.get("label"))
);
10.2 getObjectRight — 获取对象操作权限
功能介绍
获取当前用户对指定对象的操作权限级别。
方法签名
String getObjectRight(String objectApiName)
返回值
String:权限标识,如 "Read"(只读)、"Edit"(可编辑)、"All"(全权限)、"none"(无权限)。
示例
String right = ccService.getObjectRight("Account");
if ("none".equals(right)) {
throw new BusiException("无客户对象操作权限");
}
10.3 getAccessToken — 获取当前用户 AccessToken
功能介绍
获取当前登录用户的 AccessToken,可用于 API 调用认证。
方法签名
String getAccessToken()
示例
String token = ccService.getAccessToken();
10.4 getCurrencyRateInfos — 获取多货币汇率
功能介绍
获取平台配置的所有货币及其对公司本位币的汇率信息。
方法签名
List<Map> getCurrencyRateInfos()
返回值
List<Map>:每条包含 currencyCode(货币代码如 "USD")、rate(汇率)、isActive(是否启用)等。
示例
List<Map> rates = ccService.getCurrencyRateInfos();
rates.forEach(r ->
System.out.println(r.get("currencyCode") + " : " + r.get("rate"))
);
10.5 executeAsyncJob — 执行异步任务
功能介绍
通过 MQ/调度器触发后台异步任务,适合将耗时逻辑从同步接口中剥离出来,避免请求超时。executeAsyncJob 主要用于常规异步方法调度;executeAsyncCustomClass 主要用于自定义类异步执行场景。
方法签名
ServiceResult executeAsyncJob(Map paramMap)
ServiceResult executeAsyncCustomClass(Map paramMap)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
paramMap.className |
String | 是 | 需要执行的类名 |
paramMap.methodName |
String | 是 | 需要异步执行的方法名 |
paramMap.name |
String | 否 | 任务名称;不传默认 className-methodName |
paramMap.executeDate |
Date | 否 | 执行时间;不传表示立即执行,传入表示定时执行 |
paramMap.ismq |
String | 否 | 是否直接投递 MQ,支持 "true"/"false";默认 "false" |
paramMap.queueName |
String | 否 | MQ 队列名;多队列隔离时建议指定 |
paramMap.<业务参数> |
Any | 否 | 业务自定义参数;会透传到异步执行上下文中 |
执行行为说明
- 未传
executeDate:立即执行。根据事务状态,任务可能先写入缓存,事务提交后再投递队列。 - 传入
executeDate:走调度中心注册任务,到达触发时间后执行。 - 使用
executeAsyncCustomClass:按定时任务方式注册,任务类型为自定义类异步任务。 - 环境需开启
cloudcc.schedule.async.enable=true,否则executeAsyncJob会返回失败。
返回值
ServiceResult:
success=true:提交成功(表示任务已入队或已注册,不代表业务方法已执行完成)。success=false:提交失败,可通过错误信息定位配置或参数问题。- 成功时可通过
result.get("taskId")或result.getRtnInfo()获取任务标识。
示例
Map params = new HashMap<>();
params.put("className", "AccountSyncJob");
params.put("methodName", "syncAccounts");
params.put("name", "Account增量同步");
params.put("ismq", "true");
params.put("queueName", "account.sync");
params.put("batchSize", 500);
params.put("operatorId", "005xxxxxxxxxxxx");
ServiceResult result = ccService.executeAsyncJob(params);
if (result.isSuccess()) {
System.out.println("异步任务已提交, taskId=" + result.get("taskId"));
} else {
System.out.println("提交失败: " + result.getErrorMessage());
}
定时执行示例
Map params = new HashMap<>();
params.put("className", "BillingJob");
params.put("methodName", "generateMonthlyBill");
params.put("name", "月度账单生成");
params.put("executeDate", new java.util.Date(System.currentTimeMillis() + 5 * 60 * 1000));
ServiceResult result = ccService.executeAsyncJob(params);
最佳实践
- 异步方法需保证幂等(可按业务主键或
taskId去重),避免重复消费造成脏数据。 - 大任务拆批执行,不要在单个异步任务中处理超大数据集。
- 关键链路建议记录
taskId,便于排障和日志追踪。 - 如果依赖数据库事务结果,优先在事务提交后再触发异步任务。
10.6 queryTianyancha — 天眼查企业信息
功能介绍
通过天眼查 API 查询企业工商信息,需要平台配置天眼查密钥。
方法签名
ServiceResult queryTianyancha(String searchword)
ServiceResult tianYanChaDetailInfo(String keyword, String id)
入参说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
searchword |
String | 是 | 企业名称或关键词 |
keyword |
String | 是 | 搜索关键词 |
id |
String | 是 | 天眼查企业 ID(从列表查询结果中获取) |
示例
ServiceResult searchResult = ccService.queryTianyancha("阿里巴巴");
ServiceResult detail = ccService.tianYanChaDetailInfo("阿里巴巴", "tianyancha_id_xxx");
附录A 最佳实践
A.1 触发器中防递归
在 After Trigger 中更新其他对象时,必须关闭触发器开关,防止触发再次调用触发器形成无限递归。
ServiceResult result = ccService.update(relatedObj,
false,
false,
false,
false
);
A.2 批量操作优先使用 batchInsert / batchUpdate
List<CCObject> objs = buildDataList();
ccService.batchInsert(objs);
A.3 查询只取需要的字段
List<CCObject> list = ccService.cqueryByFields(
"Account", "status__c='启用'", "id,name__c,phone__c"
);
A.4 对外接口必须使用 WithRoleRight 版本
List<CCObject> list = ccService.cqueryWithRoleRight("Account", expression);
ServiceResult result = ccService.insertWithRoleRight(obj);
A.5 upsert 简化新增/更新逻辑
CCObject obj = new CCObject("Account");
if (existingId != null && !existingId.isEmpty()) {
obj.put("id", existingId);
}
obj.put("name__c", "公司名称");
obj.put("status__c", "启用");
ServiceResult result = ccService.upsert(obj);
A.6 ServiceResult 标准判断写法
ServiceResult result = ccService.insertWithRoleRight(obj);
if (result == null || !result.isSuccess()) {
String msg = (result != null) ? result.getMessage() : "操作返回为空";
throw new BusiException("保存失败:" + msg);
}
String newId = result.getId();
A.7 CQL 查询安全注意事项
String name = userInput;
List<CCObject> list = ccService.cquery(
"Account",
"name__c = '" + name.replace("'", "\\'") + "'"
);
List<CCObject> list2 = ccService.cqueryByFields(
"Account", "name__c = '" + name + "'", "id,name__c"
);