纷享销客自定义函数:实战100例(全网最全,持续更新...)

自定义函数是纷享低代码能力的实现方案,是纷享销客PaaS能力的重要组成部分,此文档主要提供纷享自定义函数实用案例,交流、咨询自定义函数、API接口相关问题:wangzhifeng@tongdog.com.cn

来源:纷享销客CRM 公共函数库

实战案例1:异步函数

//调用方函数,异步调用自定义控制器函数《funcCalled__c》,传递参数名:parameter,参数类型:map。
Map keyValue = [
"key1":"value1",
"key2":"value2"
]
 
Map param = [
"parameter":keyValue
]
def (error,result,errorMessage) = Fx.function.executeFunc("funcCalled__c",param)
Fx.log.info(result)
 
//被调用函数funcCalled__c,需要设置参数,参数类型为map,参数名称为parameter
//在被调用函数中执行异步逻辑
//log.debug(parameter);可以在被调用的函数中把传递过来的参数打印出来

实战案例2:时间、日期计算

//DateTime 同理,API 两个对象都有
Date date = Date.now()
 
//直接设置年月日,API 不会修改原始的调用对象,而是返回一个新日期对象
Date newDate = date.withYear(2019)
  .withMonth(1)
  .withDay(1)
   
//计算本月最后一天
//先设置月,日为下一个月的第一天,然后减去一天,就可以获得某一个月份最后一天
Date firstDayOfMonth = date.withMonth(date.getMonth() + 1).withDay(1) - 1.days
Fx.log.info(firstDayOfMonth)
  
//DateTimeDuration 持续时间类, 相比 1.months 1.days 1.hours 1.minutes 的区别是,可以使用计算出来的变量
//设置年
DateTimeDuration yearDuration = DateTimeDuration.Years(1)
//设置月
DateTimeDuration monthsDuration = DateTimeDuration.Months(1)
//设置日
DateTimeDuration dayDuration = DateTimeDuration.Days(1)
// 设置时
// DateTimeDuration.Hours(1)
// 设置分
// DateTimeDuration.Minutes(1)
// 日期支持加减
Date after = date - yearDuration - monthsDuration + dayDuration
Fx.log.info(after)

实战案例3:正则表达式

String text = "匹配字符"                //匹配的字符
def pattern = /^[\u4e00-\u9fa5_a-zA-Z0-9]+$/               //正则表达式,匹配中文字母和数字
 
 
//只包含任意英文大小写和数字的正则:/.*[a-z0-9A-Z].*/
//中文、英文、数字包括下划线:/^[\u4E00-\u9FA5A-Za-z0-9_]+$/
//手机号正则表达式 : /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
//匹配邮箱的正则表达式: /^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/
//匹配手机号码的正则表达式:/^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/
//匹配由英文字母[a-zA-Z]组成,但是不包含test这个字符串 /^((?!test)[A-Za-z])*$/
 
//匹配通过返回null
if(text =~ pattern){
  return null;
}else{
  //包含其他字符, 返回提示
  return Remind.Text("文本只支持输入中文,数字,下划线")
}

实战案例4:打包发送文件

def finish = false;
// 分页最大100条
def limit = 100;
// 要扫描的对象api
def objectApiName = 'object_zY5Ho__c';
// 对象上的图片字段api名称
def picFieldApidName = 'field_vm01M__c'
DateTime startDay = '2020-12-01 00:00'
DateTime endDay = '2021-01-01 00:00'
def startTime = startDay.toTimestamp()
def endTime = endDay.toTimestamp()
 
String nextPageDataId = null;
 
// 首次查询的筛选条件
def searchCondition = [
    ['create_time': Operator.GT(startTime)],
    ['create_time': Operator.LT(endTime)],
    ['life_status': Operator.EQ('normal')],
    [picFieldApidName: Operator.EXISTS(true)]
]
 
def files = []
// range最大为500次
Range range = Ranges.of(0, 499)
range.each {
    if (finish) {
        return;
    }
 
    def (Boolean error, QueryResult result, String errorMessage) = Fx.object.find(objectApiName, searchCondition, limit, 0)
    if(error){
        Fx.log.info('查询失败, 错误原因为' + errorMessage)
        finish = true;
        return
    }
 
    List dataList = result.dataList
    if(dataList.size() < limit){
        // 如果数据搞完了,就不再循环
        finish = true;
    }
 
    // 遍历处理数据
    dataList.each{ item ->
        Map objectData = item as Map
        // Fx.log.info(objectData)
        nextPageDataId = objectData['_id']
        // 把图片字段搞出来
        objectData[picFieldApidName].eachWithIndex { file, index ->
            def name = objectData['name'] as String
            def creators = objectData['created_by'] as List
            // 所属大区 field_2VGjO__c
            def region = objectData['field_2VGjO__c'] as List
            // Fx.log.info("name: $name, creators: $creators, region: $region")
            name = (creators[0] as String) + '_' + name + '_' + index
            //name = name + '_' + index
            Fx.log.info(name + ', ' + file)
            // 可以根据其他字段来构造打包文件的路径和名称
            // UserFile参数分别为:打包后的文件名、文件路径、文件后缀、文件打包后的包内存放路径
            def one = UserFile.of(name, file['path'] as String, file['ext'] as String, '/image/' + region[0])
            files.add(one)
        }
    }
 
    // 基于id做游标访问,这样是比较快的,对db压力小
    searchCondition = [
        ['_id': Operator.GT(nextPageDataId)],
        ['create_time': Operator.GT(startTime)],
        ['create_time': Operator.LT(endTime)],
        ['life_status': Operator.EQ('normal')],
        [picFieldApidName: Operator.EXISTS(true)]
    ]
}
Fx.log.info('发现文件数量:' + files.size())
Fx.log.info(files)
 
// 调用打包服务,这是异步的。成功后可以通知哪些用户进行下载。他们会收到企信通知,点击链接就可以下载了。
// 打包文件默认保存3天,过期会被删除
def (Boolean error,List data,String errorMessage) = Fx.file.packedFile(files, ['1002', '1000'])
if (error) {
Fx.log.info("打包错误," + errorMessage)
} else {
Fx.log.info(data)
}
 
return [:]

实战案例5:上传文件

def (Boolean error,HttpResult reuslt,String errorMessage) = Fx.http.get("https://img9.doubanio.com/view/photo/l_ratio_poster/public/p2633531206.jpg",null)
if(error){
    Fx.log.info("http 请求出错 : " + errorMessage)
    return null;
}
if( reuslt.statusCode != 200 ){
    Fx.log.info("http 响应错误 :" + reuslt.content)
}
 
//上传图片到文件服务器
byte[] bytes = reuslt.bytes
def uploadReusult = Fx.file.uploadFile("jpg",bytes.length, bytes)
if( uploadReusult[0]){
    Fx.log.info("上传图片错误 :" + uploadReusult[2])
    return null;
}
 
//将返回的路径更新到对象字段下
String path = uploadReusult[1]['path'] as String
List image = [["ext":"jpg","path":path,"filename":"文件名字","size":bytes.length]]
 
def ret = Fx.object.update("object_oMTq9__c","5f68bfb5325bc400018c61dc",["field_b9RGp__c":image])
Fx.log.info(ret)

实战案例6:查询出循环大批量数据,并且使用batch api

List searchCondition = []
Fx.log.info("查询条件为 :" + searchCondition)
//查询条件 要以id 进行排序,find默认的排序是最后修改时间,如果排序字段存在重复,数据库是不能保证每次查询出来顺序是一致的
//分页的时候可能会出现重复数据,导致执行遗漏。
Map orderBy = ["_id":-1]
 
boolean hasData = true
Integer limit = 100
//循环聚合所有数据
Map updateData = [:]
Range range =  Ranges.of(0,200)
range.each { i ->
  if(hasData == false){
    return
  }
   
  Integer skip = i * limit
  def(Boolean error,QueryResult result,String errorMessage) = Fx.object.find("object_tsfnr__c",searchCondition,orderBy,limit,skip)
  if(error){
    hasData = false
    Fx.log.info("查询失败" + "当前跳过的数量为 " + skip + "错误原因为" + errorMessage)
    return
  }
   
  //获取所有更新的数据,如果是预设对象,就在循环里面直接更新。
  List dataList = result.dataList
  if(dataList.size() < limit){
    hasData = false
  }
   
  //如果不需要合并数据,在这里就可以100条
  dataList.each{ item ->
    Map objectData = item as Map
    updateData.put(objectData._id,["field_SNdj9__c":"5f587913bb60d50001afffa1"])
  }
}
 
//极端情况,所有查询都失败了
if(!updateData){
  Fx.log.info("循环查询出来数据为空")
  return
}
 
//如果是自定义对象,直接调用批量更新即可,更新单次500条限制,所以我们拆分数据
List idList = updateData.keys() as List
List partitionList = Fx.utils.listPartition(idList,500)
 
partitionList.each{ item ->
  Map currentUpdateMap = [:]
  //根据id分批组装数据
  List ids = item as List
  ids.each{ id ->
    String stringId = id as String
    Map totalMap = updateData
    Map updateMap = totalMap[stringId] as Map
    currentUpdateMap.put(id,updateMap)
  }
         
  //获取这一批的数据,然后调用批量更新接口
  def updateResult = Fx.object.batchUpdate("object_tsfnr__c",currentUpdateMap)
  if(updateResult[0]){
    Fx.log.info("更新失败 原因为 " + updateResult[2])
  }else{
    Fx.log.info("更新成功")
  }
}
 
 
Fx.log.info("实际更新的数据为" + idList.size())

实战案例7:人员字段处理

// 人员字段 List<String> 里面是人员对象(PersonnelObj) 的员工ID(user_id)
//field_nzrcd__c 是人员字段,查询
 
def(Boolean findError,QueryResult findResult,String findErrorMessage) = Fx.object.find("object_L2k2I__c",[["field_nzrcd__c":Operator.IN("1000")]], 100,0)
if( findErrorMessage ){
  Fx.log.info("查询出错")
}else{
  Fx.log.info(findResult)
}
 
//更新, 如果企业开放了多个人员,否则List 里面也只有一个人员id
Map updateData = ["field_nzrcd__c":["1001","1002","1003"]]
def updateRet = Fx.object.update("object_L2k2I__c",context.data._id as String,updateData)
if( updateData[0] ){
  Fx.log.info("查询失败,原因为 :" + updateRet[2] )
}else{
  Fx.log.info(updateRet)
}
 
 
//新建传入的参数
def createResult = Fx.object.create("object_L2k2I__c",["name":"testCreate","field_nzrcd__c":["1001","1002","1003"]])
if( createResult[0] ){
  Fx.log.info("新建失败原因为" + createResult[2])
}else{
  Fx.log.info("新建后返回的数据" + createResult[1])
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值