跳到主要内容

工时拦截

要求

适用环境

  • 私有部署

ONES 版本

v6.3.0+

依赖包版本

{
"dependencies": {
"@ones-op/fetch": "0.46.12+",
"@ones-open/node-host": "0.4.2+",
"@ones/cli-plugin": "1.29.0+",
"@ones/cli-plugin-template": "1.10.8+",
"@ones-op/sdk": "0.46.7+"
}
}

特别地,还需要在插件 backend 也安装 @ones-open/node-host

cd backend/
npm install @ones-open/node-host@0.4.3+

能力概述

本文档提供工时拦截能力,客户可通过这个功能对工时的操作进行拦截,该能力为组织级别能力。在部分场景下,会出现同一数据多次收到多次拦截,所以使用该能力需保持行为的幂等性,保持行为的幂等性意味着即使同一拦截请求被多次触发,其效果应该如同只被触发一次一样,不会导致重复的数据处理或异常情况

工时验证器与插件

插件体系内,如何使用工时验证器呢?
在插件的 plugin.yaml 中添加工时验证器配置如下:

extension:
- manhourValidator: # 使用工时验证器功能扩展
provider: manhour # 字节数必须是8,后续不允许修改,谨慎定义。命名方式使用字母和数字组成的,不要使用其他特殊字符。
funcs:
- name: validate # 使用该能力必须注册,命名不能改
url: validate # 与插件内func名称一致

工时验证器与插件生命周期

工时验证器功能与插件生命周期操作存在绑定关系,如下表所示:

生命周期操作私有部署SaaS
安装组织级别:注册实例级别:注册
组织级别:注册
卸载组织级别:注销实例级别:注销
组织级别:注销

工时验证器实现

后端实现

  1. 创建文件 backend/src/manhour-validator.ts
import { FetchAsAdmin } from '@ones-op/fetch'
import { Logger } from '@ones-op/node-logger'
import type { PluginRequest, PluginResponse } from '@ones-op/node-types'

export async function validate(body: any): Promise<PluginResponse> {
Logger.info('body', body)
const haveError = true
if (haveError) {
return {
statusCode: 200,
body: {
error: {
reason: "这是一个错误提示", // 错误提示
level: "error" //错误级别
},
},
}
}
return {
statusCode: 200
}
}

请求体说明

插件注册相关能力,并实现对应方法后,会收到以下信息:

字段类型含义备注
teamUUIDstring团队uuid
userUUIDstring请求用户uuid
reqManhourRequest请求的工时相关信息

ManhourRequest 结构

type ManhourRequest struct {
Type string `json:"type"` // 预估、登记、剩余工时分类
Action string `json:"action"` // add、update、delete
Mode string `json:"mode"`
Options manhourModel.Options `json:"options"`
ManhourInfo []*ManhourInfo `json:"manhour_info"` // 工时的详细信息填充
}
字段类型含义备注
typestring工时分类登记 "recorded"
预估 "estimated"
剩余 "remaining"
以前端页面当前操作传入的工时为准
actionstring工时操作行为add、update、delete
这个信息有部分场景在add和update上不够准确,因为目前的业务架构不足以完全区分,插件尽量不要依赖该字段来区分是添加还是更新操作
modestring工时模式简单模式 "simple"
汇总模式 "detailed"
optionsOptions操作场景任务导入 "import_task" 其他场景该字段为空
manhour_info[]*ManhourInfo数组类型,详情字段见下面表格

ManhourInfo 结构

type ManhourInfo struct {
task *Task // 任务的具体信息
assess_manhour *AssessManhour // 预估工时的具体信息
remaining_manhour *RemainingHour // 剩余工时的具体信息
record_manhour *RecordManhour // 登记工时的具体信息
}
字段类型含义备注
task*Task任务的具体信息详见 Task 结构说明
assess_manhour*AssessManhour预估工时的具体信息详见 AssessManhour 结构说明
remaining_manhour*RemainingHour剩余工时的具体信息详见 RemainingHour 结构说明
record_manhour*RecordManhour登记工时的具体信息详见 RecordManhour 结构说明

Task 结构

字段类型含义备注
UUIDstring任务UUID
TeamUUIDstring团队UUID
Ownerstring任务所有者
Assignstring任务负责人
ProjectUUIDstring项目UUID
IssueTypeUUIDstring工作项类型UUID
ParentUUIDstring父任务UUID
SubIssueTypeUUIDstring子工作项类型UUID
IsCreateTaskbool是否新建任务

AssessManhour 结构

字段类型含义备注
UUIDstring预估工时UUID
Fromint64开始时间
Toint64结束时间
HoursFormatstring工时格式
IncludeNonWorkingDayint64是否包含非工作日
Hoursfloat64工时数
Ownerstring工时所有者
StartTimefloat64开始时间汇总模式-修改预估工时会填

RemainingHour 结构

字段类型含义备注
UUIDstring剩余工时UUID
Hoursfloat64剩余工时数
Ownerstring工时所有者

RecordManhour 结构

字段类型含义备注
UUIDstring登记工时UUID
StartTimefloat64开始时间
Descriptionstring工时描述
Hoursfloat64工时数
Ownerstring工时所有者

Options 结构

type Options struct {
// 用 scene 来判断是否需要权限校验
Scene string `json:"scene"`
}

最佳实践

  1. 保持行为的幂等性:即使同一拦截请求被多次触发,其效果应该如同只被触发一次一样,不会导致重复的数据处理或异常情况。
  2. 错误处理:当方法的 error 不等于空的时候,前端工时的操作行为就会失败,错误需要在真正需要中断的时候返回。
  3. 错误码结构:
//服务内部异常可以直接返回错误。
error: {
reason: "这是一个错误提示", // 错误提示
level: "error" //错误级别
}