-- ============================================= -- 钉钉开放平台初始化数据 -- -- 执行后需配置 token(OAUTH2 读取 token 列,非 api_key): -- UPDATE api_datasource_platform SET token = '你的oapi access_token' -- WHERE platform_code = 'dingtalk'; -- ============================================= -- 1. 创建钉钉平台 INSERT INTO api_datasource_platform ( tenant_id, creator, created_at, updater, updated_at, platform_code, platform_name, description, status, api_base_url, auth_type, auth_config, rate_limit_per_minute, rate_limit_per_hour, concurrency_limit, request_timeout_ms, max_retries, retry_delay_ms ) VALUES ( 1, 'admin', NOW(), 'admin', NOW(), 'dingtalk', '钉钉', '钉钉开放平台数据同步', 'ACTIVE', 'https://oapi.dingtalk.com', 'OAUTH2', '{ "token_in_query": true, "query_key": "access_token" }'::jsonb, 60, 3600, 5, 30000, 3, 1000 ); -- 2. 部门列表(递归遍历全量部门树) -- 先从根(不传 dept_id)获取一级部门,再对每个子部门递归调用获取下级 -- 请求:POST,access_token 在 URL 查询参数中 -- 响应:{"errcode":0,"errmsg":"ok","result":[{...}]} INSERT INTO api_interface ( tenant_id, creator, created_at, updater, updated_at, platform_id, name, code, url, method, status, auth_type, request_config, response_config, table_definition ) VALUES ( 1, 'admin', NOW(), 'admin', NOW(), (SELECT id FROM api_datasource_platform WHERE platform_code = 'dingtalk'), '部门列表', 'department_list', '/topapi/v2/department/listsub', 'POST', 'active', 'inherit', '{ "parameters_location": "query", "page_param": "cursor", "page_size_param": "pageSize", "language": "zh_CN", "recursive": { "key_field": "dept_id", "target_param": "dept_id" }, "max_recursive_depth": 20 }'::jsonb, '{ "success_field": "errcode", "success_value": 0, "message_field": "errmsg", "list_path": "result" }'::jsonb, '{ "table_name": "dingtalk_department", "columns": [ {"name": "dept_id", "type": "BIGINT", "comment": "部门ID"}, {"name": "name", "type": "VARCHAR(300)", "comment": "部门名称"}, {"name": "parent_id", "type": "BIGINT", "comment": "父部门ID"}, {"name": "create_dept_group", "type": "BOOLEAN", "comment": "是否同步创建关联企业群"}, {"name": "auto_add_user", "type": "BOOLEAN", "comment": "新人是否自动加入部门群"} ], "conflict_keys": ["dept_id"] }'::jsonb ); -- 3. 部门用户列表(prefetch→department_list,游标分页) -- 先递归获取全量部门树,再对每个部门分页拉取用户 -- dept_id 为必填,通过 prefetch 从部门列表注入 -- 响应:result.list(用户数组),result.has_more(是否还有更多),result.next_cursor(下一游标) INSERT INTO api_interface ( tenant_id, creator, created_at, updater, updated_at, platform_id, name, code, url, method, status, auth_type, request_config, response_config, table_definition ) VALUES ( 1, 'admin', NOW(), 'admin', NOW(), (SELECT id FROM api_datasource_platform WHERE platform_code = 'dingtalk'), '部门用户列表', 'user_list', '/topapi/v2/user/list', 'POST', 'active', 'inherit', '{ "parameters_location": "query", "page_param": "cursor", "page_size_param": "size", "cursor_pagination": true, "size": 100, "order_field": "modify_desc", "language": "zh_CN", "initial_cursor": 0, "prefetch": { "url": "/topapi/v2/department/listsub", "method": "POST", "response_path": "result", "target_param": "dept_id", "value_field": "dept_id" } }'::jsonb, '{ "success_field": "errcode", "success_value": 0, "message_field": "errmsg", "list_path": "result.list", "cursor_field": "result.next_cursor", "has_more_field": "result.has_more" }'::jsonb, '{ "table_name": "dingtalk_user", "columns": [ {"name": "userid", "type": "VARCHAR(100)", "comment": "用户userId"}, {"name": "unionid", "type": "VARCHAR(200)", "comment": "用户唯一标识"}, {"name": "name", "type": "VARCHAR(200)", "comment": "用户姓名"}, {"name": "avatar", "type": "TEXT", "comment": "头像地址"}, {"name": "state_code", "type": "VARCHAR(20)", "comment": "国际电话区号"}, {"name": "mobile", "type": "VARCHAR(50)", "comment": "手机号码"}, {"name": "hide_mobile", "type": "BOOLEAN", "comment": "是否号码隐藏"}, {"name": "telephone", "type": "VARCHAR(50)", "comment": "分机号"}, {"name": "job_number", "type": "VARCHAR(100)", "comment": "员工工号"}, {"name": "title", "type": "VARCHAR(200)", "comment": "职位"}, {"name": "email", "type": "VARCHAR(200)", "comment": "员工邮箱"}, {"name": "org_email", "type": "VARCHAR(200)", "comment": "企业邮箱"}, {"name": "work_place", "type": "VARCHAR(300)", "comment": "办公地点"}, {"name": "remark", "type": "TEXT", "comment": "备注"}, {"name": "dept_id_list", "type": "JSONB", "comment": "所属部门id列表"}, {"name": "dept_order", "type": "INT", "comment": "员工在部门中的排序"}, {"name": "extension", "type": "TEXT", "comment": "扩展属性"}, {"name": "hired_date", "type": "BIGINT", "comment": "入职时间"}, {"name": "active", "type": "BOOLEAN", "comment": "是否激活钉钉"}, {"name": "admin", "type": "BOOLEAN", "comment": "是否企业管理员"}, {"name": "boss", "type": "BOOLEAN", "comment": "是否企业老板"}, {"name": "leader", "type": "BOOLEAN", "comment": "是否部门主管"}, {"name": "exclusive_account", "type": "BOOLEAN", "comment": "是否企业账号"} ], "conflict_keys": ["userid"] }'::jsonb ); -- 4. 考勤数据查询(单个用户单日,prefetch→user_list) -- 需先同步 user_list 获取全量用户,再对每个用户调用此接口查询考勤数据 -- userid 通过 prefetch 从 user_list 注入,work_date 固定为当天日期 -- 响应:result 对象(包含 attendance_result_list/check_record_list/approve_list 等) -- 注意:当前代码支持两级 prefetch 链(即本接口 prefetch→user_list, -- user_list 自有 prefetch→department_list),但 user_list 的 dept_id 依赖 -- 在作为 prefetch 来源时不会自动解析。若需全量同步所有用户的考勤数据, -- 建议先手动同步 user_list 和 department_list,再同步此接口。 -- 使用前请将 work_date 更新为目标日期,如 '2026-06-03' INSERT INTO api_interface ( tenant_id, creator, created_at, updater, updated_at, platform_id, name, code, url, method, status, auth_type, request_config, response_config, table_definition ) VALUES ( 1, 'admin', NOW(), 'admin', NOW(), (SELECT id FROM api_datasource_platform WHERE platform_code = 'dingtalk'), '考勤数据查询', 'attendance_getupdatedata', '/topapi/attendance/getupdatedata', 'POST', 'active', 'inherit', '{ "parameters_location": "query", "prefetch": { "url": "/topapi/v2/user/list", "method": "POST", "response_path": "result.list", "target_param": "userid", "value_field": "userid" }, "work_date": "2026-06-03" }'::jsonb, '{ "success_field": "errcode", "success_value": 0, "message_field": "errmsg", "list_path": "result", "single_record": true }'::jsonb, '{ "table_name": "dingtalk_attendance", "columns": [ {"name": "userid", "type": "VARCHAR(100)", "comment": "用户userId"}, {"name": "work_date", "type": "VARCHAR(30)", "comment": "查询日期"}, {"name": "corpId", "type": "VARCHAR(100)", "comment": "企业corpId"}, {"name": "attendance_result_list", "type": "JSONB", "comment": "打卡结果列表"}, {"name": "check_record_list", "type": "JSONB", "comment": "打卡详情列表"}, {"name": "approve_list", "type": "JSONB", "comment": "审批单列表"}, {"name": "rest_time_vo_list", "type": "JSONB", "comment": "班次内休息信息"}, {"name": "rest_end_time", "type": "BIGINT", "comment": "休息结束时间"}, {"name": "rest_begin_time", "type": "BIGINT", "comment": "休息开始时间"} ], "conflict_keys": ["userid", "work_date"] }'::jsonb ); -- 5. 角色列表(偏移量分页,offset/size + hasMore) -- 响应:result.list(角色组数组),result.hasMore(是否还有更多) -- 每个角色组内包含 roles 数组({id, name})你 INSERT INTO api_interface ( tenant_id, creator, created_at, updater, updated_at, platform_id, name, code, url, method, status, auth_type, request_config, response_config, table_definition ) VALUES ( 1, 'admin', NOW(), 'admin', NOW(), (SELECT id FROM api_datasource_platform WHERE platform_code = 'dingtalk'), '角色列表', 'role_list', '/topapi/role/list', 'POST', 'active', 'inherit', '{ "parameters_location": "query", "page_param": "offset", "page_size_param": "size", "size": 200, "offset": 0, "pagination_mode": "offset" }'::jsonb, '{ "success_field": "errcode", "success_value": 0, "message_field": "errmsg", "list_path": "result.list", "has_more_field": "result.has_more" }'::jsonb, '{ "table_name": "dingtalk_role", "columns": [ {"name": "groupId", "type": "BIGINT", "comment": "角色组ID"}, {"name": "name", "type": "VARCHAR(200)", "comment": "角色组名称"}, {"name": "roles", "type": "JSONB", "comment": "角色列表"} ], "conflict_keys": ["groupId"] }'::jsonb );