# 使用说明

# 项目管理入口

如下图所示,点击左侧菜单“项目管理”,可以以不同标签页查看企业项目列表。 点击右上角“新建”按钮,可以进入项目创建界面。 在创建项目时,可以选择项目是保密还是公开。但是此时不能进行详细的权限设置。项目创建完成后,可以进入项目设置菜单进行详细设置。 注:项目的英文标识不可更改 同时,还可以选择基于模板或者其他已经存在的项目快速创建新项目。 在企业设置--》项目设置中可以创建项目的基本信息字段。在新建项目页面会显示在此开启的字段。 在企业设置的项目设置中可设置项目模板,并且设置项目工作流规则:有“项目自定义+引用项目模板”和“引用项目模板”两种方式。

  • 若使用“项目自定义+引用项目模板” 在创建项目时,可以选择引用已有的项目模板,也可以选择自定义项目模板。当选择项目自定义时,用户可以基于项目模板创建也可以选择基于已有项目创建项目。 在项目创建完成后,用户可以在项目设置--》基本设置的工作流设置规则中将自由切换项目工作流为“项目自定义”和“引用项目模板” 项目自定义
  • 若使用“引用项目模板”, 在创建项目时,只能选择引用已有的项目模板。 项目创建完成后,用户可以在项目设置--》基本设置的工作流设置规则中也只能选择“引用项目模板” 新建项目 并且可以在项目列表页中查看显示项目的属性字段以及按照项目属性字段进行筛选操作 项目列表

# 项目概览

项目概览视图是针对该项目的里程碑、报表、项目通告进行集中展现。如果在项目中配置了关联的代码库,则还可以显示关联的代码信息、关联的构建信息。

项目概览

# 产品规划

产品规划类似于故事地图,横轴是项目的规划纵轴是计划,可以将未规划的卡片拖动到相应的分类中。在规划版的下拉中切换不同的规划 其中只筛选未规划开启时,类型和状态的筛选只对未规划下的卡片生效。
此功能常用于团队内对齐思路,理解工作价值。
产品规划

# 计划与看板

在项目执行过程中,可使用此功能对项目进展进行跟踪。可以时间或者版本维度设置计划。此模块功能支持:

  • 查看分工图和燃起图

  • 显示当前计划的剩余时间、未完成的卡片数、延期的卡片数

  • 对卡片批量修改卡片类型、迁移、复制、导入、导出、删除、设置父任务

  • 左右拖动到计划盒排计划

  • 顶部人员工作量分工清晰展示

  • 支持对计划进行归档

# 列表视图

列表视图是针对项目计划会场景进行了诸多特殊优化的功能。

  • 承诺交付线便于鼓励大家制定更高的目标时,又守住交付底线

  • 上下拖动排优先级 计划会视图

# 层级视图

层级视图和列表视图很类似,区别如下: ①可显示卡片的层级关系 ②对于层级关系树中不在本计划中的卡片同样会显示,但是会置灰 ③上下位置关系不再代表优先顺序,而是支持按不同列排序 ④如果卡片关联的子级和父级不在同一个计划中,卡片的子级会显示置灰

层级视图

不论是列表视图还是层级视图都有批量操作:修改字段、修改状态、修改类型、迁移、复制、导入、导出、删除和设置父卡片。 其中导入功能支持同时导入多个卡片类型并支持父子层级卡片的导入。

层级视图

# 看板视图

看板视图适合在项目进行过程中可视化查看项目状态, 并且支持全屏模式支持站会场景,支持拖拽查看卡片状态。 同样也支持对计划进行操作 看板视图

# 查看归档计划

对于已经归档的计划,可以点击图示菜单查看,并且支持解除归档。 归档

# 甘特图

横轴表示时间,纵轴表示计划,中间区域显示计划的开始时间、完成时间、理想进度和实际进度。可以定义甘特图的查看视图如:年、季度、月、周。并支持将甘特图导出为Excel。 甘特图

# 卡片管理

卡片查询内置三个基本查询、点击“全部” 设置筛选条件。 当修改了查询条件后,可以点击“另存为" 按钮存储为一个自定义查询。 可以通过切换“列表”和“层级”不同维度去查看卡片 卡片查询

# 创建卡片

点击新建卡片,根据您的需要选择卡片的类型,并填写一些必要字段,关联卡片时可以选择项目(可以关联其他项目的卡片) 创建卡片

# 快速添加卡片

快速添加卡片类似于在excel中添加一行内容似的创建一个卡片,快速创建卡片会绕过一些必填项,只需要填写卡片类型和卡片标题即可创建成功。 快速添加卡片

# 批量创建子卡片

在卡片详情页中的更多操作中点击批量创建子卡片,批量创建子卡片可直接填写必填项。 批量创建子卡片

# 卡片详情

研发数据链

  • Wiki:卡片详情页可直接关联Wiki页面 关联wiki
  • 关联文档:卡片详情页可直接关联文档管理的文件或上传文件、文件夹 关联文件 在关联文档页面可以直接上传文件或文件夹,上传后的文件或文件夹的文件自动与卡片进行关联
  • 关联分支:卡片详情页可直接新建分支或关联已有分支 点击页面中的创建分支后选择代码库、填写分支名以及基于哪个分支创建,点击确定后会创建分支并将创建的分支与卡片进行关联 关联文件 关联分支:选择代码库后选择代码库中已有分支点击确定后代码库中的分支即可与此卡片进行关联 关联文件
  • 关联push、commit、评审 复制卡片详情右上角的卡片编号和标题,将复制的卡片编号和标题填写到提交代码时的commit message中,卡片即可与push、commit信息进行关联,当创建评审的源分支有关联卡片则评审直接与此卡片进行关联。 关联文件 关联文件 其中在评审的tab页中可直接选择状态为评审中的评审,对于已废弃和已完成的评审是无法与卡片进行关联的 关联文件
  • 关联接口、用例、执行记录 点击右侧的添加、选择关联的测试空间后选择接口、用例和执行记录即可 关联文件

# 登记工时

当在企业设置--》项目设置中开启登记工时或者项目设置--》工时设置中开启登记工时时,若开启工时登记审批时,则审批通过的工时汇总到实际工时中;若未开启工时登记审批时,登记的工时直接汇总如实际工时中 关联文件

# 筛选器

分为个人筛选器和公共筛选器,其中个人筛选器为创建筛选器的个人用户才能看到的,公共筛选器为项目内所有成员都能看到的筛选器。 系统内置三个筛选器分别为:全部、我创建的和我负责的。分别代表项目内所有的卡片、我创建的为我创建的所有的卡片、我负责的为我是负责人的所有的卡片,其中默认为未归档的卡片,勾选包含归档卡片后显示归档和未归档的全部卡片。 筛选器

# 自定义报表

# 创建报表

创建报表前需要先创建分组,在不同的分组中创建报表。 新建报表时选择不同的报表类型,查询条件等,会以不同的形式显示报表数据如下图 创建报表

其中成员负载甘特图为成员在选定时间内的负载情况,需要在卡片中填写计划开始时间、计划完成时间和估算工时进行计算。 计算公式为:估算工时/8/(计划开始时间和计划完成时间的相差天数-非工作日时间) 其中8为工作日的工作时长。当算出来的结果大于100%时代表超过每天8小时。

成员负载甘特图

开启登记工时后可使用“登记工时汇总”和“登记工时明细”两种报表统计成员的实际工时。

成员负载甘特图

# 产品版本

产品版本是对项目内的产品版本进行管理,可对产品版本进行增删改查。 产品版本可与代码库的版本进行关联,关联后可将与代码库关联的卡片与产品版本自动关联。 注:产品版本在关联代码库时的限制:后面创建的产品版本不可关联比前面产品版本关联的相同代码库低版本 如创建了产品版本v1关联了a代码库的v2版本,创建的产品版本v2只能关联a代码库的v2及大于v2的版本,不可关联代码库a比v2低的版本。 产品版本

两个产品版本可进行对比,对比内容会将两个版本差之间所有的卡片、sql、资源全部展示出来。 产品版本

# 卡片回收站

对于已经删除的卡片,可以在卡片回收站中进行还原 卡片回收站

# 设置

# 基本设置

在基本设置中可以对项目的英文标识,权限类型等基本信息进行设置。 权限类型的说明参见Tooltip中的文字说明。 对于企业内公开的项目:企业所有成员均有项目的读权限,并且可以在项目的需求池新建卡片,用于公共项目收集反馈。 在基本设置中还可以修改工作流的类型变为项目自定义还是引用项目模板 基本设置

# 角色管理

通过角色对权限进行控制,内置3个系统角色,其中在给访客创建某种类型的卡片的权限时,只能在需求池中创建不能将创建的卡片添加到其他计划中,删除时只能删除自己创建的在需求池中的卡片

# 成员设置

通过给用户分配角色实现对用户权限的控制

# 关联设置

项目管理空间可以关联wiki空间、文档管理空间、代码库、制品库、测试空间、主机组 其中关联代码库时可关联内置代码库和GitLab代码如下图: 关联代码库 其中关联gitlab代码后,在卡片详情页中的研发数据链中可选择关联的代码库的分支。

# 运维操作

可以在运维操作设置界面中删除项目、设置回收站的清理周期、归档的计划的清理周期

# 工时设置

工时审批可以设置企业中统一设置实际工时填写方式,当开启时,全部项目均按照此企业中设置的方式填写实际工时,若不开启时均按照项目中设置的工时方式填写工时。 填写实际工时的方式有两种

  • 直接填写实际工时
  • 按照登记的方式填写工时最后汇总到实际工时:可按照卡片类型设置审批流,并且可设置登记工时的审批和删除工时的审批

# 概览设置

因为内置的报表以及关联设置比较多,可在设置中的概览设置对显示内容进行设置

项目概览

# 卡片类型

此处定义的是整个项目的卡片类型开关。项目管理默认支持11种卡片类型,包括通用的事务类型卡片用于非研发任务、非研发项目。

# 流程状态

此处设置整个项目的流程状态全集,以及不同类型的卡片启用的状态集合。 可以对状态进行新建和删除操作。 注意事项: 删除状态时,会提示之前该状态的卡片这状态批量转换为其他状态,否则会导致数据不一致。 流程状态

# 自动化事件

自动化事件是针对卡片类型进行的事件触发,可以设置卡片类型、事件类型、触发条件、触发条件值、执行的操作。 自动化事件 事件类型:

  • 代码类事件:代码提交、发起及更新评审、评审通过、评审驳回、评审合入、发布版本
  • 卡片事件:卡片字段的更新

# 创建自动化事件

新建事件时先选择事件类型,事件类型不同,触发条件也不相同。其中触发条件中每个条件组之间的条件是且的关系,不同条件组是或的关系。 自动化事件 在动作详情中若字段选择流程状态时,若勾选遵循工作流限制时,设置的动作类型的卡片的原状态流转为目标状态时,若此卡片类型的工作流中从原状态可流转为目标状态时则可直接变更,若不可流转时则不可直接变更 自动化事件 当原状态流转为目标状态设置审批流时也不可进行自动流转

# 后置动作

后置动作是针对事件触发后执行的操作,目前支持脚本和WebHook两种类型。后置动作是针对时间类型为“卡片类” 自动化事件

# WebHook

在webhook中可以设置想要调取的接口,支持POST、GET两种请求方式,在请求参数中可以设置请求参数的值,支持变量和常量两种方式。系统变量中可传递卡片的字段包括系统内置字段和卡片自定义字段。 只能选择数据格式为“本平台”且类型为“自定义服务”的webhook webhook

# 脚本

脚本支持groovy和java语言,在脚本中可以卡片的字段包括系统内置字段和卡片自定义字段及卡片所在项目的一些字段。 脚本

  1. 适用场景:用于以http接口调用为主的、快速执行的轻量级任务。groovy受限执行,有着不仅限于如下所列的安全限制: 1.1 禁止操作文件系统 1.2 禁止通过groovy执行shell等命令 1.3 禁止启动线程 1.4 禁止exit退出

  2. groovy教程:(groovy3) https://groovy-lang.org/syntax.html#_single_line_comment (opens new window)

    2.1 groovy简易入门

    2.1.1 兼容java(java8)

    2.1.2 定义和使用变量:

      ```java
      def title2 = '演示功能第2版'
      String title3 = '演示功能第3版'
      def title = cardDetail.title
      def num1 = 123
      def num2 = num1 
      int num3 = num1
    
      ```
    

    2.1.3 拼接字符串:

      ```java
      def log = '更新卡片:' + title
      def log = "更新卡片:${title}"
    
      ```
    

    2.1.4 列表和对象:

      ```java
      def userNames = ['u1', 'u2']
      List<String> userNames2 = userNames
      def userName = userNames[0]
      def userObj = [userId: 1, userName: 'tom']
      def userId = userObj.userId
    
      ```
    
  3. Unirest教程:用于发起http请求 https://kong.github.io/unirest-java/#requests (opens new window)

    3.1 Unirest简易入门

    def url = 'https://user.com' 
    def userId = 123
    def response = Unirest.put("${url}/user/${userId}") // 请求地址
      .header('accept', 'application/json') // 请求头
      .queryString('disable', false) // 定义请求地址query部分:例子:?disable=true&department=erp
      .queryString('department', 'erp')
      .body([ // 请求体
        name: 'tom',
        age: 27
      ])
      .asString() // 请求返回body解析为字符串
    println response.status // 状态码,如200,404
    println response.body // body为字符串
    
    def response = Unirest.put(url)
      .asEmpty() // 对请求返回body不做解析
    println response.status
    
    def reponse = Unirest.put(url)
      .asObject(Map.class) // 请求返回body解析为map对象
    println response.body.code // body是map对象,可以访问map对象下展开字段的信息
    println response.body?.data?.id 
    
    def reponse = Unirest.put(url)
      .asObject(List.class) // 请求返回body解析为list对象
    println response.body[0] // body是list对象,可以访问list对象下展开字段的信息
    
    
  4. 卡片上下文:

    4.1 变量:

    // 上下文变量:
    baseUrl: 'https://ezone.ezone-dev.com' // 平台地址
    cardId: 123 // 卡片唯一ID
    cardDetail: // 卡片详情,具体例子可以到卡片详情页查看卡片接口所返回的信息,卡片字段列表可以到项目设置中查看
      status: 'open' // 卡片详情对象展开的状态字段,通过cardDetail.status获取
      type: 'bug'
      title: 'demo1'
      owner_users: ['tom']
      company_custom_1_long: 123 // 企业自定义字段
    
    

    4.2 工具

    // 工具 
    rest: // 参考Unirest使用文档,用于发起http请求,例rest.get("/api1");但是不要直接使用全局级的Unirest.get("api1"),因为其设置复用,随时可能被改,不稳定
    
    
  5. 例子:

    卡片自动化事件里配置如下groovy脚本,把卡片状态改为open(新建状态)

    if (cardDetail.status == 'open') {
      return
    }
    
    println "${new Date()} 开始更新卡片${cardDetail.title}的状态"
    // rest默认baseUrl为本平台,平台接口具体使用请参考接口文档。非本平台接口,需要传递完整地址,例rest.put("https://www.baidu.com/search")
    def response = rest.put("/v1/project/project/card/${cardId}/status") 
      .queryString('access_token', 'c9a392ee465ebeadf867914f01ae5ae60649989855565') // 个人中心的访问token
      .queryString('status', 'open')
      .asString()
    println response.status
    
    
    
    

    卡片自动化事件里配置如下groovy脚本,可以把卡片关联的文档和制品的下载地址推送给其它平台

    def response = rest.get("/v1/project/project/card/${cardId}/doc")
            .queryString('access_token', 'c9a392ee465ebeadf867914f01ae5ae60649989855565')
            .asObject(Map.class)
    def docUrls = response.body?.data?.refs
            ?.collect { spaceFiles -> spaceFiles?.fileDetails?.collect { "${baseUrl}/v1/doc/space/${it.spaceId}/file/download?fileId=${it.id}" } }
            ?.flatten()
    
    response = rest.get("/v1/project/project/card/${cardId}/artifact")
         .queryString('access_token', 'c9a392ee465ebeadf867914f01ae5ae60649989855565')
         .queryString('containsDescendant', true)
         .queryString('withDownloadCmds', true)
         .asObject(Map.class)
    def artifactUrls = response.body?.data?.collect {it.downloadCmds}?.flatten()
    println docUrls
    println artifactUrls
    // 推送卡片关联文档和制品的下载地址,此处只是示例,请根据外部平台的接口定义来修改请求
    def pushUrl = 'http://外部平台/api'
    response = rest.post(pushUrl)
            .body([
                    docUrls: docUrls,
                    artifactUrls: artifactUrls
            ])
            .asEmpty()
    println response.status
    
    
    

# 执行顺序

执行顺序是针对自动化事件中多个事件进行执行顺序的设置,当多个事件同时满足触发条件时,按照执行顺序的顺序依次执行。

# 字段集

此处设置的字段集是项目中所有卡片类型使用的字段的集合,每种卡片类型只需要设置自己需要的字段开关即可。在此处统一配置避免不同卡片重复添加相同或者近似的字段。 系统内置的字段不可编辑和删除、项目特殊需求可以通过新建自定义字段。 字段集

# 字段触发器

在设置工作项字段的时候,经常会遇到多个字段之间有关联关系的情况,例如:当工作项的“模块”字段是“模块A”时,其前端负责人字段要设置成“小简”,后端负责人字段要设置成“小单”,测试负责人字段要设置成“小云”,每次这么逐个手工设置不仅费时费力,而且还容易设置错误,甚至每次设置前,还需要查一下公司文档,看看每个功能模块负责人是谁。 字段触发器可以自动完成关联字段填写。 触发器

# 卡片设置

对于项目中启用的卡片类型,可以分别设置他们的字段、模板、工作流、自动流转

# 字段设置

字段设置中,可以设置对某个特定的卡片类型,启用项目字段集中的哪些字段,以及其他更多设置。 卡片字段设置

# 内容模板

作为团队研发规范,可以为每种卡片类型设置规定的模板。

# 工作流

卡片工作流可以设置哪些状态为结束状态,结束状态的设置会影响项目进度的统计,燃起图等场景。并且可以设置状态的流转规则,禁止某些状态间乱拖动。 其次是可以设置某些状态间的流转是否进行权限约束,并支持审批流的设置:在流程审批系统的审批流中创建审批流后,审批流的成员可以在工作流的审批流设置中看到审批流。在状态流转时设置审批流后,卡片的初始状态调整我目标状态时卡片详情页、卡片列表页、看板视图都中此卡片都将锁定为初始状态,并发起一条审批流待审批通过后卡片的状态自动变更为目标状态。 卡片工作流设置