Files
F6--/张阳脚本/boss/boss权限自动审批.py
T
2026-01-30 11:28:35 +08:00

693 lines
34 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from datetime import datetime
import time
from typing import Optional, List, Dict, Any
import requests
import json
import pandas as pd
token = "Bearer qygHulymo1fekJk4CIZyNKjyQAzG8CFN"
class API:
def entry_data_list(self, data: dict, replace: bool = False, max_retries: int = 20) -> Dict: # 获取多条表单数据
"""
获取多条表单数据
:param max_retries: 最大重试次数
:param replace: 是否替换字段
:param data:
api_key: 应用id
entry_id: 表单id
:return:
"""
url = 'https://api.jiandaoyun.com/api/v5/app/entry/data/list'
headers = {
'Authorization': token, # 曹伟应用api测试 app_key
'Content-Type': 'application/json'
}
all_data_batches = [] # 用于存储每次请求返回的数据批次
last_data_id = None
exit_flag = False
while True:
payload = json.dumps({
"app_id": data['api_key'], # 应用ID
"entry_id": data['entry_id'], # 表单ID
"filter": data.get('filter', {}),
"limit": 100,
"data_id": last_data_id
})
retries = 0
while retries <= max_retries:
try:
res = requests.post(url=url, data=payload, headers=headers, timeout=10)
res.raise_for_status() # 检查HTTP响应状态码,如果不等于200会抛出异常
data_get = res.json()
if data_get["data"]:
all_data_batches.extend(data_get['data'])
last_data_id = data_get['data'][-1].get('_id')
break # 成功则跳出循环
else:
if 'data' not in data_get or len(data_get['data']) == 0:
exit_flag = True
break
retries += 1
time.sleep(0.1) # 在重试之间稍作停顿
except requests.exceptions.RequestException as e:
retries += 1
time.sleep(0.1) # 在重试之间稍作停顿
if retries > max_retries:
all_data_batches.append(None) # 或者可以选择记录失败的payload以便后续处理
if exit_flag:
break
# 构建最终返回的字典
final_data = {
'data': all_data_batches # 'data' 键对应的值是列表的列表
}
return final_data
@staticmethod
def workflow_instance_get(data: dict, max_retries: int = 20) -> dict:
"""
查询实例流程信息
:param max_retries:
:param data: 简道云插件发送过来的data,包含应用id
:return: 查询简道云流程实例信息返回的结果
"""
url = 'https://api.jiandaoyun.com/api/v5/workflow/instance/get'
headers = {
'Authorization': token, # 曹伟应用api测试 appKey
'Content-Type': 'application/json'
}
payload = json.dumps({
"instance_id": data['data_id'],
"tasks_type": 1
}
)
data_get = None
retries = 0
while retries <= max_retries:
try:
res = requests.post(url=url, data=payload, headers=headers, timeout=10)
res.raise_for_status() # 检查HTTP响应状态码,如果不等于200会抛出异常
data_get = res.json()
# print( "返回结果:", data_get)
if res.status_code == 200:
break # 成功则跳出循环
else:
retries += 1
time.sleep(3) # 在重试之间稍作停顿
except requests.exceptions.RequestException as e:
retries += 1
time.sleep(0.1) # 在重试之间稍作停顿
if retries > max_retries:
break
return data_get
@staticmethod
def workflow_task_approve(data: dict) -> dict:
"""
流程待办提交
:param data:应包含username、instance_id(data_id)、task_id等信息
:return:返回简道云流程待办提交的结果
"""
url = 'https://api.jiandaoyun.com/api/v1/workflow/task/approve'
headers = {
'Authorization': token, # 曹伟应用api测试 appKey
'Content-Type': 'application/json'
}
payload = json.dumps({
"username": data["username"],
"instance_id": data["instance_id"],
"task_id": data['task_id'],
"comment": ""
}
)
res = requests.post(url=url, data=payload, headers=headers, timeout=10)
return res.json()
@staticmethod
def data_batch_create(data: dict, max_retries: int = 5) -> Optional[requests.Response]: # 新建单条数据
"""
新建单条表单数据
:param max_retries: 最大重试次数
:param data: 应该包含应用id、表单id,以及新建的数据data['data']
:return: 返回创建后简道云返回的信息
"""
url = 'https://api.jiandaoyun.com/api/v5/app/entry/data/create'
headers = {
'Authorization': token, # 曹伟应用api测试 app_key
'Content-Type': 'application/json'
}
"""
data 样式 # 后续优化发送数据样式 目前输入字段,后续优化输入表单名称
jiandaoyun_data['data'] = {"_widget_1731650067055":{"value":f'{username}{password}'},
"_widget_1731650067056":{"value": f"{group}"}}
"""
# noinspection DuplicatedCode
payload = json.dumps({
"app_id": data['api_key'], # 应用ID
"entry_id": data['entry_id'], # 表单ID
"data": data['data'],
"is_start_workflow": data.get('is_start_workflow', "false"),
"is_start_trigger": data.get('is_start_trigger', "false"),
"transaction_id": data.get('transaction_id', "")
}
)
retries = 0
while retries <= max_retries:
try:
res: requests.Response = requests.post(url=url, data=payload, headers=headers, timeout=10)
res.raise_for_status() # 检查HTTP响应状态码,如果不等于200会抛出异常
data_get = res.json()
if res.status_code == 200:
return data_get
else:
retries += 1
time.sleep(3) # 在重试之间稍作停顿
except requests.exceptions.RequestException as e:
retries += 1
time.sleep(3) # 在重试之间稍作停顿
if retries > max_retries:
print(
f"任务 {data['data_list']} 连续{max_retries}次请求失败,放弃此次请求。")
return None
@staticmethod
def entry_data_update(data: dict, max_retries: int = 20) -> dict: # 修改数据
"""
修改数据
:param max_retries: 最大重试次数,此处设置100次
:param data: 简道云插件发送过来的data,包含应用id、表单id、数据id等信息
:return: 修改数据后简道云返回的结果
"""
url = 'https://api.jiandaoyun.com/api/v5/app/entry/data/update'
headers = {
'Authorization': token, # 曹伟应用api测试 appKey
'Content-Type': 'application/json'
}
payload = json.dumps({
"app_id": data['api_key'], # 应用ID
"entry_id": data['entry_id'], # 表单ID
"data_id": data['data_id'], # 数据ID
"data": data['data']
}
)
data_get = None
retries = 0
while retries <= max_retries:
try:
res: requests.Response = requests.post(url=url, data=payload, headers=headers, timeout=10)
res.raise_for_status() # 检查HTTP响应状态码,如果不等于200会抛出异常
data_get = res.json()
# print("返回结果:", data_get)
# print(res.status_code)
if res.status_code == 200:
break # 成功则跳出循环
else:
retries += 1
time.sleep(1) # 在重试之间稍作停顿
except requests.exceptions.RequestException as e:
retries += 1
time.sleep(2) # 在重试之间稍作停顿
if retries > max_retries:
print(f"任务 {data['data_id']} 连续{max_retries}次请求失败,放弃此次请求。")
continue
return data_get
class BossPermissionAutoApproval:
"""
Boss权限自动审批
"""
def __init__(self):
self.boss_perm_switch_data = None
self.task_data = None
self.boss_switch_fields_map = {
"权限功能": "_widget_1757483372023",
"一级分类": "_widget_1757554068594",
"二级分类": "_widget_1757553855187",
"权限": "_widget_1757483372025",
"权限开关": "_widget_1757483372026",
}
self.task_data_map = {
"当日新签开户": "_widget_1754896018130",
"新开户门店名": "_widget_1754896018132",
"新开户门店编码": "_widget_1754896018133",
"关联数据": "_widget_1751522231978",
"公司名": "_widget_1751521185014",
"门店名": "_widget_1751521185015",
"门店编码": "_widget_1751521185016",
"分类": "_widget_1751521319795",
"权限功能": "_widget_1751521319796",
"申请理由": "_widget_1751599915625",
"处理人": "_widget_1751521319797",
"提交人": "_widget_1751596512100",
"需开项目-图片": "_widget_1751521386658",
"需开项目-说明": "_widget_1751600131107",
"是否开通": "_widget_1751522755921",
"拒绝原因": "_widget_1754895638981",
"完成时间": "_widget_1751521573695",
"是否新功能": "_widget_1755137980288",
"流水号": "_widget_1751596707486",
}
def load_data(self):
self.task_data = API().entry_data_list(data={
"api_key": "675b900991ad2491c69389ca", # 应用ID
"entry_id": "6866179f6a73c0d879208bcc", # 表单ID
"filter": {
"rel": "and",
"cond": [{"field": "flowState", "type": "flowstate", "method": "eq", "value": 0}]
}
}).get("data") # 获取最新权限列表
self.boss_perm_switch_data = API().entry_data_list(data={
"api_key": "675b900991ad2491c69389ca", # 应用ID
"entry_id": "68c1116b51730ebbc690ae40" # 表单ID
}).get("data") # 权限对应功能
self.get_cookies = API().entry_data_list(data={
"api_key": "675b900991ad2491c69389ca", # 应用ID
"entry_id": "68c237d565832158571e4ff4"
}).get("data")
def map_switch_data(self):
"""
映射功能开关
:return: df
"""
df = pd.DataFrame(self.task_data)
reverse_map = {v: k for k, v in self.task_data_map.items()}
df = df.rename(columns=reverse_map)
# df.to_csv(fr"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\门店开通权限.csv", index=False)
df1 = pd.DataFrame(self.boss_perm_switch_data)
boss_switch_reverse_map = {v: k for k, v in self.boss_switch_fields_map.items()}
df1 = df1.rename(columns=boss_switch_reverse_map)
# df1.to_csv(fr"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\Boss权限对应功能.csv", index=False)
all_data = []
# 获取门店编码与权限功能,并匹配对应的多条功能数据
for index, row in df.iterrows():
# 过滤出 审批节点 的数据
data_id = row["_id"]
get_task_id = API().workflow_instance_get({"data_id": data_id})
flow_name = get_task_id.get("tasks")[-1].get("flow_name")
if flow_name != "审批节点":
continue
# 确定门店编码
org_code = row["新开户门店编码"] if row["当日新签开户"] == "" else row["门店编码"]
# 获取当前行的权限功能
perm_functions = row["权限功能"]
# 获取任务的数据id
data_id = row["_id"]
# 在df1中查找匹配的所有功能
matched_functions = df1[df1['权限功能'] == perm_functions] # 假设df1中有'权限功能'列
# 如果没有匹配项,至少添加权限功能本身
if matched_functions.empty:
all_data.append({
"数据id": data_id,
"门店编码": org_code,
"权限功能": perm_functions,
"一级分类": None # 或者可以设为perm本身
})
else:
# 添加所有匹配的功能
for _, func_row in matched_functions.iterrows():
all_data.append({
"数据id": data_id,
"门店编码": org_code,
"权限功能": perm_functions,
"一级分类": func_row["一级分类"],
"二级分类": func_row["二级分类"],
"权限": func_row["权限"],
"开关": func_row["权限开关"]
})
# 如果你想要将这些数据也保存为CSV
result_df = pd.DataFrame(all_data)
# result_df.to_csv(fr"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\门店权限功能映射.csv", index=False)
return result_df
def get_company_id(self, df):
"""
获取公司id
:param df: 含门店编码的df
:return: df
"""
unique_codes = df["门店编码"].unique().tolist()
# 初始化存储结果的字典
code_to_company_id = {}
cookie_str = self.get_cookies[0].get("_widget_1757558743223")
print(cookie_str)
cookies = {}
items = cookie_str.split('; ')
for item in items:
if '=' in item:
key, value = item.split('=', 1)
cookies[key.strip()] = value.strip()
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'content-type': 'application/json;charset=UTF-8',
'origin': 'https://manage.f6yc.com',
'priority': 'u=1, i',
'referer': 'https://manage.f6yc.com/',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Microsoft Edge";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0',
'x-requested-with': 'XMLHttpRequest',
# 'cookie': 'hive-adminSESSIONID=91f4217e-3007-4762-adc5-afc2c4d11bdd; _yg_prod=EkX_f7K7eYt61spccZtpCE7FHwA2I5PROPsPCa8-iC3ASlLYfszIPQQqjcJjPPEZL0J2pO07cfp8VG-4XSfqBfYzvRdjXVIjT2D3fZ_a80KTwgID0oqvVma_W4j_-PTD1I79TjPNGx-FjivcHXdACpJVZSu_NgJB; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%222268275546837446%22%2C%22first_id%22%3A%221989d4783646e1-07c9f1a149173e8-4c657b58-2073600-1989d4783651ade%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%221989d4783646e1-07c9f1a149173e8-4c657b58-2073600-1989d4783651ade%22%7D',
}
for code in unique_codes:
json_data = {
'currentPage': 1,
'pageSize': 10,
'licenseNo': '',
'licenseName': '',
'groupName': '',
'code': code,
'name': '',
'orgId': '',
'busiType': '',
'saasVersion': '',
'saasStatus': '',
'province': '',
'city': '',
'area': '',
'orgStatus': 0,
'orgScale': '',
'mainOrgOnly': 0,
'saasEdition': '',
'storeId': '',
'franchiseGroupId': '',
'minCreateTime': '',
'maxCreateTime': '',
'serviceImplPrincipalList': [],
'containTest': True,
}
try:
response = requests.post(
'https://manage.f6yc.com/hive-admin/org/getAllOrgList',
cookies=cookies,
headers=headers,
json=json_data,
timeout=10
)
response.raise_for_status() # 检查请求是否成功
# 兼容废弃与停用门店
if len(response.json().get("data").get("records",[]))==0:
json_data['orgStatus'] = 1 # 停用
response = requests.post(
'https://manage.f6yc.com/hive-admin/org/getAllOrgList',
cookies=cookies,
headers=headers,
json=json_data,
timeout=10
)
if len(response.json().get("data").get("records",[]))==0:
json_data['orgStatus'] = 2 # 废弃
response = requests.post(
'https://manage.f6yc.com/hive-admin/org/getAllOrgList',
cookies=cookies,
headers=headers,
json=json_data,
timeout=10
)
# 提取company_id并存储到字典
company_id = response.json()['data']['records'][0]['groupId']
code_to_company_id[code] = company_id
print(f"成功查询: 门店编码 {code} -> company_id {company_id}")
except Exception as e:
print(f"查询失败: 门店编码 {code}, 错误: {str(e)}")
code_to_company_id[code] = None # 失败时存储None
df['company_id'] = df['门店编码'].map(code_to_company_id)
# df.to_csv(fr"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\门店含id权限功能映射.csv", index=False)
return df
def update_permission(self, df):
cookie_str = self.get_cookies[0].get("_widget_1757558743223")
cookies = {}
items = cookie_str.split('; ')
for item in items:
if '=' in item:
key, value = item.split('=', 1)
cookies[key.strip()] = value.strip()
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'priority': 'u=1, i',
'referer': 'https://manage.f6yc.com/',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Microsoft Edge";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0',
'x-requested-with': 'XMLHttpRequest',
# 'cookie': 'hive-adminSESSIONID=531d2ecb-893b-471c-8cf9-e76a9dcfa789; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%221989d4783646e1-07c9f1a149173e8-4c657b58-2073600-1989d4783651ade%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%221989d4783646e1-07c9f1a149173e8-4c657b58-2073600-1989d4783651ade%22%7D; _yg_prod=EkX_f7K7eYt61spccZtpCE7FGQAxK5DfP_4PB6A0jCrCT1LYfszIPQQqjcJjPPEZL0J2pO07cfp8VG-4XSfqBfYzvRdjXVIjT2D3fZ7X80GeyA8J24qvVma_W4j__vTE3I3zSTbNFRCPiizeGHdACpZXbli5aTRA; _oauth2_proxy=GdOm_1P1BJAoCcjMngUI40McDBpFqkL2vO_GTniJq-QGX6z9l3MieVkOjJJVJiDbEh5U-j6h3SmxsEjWuaOlfsJyWPx6muVdQOPavFTnd8TCr5-0Hz5xYOQncD1IqIGILgkejOJ3127iUvvu--dYjyqKiDwbtEGCN-Gb21Ik6hkb61C4OBppUra1XbJQ7kOXJnZdlBMe8FiMnlkYVOL8zJ1ZDLIzUcsyzq2s1ACRdVZFT8WU7JLhXKRvoiQSSm6qkCYPsuxGLudtHMeJibtvT8IGNp-jdvv8SF5gzomGhd1Abt_4YfCjiGznNbu421biQI866hEiPTjAZPai0EC-5E0VOi8NmfrBIxaqWx4ecIEGM6Z_8G-4ZWJVBNIv3v9AfUPANYR37yC-w8rOYYv9X2FV0YMkGqFoOKJWBnw4JbdxtdI-8UodAIQGUYVeJGLt6zOWWRNdzKeK57Z8X3Aki0CmLaP0SSUjoGW1pMJayMar94eQpzXszBVQxX_-_buXoDtXYg-u5q5jnQrXX3SLXC8W5JNY_sbDWm2ix7H2ezcxp2gypyyPnFMA5gRneE9wcLAWFtkb_YwT3Q_1KD4rUltqNBBV85KCOR77lxGXMYSEANPvJRW8mC9jg9ARD0JyvA1ZHWefjNU_Y_6RsKSiHrH5Cg5k8QU8skF-KgQrFUKGVfjWfpRfDO6IpR_z2lD-6qfwAshliwrFKyqJi1M91bdZuLR1dXubkgSNVXzyKkgjnGZ-4Ma9K8M3iLQwgBE1DoCRv92C-ie7sI3MmJ58vwu3OllkcOkiz7NjYzv1LKIIKTVEU7wgGe0SGKuEoRO2vRBOZcw_NUUW6s9SbwKleCXdsHkth2EFigiF9E7CGGdyw2G5qO1nx5nKIgEhhqPEBs6yq1uPEcza_BT_J5BauG_ffjpWrRR8TaoMFrmJFPdOf4JDON6FPukb4sbo_uANPG3tSpwNiefTv0E4QV7jNyNNOeGlhLxhcWyN2E6LZTOWH8lnVNUl6oLbSnrkcDGAV9Q76nebHhn5Yf6qJY4S1CceJwFlpIlooiz1bUWzt906c1UUcrFgxEydHMKbmScaG2S_dSjvfB76ZFgozWIGQiiZnd1bt8G7pc2VxMVW-szebBoeUf0HzPpzkej-ILRunt-E9Mpq-3afCOtbda0RfZWqR8cQsAt-cABPIdi4WT5v-Cg_jrjxBb8mueXbWZ5Q4gNPjsVmkfnpW5svBf8bKdChTbNyq_KOm2NV9itI6RSAVkIo6ANUBe9npnCs66v6hSQmmqjqbZ3H4GX1HiyT6VlFpTxT1xDry3tZsTZqw9lzvnT7Tin1lIxArQc0LnlZAoVbbLDJJlbfrXXcIF1kcClfXw5d_Smy_tfGOo5kYE9iTmfMOMh-8ZfhhjA43P4kMgSrYdQAvW1fHFMVQtqtHTmUiCSsKQ78Phh3-ampoI83iJooVzH34Yg21cv5wHpAJAn_wVC_Weto-bol3XXZkDHG0DWmoMGROViNkxc0vKxpMubwiG36E-U-1tQXsyhqqa6VqE_Vnn3fizk9m-ZgozyN-VlS5ALV6djm1wa-ISaLv9juHjQlfA0joY6ZLOxM6mcGsZliw9ZQ-mhiy1C9c3vOuPLW3ZWRCeJUX96BaA-5am-3Z3bjK1mp391cXle3idTEPFlMCKNVUUANNFwxeH0W6CKL4rcRkgiEnhWuBEADySvpfCFuYxojH2uOSfS8mCERpZ7KNEgPCIVs9VumX68w8QonxClCQLWG6JRAmfmCfYKi6UeeWWvsqQDPqQiMkowThSv_TmLgFh5baZsB9bJwFqojc6pOzM3ogHuHuY_67VsA8E_cmeeWvBzqWBV9umeciWq5fbC3Cqe_fAsHxtKb39D2vQyqWVjRk9qukzxBmcd8bXzKUV1r6lg0QgVm2PG8dyfAV_ymsR6Y4b_gtPWcVx83J5H8RgN43ofGXwdUFsqi5xnc_Bf-KO_psGgYImKnqU25ftV8eX0ss0K7jsyhafsWDwPSg2k7qHPNK2AbtLGZIQcRcjXe7efTICAeHOn9AJ4vUbU1UpO53WsY8gic1I7tEH0LKkg7Pz7rR7drDuYkDg200gXiO7y5FXl1dqGa-tilF9IL57hx3UcuM7mLZa5zU0bPprhmCelSA4CwG8la5yGUdpvBqBSz22-X-DgkrwCzLpchi_LnpAkx2_jza2yTO5PtCSjn7hFbvuNFm6Neb_AuRg6-TpolwGfl-Bu3nUySmnCoCH8IvAoA4BpXzFH7o21cAlEHdKAndnoEljtyoyxa6DAZoG5Osttn71tbudyEFh26eOiA-wGAbpHJnsg3Slp35gicLgAepJ8oDFAaqdhtyP7-jizBCCB-Bt29hqvWwH22J30wgoXKnJgjFl6F9L4hxmvRi2QHWKV35ITGA1JqrS0VayT9DIrbTUKoRIKzTme0Z5deBxB8YFmiINAEqdS86PCbQi28-tK2RYuvFJ4O_RWxrMxD1fnDhbPWhnDGiY9dGmDjPgWB70vtIVaikGr_M_Bwm_3oa7ec00eTaSnjmX1qzLCLdvX_Ie6hBFgDii7ZU-KrQndqcbLYU9KtkI2yVwXWMihlLzdxNukzuxnU4IK334Mtebpz6ykLX8e8UfvbHJx4D_JgQQKB7Gfoxb-O02owUY6bvR-tgTp8n9-Mic9osDWeBgmmPHmvyNjcWbi4SXdBSVVIML12iS7qvjHlekG01r_EalttUe000hU1MLqE_Kd1XcINRq0vZaed5m6fXEUVcPchVYN9GC7e36HMo7ZlgE0fGNsWY6pFr-seXI2_23UJW9l_edhMqpvJJh5CAJYMRQ-Rtvzfbe8n|1757554489|NPRgqlI6umo48ScNrekwcxSuAvgFZbVOWWnkmHcAJww=',
}
result_list = []
df.to_csv(fr"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\门店含id权限功能映射.csv", index=False)
df.dropna(subset=['开关'], inplace=True)
for index, row in df.iterrows():
print(row)
if row["company_id"] is None:
continue
if row["门店编码"] == "空门店编码" or row["门店编码"] is None:
result_list.append(
{
"数据id": row["数据id"],
"门店编码": row["门店编码"],
"一级分类": row["一级分类"],
"二级分类": row["二级分类"],
"权限": row["权限"],
"开关": row["开关"],
"状态": "空门店编码跳过执行",
}
)
continue
if row["一级分类"] is not None:
params = {
'groupId': row["company_id"],
}
response = requests.get(
'https://manage.f6yc.com/hive-admin/company/role/getGroupAdminRoleMenusScope',
params=params,
cookies=cookies,
headers=headers,
)
# print(response.json())
if response.status_code == 200:
pkId = response.json().get("data").get("role").get("id")
user_name = response.json().get("data").get("role").get("name")
menus_list = response.json().get("data").get("menus")
for menu in menus_list:
if menu.get("name") == row["一级分类"]:
nodes_list = menu.get("nodes")
if row["开关"] == "": # 确保一级权限为开
menu["isChecked"] = 1
for node in nodes_list:
if node.get("name") == row["二级分类"]:
child_nodes_list = node.get("nodes", [])
print(row["二级分类"], row["权限"], row["开关"])
if row["开关"] == "": # 确保二级权限为开
node["isChecked"] = 1
if row["权限"] != "":
# 处理有三级权限的情况
for child_node in child_nodes_list:
if child_node.get("name") == row["权限"]:
if row["开关"] == "":
print("更新权限:", child_node["id"], "为开")
child_node["isChecked"] = 1
else:
child_node["isChecked"] = 0
break # 找到对应的权限后跳出循环
else:
print(row["二级分类"], row["权限"], row["开关"], 11111111111)
# 处理只有二级权限的情况
if row["开关"] == "":
node["isChecked"] = 1
else:
node["isChecked"] = 0
# 同时更新所有子节点的状态
for child_node in child_nodes_list:
child_node["isChecked"] = node["isChecked"]
# 查询isChecked为1的id
checked_ids = []
def collect_checked_ids(items):
for item in items:
if item.get("isChecked") == 1:
checked_ids.append(str(item.get("id")))
if "nodes" in item:
collect_checked_ids(item["nodes"])
collect_checked_ids(menus_list)
checked_ids_str = ",".join(checked_ids)
print(f"更新后选中项的ID: {checked_ids_str}")
new_json_data = {
"pkId": pkId,
"name": user_name,
'isValid': 1,
"menuStr": checked_ids_str,
}
response = requests.post(
'https://manage.f6yc.com/hive-admin/company/role/update',
cookies=cookies,
headers=headers,
json=new_json_data,
)
# print(response.json())
if response.json().get("code", 1000) == 200:
result_list.append(
{
"数据id": row["数据id"],
"门店编码": row["门店编码"],
"一级分类": row["一级分类"],
"二级分类": row["二级分类"],
"权限": row["权限"],
"开关": row["开关"],
"状态": "更新成功",
}
)
else:
result_list.append(
{
"数据id": row["数据id"],
"门店编码": row["门店编码"],
"一级分类": row["一级分类"],
"二级分类": row["二级分类"],
"权限": row["权限"],
"开关": row["开关"],
"状态": "更新失败",
}
)
else:
payload = {
"api_key": "6694d3c4fcb69ca9a111a6c4",
"entry_id": "68cb745753594c2570ba4f70",
"data": {"_widget_1758164058473": {"value": "Boss权限自动审批"}, # 预警类型
"_widget_1758164058474": {"value": f"cookies信息失效,请更新cookie"}
# 预警内容
},
"is_start_workflow": "true"
}
res = API().data_batch_create(payload)
result_df = pd.DataFrame(result_list)
return result_df
def send_status_and_approval(self, df):
all_success_ids = [] # 全部成功的 数据id
failed_records_dict = {} # 不成功的记录 {数据id: [不成功的记录]}
# 按 "数据id" 分组,并遍历每个分组
for data_id, group in df.groupby("数据id"):
if (group["状态"] == "更新成功").all():
all_success_ids.append(data_id)
print(f"数据id {data_id} 全部成功,执行提交操作")
get_task_id = API().workflow_instance_get({"data_id": data_id})
# print(get_task_id)
task_id = get_task_id.get("tasks")[-1].get("task_id")
user_name = get_task_id.get("tasks")[-1].get("assignee").get("username")
# 表单提交到下一步
res = API().workflow_task_approve({
"username": user_name,
"task_id": task_id,
"instance_id": data_id,
})
# print(res)
new_res = API().entry_data_update({
"api_key": "675b900991ad2491c69389ca", # 应用ID
"entry_id": "68c1116b51730ebbc690ae40", # 表单ID
"data_id": data_id,
"data": {"_widget_1751522755921": {"value": ""}, # 是否开通
},
})
elif (group["状态"] == "空门店编码跳过执行").all():
print(f"数据id {data_id} 存在空门店编码,跳过执行")
else:
# 情况2:有不成功的 -> 执行操作 b(如组合不成功的记录)
failed_records = group[group["状态"] != "更新成功"].to_dict("records")
failed_records_dict[data_id] = failed_records
print(f"数据id {data_id} 有不成功的记录:{failed_records}")
payload = {
"api_key": "6694d3c4fcb69ca9a111a6c4",
"entry_id": "68cb745753594c2570ba4f70",
"data": {"_widget_1758164058473": {"value": "Boss权限自动审批"}, # 预警类型
"_widget_1758164058474": {"value": f"数据id {data_id} 有不成功的记录:{failed_records}"}
# 预警内容
},
"is_start_workflow": "true"
}
res = API().data_batch_create(payload)
# print(f"已成功提交数据预警信息:{res}")
print(f"全部成功的数据id{all_success_ids}")
def main(self):
task_start_time = datetime.now()
# step1 获取简道云上任务列表
self.load_data()
# step2 根据权限开通列表获取权限对应功能
payload_df = self.map_switch_data()
# step3 根据门店编码查询公司id。
payload_df = self.get_company_id(payload_df)
# step4 批量修改权限
result_df = self.update_permission(payload_df)
# step5 简道云发送状态与同意
self.send_status_and_approval(result_df)
if __name__ == '__main__':
BossPermissionAutoApproval().main()