1.客户信息修改,将硬编码改为动态取值

2.新增项目批量停用、材料批量修改功能
This commit is contained in:
2026-01-08 10:18:51 +08:00
parent c4c4ccc7e9
commit 3938c820b5
+281
View File
@@ -0,0 +1,281 @@
"""
项目材料相关后台任务模块
本模块包含项目材料相关的后台任务,包括:
- 项目信息批量停用
- 材料信息批量修改
这些任务在后台线程中执行,不会阻塞主请求。
"""
import logging
import traceback
import requests
import time
from typing import Dict, Any, List, Optional
from datetime import datetime
from tqdm import tqdm
from app.tasks.common import update_jiandaoyun, approve_workflow, get_operate_org_id, get_card_list, \
execute_failure_handler
import pandas as pd
import os
logger = logging.getLogger('app')
def batch_disable_projects(data: Dict[str, Any], cookies: Dict[str, str], df: pd.DataFrame, save_path: str,
option) -> None:
"""
项目批量停用后台任务
在后台线程中批量停用项目,从 Excel 文件中读取项目编码。
执行完成后会更新简道云表单并自动提交工作流。
Args:
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
cookies: 用户登录 F6 系统的 cookies 信息
df: Excel 文件读取的内容,DataFrame 格式,第一列为项目编码
save_path: Excel 文件保存的地址,执行完成后会删除此文件
option: 批量启用、批量停用
Returns:
None
注意:
- 无效的项目(None、空字符串)会被跳过
- 执行完成后会自动删除上传的文件
- 执行结果会更新到简道云表单
"""
if option == "批量启用":
type_ = 0 # 1 停用,0启用
else:
type_ = 1
df = df.where(pd.notnull(df), None)
# 获取门店id
org_id = get_operate_org_id(data)
# 获取项目信息
json_data = {
'param': '',
'name': '',
'customCode': '',
'currentPage': 1,
'pageSize': 100,
'isDel': -type_,
'customInvoiceCategory': 0,
'idOwnOrg': org_id,
}
response = requests.post(
'https://ids-goods.f6car.cn/f6-ids-goods/service/getServiceList',
cookies=cookies,
json=json_data,
)
all_project_list = []
total_pages = response.json().get("data", {}).get("totalPages", "")
for page in tqdm(range(1, total_pages + 1)):
json_data['currentPage'] = str(page)
response = requests.post(
'https://ids-goods.f6car.cn/f6-ids-goods/service/getServiceList',
cookies=cookies,
json=json_data,
)
project_list = response.json().get("data", {}).get("records", [])
all_project_list.extend(project_list)
# 遍历获取到的项目信息停用文件中的项目
code_list = df.iloc[:, 0].dropna().astype(str).tolist()
res_data_list = []
results = []
for item in tqdm(all_project_list):
custom_code = item.get("customCode")
if not custom_code or str(custom_code) not in code_list or not code_list:
continue
info_id = item.get("infoId")
pk_id = item.get("pkId")
json_data = {
"orgIdList": [
org_id,
],
"isDel": type_, # 1 停用 0启用
"infoId": info_id,
"pkId": pk_id,
"type": 1,
"idOwnOrg": org_id
}
try:
response = requests.post(
'https://ids-goods.f6car.cn/f6-ids-goods/service/editAttributeByType',
cookies=cookies,
json=json_data,
)
res_data_list.append(response.json())
response.raise_for_status() # 抛出HTTP错误
results.append({'材料编码': custom_code, '状态': '停用/启用成功'})
except requests.exceptions.RequestException as e:
results.append({'材料编码': custom_code, '状态': f'停用/启用失败: {str(e)}'})
pass
print({'msg': '已执行', 'msg_details': f'{results}'})
logger.info(f"停用/启用结果: {results}")
os.remove(save_path)
print(f'{save_path}已删除')
# 调用api回写改掉 执行明细与执行状态
msg = update_jiandaoyun(data, f'{results}')
if msg.get('msg'):
approve_workflow(data)
print('表单已自动提交至下一步')
def batch_modify_materials(data: Dict[str, Any], cookies: Dict[str, str], df: pd.DataFrame, save_path: str,
) -> None:
"""
材料批量修改后台任务
在后台线程中批量修改材料,从 Excel 文件中读取材料编码。
执行完成后会更新简道云表单并自动提交工作流。
Args:
data: 包含表单ID(api_key)、表单ID(entry_id)、数据ID(data_id)的字典
cookies: 用户登录 F6 系统的 cookies 信息
df: Excel 文件读取的内容,DataFrame 格式,第一列为材料编码
save_path: Excel 文件保存的地址,执行完成后会删除此文件
Returns:
None
注意:
- 无效的材料编码(None、空字符串)会被跳过
- 执行完成后会自动删除上传的文件
- 执行结果会更新到简道云表单
"""
# 获取门店id
org_id = get_operate_org_id(data)
# 获取材料信息
json_data = {
'keyWord': '',
'idOwnOrg': org_id,
'currentPage': 1,
'pageSize': 100,
'name': '',
'brand': '',
'supplierCode': '',
'customCode': '',
'categoryName': '',
'categoryId': '',
'labelId': '',
'labelName': '',
'spec': '',
'applyModel': '',
'sellPurchaseStatuses': [
2,
3,
4,
5,
],
'customInvoiceCategory': 0,
'getThirdPlatformCode': 0,
}
response = requests.post(
'https://ids-goods.f6car.com/f6-ids-goods/part/getExactPartStockInfo',
cookies=cookies,
json=json_data,
)
all_materials_list = []
total_pages = response.json().get("data", {}).get("totalPages", "")
for page in tqdm(range(1, total_pages + 1)):
json_data['currentPage'] = str(page)
response = requests.post(
'https://ids-goods.f6car.com/f6-ids-goods/part/getExactPartStockInfo',
cookies=cookies,
json=json_data,
)
materials_list = response.json().get("data", {}).get("records", [])
all_materials_list.extend(materials_list)
# 构建更新映射:{原customCode: {new_customCode, brand, name, spec}}
update_map = {}
for _, row in df.iterrows():
orig_code = str(row.iloc[0]).strip() if pd.notna(row.iloc[0]) else None
if not orig_code:
continue
update_map[orig_code] = {
"customCode": str(row.iloc[1]).strip() if pd.notna(row.iloc[1]) else "",
"brand": str(row.iloc[2]).strip() if pd.notna(row.iloc[2]) else "",
"name": str(row.iloc[3]).strip() if pd.notna(row.iloc[3]) else "",
"spec": str(row.iloc[4]).strip() if pd.notna(row.iloc[4]) else "",
}
# 遍历获取到的材料信息修改材料属性
code_list = df.iloc[:, 0].dropna().astype(str).tolist()
res_data_list = []
results = []
for item in tqdm(all_materials_list):
custom_code = item.get("customCode")
# 判断当前材料编码是否在文件中
if not custom_code or str(custom_code) not in update_map:
continue
part_id = item.get("partId")
try:
# 获取材料明细
params = {
'partId': part_id,
'customInvoiceCategory': '0',
'getThirdPlatformCode': '0',
}
materials_response = requests.get(
'https://ids-goods.f6car.com/f6-ids-goods/part/getPartInfo',
params=params,
cookies=cookies,
)
if materials_response.status_code != 200:
results.append({'材料编码': custom_code, '状态': '获取明细失败'})
continue
detail = materials_response.json().get("data")
if not detail:
results.append({'材料编码': custom_code, '状态': '明细为空'})
continue
updates = update_map[custom_code]
# === 关键:强制覆盖,空值也写入 ===
detail["customCode"] = updates["customCode"] # 可能是 ""
detail["brand"] = updates["brand"] # 可能是 ""
detail["name"] = updates["name"] # 可能是 ""
detail["showName"] = updates["name"] # 同步 showName(重要!)
detail["spec"] = updates["spec"] # 可能是 ""
# 修复价格和数组(必须!)
for f in ["purchasePrice", "sellPrice"]:
if isinstance(detail.get(f), (int, float)):
detail[f] = f"{detail[f]:.2f}"
if detail.get("partBarCodeVos") is None:
detail["partBarCodeVos"] = []
update_resp = requests.post(
'https://ids-goods.f6car.com/f6-ids-goods/part/updateAreaPartBasicInfo',
cookies=cookies,
json=detail
)
if update_resp.status_code == 200 and update_resp.json().get("code") == 200:
results.append({'材料编码': custom_code, '状态': '修改成功'})
else:
msg = update_resp.json().get("message", "未知错误")
results.append({'材料编码': custom_code, '状态': f'修改失败: {msg}'})
except requests.exceptions.RequestException as e:
results.append({'材料编码': custom_code, '状态': f'修改属性失败: {str(e)}'})
pass
print({'msg': '已执行', 'msg_details': f'{results}'})
logger.info(f"批量修改结果: {results}")
os.remove(save_path)
print(f'{save_path}已删除')
# 调用api回写改掉 执行明细与执行状态
msg = update_jiandaoyun(data, f'{results}')
if msg.get('msg'):
approve_workflow(data)
print('表单已自动提交至下一步')