diff --git a/README.md b/README.md index 0aaf4fe..a00667a 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ in at least 2 of Qiniu's internal systems. * [x] 消息发送 (除修改群聊会话外全部支持) * [x] 消息接收 (**接口尚不稳定,极有可能做出不兼容改动,先不要用**) * [x] 素材管理 (**支持上传**, 见下) +* [ ] OA * [ ] 会话内容存档 * [x] 企业微信登录接口 (code2Session) @@ -111,7 +112,6 @@ in at least 2 of Qiniu's internal systems.
外部联系人管理 API - * [x] 成员对外信息 * [x] 客户管理 - [x] 获取客户列表 @@ -190,6 +190,20 @@ in at least 2 of Qiniu's internal systems.
+
+OA API + +* [ ] 审批 + - [x] 获取审批模板详情 + - [x] 提交审批申请 + - [x] 审批申请状态变化回调通知 + - [x] 批量获取审批单号 + - [x] 获取审批申请详情 + - [ ] 获取企业假期管理配置 + - [ ] 修改成员假期余额 + +
+
会话内容存档 API diff --git a/apis.md.go b/apis.md.go index 40f0dbb..cfd3382 100644 --- a/apis.md.go +++ b/apis.md.go @@ -380,6 +380,62 @@ func (c *WorkwxApp) execMediaUploadImg(req reqMediaUploadImg) (respMediaUploadIm return resp, nil } +// execOAGetTemplateDetail 获取审批模板详情 +func (c *WorkwxApp) execOAGetTemplateDetail(req reqOAGetTemplateDetail) (respOAGetTemplateDetail, error) { + var resp respOAGetTemplateDetail + err := c.executeQyapiJSONPost("/cgi-bin/oa/gettemplatedetail", req, &resp, true) + if err != nil { + return respOAGetTemplateDetail{}, err + } + if bizErr := resp.TryIntoErr(); bizErr != nil { + return respOAGetTemplateDetail{}, bizErr + } + + return resp, nil +} + +// execOAApplyEvent 提交审批申请 +func (c *WorkwxApp) execOAApplyEvent(req reqOAApplyEvent) (respOAApplyEvent, error) { + var resp respOAApplyEvent + err := c.executeQyapiJSONPost("/cgi-bin/oa/applyevent", req, &resp, true) + if err != nil { + return respOAApplyEvent{}, err + } + if bizErr := resp.TryIntoErr(); bizErr != nil { + return respOAApplyEvent{}, bizErr + } + + return resp, nil +} + +// execOAGetApprovalInfo 批量获取审批单号 +func (c *WorkwxApp) execOAGetApprovalInfo(req reqOAGetApprovalInfo) (respOAGetApprovalInfo, error) { + var resp respOAGetApprovalInfo + err := c.executeQyapiJSONPost("/cgi-bin/oa/getapprovalinfo", req, &resp, true) + if err != nil { + return respOAGetApprovalInfo{}, err + } + if bizErr := resp.TryIntoErr(); bizErr != nil { + return respOAGetApprovalInfo{}, bizErr + } + + return resp, nil +} + +// execOAGetApprovalDetail 获取审批申请详情 +func (c *WorkwxApp) execOAGetApprovalDetail(req reqOAGetApprovalDetail) (respOAGetApprovalDetail, error) { + var resp respOAGetApprovalDetail + err := c.executeQyapiJSONPost("/cgi-bin/oa/getapprovaldetail", req, &resp, true) + if err != nil { + return respOAGetApprovalDetail{}, err + } + if bizErr := resp.TryIntoErr(); bizErr != nil { + return respOAGetApprovalDetail{}, bizErr + } + + return resp, nil +} + // execMsgAuditListPermitUser 获取会话内容存档开启成员列表 func (c *WorkwxApp) execMsgAuditListPermitUser(req reqMsgAuditListPermitUser) (respMsgAuditListPermitUser, error) { var resp respMsgAuditListPermitUser diff --git a/docs/apis.md b/docs/apis.md index f808fc2..0dd6022 100644 --- a/docs/apis.md +++ b/docs/apis.md @@ -149,7 +149,10 @@ Name|Request Type|Response Type|Access Token|URL|Doc Name|Request Type|Response Type|Access Token|URL|Doc :---|------------|-------------|------------|:--|:-- -`execCorpGetOpenApprovalData`|TODO|TODO|+|`POST /cgi-bin/corp/getopenapprovaldata`|[查询自建应用审批单当前状态](https://work.weixin.qq.com/api/doc#90000/90135/90269) +`execOAGetTemplateDetail`|`reqOAGetTemplateDetail`|`respOAGetTemplateDetail`|+|`POST /cgi-bin/oa/gettemplatedetail`|[获取审批模板详情](https://work.weixin.qq.com/api/doc/90000/90135/91982) +`execOAApplyEvent`|`reqOAApplyEvent`|`respOAApplyEvent`|+|`POST /cgi-bin/oa/applyevent`|[提交审批申请](https://work.weixin.qq.com/api/doc/90000/90135/91853) +`execOAGetApprovalInfo`|`reqOAGetApprovalInfo`|`respOAGetApprovalInfo`|+|`POST /cgi-bin/oa/getapprovalinfo`|[批量获取审批单号](https://work.weixin.qq.com/api/doc/90000/90135/91816) +`execOAGetApprovalDetail`|`reqOAGetApprovalDetail`|`respOAGetApprovalDetail`|+|`POST /cgi-bin/oa/getapprovaldetail`|[获取审批申请详情](https://work.weixin.qq.com/api/doc/90000/90135/91983) # 企业支付 diff --git a/docs/oa.md b/docs/oa.md new file mode 100644 index 0000000..2a6788f --- /dev/null +++ b/docs/oa.md @@ -0,0 +1,372 @@ +# OA数据接口 + +## Models + +### `OAApplyEvent` 提交审批申请 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`CreatorUserID`|`creator_userid`|`string`| 申请人userid,此审批申请将以此员工身份提交,申请人需在应用可见范围内 +`TemplateID`|`template_id`|`string`| 模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。暂不支持通过接口提交[打卡补卡][调班]模板审批单。 +`UseTemplateApprover`|`use_template_approver`|`uint8`| 审批人模式:0-通过接口指定审批人、抄送人(此时approver、notifyer等参数可用); 1-使用此模板在管理后台设置的审批流程,支持条件审批。默认为0 +`Approver`|`approver`|`[]OAApprover`| 审批流程信息,用于指定审批申请的审批流程,支持单人审批、多人会签、多人或签,可能有多个审批节点,仅use_template_approver为0时生效。 +`Notifier`|`notifyer`|`[]string`| 抄送人节点userid列表,仅use_template_approver为0时生效。 +`NotifyType`|`notify_type`|`*uint8`| 抄送方式:1-提单时抄送(默认值); 2-单据通过后抄送;3-提单和单据通过后抄送。仅use_template_approver为0时生效。 +`ApplyData`|`apply_data`|`OAContents`| 审批申请数据,可定义审批申请中各个控件的值,其中必填项必须有值,选填项可为空,数据结构同“获取审批申请详情”接口返回值中同名参数“apply_data” +`SummaryList`|`summary_list`|`[]OASummaryList`| 摘要信息,用于显示在审批通知卡片、审批列表的摘要信息,最多3行 + +### `OAApprover` 审批流程信息 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Attr`|`attr`|`uint8`| 节点审批方式:1-或签;2-会签,仅在节点为多人审批时有效 +`UserID`|`userid`|`[]string`| 审批节点审批人userid列表,若为多人会签、多人或签,需填写每个人的userid + +### `OAContent` 审批申请详情,由多个表单控件及其内容组成,其中包含需要对控件赋值的信息 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Control`|`control`|`OAControl`| 控件类型:Text-文本;Textarea-多行文本;Number-数字;Money-金额;Date-日期/日期+时间;Selector-单选/多选;;Contact-成员/部门;Tips-说明文字;File-附件;Table-明细; +`ID`|`id`|`string`| 控件id:控件的唯一id,可通过“获取审批模板详情”接口获取 +`Title`|`title`|`[]OAText`| 控件名称 ,若配置了多语言则会包含中英文的控件名称 +`Value`|`value`|`OAContentValue`| 控件值 ,需在此为申请人在各个控件中填写内容不同控件有不同的赋值参数,具体说明详见附录。模板配置的控件属性为必填时,对应value值需要有值。 + +### `OAContents` 审批申请详情,由多个表单控件及其内容组成,其中包含需要对控件赋值的信息 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Contents`|`contents`|`[]OAContent`| 审批申请详情,由多个表单控件及其内容组成,其中包含需要对控件赋值的信息 + +### `OAText` 通用文本信息 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Text`|`text`|`string`| 文字 +`Lang`|`lang`|`string`| 语言 + +### `OASummaryList` 摘要行信息,用于定义某一行摘要显示的内容 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`SummaryInfo`|`summary_info`|`[]OAText`| 摘要行信息,用于定义某一行摘要显示的内容 + +### `OAContentValue` 控件值 ,需在此为申请人在各个控件中填写内容不同控件有不同的赋值参数,具体说明详见附录。模板配置的控件属性为必填时,对应value值需要有值。 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Text`|`text`|`string`| 文本/多行文本控件(control参数为Text或Textarea) +`Number`|`new_number`|`string`| 数字控件(control参数为Number) +`Money`|`new_money`|`string`| 金额控件(control参数为Money) +`Date`|`date`|`OAContentDate`| 日期/日期+时间控件(control参数为Date) +`Selector`|`selector`|`OAContentSelector`| 单选/多选控件(control参数为Selector) +`Members`|`members`|`[]OAContentMember`| 成员控件(control参数为Contact,且value参数为members) +`Departments`|`departments`|`[]OAContentDepartment`| 部门控件(control参数为Contact,且value参数为departments) +`Files`|`files`|`[]OAContentFile`| 附件控件(control参数为File,且value参数为files) +`Table`|`children`|`[]OAContentTableList`| 明细控件(control参数为Table) +`Vacation`|`vacation`|`OAContentVacation`| 假勤组件-请假组件(control参数为Vacation) +`Location`|`location`|`OAContentLocation`| 位置控件(control参数为Location,且value参数为location) +`RelatedApproval`|`related_approval`|`[]OAContentRelatedApproval`| 关联审批单控件(control参数为RelatedApproval,且value参数为related_approval) +`Formula`|`formula`|`OAContentFormula`| 公式控件(control参数为Formula,且value参数为formula) +`DateRange`|`date_range`|`OAContentDateRange`| 时长组件(control参数为DateRange,且value参数为date_range) + +### `OAContentDate` 日期/日期+时间内容 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Type`|`type`|`string`| 时间展示类型:day-日期;hour-日期+时间 ,和对应模板控件属性一致 +`Timestamp`|`s_timestamp`|`string`| 时间戳-字符串类型,在此填写日期/日期+时间控件的选择值,以此为准 + +### `OAContentSelector` 类型标志,单选/多选控件的config中会包含此参数 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Type`|`type`|`string`| 选择方式:single-单选;multi-多选 +`Options`|`options`|`[]OAContentSelectorOption`| 多选选项,多选属性的选择控件允许输入多个 + +### `OAContentSelectorOption` 多选选项,多选属性的选择控件允许输入多个 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Key`|`key`|`string`| 选项key,可通过“获取审批模板详情”接口获得 + +### `OAContentMember` 所选成员内容,即申请人在此控件选择的成员,多选模式下可以有多个 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`UserID`|`userid`|`string`| 所选成员的userid +`Name`|`name`|`string`| 成员名 + +### `OAContentDepartment` 所选部门内容,即申请人在此控件选择的部门,多选模式下可能有多个 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`OpenAPIID`|`openapi_id`|`string`| 所选部门id +`Name`|`name`|`string`| 所选部门名 + +### `OAContentFile` 附件 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`FileID`|`file_id`|`string`| 文件id,该id为临时素材上传接口返回的的media_id,注:提单后将作为单据内容转换为长期文件存储;目前一个审批申请单,全局仅支持上传6个附件,否则将失败。 + +### `OAContentTableList` 子明细列表,在此填写子明细的所有子控件的值,子控件的数据结构同一般控件 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`List`|`list`|`[]OAContent`| 子明细列表,在此填写子明细的所有子控件的值,子控件的数据结构同一般控件 + +### `OAContentVacation` 请假内容,即申请人在此组件内选择的请假信息 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Selector`|`selector`|`OAContentSelector`| 请假类型,所选选项与假期管理关联,为假期管理中的假期类型 +`Attendance`|`attendance`|`OAContentVacationAttendance`| 假勤组件 + +### `OAContentVacationAttendance` 假勤组件 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`DateRange`|`date_range`|`OAContentVacationAttendanceDateRange`| 假勤组件时间选择范围 +`Type`|`type`|`uint8`| 假勤组件类型:1-请假;3-出差;4-外出;5-加班 + +### `OAContentVacationAttendanceDateRange` 假勤组件时间选择范围 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Type`|`type`|`string`| 时间展示类型:day-日期;hour-日期+时间 +``|``|`OAContentDateRange`| 时长范围 + +### `OAContentLocation` 位置控件 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Latitude`|`latitude`|`string`| 纬度,精确到6位小数 +`Longitude`|`longitude`|`string`| 经度,精确到6位小数 +`Title`|`title`|`string`| 地点标题 +`Address`|`address`|`string`| 地点详情地址 +`Time`|`time`|`int`| 选择地点的时间 + +### `OAContentRelatedApproval` 关联审批单控件 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`SpNo`|`sp_no`|`string`| 关联审批单的审批单号 + +### `OAContentFormula` 公式控件 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Value`|`value`|`string`| 公式的值,提交表单时无需填写,后台自动计算 + +### `OAContentDateRange` 时长组件 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`NewBegin`|`new_begin`|`int`| 开始时间,unix时间戳 +`NewEnd`|`new_end`|`int`| 结束时间,unix时间戳 +`NewDuration`|`new_duration`|`int`| 时长范围,单位秒 + + +### `OATemplateDetail` 审批模板详情 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`TemplateNames`|`template_names`|`[]OAText`| 模板名称,若配置了多语言则会包含中英文的模板名称,默认为zh_CN中文 +`TemplateContent`|`template_content`|`OATemplateControls`| 模板控件信息 +`Vacation`|`vacation_list`|`OATemplateControlConfigVacation`| Vacation控件(假勤控件) + +### `OATemplateControls` 模板控件数组。模板详情由多个不同类型的控件组成,控件类型详细说明见附录。 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Controls`|`controls`|`[]OATemplateControl`| 模板名称,若配置了多语言则会包含中英文的模板名称,默认为zh_CN中文 + +### `OATemplateControl` 模板控件信息 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Property`|`property`|`OATemplateControlProperty`| 模板控件属性,包含了模板内控件的各种属性信息 +`Config`|`config`|`OATemplateControlConfig`| 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。目前有配置信息的控件类型有:Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Table-明细;Attendance-假勤组件(请假、外出、出差、加班) + +### `OATemplateControlProperty` 模板控件属性 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Control`|`control`|`OAControl`| 模板控件属性,包含了模板内控件的各种属性信息 +`ID`|`id`|`string`| 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。目前有配置信息的控件类型有:Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Table-明细;Attendance-假勤组件(请假、外出、出差、加班) +`Title`|`title`|`[]OAText`| 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。目前有配置信息的控件类型有:Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Table-明细;Attendance-假勤组件(请假、外出、出差、加班) +`Placeholder`|`placeholder`|`[]OAText`| 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。目前有配置信息的控件类型有:Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Table-明细;Attendance-假勤组件(请假、外出、出差、加班) +`Require`|`require`|`uint8`| 是否必填:1-必填;0-非必填 +`UnPrint`|`un_print`|`uint8`| 是否参与打印:1-不参与打印;0-参与打印 + +### `OATemplateControlConfig` 模板控件配置 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Date`|`date`|`OATemplateControlConfigDate`| Date控件(日期/日期+时间控件) +`Selector`|`selector`|`OATemplateControlConfigSelector`| Selector控件(单选/多选控件) +`Contact`|`contact`|`OATemplateControlConfigContact`| Contact控件(成员/部门控件) +`Table`|`table`|`OATemplateControlConfigTable`| Table(明细控件) +`Attendance`|`attendance`|`OATemplateControlConfigAttendance`| Attendance控件(假勤控件) + +### `OATemplateControlConfigDate` 类型标志,日期/日期+时间控件的config中会包含此参数 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Type`|`type`|`string`| 时间展示类型:day-日期;hour-日期+时间 + +### `OATemplateControlConfigSelector` 类型标志,单选/多选控件的config中会包含此参数 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Type`|`type`|`string`| 选择类型:single-单选;multi-多选 +`Options`|`options`|`[]OATemplateControlConfigSelectorOption`| 选项,包含单选/多选控件中的所有选项,可能有多个 + +### `OATemplateControlConfigSelectorOption` 选项,包含单选/多选控件中的所有选项,可能有多个 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Key`|`key`|`string`| 选项key,选项的唯一id,可用于发起审批申请,为单选/多选控件赋值 +`Value`|`value`|`[]OAText`| 选项值,若配置了多语言则会包含中英文的选项值,默认为zh_CN中文 + +### `OATemplateControlConfigContact` 类型标志,单选/多选控件的config中会包含此参数 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Type`|`type`|`string`| 选择类型:single-单选;multi-多选 +`Mode`|`mode`|`string`| 选择对象:user-成员;department-部门 + +### `OATemplateControlConfigTable` 类型标志,明细控件的config中会包含此参数 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Children`|`children`|`[]OATemplateControl`| 明细内的子控件,内部结构同controls + +### `OATemplateControlConfigAttendance` 类型标志,假勤控件的config中会包含此参数 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`DateRange`|`date_range`|`OATemplateControlConfigAttendanceDateRange`| 假期控件属性 +`Type`|`type`|`uint8`| 假勤控件类型:1-请假,3-出差,4-外出,5-加班 + +### `OATemplateControlConfigAttendanceDateRange` 假期控件属性 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Type`|`type`|`string`| 时间刻度:hour-精确到分钟, halfday—上午/下午 + +### `OATemplateControlConfigVacation` 类型标志,假勤控件的config中会包含此参数 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Item`|`item`|`[]OATemplateControlConfigVacationItem`| 单个假期类型属性 + +### `OATemplateControlConfigVacationItem` 类型标志,假勤控件的config中会包含此参数 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`ID`|`id`|`int`| 假期类型标识id +`Name`|`name`|`[]OAText`| 假期类型名称,默认zh_CN中文名称 + +```go +// OAControl 控件类型 +type OAControl string + +// OAControlText 文本 +const OAControlText OAControl = "Text" + +// OAControlTextarea 多行文本 +const OAControlTextarea OAControl = "Textarea" + +// OAControlNumber 数字 +const OAControlNumber OAControl = "Number" + +// OAControlMoney 金额 +const OAControlMoney OAControl = "Money" + +// OAControlDate 日期/日期+时间控件 +const OAControlDate OAControl = "Date" + +// OAControlSelector 单选/多选控件 +const OAControlSelector OAControl = "Selector" + +// OAControlContact 成员/部门控件 +const OAControlContact OAControl = "Contact" + +// OAControlTips 说明文字控件 +const OAControlTips OAControl = "Tips" + +// OAControlFile 附件控件 +const OAControlFile OAControl = "File" + +// OAControlTable 明细控件 +const OAControlTable OAControl = "Table" + +// OAControlLocation 位置控件 +const OAControlLocation OAControl = "Location" + +// OAControlRelatedApproval 关联审批单控件 +const OAControlRelatedApproval OAControl = "RelatedApproval" + +// OAControlFormula 公式控件 +const OAControlFormula OAControl = "Formula" + +// OAControlDateRange 时长控件 +const OAControlDateRange OAControl = "DateRange" + +// OAControlVacation 假勤组件-请假组件 +const OAControlVacation OAControl = "Vacation" + +// OAControlAttendance 假勤组件-出差/外出/加班组件 +const OAControlAttendance OAControl = "Attendance" + +``` + +### `OAApprovalDetail` 审批申请详情 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`SpNo`|`sp_no`|`string`| 审批编号 +`SpName`|`sp_name`|`string`| 审批申请类型名称(审批模板名称) +`SpStatus`|`sp_status`|`uint8`| 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付 +`TemplateID`|`template_id`|`string`| 审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。 +`ApplyTime`|`apply_time`|`int`| 审批申请提交时间,Unix时间戳 +`Applicant`|`applyer`|`OAApprovalDetailApplicant`| 申请人信息 +`SpRecord`|`sp_record`|`[]OAApprovalDetailSpRecord`| 审批流程信息,可能有多个审批节点。 +`Notifier`|`notifyer`|`[]OAApprovalDetailNotifier`| 抄送信息,可能有多个抄送节点 +`ApplyData`|`apply_data`|`OAContents`| 审批申请数据 +`Comments`|`comments`|`[]OAApprovalDetailComment`| 审批申请备注信息,可能有多个备注节点 + +### `OAApprovalDetailApplicant` 审批申请详情申请人信息 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`UserID`|`userid`|`string`| 申请人userid +`PartyID`|`partyid`|`string`| 申请人所在部门id + +### `OAApprovalDetailSpRecord` 审批流程信息,可能有多个审批节点。 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`SpStatus`|`sp_status`|`uint8`| 审批节点状态:1-审批中;2-已同意;3-已驳回;4-已转审 +`ApproverAttr`|`approverattr`|`uint8`| 节点审批方式:1-或签;2-会签 +`Details`|`details`|`[]OAApprovalDetailSpRecordDetail`| 审批节点详情,一个审批节点有多个审批人 + +### `OAApprovalDetailSpRecordDetail` 审批节点详情,一个审批节点有多个审批人 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Approver`|`approver`|`OAApprovalDetailSpRecordDetailApprover`| 分支审批人 +`Speech`|`speech`|`string`| 审批意见 +`SpStatus`|`sp_status`|`uint8`| 分支审批人审批状态:1-审批中;2-已同意;3-已驳回;4-已转审 +`SpTime`|`sptime`|`int`| 节点分支审批人审批操作时间戳,0表示未操作 +`MediaID`|`media_id`|`[]string`| 节点分支审批人审批意见附件,media_id具体使用请参考:文档-获取临时素材 + +### `OAApprovalDetailSpRecordDetailApprover` 分支审批人 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`UserID`|`userid`|`string`| 分支审批人userid + +### `OAApprovalDetailNotifier` 抄送信息,可能有多个抄送节点 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`UserID`|`userid`|`string`| 节点抄送人userid + +### `OAApprovalDetailComment` 审批申请备注信息,可能有多个备注节点 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`CommentUserInfo`|`commentUserInfo`|`OAApprovalDetailCommentUserInfo`| 备注人信息 +`CommentTime`|`commenttime`|`int`| 备注提交时间戳,Unix时间戳 +`CommentTontent`|`commentcontent`|`string`| 备注文本内容 +`CommentID`|`commentid`|`string`| 备注id +`MediaID`|`media_id`|`[]string`| 备注附件id,可能有多个,media_id具体使用请参考:文档-获取临时素材 + +### `OAApprovalDetailCommentUserInfo` 备注人信息 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`UserID`|`userid`|`string`| 备注人userid + +### `OAApprovalInfoFilter` 备注人信息 +Name|JSON|Type|Doc +:---|:---|:---|:-- +`Key`|`key`|`OAApprovalInfoFilterKey`| 筛选类型,包括:template_id - 模板类型/模板id;creator - 申请人;department - 审批单提单者所在部门;sp_status - 审批状态。注意:仅“部门”支持同时配置多个筛选条件。不同类型的筛选条件之间为“与”的关系,同类型筛选条件之间为“或”的关系 +`Value`|`value`|`string`| 筛选值,对应为:template_id - 模板id;creator - 申请人userid;department - 所在部门id;sp_status - 审批单状态(1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付) + +```go +// OAApprovalInfoFilterKey 拉取审批筛选类型 +type OAApprovalInfoFilterKey string + +// OAApprovalInfoFilterKeyTemplateID 模板类型 +const OAApprovalInfoFilterKeyTemplateID OAApprovalInfoFilterKey = "template_id" + +// OAApprovalInfoFilterKeyCreator 申请人 +const OAApprovalInfoFilterKeyCreator OAApprovalInfoFilterKey = "creator" + +// OAApprovalInfoFilterKeyDepartment 审批单提单者所在部门 +const OAApprovalInfoFilterKeyDepartment OAApprovalInfoFilterKey = "department" + +// OAApprovalInfoFilterKeySpStatus 审批状态 +const OAApprovalInfoFilterKeySpStatus OAApprovalInfoFilterKey = "sp_status" + +``` diff --git a/docs/rx_msg.md b/docs/rx_msg.md index 45d776e..5bb188b 100644 --- a/docs/rx_msg.md +++ b/docs/rx_msg.md @@ -48,6 +48,9 @@ const EventTypeChangeExternalContact EventType = "change_external_contact" // EventTypeChangeExternalChat 客户群变更事件 const EventTypeChangeExternalChat EventType = "change_external_chat" +// EventTypeSysApprovalChange 审批申请状态变化回调通知 +const EventTypeSysApprovalChange EventType = "sys_approval_change" + // ChangeType 变更类型 type ChangeType string @@ -173,3 +176,9 @@ Name|XML|Type|Doc `FromUserName`|`FromUserName`|`string`|此事件该值固定为sys,表示该消息由系统生成 `FailReason`|`FailReason`|`string`|接替失败的原因, customer_refused-客户拒绝, customer_limit_exceed-接替成员的客户数达到上限 `ChatID`|`ChatId`|`string`|群ID + +### `rxEventSysApprovalChange` 接收的事件消息,审批申请状态变化回调通知 + +Name|XML|Type|Doc +:---|:--|:---|:-- +`ApprovalInfo`|`ApprovalInfo`|`OAApprovalInfo`|审批信息、 diff --git a/dummy_for_generate.go b/dummy_for_generate.go index 6d6f34c..b9e047b 100644 --- a/dummy_for_generate.go +++ b/dummy_for_generate.go @@ -5,5 +5,6 @@ package workwx //go:generate go run --tags sdkcodegen ./internal/sdkcodegen ./docs/dept_info.md ./dept_info.md.go //go:generate go run --tags sdkcodegen ./internal/sdkcodegen ./docs/external_contact.md ./external_contact.md.go //go:generate go run --tags sdkcodegen ./internal/sdkcodegen ./docs/user_info.md ./user_info.md.go +//go:generate go run --tags sdkcodegen ./internal/sdkcodegen ./docs/oa.md ./oa.md.go //go:generate go run --tags sdkcodegen ./internal/sdkcodegen ./docs/rx_msg.md ./rx_msg.md.go //go:generate go run --tags sdkcodegen ./internal/errcodegen ./errcodes/mod.go diff --git a/example_test.go b/example_test.go index 716c777..df0da0d 100644 --- a/example_test.go +++ b/example_test.go @@ -2,13 +2,18 @@ package workwx_test import ( "net/http" + "strconv" + "time" "github.com/xen0n/go-workwx" ) +const ( + corpID = "your_corpid" + corpSecret = "your_corpsecret" +) + func ExampleWorkwx() { - corpID := "your_corpid" - corpSecret := "your_corpsecret" agentID := int64(1234567) client := workwx.New(corpID) @@ -28,8 +33,6 @@ func ExampleWorkwx() { } func ExampleWorkwxApp_SendTextMessage() { - corpID := "your_corpid" - corpSecret := "your_corpsecret" agentID := int64(1234567) client := workwx.New(corpID) @@ -68,3 +71,227 @@ func ExampleWorkwxApp_SendTextMessage() { } _ = app.SendTextMessage(&to5, "send to chatid", false) } + +func ExampleWorkwxApp_ApplyOAEvent() { + agentID := int64(1234567) + + client := workwx.New(corpID) + + app := client.WithApp(corpSecret, agentID) + app.SpawnAccessTokenRefresher() + + appInfo := workwx.OAApplyEvent{ + CreatorUserID: "your_userid", + TemplateID: "your_templateid", + UseTemplateApprover: 1, + ApplyData: workwx.OAContents{ + Contents: []workwx.OAContent{ + { + Control: workwx.OAControlText, + ID: "Text-1608628829793", + Value: workwx.OAContentValue{ + Text: "文本", + }, + }, + { + Control: workwx.OAControlTextarea, + ID: "Textarea-1608628832640", + Value: workwx.OAContentValue{ + Text: "多行文本\n可换行", + }, + }, + { + Control: workwx.OAControlNumber, + ID: "Number-1608632495498", + Value: workwx.OAContentValue{ + Number: "123.45", + }, + }, + { + Control: workwx.OAControlMoney, + ID: "Money-1608632497034", + Value: workwx.OAContentValue{ + Money: "678.90", + }, + }, + { + Control: workwx.OAControlFormula, + ID: "Formula-1608632498148", + Value: workwx.OAContentValue{ + Formula: workwx.OAContentFormula{Value: "5.0"}, + }, + }, + { + Control: workwx.OAControlDate, + ID: "Date-1608632499227", + Value: workwx.OAContentValue{ + Date: workwx.OAContentDate{Type: "day", Timestamp: strconv.FormatInt(time.Now().Unix(), 10)}, + }, + }, + { + Control: workwx.OAControlDate, + ID: "Date-1608632500394", + Value: workwx.OAContentValue{ + Date: workwx.OAContentDate{Type: "hour", Timestamp: strconv.FormatInt(time.Now().Unix(), 10)}, + }, + }, + { + Control: workwx.OAControlDateRange, + ID: "DateRange-1608632502131", + Value: workwx.OAContentValue{ + DateRange: workwx.OAContentDateRange{ + NewBegin: int(time.Now().Unix()), + NewEnd: int(time.Now().Add(time.Hour * 24).Unix()), + NewDuration: 60 * 60 * 24, + }, + }, + }, + { + Control: workwx.OAControlSelector, + ID: "Selector-1608632503203", + Value: workwx.OAContentValue{ + Selector: workwx.OAContentSelector{ + Type: "single", + Options: []workwx.OAContentSelectorOption{ + {Key: "option-1608632503204"}, + }, + }, + }, + }, + { + Control: workwx.OAControlSelector, + ID: "Selector-1608632504330", + Value: workwx.OAContentValue{ + Selector: workwx.OAContentSelector{ + Type: "multi", + Options: []workwx.OAContentSelectorOption{ + {Key: "option-1608632504330"}, + {Key: "option-1608632504331"}, + }, + }, + }, + }, + { + Control: workwx.OAControlContact, + ID: "Contact-1608632505579", + Value: workwx.OAContentValue{ + Members: []workwx.OAContentMember{{ + UserID: "your_userid", + Name: "your_name", + }}, + }, + }, + { + Control: workwx.OAControlContact, + ID: "Contact-1608632506635", + Value: workwx.OAContentValue{ + Departments: []workwx.OAContentDepartment{{ + OpenAPIID: "39", + Name: "xx部门1", + }, { + OpenAPIID: "40", + Name: "xx部门2", + }}, + }, + }, + { + Control: workwx.OAControlLocation, + ID: "Location-1608632507748", + Value: workwx.OAContentValue{ + Location: workwx.OAContentLocation{ + Latitude: "30.547239", + Longitude: "104.063291", + Title: "腾讯科技(成都)有限公司(腾讯成都大厦)", + Address: "四川省成都市武侯区天府三街198号腾讯成都大厦A座", + Time: int(time.Now().Unix()), + }, + }, + }, + { + Control: workwx.OAControlRelatedApproval, + ID: "RelatedApproval-1608632509930", + Value: workwx.OAContentValue{ + RelatedApproval: []workwx.OAContentRelatedApproval{ + {SpNo: "202012220021"}, + }, + }, + }, + { + Control: workwx.OAControlTable, + ID: "Table-1608632511066", + Value: workwx.OAContentValue{ + Table: []workwx.OAContentTableList{ + { + List: []workwx.OAContent{ + { + Control: workwx.OAControlText, + ID: "Text-1608632519610", + Value: workwx.OAContentValue{ + Text: "第一行第一列", + }, + }, { + Control: workwx.OAControlText, + ID: "Text-1608632521106", + Value: workwx.OAContentValue{ + Text: "第一行第二列", + }, + }, + }, + }, + { + List: []workwx.OAContent{ + { + Control: workwx.OAControlText, + ID: "Text-1608632519610", + Value: workwx.OAContentValue{ + Text: "第二行第一列", + }, + }, { + Control: workwx.OAControlText, + ID: "Text-1608632521106", + Value: workwx.OAContentValue{ + Text: "第二行第二列", + }, + }, + }, + }, + }, + }, + }, + { + Control: workwx.OAControlVacation, + ID: "Vacation-1608715577151", + Value: workwx.OAContentValue{ + Vacation: workwx.OAContentVacation{ + Selector: workwx.OAContentSelector{ + Type: "single", + Options: []workwx.OAContentSelectorOption{ + { + Key: "3", + }, + }, + }, + Attendance: workwx.OAContentVacationAttendance{ + DateRange: workwx.OAContentVacationAttendanceDateRange{ + Type: "hour", + OAContentDateRange: workwx.OAContentDateRange{ + NewBegin: int(time.Now().Unix()), + NewEnd: int(time.Now().Add(time.Hour * 72).Unix()), + NewDuration: 60 * 60 * 72, + }, + }, + Type: 1, + }, + }, + }, + }, + }, + }, + SummaryList: []workwx.OASummaryList{{SummaryInfo: []workwx.OAText{{ + Text: "摘要第1行", + }}}, {SummaryInfo: []workwx.OAText{{ + Text: "摘要第2行", + }}}}, + } + _, _ = app.ApplyOAEvent(appInfo) +} diff --git a/models.go b/models.go index 47ca266..a00cf3e 100644 --- a/models.go +++ b/models.go @@ -850,3 +850,91 @@ type respTransferGroupChatExternalContact struct { respCommon FailedChatList []ExternalContactGroupChatTransferFailed `json:"failed_chat_list"` } + +type reqOAGetTemplateDetail struct { + TemplateID string `json:"template_id"` +} + +var _ bodyer = reqOAGetTemplateDetail{} + +func (x reqOAGetTemplateDetail) intoBody() ([]byte, error) { + result, err := json.Marshal(x) + if err != nil { + return nil, err + } + + return result, nil +} + +type respOAGetTemplateDetail struct { + respCommon + OATemplateDetail +} + +type reqOAApplyEvent struct { + OAApplyEvent +} + +var _ bodyer = reqOAApplyEvent{} + +func (x reqOAApplyEvent) intoBody() ([]byte, error) { + result, err := json.Marshal(x) + if err != nil { + return nil, err + } + + return result, nil +} + +type respOAApplyEvent struct { + respCommon + // SpNo 表单提交成功后,返回的表单编号 + SpNo string `json:"sp_no"` +} + +type reqOAGetApprovalInfo struct { + StartTime string `json:"starttime"` + EndTime string `json:"endtime"` + Cursor int `json:"cursor"` + Size uint32 `json:"size"` + Filters []OAApprovalInfoFilter `json:"filters"` +} + +var _ bodyer = reqOAGetApprovalInfo{} + +func (x reqOAGetApprovalInfo) intoBody() ([]byte, error) { + result, err := json.Marshal(x) + if err != nil { + return nil, err + } + + return result, nil +} + +type respOAGetApprovalInfo struct { + respCommon + // SpNoList 审批单号列表,包含满足条件的审批申请 + SpNoList []string `json:"sp_no_list"` +} + +type reqOAGetApprovalDetail struct { + // SpNo 审批单编号。 + SpNo string `json:"sp_no"` +} + +var _ bodyer = reqOAGetApprovalDetail{} + +func (x reqOAGetApprovalDetail) intoBody() ([]byte, error) { + result, err := json.Marshal(x) + if err != nil { + return nil, err + } + + return result, nil +} + +type respOAGetApprovalDetail struct { + respCommon + // Info 审批申请详情 + Info OAApprovalDetail `json:"info"` +} diff --git a/oa.go b/oa.go new file mode 100644 index 0000000..1eebc9d --- /dev/null +++ b/oa.go @@ -0,0 +1,156 @@ +package workwx + +import ( + "strconv" + "time" +) + +// GetOATemplateDetail 获取审批模板详情 +func (c *WorkwxApp) GetOATemplateDetail(templateID string) (*OATemplateDetail, error) { + resp, err := c.execOAGetTemplateDetail(reqOAGetTemplateDetail{ + TemplateID: templateID, + }) + if err != nil { + return nil, err + } + return &resp.OATemplateDetail, nil +} + +// ApplyOAEvent 提交审批申请 +func (c *WorkwxApp) ApplyOAEvent(applyInfo OAApplyEvent) (string, error) { + resp, err := c.execOAApplyEvent(reqOAApplyEvent{ + OAApplyEvent: applyInfo, + }) + if err != nil { + return "", err + } + return resp.SpNo, nil +} + +// GetOAApprovalInfo 批量获取审批单号 +func (c *WorkwxApp) GetOAApprovalInfo(req GetOAApprovalInfoReq) ([]string, error) { + resp, err := c.execOAGetApprovalInfo(reqOAGetApprovalInfo{ + StartTime: strconv.FormatInt(req.StartTime.Unix(), 10), + EndTime: strconv.FormatInt(req.EndTime.Unix(), 10), + Cursor: req.Cursor, + Size: req.Size, + Filters: req.Filters, + }) + if err != nil { + return nil, err + } + return resp.SpNoList, nil +} + +// GetOAApprovalDetail 提交审批申请 +func (c *WorkwxApp) GetOAApprovalDetail(spNo string) (*OAApprovalDetail, error) { + resp, err := c.execOAGetApprovalDetail(reqOAGetApprovalDetail{ + SpNo: spNo, + }) + if err != nil { + return nil, err + } + return &resp.Info, nil +} + +// GetOAApprovalInfoReq 批量获取审批单号请求 +type GetOAApprovalInfoReq struct { + // StartTime 审批单提交的时间范围,开始时间,UNix时间戳 + StartTime time.Time + // EndTime 审批单提交的时间范围,结束时间,Unix时间戳 + EndTime time.Time + // Cursor 分页查询游标,默认为0,后续使用返回的next_cursor进行分页拉取 + Cursor int + // Size 一次请求拉取审批单数量,默认值为100,上限值为100 + Size uint32 + // Filters 筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件 + Filters []OAApprovalInfoFilter +} + +// OAApprovalInfo 审批申请状态变化回调通知 +type OAApprovalInfo struct { + // SpNo 审批编号 + SpNo string `xml:"SpNo"` + // SpName 审批申请类型名称(审批模板名称) + SpName string `xml:"SpName"` + // SpStatus 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付 + SpStatus string `xml:"SpStatus"` + // TemplateID 审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。 + TemplateID string `xml:"TemplateId"` + // ApplyTime 审批申请提交时间,Unix时间戳 + ApplyTime string `xml:"ApplyTime"` + // Applicant 申请人信息 + Applicant OAApprovalInfoApplicant `xml:"Applyer"` + // SpRecord 审批流程信息,可能有多个审批节点。 + SpRecord []OAApprovalInfoSpRecord `xml:"SpRecord"` + // Notifier 抄送信息,可能有多个抄送节点 + Notifier OAApprovalInfoNotifier `xml:"Notifyer"` + // Comments 审批申请备注信息,可能有多个备注节点 + Comments []OAApprovalInfoComment `xml:"Comments"` + // StatusChangeEvent 审批申请状态变化类型:1-提单;2-同意;3-驳回;4-转审;5-催办;6-撤销;8-通过后撤销;10-添加备注 + StatusChangeEvent string `xml:"StatuChangeEvent"` +} + +// OAApprovalInfoApplicant 申请人信息 +type OAApprovalInfoApplicant struct { + // UserID 申请人userid + UserID string `xml:"UserId"` + // Party 申请人所在部门pid + Party string `xml:"Party"` +} + +// OAApprovalInfoSpRecord 审批流程信息,可能有多个审批节点。 +type OAApprovalInfoSpRecord struct { + // SpStatus 审批节点状态:1-审批中;2-已同意;3-已驳回;4-已转审 + SpStatus string `xml:"SpStatus"` + // ApproverAttr 节点审批方式:1-或签;2-会签 + ApproverAttr string `xml:"ApproverAttr"` + // Details 审批节点详情。当节点为标签或上级时,一个节点可能有多个分支 + Details []OAApprovalInfoSpRecordDetail `xml:"Details"` +} + +// OAApprovalInfoSpRecordDetail 审批节点详情。当节点为标签或上级时,一个节点可能有多个分支 +type OAApprovalInfoSpRecordDetail struct { + // Approver 分支审批人 + Approver OAApprovalInfoSpRecordDetailApprover `xml:"Approver"` + // Speech 审批意见字段 + Speech string `xml:"Speech"` + // SpStatus 分支审批人审批状态:1-审批中;2-已同意;3-已驳回;4-已转审 + SpStatus string `xml:"SpStatus"` + // SpTime 节点分支审批人审批操作时间,0为尚未操作 + SpTime string `xml:"SpTime"` + // Attach 节点分支审批人审批意见附件,赋值为media_id具体使用请参考:文档-获取临时素材 + Attach []string `xml:"Attach"` +} + +// OAApprovalInfoSpRecordDetailApprover 分支审批人 +type OAApprovalInfoSpRecordDetailApprover struct { + // UserID 分支审批人userid + UserID string `xml:"UserId"` +} + +// OAApprovalInfoNotifier 抄送信息,可能有多个抄送节点 +type OAApprovalInfoNotifier struct { + // UserID 节点抄送人userid + UserID string `xml:"UserId"` +} + +// OAApprovalInfoComment 审批申请备注信息,可能有多个备注节点 +type OAApprovalInfoComment struct { + // CommentUserInfo 备注人信息 + CommentUserInfo OAApprovalInfoCommentUserInfo `xml:"CommentUserInfo"` + // CommentTime 备注提交时间 + CommentTime string `xml:"CommentTime"` + // CommentContent 备注文本内容 + CommentContent string `xml:"CommentContent"` + // CommentID 备注id + CommentID string `xml:"CommentId"` + // Attach 备注意见附件,值是附件media_id具体使用请参考:文档-获取临时素材 + Attach []string `xml:"Attach"` +} + +// OAApprovalInfoCommentUserInfo 备注人信息 +type OAApprovalInfoCommentUserInfo struct { + // UserID 备注人userid + UserID string `xml:"UserId"` +} diff --git a/oa.md.go b/oa.md.go new file mode 100644 index 0000000..d648b01 --- /dev/null +++ b/oa.md.go @@ -0,0 +1,485 @@ +// Code generated by sdkcodegen; DO NOT EDIT. + +package workwx + +// OAApplyEvent 提交审批申请 +type OAApplyEvent struct { + // CreatorUserID 申请人userid,此审批申请将以此员工身份提交,申请人需在应用可见范围内 + CreatorUserID string `json:"creator_userid"` + // TemplateID 模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。暂不支持通过接口提交[打卡补卡][调班]模板审批单。 + TemplateID string `json:"template_id"` + // UseTemplateApprover 审批人模式:0-通过接口指定审批人、抄送人(此时approver、notifyer等参数可用); 1-使用此模板在管理后台设置的审批流程,支持条件审批。默认为0 + UseTemplateApprover uint8 `json:"use_template_approver"` + // Approver 审批流程信息,用于指定审批申请的审批流程,支持单人审批、多人会签、多人或签,可能有多个审批节点,仅use_template_approver为0时生效。 + Approver []OAApprover `json:"approver"` + // Notifier 抄送人节点userid列表,仅use_template_approver为0时生效。 + Notifier []string `json:"notifyer"` + // NotifyType 抄送方式:1-提单时抄送(默认值); 2-单据通过后抄送;3-提单和单据通过后抄送。仅use_template_approver为0时生效。 + NotifyType *uint8 `json:"notify_type"` + // ApplyData 审批申请数据,可定义审批申请中各个控件的值,其中必填项必须有值,选填项可为空,数据结构同“获取审批申请详情”接口返回值中同名参数“apply_data” + ApplyData OAContents `json:"apply_data"` + // SummaryList 摘要信息,用于显示在审批通知卡片、审批列表的摘要信息,最多3行 + SummaryList []OASummaryList `json:"summary_list"` +} + +// OAApprover 审批流程信息 +type OAApprover struct { + // Attr 节点审批方式:1-或签;2-会签,仅在节点为多人审批时有效 + Attr uint8 `json:"attr"` + // UserID 审批节点审批人userid列表,若为多人会签、多人或签,需填写每个人的userid + UserID []string `json:"userid"` +} + +// OAContent 审批申请详情,由多个表单控件及其内容组成,其中包含需要对控件赋值的信息 +type OAContent struct { + // Control 控件类型:Text-文本;Textarea-多行文本;Number-数字;Money-金额;Date-日期/日期+时间;Selector-单选/多选;;Contact-成员/部门;Tips-说明文字;File-附件;Table-明细; + Control OAControl `json:"control"` + // ID 控件id:控件的唯一id,可通过“获取审批模板详情”接口获取 + ID string `json:"id"` + // Title 控件名称 ,若配置了多语言则会包含中英文的控件名称 + Title []OAText `json:"title"` + // Value 控件值 ,需在此为申请人在各个控件中填写内容不同控件有不同的赋值参数,具体说明详见附录。模板配置的控件属性为必填时,对应value值需要有值。 + Value OAContentValue `json:"value"` +} + +// OAContents 审批申请详情,由多个表单控件及其内容组成,其中包含需要对控件赋值的信息 +type OAContents struct { + // Contents 审批申请详情,由多个表单控件及其内容组成,其中包含需要对控件赋值的信息 + Contents []OAContent `json:"contents"` +} + +// OAText 通用文本信息 +type OAText struct { + // Text 文字 + Text string `json:"text"` + // Lang 语言 + Lang string `json:"lang"` +} + +// OASummaryList 摘要行信息,用于定义某一行摘要显示的内容 +type OASummaryList struct { + // SummaryInfo 摘要行信息,用于定义某一行摘要显示的内容 + SummaryInfo []OAText `json:"summary_info"` +} + +// OAContentValue 控件值 ,需在此为申请人在各个控件中填写内容不同控件有不同的赋值参数,具体说明详见附录。模板配置的控件属性为必填时,对应value值需要有值。 +type OAContentValue struct { + // Text 文本/多行文本控件(control参数为Text或Textarea) + Text string `json:"text"` + // Number 数字控件(control参数为Number) + Number string `json:"new_number"` + // Money 金额控件(control参数为Money) + Money string `json:"new_money"` + // Date 日期/日期+时间控件(control参数为Date) + Date OAContentDate `json:"date"` + // Selector 单选/多选控件(control参数为Selector) + Selector OAContentSelector `json:"selector"` + // Members 成员控件(control参数为Contact,且value参数为members) + Members []OAContentMember `json:"members"` + // Departments 部门控件(control参数为Contact,且value参数为departments) + Departments []OAContentDepartment `json:"departments"` + // Files 附件控件(control参数为File,且value参数为files) + Files []OAContentFile `json:"files"` + // Table 明细控件(control参数为Table) + Table []OAContentTableList `json:"children"` + // Vacation 假勤组件-请假组件(control参数为Vacation) + Vacation OAContentVacation `json:"vacation"` + // Location 位置控件(control参数为Location,且value参数为location) + Location OAContentLocation `json:"location"` + // RelatedApproval 关联审批单控件(control参数为RelatedApproval,且value参数为related_approval) + RelatedApproval []OAContentRelatedApproval `json:"related_approval"` + // Formula 公式控件(control参数为Formula,且value参数为formula) + Formula OAContentFormula `json:"formula"` + // DateRange 时长组件(control参数为DateRange,且value参数为date_range) + DateRange OAContentDateRange `json:"date_range"` +} + +// OAContentDate 日期/日期+时间内容 +type OAContentDate struct { + // Type 时间展示类型:day-日期;hour-日期+时间 ,和对应模板控件属性一致 + Type string `json:"type"` + // Timestamp 时间戳-字符串类型,在此填写日期/日期+时间控件的选择值,以此为准 + Timestamp string `json:"s_timestamp"` +} + +// OAContentSelector 类型标志,单选/多选控件的config中会包含此参数 +type OAContentSelector struct { + // Type 选择方式:single-单选;multi-多选 + Type string `json:"type"` + // Options 多选选项,多选属性的选择控件允许输入多个 + Options []OAContentSelectorOption `json:"options"` +} + +// OAContentSelectorOption 多选选项,多选属性的选择控件允许输入多个 +type OAContentSelectorOption struct { + // Key 选项key,可通过“获取审批模板详情”接口获得 + Key string `json:"key"` +} + +// OAContentMember 所选成员内容,即申请人在此控件选择的成员,多选模式下可以有多个 +type OAContentMember struct { + // UserID 所选成员的userid + UserID string `json:"userid"` + // Name 成员名 + Name string `json:"name"` +} + +// OAContentDepartment 所选部门内容,即申请人在此控件选择的部门,多选模式下可能有多个 +type OAContentDepartment struct { + // OpenAPIID 所选部门id + OpenAPIID string `json:"openapi_id"` + // Name 所选部门名 + Name string `json:"name"` +} + +// OAContentFile 附件 +type OAContentFile struct { + // FileID 文件id,该id为临时素材上传接口返回的的media_id,注:提单后将作为单据内容转换为长期文件存储;目前一个审批申请单,全局仅支持上传6个附件,否则将失败。 + FileID string `json:"file_id"` +} + +// OAContentTableList 子明细列表,在此填写子明细的所有子控件的值,子控件的数据结构同一般控件 +type OAContentTableList struct { + // List 子明细列表,在此填写子明细的所有子控件的值,子控件的数据结构同一般控件 + List []OAContent `json:"list"` +} + +// OAContentVacation 请假内容,即申请人在此组件内选择的请假信息 +type OAContentVacation struct { + // Selector 请假类型,所选选项与假期管理关联,为假期管理中的假期类型 + Selector OAContentSelector `json:"selector"` + // Attendance 假勤组件 + Attendance OAContentVacationAttendance `json:"attendance"` +} + +// OAContentVacationAttendance 假勤组件 +type OAContentVacationAttendance struct { + // DateRange 假勤组件时间选择范围 + DateRange OAContentVacationAttendanceDateRange `json:"date_range"` + // Type 假勤组件类型:1-请假;3-出差;4-外出;5-加班 + Type uint8 `json:"type"` +} + +// OAContentVacationAttendanceDateRange 假勤组件时间选择范围 +type OAContentVacationAttendanceDateRange struct { + // Type 时间展示类型:day-日期;hour-日期+时间 + Type string `json:"type"` + // 时长范围 + OAContentDateRange +} + +// OAContentLocation 位置控件 +type OAContentLocation struct { + // Latitude 纬度,精确到6位小数 + Latitude string `json:"latitude"` + // Longitude 经度,精确到6位小数 + Longitude string `json:"longitude"` + // Title 地点标题 + Title string `json:"title"` + // Address 地点详情地址 + Address string `json:"address"` + // Time 选择地点的时间 + Time int `json:"time"` +} + +// OAContentRelatedApproval 关联审批单控件 +type OAContentRelatedApproval struct { + // SpNo 关联审批单的审批单号 + SpNo string `json:"sp_no"` +} + +// OAContentFormula 公式控件 +type OAContentFormula struct { + // Value 公式的值,提交表单时无需填写,后台自动计算 + Value string `json:"value"` +} + +// OAContentDateRange 时长组件 +type OAContentDateRange struct { + // NewBegin 开始时间,unix时间戳 + NewBegin int `json:"new_begin"` + // NewEnd 结束时间,unix时间戳 + NewEnd int `json:"new_end"` + // NewDuration 时长范围,单位秒 + NewDuration int `json:"new_duration"` +} + +// OATemplateDetail 审批模板详情 +type OATemplateDetail struct { + // TemplateNames 模板名称,若配置了多语言则会包含中英文的模板名称,默认为zh_CN中文 + TemplateNames []OAText `json:"template_names"` + // TemplateContent 模板控件信息 + TemplateContent OATemplateControls `json:"template_content"` + // Vacation Vacation控件(假勤控件) + Vacation OATemplateControlConfigVacation `json:"vacation_list"` +} + +// OATemplateControls 模板控件数组。模板详情由多个不同类型的控件组成,控件类型详细说明见附录。 +type OATemplateControls struct { + // Controls 模板名称,若配置了多语言则会包含中英文的模板名称,默认为zh_CN中文 + Controls []OATemplateControl `json:"controls"` +} + +// OATemplateControl 模板控件信息 +type OATemplateControl struct { + // Property 模板控件属性,包含了模板内控件的各种属性信息 + Property OATemplateControlProperty `json:"property"` + // Config 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。目前有配置信息的控件类型有:Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Table-明细;Attendance-假勤组件(请假、外出、出差、加班) + Config OATemplateControlConfig `json:"config"` +} + +// OATemplateControlProperty 模板控件属性 +type OATemplateControlProperty struct { + // Control 模板控件属性,包含了模板内控件的各种属性信息 + Control OAControl `json:"control"` + // ID 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。目前有配置信息的控件类型有:Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Table-明细;Attendance-假勤组件(请假、外出、出差、加班) + ID string `json:"id"` + // Title 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。目前有配置信息的控件类型有:Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Table-明细;Attendance-假勤组件(请假、外出、出差、加班) + Title []OAText `json:"title"` + // Placeholder 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。目前有配置信息的控件类型有:Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Table-明细;Attendance-假勤组件(请假、外出、出差、加班) + Placeholder []OAText `json:"placeholder"` + // Require 是否必填:1-必填;0-非必填 + Require uint8 `json:"require"` + // UnPrint 是否参与打印:1-不参与打印;0-参与打印 + UnPrint uint8 `json:"un_print"` +} + +// OATemplateControlConfig 模板控件配置 +type OATemplateControlConfig struct { + // Date Date控件(日期/日期+时间控件) + Date OATemplateControlConfigDate `json:"date"` + // Selector Selector控件(单选/多选控件) + Selector OATemplateControlConfigSelector `json:"selector"` + // Contact Contact控件(成员/部门控件) + Contact OATemplateControlConfigContact `json:"contact"` + // Table Table(明细控件) + Table OATemplateControlConfigTable `json:"table"` + // Attendance Attendance控件(假勤控件) + Attendance OATemplateControlConfigAttendance `json:"attendance"` +} + +// OATemplateControlConfigDate 类型标志,日期/日期+时间控件的config中会包含此参数 +type OATemplateControlConfigDate struct { + // Type 时间展示类型:day-日期;hour-日期+时间 + Type string `json:"type"` +} + +// OATemplateControlConfigSelector 类型标志,单选/多选控件的config中会包含此参数 +type OATemplateControlConfigSelector struct { + // Type 选择类型:single-单选;multi-多选 + Type string `json:"type"` + // Options 选项,包含单选/多选控件中的所有选项,可能有多个 + Options []OATemplateControlConfigSelectorOption `json:"options"` +} + +// OATemplateControlConfigSelectorOption 选项,包含单选/多选控件中的所有选项,可能有多个 +type OATemplateControlConfigSelectorOption struct { + // Key 选项key,选项的唯一id,可用于发起审批申请,为单选/多选控件赋值 + Key string `json:"key"` + // Value 选项值,若配置了多语言则会包含中英文的选项值,默认为zh_CN中文 + Value []OAText `json:"value"` +} + +// OATemplateControlConfigContact 类型标志,单选/多选控件的config中会包含此参数 +type OATemplateControlConfigContact struct { + // Type 选择类型:single-单选;multi-多选 + Type string `json:"type"` + // Mode 选择对象:user-成员;department-部门 + Mode string `json:"mode"` +} + +// OATemplateControlConfigTable 类型标志,明细控件的config中会包含此参数 +type OATemplateControlConfigTable struct { + // Children 明细内的子控件,内部结构同controls + Children []OATemplateControl `json:"children"` +} + +// OATemplateControlConfigAttendance 类型标志,假勤控件的config中会包含此参数 +type OATemplateControlConfigAttendance struct { + // DateRange 假期控件属性 + DateRange OATemplateControlConfigAttendanceDateRange `json:"date_range"` + // Type 假勤控件类型:1-请假,3-出差,4-外出,5-加班 + Type uint8 `json:"type"` +} + +// OATemplateControlConfigAttendanceDateRange 假期控件属性 +type OATemplateControlConfigAttendanceDateRange struct { + // Type 时间刻度:hour-精确到分钟, halfday—上午/下午 + Type string `json:"type"` +} + +// OATemplateControlConfigVacation 类型标志,假勤控件的config中会包含此参数 +type OATemplateControlConfigVacation struct { + // Item 单个假期类型属性 + Item []OATemplateControlConfigVacationItem `json:"item"` +} + +// OATemplateControlConfigVacationItem 类型标志,假勤控件的config中会包含此参数 +type OATemplateControlConfigVacationItem struct { + // ID 假期类型标识id + ID int `json:"id"` + // Name 假期类型名称,默认zh_CN中文名称 + Name []OAText `json:"name"` +} + +// OAControl 控件类型 +type OAControl string + +// OAControlText 文本 +const OAControlText OAControl = "Text" + +// OAControlTextarea 多行文本 +const OAControlTextarea OAControl = "Textarea" + +// OAControlNumber 数字 +const OAControlNumber OAControl = "Number" + +// OAControlMoney 金额 +const OAControlMoney OAControl = "Money" + +// OAControlDate 日期/日期+时间控件 +const OAControlDate OAControl = "Date" + +// OAControlSelector 单选/多选控件 +const OAControlSelector OAControl = "Selector" + +// OAControlContact 成员/部门控件 +const OAControlContact OAControl = "Contact" + +// OAControlTips 说明文字控件 +const OAControlTips OAControl = "Tips" + +// OAControlFile 附件控件 +const OAControlFile OAControl = "File" + +// OAControlTable 明细控件 +const OAControlTable OAControl = "Table" + +// OAControlLocation 位置控件 +const OAControlLocation OAControl = "Location" + +// OAControlRelatedApproval 关联审批单控件 +const OAControlRelatedApproval OAControl = "RelatedApproval" + +// OAControlFormula 公式控件 +const OAControlFormula OAControl = "Formula" + +// OAControlDateRange 时长控件 +const OAControlDateRange OAControl = "DateRange" + +// OAControlVacation 假勤组件-请假组件 +const OAControlVacation OAControl = "Vacation" + +// OAControlAttendance 假勤组件-出差/外出/加班组件 +const OAControlAttendance OAControl = "Attendance" + +// OAApprovalDetail 审批申请详情 +type OAApprovalDetail struct { + // SpNo 审批编号 + SpNo string `json:"sp_no"` + // SpName 审批申请类型名称(审批模板名称) + SpName string `json:"sp_name"` + // SpStatus 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付 + SpStatus uint8 `json:"sp_status"` + // TemplateID 审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。 + TemplateID string `json:"template_id"` + // ApplyTime 审批申请提交时间,Unix时间戳 + ApplyTime int `json:"apply_time"` + // Applicant 申请人信息 + Applicant OAApprovalDetailApplicant `json:"applyer"` + // SpRecord 审批流程信息,可能有多个审批节点。 + SpRecord []OAApprovalDetailSpRecord `json:"sp_record"` + // Notifier 抄送信息,可能有多个抄送节点 + Notifier []OAApprovalDetailNotifier `json:"notifyer"` + // ApplyData 审批申请数据 + ApplyData OAContents `json:"apply_data"` + // Comments 审批申请备注信息,可能有多个备注节点 + Comments []OAApprovalDetailComment `json:"comments"` +} + +// OAApprovalDetailApplicant 审批申请详情申请人信息 +type OAApprovalDetailApplicant struct { + // UserID 申请人userid + UserID string `json:"userid"` + // PartyID 申请人所在部门id + PartyID string `json:"partyid"` +} + +// OAApprovalDetailSpRecord 审批流程信息,可能有多个审批节点。 +type OAApprovalDetailSpRecord struct { + // SpStatus 审批节点状态:1-审批中;2-已同意;3-已驳回;4-已转审 + SpStatus uint8 `json:"sp_status"` + // ApproverAttr 节点审批方式:1-或签;2-会签 + ApproverAttr uint8 `json:"approverattr"` + // Details 审批节点详情,一个审批节点有多个审批人 + Details []OAApprovalDetailSpRecordDetail `json:"details"` +} + +// OAApprovalDetailSpRecordDetail 审批节点详情,一个审批节点有多个审批人 +type OAApprovalDetailSpRecordDetail struct { + // Approver 分支审批人 + Approver OAApprovalDetailSpRecordDetailApprover `json:"approver"` + // Speech 审批意见 + Speech string `json:"speech"` + // SpStatus 分支审批人审批状态:1-审批中;2-已同意;3-已驳回;4-已转审 + SpStatus uint8 `json:"sp_status"` + // SpTime 节点分支审批人审批操作时间戳,0表示未操作 + SpTime int `json:"sptime"` + // MediaID 节点分支审批人审批意见附件,media_id具体使用请参考:文档-获取临时素材 + MediaID []string `json:"media_id"` +} + +// OAApprovalDetailSpRecordDetailApprover 分支审批人 +type OAApprovalDetailSpRecordDetailApprover struct { + // UserID 分支审批人userid + UserID string `json:"userid"` +} + +// OAApprovalDetailNotifier 抄送信息,可能有多个抄送节点 +type OAApprovalDetailNotifier struct { + // UserID 节点抄送人userid + UserID string `json:"userid"` +} + +// OAApprovalDetailComment 审批申请备注信息,可能有多个备注节点 +type OAApprovalDetailComment struct { + // CommentUserInfo 备注人信息 + CommentUserInfo OAApprovalDetailCommentUserInfo `json:"commentUserInfo"` + // CommentTime 备注提交时间戳,Unix时间戳 + CommentTime int `json:"commenttime"` + // CommentTontent 备注文本内容 + CommentTontent string `json:"commentcontent"` + // CommentID 备注id + CommentID string `json:"commentid"` + // MediaID 备注附件id,可能有多个,media_id具体使用请参考:文档-获取临时素材 + MediaID []string `json:"media_id"` +} + +// OAApprovalDetailCommentUserInfo 备注人信息 +type OAApprovalDetailCommentUserInfo struct { + // UserID 备注人userid + UserID string `json:"userid"` +} + +// OAApprovalInfoFilter 备注人信息 +type OAApprovalInfoFilter struct { + // Key 筛选类型,包括:template_id - 模板类型/模板id;creator - 申请人;department - 审批单提单者所在部门;sp_status - 审批状态。注意:仅“部门”支持同时配置多个筛选条件。不同类型的筛选条件之间为“与”的关系,同类型筛选条件之间为“或”的关系 + Key OAApprovalInfoFilterKey `json:"key"` + // Value 筛选值,对应为:template_id - 模板id;creator - 申请人userid;department - 所在部门id;sp_status - 审批单状态(1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付) + Value string `json:"value"` +} + +// OAApprovalInfoFilterKey 拉取审批筛选类型 +type OAApprovalInfoFilterKey string + +// OAApprovalInfoFilterKeyTemplateID 模板类型 +const OAApprovalInfoFilterKeyTemplateID OAApprovalInfoFilterKey = "template_id" + +// OAApprovalInfoFilterKeyCreator 申请人 +const OAApprovalInfoFilterKeyCreator OAApprovalInfoFilterKey = "creator" + +// OAApprovalInfoFilterKeyDepartment 审批单提单者所在部门 +const OAApprovalInfoFilterKeyDepartment OAApprovalInfoFilterKey = "department" + +// OAApprovalInfoFilterKeySpStatus 审批状态 +const OAApprovalInfoFilterKeySpStatus OAApprovalInfoFilterKey = "sp_status" diff --git a/rx_msg.go b/rx_msg.go index 9846a7a..148e242 100644 --- a/rx_msg.go +++ b/rx_msg.go @@ -163,3 +163,9 @@ func (m *RxMessage) EventChangeExternalChat() (EventChangeExternalChat, bool) { y, ok := m.extras.(EventChangeExternalChat) return y, ok } + +// EventSysApprovalChange 如果消息为审批申请状态变化回调通知,则拿出相应的消息参数,否则返回 nil, false +func (m *RxMessage) EventSysApprovalChange() (EventSysApprovalChange, bool) { + y, ok := m.extras.(EventSysApprovalChange) + return y, ok +} diff --git a/rx_msg.md.go b/rx_msg.md.go index 7bfc8df..b86ec21 100644 --- a/rx_msg.md.go +++ b/rx_msg.md.go @@ -55,6 +55,9 @@ const EventTypeChangeExternalContact EventType = "change_external_contact" // EventTypeChangeExternalChat 客户群变更事件 const EventTypeChangeExternalChat EventType = "change_external_chat" +// EventTypeSysApprovalChange 审批申请状态变化回调通知 +const EventTypeSysApprovalChange EventType = "sys_approval_change" + // ChangeType 变更类型 type ChangeType string @@ -203,3 +206,9 @@ type rxEventChangeExternalChat struct { // ChatID 群ID ChatID string `xml:"ChatId"` } + +// rxEventSysApprovalChange 接收的事件消息,审批申请状态变化回调通知 +type rxEventSysApprovalChange struct { + // ApprovalInfo 审批信息、 + ApprovalInfo OAApprovalInfo `xml:"ApprovalInfo"` +} diff --git a/rx_msg_extras.go b/rx_msg_extras.go index 52c0230..0732374 100644 --- a/rx_msg_extras.go +++ b/rx_msg_extras.go @@ -63,6 +63,14 @@ func extractMessageExtras(common rxMessageCommon, body []byte) (messageKind, err case MessageTypeEvent: switch common.Event { + case EventTypeSysApprovalChange: + var x rxEventSysApprovalChange + err := xml.Unmarshal(body, &x) + if err != nil { + return nil, err + } + return &x, nil + case EventTypeChangeExternalContact: switch common.ChangeType { case ChangeTypeAddExternalContact: @@ -599,3 +607,23 @@ func (r *rxEventChangeExternalChat) GetFromUserName() string { func (r *rxEventChangeExternalChat) GetFailReason() string { return r.FailReason } + +// EventSysApprovalChange 审批申请状态变化回调通知 +type EventSysApprovalChange interface { + messageKind + + // GetApprovalInfo 获取审批模板详情 + GetApprovalInfo() OAApprovalInfo +} + +func (r rxEventSysApprovalChange) formatInto(w io.Writer) { + _, _ = fmt.Fprintf( + w, + "ApprovalInfo: %#v", + r.ApprovalInfo, + ) +} + +func (r rxEventSysApprovalChange) GetApprovalInfo() OAApprovalInfo { + return r.ApprovalInfo +}