H3 Workflow自由流的实现

本文介绍了一种在H3工作流平台实现自由流的方法,即允许用户自定义流程步骤及审批人的流程。通过限制步骤数量并在发起时设置审批人的方式实现了客户需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       最近一年的时间都在做H3工作流的项目,作为国产的一个工作流产品H3已经做得很好了,面对如此庞大复杂的一个客户环境H3基本上完成了他们所有的功能。H3开发流程的一个主要特点就是开发速度快,笔者曾经一天做了4个简单的流程,业务复杂的流程也顶多花了3天的时间就能搞定,K2流程的开发就稍微显得繁琐。由于H3的引擎是自己开发的,这一点和K2是不同的,K2是基于Microsoft的WF的,K2的可定制化很高,H3的定制化没有K2那么灵活。在与客户各种系统集成的过程中我们遇到了很多困难,经过求助H3支持工程师和与客户方协同商量基本上都解决了。

     下面简单介绍一下H3中自由流的实现,自由流就是所有的流程步骤,步骤当中的审批人都是由用户自己设置的。这种情况在workflow中时不允许出现的,因为BPM的目标之一就是规范业务审批流程步骤,禁止用户自己控制流程的走向以及审批人。如果存在这种流程的话,那么用户肯定不会使用其他的业务流程了,全部都使用自由流了,这跟传统的OA审批流程没有任何区别也就失去了BPM的意义。但是由于客户方态度很强硬,一定要求实现这种流程功能,没办法,只能硬着头皮做了一个勉强算是自由流的一个流程,步骤如下。

     1.开发H3流程首先就是流程图的绘制,客户想要的自由流是完全自己设置流程的步骤,可多可少,可大可小,跟孙悟空的金箍棒似的,这一点我们明确表示产品没法做到。因为H3必须在流程图确立的情况下才能运行流程,不能在过程中随意修改流程图也没法修改。经过协商,决定流程步骤限死为10个步骤,不允许超过10个步骤的审批,流程图如下:

     

在这里我们设置了10个审批步骤,而且数据项里面我们还添加了10个参与者数据类型的审批人,名称分别为:审批人1,审批人2,……,审批人10.

     2.下面就是流程的发起界面了,自由流需要在发起界面的时候设置这10个步骤的审批人(当然也可以少于10个人),发起界面如下:

发起界面我们有一个 流程模板 选择界面,点击这一个选择按钮进入 设置流程审批步骤的审批人界面,简单界面如下:

很简单的一个table,简单看一下这个选人界面的后台代码,为了方便用户打开这个设置人界面时之前的数据依旧可以展示出来,我们将选择的结果放在一个session里面,页面卸载的时候移除session。

    /// <summary>
    /// 初始化数据
    /// </summary>
    private void InitData()
    {
        DataTable dt;
        if (Session["dt"] != null)
        {
            dt = Session["dt"] as DataTable;
        }
        else
        {
            dt = DefineDataTableSchema(hfRptColumns.Value);
            DataRow row;
            for (int i = 1; i <= 3; i++)
            {
                row = dt.NewRow();
                row["StepName"] = "";
                row["UserID"] = "";
                dt.Rows.Add(row);
            }
        }
        repDt.DataSource = dt;
        repDt.DataBind();
    }

    //添加行
    protected void btnAdd_Click(object sender, EventArgs e)
    {
        DataTable dt = GetDataSource();
        Button btn = sender as Button;
        string curNum = btn.CommandArgument;
        DataRow row = dt.NewRow();
        row["StepName"] = "";
        row["UserID"] = "";
        dt.Rows.InsertAt(row, Int32.Parse(curNum));
        repDt.DataSource = dt;
        repDt.DataBind();
    }

    //删除行
    protected void btnDel_Click(object sender, EventArgs e)
    {
        DataTable dt = GetDataSource();
        Button btn = sender as Button;
        string curNum = btn.CommandArgument;
        dt.Rows.RemoveAt(Int32.Parse(curNum) - 1);
        repDt.DataSource = dt;
        repDt.DataBind();
    }

    //保存数据
    protected void btnSave_Click(object sender, EventArgs e)
    {
        DataTable dt = GetDataSource();
        Session.Add("dt", dt);
        string js = "<script>window.opener.setValue();window.close();</script>";
        Page.ClientScript.RegisterStartupScript(Page.GetType(), "msg", js);
    }

    /// <summary>
    /// 根据repeater相对应的列名,定义数据源datatable的schema
    /// </summary>
    /// <param name="columns">列名</param>
    /// <returns>datatable的schema</returns>
    private DataTable DefineDataTableSchema(string columns)
    {
        DataTable dt = new DataTable();
        string[] columnsAry = columns.Split(',');
        foreach (string str in columnsAry)
        {
            dt.Columns.Add(str);
        }
        return dt;
    }

    /// <summary>
    /// 获取数据源
    /// </summary>
    /// <returns>数据源</returns>
    private DataTable GetDataSource()
    {
        DataTable dt = DefineDataTableSchema(hfRptColumns.Value);
        foreach (RepeaterItem item in repDt.Items)
        {
            DataRow newRow = dt.NewRow();
            newRow["StepName"] = ((TextBox)item.FindControl("txtStepName")).Text;
            string[] selectuser = ((UserSelector)item.FindControl("userSelector")).SelectedUsers;
            string userid = "";
            foreach (string user in selectuser)
            {
                userid += user;
                userid += ";";
            }
            newRow["UserID"] = userid;
            dt.Rows.Add(newRow);
        }
        Session["dt"] = dt;
        return dt;
    }

    protected void repDt_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (Session["dt"] != null)
        {
            DataTable dt = Session["dt"] as DataTable;
            int index = e.Item.ItemIndex;
            //确保处理的是数据行,而不是Header或者Footer 
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem
                || e.Item.ItemType == ListItemType.SelectedItem)
            {
                UserSelector userSelector = ((UserSelector)e.Item.FindControl("userSelector")) as UserSelector;
                string[] selectuser = dt.Rows[index]["UserID"].ToString().Split(';');
                userSelector.SelectedUsers = selectuser;
            }
        }
    }


         3.用户设置好流程的审批人之后,下面就是在我们发起界面的SaveDataFields(OThinker.H3.WorkSheet.SheetSubmitEventArgs Args)事件里面依次给我们的 审批人赋值,简单代码如下:

        /// <summary>
        /// 设置流程步骤审批信息
        /// </summary>
        private void SetFlowApprovePerson()
        {
            DataTable dt = Session["dt"] as DataTable;
            if (dt != null && dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    if (dt.Rows[i]["StepName"] != null && dt.Rows[i]["UserID"] != null
                        && dt.Rows[i]["StepName"].ToString() != "" && dt.Rows[i]["UserID"].ToString() != "")
                    {
                        string stepName = "审批步骤名称" + (i + 1).ToString();
                        this.Enviroment.InstanceData[stepName].Value = dt.Rows[i]["StepName"].ToString();

                        string stepPerson = "审批人" + (i + 1).ToString();
                        string[] selectuser = dt.Rows[i]["UserID"].ToString().Split(';');
                        this.Enviroment.InstanceData[stepPerson].Value = selectuser;
                    }
                }
            }
        }

 在这里我们循环遍历DataTable给流程的审批人数据赋值。下面我们看一下审批效果:

      

 

整个自由流的创建过程基本上就是这样,其实也是很简单的,只要手工给每一个审批步骤设置好审批人就可以了。这接近一年的H3使用过程中感觉H3产品功能很全面,要是细节方面能完善一下,美工做得更好一点,我相信一定是一个非常不错的产品。

<h3 id="sec3.1">3.1 涉及底层JIRA程</h3> <!-- 提示用户可以查看详情页 --> <div class="note"> <p>点击左侧目录中的“详细”图标查看该内容的独立详情页,适合完整阅读。</p> </div> <!-- 添加完整详细3.1.1 --> <div class="detail-section"> <h3>3.1.1 背景与目标</h3> <h4>3.1.1.1 背景</h4> <p>随着项目规模扩大和团队人数增加,原有的问题处理程暴露出以下痛点:</p> <ul> <li> <h5>问题分类不明确,转效率低下</h5> <p>缺乏统一的问题归类标准,导致问题在项目或多个团队转时增加不确定性。</p> </li> <li> <h5>责任归属不清晰,团队间推诿</h5> <p>问题分配机制和责任人界定不完善,问题解决的推动效率降低。</p> </li> <li> <h5>缺乏标准化字段,统计分析困难</h5> <p>没有标准化字段体系支撑,无法轻松完成问题类型、数量或原因的数据统计分析。</p> </li> <li> <h5>新成员学习成本高,程掌握时间长</h5> <p>程不直观,新成员需要时间熟悉复杂的分类或操作。</p> </li> </ul> <h4>3.1.1.2 目标</h4> <div class="field-detail"> <ol> <li><strong>定义标准化操作步骤</strong>:为底层工程师提供清晰的问题处理程</li> <li><strong>优化问题转效率</strong>:通过字段分类实现问题快速分配</li> <li><strong>确保数据可追溯</strong>:完整记录问题处理过程,便于后续分析</li> <li><strong>降低学习曲线</strong>:新成员可快速掌握团队工作流程</li> </ol> </div> </div> <!-- 添加完整详细3.1.2 --> <div class="detail-section"> <h3>3.1.2 JIRA程相关字段属性介绍</h3> <h4>字段属性介绍</h4> <table> <thead> <tr> <th>字段名称</th> <th>字段说明</th> <th>填写要求</th> </tr> </thead> <tbody> <tr> <td><strong>Component/s</strong></td> <td>用于指定涉及底层问题所对应的技术栈,例如 IoHwAb_Stack, Com_Stack 等。</td> <td>必填字段,至少选一个技术栈模块。如果Custom_2不是“非BSW问题”,需要重新检查Component/s选择正确的协议栈来匹配问题。(程的任何阶段都可以修改属性)</td> </tr> <tr> <td><strong>Custom_1</strong></td> <td>用于问题的快速转。需要处理问题的部门分类,例如 BSW(基础软件)、HW(硬件)、ASW(应用层软件)、Other(其他)。</td> <td>试点项目必填字段(建jira和转问题时关注),确保问题建立时明确责任归属或下一步转对象。</td> </tr> <tr> <td><strong>Custom_2</strong></td> <td>涉及底层问题分析的结果归类</td> <td>必填字段,根据问题分析结果选择适当选项,支持动态调整。(程的任何阶段都可以修改属性)</td> </tr> <tr> <td><strong>Assignee</strong></td> <td>问题的任务负责人或分配人,它表示当前任务或者工作项(如 Story、Task、Bug 等)被分配给了谁,需要由这个人来完成任务或处理问题。。</td> <td>在确定问题分类后指派给合适的责任人,例如底层开发工程师或平台工程师。</td> </tr> <tr> <td><strong>Comment</strong></td> <td>自由文本,记录问题的描述、分析说明以及责任转交原因。</td> <td>重要字段,用以清晰记录问题处理过程,便于后续问题追踪或评估。</td> </tr> </tbody> </table> </div> <!-- 添加完整详细3.1.3 --> <div class="detail-section"> <h3>3.1.3 字段属性的具体类别</h3> <h4>3.1.3.1 Component/s 属性</h4> <ol> <p><strong>定义:</strong> 表示问题的初步分类,例如 BSW、HW、ASW 等。</p> <p><strong>适用范围:</strong> 全部项目。</p> <p><strong>类型列表:</strong> 用于简单分类问题所涉及的技术栈模块,以规范问题范围。</p> <table> <thead> <tr> <th>类型</th> <th>说明</th> <th>关键模块</th> </tr> </thead> <tbody> <tr> <td><strong>Cdd_Stack</strong></td> <td>为特定硬件设备或自定义硬件提供支持,针对复杂设备功能,满足标准化 API 无法实现的需求。</td> <td> <p>• 自定义设备驱动(CDD): 根据具体设备需求开发的驱动模块。</p> <p>• RTE(运行时环境): 确保与上层通信。</p> <p>• 直接与硬件寄存器交互以实现底层逻辑。</p> </td> </tr> <tr> <td><strong>Com_Stack</strong></td> <td>管理 ECU 间及 ECU 与外部工具的通信,确保信号与数据高效、稳定传输。</td> <td> <p>• Com(通信管理器): 应用层管理信号与 PDU。</p> <p>• PduR(PDU 路由模块): 管理上下层模块的数据路由。</p> <p>• 接口模块(CAN/LIN/FlexRay/Ethernet): 如 CanIf、LinIf。</p> <p>• SoAd 和 TcpIp: 提供以太网通信功能。</p> </td> </tr> <tr> <td><strong>Diag_Stack</strong></td> <td>提供 ECU 的诊断支持,包括故障记录、诊断服务和外部工具交互,符合 UDS(ISO 14229)标准。</td> <td> <p>• Dcm(诊断通信管理器): 提供诊断服务(如读取故障码)。</p> <p>• Dem(诊断事件管理器): 记录并存储故障信息。</p> <p>• FIM(故障禁用管理): 管理功能禁用逻辑。</p> </td> </tr> <tr> <td><strong>CybSec_Stack</strong></td> <td>提升 ECU 通信安全性,保证数据完整性、机密性,并防护潜在的恶意攻击。</td> <td> <p>• SecOC(安全本地通信模块): 确保通信完整性和真实性。</p> <p>• CryIf(加密接口模块): 提供通用的加密接口。</p> <p>• Csm(加密服务管理器): 调度加密算法。</p> <p>• KeyM(密钥管理模块): 管理密钥生成与分配。</p> <p>• 防火墙模块: 过滤并保护数据。</p> </td> </tr> <tr> <td><strong>Fbl_Stack</strong></td> <td>符合 ISO 26262 标准,提供功能安全支持,避免关键系统由于故障进入危险的运行状态。</td> <td> <p>• WDG(看门狗模块): 防止死锁并监控硬件运行状况。</p> <p>• E2E(端到端保护模块): 提供通信完整性和一致性保护</p> <p>• SafeM(安全管理模块): 检测并处理系统威胁。</p> </td> </tr> <tr> <td><strong>IoHwAb_Stack</strong></td> <td>提供硬件与上层的标准化接口,屏蔽硬件差异,适用于传感器与执行器的控制需求。</td> <td> <p>• IoHwAb(硬件抽象层): 屏蔽底层硬件差异化。</p> <p>• ADC(模数转换模块): 负责信号数字化。</p> <p>• PWM: 提供执行器的信号控制。</p> <p>• DIO: 处理数字 I/O 信号。</p> <p>• Gpt: 软硬件定时功能支持。</p> </td> </tr> <tr> <td><strong>Mem_Stack</strong></td> <td>管理 ECU 中非易失性数据(如 EEPROM 和 Flash)的读写,保障数据一致性和可靠性。</td> <td> <p>• MemIf(存储接口): 提供统一访问接口。</p> <p>• NvM(非易失性存储管理模块): 管理重要数据存储。</p> <p>• Fee(Flash EEPROM 仿真模块): 负责模拟 EEPROM 功能。</p> <p>• Ea(EEPROM 抽象层): 提供直接存储支持。</p> </td> </tr> <tr> <td><strong>ModeMgm_Stack</strong></td> <td>管理 ECU 的运行模式切换(如启动、运行、休眠等),协调多模块模式同步。</td> <td> <p>• BswM(基础软件模式管理器): 协调 BSW 的模式切换。</p> <p>• EcuM(ECU 管理模块): 控制运行模式切换。</p> <p>• ModeSwitch: 提供统一切换接口。</p> <p>• RTE: 支持应用与基础软件运行协调。</p> </td> </tr> <tr> <td><strong>Sys_Stack</strong></td> <td>系统服务栈:提供基础服务支持(如断电保护、中断管理等),保障 ECU 系统运行稳定性与效率。</td> <td> <p>• RTE(运行时环境): 负责系统接口协调。</p> <p>• Scheduler(调度模块): 提供任务调度支持。</p> <p>• EcuM: 支持 ECU 生命周期管理。</p> <p>• Diagnostic Services: 提供核心诊断功能。</p> </td> </tr> <tr> <td><strong>OS_Stack</strong></td> <td>操作系统栈:提供基于 AUTOSAR 标准的实时操作系统(RTOS),用于实现任务管理、调度以及多任务间的通讯和同步。</td> <td> <p>• OSEK/VDX 兼容 OS: 支持多任务调度与优先级管理。</p> <p>• 资源管理模块: 确保任务安全访问硬件资源。</p> <p>• 任务调度模块: 依据优先级或时间分片执行任务分配。</p> </td> </tr> </tbody> </table> </ol> <br> <h4>3.1.3.2 Custom_1 属性</h4> <ol> <li><strong>定义:</strong> 表示问题的初步分类,例如 BSW(基础软件)、HW(硬件)、ASW(应用软件)等。</li> <li><strong>适用范围:</strong> 仅在 <strong>试点项目程</strong> 中使用。</li> <li><strong>定义:</strong> 用于简单分类问题所涉及的技术栈模块,以规范问题范围。</li> <table> <thead> <tr> <th>类型</th> <th>说明</th> <th>示例场景</th> </tr> </thead> <tbody> <tr> <td><strong>BSW</strong></td> <td>基础软件问题</td> <td>Timer 配置错误</td> </tr> <tr> <td><strong>HW</strong></td> <td>硬件相关问题</td> <td>电路问题导致功能失效。</td> </tr> <tr> <td><strong>ASW</strong></td> <td>应用软件问题。</td> <td>软件控制逻辑失效</td> </tr> <tr> <td><strong>Other</strong></td> <td>其他问题。</td> <td>无法明确定位的问题场景</td> </tr> </tbody> </table> </ol> <br> <h4>3.1.3.3 Custom_2 属性</h4> <ol> <li><strong>定义:</strong> 在底层问题处理过程中,进一步对问题进行详细分类,辅助后续分析和统计。</li> <li><strong>适用范围:</strong> 全部项目</li> <li><strong>定义:</strong> ?。</li> <table> <thead> <tr> <th>类型</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td><strong>开发设计问题</strong></td> <td>底层代码或设计中的缺陷导致的问题。</td> </tr> <tr> <td><strong>需求问题</strong></td> <td>客户需求逻辑不明确,存在设计问题或错误。 没有明确给到底层</td> </tr> <tr> <td><strong>平台问题</strong></td> <td>问题涉及平台设计相关问题。 非项目Base。</td> </tr> <tr> <td><strong>三方包问题</strong></td> <td>第三方软件包相关问题。。</td> </tr> <tr> <td><strong>非BSW问题</strong></td> <td>问题非底层问题,应用层或非问题。</td> </tr> </tbody> </table> </ol> </div> <!-- 添加完整详细3.1.4 --> <div class="detail-section"> <h3>3.1.4 程说明</h3> <h4>3.1.4.1 常规项目程(无Custom_1属性)</h4> <div class="flowchart-container"> <div class="mermaid"> flowchart TD A[创建 JIRA] --> B[将任务分配给底层工程师] B --> C[底层工程师根据问题描述填写 Component/s] C --> D[底层工程师分析问题并填写 Custom_2] D --> E{问题分类是否为底层问题?} E -- 是 --> F[检查并更新 Component/s 的正确性] E -- 否 --> G[无需更新 Component/s] F --> H[程完成或转至下一节点] G --> H[程完成或转至下一节点] </div> </div> <br> <h4>3.1.4.2 试点项目程(有Custom_1属性)</h4> <div class="flowchart-container"> <div class="mermaid"> flowchart TD A[创建 JIRA] --> B[填写 Custom_1 属性进行问题初步分类] B --> C{问题分类是否为 BSW?} C -- 是 --> D[转到 BSW TL 负责人] C -- 否 --> E[转非BSW处理] D --> F[BSW TL 审核并分配给对应底层工程师] F --> G[底层工程师根据问题描述填写 Component/s 属性] G --> H[底层工程师分析问题并填写 Custom_2] H --> I{问题分类是否为底层问题?} I -- 是 --> J[检查并更新 Component/s 属性的正确性] I -- 否 --> K[无需更新 Component/s 属性] J --> L[底层工程师将问题回传给 BSW TL] K --> L[底层工程师将问题回传给 BSW TL] L --> M[BSW TL 检查并转至下一个步骤] </div> </div> </div> <!-- 添加完整详细3.1.5 --> <div class="detail-section"> <h3>3.1.5 底层JIRA闭环</h3> <h4>3.1.5.1 重点Satck复盘</h4> <ol> <p><strong>定义:</strong> http://10.190.3.206:8080/cb/wiki/895157。</p> <p><strong>适用范围:</strong> 全部项目。</p> <p><strong>类型列表:</strong> 用于简单分类问题所涉及的技术栈模块,以规范问题范围。</p> <table> <thead> <tr> <th>类型</th> <th>说明</th> <th>关键模块</th> </tr> </thead> <tbody> <tr> <td><strong>Cdd_Stack</strong></td> <td>为特定硬件设备或自定义硬件提供支持,针对复杂设备功能,满足标准化 API 无法实现的需求。</td> <td> <p>• 自定义设备驱动(CDD): 根据具体设备需求开发的驱动模块。</p> <p>• RTE(运行时环境): 确保与上层通信。</p> <p>• 直接与硬件寄存器交互以实现底层逻辑。</p> </td> </tr> </tbody> </table> </ol> <br> <h4>3.1.5.2 项目 JIRA 底层健康度</h4> <br> <h5>3.1.5.2.1 说明</h5> <ol> <p><strong>定义:</strong> 项目 JIRA 健康度是衡量项目运行状态和质量的一种综合性指标。通过分析 JIRA 系统中的关键属性(如问题类型、任务状态、转效率等),评估项目的执行情况和管理水平。</p> <p><strong>数据来源:</strong><a href="https://superset.cn.kostal.int/superset/dashboard/81/?native_filters_key=sFUtjAalYPrgQTk65C9T5ERbP2ZbcDJnl82bQ2-X9N4paTeyNIL-dpl89MjyFCSZ" target="_blank">BSW_JIRA Superset</a></p> <p><strong>适用范围:</strong> Superset 监控的项目。</p> <p><strong>健康度组成:</strong></p> <table border="1" style="border-collapse: collapse; width: 100%; text-align: left;"> <thead> <tr style="background-color: #f0f0f0;"> <th>组成部分</th> <th>来源</th> <th>健康度占比</th> <th>具体公式计算</th> </tr> </thead> <tbody> <tr> <td><strong>初步分析完成度</strong></td> <td>涉及底层JIRA的Component/s的完成情况,完成标签的个数占涉及底层的jira数</td> <td>20%</td> <td> - 如果无底层参与,得分为 20%。<br> - 否则:完成数量 / 总数量 * 20%。 </td> </tr> <tr> <td><strong>底层分析结束完成度</strong></td> <td>涉及底层JIRA的Custom_2的完成情况,完成标签的个数占涉及底层的jira数</td> <td>40%</td> <td> - 如果无底层参与,得分为 40%。<br> - 否则:分析完成数量 / 总数量 * 40%。 </td> </tr> <tr> <td><strong>底层问题占比</strong></td> <td>Custom_2为底层问题jira数占总jira的比例</td> <td>30%</td> <td> - 如果无总数量,则得分为 30%。<br> - 如果计算结果 > 1,得分为 30%。<br> - 如果计算结果 < 0,得分为 0。<br> - 否则:动态得分 = (1.4 - (底层问题数 + 涉及底层jira未分析数)/总数*2) * 30%。 </td> <tr> <td><strong>长期不转</strong></td> <td>当前jira的assignee在底层工程师,超过7天没有处理或超过15天没有处理</td> <td>10%</td> <td> - 如果无底层参与,得分为 10%。<br> - 若 7 天未处理占比 > 30% 或 15 天未转占比 > 10%,得分为 0。<br> - 否则,根据惩罚公式:1 - 2 * (7 天未处理占比) - 5 * (15 天未转占比),结果乘 10%。 </td> </tr> </tbody> </table> <br> <p><strong>备注:</strong></p> <ul> <li><strong>涉及底层jira:</strong> 项目中assignee给底层工程师的jira,包括当前和过去</li> <li><strong>不规范填写:</strong> 由于Custom_2是文本格式,所以不能主观修改定义好的类别。写过一次 Custom_2 的类别后,系统会记住该类别,下一次可以直接选择之前使用过的类别。</li> </ul> </ol> <br> <h5>3.1.5.2.2 不规范提醒及健康值公布</h5> <ol> <p><strong>周提醒:</strong> 实时健康值(2025/5/1之后到当前)+每月健康值(-60天到-30天的)+超期提醒(全部时间范围内)</p> <ol> <p><strong>提醒内容:</strong> 包含ProjectNo+Responsible+健康度,按照assignee划分的时效性报告</p> <p><strong>备注:</strong>周提醒邮件收到之后,项目的底层责任人会收到当前负责的项目未处理jira清单,发件人:底层JIRA处理提示no-reply@kostal.com</p> </ol> <br> <p><strong>月汇报:</strong> 健康值度+上个月重点Stack复盘说明</p> <ol> <p><strong>提醒内容:</strong> 月度底层总jira健康度及存在的问题点,每个项目的健康度和改进意见</p> </ol> </ol> </div>
最新发布
07-31
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悠悠虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值