调用飞书接口导入供应商bug
1、业务背景
财务这边大部分系统都是供应商项目,由于供应商的研发人员没有飞书项目的权限,涉及到供应商系统需求 财务这边都是通过多维表格进行bug的生命周期管理如图:
但多维表格没有跟飞书项目直接关联,测试组做bug统计的时候无法计入供应商bug,对测试人员的bug数量造成一些影响。
解决方案:
读取表格数据,调用飞书项目接口,将bug导入到对应飞书项目需求里
2、结果展示
1、点击桌面“供应商bug导入”应用图标
2、输入文件路径和飞书项目ID
3、结果展示
导入结果:
原始数据:
备注:代码逻辑里对bug优先级做了映射,高级-- C类、中级-- B类、低级和建议-- C类
3、实现方式
官方文档: 飞书项目开发者手册
1、创建插件
插件入口
点击个人头像,从「开发者后台」进入插件开发者后台;
创建完成后,对插件进行数据权限管理和发布
插件凭证
插件凭证是插件开发阶段、运行阶段用于身份鉴权的唯一凭证。
2、名词解释
中文名词 | API名词 | 描述 |
空间域名 | simple_name | |
字段ID | field_key | |
工作项实例 | instance | 工作项实例是一个具体的事例,例如,一个已经创建的需求、缺陷、项目等 |
3、接口调用
通过基础名词解释可得,我们创建bug就是新增一个工作实例,找到官方文档中的创建工作项的接口信息
1、创建工作项接口
请求方式 | POST | ||||
请求地址 | /open_api/:project_key/work_item/create | ||||
请求header | 详见 请求header | ||||
请求参数 | 参数类型 | 参数名 | 是否必填 | 值类型 | 说明 |
路径参数 | project_key | 是 | string | 空间id(project_key),或者空间域名(simple_name) | |
请求体参数 | work_item_type_key | 是 | string | 工作项类型,自定义工作项可通过获取空间下工作项类型获取 | |
name | 是 | string | 工作项名称 | ||
field_value_pairs | 否 | list<FieldValuePair> FieldValuePair | 创建工作项的具体字段可以从获取创建工作项元数据 接口中获取,字段格式可查看字段与属性解析格式 | ||
template_id | 是 | int64 | 模板ID,可以从以下途径获取:
| ||
请求体格式 | | ||||
返回格式 | |
根据接口文档描述,我们需要获得 请求header 信息。需要查看header文档
通过请求header文档,得知我们需要获取访问凭证
1、获取访问凭证接口
调用 获取插件访问凭证 接口,通过插件凭证 Plugin ID 和 Plugin Secret获取 plugin_access_token (或者virtual_plugin_access_token)
请求方式 | POST | |||
请求地址 | https://{平台域名}/open_api/authen/plugin_token | |||
请求头参数 | 参数名 | 类型 | 必填 | 说明 |
Content-Type | string | 是 | 固定值:“application/json” | |
请求体参数 | 参数名 | 类型 | 必填 | 说明 |
plugin_id | string | 是 | 插件唯一标识,Plugin ID | |
plugin_secret | string | 是 | 插件密钥,Plugin Secret | |
type | int | 否 | 插件访问凭证类型,可选值:0、1。默认为plugin_access_token,值为1时将返回virtual_plugin_access_token | |
cURL示例 | | |||
响应体参数 | |
"plugin_id" 和 "plugin_secret" 我们创建插件时已经获得,由接口文档,可以轻松获取到请求header的凭证信息
2、工作项类型获取
根据创建工作项的接口文档 work_item_type_key 需要通过 获取空间下工作项类型 接口获取
为了方便获取到我们需要的参数,只需要用postman获取即可
即: "work_item_type_key": "issue"
3、获取 template_id
同理我们可以调用获取字段信息接口,拿到缺陷的 template_id
即: "template_id": 34673,
4、其余自定义字段获取
可以通过获取工作项详情查询
最终的请求数据
{ "work_item_type_key": "issue", "name": data[i][0], "template_id": 34673, "field_value_pairs": [ { "field_alias": "bug_priority", "field_value": {"label": priority_map.get(data[i][6], {"label": "B类", "value": "53cnaxoz_"}).get("label"), "value": priority_map.get(data[i][6], {"label": "B类", "value": "53cnaxoz_"}).get("value") }, }, {"field_alias": "_field_linked_story", "field_value": linked_story}, {"field_alias": "owner", "field_value": reporter_map.get(data[i][1], "7230980664668045340")}, {"field_alias": "issue_reporter", "field_value": reporter_map.get(data[i][1], "7230980664668045340")}, {"field_alias": "issue_operator", "field_value": ["7413123527076806659"]}, {"field_alias": "description", "field_value": data[i][0]}, ] }
2、状态流转接口
状态流转接口新
请求方式 | POST | ||||
请求地址 | /open_api/:project_key/workflow/:work_item_type_key/:work_item_id/node/state_change | ||||
请求header | 详见 请求header | ||||
请求参数 | 参数类型 | 参数名 | 是否必填 | 值类型 | 说明 |
路径参数 | work_item_id | 是 | int64 | 工作项ID | |
work_item_type_key | 是 | string | 工作项类型可以,从获取空间下工作项类型接口获取 | ||
project_key | 是 | string | 空间id(project_key),或者空间域名(simple_name) | ||
请求体参数 | transition_id | 是 | int64 | 流转到下一状态的id,从获取工作流详情接口查询状态流获取 | |
role_owners | 否 | list<RoleOwner> RoleOwner | 角色及负责人 | ||
fields | 否 | list<FieldValuePair> FieldValuePair | 要更新的字段数组(只能更新状态表单) | ||
请求体格式 | |
根据接口文档,我们需要获取header、work_item_id、work_item_type_key、project_key、transition_id等信息
其中header、work_item_type_key、project_key可以参考 “创建工作项” 接口里的获取方式
1、work_item_id的取值
work_item_id 我们可以从创建工作项接口的返回值里取到
2、transition_id 获取
transition_id 可以通过调用 获取工作流详情 接口获取
从接口返回信息可得,bug状态 :
由 OPEN --> RESOLVED 的 transition_id 是 983309
由 RESOLVED --> CLOSED 的 transition_id 是 983314
状态流转的请求json信息
{ "transition_id": 983309, # 状态改成 RESOLVED "fields": [ {"field_alias": "bug_remark", "field_value": "供应商bug"}, {"field_alias": "bug_reason", "field_type_key": "select", "field_key": "field_21fcfb", "field_value": {"label": "自测不仔细产生bug", "value": "b39yvbscm"}} ] }
4、代码示例
import pandas as pd
import json
import requests
from tkinter_test import imp_confirmdef get_plugin_token():"""获取插件的 token并返回:return: 插件的token信息"""url = 'https://project.feishu.cn/open_api/authen/plugin_token'payload = json.dumps({"plugin_id": plugin_id,"plugin_secret": plugin_secret,"type": 0})headers = {'Content-Type': 'application/json'}response = requests.request("POST", url, headers=headers, data=payload)return response.json()['data']['token']def add_bug_datas(linked_story, file_path):"""把bug导入到对应的飞书项目里:param linked_story: 飞书项目ID:param file_path: bug文件路径"""df = pd.read_excel(file_path)data = df.iloc[0:, :]data = data.to_numpy()url = "https://project.feishu.cn/open_api/hdltech/work_item/create"for i in range(len(data)):user_data = {"work_item_type_key": "issue","name": data[i][0],"template_id": 34673,"field_value_pairs": [{"field_alias": "bug_priority","field_value": {"label": priority_map.get(data[i][6], {"label": "B类", "value": "53cnaxoz_"}).get("label"),"value": priority_map.get(data[i][6], {"label": "B类", "value": "53cnaxoz_"}).get("value")},},{"field_alias": "_field_linked_story", "field_value": linked_story},{"field_alias": "owner", "field_value": reporter_map.get(data[i][1], "7230980664668045340")},{"field_alias": "issue_reporter", "field_value": reporter_map.get(data[i][1], "7230980664668045340")},{"field_alias": "issue_operator","field_value": ["7413123527076806659"]},{"field_alias": "description", "field_value": data[i][0]},]}data_to_send = json.dumps(user_data).encode("utf-8")header = {"content-type": "application/json","X-User-Key": user_key,"X-PLUGIN-TOKEN": get_plugin_token()}r = requests.post(url, data=data_to_send, headers=header)data_list.append(r.json()["data"])print(r.json())def close_bug():"""更改bug状态"""headers = {"Content-Type": "application/json","X-PLUGIN-TOKEN": get_plugin_token(),"X-USER-KEY": user_key,}for bug_id in data_list:bug_id = bug_idurl = f"https://project.feishu.cn/open_api/hdltech/workflow/issue/{bug_id}/node/state_change"data = {"transition_id": 983309, # 状态改成 RESOLVED"fields": [{"field_alias": "bug_remark", "field_value": "供应商bug"},{"field_alias": "bug_reason","field_type_key": "select","field_key": "field_21fcfb","field_value": {"label": "自测不仔细产生bug", "value": "b39yvbscm"}}]}requests.post(url, json=data, headers=headers).json()data = {"transition_id": 983314, # 状态改成close"fields": [{"field_alias": "bug_remark", "field_value": "供应商bug"},]}result = requests.post(url, json=data, headers=headers).json()print(result)file_path, linked_story = imp_confirm()
add_bug_datas(linked_story, file_path)
close_bug()
#print(file_path, linked_story)
4、弹窗信息的实现
Python GUI编程(Tkinter) :https://docs.python.org/zh-cn/3/library/tk.html
Tkinter文档
import tkinter as tkroot = tk.Tk()
root.geometry('400x230+500+260')
root.title('导入bug操作')
page = tk.Frame(root)
page.pack()file_path = tk.StringVar()
story_id = tk.StringVar()tk.Label(page).grid(row=0, column=0)
tk.Label(page, text='请输入文件路径').grid(row=1, column=1)
tk.Entry(page, textvariable=file_path).grid(row=1, column=2, pady=10)
tk.Label(page, text='请输入项目ID').grid(row=2, column=1, pady=10)
tk.Entry(page, textvariable=story_id).grid(row=2, column=2, pady=10)def imp_confirm():filepath = file_path.get().replace(" ", "")storyid = story_id.get().replace(" ", "")if len(filepath) == 0:messagebox.showwarning("警告", "文件路径不能为空")elif len(storyid) == 0:messagebox.showwarning("警告", "项目ID不能为空")elif not storyid.isdigit():messagebox.showwarning('警告', '项目ID为整数请确认后输入')else:page.quit()#messagebox.showinfo("提示", "开始导入请稍后")return filepath, int(storyid)tk.Button(page, text='确认', command=imp_confirm).grid(row=3, column=1, pady=10)
tk.Button(page, text='取消', command=page.quit).grid(row=3, column=2)root.mainloop()
5、打包操作
使用 Pyinstaller 进行打包
pyinsatll中文文档
pyinstaller -w -i im.icns -n 供应商bug导入 opexcel.py
相关文章:
调用飞书接口导入供应商bug
1、业务背景 财务这边大部分系统都是供应商项目,由于供应商的研发人员没有飞书项目的权限,涉及到供应商系统需求 财务这边都是通过多维表格进行bug的生命周期管理如图: 但多维表格没有跟飞书项目直接关联,测试组做bug统计的时候无…...
《深度学习》OpenCV 角点检测、特征提取SIFT 原理及案例解析
目录 一、角点检测 1、什么是角点检测 2、检测流程 1)输入图像 2)图像预处理 3)特征提取 4)角点检测 5)角点定位和标记 6)角点筛选或后处理(可选) 7)输出结果 3、邻域…...
golang grpc初体验
grpc 是一个高性能、开源和通用的 RPC 框架,面向服务端和移动端,基于 HTTP/2 设计。目前支持c、java和go,分别是grpc、grpc-java、grpc-go,目前c版本支持c、c、node.js、ruby、python、objective-c、php和c#。grpc官网 grpc-go P…...
基于小程序+Vue + Spring Boot的进销存库存出库入库统计分析管理系统
目录 一、项目背景及需求分析 1. 项目背景 2. 需求分析 二、系统架构设计 1. 技术选型 2. 模块划分 三、数据库设计数据库表结构 四、前端实现 五、后端实现 1. RESTful API设计 2. 数据库操作 六、安全性和性能优化 1. 安全性 2. 性能优化 七、测试与部署 1. …...
【数据结构与算法】时间复杂度和空间复杂度例题
文章目录 时间复杂度常数阶时间O(1)对数阶时间O(logN)线性阶时间O(n)线性对数阶时间O(nlogN)平方阶时间O(n*n) 空间复杂度常量空间O(1)线性空间O(n)二维空间O(n*n)递归空间 时间复杂度 常数阶时间O(1) 代码在执行的时候,它消耗的时间并不随着某个变量的增长而增长…...
停止模式下USART为什么可以唤醒MCU?
在MCU的停止模式下,USART之类的外设时钟是关闭的,但是USART章节有描述到在停止模式下可以用USART来对MCU进行唤醒: 大家是否会好奇在外设的时钟被关闭的情况下,USART怎么能通过接收中断或者唤醒事件对MCU进行唤醒的呢࿱…...
Web安全 - 路径穿越(Path Traversal)
文章目录 OWASP 2023 TOP 10导图定义路径穿越的原理常见攻击目标防御措施输入验证和清理避免直接拼接用户输入最小化权限日志监控 ExampleCode漏洞代码:路径穿越攻击案例漏洞说明修复后的安全代码代码分析 其他不同文件系统下的路径穿越特性Windows系统类Unix系统&a…...
JSR303微服务校验
一.创建idea 二.向pom.xml添加依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.7.RELEASE</version></parent><properties><java.vers…...
56. QTreeWidget的基本使用
1. 说明 在软件开发中会遇到将数据信息制作成一种树目录的形式进行展示,那么此时就可以借助QT提供的QTreeWidget控件来实现这种需求,本篇博客会做一个案例简要说明这个控件的基本使用方法,博客中代码能够实现的功能是将此项目代码所在文件夹中的内容展示出来,如下图所示:…...
领域偏移:协变量移位下的域自适应
现在我们将焦点转移到一种叫做协变量转移的扰动上。我们在一个分类或回归设置中工作,我们希望从x预测y,并假设p≈(y | x)和p∗(y | x)是相同的(标记函数在训练和测试之间不会改变) 假设 (Covariate Shift)。对于列车分布p~和检验分布p∗,我们…...
前端开发技术框架选型
一、引言 在前端开发领域,技术框架的选择对于项目的成功至关重要。一个优秀的前端框架不仅可以提高开发效率,还能确保项目的稳定性和可扩展性。而不同的框架具有不同的特点和优势,能够满足不同项目的需求。下面将对目前主流的前端开发技术框…...
/etc/init.d/mysql
Since you’ve installed MySQL from source, you’ll need to create a custom init script to manage the MySQL server (start, stop, status) similarly to a service. Here’s a simple init.d script template for MySQL that you can use. This script assumes MySQL is…...
Qt_线程介绍与使用
目录 1、QThread常用API 2、Qt线程安全 3、使用线程QThread 4、connect函数的第五个参数 5、Qt互斥锁 5.1 QMutexLocker 6、条件变量 7、信号量 结语 前言: 线程是应用程序开发非常重要的概念,在Qt中,用QThread类来实现多线程&a…...
通讯方面的数据,人工智能 机器学习的时候,因为数字都接近于一,数据归一化的一种方法,做了一个简化版本的Z-score标准化
这个表达式实现了一种形式的数据归一化,它将张量x中的每个元素除以x的标准差的估计值。这种处理方式可以使得变换后的数据具有单位标准差(假设数据已经是零均值或者在计算过程中考虑了均值)。具体来说,它是基于以下步骤进行的&…...
python itertools模块介绍
itertools 是 Python 内建的一个高效处理迭代器的模块,提供了创建复杂迭代器的函数工具。它包含一系列用于迭代、组合、排列、过滤等功能的迭代器构建工具,常用于数据处理和算法设计。下面是 itertools 模块中一些常见的函数介绍: 1. 无限迭…...
【分布式微服务云原生】5分钟深入剖析Kafka:Leader与Follower分区的秘密及负载均衡的艺术
深入剖析Kafka:Leader与Follower分区的秘密及负载均衡的艺术 摘要: Apache Kafka作为当前最流行的分布式流处理平台之一,其内部的分区机制和消费者组的负载均衡策略是实现高吞吐量和高可靠性的关键。本文将深入探讨Kafka中Leader分区与Follo…...
在线代码编辑器
在线代码编辑器 文章说明前台核心代码后台核心代码效果展示源码下载 文章说明 采用Java结合vue3设计实现的在线代码编辑功能,支持在线编辑代码、运行代码,同时支持导入文件,支持图片识别,支持复制代码,可将代码导出为图…...
深入了解 MPlayer:Linux 系统中的多功能多媒体播放器
文章目录 深入了解 MPlayer:Linux 系统中的多功能多媒体播放器一、MPlayer 的安装二、MPlayer 的基本使用三、MPlayer 音频功能详解1. 支持的音频格式2. 调整音频输出设备3. 使用音频滤镜和效果4. 音频输出格式转换5. 多声道与环绕声支持6. 音频控制:播放…...
Netty系列-7 Netty编解码器
背景 netty框架中,自定义解码器的起点是ByteBuf类型的消息, 自定义编码器的终点是ByteBuf类型。 1.解码器 业务解码器的起点是ByteBuf类型 netty中可以通过继承MessageToMessageEncoder类自定义解码器类。MessageToMessageEncoder继承自ChannelInboundHandlerAdap…...
OpenHarmony标准系统上实现对rk系列芯片NPU的支持(npu使用)
在上篇文章中,我们学习了移植rk的npu驱动到OpenHarmony提供的内核。本文我们来学习如何在OpenHarmony标准系统rk系列芯片如何使用npu OpenHarmony RK系列芯片运行npu测试用例 在移植npu驱动到OpenHarmony之后,来运行npu样例进行简单测试 1.O 测试准备…...
大表性能优化的关键技术
1 引言 在现代企业应用中,随着数据量的不断增长,大表的性能优化成为数据库管理的重要环节。本文将探讨大表性能优化的关键技术,包括索引优化、查询优化、分区分表、读写分离以及缓存策略等方面。通过综合运用这些技术,可以显著提升大表的处理效率和响应速度,确保系统的稳…...
广联达 Linkworks办公OA Service.asmx接口存在信息泄露漏洞
漏洞描述 广联达科技股份有限公司以建设工程领域专业应用为核心基础支撑,提供一百余款基于“端云大数据”产品/服务,提供产业大数据、产业新金融等增值服务的数字建筑平台服务商。广联达OA存在信息泄露漏洞,由于某些接口没有鉴权,…...
如何成为成功的AI产品经理:经验与策略分享
引言 随着人工智能(AI)技术的迅猛发展,AI产品经理(AI PM)的角色变得越来越重要。Google AI产品负责人Marily Nika在最近的一次播客中分享了她在AI产品管理领域的宝贵经验和见解。本文将整理并总结她的核心内容,帮助有志于进入AI PM领域的人士了解如何准备、所需的核心技…...
spring loCDI 详解
文章目录 一、IoC & DI 基本知识1.1 IoC 的基本概念:1.2 IoC 的优势:1.3 DI 介绍: 二、IoC 详解2.1 Spring 容器:2.2 被存储 Bean 的命名约定:2.3 Bean 的存储方式:2.3.1 五大类注解:2.3.1.…...
遇到 Docker 镜像拉取失败的问题时该如何解决
遇到 Docker 镜像拉取失败的问题时,可以按照以下步骤进行排查和解决: 1. 检查网络连接 确保你的计算机可以访问互联网。尝试 ping 通 Docker Hub 或其他镜像仓库的域名: ping hub.docker.com2. 检查 Docker 服务状态 确保 Docker 服务正在…...
【C/C++】错题记录(三)
题目一 题目二 题目三 题目四 题目五 题目六 题目七??? 题目八 这道题主要考查对数据类型和位运算的理解与运用。 分析选项 A: *((unsigned char *)(&number) 1)0xcd; 这里将 number 的地址强制转换为 unsigned char* 类型&a…...
深入理解Web浏览器与服务器的连接过程
目录 1. 域名解析:找到地址 2. TCP连接:建立通信 3. HTTP请求:点菜 4. 服务器处理请求:厨房做菜 5. HTTP响应:上菜 6. 客户端接收响应:品尝美食 7. 关闭TCP连接:吃完离开 8. 持久连接&a…...
深入解析 https
我的主页:2的n次方_ 1. 背景介绍 在使用 http 协议的时候是不安全的,可能会出现运营商劫持等安全问题,运营商通过劫持 http 流量,篡改返回的网页内容,例如广告业务,可能会通过 Referer 字段 来统计是…...
NP-hard问题
一、前置知识 1.多项式 多项式是由变量(如x、y等)和系数通过有限次的加、减、乘运算得到的表达式。例如3x^22x 1就是一个关于(x)的多项式 2.时间复杂度 时间复杂度是用来衡量算法运行效率的一个指标。它描述了算法运行时间随着输入规模增长而增长的量…...
【Nacos架构 原理】内核设计之Nacos通信通道
文章目录 Nacos通信通道 (长链接)现状背景场景分析配置服务 长链接核心诉求功能性诉求负载均衡连接生命周期 Nacos通信通道 (长链接) 现状背景 Nacos 1.X 版本 Config/Naming 模块各自的推送通道都是按照自己的设计模型来实现的…...
wordpress 全文搜索/宁波企业seo服务
一、 变量的定义和缺省初始化 c 中声明变量的时候大多的进行了定义(即分配了内存),特例有: 1) extent int x,仅仅声明了x,没有为x分配内存。 2) 函数的声明(即在调用函数之前进行的声明,此时未定…...
做宣传图册在什么网站/推广普通话手抄报内容资料
hw5相比hw4,修改了以下的bug,从而更好的实现了对代码的封装: 1:hw4中,remove(n)时,若n不存在于本list却存在于其他list中,会remove其他list中的node,同时减少本list的size。 2&#…...
天天网站建设/西安网站关键词排名
本来不想谈这种招人骂的话题的,哎,不过今天在一个QQ群中遇到了类似的情况,站在现实的角度,说了几句自己学校的不好,然后遇到了一个喷子,而且还不是我们学校的。让我觉的这件事情很奇…...
设计师门户网站程序/网站推广软件
2019独角兽企业重金招聘Python工程师标准>>> 用eosjs连接主网节点很简单,只需要在创建JsonRpc对象时,指定要连接主网节点的地址 就可以了。 如果要深入系统地学习EOS开发,推荐这个课程:EOS智能合约与DApp开发入门 例如…...
怎样做旅游网站/肇庆seo按天收费
暂无转载于:https://www.cnblogs.com/Sue_/articles/1657390.html...
国外网站怎么做威客/seo排名需要多少钱
SQLite C/C 接口介绍 这篇文章简要的介绍了 SQLite 的 C/C 接口。 早期版本的 SQLite 很好学是因为他们只提供了 5 个 C/C 的接口。但是随着 SQLite 功能的增加,新的 C/C 接口加入,现在已经有超过 200 个不同的 API 了。这对新人可能是一种阻碍。幸运的是…...