版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

目录

类型基类简介
过滤条件DynamicConditionBase用于动态过滤条件
校验器DynamicCheckBase用于数据新增或编辑时的校验
模型插件BaseModelPlugIn用于数据新增或编辑的前后处理插件
list_pluginBaseListPlugIn用于对list接口返回的数据进行二次处理
动态ActionDynamicActionBase用于按钮中调用云函数
数据检查DynamicValidateCheckBase用于数据规范性的检查
报表公式BaseFormulaObject用于报表计算
薪酬公式BaseSalaryFormulaObject用于薪酬计算
社保公式BaseSocialFormulaObject用于社保计算
工作流云函数WorkFlowDynamicScriptBase用于工作流程
同步ThirdBaseUpdateObject
个性化短信服务MobileMessageServiceBase
休假标准公式

LeaveStandardCalcDynamicBase


公共个性化公式

BaseCustomerFormulaObject


其他

object


信息

在云函数中调用接口使用self.call_open_api('hcm.model.get',{'id'_:1,'model':'Employee'}) 或者 self.call_open_api({name='hcm.model.get','id'_:1,params='model':'Employee'})

下面的使用方式会报错:

self.call_open_api('hcm.model.get',{api_name='id'_:1,api_params='model':'Employee'})


1.过滤条件

1.名称命名规则

公司ID_condition_云函数名称  例如 127_condition_test

2.案例

代码块
class DynamicCondition(DynamicConditionBase):
    """
    用于列表添加动态过滤条件
    使用示例:"conditions": {"job_info.employee_category_id": "dynamic#employee_category_dynamic_condition"}
    """
    def condition(self, query_, field_, condition_context):
        result = self.call_open_api("hcm.model.list", param={"model": "emp_role_detail", "filter_dict": {
            "employee_id": self.plugin_context.employee.id}})['list']

        job_step_value = [0]
        if len(result) > 0:
            if result[0]['emp_type'] == 1:  # 是什么类型人员
                job_step_value = [546, 547, 548]
            elif result[0]['emp_type'] == 2:
                job_step_value = [549, 550, 551]
            else:
                job_step_value = [0]
        query_ = query_.filter(field_.in_(job_step_value))
        return query_


3.云函数测试参数

key含义案例
model模型Employee
state场景all
params参数

对应模型的获取list接口的参数

代码块
{"model":"Employee","filter_str":null,"filter_dict":{"is_child_include":true,"role":"cm-org-emp.emp","department.origin_id":{"child_include":12495124}},"page_index":1,"page_size":20,"extra_property":{"state":"all","sorts":[{"type":"asc","key":"number"},{"type":"asc","key":"orderno"}]}}


condition动态过滤


代码块
    "id": {
        "dynamic": {
            "name": "test",							//			云函数名称
            "params": {								//			云函数传递参数 通常在表单上使用
                "dynamic_job_id": "=dynamic_job_id"
            }
        }
    }
    }


virtual_employee_id
虚拟身份可指定人员,若未填写则默认为当前用户 

2.校验器

1.名称命名规则

DataChecker_xxx

2.案例

代码块
class EndBeginTimeChecker(DynamicCheckBase):
    """
    云函数校验器示例,在对象新增,修改时会校验
    """
    def check(self, info):
        result = {}
        result['success'] = True
        return result

3.云函数测试参数

key含义案例
model模型Employee
params参数对应模型的增加或编辑info的参数   {"info":{"name":"1"}}
virtual_employee_id虚拟身份可指定人员,若未填写则默认为当前用户 

3.模型插件

1.名称命名规则

2.案例

代码块
class ModelPlugInXXX(BaseModelPlugIn):
    """
    模型插件
    应用范围:create_data,edit_data,remove_data,remove_datas
    如果类型为pre,调用pre方法,类型为post,调用post方法
    """
    def pre(self, company_id, **kwargs):
        """
        Pre插件
        kwargs:经过转换的原函数调用参数,经过干预后,返回kwargs继续调用原函数
        """
        return kwargs
    
    def post(self, company_id, result,**kwargs):
        """
        Post插件
        result:原函数调用返回的结果,经过干预后,返回
        kwargs:原函数调用参数
        """
        return result


3.云函数测试参数

key含义案例
model模型Employee
params参数

编辑: 

代码块
{
    "id_": 2073,
    "info": {
        "company_id": 150,
        "outer_info": null,
        "operator_id": 319055,
        "operate_time": "2019-09-01 21:53:13",
        "name": "aaaa"
    }
}

新增: 

代码块
{
    "info": {
        "company_id": 150,
        "outer_info": null,
        "operator_id": 319055,
        "operate_time": "2019-09-01 21:53:13",
        "name": "aaaa"
    }
}


plugin插件

类型分为:pre_create_data,post_create_data,pre_edit_data,pre_edit_data 


代码块
{
    "key": "plugins",
    "type": "post_edit_data",
    "name": "plugins"
}


virtual_employee_id虚拟身份可指定人员,若未填写则默认为当前用户 


4.list_plugin

1.命名规则

2.案例

代码块
class ListPlugInXXX(BaseListPlugIn):
    """
    模型data list插件
    应用范围:对list接口返回的数据进行二次处理
    """
    def post(self, context, _list, _count, plugin_config, **kwargs):
        for _l in _list:
            _id = _l.get('id')
            _l['name']='aaaa'
            logging.info(_id)
        return _list, _count

3.云函数测试参数

key含义案例
model模型Employee
state场景all
params参数

对应模型的获取list接口的参数

代码块
{"model":"Employee","filter_str":null,"filter_dict":{"is_child_include":true,"role":"cm-org-emp.emp","department.origin_id":{"child_include":12495124}},"page_index":1,"page_size":20,"extra_property":{"state":"all","sorts":[{"type":"asc","key":"number"},{"type":"asc","key":"orderno"}]}}


list插件


代码块
{
    "key": "Employee_data_plugins",
    "name": "data_plugins"				//对应云函数的名称
}


virtual_employee_id
虚拟身份

可指定人员,若未填写则默认为当前用户 

5.动态Action

1.命名规则

公司ID_模型名称_云函数名称  例如 127_testModel_testAction

2.案例

代码块
class VirtualAction(DynamicActionBase):
    """
    动态Action方法,装成模型上的方法
    使用方法
    """

    def action(self, method_context, params):
        # raise NotImplementedError
        logging.info(method_context)
        logging.info("in method")
        logging.info(params)
        return params

3.云函数测试参数

key含义案例
model模型Employee
params参数


代码块
{
    "model": "testModel",		// 模型名称
    "action": "testAction",		// 云函数名称 
    "params": {}	  			// 	云函数接收参数
}


virtual_employee_id虚拟身份可指定人员,若未填写则默认为当前用户 

6.数据检查

1.命名规则

2.案例

代码块
class XXXXChecher(DynamicValidateCheckBase): 
    """
     数据检查,主要是检查数据逻辑关系是否有问题,返回值是 ['xxxxx1数据有问题','xxxx2数据有问题']     
""" 
    def check(self, **kwargs): 
        error_msg = [] 
        model = self.get_model('EmployeeEducation') 
        rows = self.db.query(model).filter(model.company_id == self.context.company.id).all() 
        emp_group = {} 
        for row in rows: 
            if len(emp_educations) == 0:     
            error_msg.append('人员:{}的最高学历为空'.format(emp)) 
            elif len(emp_educations) > 1:     
            error_msg.append('人员:{}的最高学历大于一个'.format(emp))  
        return error_msg

3.云函数测试参数

key含义案例
model模型Employee
params参数

云函数中接收的参数

virtual_employee_id虚拟身份可指定人员,若未填写则默认为当前用户 

7.报表公式

1.命名规则

FlexFormula_xxx

2.案例

代码块
class DynamicFunctionReport(BaseFormulaObject):
    """
    报表云函数
    """

    def do(self,dept_id):
        # 引入日志
        company_id = self.context.get('COMPANY_ID')
        return {}

3.云函数测试参数

key含义案例

报表过滤参数{"dept_id":1234}
params参数

云函数中接收的参数

virtual_employee_id虚拟身份可指定人员,若未填写则默认为当前用户 

8.薪酬公式

1.命名规则

SalaryFormula_xxx

2.案例

代码块
class BaseSalaryFormula(BaseSalaryFormulaObject):
    """
    薪酬公式云函数示例
    """
    def execute(self):
        _cache_key = 'my_cache_key'
        _cache = self.executor.context.get(_cache_key)
        if _cache is None:
            employee_ids = [_p.get('employee_id') for _p in self.context['profile_list']]
            #你的取数逻辑
            self.executor.context[_cache_key] = _cache
        _result = _cache.get(self.context['profile']['employee_id'], 0)
        return _result

3.云函数测试参数

key含义案例
profile_id社保档案ID
month期间对应的月份
params参数

云函数中接收的参数

virtual_employee_id虚拟身份可指定人员,若未填写则默认为当前用户 

9.社保公式

1.命名规则

SocialFormula__xxx

2.案例

代码块
class BaseSocialFormula(BaseSocialFormulaObject):
    """
    社保公式云函数示例
    """
    def execute(self):
        _cache_key = 'my_cache_key'
        _cache = self.executor.context.get(_cache_key)
        if _cache is None:
            employee_ids = [_p.get('employee_id') for _p in self.context['profile_list']]
            #你的取数逻辑
            self.executor.context[_cache_key] = _cache
        _result = _cache.get(self.context['profile']['employee_id'], 0)
        return _result

3.云函数测试参数

key含义案例
profile_id社保档案ID1234
month期间对应的月份
params参数

云函数中接收的参数

virtual_employee_id虚拟身份可指定人员,若未填写则默认为当前用户 

10.工作流云函数

1.命名规则

2.案例

代码块
class WorkFlowDynamicScriptHandle(WorkFlowDynamicScriptBase):
    def execute(self, **kwargs):
        """
        方案很合理可能多项目使用,可以联系下流程平台作为经典解决方案案例
        :param kwargs:
        :return:
        """
        #  1. 原则上禁止重复接口多次调用,禁止使用 for 循环调用接口 . (不得不多次调用除外)
        #  2. 尽量不使用 try,如果是校验可以 raise
        #  3. 云函数标准耗时原则耗时不超 1秒
        #  4. log 测试完成后需要移除
        return

3.云函数测试参数

key含义案例
params参数

云函数中接收的参数

virtual_employee_id虚拟身份可指定人员,若未填写则默认为当前用户 

11.同步

1.命名规则

third_data_sync_xxx(云函数里面的__third_type__)

Image Modified

12.个性化短信服务

待更新


13.公共个性化公式

命名规则:CommonFormula_xxx

案例:

xxx例如设置成GET_MES_D,则里面公式固定拼接成C_xxx, 其中:C_ 为平台公共个性化标识

...

取MES模型某车间,某天,某班组,某岗位的某指标的数值 模型: U_MES_XJ_FFJ_01   --------公式编辑器的注释内容
C_GET_MES_D($('档案参数.车间(工段)编号'),$('档案参数.日期'),$('档案参数.班组'),$('档案参数.岗位'),'淀粉投入量')------公式以及公式传参定义内容

'''

公式会自动进行参数解析,然后可以进行公式个性化的逻辑处理

代码块
class CommonFormulaGETMESD(BaseCustomerFormulaObject):
    """
    公共个性化公式云函数示例
    """

    def execute(self, u_department_code, u_date, u_team_name, u_post_name, u_assess_desc, **kwargs):
        """
        取MES模型某车间,某天,某班组,某岗位的某指标的数值 模型: U_MES_XJ_FFJ_01
        C_GET_MES_D($('档案参数.车间(工段)编号'),$('档案参数.日期'),$('档案参数.班组'),$('档案参数.岗位'),'淀粉投入量')
        """
        param = {
            'model': 'U_MES_XJ_FFJ_01',
            'filter_dict': {'u_date': u_date,
                            'u_post_name': u_post_name,
                            'u_department_code': u_department_code,
                            'u_team_name': u_team_name,
                            'u_assess_desc': u_assess_desc},
            'extra_property': {
                'only_list': True,
                'fields': [
                    {'field': ['u_quanity_num']}
                ]
            }
        }
        _list = CustomerUtil.call_open_api("hcm.model.list", param)["list"]
        if _list:
            result = _list[0]["u_quanity_num"]
        else:
            result = None
        return result

效果:

Image Modified

14.动态OpenAPI

1.新建私有动态API

如图所示

建议描述部分包含以下内容:

  1. 云函数实现的业务
  2. 云函数参数和返回结果的说明
  3. 测试参数 

 

 

2.测试私有动态API

3.使用方式

  1. 内部使用和标准的OPEN API无异
  2. 外部使用需要结合访问令牌使用, 如下
  3. 外部使用方式有两种, 如下
      
     

15.云函数工具类

1. DataUtil

  • convert_num_to_idid 

    作用:用于编码换取ID,解决云函数中写死固定编码而无法迁移问题(业务数据编码保证唯一)

    参数含义是否必需
    model_name
    模型名称(组织类OrgDepartment, OrgPosition...基于DepartmentHistory,流程Business,码表,实体模型均可以支持)
    模型名称
    num
    编码
    default
    默认值,当查询不到时如果存在默认值可以不抛出异常,返回设定的默认值
    可换取的模型类别: 
    • 组织岗位类('OrgDepartment', 'BaseDepartment', 'Department', 'OrgUnit', 'Unit', 'OrgPosition','Position')
      基于DepartmentHistory,返回origin_id,即组织ID,DepartmentHistory不支持获取本身原始ID行为。
    • 流程(Business),返回流程ID
    • 码表(common_basic_item_data.性别),返回码表ID
    • 实体(EmployeeCateory,  PositionStatus 等),返回实际数据ID


代码块
languagepy
themeRDark

...

title云函数事例
linenumberstrue
class TestNumToId(BasePrivateApiService):
    """
    动态私有OpenAPI
    使用方法
    """
    def execute(self, **kwargs):
        """
        参数:number
        default 设置为None时,如果编码换取不到ID时,程序不会抛出异常
        """
        

...

position_id = DataUtil.convert_num_to_id('OrgPosition', kwargs['number'], default=None)

...

 # 组织类,岗位ID
        employee_category_id = DataUtil.convert_num_to_id('EmployeeCategory', kwargs['number'], default=None) # 实体类,用工类型ID
        business_id = DataUtil.convert_num_to_id('Business', kwargs['number'], default=None) # 流程,流程ID
        item_id = DataUtil.convert_num_to_id('common_basic_item_data.性别', kwargs['number'], default=None) # 码表,代码项ID;如果是树形代码项,需要保证number唯一
		return 


2.CustomerUtil

  • call_open_api
    调用系统API

3.ModelUtil

HTML
<table>
    <thead>
        <tr>
            <th>方法</th>
            <th>描述</th>
        </tr>
    </thead>
    
    <tbody>
    <tr>
        <td>count</td>
        <td>分组统计数值
            :param model:
            :param filter_dict:
            :param state:
            :param fields:
            :param sorts:
            :param extra_property:
            :param query_str:
            :param filter_str:
            :param group_by:
            :param count_by:
            :param distinct_count_by:
            :param sum_by:
            :param avg_by:
            :param min_by:
            :param max_by:
            :param page_index:
            :param page_size:
            :return:
        </td>
    </tr>
    <tr>
        <td>count_value</td>
        <td>统计模型满足条件的个数,只有一个值
            :param model:
            :param filter_dict:
            :param state:
            :param fields:
            :param sorts:
            :param extra_property:
            :param query_str:
            :param filter_str:
            :return:
        </td>
    </tr>
    <tr>
        <td>create</td>
        <td>新增模型数据
            :param model:
            :param info:
            :param role:
            :return:
        </td>
    </tr>
    <tr>
        <td>create_batch</td>
        <td>批量新增模型数据
            :param model:
            :param info_list:
            :param role:
            :return:
        </td>
    </tr>
    <tr>
        <td>edit</td>
        <td>修改模型数据
            :param model:
            :param id_:
            :param info:
            :param role:
            :return:
        </td>
    </tr>
    <tr>
        <td>edit_batch</td>
        <td>批量修改数据
            :param model:
            :param edit_list:
            :param role:
            :return:
        </td>
    </tr>
    <tr>
        <td>get</td>
        <td>获取模型数据
            :param model_:
            :param id_:
            :param kwargs:
            :return:
        </td>
    </tr>
    <tr>
        <td>list</td>
        <td>获取列表满足条件的所有数据(数据量少的时候用)
            :param model:
            :param filter_dict:
            :param state:
            :param fields:
            :param fields_key: 直接传字段列表,这边直接进行切割,
            :param sorts:
            :param extra_property:
            :param query_str:
            :param filter_str:
            :param page_index:
            :param page_size:
            :return:
        </td>
    </tr>
    <tr>
        <td>list_ids</td>
        <td>获取列表满足条件的所有数据id,直接返回id列表
            :param model:
            :param filter_dict:
            :param state:
            :param fields:
            :param fields_key: 直接传字段列表,这边直接进行切割,
            :param sorts:
            :param extra_property:
            :param query_str:
            :param filter_str:
            :param page_index:
            :param page_size:
            :return:
        </td>
    </tr>
    <tr>
        <td>record</td>
        <td>日志记录
            日志查看页面:/common_model_list?model=DynamicLogRecord
            :param content: 内容
            :param category
            :param type_: 1正常 2 异常 3 成功
            :param enabled: 是否执行
            :return:
        </td>
    </tr>
    <tr>
        <td>remove</td>
        <td>删除数据
            :param model:
            :param id_:
            :param role:
            :return:
        </td>
    </tr>
    <tr>
        <td>remove_batch</td>
        <td>批量删除数据
            :param model:
            :param ids:
            :param role:
            :return:
        </td>
    </tr>
    <tr>
        <td>yield_count</td>
        <td>aggr接口分批获取,
            :param model:
            :param filter_dict:
            :param state:
            :param fields:
            :param sorts:
            :param extra_property:
            :param query_str:
            :param filter_str:
            :param group_by:
            :param count_by:
            :param distinct_count_by:
            :param sum_by:
            :param avg_by:
            :param max_by:
            :param min_by:
            :param page_size:
            :return:
        </td>
    </tr>
    <tr>
        <td>yield_list</td>
        <td>循环按分页取列表,每次返回一个list 迭代
            :param model:
            :param filter_dict:
            :param state:
            :param fields:
            :param fields_key: 接收fields key列表,['name','position.name']
            :param sorts:
            :param extra_property:
            :param query_str:
            :param filter_str:
            :param page_size:
            :return:
            示例: for group in yield_list:
        </td>
    </tr>
    </tbody>
</table>
<style type="text/css">
    table,
    td,
    th {
        border: 1px solid #000;
        border-collapse: collapse;
    }

    table td {
        white-space: break-spaces;
        padding: 8px 16px;
    }
    
    thead >tr {
        background: rgb(237 238 242);
        height: 32px;
        font-size: 18px;
    }

    tbody > tr:nth-of-type(even) {
        background-color: rgb(237 238 242);
    }
</style>
  1. CustomerUtil

...