feat: 完善dulizhan项目测试代码
This commit is contained in:
20198
JoyHub_API接口文档.md
Normal file
20198
JoyHub_API接口文档.md
Normal file
File diff suppressed because it is too large
Load Diff
463
Log/run.log
463
Log/run.log
File diff suppressed because one or more lines are too long
@@ -1,75 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import allure
|
||||
import logging
|
||||
|
||||
from zhyy.library.BusinessKw.SZPurchase.PurchaseOrderManage import PurchaseOrder
|
||||
|
||||
|
||||
@allure.feature('深圳采购工作台采购订单页面')
|
||||
class Test_purchase_order(object):
|
||||
test_case = PurchaseOrder()
|
||||
|
||||
def teardown_method(self):
|
||||
logging.info("-----------------------------End-------------------------------")
|
||||
|
||||
@allure.story("验证采购工作台采购订单页面列表查询")
|
||||
def test_check_purchase_order_page(self):
|
||||
purchase_order_code = 'PO251209048' # 采购单号 必填
|
||||
supplier_company_ids = ['334'] # 供应商id 非必填
|
||||
payment_status = '0' # 付款状态 非必填
|
||||
status = '0' # 采购单状态 非必填
|
||||
page_no = 1 # 页码 必填
|
||||
page_size = 10 # 每页条数 必填
|
||||
response_data = self.test_case.kw_zhyy_get_purchase_page_post(
|
||||
note="采购工作台采购订单页面列表查询",
|
||||
user='purchase',
|
||||
order_sn=purchase_order_code,
|
||||
supplier_company_ids=supplier_company_ids,
|
||||
payment_status=payment_status,
|
||||
status=status,
|
||||
page_no=page_no,
|
||||
page_size=page_size
|
||||
)
|
||||
|
||||
# 断言检查
|
||||
assert response_data is not None, "响应数据不能为空"
|
||||
assert 'code' in response_data, "响应数据中缺少code字段"
|
||||
assert response_data['code'] == 0, "接口调用失败,code: {}, msg: {}".format(
|
||||
response_data.get('code'), response_data.get('msg', '未知错误'))
|
||||
assert 'data' in response_data, "响应数据中缺少data字段"
|
||||
assert response_data['data'] is not None, "响应数据中的data字段不能为空"
|
||||
|
||||
# 如果传入了采购单号,检查返回的数据中是否包含该采购单号
|
||||
if purchase_order_code:
|
||||
data = response_data.get('data', {})
|
||||
order_found = False
|
||||
|
||||
# 检查返回的数据结构,可能包含列表或其他结构
|
||||
if isinstance(data, dict):
|
||||
# 如果data是字典,可能包含records、list、data等字段
|
||||
records = data.get('records') or data.get('list') or data.get('data') or []
|
||||
if isinstance(records, list) and len(records) > 0:
|
||||
# 检查列表中是否包含指定的采购单号
|
||||
for item in records:
|
||||
if isinstance(item, dict):
|
||||
order_sn = item.get('order_sn') or item.get('orderSn') or item.get('orderSn')
|
||||
if order_sn == purchase_order_code:
|
||||
order_found = True
|
||||
break
|
||||
elif isinstance(data, list):
|
||||
# 如果data本身就是列表
|
||||
for item in data:
|
||||
if isinstance(item, dict):
|
||||
order_sn = item.get('order_sn') or item.get('orderSn') or item.get('orderSn')
|
||||
if order_sn == purchase_order_code:
|
||||
order_found = True
|
||||
break
|
||||
|
||||
if order_found:
|
||||
logging.info("✓ 断言通过:返回的数据中包含采购单号 {}".format(purchase_order_code))
|
||||
else:
|
||||
logging.warning("⚠ 警告:返回的数据中未找到采购单号: {},但接口调用成功".format(purchase_order_code))
|
||||
|
||||
logging.info("✓ 所有断言检查通过")
|
||||
print("✓ 查询成功,响应数据: {}".format(response_data))
|
||||
@@ -1,19 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import allure
|
||||
import logging
|
||||
|
||||
from zhyy.library.BusinessKw.SZPurchase.index import PurchaseIndex
|
||||
|
||||
|
||||
@allure.feature('深圳采购工作台首页')
|
||||
class Test_purchase_index(object):
|
||||
# config = ReadConfig.ReadConfig() # 调用读取配置文件的方法类
|
||||
test_case = PurchaseIndex()
|
||||
|
||||
def teardown_method(self):
|
||||
logging.info("-----------------------------End-------------------------------")
|
||||
|
||||
@allure.story("验证采购工作台待办任务与在办任务功能")
|
||||
def test_check_todo(self):
|
||||
get_purchase_data = self.test_case.kw_zhyy_get_todo(note="采购工作台首页待办任务PO与在办任务PO", user='purchase')
|
||||
@@ -46,8 +46,8 @@ def run_pytest(args_list):
|
||||
if is_jenkins and 'WORKSPACE' in env:
|
||||
# Jenkins环境下使用绝对路径
|
||||
global ALLURE_RESULTS_DIR, ALLURE_REPORT_DIR
|
||||
ALLURE_RESULTS_DIR = os.path.join(env['WORKSPACE'], 'zhyy', 'test_case', 'reports', 'allure-results')
|
||||
ALLURE_REPORT_DIR = os.path.join(env['WORKSPACE'], 'zhyy', 'test_case', 'reports', 'allure-report')
|
||||
ALLURE_RESULTS_DIR = os.path.join(env['WORKSPACE'], 'dulizhan', 'test_case', 'reports', 'allure-results')
|
||||
ALLURE_REPORT_DIR = os.path.join(env['WORKSPACE'], 'dulizhan', 'test_case', 'reports', 'allure-report')
|
||||
ensure_dirs()
|
||||
|
||||
cmd = ['python', '-m', 'pytest'] + args_list
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Author: qiaoxinjiu
|
||||
Email: qiaoxinjiu@sparkedu.com
|
||||
Create Date: 2026/01/22 5:58 下午
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
# 添加项目根目录到 Python 路径,以便导入 base_framework 模块
|
||||
current_file_path = os.path.abspath(__file__)
|
||||
project_root = os.path.abspath(os.path.join(os.path.dirname(current_file_path), '../../../../'))
|
||||
if project_root not in sys.path:
|
||||
sys.path.insert(0, project_root)
|
||||
|
||||
from base_framework.public_tools import log
|
||||
from base_framework.public_tools.my_faker import MyFaker
|
||||
from base_framework.public_tools.runner import Runner
|
||||
from base_framework.public_tools.pgsqlhelper import PgSqlHelper
|
||||
from base_framework.public_tools import read_config
|
||||
from base_framework.public_tools import utils
|
||||
from base_framework.public_tools import mg_keyword
|
||||
from zhyy.library.ZZYY_interface import ZhyyInterface
|
||||
|
||||
obj_get_log = log.get_logger()
|
||||
obj_my_faker = MyFaker()
|
||||
obj_runner = Runner()
|
||||
obj_pgsql_helper = PgSqlHelper()
|
||||
obj_get_way = utils.Tools()
|
||||
obj_mg_keyword = mg_keyword.ManageKeyWord()
|
||||
|
||||
|
||||
class PurchaseOrder(ZhyyInterface):
|
||||
def __init__(self):
|
||||
'''
|
||||
这个是针对于读取配置文件的初始化函数,用于读取默认参数
|
||||
'''
|
||||
super().__init__()
|
||||
self.config_index_path = os.path.dirname(os.path.abspath(__file__))
|
||||
self.config_index_filePath = os.path.join(self.config_index_path, "purchase.ini")
|
||||
self.config_index_content = read_config.ReadConfig(filename=self.config_index_filePath)
|
||||
|
||||
def kw_zhyy_get_purchase_page_post(self, note, user, **kwargs):
|
||||
"""
|
||||
| 功能说明: | 返回采购工作台采购单列表数据 |
|
||||
| 输入参数: | note | 注释 |
|
||||
|user | 用户信息,传入 'purchase' 默认读取配置文件里面 'purchase' 对应的默认账号信息|
|
||||
|supplier_company_ids | 供应商id | 非必填
|
||||
|payment_status | 付款状态 | 非必填
|
||||
|status | 采购单状态 | 非必填
|
||||
|order_sn | 采购单号 | 非必填
|
||||
|page_no | 页码 | 必填
|
||||
|page_size | 每页条数 | 必填
|
||||
| 返回参数: | {"success":true,"message":"success","code":200,"data":
|
||||
{'todoTask':['PO260116003','PO260115010'],'inProcessTask':['PO260116003','PO260115010']}} | |
|
||||
| 作者信息: | 谯新久 | 修改时间 | 2022-8-20 |
|
||||
"""
|
||||
logging.info("==========={0}===========".format(note))
|
||||
# 获取所有参数
|
||||
supplier_company_ids = kwargs.get("supplier_company_ids")
|
||||
payment_status = kwargs.get("payment_status")
|
||||
status = kwargs.get("status")
|
||||
order_sn = kwargs.get("order_sn")
|
||||
page_no = kwargs.get("page_no")
|
||||
page_size = kwargs.get("page_size")
|
||||
|
||||
# 检查必填参数
|
||||
if not page_no or not page_size:
|
||||
raise Exception("页码和每页条数不能为空")
|
||||
|
||||
# 组装参数字典,只包含非空字段,参数名使用 pageNo 和 pageSize
|
||||
request_params = {
|
||||
"pageNo": page_no,
|
||||
"pageSize": page_size
|
||||
}
|
||||
|
||||
# 如果字段不为空,才添加到参数字典中
|
||||
if supplier_company_ids is not None and supplier_company_ids != "":
|
||||
request_params["supplier_company_ids"] = supplier_company_ids
|
||||
if payment_status is not None and payment_status != "":
|
||||
request_params["payment_status"] = payment_status
|
||||
if status is not None and status != "":
|
||||
request_params["status"] = status
|
||||
if order_sn is not None and order_sn != "":
|
||||
request_params["order_sn"] = order_sn
|
||||
|
||||
# 使用 ** 方式解包字典传递参数
|
||||
get_todo_info = self.kw_in_zhyy_purchase_order_page_post(user=user, **request_params)
|
||||
print(get_todo_info if get_todo_info else "查询失败")
|
||||
return get_todo_info
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test = PurchaseOrder()
|
||||
a = test.kw_zhyy_get_purchase_page_post(user='purchase', note="测试", page_no=1, page_size=10)
|
||||
print(a)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,88 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Author: qiaoxinjiu
|
||||
Email: qiaoxinjiu@sparkedu.com
|
||||
Create Date: 2022/08/20 5:58 下午
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
# 添加项目根目录到 Python 路径,以便导入 base_framework 模块
|
||||
current_file_path = os.path.abspath(__file__)
|
||||
project_root = os.path.abspath(os.path.join(os.path.dirname(current_file_path), '../../../../'))
|
||||
if project_root not in sys.path:
|
||||
sys.path.insert(0, project_root)
|
||||
|
||||
from base_framework.public_tools import log
|
||||
from base_framework.public_tools.my_faker import MyFaker
|
||||
from base_framework.public_tools.runner import Runner
|
||||
from base_framework.public_tools.pgsqlhelper import PgSqlHelper
|
||||
from base_framework.public_tools import read_config
|
||||
from base_framework.public_tools import utils
|
||||
from base_framework.public_tools import mg_keyword
|
||||
from zhyy.library.ZZYY_interface import ZhyyInterface
|
||||
|
||||
obj_get_log = log.get_logger()
|
||||
obj_my_faker = MyFaker()
|
||||
obj_runner = Runner()
|
||||
obj_pgsql_helper = PgSqlHelper()
|
||||
obj_get_way = utils.Tools()
|
||||
obj_mg_keyword = mg_keyword.ManageKeyWord()
|
||||
|
||||
|
||||
class PurchaseIndex(ZhyyInterface):
|
||||
def __init__(self):
|
||||
'''
|
||||
这个是针对于读取配置文件的初始化函数,用于读取默认参数
|
||||
'''
|
||||
super().__init__()
|
||||
self.config_index_path = os.path.dirname(os.path.abspath(__file__))
|
||||
self.config_index_filePath = os.path.join(self.config_index_path, "purchase.ini")
|
||||
self.config_index_content = read_config.ReadConfig(filename=self.config_index_filePath)
|
||||
|
||||
def kw_zhyy_get_todo(self, note, user):
|
||||
"""
|
||||
| 功能说明: | 返回采购工作台首页待办任务的PO与在办任务PO |
|
||||
| 输入参数: | note | 注释 |
|
||||
|user | 用户信息,传入 'purchase' 默认读取配置文件里面 'purchase' 对应的默认账号信息|
|
||||
| 返回参数: | {"success":true,"message":"success","code":200,"data":
|
||||
{'todoTask':['PO260116003','PO260115010'],'inProcessTask':['PO260116003','PO260115010']}} | |
|
||||
| 作者信息: | 谯新久 | 修改时间 | 2022-8-20 |
|
||||
"""
|
||||
logging.info("==========={0}===========".format(note))
|
||||
get_todo_info = self.kw_in_zhyy_purchase_todo_get(user=user)
|
||||
if get_todo_info['code'] != 0:
|
||||
raise Exception("查询采购待办任务失败: {}".format(get_todo_info))
|
||||
get_todo_info["message"] = "查询采购待办任务成功"
|
||||
data = get_todo_info.get("data")
|
||||
if data is None:
|
||||
raise Exception("返回数据为空,data字段不存在")
|
||||
list_get_todo_task = data.get("todoTask") or []
|
||||
list_get_process_task = data.get("inProcessTask") or []
|
||||
list_todo_task_po = []
|
||||
list_process_task_po = []
|
||||
for todoTask in list_get_todo_task:
|
||||
if isinstance(todoTask, dict):
|
||||
list_todo_task_po.append(todoTask.get("businessSn"))
|
||||
for processTask in list_get_process_task:
|
||||
if isinstance(processTask, dict):
|
||||
list_process_task_po.append(processTask.get("businessSn"))
|
||||
get_todo_info["data"]["todoTask"] = list_todo_task_po
|
||||
get_todo_info["data"]["inProcessTask"] = list_process_task_po
|
||||
if list_todo_task_po:
|
||||
test_purchase = list_todo_task_po[0]
|
||||
# 表在public schema中,使用public.erp_purchase_order格式
|
||||
sql = "SELECT * FROM public.erp_purchase_order WHERE order_sn = '{}'".format(test_purchase)
|
||||
try:
|
||||
obj_pgsql_helper.select_one(sql)
|
||||
except Exception as e:
|
||||
# 如果查询失败,记录日志但不影响主流程
|
||||
obj_get_log.warning("查询采购订单表失败,订单号:{},错误:{}".format(test_purchase, str(e)))
|
||||
return get_todo_info
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test = PurchaseIndex()
|
||||
a = test.kw_zhyy_get_todo(user='purchase',note="测试")
|
||||
print(a)
|
||||
@@ -1,2 +0,0 @@
|
||||
[qa-user]
|
||||
user_info ={"studentId":21797349,"sex":0,"nickName":"auto st test","birthday":1640966400000,"avatar":"https://stalegacy.huohua.cn/image/huohua/avatar/default/default_avatar1.png"}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,57 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
"""
|
||||
Author: 陈江
|
||||
Email: chenjiang@huohua.cn
|
||||
Create Date: 2022/03/03 11:25 下午
|
||||
"""
|
||||
from base_framework.public_tools import log
|
||||
from base_framework.public_tools.sqlhelper import MySqLHelper
|
||||
|
||||
obj_log = log.get_logger()
|
||||
obj_my_sql_helper = MySqLHelper()
|
||||
|
||||
class AssetCommon:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_course_package_info_by_name(self, course_package_name):
|
||||
"""
|
||||
功能:根据套餐名称获取套餐基本信息
|
||||
| 输入参数: | course_package_name string | 套餐名称 |
|
||||
"""
|
||||
sql = "SELECT id,code,name,price FROM `peppa`.`course_package` WHERE `name`='{}';".format(course_package_name)
|
||||
return obj_my_sql_helper.select_one(sql)
|
||||
|
||||
def get_order_info_V2(self, **where_condition):
|
||||
# user_id = None, course_package_id = None, course_id = None, business_line_type = None, order_id = None, order_code = None
|
||||
ocp = ['user_id', 'business_line_type', 'order_id', 'order_code', 'status']
|
||||
sprl = ['course_package_id', 'course_id']
|
||||
where_str = None
|
||||
for k in where_condition.keys():
|
||||
t = ''
|
||||
if k in sprl:
|
||||
t = 'sprl'
|
||||
else:
|
||||
t = 'ocp'
|
||||
|
||||
if not where_str:
|
||||
where_str = '{}.{}=\'{}\''.format(t, k, where_condition.get(k))
|
||||
else:
|
||||
where_str = '{} AND {}.{}=\'{}\''.format(where_str, t, k, where_condition.get(k))
|
||||
if not where_str:
|
||||
obj_log.error('参数必填')
|
||||
return False
|
||||
sql = "SELECT ocp.id as order_id,ocp.code,ocp.audit_status,ocp.status as order_status,ocp.user_id,ocp.user_address_id,ocp.business_line_type,sprl.course_package_id,sprl.course_id,sprl.subscribe_id,sprl.valid as subscribe_pre_valid,sprl.id as subscribe_pre_id FROM order_center.order_course_package ocp LEFT JOIN order_center.subscribe_pre_create_log sprl ON ocp.id=sprl.order_id WHERE {} ORDER BY ocp.id DESC LIMIT 1".format(
|
||||
where_str.replace('order_id', 'id'))
|
||||
obj_log.info(sql)
|
||||
return obj_my_sql_helper.select_one(sql)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
user_common_obj = AssetCommon()
|
||||
print(user_common_obj.get_order_info(**{'order_id': 1193182, 'business_line_type': '1', 'status': 100}))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# @Time : 2023/3/7 13:28
|
||||
# @Author: luozhipeng
|
||||
# @File : contract_pair_check.py
|
||||
import os
|
||||
import sys
|
||||
input_team_name = sys.argv
|
||||
|
||||
BASIC_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
TEAM_PATH = os.path.abspath(os.path.join(BASIC_PATH, '../../../{}'.format("base_framework")))
|
||||
sys.path.append(TEAM_PATH)
|
||||
PROJECT_PATH = os.path.abspath(os.path.join(BASIC_PATH, '../../..'))
|
||||
sys.path.append(PROJECT_PATH)
|
||||
from base_framework.public_tools.sqlhelper import MySqLHelper
|
||||
from base_framework.public_tools.utils import Tools
|
||||
import requests
|
||||
import re
|
||||
import json
|
||||
import pymysql
|
||||
|
||||
obj_my_sql_helper = MySqLHelper()
|
||||
|
||||
|
||||
class ContractPairCheck():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_unfinished_interface(self):
|
||||
sql_get_interface = "SELECT distinct (x.con_url) 提供方接口,x.pro_url 消费方接口,x.con_method 提供方请求方式,x.con_server 提供方服务,x.pro_server 消费方服务,x.at_num 自动化接口数 FROM sparkatp.contract_pair x WHERE x.at_num =0 and x.status =1 and x.con_server in (select si.server_name from sparkatp.swagger_info si where si.team in ('ubrd','GUE') and access_type IN (2)) and x.pro_server not in (select si.server_name from sparkatp.swagger_info si where si.team ='ubrd' and access_type IN (2)) and x.roles = 0 order by x.pro_server,x.con_url"
|
||||
unfinished_interface = obj_my_sql_helper.select_all(sql_get_interface)
|
||||
return unfinished_interface
|
||||
|
||||
def send_reshult(self):
|
||||
|
||||
headers = {"Content-Type": "application/json;charset=UTF-8"}
|
||||
web_hook = "https://open.feishu.cn/open-apis/bot/v2/hook/9f3556b7-cb60-44bf-adbf-24b5b2552014"
|
||||
|
||||
contract_pair_intf = self.get_unfinished_interface()
|
||||
if len(contract_pair_intf) != 0:
|
||||
message_data = {"msg_type": "text", "content": {'text': '未完成自动化的契约对接口{}'.format(contract_pair_intf)}}
|
||||
|
||||
rsp = requests.post(url=web_hook, json=message_data, headers=headers)
|
||||
|
||||
|
||||
class AutoInterfaceCheck():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_unfinished_interface(self):
|
||||
sql_get_interface = """select id,in_url from sparkatp.interface_info a WHERE( a.swagger_id in (SELECT id FROM sparkatp.swagger_info WHERE team in ("UBRD","GUE") and access_type not IN (0)) ) AND a.created_time > "2023-01-01 00:00:50" AND is_used = 1 and (case_numbers IS NULL or case_numbers='') and offline=0 and jira_id is null order by created_time """
|
||||
unfinished_interface_list = obj_my_sql_helper.select_all(sql_get_interface)
|
||||
return unfinished_interface_list
|
||||
|
||||
def get_interface_jira(self,interface):
|
||||
sql_req_time = "select max(created_time) created_time from sparkatp.request_parameters rp where rp.interface_id ={}".format(
|
||||
interface["id"])
|
||||
req_max_time = obj_my_sql_helper.select_one(sql_req_time)['created_time']
|
||||
sql_rep_time = "select max(created_time) created_time from sparkatp.response_parameters rp where rp.interface_id ={}".format(
|
||||
interface["id"])
|
||||
rep_max_time = obj_my_sql_helper.select_one(sql_rep_time)['created_time']
|
||||
if rep_max_time and req_max_time:
|
||||
if rep_max_time <= req_max_time:
|
||||
sql_req_jira = "select distinct (jira_id) from sparkatp.request_parameters rp where rp.interface_id ={0} and created_time = '{1}'".format(
|
||||
interface["id"], req_max_time)
|
||||
interface_jira = obj_my_sql_helper.select_one(sql_req_jira)["jira_id"]
|
||||
else:
|
||||
sql_rep_jira = "select distinct (jira_id) from sparkatp.response_parameters rp where rp.interface_id ={0} and created_time = '{1}'".format(
|
||||
interface["id"], rep_max_time)
|
||||
interface_jira = obj_my_sql_helper.select_one(sql_rep_jira)["jira_id"]
|
||||
elif rep_max_time and not req_max_time:
|
||||
sql_rep_jira = "select distinct (jira_id) from sparkatp.response_parameters rp where rp.interface_id ={0} and created_time = '{1}'".format(
|
||||
interface["id"], rep_max_time)
|
||||
interface_jira = obj_my_sql_helper.select_one(sql_rep_jira)["jira_id"]
|
||||
elif not rep_max_time and req_max_time:
|
||||
sql_req_jira = "select distinct (jira_id) from sparkatp.request_parameters rp where rp.interface_id ={0} and created_time = '{1}'".format(
|
||||
interface["id"], req_max_time)
|
||||
interface_jira = obj_my_sql_helper.select_one(sql_req_jira)["jira_id"]
|
||||
return interface_jira
|
||||
|
||||
def send_result(self):
|
||||
unfinished_interface_list = self.get_unfinished_interface()
|
||||
for interface in unfinished_interface_list:
|
||||
interface['jira'] = self.get_interface_jira(interface)
|
||||
if not interface['jira']:
|
||||
interface['qa'] = None
|
||||
else:
|
||||
interface['qa'] = self.get_jira_qa(interface['jira'])
|
||||
headers = {"Content-Type": "application/json;charset=UTF-8"}
|
||||
web_hook = "https://open.feishu.cn/open-apis/bot/v2/hook/9f3556b7-cb60-44bf-adbf-24b5b2552014"
|
||||
if len(unfinished_interface_list) != 0:
|
||||
message_data = {"msg_type": "text", "content": {'text': 'QA公共环境未完成自动化的接口{}'.format(unfinished_interface_list)}}
|
||||
rsp = requests.post(url=web_hook, json=message_data, headers=headers)
|
||||
|
||||
def get_jira_qa(self,jira):
|
||||
try:
|
||||
conn = pymysql.connect(host='10.250.200.53',user='root',password='peppa@test',database='tools',charset="utf8",port=3306)
|
||||
except :
|
||||
raise pymysql.OperationalError("连接数据库失败")
|
||||
cn =conn.cursor()
|
||||
sql = "SELECT tester FROM tools.tm_project where jira_number = '{}'".format(jira)
|
||||
cn.execute(sql)
|
||||
qa = cn.fetchall()
|
||||
cn.close()
|
||||
conn.close()
|
||||
if qa:
|
||||
return qa[0][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class CoverageCheck():
|
||||
|
||||
# 连接数据库
|
||||
@staticmethod
|
||||
def get_select(sql):
|
||||
try:
|
||||
conn = pymysql.connect(host='10.250.200.53', user='root', password='peppa@test', database='tools',
|
||||
charset="utf8", port=3306)
|
||||
except:
|
||||
raise pymysql.OperationalError("连接数据库失败")
|
||||
cn = conn.cursor()
|
||||
cn.execute(sql)
|
||||
res = cn.fetchall()
|
||||
cn.close()
|
||||
conn.close()
|
||||
return res
|
||||
|
||||
# 获取未搜集覆盖率的项目
|
||||
@staticmethod
|
||||
def get_unfinished_coverage():
|
||||
start_time = Tools().get_format_date(r_type=15, add_days=-2)
|
||||
end_time = Tools().get_format_date(r_type=16, add_days=-1)
|
||||
|
||||
# 查询最近一天上线有后端代码变动,需要搜集覆盖率项目
|
||||
need_sql = """SELECT env FROM tools.project_plan WHERE ID IN
|
||||
(SELECT project_id FROM tools.project_tester WHERE tester IN ("陈洁","陈江","罗志鹏","谯新久","刘涛婷"))
|
||||
AND status IN (14) AND rd_code_add_line>0 AND (it_start_date IS NOT NULL OR qa_start_date IS NOT null)
|
||||
AND online_date BETWEEN '{}' AND '{}'""".format(start_time, end_time)
|
||||
need_coverage_list = CoverageCheck().get_select(need_sql)
|
||||
|
||||
# 查询已搜集覆盖率项目
|
||||
sql_implemented_sql = '''SELECT `env_name` FROM `sparkatp`.`build_jacoco` WHERE `team` = 'UBRD' AND `status` = '1'
|
||||
AND `is_delete` = '0' AND `is_pass` = '1' '''
|
||||
completed_coverage_list = obj_my_sql_helper.select_all(sql_implemented_sql)
|
||||
|
||||
unfinished_coverage_list = []
|
||||
for item1 in range(0, len(need_coverage_list)):
|
||||
unfinished_coverage_list.append(need_coverage_list[item1][0])
|
||||
|
||||
# 返回未搜集覆盖率的项目
|
||||
for item in completed_coverage_list:
|
||||
completed_jira = item["env_name"]
|
||||
if completed_jira in unfinished_coverage_list:
|
||||
unfinished_coverage_list.remove(completed_jira)
|
||||
# 根据unfinished_coverage_list 查jira_name
|
||||
jira_name_list = []
|
||||
for item in unfinished_coverage_list:
|
||||
env_name = item
|
||||
sql = """SELECT jira_number FROM tools.project_plan WHERE env='{}'""".format(env_name)
|
||||
jira_name = CoverageCheck().get_select(sql)
|
||||
jira_name_list.append(jira_name[0][0])
|
||||
return jira_name_list
|
||||
|
||||
# 获取未构建基线用例项目
|
||||
@staticmethod
|
||||
def get_not_bulid_jira():
|
||||
start_time = Tools().get_format_date(r_type=15, add_days=-2)
|
||||
end_time = Tools().get_format_date(r_type=16, add_days=-1)
|
||||
|
||||
# 返回有后端变动的jira (有后端代码变更&上线时间在3天内 + jira存在服务变更,项目状态为sim测试)
|
||||
need_sql = """SELECT env FROM tools.project_plan WHERE
|
||||
ID IN (SELECT project_id FROM tools.project_tester WHERE tester IN ("陈洁","陈江","罗志鹏","谯新久","刘涛婷"))
|
||||
AND status IN (14) AND rd_code_add_line>0 AND online_date BETWEEN '{}' AND '{}'
|
||||
AND qa_start_date IS NOT NULL UNION SELECT env FROM tools.project_plan WHERE ID IN (SELECT project_plan_id
|
||||
FROM tools.project_plan_server) AND jira_number IN (SELECT jira_number FROM tools.tm_project WHERE status
|
||||
IN (12) AND `tester` IN ("陈洁","陈江","罗志鹏","谯新久","刘涛婷") AND test_qa_time_consume>0)""".format(start_time,
|
||||
end_time)
|
||||
|
||||
need_build_list = CoverageCheck().get_select(need_sql)
|
||||
|
||||
# 返回有构建基线用例jira
|
||||
built_sql = """SELECT DISTINCT special_env FROM sparkatp.build_info WHERE run_type=2 AND team='UBRD' AND STATUS=2"""
|
||||
built_list = obj_my_sql_helper.select_all(built_sql)
|
||||
|
||||
not_bulit_list = []
|
||||
# 取出有后端改动得jira
|
||||
for item1 in range(0, len(need_build_list)):
|
||||
not_bulit_list.append(need_build_list[item1][0])
|
||||
|
||||
# 返回未构建基线用例jira
|
||||
for item in built_list:
|
||||
completed_jira = item["special_env"]
|
||||
if completed_jira in not_bulit_list:
|
||||
not_bulit_list.remove(completed_jira)
|
||||
jira_name_list = []
|
||||
for item in not_bulit_list:
|
||||
env_name = item
|
||||
sql = """SELECT jira_number FROM tools.project_plan WHERE env='{}'""".format(env_name)
|
||||
jira_name = CoverageCheck().get_select(sql)
|
||||
jira_name_list.append(jira_name[0][0])
|
||||
return jira_name_list
|
||||
|
||||
# 发送消息
|
||||
def send_result(self, type=1):
|
||||
if type == 1:
|
||||
jira_list = self.get_unfinished_coverage()
|
||||
elif type == 2:
|
||||
jira_list = self.get_not_bulid_jira()
|
||||
|
||||
send_list = []
|
||||
for item in jira_list:
|
||||
send_dict = {}
|
||||
send_dict["jira"] = item
|
||||
qa_list = AutoInterfaceCheck().get_jira_qa(item)
|
||||
send_dict["qa"] = qa_list
|
||||
send_list.append(send_dict)
|
||||
|
||||
headers = {"Content-Type": "application/json;charset=UTF-8"}
|
||||
web_hook = "https://open.feishu.cn/open-apis/bot/v2/hook/b6bf33ae-4239-4bef-a8a8-21896e0d1ba1"
|
||||
if len(jira_list) != 0:
|
||||
if type == 1:
|
||||
message_data = {"msg_type": "text",
|
||||
"content": {'text': '未搜集覆盖率已上线项目{}'.format(send_list)}}
|
||||
rsp = requests.post(url=web_hook, json=message_data, headers=headers)
|
||||
elif type == 2:
|
||||
message_data = {"msg_type": "text",
|
||||
"content": {'text': '未构建基线用例已上线项目{}'.format(send_list)}}
|
||||
rsp = requests.post(url=web_hook, json=message_data, headers=headers)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
A = ContractPairCheck()
|
||||
A.send_reshult()
|
||||
B = AutoInterfaceCheck()
|
||||
# B.get_unfinished_interface()
|
||||
# B.get_jira_qa(jira = 'PLATFORM-31791')
|
||||
B.send_result()
|
||||
C = CoverageCheck()
|
||||
C.send_result(type=1)
|
||||
C.send_result(type=2)
|
||||
@@ -1,31 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
"""
|
||||
Author: 罗志鹏
|
||||
Email: luozhipeng@huohua.cn
|
||||
Create Date: 2022/03/03 11:25 下午
|
||||
"""
|
||||
from base_framework.public_tools import log
|
||||
from base_framework.public_tools.sqlhelper import MySqLHelper
|
||||
|
||||
obj_log = log.get_logger()
|
||||
obj_my_sql_helper = MySqLHelper()
|
||||
|
||||
class CoursePackageCommon:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_course_package_info_by_name(self, course_package_name):
|
||||
"""
|
||||
功能:根据套餐名称获取套餐基本信息
|
||||
| 输入参数: | course_package_name string | 套餐名称 |
|
||||
"""
|
||||
sql = "SELECT id,code,name,price FROM `peppa`.`course_package` WHERE `name`='{}';".format(course_package_name)
|
||||
return obj_my_sql_helper.select_one(sql)
|
||||
if __name__ == '__main__':
|
||||
user_common_obj = CoursePackageCommon()
|
||||
user_common_obj.get_course_package_info_by_name('测试杰拉德0325-火花-直播逻辑思维')
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib
|
||||
|
||||
# 设置字体为支持中文的字体(如SimHei)
|
||||
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # Windows系统
|
||||
# matplotlib.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # macOS系统
|
||||
matplotlib.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
|
||||
|
||||
# 数据
|
||||
categories = ['供应链', '天窗', 'cc', 'la', '题库', '练测', '教务', '教师', '基础', '学生端', '家长端', '活字', '转介绍']
|
||||
values = [8, 4, 13, 20, 11, 2, 22, 10, 1, 1, 14, 1, 17]
|
||||
|
||||
# 创建柱状图
|
||||
plt.figure(figsize=(10, 6))
|
||||
bars = plt.bar(categories, values, color='skyblue')
|
||||
|
||||
# 添加标题和标签
|
||||
plt.title('各类别数量统计', fontsize=16)
|
||||
plt.xlabel('类别', fontsize=12)
|
||||
plt.ylabel('数量', fontsize=12)
|
||||
plt.xticks(rotation=45, ha='right') # 旋转X轴标签
|
||||
|
||||
# 在每个柱子上方显示数量
|
||||
for bar in bars:
|
||||
height = bar.get_height()
|
||||
plt.text(bar.get_x() + bar.get_width() / 2, height, str(height),
|
||||
ha='center', va='bottom', fontsize=10)
|
||||
|
||||
# 显示图表
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
@@ -1,7 +0,0 @@
|
||||
[QA]
|
||||
check_list = ['PEPPA-STUDENT-API','PEPPA-LEARNING-PLAN-LISTENER','PEPPA-LEARNING-PLAN-SERVER','PEPPA-TEACH-BIZ','PEPPA-TEACH-LISTENER','PEPPA-TEACH-TIMETABLE-SERVER','PEPPA-USER-AUTH-API','PEPPA-USER-CENTER-SERVER']
|
||||
|
||||
|
||||
|
||||
[SIM]
|
||||
check_list = ['PEPPA-STUDENT-API','PEPPA-LEARNING-PLAN-LISTENER','PEPPA-LEARNING-PLAN-SERVER','PEPPA-TEACH-BIZ','PEPPA-TEACH-LISTENER','PEPPA-TEACH-TIMETABLE-SERVER','PEPPA-USER-AUTH-API','PEPPA-USER-CENTER-SERVER']
|
||||
@@ -1,141 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
"""
|
||||
Author: 罗志鹏
|
||||
Email: luozhipeng@huohua.cn
|
||||
Create Date: 2022/07/25 11:25 下午
|
||||
"""
|
||||
|
||||
import requests
|
||||
import re
|
||||
import json
|
||||
|
||||
|
||||
|
||||
|
||||
class EnvCheck():
|
||||
def __init__(self):
|
||||
self.container_ip_list = []
|
||||
|
||||
|
||||
|
||||
def get_env_container_ip(self,env):
|
||||
dis_server =[]
|
||||
dis_ip = []
|
||||
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9','Accept-Encoding':'gzip, deflate, br'}
|
||||
if env =='QA':
|
||||
req = requests.get(url="http://eureka.qa.huohua.cn/",headers=headers)
|
||||
elif env == 'SIM':
|
||||
req = requests.get(url="http://eureka.sim.huohua.cn/", headers=headers)
|
||||
else:
|
||||
raise RuntimeError("环境选择异常")
|
||||
req_list =req.text.split('tbody')
|
||||
# print(req_list[1])
|
||||
server_str_list = req_list[1].split('<tr>')
|
||||
check_list = self.get_check_lsit(env=env)
|
||||
|
||||
for server in check_list:
|
||||
if req.text.find(server) ==-1:
|
||||
dis_server.append(server)
|
||||
|
||||
|
||||
for i in check_list:
|
||||
for str_ser in server_str_list:
|
||||
if str_ser.find(i) != -1:
|
||||
dict_sever = {}
|
||||
# ip_list = []
|
||||
str_sername_start = '<td><b>'
|
||||
str_sername_end = '</b></td>'
|
||||
server_name = str_ser[str_ser.find(str_sername_start) + 7:str_ser.find(str_sername_end)]
|
||||
ip_list = re.findall(r'[a-z]://(.*?):8080', str_ser)
|
||||
dict_sever[server_name] = ip_list
|
||||
# print(dict_sever)
|
||||
for ip_ch in ip_list:
|
||||
url_check = "http://"+ip_ch+':8080/actuator/health'
|
||||
resp = requests.get(url=url_check)
|
||||
# print(resp.json())
|
||||
if resp.json()['status'] != 'UP':
|
||||
dict_ip = {server_name:ip_ch}
|
||||
dis_ip.append(dict_ip)
|
||||
return dis_ip,dis_server
|
||||
|
||||
|
||||
# re_list = []
|
||||
# server_list = []
|
||||
# for str_ser in server_check_list:
|
||||
# print(str_ser)
|
||||
|
||||
# print(server_name)
|
||||
|
||||
# pattern = re.compile(r'')
|
||||
# str_server = pattern.search(str_ser)
|
||||
# server_name = str_ser[str_ser.start():str_ser.end()]
|
||||
# print(server_name)
|
||||
# for server in check_list :
|
||||
# for string_server in server_list:
|
||||
# if string_server.find(server)!= -1:
|
||||
# # print(string_server.find(server))
|
||||
# re_list.append(string_server)
|
||||
|
||||
# print(re_list)
|
||||
# ip_list = []
|
||||
# for string_server in re_list :
|
||||
# if string_server.find('http://'):
|
||||
# pattern = re.compile(r'[a-zA-z]+://[^\s]*:8080')
|
||||
# str_ip = pattern.search(string_server)
|
||||
# # print(str_ip.start())
|
||||
# url = string_server[str_ip.start():str_ip.end()]
|
||||
# print(url)
|
||||
|
||||
def send_result(self):
|
||||
dis_ip,dis_server = self.get_env_container_ip(env='SIM')
|
||||
at_user_list = [{"tag": "at", "user_id": "{}".format("7020366259502153730")}]
|
||||
|
||||
message_data_SIM_server = {"msg_type": "text", "content": {'text':'SIM服务未找到部署IP{}'.format(dis_server)}}
|
||||
message_data_SIM_IP = {"msg_type": "text", "content": {'text':'SIM服务部署IP不可用{}'.format(dis_ip)}}
|
||||
|
||||
headers = {"Content-Type": "application/json;charset=UTF-8"}
|
||||
web_hook = "https://open.feishu.cn/open-apis/bot/v2/hook/28b775e7-a863-4807-b280-c82e09be0a80"
|
||||
if len(dis_server) != 0:
|
||||
json_data = json.dumps(message_data_SIM_server)
|
||||
rsp = requests.post(url=web_hook, json=message_data_SIM_server, headers=headers)
|
||||
|
||||
if len(dis_ip) != 0:
|
||||
json_data = json.dumps(message_data_SIM_IP)
|
||||
rsp = requests.post(url=web_hook, json=message_data_SIM_IP, headers=headers)
|
||||
dis_ip,dis_server = self.get_env_container_ip(env='QA')
|
||||
message_data_QA_server = {"msg_type": "text", "content": {'text':'QA服务未找到部署IP{}'.format(dis_server)}}
|
||||
message_data_QA_IP = {"msg_type": "text", "content": {'text':'QA服务部署IP不可用{}'.format(dis_ip)}}
|
||||
|
||||
if len(dis_server) != 0:
|
||||
json_data = json.dumps(message_data_QA_server)
|
||||
rsp = requests.post(url=web_hook, data=json_data, headers=headers)
|
||||
if len(dis_ip) != 0:
|
||||
json_data = json.dumps(message_data_QA_IP)
|
||||
rsp = requests.post(url=web_hook, json=message_data_QA_IP, headers=headers)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def get_check_lsit(self,env):
|
||||
if env == 'QA':
|
||||
check_list = ['PEPPA-STUDENT-API','PEPPA-LEARNING-PLAN-LISTENER','PEPPA-LEARNING-PLAN-SERVER','PEPPA-TEACH-BIZ','PEPPA-TEACH-LISTENER','PEPPA-TEACH-TIMETABLE-SERVER','PEPPA-USER-AUTH-API','PEPPA-USER-CENTER-SERVER']
|
||||
return check_list
|
||||
if env == 'SIM':
|
||||
check_list = ['PEPPA-STUDENT-API','PEPPA-LEARNING-PLAN-LISTENER','PEPPA-LEARNING-PLAN-SERVER','PEPPA-TEACH-BIZ','PEPPA-TEACH-LISTENER','PEPPA-TEACH-TIMETABLE-SERVER','PEPPA-USER-AUTH-API','PEPPA-USER-CENTER-SERVER']
|
||||
return check_list
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# o ='"http://10.251.187.248:8080/actuator/info" "http://10.251.187.248:8080/actuator/info"'
|
||||
# i =re.findall(r'[a-z]://(.*?):8080',o)
|
||||
# print(a)
|
||||
A=EnvCheck()
|
||||
A.send_result()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
# encoding: UTF-8
|
||||
import time
|
||||
import subprocess
|
||||
from subprocess import PIPE,Popen
|
||||
import os
|
||||
|
||||
|
||||
class OSType:
|
||||
WIN, LINUX, UNKNOWN = range(3)
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_type():
|
||||
import platform
|
||||
system_name = platform.system()
|
||||
if system_name.lower() == 'windows':
|
||||
return OSType.WIN
|
||||
elif system_name.lower() == 'linux':
|
||||
return OSType.LINUX
|
||||
else:
|
||||
return OSType.UNKNOWN
|
||||
|
||||
|
||||
class tool(object):
|
||||
def __init__(self):
|
||||
self.env_port = 5011
|
||||
|
||||
def run_process(self, cmd_str, out_p=False):
|
||||
"""
|
||||
run command
|
||||
cmd_str unicode string.
|
||||
"""
|
||||
if OSType.WIN == OSType.get_type():
|
||||
# cmd_str = cmd_str.encode('gbk')
|
||||
cmd_str = cmd_str
|
||||
elif OSType.LINUX == OSType.get_type():
|
||||
cmd_str = cmd_str.encode('utf-8')
|
||||
else:
|
||||
raise RuntimeError("your os is not support.")
|
||||
close_fds = False if OSType.WIN == OSType.get_type() else True
|
||||
if out_p:
|
||||
p = subprocess.Popen(cmd_str, shell=True, close_fds=close_fds, stdout=PIPE)
|
||||
p.wait()
|
||||
return p.returncode, p.stdout.read()
|
||||
else:
|
||||
c = self.get_devnull()
|
||||
p = subprocess.Popen(cmd_str, shell=True, close_fds=close_fds, stdout=c)
|
||||
# for line in p.stdout.readline():
|
||||
# print(line)
|
||||
# p.stdout.close()
|
||||
p.communicate()
|
||||
return p.returncode, None
|
||||
|
||||
def adb_cmd(self,cmd):
|
||||
process = Popen(cmd, shell=True, stderr=PIPE, stdout=PIPE)
|
||||
(stdout, stdrr) = process.communicate()
|
||||
stdout = stdout.decode('gbk') # 返回字段中存在中文,使用gbk
|
||||
|
||||
return stdout, stdrr
|
||||
|
||||
def get_devnull(self):
|
||||
try:
|
||||
return subprocess.DEVNULL
|
||||
except AttributeError:
|
||||
# Python 2.x or older
|
||||
return open(os.devnull, 'r+')
|
||||
|
||||
def _kills_pid(self):
|
||||
if OSType.WIN == OSType.get_type():
|
||||
kill_pid_cmd = "taskkill /f /pid {}".format(self.pid)
|
||||
elif OSType.LINUX == OSType.get_type():
|
||||
kill_pid_cmd = "kill -9 {}".format(self.pid)
|
||||
else:
|
||||
raise RuntimeError("your os is not support.")
|
||||
|
||||
res_code, res_context = self.run_process(kill_pid_cmd)
|
||||
if res_code:
|
||||
raise RuntimeError("kill pid: {} failed. error: {}".format(self.pid, res_context))
|
||||
|
||||
def check_port(self):
|
||||
if OSType.WIN == OSType.get_type():
|
||||
find_pid_win_cmd = 'netstat -ano | findstr {} | findstr LISTENING'.format(self.env_port)
|
||||
print(find_pid_win_cmd)
|
||||
res_code, res_context = self.run_process(find_pid_win_cmd, out_p=True)
|
||||
if res_code == 0:
|
||||
if len(res_context) > 0:
|
||||
try:
|
||||
self.pid = str(res_context).split()[-1].replace("\\r\\n'", "")
|
||||
self._kills_pid()
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
elif OSType.LINUX == OSType.get_type():
|
||||
find_pid_linux_cmd = "lsof -i:{}".format(self.env_port)
|
||||
res_code, res_context = self.run_process(find_pid_linux_cmd, out_p=True)
|
||||
if res_code == 0:
|
||||
# 获取pid
|
||||
if len(res_context) > 0:
|
||||
try:
|
||||
self.pid = str(res_context).split("\n")[1].split()[1]
|
||||
self._kills_pid()
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
raise RuntimeError("your os is not support.")
|
||||
|
||||
def run_manage(self):
|
||||
count = 3
|
||||
while count > 0:
|
||||
self.run_manages()
|
||||
find_pid_linux_cmd = "lsof -i:{}".format(self.env_port)
|
||||
res_code, res_context = self.run_process(find_pid_linux_cmd, out_p=True)
|
||||
print(res_code, "---res_code---", res_context, "---res_context---")
|
||||
if len(res_context) > 0:
|
||||
time.sleep(2)
|
||||
pid = str(res_context).split("\n")[1].split()[1]
|
||||
print(pid, "pid####")
|
||||
count -= 1
|
||||
if pid:
|
||||
break
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
def run_manages(self):
|
||||
lod = "nohup python3 platform_tools/aida/manage.py &."
|
||||
sh_lod = "./5011.sh"
|
||||
|
||||
self.run_process(sh_lod)
|
||||
# subprocess.call(["./5011.sh"])
|
||||
# self.run_process(lod)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test = tool()
|
||||
test.check_port()
|
||||
time.sleep(3)
|
||||
test.run_manage()
|
||||
@@ -1,105 +0,0 @@
|
||||
import os
|
||||
import subprocess
|
||||
from urllib.parse import urlparse
|
||||
import argparse
|
||||
|
||||
|
||||
class HarmonyAppInstaller:
|
||||
def __init__(self) -> None:
|
||||
self.project_path = os.getcwd()
|
||||
self.temp_dir = os.path.join(self.project_path, "temp")
|
||||
|
||||
def _run_command(self, command: str) -> str:
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception(f"Command failed: {command}\nError: {result.stderr}")
|
||||
return result.stdout
|
||||
|
||||
def install(self, appUniqId, packageId):
|
||||
import requests
|
||||
import os
|
||||
import shutil
|
||||
|
||||
# Create or clean temp directory
|
||||
if os.path.exists(self.temp_dir):
|
||||
shutil.rmtree(self.temp_dir)
|
||||
os.makedirs(self.temp_dir)
|
||||
|
||||
url = "https://api.qa.huohua.cn/api/versions"
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'huohua-podenv': 'HHC-111781'
|
||||
}
|
||||
|
||||
params = {
|
||||
'version': '25.1.2.1',
|
||||
'platform': 'harmonyos',
|
||||
'appUniqId': appUniqId,
|
||||
'packageId': packageId
|
||||
}
|
||||
|
||||
response = requests.get(url, headers=headers, params=params)
|
||||
response_data = response.json()
|
||||
|
||||
if not response_data.get('success'):
|
||||
raise Exception(f"API request failed: {response_data.get('message')}")
|
||||
|
||||
app_version = response_data.get('data', {}).get('app_version', {})
|
||||
download_url = app_version.get('url')
|
||||
|
||||
if not download_url:
|
||||
raise Exception("No download URL found in response")
|
||||
|
||||
# Get the filename from the URL
|
||||
hap_filename = os.path.basename(urlparse(download_url).path)
|
||||
if not hap_filename.endswith('.hap'):
|
||||
hap_filename = 'eduparent.hap' # fallback name if URL doesn't end with .hap
|
||||
|
||||
# Download the HAP file
|
||||
hap_file_path = os.path.join(self.temp_dir, hap_filename)
|
||||
download_response = requests.get(download_url, stream=True)
|
||||
download_response.raise_for_status()
|
||||
|
||||
with open(hap_file_path, 'wb') as f:
|
||||
for chunk in download_response.iter_content(chunk_size=8192):
|
||||
if chunk:
|
||||
f.write(chunk)
|
||||
|
||||
# Execute HDC commands
|
||||
device_path = f"data/local/tmp/{hap_filename}"
|
||||
|
||||
print(f'hdc file send "{hap_file_path}" "{device_path}"')
|
||||
# Push HAP file to device
|
||||
self._run_command(f'hdc file send "{hap_file_path}" "{device_path}"')
|
||||
|
||||
try:
|
||||
# Install HAP package
|
||||
print(f'hdc shell bm install -p "{device_path}"')
|
||||
self._run_command(f'hdc shell bm install -p "{device_path}"')
|
||||
finally:
|
||||
# Clean up: Remove HAP file from device
|
||||
print(f'hdc shell rm -rf "{device_path}"')
|
||||
self._run_command(f'hdc shell rm -rf "{device_path}"')
|
||||
|
||||
return hap_file_path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Install HarmonyOS application')
|
||||
parser.add_argument('--app-uniq-id', required=True, help='Unique ID of the application')
|
||||
parser.add_argument('--package-id', required=True, help='Package ID for the application')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
installer = HarmonyAppInstaller()
|
||||
hap_path = installer.install(args.app_uniq_id, args.package_id)
|
||||
print(f"Successfully installed HAP from: {hap_path}")
|
||||
except Exception as e:
|
||||
print(f"Error: {str(e)}")
|
||||
exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,257 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
WORKSPACE = sys.argv[1]
|
||||
sys.path.append(WORKSPACE)
|
||||
import json
|
||||
import requests
|
||||
import os
|
||||
import re
|
||||
from bs4 import BeautifulSoup
|
||||
from html.parser import HTMLParser
|
||||
|
||||
handle_parser = HTMLParser()
|
||||
BUILD_INFO = {}
|
||||
|
||||
|
||||
class handle_to_jenkins():
|
||||
'''
|
||||
处理关于jenkins的执行相关方法
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
self.dict_info = {}
|
||||
self.list_info = []
|
||||
def GetJenkinsVar(self, key):
|
||||
'''
|
||||
获取jenkins上获得的参数信息
|
||||
'''
|
||||
try:
|
||||
value = os.environ.get(key)
|
||||
except Exception:
|
||||
value = os.environ.get(key.upper())
|
||||
if (not value):
|
||||
value = ''
|
||||
return value
|
||||
|
||||
def kw_to_get_dd_token(self, environment):
|
||||
"""
|
||||
功能: 根据传入环境获取不同的token信息
|
||||
"""
|
||||
sim = "40696c86-264a-4222-a40c-cfd64a05dffd"
|
||||
product = "40696c86-264a-4222-a40c-cfd64a05dffd"
|
||||
if environment.lower() == "sim" or environment.lower() == "qa":
|
||||
return sim
|
||||
else:
|
||||
return product
|
||||
|
||||
def send_message_by_dingding(self, data, environment="qa"):
|
||||
'''
|
||||
发送钉钉消息
|
||||
'''
|
||||
token = self.kw_to_get_dd_token(environment=environment)
|
||||
# web_hook = "https://oapi.dingtalk.com/robot/send?access_token={}".format(token)
|
||||
web_hook = "https://open.feishu.cn/open-apis/bot/v2/hook/{}".format(token)
|
||||
headers = {"Content-Type": "application/json"}
|
||||
json_data = json.dumps(data)
|
||||
rsp = requests.post(url=web_hook, data=json_data, headers=headers)
|
||||
return rsp
|
||||
|
||||
# print(data)
|
||||
def send_feishu(self,inferfaces):
|
||||
'''
|
||||
发送飞书
|
||||
:return:
|
||||
'''
|
||||
at_user_list = [{"tag": "at", "user_id": "{}".format("7020366259502153730")}]
|
||||
message_data = {"msg_type": "post", "content": {
|
||||
"post": {"zh_cn": {"title": "有存在的接口未实现自动化哦",
|
||||
"content": [[{"tag": "text", "text": "问题数据:"}],
|
||||
[{"tag": "text", "text": "{}".format(inferfaces)}],
|
||||
at_user_list]}}}}
|
||||
web_hook = "https://open.feishu.cn/open-apis/bot/v2/hook/40696c86-264a-4222-a40c-cfd64a05dffd"
|
||||
headers = {"Content-Type": "application/json"}
|
||||
json_data = json.dumps(message_data)
|
||||
print(json_data)
|
||||
rsp = requests.post(url=web_hook, data=json_data, headers=headers)
|
||||
return rsp
|
||||
|
||||
def handle_send_message(self,root):
|
||||
'''
|
||||
处理对应所有人,根据job名称匹配来发送@的消息
|
||||
'''
|
||||
list_name_phone = {"陈江": "13458500234", "张楠": "", "罗志鹏": "",
|
||||
"蒲思宇": "", "陈洁": "15328118883", "刘涛婷": "18328504751", "谯新久": "18202810506"}
|
||||
job_name = self.GetJenkinsVar("JOB_TO_NAME")
|
||||
job_url = self.GetJenkinsVar("JOB_TO_URL")
|
||||
enviroment = self.GetJenkinsVar("JOB_ENVIRONMENT")
|
||||
|
||||
# job_name = "123"
|
||||
# job_url = "http://10.250.200.1:8080/jenkins/job/QA%E7%8E%AF%E5%A2%83%E5%B7%A1%E6%A3%80/2387/robot/report/report.html"
|
||||
# enviroment = "PRODUCT"
|
||||
|
||||
dict_info = self.get_fail_test_case(son_node=root)
|
||||
BUILD_INFO = dict_info.get("BUILD_INFO")
|
||||
fail_info = dict_info.get("INFO")
|
||||
list_phone = []
|
||||
if BUILD_INFO:
|
||||
for key, value in BUILD_INFO.items():
|
||||
list_phone.append(list_name_phone.get(key))
|
||||
print(list_phone)
|
||||
print("+++++++{0}+++++{1}".format(job_name, job_url))
|
||||
if re.search("PRODUCT", enviroment):
|
||||
# message_data = {"msg_type": "text", "content": {
|
||||
# "text": "线上巡检:线上环境出现了问题,请点击进行查看{0},以下是错误日志:{1}".format(job_url + "robot/report/report.html",fail_info)},
|
||||
# "at": {"atMobiles": list_phone}}
|
||||
|
||||
at_user_list = [{"tag": "at", "user_id": "{}".format("7020366258071715842")}]
|
||||
message_data = {"msg_type": "post", "content": {
|
||||
"post": {"zh_cn": {"title": "线上环境巡检",
|
||||
"content": [[{"tag": "text", "text": "线上环境出现了问题:"}],
|
||||
[{"tag": "a", "text": "点击查看","href":"".format(job_url + "robot/report/report.html")}],
|
||||
at_user_list]}}}}
|
||||
print(message_data)
|
||||
self.send_message_by_dingding(message_data,environment="product")
|
||||
|
||||
return enviroment
|
||||
if re.search("QA", enviroment) or re.search("SIM", enviroment):
|
||||
message_data = {"msg_type": "text", "content": {
|
||||
"text": "{0}环境构建出问题了哦,请点击进行查看{1},以下是错误日志:{2}".format(enviroment, job_url + "robot/report/report.html",fail_info)},
|
||||
"at": {"atMobiles": list_phone}}
|
||||
print(message_data)
|
||||
self.send_message_by_dingding(message_data)
|
||||
return enviroment
|
||||
for key, value in list_name_phone.items():
|
||||
if re.search(key, job_name):
|
||||
message_data = {"msg_type": "text", "content": {
|
||||
"text": "亲爱的{0}同学,你的独立环境构建出问题了哦,请点击进行查看{1}".format(key, job_url + "robot/report/report.html")},
|
||||
"at": {"atMobiles": [value]}}
|
||||
self.send_message_by_dingding(message_data)
|
||||
return value
|
||||
else:
|
||||
return "这个job:{}没有找到人".format(job_name)
|
||||
|
||||
def get_fail_test_case(self,son_node, father_node=None, grandpa_node=None):
|
||||
"""
|
||||
功能:遍历xml文件的所有节点,搜索构建失败的用例信息
|
||||
"""
|
||||
children_node = son_node.getchildren()
|
||||
if len(children_node) == 0:
|
||||
# if son_node.tag == 'doc':
|
||||
# print(son_node.text)
|
||||
# if son_node.tag == 'msg' and son_node.attrib['level'] == 'FAIL':
|
||||
# # print(son_node.text)
|
||||
# # print(son_node.attrib['timestamp'])
|
||||
# print(children_node)
|
||||
if son_node.tag == 'status' and son_node.attrib['status'] == 'FAIL' and 'critical' in son_node.attrib:
|
||||
|
||||
# print(father_node.attrib["name"])
|
||||
tag = self.find_tags(father_node)
|
||||
# a = self.find_error(father_node)
|
||||
# print(a)
|
||||
info_error = self.check_log_info(son_node.text)
|
||||
INFO = "用例名称:" + father_node.attrib["name"] +"。人员:" + tag + "。失败日志:" + str(info_error)
|
||||
run_time = son_node.attrib['endtime']
|
||||
# print(info_error)
|
||||
# print(son_node.text)
|
||||
# self.check_log_info(text=son_node.text)
|
||||
run_time = "{}-{}-{} {}".format(run_time[0:4], run_time[4:6], run_time[6:8], run_time[9:17])
|
||||
reason = son_node.text.replace('"', '\\"')
|
||||
# 满足构建时间,同时数据库中没有数据,才入库
|
||||
# print(run_time)
|
||||
if tag in BUILD_INFO:
|
||||
BUILD_INFO[tag] += 1
|
||||
else:
|
||||
BUILD_INFO[tag] = 1
|
||||
# print(BUILD_INFO)
|
||||
# print(tag)
|
||||
self.list_info.append(INFO)
|
||||
self.dict_info["BUILD_INFO"] = BUILD_INFO
|
||||
self.dict_info["INFO"] = self.list_info
|
||||
# print(tag)
|
||||
|
||||
run_time = run_time
|
||||
author = tag
|
||||
case_name = father_node.attrib['name']
|
||||
file_path = grandpa_node.attrib['source']
|
||||
reason = reason[0:4500]
|
||||
return self.dict_info
|
||||
for child in children_node:
|
||||
self.dict_info = self.get_fail_test_case(child, son_node, father_node)
|
||||
return self.dict_info
|
||||
|
||||
def check_log_info(self,text):
|
||||
'''
|
||||
过滤精确日志信息
|
||||
'''
|
||||
soup = BeautifulSoup(text, features="lxml")
|
||||
list_info = []
|
||||
for a in soup.find_all(name='span'):
|
||||
dict_info = {}
|
||||
if a.text == "Old message:":
|
||||
dict_info["old_message"] = a.nextSibling
|
||||
list_info.append(dict_info)
|
||||
elif a.text == "New message:":
|
||||
dict_info["new_message"] = a.nextSibling
|
||||
list_info.append(dict_info)
|
||||
# print(a.nextSibling)
|
||||
|
||||
if list_info:
|
||||
return list_info
|
||||
else:
|
||||
return text
|
||||
|
||||
|
||||
|
||||
def find_tags(self,root):
|
||||
"""
|
||||
功能:在xml文件中搜索失败用对应的作者
|
||||
"""
|
||||
children_node = root.getchildren()
|
||||
for child in children_node:
|
||||
if child.tag == 'tags':
|
||||
tags = child.getchildren()
|
||||
for tag in tags:
|
||||
if 'qa-' in tag.text.lower():
|
||||
return tag.text[3:len(tag.text)]
|
||||
return "无作者标签"
|
||||
|
||||
def find_error(self,root):
|
||||
"""
|
||||
功能:在xml文件中查询失败日志
|
||||
"""
|
||||
children_node = root.getchildren()
|
||||
for child in children_node:
|
||||
if child.tag == 'kw':
|
||||
msgs = child.getchildren()
|
||||
for msg in msgs:
|
||||
a = msg.tag
|
||||
|
||||
# t = msg.attrib['level']
|
||||
l = msg.text
|
||||
# print(msg.attrib['timestamp'])
|
||||
if msg.tag == 'msg' and msg.attrib['level'] == 'FAIL':
|
||||
print(msg.attrib)
|
||||
s = msg.text
|
||||
return msg.text
|
||||
return ""
|
||||
|
||||
def run(self):
|
||||
'''
|
||||
运行入口
|
||||
'''
|
||||
# FILE_PATH = "D:/output2.xml"
|
||||
FILE_PATH = os.path.abspath(os.path.join(WORKSPACE, 'Report/out/output.xml'))
|
||||
root = ET.parse(FILE_PATH).getroot()
|
||||
# self.get_fail_test_case(son_node=root)
|
||||
self.handle_send_message(root=root)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test = handle_to_jenkins()
|
||||
|
||||
# FILE_PATH = "D:/output1.xml"
|
||||
# FILE_PATH = os.path.abspath(os.path.join(WORKSPACE, 'Report/out/output.xml'))
|
||||
# root = ET.parse(FILE_PATH).getroot()
|
||||
# print(test.get_fail_test_case(son_node=root))
|
||||
test.run()
|
||||
# test.handle_send_message(root=root)
|
||||
@@ -1,331 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
人员当日jira任务、故事状态流转
|
||||
"""
|
||||
import os, sys
|
||||
|
||||
file_dir = os.path.dirname(__file__)
|
||||
project_dir = os.path.abspath(os.path.join(file_dir, "..", "..", ".."))
|
||||
sys.path.append(project_dir)
|
||||
|
||||
from jira import JIRA
|
||||
from base_framework.public_tools.utils import Tools
|
||||
from base_framework.public_tools.read_config import ReadConfig
|
||||
from base_framework.platform_tools.Message_service.Feishu_api import FeiShuMessage,get_user_name_by_email_prefix,get_feishu_config_value
|
||||
from configparser import ConfigParser
|
||||
from base_framework.base_config.current_pth import *
|
||||
import datetime
|
||||
|
||||
tools = Tools()
|
||||
ReadConfig = ReadConfig(filename=la_config_path)
|
||||
FS_INFO = [{"team": "TO", "users": "wuyonggang,xuwenjun,luohong"},
|
||||
{"team": "TO-RD", "users": "fengtian,guosongchao,zhaoxiaofang,"
|
||||
"zhuliang,majincheng,gaozhijun,liuxuegang,"
|
||||
"zhangxiong"},
|
||||
{"team": "USER-FE", "users": "zhaofei,liuxinlin,qingchen,yefei,xiangming,jianghao,jianglingmin,xuchangle,"
|
||||
"libaicheng,gouyuheng,jixiang.dong,baiyang01"}
|
||||
]
|
||||
|
||||
|
||||
class JiraApi:
|
||||
def __init__(self):
|
||||
self.jira = JIRA(server='https://jira.bg.huohua.cn/',
|
||||
basic_auth=("wuyonggang", "Mima@123"))
|
||||
|
||||
def close_jira_subtask(self, user_name):
|
||||
"""
|
||||
功能: 关闭指定人员名下当天结束的子任务
|
||||
请求参数 user_name (指定人员jira登录名,type: list)
|
||||
"""
|
||||
bad_name = []
|
||||
right_name = []
|
||||
for j in user_name:
|
||||
if j not in ReadConfig.get_sections():
|
||||
bad_name.append(j)
|
||||
elif j in ReadConfig.get_sections():
|
||||
right_name.append(j)
|
||||
success = []
|
||||
false = []
|
||||
today_time = tools.get_format_date(r_type=1)
|
||||
work_start_time = datetime.datetime.strptime('{0} 10:00:00'.format(today_time), '%Y-%m-%d %H:%M:%S')
|
||||
for name in right_name:
|
||||
jira = JIRA(server='https://jira.bg.huohua.cn/', basic_auth=(name, ReadConfig.get_value(name, 'password')))
|
||||
jql = 'project = HHC AND issuetype = 子任务 AND status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计,' \
|
||||
' 产品需求内审, 需求评审, 排期, 执行, 开发, 待测试, QA测试, SIM验证, 验证中, 待办, 处理中, 关闭) AND resolution = Unresolved' \
|
||||
' AND (QA in ({0}) OR assignee in ({1})) ORDER BY priority DESC, updated DESC'.format(name,name)
|
||||
issues = jira.search_issues(jql, fields='')
|
||||
# if len(issues) == 0: break
|
||||
not_need_closed = 0
|
||||
for i in issues:
|
||||
s = list(jira.transitions(i))
|
||||
close_status_id = [x['id'] for x in s if x['name'] == '关闭']
|
||||
if str(i.fields.status) == '处理中':
|
||||
if i.fields.aggregatetimeestimate != None:
|
||||
if i.fields.aggregatetimeestimate > 28800:
|
||||
jira.add_worklog(i, timeSpent='7', started=work_start_time)
|
||||
elif 0 < i.fields.aggregatetimeestimate <= 28800:
|
||||
jira.add_worklog(i, timeSpent='{0}'.format(i.fields.aggregatetimeestimate / 3600),
|
||||
started=work_start_time)
|
||||
else:
|
||||
jira.add_worklog(i, timeSpent='8', started=work_start_time)
|
||||
if str(i.fields.status) == '处理中' and str(i.fields.customfield_13406) == today_time:
|
||||
jira.transition_issue(i, int(close_status_id[0]))
|
||||
else:
|
||||
not_need_closed += 1
|
||||
issues2 = jira.search_issues(jql, fields='')
|
||||
if not_need_closed == len(issues2):
|
||||
success.append(name)
|
||||
else:
|
||||
false.append(name)
|
||||
return "{0}今日结束的子任务已关闭成功; {1}今日结束的子任务关闭失败; {2}没有进行账号配置".format(success, false, bad_name)
|
||||
|
||||
def start_jira_subtask(self, user_name):
|
||||
"""
|
||||
功能: 将待开始为今天的子任务状态流转为“处理中”
|
||||
请求参数 user_name (指定人员jira登录名,type: list)
|
||||
"""
|
||||
bad_name = []
|
||||
right_name = []
|
||||
for j in user_name:
|
||||
if j not in ReadConfig.get_sections():
|
||||
bad_name.append(j)
|
||||
elif j in ReadConfig.get_sections():
|
||||
right_name.append(j)
|
||||
success = []
|
||||
false = []
|
||||
for name in right_name:
|
||||
jira = JIRA(server='https://jira.bg.huohua.cn/', basic_auth=(name, ReadConfig.get_value(name, 'password')))
|
||||
jql = 'project = HHC AND issuetype = 子任务 AND status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计, 产品需求内审, 需求评审, ' \
|
||||
'排期, 执行, 开发, 待测试, QA测试, SIM验证, 验证中, 待办, 关闭) AND resolution = Unresolved' \
|
||||
' AND (QA in ({0}) OR assignee in ({1})) ORDER BY priority DESC, updated DESC'.format(name,name)
|
||||
today_time = tools.get_format_date(r_type=1)
|
||||
issues = jira.search_issues(jql, fields='')
|
||||
# if len(issues) == 0: break
|
||||
not_need_update = 0
|
||||
for i in issues:
|
||||
s = list(jira.transitions(i))
|
||||
start_status_id = [x['id'] for x in s if x['name'] == '处理中']
|
||||
if str(i.fields.status) == '待办' and str(i.fields.customfield_12700) == today_time:
|
||||
jira.transition_issue(i, int(start_status_id[0]))
|
||||
else:
|
||||
not_need_update += 1
|
||||
issues2 = jira.search_issues(jql, fields='')
|
||||
if not_need_update == len(issues2):
|
||||
success.append(name)
|
||||
else:
|
||||
false.append(name)
|
||||
return "{0}今日开始的子任务已将状态修改为“处理中”‘; {1}今日开始的子任务状态修改失败; {2}没有进行账号配置".format(success, false, bad_name)
|
||||
|
||||
def change_story(self, user_name, type):
|
||||
"""
|
||||
功能: 将提测时间为今天的指定人员名下的故事状态修改至“QA测试”
|
||||
请求参数 user_name (指定人员jira登录名,type: list)
|
||||
type (故事需要修改至的状态 1:提测日为今天,状态修改至【QA测试】 2:上线日为今天,状态修改至【关闭】)
|
||||
"""
|
||||
bad_name = []
|
||||
right_name = []
|
||||
for j in user_name:
|
||||
if j not in ReadConfig.get_sections():
|
||||
bad_name.append(j)
|
||||
elif j in ReadConfig.get_sections():
|
||||
right_name.append(j)
|
||||
success = []
|
||||
false = []
|
||||
for name in right_name:
|
||||
jira = JIRA(server='https://jira.bg.huohua.cn/', basic_auth=(name, ReadConfig.get_value(name, 'password')))
|
||||
jql = "project = HHC AND issuetype = 故事 AND " \
|
||||
"status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计, 产品需求内审, 需求评审, 排期, 执行, 开发, 待测试, 验证中, 待办, QA测试, SIM验证, 处理中, 关闭)" \
|
||||
" AND resolution = Unresolved AND QA in ({0}) ORDER BY priority DESC, updated DESC".format(name)
|
||||
today_time = tools.get_format_date(r_type=1)
|
||||
issues = jira.search_issues(jql, fields='')
|
||||
# if len(issues) == 0 : break
|
||||
x = 0
|
||||
need_update = 0
|
||||
if type == 1: # 将故事状态一直流转至“QA测试”
|
||||
for i in issues:
|
||||
if str(i.fields.status) == 'QA测试' or str(i.fields.status) == 'SIM验证': need_update += 1
|
||||
if str(i.fields.customfield_10504) == today_time:
|
||||
if str(i.fields.status) != 'QA测试' and str(i.fields.status) != 'SIM验证':
|
||||
need_update += 1
|
||||
for j in range(8):
|
||||
jira.transition_issue(i, int(jira.transitions(i)[2]['id']))
|
||||
issues_2 = jira.search_issues(jql, fields='') # 重新获取所有故事
|
||||
status_now = issues_2[x].fields.status
|
||||
print(status_now)
|
||||
if str(status_now) == 'QA测试' or str(status_now) == 'SIM验证':
|
||||
break
|
||||
x += 1
|
||||
jql2 = "project = HHC AND issuetype = 故事 AND " \
|
||||
"status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计, 产品需求内审, 需求评审, 排期, 执行, 开发, 待测试, 验证中, 待办, 处理中, 关闭)" \
|
||||
" AND resolution = Unresolved AND QA in ({0}) ORDER BY priority DESC, updated DESC".format(name)
|
||||
issues2 = jira.search_issues(jql2, fields='')
|
||||
if len(issues2) == len(issues) - need_update:
|
||||
success.append(name)
|
||||
else:
|
||||
false.append(name)
|
||||
elif type == 2: # 直接将故事关闭
|
||||
for i in issues:
|
||||
if str(i.fields.customfield_10606) == today_time:
|
||||
jira.transition_issue(i, int(jira.transitions(i)[1]['id']), comment="已上线") # 将故事修改为关闭状态
|
||||
need_update += 1
|
||||
issues2 = jira.search_issues(jql, fields='')
|
||||
if len(issues2) + need_update == len(issues):
|
||||
success.append(name)
|
||||
else:
|
||||
false.append(name)
|
||||
|
||||
return "{0}今日的故事已将状态修改成功!; {1}今日的故事状态修改失败; {2}没有进行账号配置".format(success, false, bad_name)
|
||||
|
||||
def change_jira_status(self, user_name):
|
||||
"""
|
||||
功能: 判断当前时间是否在下午18:00点以前,来选择打开或关闭【子任务】和【故事】
|
||||
请求参数 user_name (指定人员jira登录名,type: list)
|
||||
"""
|
||||
time_now = tools.get_format_date(r_type=4)
|
||||
time_now2 = '{0} 18:00:00'.format(time_now[0:10:1])
|
||||
if time_now < '{0} 18:00:00'.format(time_now2):
|
||||
a = self.start_jira_subtask(user_name)
|
||||
b = self.change_story(user_name, type=1)
|
||||
return a + '\n' + b
|
||||
elif time_now >= '{0} 18:00:00'.format(time_now2):
|
||||
a = self.close_jira_subtask(user_name)
|
||||
b = self.change_story(user_name, type=2)
|
||||
return a + '\n' + b
|
||||
|
||||
def query_jira_subtask(self, user_name, begin_date=0, end_date=0):
|
||||
"""
|
||||
| 功能 | 查询用户对应的jira子任务 |
|
||||
| 入参 | user_name | 用户名字 |
|
||||
| | begin_date | 开始时间:0-今天,X-未来X天,-X-过去的X天 |
|
||||
| | end_date | 开始时间:0-今天,X-未来X天,-X-过去的X天 |
|
||||
"""
|
||||
b_date = tools.get_format_date(r_type=1, add_days=int(begin_date))
|
||||
e_date = tools.get_format_date(r_type=1, add_days=int(end_date))
|
||||
jql = "issuetype = 子任务 AND 计划开始时间 <= {} AND 计划结束时间 >= {} AND assignee in ({}) ORDER BY cf[12700] ASC"\
|
||||
.format(b_date, e_date, user_name)
|
||||
issues = self.jira.search_issues(jql, fields='')
|
||||
# print(jql)
|
||||
return issues
|
||||
# for item in issues:
|
||||
# print("{0}:{1}, 当前状态:{2}".format(item.key, item.fields.summary, item.fields.status))
|
||||
|
||||
def query_jira_by_id(self, jira_id):
|
||||
"""
|
||||
| 功能 | 跟进jira的id查询具体详情 |
|
||||
| 入参 | jira_id | jira的id |
|
||||
"""
|
||||
jql = "id={}".format(jira_id)
|
||||
issues = self.jira.search_issues(jql, fields='')
|
||||
if len(issues) == 0:
|
||||
raise Exception("根据jira_id未查询到对应的jira信息,请检查....")
|
||||
rd = issues[0].fields.assignee.displayName
|
||||
qa = issues[0].fields.reporter.displayName
|
||||
title = issues[0].fields.summary
|
||||
status = issues[0].fields.status
|
||||
j_time = issues[0].fields.created
|
||||
j_time = j_time[0:10] + ' ' + j_time[11:19]
|
||||
return {"jira_rd": rd,
|
||||
"jira_qa": qa,
|
||||
"jira_title": title,
|
||||
"jira_time": j_time,
|
||||
"jira_status": str(status)}
|
||||
|
||||
def query_overdue_issues(self, user_name):
|
||||
"""
|
||||
| 功能 | 查询逾期的子任务和故事 |
|
||||
| 入参 | 无 |
|
||||
"""
|
||||
today = tools.get_format_date()
|
||||
check_time = tools.get_format_date(r_type=4)
|
||||
if check_time < "{} 17:00:00".format(today):
|
||||
jql = "issuetype in (故事,子任务) AND (计划结束时间<now() OR 计划上线时间<now()) AND status!=关闭 AND " \
|
||||
"(assignee={0} OR QA={0})".format(user_name)
|
||||
else:
|
||||
jql = "issuetype in (故事,子任务) AND (计划结束时间<=now() OR 计划上线时间<=now()) AND status!=关闭 AND " \
|
||||
"(assignee={0} OR QA={0})".format(user_name)
|
||||
issues = self.jira.search_issues(jql, fields='')
|
||||
return issues
|
||||
|
||||
def check_overdue_issues(self):
|
||||
"""检查预期未关闭的故事和子任务"""
|
||||
today = tools.get_format_date()
|
||||
fs = FS_INFO[0]
|
||||
user_list = fs['users'].split(',')
|
||||
remind_info = []
|
||||
for user in user_list:
|
||||
issues = self.query_overdue_issues(user_name=user)
|
||||
if issues:
|
||||
for issue in issues:
|
||||
issue_info = [user, issue.key]
|
||||
remind_info.append(issue_info)
|
||||
if remind_info:
|
||||
msg = "【JIRA任务延期提醒{}】:\n".format(today)
|
||||
for info in remind_info:
|
||||
user_name = get_user_name_by_email_prefix(email_prefix=info[0])
|
||||
open_id = get_feishu_config_value(option_key=user_name)
|
||||
at_msg = " |--<at user_id='{}'>{}</at>".format(open_id, user_name)
|
||||
msg = msg + at_msg + ": https://jira.bg.huohua.cn/browse/{}\n".format(info[1])
|
||||
msg = msg + " |--请及时关闭以上逾期任务..."
|
||||
print(msg)
|
||||
fs = FeiShuMessage(team=fs['team'])
|
||||
fs.send_text(msg=msg)
|
||||
else:
|
||||
print("++++++++++++++++++++++")
|
||||
print("| 所有任务或故事均已关闭 |")
|
||||
print("++++++++++++++++++++++")
|
||||
|
||||
def check_pdp_standard(self):
|
||||
"""查找当天有无子任务,没有则发送飞书消息提醒"""
|
||||
# 非工作日构建
|
||||
today = tools.get_format_date()
|
||||
if not tools.check_the_date_is_a_working_day(today):
|
||||
print("### 非工作日,不检查....")
|
||||
return False
|
||||
|
||||
for fs in FS_INFO:
|
||||
user_list = fs['users'].split(',')
|
||||
need_remind_user = []
|
||||
for user in user_list:
|
||||
issues = self.query_jira_subtask(user_name=user)
|
||||
if not issues:
|
||||
need_remind_user.append(user)
|
||||
if need_remind_user:
|
||||
msg = "【JIRA子任务提醒{}】:\n |--".format(today)
|
||||
for user in need_remind_user:
|
||||
user_name = get_user_name_by_email_prefix(email_prefix=user)
|
||||
open_id = get_feishu_config_value(option_key=user_name)
|
||||
at_msg = "<at user_id='{}'>{}</at>".format(open_id, user_name)
|
||||
msg = msg + at_msg
|
||||
msg = msg + "\n |--请及时添加与今日工作对应的子任务哦..."
|
||||
print(msg)
|
||||
fs = FeiShuMessage(team=fs['team'])
|
||||
fs.send_text(msg=msg)
|
||||
else:
|
||||
print("++++++++++++++++++++++++++++++++")
|
||||
print("| {} 满足pdp规范,无须提示 |".format(fs['team']))
|
||||
print("++++++++++++++++++++++++++++++++")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# 关闭自动修改jira的代码,不要再打开了...
|
||||
# lp = Jira_About()
|
||||
# print(lp.change_jira_status(['liupeng', 'zhourenhua', 'xuwenjun', 'lichao04', 'wanggang02', 'baoli']))
|
||||
|
||||
# 以下内容若有修改,请勿上传,否则会影响jira监控的每日构建
|
||||
# 1.获取命令行参数
|
||||
cmd_params = sys.argv
|
||||
try:
|
||||
index = cmd_params.index('-t')
|
||||
except ValueError:
|
||||
raise Exception("类型参数必填:pdp-检查PDP规范,overdue-检查预期未关闭的故事和子任务....")
|
||||
else:
|
||||
check_type = cmd_params[index + 1]
|
||||
if check_type.lower() not in ("pdp", "overdue"):
|
||||
raise Exception("目前仅支持pdp和overdue,但你输入的是:{}".format(check_type))
|
||||
|
||||
jira = JiraApi()
|
||||
if check_type.lower() == "pdp":
|
||||
jira.check_pdp_standard()
|
||||
elif check_type.lower() == "overdue":
|
||||
jira.check_overdue_issues()
|
||||
@@ -1,45 +0,0 @@
|
||||
import requests
|
||||
|
||||
|
||||
def fetch_kibana_logs(query, time_range, index_pattern):
|
||||
kibana_url = "https://logstashlog-kibana.qc.huohua.cn/login" # 替换为实际的Kibana URL
|
||||
search_endpoint = f"{kibana_url}/app/kibana" # Kibana搜索API的URL
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
user = "elastic"
|
||||
pwd = "s3dr40O,&j"
|
||||
payload = {
|
||||
"query": query,
|
||||
"timeRange": time_range,
|
||||
"index": index_pattern
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(kibana_url, headers=headers,auth=(user, pwd), json=payload)
|
||||
response.raise_for_status()
|
||||
logs = response.json()
|
||||
# 处理日志数据
|
||||
# ...
|
||||
|
||||
return logs
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching Kibana logs: {str(e)}")
|
||||
return None
|
||||
|
||||
|
||||
query = "error" # 搜索关键字
|
||||
time_range = "now-1d/d" # 过去一天内的日志
|
||||
index_pattern = "my-logs-*" # 匹配以 "my-logs-" 开头的索引
|
||||
|
||||
logs = fetch_kibana_logs(query, time_range, index_pattern)
|
||||
|
||||
if logs:
|
||||
# 处理日志数据
|
||||
for log in logs:
|
||||
# 对每条日志进行操作
|
||||
print(log)
|
||||
else:
|
||||
# 处理错误情况
|
||||
print("Failed to fetch Kibana logs.")
|
||||
@@ -1,204 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Author: qiaoxinjiu
|
||||
Email: qiaoxinjiu@sparkedu.com
|
||||
Create Date: 2022/05/08 5:58 下午
|
||||
"""
|
||||
import os
|
||||
from urllib import parse
|
||||
|
||||
from base_framework.public_tools import read_config
|
||||
import requests
|
||||
import sys
|
||||
import json
|
||||
|
||||
|
||||
class auth_login():
|
||||
def __init__(self):
|
||||
self.config_login_path = os.path.dirname(os.path.abspath(__file__))
|
||||
self.config_login_filePath = os.path.join(self.config_login_path, "../Config/team_config.ini")
|
||||
self.config_login_content = read_config.ReadConfig(filename=self.config_login_filePath)
|
||||
|
||||
def get_json_result(self, url, request_data=None, headers=None, send_way="GET"):
|
||||
"""
|
||||
# url: 测试的url
|
||||
# request_data: url请求时发送的数据
|
||||
# headers: url请求时发送的消息头
|
||||
# 功能:获取json格式的数据
|
||||
"""
|
||||
if send_way == "GET":
|
||||
response = requests.request(send_way, url, headers=headers, params=json.dumps(request_data))
|
||||
else:
|
||||
response = requests.request(send_way, url, headers=headers, data=json.dumps(request_data))
|
||||
try:
|
||||
response_data = json.loads(response.text)
|
||||
except:
|
||||
info = sys.exc_info()
|
||||
response_data = info[1], info[2]
|
||||
return response_data
|
||||
|
||||
def get_m_online_token(self):
|
||||
'''
|
||||
获取家长端线上登录的token
|
||||
:param username:
|
||||
:param password:
|
||||
:return:
|
||||
'''
|
||||
headers = {
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"sso-client-id": "gmp"
|
||||
}
|
||||
get_login_info = eval(
|
||||
self.config_login_content.get_value(sections="m-userinfo", options="login_parent_info")) # 获取配置文件中的默认请求参数值
|
||||
get_url_info = eval(self.config_login_content.get_value(sections="m-userinfo", options="parent_url"))
|
||||
m_token = requests.post(url=get_url_info.get("login_url"), json=get_login_info, verify=False, headers=headers)
|
||||
if m_token.status_code == 200:
|
||||
token = m_token.json()
|
||||
token = token['data']['token']
|
||||
return token
|
||||
else:
|
||||
raise KeyError('获取 parent token失败!')
|
||||
|
||||
def get_student_online_token(self):
|
||||
'''
|
||||
获取学生端线上登录的token
|
||||
:param username:
|
||||
:param password:
|
||||
:return:
|
||||
'''
|
||||
headers = {
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"sso-client-id": "gmp"
|
||||
}
|
||||
get_login_info = eval(
|
||||
self.config_login_content.get_value(sections="m-userinfo", options="login_student_info")) # 获取配置文件中的默认请求参数值
|
||||
get_url_info = eval(self.config_login_content.get_value(sections="m-userinfo", options="student_url"))
|
||||
m_token = requests.post(url=get_url_info.get("login_url"), json=get_login_info, verify=False, headers=headers)
|
||||
if m_token.status_code == 200:
|
||||
token = m_token.json()
|
||||
token = token['data']['token']
|
||||
return token
|
||||
else:
|
||||
raise KeyError('获取 parent token失败!')
|
||||
|
||||
def get_m_headers(self, m_token):
|
||||
'''
|
||||
获取请求的header
|
||||
:return:
|
||||
'''
|
||||
headers = {
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"sso-client-id": "gmp",
|
||||
"user-token": m_token,
|
||||
}
|
||||
return headers
|
||||
|
||||
def get_parent_config_info(self, url_name):
|
||||
'''
|
||||
获取家长端配置文件中的url信息
|
||||
:return:
|
||||
'''
|
||||
get_parent_url_info = eval(self.config_login_content.get_value(sections="m-userinfo", options="parent_url"))
|
||||
get_realm_name = eval(self.config_login_content.get_value(sections="m-userinfo", options="realm_name"))
|
||||
get_url = get_realm_name.get("parent_api") + get_parent_url_info.get(url_name)
|
||||
return get_url
|
||||
|
||||
def get_visaprk_parent_config_info(self, url_name):
|
||||
'''
|
||||
获取海外家长端配置文件中的url信息
|
||||
:return:
|
||||
'''
|
||||
get_parent_url_info = eval(self.config_login_content.get_value(sections="m-userinfo", options="parent_course_url"))
|
||||
get_realm_name = eval(self.config_login_content.get_value(sections="m-userinfo", options="realm_name"))
|
||||
get_url = get_realm_name.get("parent_vispark_api") + get_parent_url_info.get(url_name)
|
||||
return get_url
|
||||
|
||||
def get_student_config_info(self, url_name):
|
||||
'''
|
||||
获取学生端配置文件中的url信息
|
||||
:return:
|
||||
'''
|
||||
get_student_url_info = eval(self.config_login_content.get_value(sections="m-userinfo", options="student_url"))
|
||||
get_realm_name = eval(self.config_login_content.get_value(sections="m-userinfo", options="realm_name"))
|
||||
get_url = get_realm_name.get("student_api") + get_student_url_info.get(url_name)
|
||||
return get_url
|
||||
|
||||
|
||||
class m_parent():
|
||||
def __init__(self):
|
||||
self.get_url = auth_login()
|
||||
|
||||
def get_parentPayEditionPage(self):
|
||||
'''
|
||||
首页轮播页面展示
|
||||
:return:
|
||||
'''
|
||||
|
||||
m_token = self.get_url.get_m_online_token()
|
||||
headers = self.get_url.get_m_headers(m_token=m_token)
|
||||
url = self.get_url.get_parent_config_info(url_name="parentPayEditionPage_url")
|
||||
get_response_data = self.get_url.get_json_result(url=url, headers=headers, request_data={"terminalType": 5})
|
||||
return get_response_data
|
||||
|
||||
def get_recommendedCourse(self):
|
||||
'''
|
||||
家长端获取课程信息
|
||||
:return:
|
||||
'''
|
||||
m_token = self.get_url.get_m_online_token()
|
||||
headers = self.get_url.get_m_headers(m_token=m_token)
|
||||
url = self.get_url.get_parent_config_info(url_name="recommendedCourse_url")
|
||||
get_response_data = self.get_url.get_json_result(url=url, headers=headers)
|
||||
return get_response_data
|
||||
|
||||
def get_trial_level(self,courseSubtype):
|
||||
'''
|
||||
获取试听课级别
|
||||
ap为21,cp为20
|
||||
:return:
|
||||
'''
|
||||
m_token = self.get_url.get_m_online_token()
|
||||
headers = self.get_url.get_m_headers(m_token=m_token)
|
||||
url = self.get_url.get_visaprk_parent_config_info(url_name="get_trial_url")
|
||||
request_url = url +"?courseSubtype={0}&subjectType=1".format(courseSubtype)
|
||||
get_response_data = self.get_url.get_json_result(url=request_url, headers=headers)
|
||||
# 针对ap或者cp获取级别,查看是否存在重复的level
|
||||
list_level = []
|
||||
for trial_data in get_response_data.get("data"):
|
||||
list_level.append(trial_data.get("level"))
|
||||
set_level = set(list_level)
|
||||
dict_response = {}
|
||||
for level in set_level:
|
||||
if list_level.count(level) > 1:
|
||||
dict_response[level] = list_level.count(level)
|
||||
if dict_response:
|
||||
return {"code":500,"data":dict_response}
|
||||
else:
|
||||
return {"code":200,"data":dict_response}
|
||||
|
||||
class student_verity():
|
||||
def __init__(self):
|
||||
self.get_url = auth_login()
|
||||
|
||||
def get_schedule_count(self):
|
||||
'''
|
||||
|
||||
:return:
|
||||
'''
|
||||
m_token = self.get_url.get_m_online_token()
|
||||
headers = self.get_url.get_m_headers(m_token=m_token)
|
||||
url = self.get_url.get_student_config_info(url_name="scheduleCount_url")
|
||||
print(url)
|
||||
get_response_data = self.get_url.get_json_result(url=url, headers=headers, request_data={"subjectType": 4})
|
||||
|
||||
return get_response_data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test = auth_login()
|
||||
test1 = m_parent()
|
||||
test2 = student_verity()
|
||||
# print(test.get_student_online_token())
|
||||
# print(test1.get_recommendedCourse())
|
||||
print(test1.get_trial_level(courseSubtype=22))
|
||||
# print(test2.get_schedule_count())
|
||||
@@ -1,19 +0,0 @@
|
||||
import pika
|
||||
|
||||
# 设置RabbitMQ服务器的连接参数,使用自定义端口9876
|
||||
connection_params = pika.ConnectionParameters('rocketmq.qa.huohua.cn', 9876)
|
||||
connection = pika.BlockingConnection(connection_params)
|
||||
channel = connection.channel()
|
||||
|
||||
# 声明一个队列,如果队列不存在则会创建
|
||||
queue_name = 'my_queue'
|
||||
channel.queue_declare(queue=queue_name)
|
||||
|
||||
# 发布消息到指定的队列
|
||||
message = 'Hello, World!'
|
||||
channel.basic_publish(exchange='',
|
||||
routing_key=queue_name,
|
||||
body=message)
|
||||
print(f" [x] Sent '{message}'")
|
||||
# 关闭连接
|
||||
connection.close()
|
||||
@@ -1,56 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Author: qiaoxinjiu
|
||||
Email: qiaoxinjiu@sparkedu.com
|
||||
Create Date: 2022/05/08 5:58 下午
|
||||
"""
|
||||
import os
|
||||
from PIL import Image
|
||||
|
||||
def image_gray(img):
|
||||
# 打开图片
|
||||
img = Image.open(img)
|
||||
|
||||
# 计算平均灰度值
|
||||
gray_sum = 0
|
||||
count = 0
|
||||
for x in range(img.width):
|
||||
for y in range(img.height):
|
||||
if img.mode == "RGB":
|
||||
r, g, b = img.getpixel((x, y))
|
||||
gray_sum += (r + g + b) / 3
|
||||
elif img.mode == "L":
|
||||
gray_value = img.getpixel((x, y))
|
||||
gray_sum += gray_value
|
||||
count += 1
|
||||
|
||||
avg_gray = gray_sum / count
|
||||
return avg_gray
|
||||
|
||||
|
||||
def find_image(folder_path):
|
||||
# 定义一个列表存储图片路径
|
||||
images = []
|
||||
# 遍历文件夹下的所有文件
|
||||
for root, dirs, files in os.walk(folder_path):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
# 处理每个文件,将其添加到列表中
|
||||
images.append(file_path)
|
||||
return images
|
||||
|
||||
|
||||
def assert_run(folder_path):
|
||||
images = find_image(folder_path)
|
||||
for img in images:
|
||||
gray = image_gray(img)
|
||||
# 灰度值小于50,将认为是黑图
|
||||
if gray < 50:
|
||||
print(img, ":", gray)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# image_gray()
|
||||
# find_image()
|
||||
folder_path = r'D:\picture'
|
||||
assert_run(folder_path)
|
||||
@@ -1,211 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Author: qiaoxinjiu
|
||||
Email: xinjiu.qiao@allschool.com
|
||||
Create Date: 2022/04/26 5:58 下午
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
input_team_name = sys.argv
|
||||
|
||||
BASIC_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
TEAM_PATH = os.path.abspath(os.path.join(BASIC_PATH, '../../../{}'.format("base_framework")))
|
||||
sys.path.append(TEAM_PATH)
|
||||
PROJECT_PATH = os.path.abspath(os.path.join(BASIC_PATH, '../../..'))
|
||||
sys.path.append(PROJECT_PATH)
|
||||
from base_framework.public_tools.sqlhelper import MySqLHelper
|
||||
import json
|
||||
import requests
|
||||
|
||||
obj_mysql_helper = MySqLHelper()
|
||||
|
||||
|
||||
class Handle_tools:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def query_interface_sql(self):
|
||||
'''
|
||||
查询qa的余量接口信息
|
||||
:return:
|
||||
'''
|
||||
query_sql = ''' SELECT in_url,controller_name
|
||||
FROM
|
||||
sparkatp.interface_info
|
||||
WHERE
|
||||
id IN (
|
||||
SELECT
|
||||
a.id
|
||||
FROM
|
||||
(SELECT * from sparkatp.interface_info) a
|
||||
WHERE
|
||||
( a.swagger_id in (SELECT id FROM sparkatp.swagger_info WHERE team="UBRD") )
|
||||
AND a.created_time > "2022-01-01 00:00:50"
|
||||
AND is_used = 1 and at_numbers = 0 and offline=0 and jira_id is null) ORDER BY created_time'''
|
||||
|
||||
query_sql_r = """SELECT
|
||||
si.id AS interface_id,
|
||||
rpgm.jira_id,
|
||||
si.in_url
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
ii.id,
|
||||
ii.in_url,
|
||||
ii.jira_id
|
||||
FROM
|
||||
sparkatp.interface_info ii
|
||||
WHERE
|
||||
ii.swagger_id IN ( SELECT id FROM sparkatp.swagger_info WHERE team = "UBRD" )
|
||||
AND ii.created_time > "2022-01-01 00:00:50"
|
||||
AND ii.is_used = 1
|
||||
AND ii.at_numbers = 0
|
||||
AND ii.offline = 0
|
||||
AND ii.jira_id IS NULL
|
||||
) si
|
||||
INNER JOIN (
|
||||
SELECT
|
||||
rp.interface_id,
|
||||
rp.jira_id,
|
||||
MAX( modified_time )
|
||||
FROM
|
||||
request_parameters rp
|
||||
WHERE
|
||||
rp.jira_id IS NOT NULL
|
||||
AND rp.jira_id <> 'None'
|
||||
AND rp.jira_id <> ''
|
||||
GROUP BY
|
||||
rp.interface_id
|
||||
) rpgm ON rpgm.interface_id = si.id;"""
|
||||
|
||||
# query_sql = " SELECT * FROM sparkatp.interface_info WHERE id IN (SELECT a.id FROM(SELECT * from sparkatp.interface_info) a WHERE( a.swagger_id in (SELECT id FROM sparkatp.swagger_info WHERE team='UBRD') ) AND a.created_time > '2022-01-01 00:00:50' AND is_used = 1 and at_numbers = 0 and offline=0 and jira_id is null) ORDER BY created_time"
|
||||
query_sql_r_result = obj_mysql_helper.select_all(query_sql_r)
|
||||
query_sql_dict = {}
|
||||
query_sql_dict_temp = {}
|
||||
# <class 'dict'>: {'interface_id': 924646, 'jira_id': 'HHC-48875', 'in_url': 'http://peppa-parent-api.qa.huohua.cn/classes/audition/enter'}
|
||||
for qsrr in query_sql_r_result:
|
||||
in_url = "{}_{}".format(str(qsrr.get('interface_id')).strip(' '), qsrr.get('in_url').strip(' '))
|
||||
if qsrr.get('jira_id') in query_sql_dict.keys():
|
||||
if in_url in query_sql_dict.get(qsrr.get('jira_id')):
|
||||
pass
|
||||
else:
|
||||
query_sql_dict[qsrr.get('jira_id')].append(in_url)
|
||||
else:
|
||||
query_sql_dict[qsrr.get('jira_id')] = [in_url]
|
||||
|
||||
query_sql_s = """SELECT
|
||||
si.id AS interface_id,
|
||||
rpgm.jira_id,
|
||||
si.in_url
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
ii.id,
|
||||
ii.in_url,
|
||||
ii.jira_id
|
||||
FROM
|
||||
sparkatp.interface_info ii
|
||||
WHERE
|
||||
ii.swagger_id IN ( SELECT id FROM sparkatp.swagger_info WHERE team = "UBRD" )
|
||||
AND ii.created_time > "2022-01-01 00:00:50"
|
||||
AND ii.is_used = 1
|
||||
AND ii.at_numbers = 0
|
||||
AND ii.offline = 0
|
||||
AND ii.jira_id IS NULL
|
||||
) si
|
||||
INNER JOIN (
|
||||
SELECT
|
||||
rp.interface_id,
|
||||
rp.jira_id,
|
||||
MAX( modified_time )
|
||||
FROM
|
||||
response_parameters rp
|
||||
WHERE
|
||||
rp.jira_id IS NOT NULL
|
||||
AND rp.jira_id <> 'None'
|
||||
AND rp.jira_id <> ''
|
||||
GROUP BY
|
||||
rp.interface_id
|
||||
) rpgm ON rpgm.interface_id = si.id;"""
|
||||
|
||||
query_sql_s_result = obj_mysql_helper.select_all(query_sql_s)
|
||||
for qsrs in query_sql_s_result:
|
||||
in_url = "{}_{}".format(str(qsrs.get('interface_id')).strip(' '), qsrs.get('in_url').strip(' '))
|
||||
if qsrs.get('jira_id') in query_sql_dict.keys():
|
||||
if in_url in query_sql_dict[qsrs.get('jira_id')]:
|
||||
pass
|
||||
else:
|
||||
query_sql_dict[qsrs.get('jira_id')].append(in_url)
|
||||
else:
|
||||
query_sql_dict[qsrs.get('jira_id')] = [in_url]
|
||||
return query_sql_dict
|
||||
|
||||
def send_log_info(self):
|
||||
'''
|
||||
每天进行日志提醒
|
||||
:return:
|
||||
'''
|
||||
feishu_name_id = {"罗志鹏": "7020366259502153730", "谯新久": "7020366258071715842",
|
||||
"陈洁": "7020370251997069314", "蒲思宇": "7076270364313108481", "张楠": "7076270369128349697",
|
||||
"刘涛婷": "7020366262240854017"}
|
||||
order_list = ["谯新久", "陈洁", "刘涛婷", "罗志鹏", "蒲思宇", "张楠"]
|
||||
# for name in order_list:
|
||||
|
||||
def send_feishu(self, inferfaces):
|
||||
'''
|
||||
发送飞书
|
||||
:return:
|
||||
'''
|
||||
at_user_list = [{"tag": "at", "user_id": "{}".format("7020366259502153730")}]
|
||||
message_data = {"msg_type": "post", "content": {
|
||||
"post": {"zh_cn": {"title": "有存在的接口未实现自动化哦",
|
||||
"content": [[{"tag": "text", "text": "问题数据:"}],
|
||||
[{"tag": "text", "text": "{}".format(inferfaces)}],
|
||||
at_user_list]}}}}
|
||||
web_hook = "https://open.feishu.cn/open-apis/bot/v2/hook/40696c86-264a-4222-a40c-cfd64a05dffd"
|
||||
headers = {"Content-Type": "application/json"}
|
||||
json_data = json.dumps(message_data)
|
||||
print(json_data)
|
||||
rsp = requests.post(url=web_hook, data=json_data, headers=headers)
|
||||
return rsp
|
||||
|
||||
def send_message_by_feishu(self, web_hook, data):
|
||||
headers = {"Content-Type": "application/json"}
|
||||
json_data = json.dumps(data)
|
||||
rsp = requests.post(url=web_hook, data=json_data, headers=headers)
|
||||
return rsp
|
||||
|
||||
def compare_txt(self, su_t, st_t):
|
||||
'''
|
||||
对比两个文档,返回不同的信息
|
||||
:param su_t:
|
||||
:param st_t:
|
||||
:return:
|
||||
'''
|
||||
file_object1 = open(su_t, 'r', encoding='utf-8')
|
||||
file_object2 = open(st_t, 'r', encoding='utf-8')
|
||||
try:
|
||||
while True:
|
||||
line = file_object1.readline()
|
||||
lines = file_object2.readline()
|
||||
if line.strip() != lines.strip():
|
||||
print("pc :", line)
|
||||
print("right:", lines)
|
||||
else:
|
||||
continue
|
||||
finally:
|
||||
file_object1.close()
|
||||
file_object2.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test = Handle_tools()
|
||||
# get_interfaces = test.query_interface_sql()
|
||||
# if get_interfaces:
|
||||
# test.send_feishu(json.dumps(get_interfaces))
|
||||
# else:
|
||||
# print("都已经完成")
|
||||
su_t = r"D:\UiVispark\spark1.txt"
|
||||
st_t = r"D:\UiVispark\spark2.txt"
|
||||
test.compare_txt(st_t=st_t,su_t=su_t)
|
||||
@@ -1 +0,0 @@
|
||||
host_list = [{"ip":'127.0.0.1',"host_names":"ts.sim.huohua.cn"},{"ip":'127.0.0.1',"host_names":"student-api.sim.huohua.cn"}]
|
||||
@@ -1,263 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# @Time : 2023/7/5 10:27
|
||||
# @Author: luozhipeng
|
||||
# @File : host_update.py
|
||||
import os
|
||||
from python_hosts import Hosts, HostsEntry
|
||||
import sys
|
||||
LOCAL_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
BASE_PROJECT_PATH = os.path.abspath(os.path.join(LOCAL_PATH, '../../../{}'.format("UBRD")))
|
||||
BASIC_PATH = os.path.abspath(os.path.join(LOCAL_PATH, '../../../'))
|
||||
sys.path.append(BASE_PROJECT_PATH)
|
||||
sys.path.append(BASIC_PATH)
|
||||
from base_framework.public_tools.utils import Tools
|
||||
from base_framework.public_tools.apollo import Apollo
|
||||
import requests, time
|
||||
import os
|
||||
import sys
|
||||
import socket
|
||||
import subprocess
|
||||
import requests
|
||||
import urllib.parse
|
||||
obj_apollo = Apollo()
|
||||
|
||||
obj_tools = Tools()
|
||||
|
||||
class HostUpdate:
|
||||
def __init__(self):
|
||||
if sys.platform.startswith('win'):
|
||||
self.hosts_location = Hosts(path='C:\Windows\System32\drivers\etc\hosts')
|
||||
elif sys.platform.startswith('darwin'):
|
||||
self.hosts_location = Hosts(path='\etc\hosts')
|
||||
|
||||
def host_update_by_host_dict(self, host_dict_list: list):
|
||||
|
||||
entry_list = []
|
||||
for host in host_dict_list:
|
||||
new_entry = HostsEntry(entry_type='ipv4', address=host['ip'], names=[host['host_name'], ''])
|
||||
entry_list.append(new_entry)
|
||||
self.hosts_location.add(entry_list)
|
||||
self.hosts_location.write()
|
||||
|
||||
def host_remove_intercept(self,address,name):
|
||||
self.hosts_location.remove_all_matching(address,name)
|
||||
self.hosts_location.write()
|
||||
|
||||
def get_ip_by_host_domain(self,domain: str):
|
||||
ip=socket.gethostbyname(domain)
|
||||
return ip
|
||||
|
||||
def wait_dns_flush(self,ip,domain):
|
||||
count=1
|
||||
while True:
|
||||
|
||||
cmd1="ipconfig /flushdns"
|
||||
result1=subprocess.run(cmd1,capture_output=True,text=True)
|
||||
output1=result1.stdout
|
||||
print(output1)
|
||||
cmd2="ping {}".format(domain)
|
||||
result2=subprocess.run(cmd2,capture_output=True,text=True)
|
||||
output2=result2.stdout
|
||||
print(output2)
|
||||
cmd="ipconfig /displaydns"
|
||||
result=subprocess.run(cmd,capture_output=True,text=True)
|
||||
output=result.stdout
|
||||
print(output)
|
||||
if output is None:
|
||||
output=''
|
||||
if ip in output:
|
||||
break
|
||||
if count >= 30:
|
||||
break
|
||||
count=count + 1
|
||||
host_list=[{"ip": ip,"host_name": domain}]
|
||||
self.host_remove_intercept(ip,domain)
|
||||
self.host_update_by_host_dict(host_list)
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
class CoreApollo:
|
||||
def __init__(self,show_username=None,password=None,current_evn=None):
|
||||
if not show_username:
|
||||
self.show_username="liuruiquan"
|
||||
if not password:
|
||||
self.password="lrq5823LRQ"
|
||||
self.apollo_url="http://apollo.qa.huohua.cn/signin"
|
||||
if not current_evn:
|
||||
self.current_evn="SIM"
|
||||
self.apollo_host="http://apollo.qa.huohua.cn"
|
||||
self.session=self.core_apollo_login()
|
||||
|
||||
def core_apollo_login(self):
|
||||
post_data=dict()
|
||||
post_data['login-submit']='登录'
|
||||
post_data['username']=self.show_username
|
||||
post_data['password']=self.password
|
||||
req_session=requests.Session()
|
||||
resp=req_session.post(url=self.apollo_url,data=post_data)
|
||||
return req_session
|
||||
|
||||
def get_key(self,server,cluster,key,project):
|
||||
req_url="%s/apps/%s/envs/%s/clusters/%s/namespaces" % (
|
||||
self.apollo_host,server,self.current_evn,cluster)
|
||||
resp=self.session.get(url=req_url).json()
|
||||
for item in resp:
|
||||
base_info=item.get('baseInfo')
|
||||
items=item.get('items')
|
||||
if not base_info['namespaceName'].lower() == project.lower():
|
||||
continue
|
||||
for key_info in items:
|
||||
item_detail=key_info["item"]
|
||||
if item_detail["key"] == key:
|
||||
return key_info["item"]
|
||||
else:
|
||||
return None
|
||||
|
||||
def set_key(self,key,value,cluster='default',server="",project=None):
|
||||
if server:
|
||||
self.server=server
|
||||
req_url="%s/apps/%s/envs/%s/clusters/%s/namespaces/%s/item" % (
|
||||
self.apollo_host,self.server,self.current_evn,cluster,project)
|
||||
items=self.get_key(server,cluster,key,project)
|
||||
if items is None:
|
||||
items=dict()
|
||||
items["value"]=value
|
||||
items["key"]=key
|
||||
items["tableViewOperType"]='create'
|
||||
items["addItemBtnDisabled"]=True
|
||||
|
||||
else:
|
||||
items["value"]=value
|
||||
items["tableViewOperType"]='update'
|
||||
update_resp=self.session.put(url=req_url,json=items)
|
||||
|
||||
assert update_resp.status_code == 200
|
||||
release_body=dict()
|
||||
release_time_stamp=time.localtime()
|
||||
release_time='%s-release' % time.strftime("%Y%m%d%H%M%S",release_time_stamp)
|
||||
release_body["isEmergencyPublish"]=False
|
||||
release_body["releaseComment"]=""
|
||||
release_body["releaseTitle"]=release_time
|
||||
release_url="%s/apps/%s/envs/%s/clusters/%s/namespaces/%s/releases" % (
|
||||
self.apollo_host,self.server,self.current_evn,cluster,project)
|
||||
resp=self.session.post(url=release_url,json=release_body)
|
||||
assert resp.status_code == 200
|
||||
time.sleep(5)
|
||||
|
||||
def set_user_force_true(self,vlaue="true"):
|
||||
self.set_key(value=vlaue,key="user-token.forceFallback",server="peppa-core-api",cluster="check"
|
||||
,project="application")
|
||||
|
||||
def set_teacher_force_true(self,vlaue="true"):
|
||||
self.set_key(value=vlaue,key="sso-token.forceFallback",server="peppa-core-api",cluster="check"
|
||||
,project="application")
|
||||
|
||||
|
||||
class EduClassroom:
|
||||
def kw_ubrd_get_online_test_classroom(self,post_data_input=None):
|
||||
post_data = dict()
|
||||
host = "sso.huohua.cn"
|
||||
api_url = "https://{}/authentication/form".format(host)
|
||||
show_username = "liuruiquan"
|
||||
username = "liuruiquan"
|
||||
password = "lrq5823LRQ"
|
||||
post_data['showUsername'] = show_username
|
||||
post_data['username'] = username
|
||||
post_data['password'] = password
|
||||
user_agent = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}
|
||||
deviceid = {"SSO_DEVICE_ID":"8dfbecf2-064a-4e3f-ac2b-fc09a2401416"}
|
||||
req_session = requests.session()
|
||||
req_session.cookies.update(deviceid)
|
||||
req_session.headers.update(user_agent)
|
||||
resp = req_session.post(
|
||||
url=api_url,
|
||||
data=post_data,
|
||||
allow_redirects=False)
|
||||
|
||||
# token_header = {"accesstoken": token}
|
||||
# req_session.headers.update(token_header)
|
||||
# print(token_header)
|
||||
client_id = "tic-payment-admin"
|
||||
origin_url="aHR0cHM6Ly9zc28uaHVvaHVhLmNuLw=="
|
||||
# origin_url="aHR0cHM6Ly9zc28uc2ltLmh1b2h1YS5jbi8="
|
||||
|
||||
redirect_uri = "https://{}/uim/authorize_proxy?client_id={}&debug_mode=1&origin_url={}".format(host,client_id,origin_url)
|
||||
print(redirect_uri)
|
||||
token_code_url = "https://{}/oauth/authorize?client_id={}&response_type=code&".format(host,client_id,redirect_uri)
|
||||
authorize_data = {"redirect_uri": redirect_uri}
|
||||
authorize_data_uri =urllib.parse.urlencode(authorize_data)
|
||||
resp = req_session.get(
|
||||
url=token_code_url+authorize_data_uri,
|
||||
data=authorize_data,
|
||||
allow_redirects=False)
|
||||
print(resp.url)
|
||||
print(resp.headers)
|
||||
print(resp)
|
||||
|
||||
# token_url = "https://{}/uim/authorize_proxy?client_id={}&debug_mode=1&origin_url={}&code={}".format(host,client_id,origin_url,code)
|
||||
token_url= resp.headers["Location"]
|
||||
# authorize_code_data = {"client_id":"tic-payment-admin","debug_mode": 1,"origin_url": origin_url,"code":code}
|
||||
|
||||
print(token_url,"token_url")
|
||||
# print(authorize_code_data)
|
||||
resp = req_session.get(
|
||||
url=token_url,
|
||||
# data=authorize_code_data,
|
||||
allow_redirects=False)
|
||||
print(resp)
|
||||
print(resp.url)
|
||||
for key, value in req_session.cookies.items():
|
||||
if key == 'peppa_sso_token':
|
||||
token = value
|
||||
token_header = {"accesstoken": token}
|
||||
req_session.headers.update(token_header)
|
||||
print(token_header)
|
||||
print(value)
|
||||
break
|
||||
|
||||
|
||||
op_time = obj_tools.get_format_date(r_type=4,add_minutes=10)
|
||||
print(op_time)
|
||||
|
||||
create_classroom_json = {"courseId":1898,"unionFlag":0,"lessonId":49264,"planStudentCount":4,"timezoneName":"Asia/Shanghai","openTime":op_time,"overseasTag":0,"secondOpenTime":op_time,"teacherId":36573,"type":100}
|
||||
api_url_created_classroom = "https://teach-api.huohua.cn/peppa-teach-api/classroom"
|
||||
create_classroom_resp = req_session.post(
|
||||
url=api_url_created_classroom,
|
||||
json=create_classroom_json)
|
||||
# print(req_session.headers)
|
||||
# print(req_session.cookies)
|
||||
# print(resp.content)
|
||||
# print(resp.url)
|
||||
print(create_classroom_resp.json())
|
||||
classroom_id = create_classroom_resp.json()['data']["classroomId"]
|
||||
print(create_classroom_resp.json())
|
||||
#
|
||||
# return req_session
|
||||
add_student_json = {"classroomId":classroom_id,"studentId":274886,"userId":275774,"joinType":0,"ignoreClassHour":1}
|
||||
api_url_add_student = "https://teach-api.huohua.cn/peppa-teach-api/classroom_student/add"
|
||||
add_student_resp = req_session.post(
|
||||
url=api_url_add_student,
|
||||
json=add_student_json)
|
||||
print(add_student_resp.json())
|
||||
|
||||
# return req_session
|
||||
add_student_json1 = {"classroomId":classroom_id,"studentId":5635578,"userId":5646962,"joinType":0,"ignoreClassHour":1}
|
||||
add_student_resp1 = req_session.post(
|
||||
url=api_url_add_student,
|
||||
json=add_student_json1)
|
||||
print(add_student_resp1.json())
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
||||
host_list = [{"ip": "127.0.0.1", "host_name": "ts.sim.huohua.cn"},
|
||||
{"ip": "127.0.0.1", "host_name": "its.sim.huohua.cn"},
|
||||
{"ip": "127.0.0.1", "host_name": "student-api.sim.huohua.cn"},
|
||||
{"ip": "127.0.0.1", "host_name": "sentry.sim.huohua.cn"},
|
||||
{"ip": "127.0.0.1", "host_name": "gray.sim.huohua.cn"},
|
||||
{"ip": "127.0.0.1", "host_name": "classroom-api.sim.huohua.cn"},
|
||||
{"ip": "127.0.0.1", "host_name": "logserver.sim.huohua.cn"},
|
||||
{"ip": "127.0.0.1", "host_name": "zipkin.sim.huohua.cn"},
|
||||
{"ip": "127.0.0.1", "host_name": "gs.sim.huohua.cn"}]
|
||||
A = EduClassroom()
|
||||
A.kw_ubrd_get_online_test_classroom()
|
||||
@@ -1,142 +0,0 @@
|
||||
import os
|
||||
import re
|
||||
import threading
|
||||
|
||||
|
||||
class StatisticalFunction:
|
||||
def __init__(self):
|
||||
self.java_dir =[]
|
||||
self.zh_file = []
|
||||
self.python_dir = []
|
||||
self.robot_dir = []
|
||||
|
||||
|
||||
def check_lang_every_word(self,file_path):
|
||||
""" 获取文件中注释外含中文的文档 """
|
||||
# file_path ='C:\\Users\\HuoH # a=time.time()ua\\Downloads\\peppa-parent-api\\src\\main\\java\\com\\peppa\\parent\\api\\common\\ApiErrorEnum.java'
|
||||
with open(file_path,'r',encoding='utf-8') as text:
|
||||
all_content = text.read()
|
||||
all_content = all_content.encode('utf-8')
|
||||
all_content = all_content.decode('utf-8','ignore')
|
||||
yy= re.sub("\/\*\*.*?\*\*\/", "",all_content) # 去除多行注释
|
||||
yy = re.sub("\/\*[\w\W]*?\*\/|\/\/.*", "", yy) # 去除文本注释
|
||||
yy = re.sub("(?<!:)\/\/.*", "", yy) # 去除行注释
|
||||
yy=yy.replace(" ","")
|
||||
yy=yy.replace('\n','')
|
||||
# for eachline in text.read():
|
||||
# line = eachline.strip()
|
||||
# l2 =line.encode('utf-8')
|
||||
# l1=l2.decode('utf-8','ignore')
|
||||
# lineTuple = langid.classify(l1)
|
||||
# for word in yy:
|
||||
# lineTuple = langid.classify(word)
|
||||
# if lineTuple[0] == "zh":
|
||||
# if file_path not in zh_file:
|
||||
# zh_file.append(file_path)
|
||||
zhPattern = re.compile(u'[\u4e00-\u9fa5]+')
|
||||
match = zhPattern.search(yy)
|
||||
if match:
|
||||
print(match,'\n',file_path)
|
||||
self.zh_file.append(file_path)
|
||||
# b =time.time()
|
||||
# print(b-a)
|
||||
|
||||
def get_java_file(self,path):
|
||||
"""获取所有java文件"""
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files :
|
||||
if file.endswith('.java'):
|
||||
# print(os.path.join(root, file))
|
||||
self.java_dir.append(os.path.join(root, file))
|
||||
|
||||
if dirs:
|
||||
for dir_single in dirs:
|
||||
if re.match('__',dir_single) :
|
||||
print(dir_single)
|
||||
# print(os.path.join(root, dirs[0]))
|
||||
self.get_java_file(os.path.join(root,dir_single))
|
||||
return self.java_dir
|
||||
|
||||
|
||||
def muti_threading(self):
|
||||
# 多线程调用
|
||||
threads =[]
|
||||
for file_zh in self.java_dir:
|
||||
threads.append(
|
||||
threading.Thread(target=self.check_lang_every_word,args=(file_zh,))
|
||||
)
|
||||
for thread in threads:
|
||||
thread.start()
|
||||
# print(thread.name)
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
# print(thread.name,"结束")
|
||||
|
||||
print("end")
|
||||
|
||||
def get_python_file(self,path):
|
||||
"""获取所有python文件"""
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files :
|
||||
if file.endswith('.py'):
|
||||
# print(os.path.join(root, file))
|
||||
self.python_dir.append(os.path.join(root, file))
|
||||
|
||||
if dirs:
|
||||
for dir_single in dirs:
|
||||
if re.match('__',dir_single) :
|
||||
print(dir_single)
|
||||
# print(os.path.join(root, dirs[0]))
|
||||
self.get_python_file(os.path.join(root,dir_single))
|
||||
return self.python_dir
|
||||
|
||||
def get_robot_file(self,path):
|
||||
"""获取所有robot文件"""
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files :
|
||||
if file.endswith('.robot'):
|
||||
# print(os.path.join(root, file))
|
||||
self.robot_dir.append(os.path.join(root, file))
|
||||
|
||||
if dirs:
|
||||
for dir_single in dirs:
|
||||
if re.match('__',dir_single) :
|
||||
print(dir_single)
|
||||
# print(os.path.join(root, dirs[0]))
|
||||
self.get_robot_file(os.path.join(root,dir_single))
|
||||
return self.robot_dir
|
||||
|
||||
@staticmethod
|
||||
def get_class_function(class_ubrd):
|
||||
ubrd_function = []
|
||||
all_function = dir(class_ubrd)
|
||||
for function in all_function:
|
||||
if 'kw_in_ubrd' in function :
|
||||
ubrd_function.append(function)
|
||||
|
||||
return ubrd_function
|
||||
|
||||
@staticmethod
|
||||
def statistical(ubrd_function,dir_robot_python):
|
||||
dict_function = {}
|
||||
for function in ubrd_function:
|
||||
count_num_all = 0
|
||||
for dir_a in dir_robot_python:
|
||||
|
||||
with open(dir_a,'r',encoding='utf-8') as text:
|
||||
all_content = text.read()
|
||||
count_num_file = all_content.count(function)
|
||||
count_num_all = count_num_all +count_num_file
|
||||
count_num_all = count_num_all-1
|
||||
if count_num_all in dict_function:
|
||||
dict_function[count_num_all] += 1
|
||||
else:
|
||||
dict_function[count_num_all] = 1
|
||||
return dict_function
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import datetime, time
|
||||
import random
|
||||
|
||||
class UbrdNowTime:
|
||||
|
||||
@staticmethod
|
||||
def kw_ubrd_get_now_time():
|
||||
now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
return now_time
|
||||
|
||||
def get_few_days_before_or_after_current_time(self, n=0):
|
||||
"""
|
||||
| 功能说明: | 获取当前时间的前几天或后几天的日期 |
|
||||
| 输入参数: | n | 前n天或后n天,通过正负数来区分 |
|
||||
| 输入参数: | hms | 1表示返回时分秒为当前时间,0表示00:00:00 |
|
||||
| 返回参数: | newtime_str | 当前时间的前几天或后几天的具体日期|
|
||||
| 作者信息: | 刘睿权 | 修改时间 20211025|
|
||||
举例说明:
|
||||
| get_few_days_before_or_after_current_time | -7 |表示当前时间往后推7天的日期|
|
||||
"""
|
||||
nowtime = datetime.datetime.now()
|
||||
Newnowtime = nowtime - datetime.timedelta(days=n)
|
||||
return datetime.datetime.strftime(Newnowtime, '%Y-%m-%d %H:%M:%S')
|
||||
@staticmethod
|
||||
def kw_change_format_time(r_date):
|
||||
get_time = r_date / 1000
|
||||
time_array = time.localtime(get_time)
|
||||
other_style_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
|
||||
return other_style_time
|
||||
|
||||
@staticmethod
|
||||
def kw_ubrd_get_random_time():
|
||||
'''
|
||||
获取一个随机的时间
|
||||
:param r_date:
|
||||
:return:
|
||||
'''
|
||||
get_random_week = random.randint(0, 11)
|
||||
get_minite_time = get_random_week * 5
|
||||
if get_minite_time == 0:
|
||||
get_time = "00"
|
||||
elif get_minite_time == 5:
|
||||
get_time = "05"
|
||||
else:
|
||||
get_time = str(get_minite_time)
|
||||
return get_time
|
||||
|
||||
@staticmethod
|
||||
def kw_ubrd_get_week_day(type):
|
||||
now = datetime.datetime.now()
|
||||
# 计算当前周的周一和下周一的日期
|
||||
current_weekday = now.weekday() # 获取当前日期的星期几,星期一为0,星期日为6
|
||||
current_monday = now - datetime.timedelta(days=current_weekday) # 当前周的周一
|
||||
next_monday = current_monday + datetime.timedelta(days=7) # 下周一
|
||||
# 设置时间为0点
|
||||
if type == "1":
|
||||
current_day = current_monday.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
else:
|
||||
current_day = next_monday.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
return current_day
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(UbrdNowTime.kw_ubrd_get_week_day(type=2))
|
||||
@@ -1,272 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
"""
|
||||
Author: 罗志鹏
|
||||
Email: luozhipeng@huohua.cn
|
||||
Create Date: 2022/03/03 11:25 下午
|
||||
"""
|
||||
from base_framework.public_tools import log
|
||||
from base_framework.public_tools.sqlhelper import MySqLHelper
|
||||
from library.UBRD_interface import UBRDInterface
|
||||
from base_framework.public_tools.edu_user_helper import EDUUserHelper
|
||||
from base_framework.public_tools.redis_api import RedisApi
|
||||
from base_framework.public_tools.read_config import ReadConfig
|
||||
from base_framework.base_config.current_pth import env_choose_path
|
||||
from redis import Redis
|
||||
from base_framework.public_tools.runner import Runner
|
||||
from base_framework.public_tools.utils import Tools
|
||||
from base_framework.public_business.common.UBRD.UBRD_public_business import BaseLogic
|
||||
from base_framework.public_business.common.UBRD.kw.user_keyword import UserKW
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import pad
|
||||
import base64
|
||||
obj_runner = Runner()
|
||||
obj_log = log.get_logger()
|
||||
obj_my_sql_helper = MySqLHelper()
|
||||
obj_edu_user_helper = EDUUserHelper()
|
||||
obj_redis_api = RedisApi()
|
||||
obj_tools = Tools()
|
||||
obj_base_logic = BaseLogic()
|
||||
user_kw_obj = UserKW()
|
||||
|
||||
|
||||
class UserCommon(UBRDInterface):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.evn_cfg = ReadConfig(env_choose_path)
|
||||
self.current_business = self.evn_cfg.get_value(sections="run_evn_name", options="current_business")
|
||||
|
||||
@staticmethod
|
||||
def update_user_pwd_by_phone(phone):
|
||||
"""
|
||||
功能:初始化用户密码为A123456
|
||||
| 输入参数: | phone string | 手机号 |
|
||||
| 作者: | lzp | 2022.03.07 |
|
||||
"""
|
||||
sql_user_by_phone = "SELECT x.id FROM ucenter.user_profile x WHERE x.phone IN ('{0}')".format(phone)
|
||||
user_by_phone = obj_my_sql_helper.select_all(sql_user_by_phone)
|
||||
|
||||
if isinstance(user_by_phone, tuple):
|
||||
raise RuntimeError("未找到手机号为{0}的用户".format(phone))
|
||||
sql_update_pwd = "update ucenter.user_profile set auth_hash = '2ad5381b6a2952287a95b9accb0bb51c'," \
|
||||
"auth_salt='fFRzeLZGR5' WHERE phone IN ('{0}')".format(phone)
|
||||
obj_my_sql_helper.update(sql_update_pwd)
|
||||
obj_log.info('成功更新{0}用户密码为A123456'.format(phone))
|
||||
|
||||
def update_teacher_pwd_by_classroom(self, classroom_Code):
|
||||
"""
|
||||
功能:初始化教师账号密码为Huohua123456
|
||||
| 输入参数: | classroom_Code string | 课堂code |
|
||||
| 作者: | lzp | 2022.03.07 |
|
||||
"""
|
||||
teacher_info = self.get_teacher_info_by_classroom(classroom_Code)
|
||||
sql_update_pwd = "update account.account set pwd = 'e1NTSEF9dzE4ZlFhRytVNzZWeFVKMFFIV2VUNy83U2hxOE5oNUhMT0doTnc9PQ==' WHERE id ={0}".format(
|
||||
teacher_info["account_id"])
|
||||
obj_my_sql_helper.update(sql_update_pwd)
|
||||
obj_log.info('成功更新{0}课堂教师{1}密码为Mima@123'.format(classroom_Code, teacher_info["phone"]))
|
||||
|
||||
def update_teacher_pwd_by_classroom_2(self,classroom_Code):
|
||||
"""
|
||||
功能:初始化教师账号密码为MIma@123456
|
||||
| 输入参数: | classroom_Code string | 课堂code |
|
||||
| 作者: | lrq | 2024.06.12 |
|
||||
"""
|
||||
teacher_info = self.get_teacher_info_by_classroom(classroom_Code)
|
||||
sql_update_pwd = "update account.account set pwd = 'e1NTSEF9dzE4ZlFhRytVNzZWeFVKMFFIV2VUNy83U2hxOE5oNUhMT0doTnc9PQ==' WHERE id ={0}".format(teacher_info["account_id"])
|
||||
obj_my_sql_helper.update(sql_update_pwd)
|
||||
obj_log.info('成功更新{0}课堂教师{1}密码为MIma@123456'.format(classroom_Code,teacher_info["phone"]))
|
||||
|
||||
def update_teacher_pwd_by_teacher_id(self, teacher_id):
|
||||
"""
|
||||
功能:初始化教师账号密码为Huohua123456
|
||||
| 输入参数: | classroom_Code string | 课堂code |
|
||||
| 作者: | lzp | 2022.03.07 |
|
||||
"""
|
||||
teacher_info = self.get_teacher_info_by_teacher_id(teacher_id)
|
||||
sql_update_pwd = "update account.account set pwd = 'e1NTSEF9dzE4ZlFhRytVNzZWeFVKMFFIV2VUNy83U2hxOE5oNUhMT0doTnc9PQ==' WHERE id ={0}".format(
|
||||
teacher_info["account_id"])
|
||||
obj_my_sql_helper.update(sql_update_pwd)
|
||||
obj_log.info('成功更新{0}教师{1}密码为Mima@123'.format(teacher_id, teacher_info["phone"]))
|
||||
|
||||
def get_chess_classroom_by_mcr_code(self, mcr_code):
|
||||
"""
|
||||
功能:获取课堂教师信息 仅支持emp教师
|
||||
| 输入参数: | teacher_id int | 老师id |
|
||||
| 作者: | lzp | 2022.03.07 |
|
||||
"""
|
||||
sql_chess_classroom = "SELECT x.relation_classroom_code FROM learning_plan.classroom_relation x WHERE x.classroom_code IN ('{0}') and status =1 and relation_type = 1".format(
|
||||
mcr_code)
|
||||
chess_classroom = obj_my_sql_helper.select_all(sql_chess_classroom)
|
||||
return chess_classroom
|
||||
|
||||
def get_teacher_info_by_teacher_id(self, teacher_id):
|
||||
"""
|
||||
功能:获取课堂教师信息 仅支持emp教师
|
||||
| 输入参数: | teacher_id int | 老师id |
|
||||
| 作者: | lzp | 2022.03.07 |
|
||||
"""
|
||||
sql_phone_by_classroom_code = "select tp.id,e.phone,tp.account_id from emp.employee e inner join teach_teacher.teacher_profile tp on tp.employee_id = e.id inner join account.account a on a.id= tp.account_id where tp.id = {0}".format(
|
||||
teacher_id)
|
||||
teacher_info = obj_my_sql_helper.select_all(sql_phone_by_classroom_code)
|
||||
return teacher_info[0]
|
||||
|
||||
def get_teacher_info_by_classroom(self, classroom_Code):
|
||||
"""
|
||||
功能:获取课堂教师信息 仅支持emp教师
|
||||
| 输入参数: | classroom_Code string | 课堂code |
|
||||
| 作者: | lzp | 2022.03.07 |
|
||||
"""
|
||||
sql_phone_by_classroom_code = "select c.teacher_id,e.phone,tp.account_id from emp.employee e inner join teach_teacher.teacher_profile tp on tp.employee_id = e.id inner join teach_classes.classroom c on c.teacher_id = tp.id inner join account.account a on a.id= tp.account_id where c.code = '{0}'".format(
|
||||
classroom_Code)
|
||||
teacher_info = obj_my_sql_helper.select_all(sql_phone_by_classroom_code)
|
||||
return teacher_info[0]
|
||||
|
||||
def get_student_info_by_phone(self, phone):
|
||||
"""
|
||||
功能:根据手机号码获取学生基本信息
|
||||
| 输入参数: | phone string | 手机号 |
|
||||
"""
|
||||
user_info = user_kw_obj.kw_ubrd_public_get_user_info_by_phone(phone)
|
||||
sql = "SELECT id studentId FROM ucenter.student_profile where user_id ='{}'".format(user_info["user_id"])
|
||||
return obj_my_sql_helper.select_one(sql)
|
||||
|
||||
def get_classroom_info_by_code(self, code):
|
||||
"""
|
||||
功能:根据课堂号获取课堂信息
|
||||
| 输入参数: | phone string | 手机号 |
|
||||
"""
|
||||
sql = "SELECT id,code,classes_id,classes_code,course_id,course_name,lesson_id,lesson_name,teacher_id,open_time,close_time,is_closed,status FROM teach_classes.classroom where code = '{0}'".format(
|
||||
code)
|
||||
return obj_my_sql_helper.select_one(sql)
|
||||
|
||||
def register_by_code_phone(self, phone, countryCode=86):
|
||||
auth_code_send_result = obj_base_logic.logic_public_send_auth_code(
|
||||
{'h': {'accept-language': 'en'}, 'phone': phone, 'countryCode': '{}'.format(countryCode), 'authType': 2,
|
||||
'verifyAppId': 2})
|
||||
obj_log.info(auth_code_send_result)
|
||||
sms_code = obj_edu_user_helper.get_sms_code_by_phone(phone)
|
||||
obj_log.info(sms_code)
|
||||
login_post_result = self.kw_in_ubrd_login_post(
|
||||
**{'phone': phone, 'countryCode': '86', 'password': 'A123456', 'authCode': sms_code})
|
||||
obj_log.info(login_post_result)
|
||||
# 更新密码
|
||||
obj_my_sql_helper.update(
|
||||
"update ucenter.user_profile set auth_hash = 'e2a0c8ec7503d1bfea587d5ffa0efc2f',auth_salt='fTvsqofig7' WHERE phone='{}'".format(
|
||||
phone))
|
||||
|
||||
def get_change_pwd_vcode_by_sms_code(self, phone):
|
||||
""" 获取学生端修改密码验证码 """
|
||||
sms_code = obj_edu_user_helper.get_sms_code_by_phone(phone)
|
||||
return sms_code
|
||||
|
||||
def get_register_vccode_by_redis(self, phone):
|
||||
"""
|
||||
获取学生端注册验证码
|
||||
"""
|
||||
key = "api:AUTH_CODE:{0}_SIGN_IN".format(phone)
|
||||
obj_log.info(key)
|
||||
return self.get_student_key_value_by_redis(key, 9)
|
||||
|
||||
def delete_change_student_pwd_limit_redis(self, phone):
|
||||
"""
|
||||
功能:删除学生端修改密码次数限制缓存
|
||||
| 作者: | lzp | 2021.08. 15 |
|
||||
"""
|
||||
key_1 = "GRANULARITY:PHONE_AUTH_RECEIVE_COUNT_CHANNEL_MOBILE_API{0}".format(phone)
|
||||
key_2 = "GRANULARITY:PHONE_AUTH_RECEIVE_COUNT_CHANNEL_MOBILE_API{0}_1".format(phone)
|
||||
self.delete_student_key_redis(key_1, 9)
|
||||
self.delete_student_key_redis(key_2, 9)
|
||||
|
||||
def delete_student_key_redis(self, key: object, db: object):
|
||||
"""
|
||||
删除指定key
|
||||
"""
|
||||
if self.current_business == "hh":
|
||||
host = 'redis.qa.huohua.cn'
|
||||
password = 'AcUVeRb8lN'
|
||||
port = 6379
|
||||
elif self.current_business == "hhi":
|
||||
host = 'redis.qa.visparklearning.com'
|
||||
password = 'hxTjlWBYdK6UpAGF'
|
||||
port = 6379
|
||||
else:
|
||||
raise RuntimeError("读取本地配置环境失败,未能正常连接redis")
|
||||
pool = Redis(host=host, port=port, password=password, db=db)
|
||||
pool.delete(key)
|
||||
|
||||
def get_student_key_value_by_redis(self, key, db):
|
||||
"""
|
||||
获取指定key的value
|
||||
"""
|
||||
if self.current_business == "hh":
|
||||
host = 'redis.qa.huohua.cn'
|
||||
password = 'AcUVeRb8lN'
|
||||
port = 6379
|
||||
elif self.current_business == "hhi":
|
||||
host = 'redis.qa.visparklearning.com'
|
||||
password = 'hxTjlWBYdK6UpAGF'
|
||||
port = 6379
|
||||
else:
|
||||
raise RuntimeError("读取本地配置环境失败,未能正常连接redis")
|
||||
pool = Redis(host=host, port=port, password=password, db=db, decode_responses=True)
|
||||
value = pool.get(key)
|
||||
return value
|
||||
|
||||
def check_data_in_list(self, array: list, item):
|
||||
"""
|
||||
判断某个数据是否在数组中
|
||||
"""
|
||||
if item in array:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def update_classroom_data_to_join(self, classroom_id):
|
||||
"""
|
||||
更新学习服务课堂数据
|
||||
"""
|
||||
open_time_timestamp = obj_tools.get_format_date(r_type=12)
|
||||
close_time_timestamp = obj_tools.get_format_date(r_type=12, add_hours=1)
|
||||
|
||||
open_time_standard_time = obj_tools.get_format_date(r_type=4)
|
||||
close_time_standard_time = obj_tools.get_format_date(r_type=4, add_hours=1)
|
||||
# 更新学员课表数据
|
||||
sql_learning_schedule = "update learning_plan.learning_schedule set open_time ='{0}',close_time = '{1}' " \
|
||||
"where classroom_id = {2}".format(open_time_standard_time, close_time_standard_time,
|
||||
classroom_id)
|
||||
obj_my_sql_helper.update(sql_learning_schedule)
|
||||
|
||||
# 更新教师课表数据
|
||||
sql_teaching_schedule = "update learning_plan.teaching_schedule set open_time ='{0}',close_time = '{1}', class_status =0 " \
|
||||
"where classroom_id = {2}".format(open_time_timestamp, close_time_timestamp,
|
||||
classroom_id)
|
||||
obj_my_sql_helper.update(sql_teaching_schedule)
|
||||
|
||||
def check_data_in_db(self, sql, retry_count):
|
||||
"""
|
||||
判断某个数据是否在数据库中
|
||||
"""
|
||||
obj_my_sql_helper.check_result_exist(sql, retry_count=retry_count)
|
||||
|
||||
def encryption_aes(self,data,key=None):
|
||||
if not key:
|
||||
key = b"y3wa93twda35eqer"
|
||||
cipher = AES.new(key, AES.MODE_ECB)
|
||||
padded_data = pad(data.encode(), AES.block_size) # PKCS5Padding
|
||||
encrypted_data = cipher.encrypt(padded_data)
|
||||
return base64.b64encode(encrypted_data).decode()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
user_common_obj = UserCommon()
|
||||
a = 138475
|
||||
s=user_common_obj.update_teacher_pwd_by_teacher_id(teacher_id=183152 )
|
||||
print(s)
|
||||
# print(user_common_obj.get_user_info_by_phone('13458500234'))
|
||||
# phone_dict ={'phone': '65-98760021'}
|
||||
# user_common_obj.get_register_vccode_by_redis('65-98760021')
|
||||
# user_common_obj.update_classroom_data_to_join(classroom_id=500852944)
|
||||
@@ -1,20 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# @Time : 2022/11/22 18:48
|
||||
# @Author: luozhipeng
|
||||
# @File : user_message.py
|
||||
|
||||
class ClassesReminder():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def before_24h_reminder(self):
|
||||
pass
|
||||
|
||||
def absence_classes_reminder(self):
|
||||
pass
|
||||
|
||||
def before_1h_reminder(self):
|
||||
pass
|
||||
|
||||
def before_2min_reminder(self):
|
||||
pass
|
||||
@@ -1,9 +0,0 @@
|
||||
# 存放小组内的配置信息
|
||||
[m-userinfo]
|
||||
login_sso_info = {"user":"liuruiquan","password":"lrq5823LRQ"}
|
||||
login_parent_info ={"phone":"15328118883","password":"a123456","loginType":2,"countryCode":"null","userType":1,"subjectType":0}
|
||||
login_student_info ={"phone":"18202810506","countryCode":86,"password":"A123456","authCodeType":2,"loginType":2}
|
||||
realm_name = {"parent_api":"https://parent-api.huohua.cn","student_api":"https://student-api.huohua.cn","parent_vispark_api":"https://pst-gw.huohua.cn"}
|
||||
parent_url = {"login_url":"https://m.huohua.cn/passport/login","parentPayEditionPage_url":"/parentPayEditionPage/user_info","recommendedCourse_url":"/personal_center/recommendedCourse"}
|
||||
student_url = {"login_url":"https://core-api.huohua.cn/token","scheduleCount_url":"/learning/schedule/count/4"}
|
||||
parent_course_url = {"get_trial_url":"/parent/audition/classes/overseas/course"}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,37 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Author: qiaoxinjiu
|
||||
Email: qiaoxinjiu@qq.com
|
||||
Create Date: 2026/01/17 5:58 下午
|
||||
"""
|
||||
from base_framework.public_tools.mg_keyword import ManageKeyWord
|
||||
from base_framework.public_tools import utils
|
||||
from zhyy.library.BusinessKw.SZPurchase.index import PurchaseIndex
|
||||
|
||||
obj_get_way = utils.Tools()
|
||||
obj_purchase_kw = PurchaseIndex()
|
||||
obj_manage_kw = ManageKeyWord()
|
||||
|
||||
|
||||
class PurchaseLogic():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def logic_zhyy_sz_purchase_todo_task(self, post_data_input, phone=None):
|
||||
"""
|
||||
| 功能说明: | 深圳采购待办任务处理 |
|
||||
| 请求参数名 | 说明 | 类型 | 条件 | 是否必填 | |
|
||||
| userName | 登录名 | string |None | 0 |
|
||||
|
||||
作者信息: | 谯新久 | 2026/01/17 |
|
||||
"""
|
||||
try:
|
||||
post_data_input = eval(post_data_input)
|
||||
except:
|
||||
post_data_input = post_data_input
|
||||
|
||||
return
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
@@ -1,68 +0,0 @@
|
||||
# -*-coding:utf-8-*
|
||||
import os
|
||||
import sys
|
||||
|
||||
# 添加项目根目录到 Python 路径,以便导入 base_framework 模块
|
||||
current_file_path = os.path.abspath(__file__)
|
||||
project_root = os.path.abspath(os.path.join(os.path.dirname(current_file_path), '../../'))
|
||||
if project_root not in sys.path:
|
||||
sys.path.insert(0, project_root)
|
||||
|
||||
from base_framework.public_tools import utils
|
||||
from base_framework.public_tools.log import get_logger
|
||||
from base_framework.public_tools.runner import Runner
|
||||
from base_framework.public_tools.utils import Tools
|
||||
from base_framework.public_tools import check_resp, convert_json, get_user, custom_check_resp
|
||||
from base_framework.public_tools.eureka_api import EurekaAPI
|
||||
import requests
|
||||
|
||||
obj_runner = Runner()
|
||||
obj_log = get_logger()
|
||||
tools = Tools()
|
||||
obj_tool = utils.Tools()
|
||||
s = requests.session()
|
||||
eureka = EurekaAPI()
|
||||
|
||||
|
||||
class ZhyyInterface:
|
||||
def __init__(self):
|
||||
self.domain_url = eureka.get_url_from_config()
|
||||
|
||||
def kw_in_zhyy_purchase_todo_get(self, is_check='', **kwargs):
|
||||
"""
|
||||
查询采购待办任务 + POST + interface id: 88383
|
||||
url: http://peppa-personas-server.qa.huohua.cn/crowd_pack_query/list
|
||||
| 请求参数名 | 说明 | 类型 | 条件 | 是否必填 |
|
||||
| is_check | is_check默认空不校验返回,有值就校验返回 | string | 业务case的时候需要传入值 | False |
|
||||
"""
|
||||
user, kwargs = get_user(kwargs)
|
||||
kwargs = convert_json(kwargs)
|
||||
url = "%s/erp/purchase-workbench/get-todo" % self.domain_url
|
||||
obj_log.info("your input:{0}".format(kwargs))
|
||||
resp = obj_runner.call_rest_api(API_URL=url, req_type="GET", user=user)
|
||||
check_resp(is_check, resp)
|
||||
return resp
|
||||
|
||||
def kw_in_zhyy_purchase_order_page_post(self, is_check='', **kwargs):
|
||||
"""
|
||||
查询采购单列表 + POST + interface id: 88383
|
||||
url: http://peppa-personas-server.qa.huohua.cn/admin-api/erp/purchase-order/page
|
||||
| 请求参数名 | 说明 | 类型 | 条件 | 是否必填 |
|
||||
| is_check | is_check默认空不校验返回,有值就校验返回 | string | 业务case的时候需要传入值 | False |
|
||||
| pageNum | 页码 | integer | None | 0 |
|
||||
| pageSize | 每页条数 | integer | None | 0 |
|
||||
"""
|
||||
user, kwargs = get_user(kwargs)
|
||||
kwargs = convert_json(kwargs)
|
||||
url = "%s/erp/purchase-order/page" % self.domain_url
|
||||
obj_log.info("your input:{0}".format(kwargs))
|
||||
resp = obj_runner.call_rest_api(API_URL=url, req_type="POST", json=kwargs, user=user)
|
||||
check_resp(is_check, resp)
|
||||
return resp
|
||||
|
||||
if __name__ == '__main__':
|
||||
test = ZhyyInterface()
|
||||
# print(test.domain_url)
|
||||
a = test.kw_in_zhyy_purchase_todo_get(
|
||||
user="purchase")
|
||||
print(a)
|
||||
@@ -1,134 +0,0 @@
|
||||
# coding: utf-8
|
||||
import importlib
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
from base_framework.base_config.current_pth import env_choose_path
|
||||
from base_framework.public_tools.read_config import ReadConfig
|
||||
from base_framework.public_tools.log import get_logger
|
||||
evn_cfg = ReadConfig(env_choose_path)
|
||||
team = evn_cfg.get_value(sections="run_evn_name", options="current_team")
|
||||
__all__ = ['KwLibrary']
|
||||
cls_list_all = list()
|
||||
cls_list_father = list()
|
||||
cls_list_children = list()
|
||||
t_c_list = list()
|
||||
obj_log = get_logger()
|
||||
|
||||
|
||||
def is_import(root):
|
||||
black_list = [os.sep.join(['platform', 'tools']),'scene_server']
|
||||
import_flag = True
|
||||
for black_item in black_list:
|
||||
if black_item in root:
|
||||
# print(3, root)
|
||||
import_flag = False
|
||||
return import_flag
|
||||
|
||||
|
||||
def class_import(path_list):
|
||||
root_path = os.path.abspath(os.path.join(os.getcwd(), "../"))
|
||||
module_path = root_path + os.sep + os.sep.join(path_list)
|
||||
sys.path.append(module_path)
|
||||
for root, dirs, files in os.walk(module_path):
|
||||
# if is_import(root):
|
||||
for file in files:
|
||||
if os.path.splitext(file)[1] == '.py' and not file.startswith('__'):
|
||||
with open(os.sep.join([root, file]), encoding="utf-8") as f:
|
||||
for line in f.readlines():
|
||||
cls_match = re.match(r"class\s(.*?)[\(:]", line)
|
||||
if cls_match:
|
||||
cls_name = cls_match.group(1)
|
||||
try:
|
||||
if cls_name not in ["Runner"]:
|
||||
# module_list = root.split(os.sep)[len(os.getcwd().split(os.sep)) - 1:]
|
||||
# module_list.append(os.path.splitext(file)[0])
|
||||
# module = importlib.import_module('.'.join(module_list))
|
||||
module_path_list = root.split(os.sep)
|
||||
module_path_list.append(os.path.splitext(file)[0])
|
||||
module_path = ''
|
||||
for index in range(len(module_path_list)):
|
||||
if module_path_list[index].lower() == 'base_framework' or module_path_list[index].lower() == 'library':
|
||||
tmp_path = module_path_list[index:]
|
||||
for path in tmp_path:
|
||||
module_path = module_path + path + '.'
|
||||
break
|
||||
module_path = module_path[0:-1]
|
||||
module = importlib.import_module(module_path)
|
||||
|
||||
class_attr = getattr(module, cls_name)
|
||||
t_c_list.append(class_attr)
|
||||
# if class_attr:
|
||||
# if class_attr.__bases__[0] == object:
|
||||
# cls_list_children.append(class_attr)
|
||||
# else:
|
||||
# cls_list_father.append(class_attr)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
print("ERROR import", file, cls_name)
|
||||
|
||||
|
||||
def sort_class(class_list):
|
||||
"""
|
||||
功能:将所有的class按继承关系排序,子类在前,父类在后,用于startup启动加载
|
||||
"""
|
||||
while len(class_list) > 0:
|
||||
# cls_list_len = len(cls_list_all)
|
||||
tmp_class_list = []
|
||||
del_list = []
|
||||
for index in range(len(class_list)):
|
||||
if not cls_list_all:
|
||||
# 先找出所有的父类是object的基类
|
||||
if class_list[index].__bases__[0] == object:
|
||||
# while class_list[index].__bases__[0] == object:
|
||||
tmp_class_list.append(class_list[index])
|
||||
del_list.append(class_list[index])
|
||||
else:
|
||||
# 寻找前一步晒出基类的子类
|
||||
if class_list[index].__bases__[0] in cls_list_all[len(cls_list_all) - 1]:
|
||||
tmp_class_list.append(class_list[index])
|
||||
del_list.append(class_list[index])
|
||||
if len(tmp_class_list) > 0:
|
||||
# 如果父类在已选出的类中,则保存该类
|
||||
cls_list_all.append(tmp_class_list)
|
||||
for item in del_list:
|
||||
class_list.remove(item)
|
||||
else:
|
||||
# 如果父类都不在已选出的类中,则全部按父类是object处理
|
||||
cls_list_all.append(class_list)
|
||||
class_list = []
|
||||
|
||||
|
||||
class_import(["base_framework", "public_tools"])
|
||||
class_import(["base_framework", "public_business"])
|
||||
class_import([team, "library"])
|
||||
# BaseLibrary = type('BaseLibrary', tuple(cls_list_father + cls_list_children), {})
|
||||
sort_class(t_c_list)
|
||||
c_len = len(cls_list_all)
|
||||
obj_cls_tuple = ()
|
||||
while c_len > 0:
|
||||
obj_cls_tuple += tuple(cls_list_all[c_len - 1], )
|
||||
c_len = c_len - 1
|
||||
print(obj_cls_tuple)
|
||||
BaseLibrary = type('BaseLibrary', obj_cls_tuple, {})
|
||||
|
||||
|
||||
class KwLibrary(BaseLibrary):
|
||||
|
||||
def __init__(self):
|
||||
class_len = 0
|
||||
for base in BaseLibrary.__bases__:
|
||||
try:
|
||||
if hasattr(base, '__init__'):
|
||||
if '__init__' in base.__dict__.keys():
|
||||
if base.__bases__[0] != object or len(base.__init__.__code__.co_varnames) == 1:
|
||||
base.__init__(self)
|
||||
print(base)
|
||||
# obj_log.info("init class:{} success...".format(base))
|
||||
class_len += 1
|
||||
except Exception as e:
|
||||
if base.__bases__[0] == object:
|
||||
print("INIT", e, base, base.__dict__)
|
||||
# obj_log.info("import files num: {}".format(class_len))
|
||||
print("import files num: {}".format(class_len))
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
print("222222222222")
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,337 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Author: 陈江
|
||||
Email: chenjiang@sparkedu.com
|
||||
Create Date: 2022/09/23 2:06 下午
|
||||
"""
|
||||
from base_framework.public_tools.sqlhelper import MySqLHelper
|
||||
|
||||
import json
|
||||
|
||||
obj_mysql_helper = MySqLHelper()
|
||||
|
||||
|
||||
class CoursePackage:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def __get_data_name(data_list):
|
||||
temp_data_list = []
|
||||
if data_list:
|
||||
for data in data_list:
|
||||
temp_data_list.append(
|
||||
{"course_package_id": data.get('value'), "cc显示_course_package_name": data.get('name'),
|
||||
"course_package_name": data.get('text')})
|
||||
return temp_data_list
|
||||
return None
|
||||
|
||||
def get_course_package_by_cc_crm(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 获取套餐信息,根据cc/crm购买可选套餐 |
|
||||
| 输入参数: |
|
||||
| 作者信息: | 陈江 | 修改时间 | 2022-9-28 |
|
||||
"""
|
||||
sql_crm_vispark_subscribe_chinese = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
type = 1
|
||||
AND business_line = 1
|
||||
AND business_line_type = 2
|
||||
AND teaching_method = 0
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject = ',2,'
|
||||
AND course_type IN ( ',5,', ',1,' )
|
||||
AND sale_type = 2
|
||||
AND course_teaching_method = 1
|
||||
AND STATUS = 1
|
||||
AND view_authority_scope LIKE '%,7,%'
|
||||
ORDER BY
|
||||
id DESC LIMIT 3;"""
|
||||
crm_vispark_subscribe_chinese_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_subscribe_chinese))
|
||||
|
||||
sql_crm_vispark_subscribe_sg = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
type = 1
|
||||
AND business_line = 1
|
||||
AND business_line_type = 1
|
||||
AND teaching_method = 0
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject = ',1,'
|
||||
AND course_type IN ( ',5,' )
|
||||
AND sale_type = 2
|
||||
AND course_teaching_method = 1
|
||||
AND STATUS = 1
|
||||
AND view_authority_scope LIKE '%,10,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
crm_vispark_subscribe_sg_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_subscribe_sg))
|
||||
|
||||
sql_crm_vispark_subscribe_oc = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
type = 1
|
||||
AND business_line = 1
|
||||
AND business_line_type in( 1,10 )
|
||||
AND teaching_method = 0
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject = ',1,'
|
||||
AND course_type IN ( ',5,' )
|
||||
AND sale_type = 2
|
||||
AND course_teaching_method = 1
|
||||
AND STATUS = 1
|
||||
AND view_authority_scope LIKE '%,13,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
crm_vispark_subscribe_oc_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_subscribe_oc))
|
||||
|
||||
sql_crm_vispark_buy_chinese = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
type = 1
|
||||
AND business_line = 1
|
||||
AND business_line_type = 2
|
||||
AND teaching_method = 0
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject = ',2,'
|
||||
AND course_type IN ( ',5,', ',1,', ',1,5,', ',5,1,')
|
||||
AND sale_type = 1
|
||||
AND course_teaching_method = 1
|
||||
AND STATUS = 1
|
||||
AND view_authority_scope LIKE '%,7,%'
|
||||
ORDER BY
|
||||
IF (abbreviation="",NAME,abbreviation) asc limit 3;"""
|
||||
crm_vispark_buy_chinese_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_buy_chinese))
|
||||
|
||||
sql_crm_vispark_buy_us = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
type = 1
|
||||
AND business_line = 1
|
||||
AND business_line_type = 10
|
||||
AND teaching_method = 0
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject = ',1,'
|
||||
AND course_type IN ( ',5,', ',1,', ',1,5,', ',5,1,')
|
||||
AND sale_type = 1
|
||||
AND course_teaching_method = 1
|
||||
AND STATUS = 1
|
||||
AND view_authority_scope LIKE '%,11,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
crm_vispark_buy_us_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_buy_us))
|
||||
|
||||
sql_crm_vispark_buy_canada = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
type = 1
|
||||
AND business_line = 1
|
||||
AND business_line_type = 10
|
||||
AND teaching_method = 0
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject = ',1,'
|
||||
AND course_type IN ( ',5,', ',1,', ',1,5,', ',5,1,')
|
||||
AND sale_type = 1
|
||||
AND course_teaching_method = 1
|
||||
AND STATUS = 1
|
||||
AND view_authority_scope LIKE '%,1012,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
crm_vispark_buy_canada_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_buy_canada))
|
||||
|
||||
sql_crm_vispark_buy_sg = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
type = 1
|
||||
AND business_line = 1
|
||||
AND business_line_type = 1
|
||||
AND teaching_method = 0
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject = ',1,'
|
||||
AND course_type IN ( ',5,', ',1,', ',1,5,', ',5,1,')
|
||||
AND sale_type = 1
|
||||
AND course_teaching_method = 1
|
||||
AND STATUS = 1
|
||||
AND view_authority_scope LIKE '%,10,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
crm_vispark_buy_sg_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_buy_sg))
|
||||
|
||||
sql_crm_vispark_buy_oc = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
type = 1
|
||||
AND business_line = 1
|
||||
AND business_line_type in( 1,10 )
|
||||
AND teaching_method = 0
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject = ',1,'
|
||||
AND course_type IN ( ',5,', ',1,', ',1,5,', ',5,1,')
|
||||
AND sale_type = 1
|
||||
AND course_teaching_method = 1
|
||||
AND STATUS = 1
|
||||
AND view_authority_scope LIKE '%,13,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
crm_vispark_buy_oc_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_buy_oc))
|
||||
|
||||
sql_crm_vispark_buy_huohua = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
teaching_method = 0
|
||||
AND business_line_type in( 0,4,9 )
|
||||
-- AND business_line = 0 (以及业务线)
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject like '%,2,%'
|
||||
-- AND course_type IN ( ',1,',',5,' ) (课程类型)
|
||||
AND sale_type = 1
|
||||
AND course_teaching_method = 1
|
||||
-- AND STATUS = 1 (状态)
|
||||
AND view_authority_scope LIKE '%,7,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
crm_vispark_buy_huohua_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_buy_huohua))
|
||||
|
||||
sql_crm_vispark_subscribe_huohua = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
teaching_method = 0
|
||||
AND business_line_type in( 0,4,9 )
|
||||
AND business_line = 1
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject like '%,2,%'
|
||||
-- AND course_type IN ( ',1,',',5,' ) (课程类型)
|
||||
AND sale_type = 2
|
||||
AND course_teaching_method = 1
|
||||
-- AND STATUS = 1 (状态)
|
||||
AND view_authority_scope LIKE '%,7,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
crm_vispark_subscribe_huohua_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_crm_vispark_subscribe_huohua))
|
||||
|
||||
sql_cc_vispark_subscribe_huohua = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
teaching_method = 0
|
||||
AND business_line_type in( 0,3,9 )
|
||||
AND business_line = 1
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject like '%,1,%'
|
||||
-- AND course_type IN ( ',1,',',5,' ) (课程类型)
|
||||
AND sale_type = 2
|
||||
AND course_teaching_method = 1
|
||||
-- AND STATUS = 1 (状态)
|
||||
AND view_authority_scope LIKE '%,2,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
cc_vispark_subscribe_huohua_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_cc_vispark_subscribe_huohua))
|
||||
|
||||
sql_cc_vispark_buy_huohua = """SELECT
|
||||
IF (abbreviation="",NAME,abbreviation) AS 'text',name,
|
||||
id AS 'value',
|
||||
type,business_line,business_line_type,teaching_method,sale_status,saleable_status,course_subject,course_type,sale_type,course_teaching_method,STATUS,view_authority_scope
|
||||
FROM
|
||||
peppa.course_package
|
||||
WHERE
|
||||
teaching_method = 0
|
||||
AND business_line_type in( 0,3,9 )
|
||||
AND business_line = 1
|
||||
AND sale_status = 1
|
||||
AND saleable_status = 1
|
||||
AND course_subject like '%,1,%'
|
||||
-- AND course_type IN ( ',1,',',5,' ) (课程类型)
|
||||
AND sale_type = 1
|
||||
AND course_teaching_method = 1
|
||||
-- AND STATUS = 1 (状态)
|
||||
AND view_authority_scope LIKE '%,2,%'
|
||||
ORDER BY
|
||||
id DESC limit 3;"""
|
||||
cc_vispark_buy_huohua_list = self.__get_data_name(
|
||||
obj_mysql_helper.select_all(sql_cc_vispark_buy_huohua))
|
||||
data = {"crm中订阅vispark业务的对外汉语-套餐": crm_vispark_subscribe_chinese_list,
|
||||
"crm中订阅vispark业务的sg-套餐": crm_vispark_subscribe_sg_list,
|
||||
"crm中订阅vispark业务的海华-套餐": crm_vispark_subscribe_oc_list,
|
||||
"crm中直购vispark业务的对外汉语-套餐": crm_vispark_buy_chinese_list,
|
||||
"crm中直购vispark业务的us-套餐": crm_vispark_buy_us_list,
|
||||
"crm中直购vispark业务的加拿大-套餐": crm_vispark_buy_canada_list,
|
||||
"crm中直购vispark业务的sg-套餐": crm_vispark_buy_sg_list,
|
||||
"crm中直购vispark业务的海华-套餐": crm_vispark_buy_oc_list,
|
||||
"crm中直购vispark业务的火花-套餐": crm_vispark_buy_huohua_list,
|
||||
"crm中订阅vispark业务的火花-套餐": crm_vispark_subscribe_huohua_list,
|
||||
"cc中订阅vispark业务的火花-套餐": cc_vispark_subscribe_huohua_list,
|
||||
"cc中直购vispark业务的火花-套餐": cc_vispark_buy_huohua_list}
|
||||
|
||||
return data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cc = CoursePackage()
|
||||
bb = cc.get_course_package_by_cc_crm('')
|
||||
print(bb)
|
||||
@@ -1,109 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Author: 陈江
|
||||
Email: chenjiang@sparkedu.com
|
||||
Create Date: 2022/09/23 2:06 下午
|
||||
"""
|
||||
from base_framework.public_business.common.UBRD.kw.coursePackage_keyword import CoursePackageKW
|
||||
from base_framework.public_tools import utils
|
||||
from base_framework.public_tools.sqlhelper import MySqLHelper
|
||||
from base_framework.public_tools.mg_keyword import ManageKeyWord
|
||||
from base_framework.public_business import manage_public_business
|
||||
|
||||
import json
|
||||
|
||||
|
||||
obj_course_package_kw = CoursePackageKW()
|
||||
obj_get_way = utils.Tools()
|
||||
obj_mysql_helper = MySqLHelper()
|
||||
obj_manage_kw = ManageKeyWord()
|
||||
obj_manage_business = manage_public_business.ManagePublicBusiness()
|
||||
|
||||
class Order:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def order_done_pay(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 订单完成支付 |
|
||||
| 输入参数: |
|
||||
|orderId/orderCode/prepayCode| 订单id/code/prepayCode | 必填其一
|
||||
| podenv | str | 独立环境编号| 非必填
|
||||
| 作者信息: | 陈江 | 修改时间 | 2022-9-28 |
|
||||
"""
|
||||
if not post_data_input.get('orderId') and not post_data_input.get('orderCode') and not post_data_input.get(
|
||||
'prepayCode'):
|
||||
raise "orderId/orderCode/prepayCode必传1个"
|
||||
|
||||
ordr_info = obj_course_package_kw.get_order_info(post_data_input)
|
||||
order_id = ordr_info.get('orderId')
|
||||
mq_body_dict = obj_course_package_kw.kw_ubrd_public_get_service_id_by_order_id({"orderId": order_id})
|
||||
message_body = {"orderId": order_id, "serviceId": int(mq_body_dict.get('serviceId'))}
|
||||
if post_data_input.get('podenv'):
|
||||
obj_get_way.mq_send(mq_body_dict.get('topic'), json.dumps(message_body), pro=post_data_input.get('podenv'))
|
||||
else:
|
||||
obj_get_way.mq_send(mq_body_dict.get('topic'), json.dumps(message_body))
|
||||
order_100_sql = f"SELECT id FROM `order_center`.`order_course_package` WHERE id='{order_id}' AND status=100"
|
||||
obj_mysql_helper.check_result_exist(order_100_sql, retry_count=20)
|
||||
subscribe_id_sql = f"SELECT subscribe_id FROM `order_center`.`subscribe_order_log` WHERE order_id={order_id}"
|
||||
obj_mysql_helper.check_result_exist(subscribe_id_sql, retry_count=20)
|
||||
subscribe_id = obj_mysql_helper.select_one(subscribe_id_sql).get('subscribe_id')
|
||||
|
||||
return {"order_id": order_id, "subscribe_id": subscribe_id}
|
||||
|
||||
def add_review_subscribe_order(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 生成续订阅订单 |
|
||||
| 输入参数: |
|
||||
|subscribeIds| 订阅id | 传了用该订阅id生成续订阅订单,必传 比如[3355]
|
||||
| 作者信息: | 张楠 | 修改时间 | 2022-11-10 |
|
||||
"""
|
||||
try:
|
||||
post_data_input = eval(post_data_input)
|
||||
except:
|
||||
post_data_input = post_data_input
|
||||
|
||||
if not post_data_input.get('subscribeIds'):
|
||||
raise RuntimeWarning("订阅id必传")
|
||||
# 构造生成续订阅订单请求参数
|
||||
response_data = obj_manage_kw.kw_execute_xxl_job(8306, para=json.dumps(post_data_input))
|
||||
return response_data
|
||||
|
||||
def create_order(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 创建直购订单 |
|
||||
| 请求参数名 | 说明 | 类型 | 是否必填 | 如无要求时的值 |
|
||||
| userId | 用户id | string | 0 | |
|
||||
| phone | 用户手机号 | string | 0 | |
|
||||
| coursePackageId | 套餐id | integer | 0 | |
|
||||
| businessLine | 业务线一级类型,0:火花中国、1:vispark | integer | 0 | |
|
||||
| businessLineType | 业务线二级类型,1:新加坡数学、2:对外汉语、3:直播逻辑思维、4:直播中文素养、5:直播双语素养、6:AI、7:围棋、8:国际象棋、9:其他、10:北美数学、11:越南数学、12:春风思维、13:口才课 | integer | 0 | |
|
||||
| category | 业务线三级类型,K-SMAP:新加坡AP、P-CM:新加坡CP、A:北美AP、C-北美CP、V-越南AP、N-越南CP、ZHK-对外汉语综合课 | string | 0 | |
|
||||
| teachingMethod | 授课方式, 0:直播、1:AI | integer | 0 | 0 |
|
||||
| type | 套餐类型,1:正式课、2:体验课 | integer | 0 | 1 |
|
||||
| courseSubjectList | 课程学科集合,1:数学、2:语文、3:科学、4:英语、5:编程、7:围棋、8:国际象棋、9:春风思维、10:口才课 | list | 0 | |
|
||||
| courseId | 课程id | integer | 0 | |
|
||||
| channel | 渠道,1:电商、0:非电商 | integer | 0 | 0 |
|
||||
| channelValue | 渠道chi | string | 0 | 0 |
|
||||
| classHourType | 课时类型,0:小班课、3:1v1 | integer | 0 | |
|
||||
| offline | 线下,1:线下、0:线上 | integer | 0 | 1 |
|
||||
| businessType | 业务类型,0:常规、1:补差、2:可补差 | integer | 0 | 0 |
|
||||
| currency | 币种,0:人民币、1:美元 | integer | 0 | |
|
||||
| saleType | 售卖方式,1:直购、2:订阅 | integer | 0 | 1 |
|
||||
| teachingScope | 授课范围,1:所有课程、2:自定义课程 | integer | 0 | 1 |
|
||||
| payPrice | 实付金额 | integer | 0 | |
|
||||
| createdType | 订单类型,0:默认未选择、 10:团购订单、11:加价购-团购订单、12:加价购-普通订单、20:CC提单、30:CC提单、40:自助下单、50:微店购买| integer | 0| 0 |
|
||||
Returns:
|
||||
{orderId, orderCode}
|
||||
| 作者信息: | lrq | 修改时间 | 2025-03-18 |
|
||||
"""
|
||||
try:
|
||||
post_data_input = eval(post_data_input)
|
||||
except:
|
||||
post_data_input = post_data_input
|
||||
return obj_manage_business.kw_public_manage_create_order(**post_data_input)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
a = Order()
|
||||
a.create_order({"userId":"2557864","channel":"35d75242534611e8b5325cb9018964ec","coursePackageId":"2503934602"})
|
||||
@@ -1,208 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Author: 陈江
|
||||
Email: chenjiang@sparkedu.com
|
||||
Create Date: 2022/09/23 2:06 下午
|
||||
"""
|
||||
from base_framework.public_business.common.UBRD.UBRD_public_business import BaseLogic
|
||||
from base_framework.public_business.common.UBRD.kw.coursePackage_keyword import CoursePackageKW
|
||||
from base_framework.public_tools import utils
|
||||
from base_framework.public_tools.sqlhelper import MySqLHelper
|
||||
from base_framework.public_tools.log import get_logger
|
||||
from base_framework.public_business.common.UBRD.kw.user_keyword import UserKW
|
||||
from base_framework.public_tools.mg_keyword import ManageKeyWord
|
||||
from library.CommonFun.handle_tools import Handle_tools
|
||||
import requests
|
||||
|
||||
obj_base_logic = BaseLogic()
|
||||
obj_course_package_kw = CoursePackageKW()
|
||||
obj_get_way = utils.Tools()
|
||||
obj_mysql_helper = MySqLHelper()
|
||||
log = get_logger()
|
||||
obj_user_kw = UserKW()
|
||||
obj_manage_kw = ManageKeyWord()
|
||||
obj_handle_tools = Handle_tools()
|
||||
|
||||
|
||||
class User:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def add_user_recharge(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 新增用户,充值课时 |
|
||||
| 输入参数: |
|
||||
|phone/userId| 用户手机号/用户id | 非必填,不传会默认随机注册一个账号;传的手机号不存在会自动进行注册;
|
||||
|coursePackageCode/courseId/coursePackageId/coursePackageName| 传一个即可 | 传了就给用充值课时,不传就不充
|
||||
|classHour | | 充值课时 | 不传,需要充值时默认充值100
|
||||
|new_user_count | | 生成新账号数量,存在这个参数时只会生成相应数量的账号 |
|
||||
| 作者信息: | 陈江 | 修改时间 | 2022-9-23 |
|
||||
"""
|
||||
user_list = []
|
||||
try:
|
||||
post_data_input = eval(post_data_input)
|
||||
except:
|
||||
post_data_input = post_data_input
|
||||
|
||||
if post_data_input.get('new_user_count'):
|
||||
new_user_count = post_data_input.pop('new_user_count')
|
||||
for count in range(0, int(new_user_count)):
|
||||
user_info = obj_base_logic.logic_public_add_user_recharge(post_data_input)
|
||||
user_list.append(user_info)
|
||||
return user_list
|
||||
return obj_base_logic.logic_public_add_user_recharge(post_data_input)
|
||||
|
||||
def add_new_user(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 新增用户 |
|
||||
| 输入参数: |
|
||||
|fu_phone/fu_user_Id| 邀请人手机号或者user_id | 非必填,不传新增用户无邀请人;
|
||||
|new_phone| 新增用户手机号 | 传了用该手机号注册,不传则随机一个手机号
|
||||
|new_user_count | | 生成新账号数量,存在这个参数时只会生成相应数量的账号 |
|
||||
| 作者信息: | 陈江 | 修改时间 | 2022-11-01 |
|
||||
"""
|
||||
user_list = []
|
||||
try:
|
||||
post_data_input = eval(post_data_input)
|
||||
except:
|
||||
post_data_input = post_data_input
|
||||
|
||||
# 构造增加用户请求参数
|
||||
add_user_params = {}
|
||||
# 判断是否需要进行邀请
|
||||
if post_data_input.get('fu_phone'):
|
||||
user_info = obj_user_kw.kw_ubrd_public_get_user_info_by_phone(phone=post_data_input.get('fu_phone'))
|
||||
add_user_params['fromUserId'] = user_info.get('user_id')
|
||||
elif post_data_input.get('fu_user_Id'):
|
||||
add_user_params['fromUserId'] = post_data_input.get('fu_user_Id')
|
||||
else:
|
||||
pass
|
||||
|
||||
if post_data_input.get('new_phone'):
|
||||
user_info = obj_user_kw.kw_ubrd_public_get_user_info_by_phone(phone=post_data_input.get('new_phone'))
|
||||
if user_info:
|
||||
raise RuntimeWarning(f"该手机号{post_data_input.get('new_phone')}已经存在")
|
||||
add_user_params['phone'] = post_data_input.get('new_phone')
|
||||
obj_user_kw.kw_ubrd_public_add_user_profile(post_data_input=add_user_params)
|
||||
user_info = obj_user_kw.kw_ubrd_public_get_user_info_by_phone(phone=post_data_input.get('new_phone'))
|
||||
return user_info
|
||||
else:
|
||||
if post_data_input.get('new_user_count'):
|
||||
new_user_count = post_data_input.pop('new_user_count')
|
||||
for count in range(0, int(new_user_count)):
|
||||
phone = obj_user_kw.kw_ubrd_public_get_unregistered_phone()
|
||||
add_user_params['phone'] = phone
|
||||
obj_user_kw.kw_ubrd_public_add_user_profile(post_data_input=add_user_params)
|
||||
user_info = obj_user_kw.kw_ubrd_public_get_user_info_by_phone(phone=phone)
|
||||
user_list.append(user_info)
|
||||
return user_list
|
||||
else:
|
||||
phone = obj_user_kw.kw_ubrd_public_get_unregistered_phone()
|
||||
add_user_params['phone'] = phone
|
||||
obj_user_kw.kw_ubrd_public_add_user_profile(post_data_input=add_user_params)
|
||||
user_info = obj_user_kw.kw_ubrd_public_get_user_info_by_phone(phone=phone)
|
||||
return user_info
|
||||
|
||||
def add_new_haihua_user(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 生成海华标签新用户 |
|
||||
| 输入参数: |
|
||||
|fu_phone/fu_user_Id| 邀请人手机号或者user_id | 非必填,不传新增用户无邀请人;
|
||||
|new_phone| 新增用户手机号 | 传了用该手机号注册,不传则随机一个手机号
|
||||
|new_user_count | | 生成新账号数量,存在这个参数时只会生成相应数量的账号 |
|
||||
| 作者信息: | 陈江 | 修改时间 | 2022-11-01 |
|
||||
"""
|
||||
user_info_list = self.add_new_user(post_data_input)
|
||||
if user_info_list:
|
||||
for user_info in user_info_list:
|
||||
# 设置权益信息
|
||||
obj_mysql_helper.insert_one(
|
||||
f"""INSERT INTO `operation`.`haibao_task_equity`(`user_id`, `order_id`, `order_business_side`, `course_package_id`, `course_package_name`, `equity_num`, `used_num`, `remain_num`, `lock_num`, `start_time`, `end_time`, `effect_period`, `generated_first_task`, `frozen_status`, `refund_status`, `equity_status`, `policy`, `subject_type`, `related_order_id`, `creator_id`, `creator_name`, `created_time`, `modifier_id`, `modifier_name`, `modified_time`) VALUES ({user_info.get('user_id')}, 8881050, 0, 23002, '逻辑思维直播系统课48课包', 20, 0, 20, 0, '2023-02-09 14:44:36', '2023-02-09 14:44:36', 360, 0, 0, 0, 0, 2, 0, 0, 0, '', '2023-02-01 00:00:01', 0, '', '2023-02-09 14:44:36');""")
|
||||
# 设置海华标签
|
||||
obj_mysql_helper.insert_one(
|
||||
f"""INSERT INTO `utag_mass`.`user_tag`(`user_id`, `tag_id`, `tag_name`, `creator_id`, `creator_name`, `created_time`, `status`, `is_del`, `source_type`, `expiration_time`, `modifier_id`, `modifier_name`, `modified_time`) VALUES ({user_info.get('user_id')}, 51, '海外及港澳台用户', 587312, '陈江', '2023-02-09 16:08:24', 1, 0, 0, NULL, 587312, '陈江', '2023-02-09 16:08:24');""")
|
||||
return user_info_list
|
||||
|
||||
def get_unregistered_user(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 获取未注册手机号 |
|
||||
| 输入参数: |
|
||||
|user_count | | 返回未注册手机号数量 |
|
||||
| 作者信息: | 刘涛婷 | 修改时间 | 2022-11-10 |
|
||||
"""
|
||||
user_list = []
|
||||
try:
|
||||
post_data_input = eval(post_data_input)
|
||||
except:
|
||||
post_data_input = post_data_input
|
||||
|
||||
if post_data_input.get('user_count'):
|
||||
user_count = post_data_input.pop('user_count')
|
||||
for count in range(0, int(user_count)):
|
||||
user_phone = obj_user_kw.kw_ubrd_public_get_unregistered_phone()
|
||||
user_list.append(user_phone)
|
||||
return user_list
|
||||
return obj_user_kw.kw_ubrd_public_get_unregistered_phone()
|
||||
|
||||
def get_sms_code_by_phone(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 发送验证码 |
|
||||
| 输入参数:
|
||||
| phone | 手机号| 必填
|
||||
| countryCode | 国家码 | 默认 86
|
||||
| authType | 验证码类型 | 默认2
|
||||
| verifyAppId | 验证appId | 默认2
|
||||
| 作者信息: | 陈江 | 2022/10/21 |
|
||||
"""
|
||||
# 发送验证码
|
||||
obj_base_logic.logic_public_send_auth_code(post_data_input)
|
||||
# 获取验证码内容
|
||||
# 根据phone获取phone_code
|
||||
phone_server_ip = obj_get_way.get_container_ip_from_eureka('PHONE-SERVER', need_jira_id='qa',
|
||||
eureka_url='http://eureka.qa.huohua.cn')
|
||||
if post_data_input.get('countryCode'):
|
||||
phone = f"{post_data_input.get('countryCode')}-{post_data_input.get('phone')}"
|
||||
else:
|
||||
phone = post_data_input.get('phone')
|
||||
|
||||
if phone_server_ip.get('container_ip'):
|
||||
url = 'http://{}:8080/encrypt/regdata?biztype=phone&uid=123456&sourceData={}'.format(
|
||||
phone_server_ip.get('container_ip'), phone)
|
||||
response = requests.post(url=url) # 三个参数
|
||||
response_json = response.json()
|
||||
else:
|
||||
raise "获取phone server ip失败"
|
||||
|
||||
if response_json.get('data'):
|
||||
msg = obj_mysql_helper.select_all(
|
||||
'SELECT msg FROM `push_service`.`sms` WHERE `phone_code` = \'{}\' ORDER BY id DESC LIMIT 1 '.format(
|
||||
response_json.get('data')))
|
||||
if msg:
|
||||
web_hook = "https://open.feishu.cn/open-apis/bot/v2/hook/c9baf09d-55f1-46a6-8d67-9d4ff30b1be2"
|
||||
message_data = {"msg_type": "post", "content": {
|
||||
"post": {"zh_cn": {"title": "message",
|
||||
"content": [[{"tag": "text", "text": msg[0].get('msg')}]]}}}}
|
||||
obj_handle_tools.send_message_by_feishu(web_hook, message_data)
|
||||
else:
|
||||
raise f"{phone}获取验证码失败"
|
||||
return msg[0].get('msg')
|
||||
|
||||
else:
|
||||
return response_json
|
||||
|
||||
def register_user(self, post_data_input):
|
||||
"""
|
||||
| 功能说明: | 通过注册接口进行注册用户并设置密码A123456(支持邀请码,渠道) |
|
||||
| 输入参数: |
|
||||
| | | channelId | string | 渠道id |
|
||||
| | | invitePhone | string | 手机号 | "12030690001/86-13400114600"
|
||||
| | | registerPhone | string | 手机号 | "12030690001/86-13400114600"
|
||||
| 作者信息: | 陈江 | 修改时间 | 2022-11-10 |
|
||||
"""
|
||||
return obj_base_logic.logic_public_register_user(post_data_input)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ff = {'phone': '13400234500','coursePackageId':29497}
|
||||
# User().add_user_recharge(ff)
|
||||
User().add_new_user(post_data_input={"new_user_count":"2"})
|
||||
@@ -1,190 +0,0 @@
|
||||
# Jenkins + Allure 报告集成配置指南
|
||||
|
||||
## 前置要求
|
||||
|
||||
1. **Jenkins已安装并运行**
|
||||
2. **安装Allure插件**
|
||||
- 进入 Jenkins → Manage Jenkins → Manage Plugins
|
||||
- 搜索并安装 "Allure Plugin"
|
||||
3. **安装Allure命令行工具**
|
||||
- 下载:https://github.com/allure-framework/allure2/releases
|
||||
- 解压并添加到系统PATH环境变量
|
||||
- 或在Jenkins全局工具配置中配置Allure路径
|
||||
|
||||
## Jenkins配置步骤
|
||||
|
||||
### 方式一:使用Jenkinsfile(推荐)
|
||||
|
||||
1. **在Jenkins中创建Pipeline任务**
|
||||
- 新建任务 → 选择 "Pipeline"
|
||||
- 任务名称:例如 "ZZYY_Test_Automation"
|
||||
|
||||
2. **配置Pipeline**
|
||||
- Pipeline definition → Pipeline script from SCM
|
||||
- SCM: Git(或其他版本控制)
|
||||
- Script Path: `zhyy/test_case/Jenkinsfile`
|
||||
- 保存
|
||||
|
||||
3. **运行任务**
|
||||
- 点击 "Build with Parameters"
|
||||
- 选择运行方式(RUN_TYPE)
|
||||
- 填写相应参数
|
||||
- 点击 "Build"
|
||||
|
||||
### 方式二:自由风格项目配置
|
||||
|
||||
1. **创建自由风格项目**
|
||||
- 新建任务 → 选择 "Freestyle project"
|
||||
- 任务名称:例如 "ZZYY_Test_Automation"
|
||||
|
||||
2. **配置源码管理**
|
||||
- Source Code Management → Git
|
||||
- Repository URL: 你的Git仓库地址
|
||||
- Branch: 分支名称
|
||||
|
||||
3. **配置构建步骤**
|
||||
- Build → Add build step → Execute shell(Linux/Mac)或 Execute Windows batch command(Windows)
|
||||
- 命令示例:
|
||||
```bash
|
||||
# Linux/Mac
|
||||
cd ${WORKSPACE}
|
||||
python zhyy/test_case/run_tests.py --all --no-report
|
||||
```
|
||||
```batch
|
||||
# Windows
|
||||
cd %WORKSPACE%
|
||||
python zhyy\test_case\run_tests.py --all --no-report
|
||||
```
|
||||
|
||||
4. **配置Allure报告**
|
||||
- Post-build Actions → Add post-build action → Allure Report
|
||||
- Results path: `zhyy/test_case/reports/allure-results`
|
||||
- Report path: `zhyy/test_case/reports/allure-report`(可选)
|
||||
- 保存
|
||||
|
||||
5. **配置参数化构建(可选)**
|
||||
- This project is parameterized → Add Parameter
|
||||
- 添加Choice Parameter:
|
||||
- Name: `RUN_TYPE`
|
||||
- Choices: `all`, `feature`, `story`, `dir`, `file`, `keyword`, `marker`
|
||||
- 添加String Parameter(根据需要):
|
||||
- `FEATURE_NAME`, `STORY_NAME`, `DIR_PATH`, `FILE_PATH`, `KEYWORD`, `MARKER`
|
||||
|
||||
6. **修改构建命令以使用参数**
|
||||
```bash
|
||||
# Linux/Mac
|
||||
cd ${WORKSPACE}
|
||||
if [ "${RUN_TYPE}" = "all" ]; then
|
||||
python zhyy/test_case/run_tests.py --all --no-report
|
||||
elif [ "${RUN_TYPE}" = "feature" ]; then
|
||||
python zhyy/test_case/run_tests.py --feature "${FEATURE_NAME}" --no-report
|
||||
elif [ "${RUN_TYPE}" = "dir" ]; then
|
||||
python zhyy/test_case/run_tests.py --dir "${DIR_PATH}" --no-report
|
||||
# ... 其他条件
|
||||
fi
|
||||
```
|
||||
|
||||
## Allure插件配置
|
||||
|
||||
### 全局工具配置
|
||||
|
||||
1. **配置Allure命令行工具路径**
|
||||
- Manage Jenkins → Global Tool Configuration
|
||||
- Allure Commandline → Add Allure Commandline
|
||||
- Name: `Allure`(或自定义名称)
|
||||
- Installation directory: Allure安装路径(如:`C:\allure\bin` 或 `/usr/local/allure/bin`)
|
||||
- 保存
|
||||
|
||||
### 项目配置
|
||||
|
||||
1. **在项目配置中添加Allure报告**
|
||||
- Post-build Actions → Allure Report
|
||||
- Results path: `zhyy/test_case/reports/allure-results`
|
||||
- 勾选 "Keep allure results history"
|
||||
|
||||
## 环境变量配置
|
||||
|
||||
### Jenkins全局环境变量
|
||||
|
||||
1. **配置Python路径(如需要)**
|
||||
- Manage Jenkins → Configure System → Global properties
|
||||
- Environment variables → Add
|
||||
- Name: `PYTHONPATH`
|
||||
- Value: `${WORKSPACE}`
|
||||
|
||||
### 项目环境变量
|
||||
|
||||
在Pipeline或构建脚本中设置:
|
||||
```groovy
|
||||
environment {
|
||||
PYTHONPATH = "${WORKSPACE}"
|
||||
ALLURE_RESULTS = "${WORKSPACE}/zhyy/test_case/reports/allure-results"
|
||||
}
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 运行所有测试
|
||||
```bash
|
||||
python zhyy/test_case/run_tests.py --all --no-report
|
||||
```
|
||||
|
||||
### 按目录运行
|
||||
```bash
|
||||
python zhyy/test_case/run_tests.py --dir "接口/SZPurchase" --no-report
|
||||
```
|
||||
|
||||
### 按Feature标签运行
|
||||
```bash
|
||||
python zhyy/test_case/run_tests.py --feature "深圳采购工作台采购订单页面" --no-report
|
||||
```
|
||||
|
||||
## 报告查看
|
||||
|
||||
1. **在Jenkins中查看**
|
||||
- 构建完成后,在项目页面左侧菜单会出现 "Allure Report" 链接
|
||||
- 点击即可查看详细的测试报告
|
||||
|
||||
2. **报告内容**
|
||||
- 测试用例执行情况
|
||||
- 通过/失败统计
|
||||
- 执行时间
|
||||
- 测试步骤详情
|
||||
- 截图和日志(如果配置了)
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1. Allure命令未找到
|
||||
- 确保Allure已安装并添加到PATH
|
||||
- 或在Jenkins全局工具配置中指定Allure路径
|
||||
|
||||
### 2. 模块导入错误
|
||||
- 检查PYTHONPATH环境变量
|
||||
- 确保项目根目录在Python路径中
|
||||
|
||||
### 3. 报告未生成
|
||||
- 检查allure-results目录是否存在且包含数据
|
||||
- 检查Jenkins Allure插件配置的路径是否正确
|
||||
|
||||
### 4. 权限问题
|
||||
- 确保Jenkins有权限访问工作空间目录
|
||||
- 确保有权限执行Python和Allure命令
|
||||
|
||||
## 邮件通知配置(可选)
|
||||
|
||||
在Post-build Actions中添加:
|
||||
- Email Notification
|
||||
- 配置收件人、主题等
|
||||
- 可以附加Allure报告链接
|
||||
|
||||
## 定时构建(可选)
|
||||
|
||||
在项目配置中:
|
||||
- Build Triggers → Build periodically
|
||||
- 例如:`H 2 * * *`(每天凌晨2点执行)
|
||||
|
||||
## 多节点执行(可选)
|
||||
|
||||
如果有多台Jenkins节点:
|
||||
- 在Pipeline中配置 `agent { label 'your-node-label' }`
|
||||
- 或在自由风格项目中配置 "Restrict where this project can be run"
|
||||
175
zhyy/test_case/Jenkinsfile
vendored
175
zhyy/test_case/Jenkinsfile
vendored
@@ -1,175 +0,0 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
options {
|
||||
// 保留最近10次构建
|
||||
buildDiscarder(logRotator(numToKeepStr: '10'))
|
||||
// 超时时间60分钟
|
||||
timeout(time: 60, unit: 'MINUTES')
|
||||
}
|
||||
|
||||
environment {
|
||||
// Python路径
|
||||
PYTHONPATH = "${WORKSPACE}"
|
||||
// Allure结果目录
|
||||
ALLURE_RESULTS = "${WORKSPACE}/zhyy/test_case/reports/allure-results"
|
||||
// Allure报告目录
|
||||
ALLURE_REPORT = "${WORKSPACE}/zhyy/test_case/reports/allure-report"
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
echo '检出代码...'
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
|
||||
stage('环境准备') {
|
||||
steps {
|
||||
echo '准备测试环境...'
|
||||
script {
|
||||
// 确保Python环境
|
||||
sh '''
|
||||
python --version
|
||||
pip --version
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('运行测试') {
|
||||
steps {
|
||||
echo '执行测试用例...'
|
||||
script {
|
||||
// 根据参数选择运行方式
|
||||
def runType = params.RUN_TYPE ?: 'all'
|
||||
def testCommand = ''
|
||||
|
||||
switch(runType) {
|
||||
case 'all':
|
||||
testCommand = 'python zhyy/test_case/run_tests.py --all --no-report'
|
||||
break
|
||||
case 'feature':
|
||||
def feature = params.FEATURE_NAME ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --feature \"${feature}\" --no-report"
|
||||
break
|
||||
case 'story':
|
||||
def story = params.STORY_NAME ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --story \"${story}\" --no-report"
|
||||
break
|
||||
case 'dir':
|
||||
def dir = params.DIR_PATH ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --dir \"${dir}\" --no-report"
|
||||
break
|
||||
case 'file':
|
||||
def file = params.FILE_PATH ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --file \"${file}\" --no-report"
|
||||
break
|
||||
case 'keyword':
|
||||
def keyword = params.KEYWORD ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --keyword \"${keyword}\" --no-report"
|
||||
break
|
||||
case 'marker':
|
||||
def marker = params.MARKER ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --marker \"${marker}\" --no-report"
|
||||
break
|
||||
default:
|
||||
testCommand = 'python zhyy/test_case/run_tests.py --all --no-report'
|
||||
}
|
||||
|
||||
sh """
|
||||
cd ${WORKSPACE}
|
||||
${testCommand}
|
||||
"""
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
// 无论成功失败都收集测试结果
|
||||
echo '收集测试结果...'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('生成Allure报告') {
|
||||
steps {
|
||||
echo '生成Allure报告...'
|
||||
script {
|
||||
sh """
|
||||
cd ${WORKSPACE}
|
||||
allure generate ${ALLURE_RESULTS} -o ${ALLURE_REPORT} --clean || echo "Allure报告生成失败,但继续执行"
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
// 发布Allure报告
|
||||
allure([
|
||||
includeProperties: false,
|
||||
jdk: '',
|
||||
properties: [],
|
||||
reportBuildPolicy: 'ALWAYS',
|
||||
results: [[path: 'zhyy/test_case/reports/allure-results']]
|
||||
])
|
||||
|
||||
// 清理工作空间(可选)
|
||||
// cleanWs()
|
||||
}
|
||||
success {
|
||||
echo '✓ 测试执行成功'
|
||||
// 可以在这里添加成功通知,如发送邮件、钉钉等
|
||||
}
|
||||
failure {
|
||||
echo '✗ 测试执行失败'
|
||||
// 可以在这里添加失败通知
|
||||
}
|
||||
unstable {
|
||||
echo '⚠ 测试执行不稳定'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 参数化构建
|
||||
properties([
|
||||
parameters([
|
||||
choice(
|
||||
name: 'RUN_TYPE',
|
||||
choices: ['all', 'feature', 'story', 'dir', 'file', 'keyword', 'marker'],
|
||||
description: '选择运行方式'
|
||||
),
|
||||
string(
|
||||
name: 'FEATURE_NAME',
|
||||
defaultValue: '',
|
||||
description: 'Feature标签名称(当RUN_TYPE=feature时使用)'
|
||||
),
|
||||
string(
|
||||
name: 'STORY_NAME',
|
||||
defaultValue: '',
|
||||
description: 'Story标签名称(当RUN_TYPE=story时使用)'
|
||||
),
|
||||
string(
|
||||
name: 'DIR_PATH',
|
||||
defaultValue: '接口/SZPurchase',
|
||||
description: '测试目录路径(当RUN_TYPE=dir时使用,相对于TestCase目录)'
|
||||
),
|
||||
string(
|
||||
name: 'FILE_PATH',
|
||||
defaultValue: '接口/SZPurchase/PurchaseOrderManage.py',
|
||||
description: '测试文件路径(当RUN_TYPE=file时使用,相对于TestCase目录)'
|
||||
),
|
||||
string(
|
||||
name: 'KEYWORD',
|
||||
defaultValue: 'purchase',
|
||||
description: '关键字(当RUN_TYPE=keyword时使用)'
|
||||
),
|
||||
string(
|
||||
name: 'MARKER',
|
||||
defaultValue: 'smoke',
|
||||
description: 'Pytest标记(当RUN_TYPE=marker时使用)'
|
||||
)
|
||||
])
|
||||
])
|
||||
@@ -1,84 +0,0 @@
|
||||
# Jenkins + Allure 集成快速参考
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 安装Allure插件
|
||||
- Jenkins → Manage Jenkins → Manage Plugins
|
||||
- 搜索 "Allure Plugin" 并安装
|
||||
|
||||
### 2. 配置Allure工具
|
||||
- Manage Jenkins → Global Tool Configuration
|
||||
- Allure Commandline → 添加Allure安装路径
|
||||
|
||||
### 3. 创建Jenkins任务
|
||||
|
||||
#### 方式A:使用Jenkinsfile(推荐)
|
||||
1. 新建Pipeline任务
|
||||
2. Pipeline script from SCM
|
||||
3. Script Path: `zhyy/test_case/Jenkinsfile`
|
||||
4. 保存并运行
|
||||
|
||||
#### 方式B:自由风格项目
|
||||
1. 新建Freestyle project
|
||||
2. 构建步骤:执行 `jenkins_build.sh` 或 `jenkins_build.bat`
|
||||
3. Post-build Actions → Allure Report
|
||||
4. Results path: `zhyy/test_case/reports/allure-results`
|
||||
|
||||
## 参数化构建
|
||||
|
||||
在Jenkins任务中配置以下参数:
|
||||
|
||||
| 参数名 | 类型 | 说明 | 示例值 |
|
||||
|--------|------|------|--------|
|
||||
| RUN_TYPE | Choice | 运行方式 | all, feature, story, dir, file, keyword, marker |
|
||||
| FEATURE_NAME | String | Feature标签 | 深圳采购工作台采购订单页面 |
|
||||
| STORY_NAME | String | Story标签 | 验证采购工作台采购订单页面列表查询 |
|
||||
| DIR_PATH | String | 目录路径 | 接口/SZPurchase |
|
||||
| FILE_PATH | String | 文件路径 | 接口/SZPurchase/PurchaseOrderManage.py |
|
||||
| KEYWORD | String | 关键字 | purchase |
|
||||
| MARKER | String | Pytest标记 | smoke |
|
||||
|
||||
## 常用命令
|
||||
|
||||
### 本地运行
|
||||
```bash
|
||||
# 运行所有测试
|
||||
python run_tests.py
|
||||
|
||||
# 按目录运行
|
||||
python run_tests.py --dir "接口/SZPurchase"
|
||||
|
||||
# 按文件运行
|
||||
python run_tests.py --file "接口/SZPurchase/PurchaseOrderManage.py"
|
||||
|
||||
# 生成并打开报告
|
||||
python run_tests.py --all --report --open
|
||||
```
|
||||
|
||||
### Jenkins中运行
|
||||
```bash
|
||||
# 使用构建脚本(自动检测参数)
|
||||
bash jenkins_build.sh
|
||||
|
||||
# 或直接使用run_tests.py
|
||||
python run_tests.py --all --no-report
|
||||
```
|
||||
|
||||
## Allure报告路径
|
||||
|
||||
- **结果目录**: `zhyy/test_case/reports/allure-results`
|
||||
- **报告目录**: `zhyy/test_case/reports/allure-report`
|
||||
- **Jenkins中查看**: 构建完成后点击左侧 "Allure Report" 链接
|
||||
|
||||
## 环境变量
|
||||
|
||||
Jenkins会自动设置以下环境变量:
|
||||
- `WORKSPACE`: Jenkins工作空间路径
|
||||
- `BUILD_NUMBER`: 构建编号
|
||||
- `JENKINS_URL`: Jenkins服务器地址
|
||||
|
||||
`run_tests.py` 会自动检测Jenkins环境并调整路径。
|
||||
|
||||
## 详细文档
|
||||
|
||||
更多配置说明请参考:`JENKINS_SETUP.md`
|
||||
@@ -1,96 +0,0 @@
|
||||
# 测试执行说明
|
||||
|
||||
## 统一测试执行工具
|
||||
|
||||
使用 `run_tests.py` 可以方便地执行各种测试用例。
|
||||
|
||||
## 安装依赖
|
||||
|
||||
```bash
|
||||
pip install pytest
|
||||
pip install pytest-allure-adaptor # 或 allure-pytest
|
||||
pip install allure-python-commons
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 运行所有测试用例
|
||||
|
||||
```bash
|
||||
python run_tests.py --all
|
||||
```
|
||||
|
||||
### 2. 按 Allure Feature 标签运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --feature "深圳采购工作台采购订单页面"
|
||||
```
|
||||
|
||||
### 3. 按 Allure Story 标签运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --story "验证采购工作台采购订单页面列表查询"
|
||||
```
|
||||
|
||||
### 4. 按目录运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --dir "接口/SZPurchase"
|
||||
```
|
||||
|
||||
### 5. 按文件运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --file "接口/SZPurchase/PurchaseOrderManage.py"
|
||||
```
|
||||
|
||||
### 6. 按关键字运行(匹配文件名或类名)
|
||||
|
||||
```bash
|
||||
python run_tests.py --keyword "purchase"
|
||||
```
|
||||
|
||||
### 7. 按 pytest 标记运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --marker "smoke"
|
||||
```
|
||||
|
||||
### 8. 生成并打开 Allure 报告
|
||||
|
||||
```bash
|
||||
python run_tests.py --all --report --open
|
||||
```
|
||||
|
||||
## 快捷方式(Windows)
|
||||
|
||||
- `run_all.bat` - 运行所有测试用例
|
||||
- `run_purchase.bat` - 运行采购相关测试用例
|
||||
|
||||
## 参数说明
|
||||
|
||||
- `--all`: 运行所有测试用例
|
||||
- `--feature <name>`: 按allure feature标签运行
|
||||
- `--story <name>`: 按allure story标签运行
|
||||
- `--dir <path>`: 按目录运行(相对于TestCase目录)
|
||||
- `--file <path>`: 按文件运行(相对于TestCase目录)
|
||||
- `--keyword <keyword>`: 按关键字运行
|
||||
- `--marker <marker>`: 按pytest标记运行
|
||||
- `--report`: 生成Allure报告
|
||||
- `--open`: 打开Allure报告
|
||||
- `--no-report`: 不生成Allure报告
|
||||
|
||||
## 报告位置
|
||||
|
||||
- Allure结果: `reports/allure-results/`
|
||||
- Allure报告: `reports/allure-report/`
|
||||
|
||||
## 查看报告
|
||||
|
||||
生成报告后,可以使用以下命令打开:
|
||||
|
||||
```bash
|
||||
allure open reports/allure-report
|
||||
```
|
||||
|
||||
或者直接使用 `--open` 参数自动打开。
|
||||
@@ -1,9 +0,0 @@
|
||||
*** Settings ***
|
||||
*** Variables ***
|
||||
|
||||
${parent_phone_1} 13400234900 # 增长业务使用(陈江)(陈洁-login、留资等也在使用),逻辑思维用户
|
||||
${parentphone_customerId_1} 6022462 #用户 13400234900逻辑思维线索id
|
||||
${parent_phone_2} 12030990019 #张楠 course_package.robot(陈洁-login、留资等也在使用),中文素养用户
|
||||
${parent_phone_3} 13400234902 # 海报任务专用
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,75 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import allure
|
||||
import logging
|
||||
|
||||
from zhyy.library.BusinessKw.SZPurchase.PurchaseOrderManage import PurchaseOrder
|
||||
|
||||
|
||||
@allure.feature('深圳采购工作台采购订单页面')
|
||||
class Test_purchase_order(object):
|
||||
test_case = PurchaseOrder()
|
||||
|
||||
def teardown_method(self):
|
||||
logging.info("-----------------------------End-------------------------------")
|
||||
|
||||
@allure.story("验证采购工作台采购订单页面列表查询")
|
||||
def test_check_purchase_order_page(self):
|
||||
purchase_order_code = 'PO251209048' # 采购单号 必填
|
||||
supplier_company_ids = ['334'] # 供应商id 非必填
|
||||
payment_status = '0' # 付款状态 非必填
|
||||
status = '0' # 采购单状态 非必填
|
||||
page_no = 1 # 页码 必填
|
||||
page_size = 10 # 每页条数 必填
|
||||
response_data = self.test_case.kw_zhyy_get_purchase_page_post(
|
||||
note="采购工作台采购订单页面列表查询",
|
||||
user='purchase',
|
||||
order_sn=purchase_order_code,
|
||||
supplier_company_ids=supplier_company_ids,
|
||||
payment_status=payment_status,
|
||||
status=status,
|
||||
page_no=page_no,
|
||||
page_size=page_size
|
||||
)
|
||||
|
||||
# 断言检查
|
||||
assert response_data is not None, "响应数据不能为空"
|
||||
assert 'code' in response_data, "响应数据中缺少code字段"
|
||||
assert response_data['code'] == 0, "接口调用失败,code: {}, msg: {}".format(
|
||||
response_data.get('code'), response_data.get('msg', '未知错误'))
|
||||
assert 'data' in response_data, "响应数据中缺少data字段"
|
||||
assert response_data['data'] is not None, "响应数据中的data字段不能为空"
|
||||
|
||||
# 如果传入了采购单号,检查返回的数据中是否包含该采购单号
|
||||
if purchase_order_code:
|
||||
data = response_data.get('data', {})
|
||||
order_found = False
|
||||
|
||||
# 检查返回的数据结构,可能包含列表或其他结构
|
||||
if isinstance(data, dict):
|
||||
# 如果data是字典,可能包含records、list、data等字段
|
||||
records = data.get('records') or data.get('list') or data.get('data') or []
|
||||
if isinstance(records, list) and len(records) > 0:
|
||||
# 检查列表中是否包含指定的采购单号
|
||||
for item in records:
|
||||
if isinstance(item, dict):
|
||||
order_sn = item.get('order_sn') or item.get('orderSn') or item.get('orderSn')
|
||||
if order_sn == purchase_order_code:
|
||||
order_found = True
|
||||
break
|
||||
elif isinstance(data, list):
|
||||
# 如果data本身就是列表
|
||||
for item in data:
|
||||
if isinstance(item, dict):
|
||||
order_sn = item.get('order_sn') or item.get('orderSn') or item.get('orderSn')
|
||||
if order_sn == purchase_order_code:
|
||||
order_found = True
|
||||
break
|
||||
|
||||
if order_found:
|
||||
logging.info("✓ 断言通过:返回的数据中包含采购单号 {}".format(purchase_order_code))
|
||||
else:
|
||||
logging.warning("⚠ 警告:返回的数据中未找到采购单号: {},但接口调用成功".format(purchase_order_code))
|
||||
|
||||
logging.info("✓ 所有断言检查通过")
|
||||
print("✓ 查询成功,响应数据: {}".format(response_data))
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,19 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import allure
|
||||
import logging
|
||||
|
||||
from zhyy.library.BusinessKw.SZPurchase.index import PurchaseIndex
|
||||
|
||||
|
||||
@allure.feature('深圳采购工作台首页')
|
||||
class Test_purchase_index(object):
|
||||
# config = ReadConfig.ReadConfig() # 调用读取配置文件的方法类
|
||||
test_case = PurchaseIndex()
|
||||
|
||||
def teardown_method(self):
|
||||
logging.info("-----------------------------End-------------------------------")
|
||||
|
||||
@allure.story("验证采购工作台待办任务与在办任务功能")
|
||||
def test_check_todo(self):
|
||||
get_purchase_data = self.test_case.kw_zhyy_get_todo(note="采购工作台首页待办任务PO与在办任务PO", user='purchase')
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user