Bonus-Transfer-Machines/安全/退料.py

291 lines
9.9 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.

import configparser
import pandas as pd
from sqlalchemy import create_engine
from urllib.parse import quote_plus
# 读取配置文件
config = configparser.ConfigParser()
config.read('config.ini')
# 获取数据库连接配置
source_config = {
'host': config.get('source_db', 'host'),
'user': config.get('source_db', 'user'),
'password': config.get('source_db', 'password'),
'database': config.get('source_db', 'database'),
'port': config.getint('source_db', 'port')
}
target_config = {
'host': config.get('target_db', 'host'),
'user': config.get('target_db', 'user'),
'password': config.get('target_db', 'password'),
'database': config.get('target_db', 'database'),
'port': config.getint('target_db', 'port')
}
# 创建数据库引擎
source_engine = create_engine(
f"mysql+pymysql://{source_config['user']}:{quote_plus(source_config['password'])}@{source_config['host']}:{source_config['port']}/{source_config['database']}"
)
target_engine = create_engine(
f"mysql+pymysql://{target_config['user']}:{quote_plus(target_config['password'])}@{target_config['host']}:{target_config['port']}/{target_config['database']}"
)
# 定义type映射关系
type_mapping = {
6: 'sgd', # 独立施工队
7: 'xmb', # 项目部
122: 'fbs', # 分包商
126: 'hq' # 后勤
}
def get_agreement_id(unit_id, project_id, type_code):
"""根据组合条件查询agreement_id"""
try:
sql = f"""
SELECT (bpr.ID + 500000) as agreement_id
FROM bm_project_relation bpr
WHERE bpr.UNIT_ID = {unit_id}
AND bpr.project_id = {project_id}
AND bpr.type = '{type_code}'
LIMIT 1
"""
result = pd.read_sql(sql, source_engine)
return result['agreement_id'].iloc[0] if not result.empty else None
except Exception as e:
print(f"查询agreement_id出错: {str(e)}")
return None
def process_tm_task():
"""处理任务主表"""
try:
sql = """
SELECT
(be.ID + 500000) as task_id,
3 as task_type,
IF(be.`STATUS` = 50, 2, 0) as task_status,
be.`CODE`,
pu.`NAME` as create_by,
be.CREATE_TIME
FROM
bpm_example be
LEFT JOIN sys_data_dict sdd on be.`STATUS` = sdd.ID
LEFT JOIN pm_user pu on be.CREATOR = pu.ID
WHERE be.DEFINITION_ID = 5
"""
df = pd.read_sql(sql, source_engine)
df.to_sql('tm_task', target_engine, if_exists='append', index=False)
print(f"成功导入 {len(df)} 条任务主表数据")
return True
except Exception as e:
print(f"处理任务主表时出错: {str(e)}")
return False
def process_tm_task_agreement():
"""处理任务关联表"""
try:
# 第一步查询基础数据
base_sql = """
SELECT
(be.ID + 600000) as task_id,
be.DEPT_ID,
be.SUB_ID,
be.TEAM_ID,
be.REAR_ID,
be.TYPE,
be.PROJECT_ID
FROM bpm_example be
WHERE be.DEFINITION_ID = 5
"""
base_df = pd.read_sql(base_sql, source_engine)
# 填充空值并转换为适当类型
base_df = base_df.fillna(0)
base_df['TYPE'] = base_df['TYPE'].astype(int)
for col in ['DEPT_ID', 'SUB_ID', 'TEAM_ID', 'REAR_ID', 'PROJECT_ID']:
base_df[col] = pd.to_numeric(base_df[col], errors='coerce').fillna(0).astype(int)
# 第二步处理每个记录获取agreement_id
results = []
skipped_records = 0
for _, row in base_df.iterrows():
try:
# 确定unit_id和type_code
unit_id = None
type_code = None
if row['TYPE'] == 6: # 施工队
if row['TEAM_ID'] > 0:
unit_id = int(row['TEAM_ID']) + 5000
type_code = 'sgd'
elif row['TYPE'] == 7: # 项目部
if row['DEPT_ID'] > 0:
unit_id = int(row['DEPT_ID']) + 4000
type_code = 'xmb'
elif row['TYPE'] == 122: # 分包商
if row['SUB_ID'] > 0:
unit_id = int(row['SUB_ID']) + 6000
type_code = 'fbs'
elif row['TYPE'] == 126: # 后勤
if row['REAR_ID'] > 0:
unit_id = int(row['REAR_ID']) + 6000
type_code = 'hq'
# 检查必要参数是否有效
if not unit_id or not type_code or row['PROJECT_ID'] <= 0:
skipped_records += 1
continue
# 使用参数化查询避免字符串拼接问题
agreement_id = get_agreement_id(unit_id, int(row['PROJECT_ID']), type_code)
if agreement_id:
results.append({
'task_id': int(row['task_id']),
'agreement_id': int(agreement_id)
})
except Exception as e:
print(f"处理记录时出错: {str(e)},记录内容: {row.to_dict()}")
skipped_records += 1
continue
# 写入目标表
if results:
result_df = pd.DataFrame(results)
result_df.to_sql('tm_task_agreement', target_engine,
if_exists='append', index=False)
print(f"成功导入 {len(result_df)} 条任务关联数据,跳过 {skipped_records} 条无效记录")
return True
except Exception as e:
print(f"处理任务关联表时出错: {str(e)}")
return False
def get_agreement_id(unit_id, project_id, type_code):
"""根据组合条件查询agreement_id使用参数化查询"""
try:
# 使用参数化查询
sql = """
SELECT (bpr.ID + 500000) as agreement_id
FROM bm_project_relation bpr
WHERE bpr.UNIT_ID = %s
AND bpr.project_id = %s
AND bpr.type = %s
LIMIT 1
"""
params = (int(unit_id), int(project_id), str(type_code))
result = pd.read_sql(sql, source_engine, params=params)
return result['agreement_id'].iloc[0] if not result.empty else None
except Exception as e:
print(f"查询agreement_id出错: unit_id={unit_id}, project_id={project_id}, type={type_code}, 错误: {str(e)}")
return None
def process_back_apply_info():
"""处理退料申请信息"""
try:
sql = """
SELECT
be.`CODE`,
(be.ID + 500000) as task_id,
be.LINK_MAN as back_person,
NULL as phone, -- 需根据实际情况补充
pu.`NAME` as create_by,
be.CREATE_TIME,
IF(be.`STATUS` = 50, 1, 0) as status,
be.IS_PRINT as print_status
FROM
bpm_example be
LEFT JOIN sys_data_dict sdd on be.`STATUS` = sdd.ID
LEFT JOIN pm_user pu on be.CREATOR = pu.ID
WHERE be.DEFINITION_ID = 5
"""
df = pd.read_sql(sql, source_engine)
df.to_sql('back_apply_info', target_engine, if_exists='append', index=False)
print(f"成功导入 {len(df)} 条退料申请信息")
return True
except Exception as e:
print(f"处理退料申请信息时出错: {str(e)}")
return False
def process_back_apply_details():
"""处理退料申请明细"""
try:
sql = """
SELECT
be.`CODE`,
(be.ID + 500000) as parent_id,
(bbf.MATYPE_ID+6000) as type_id,
SUM(bbf.BACK_NUM) as pre_num,
SUM(bbf.BACK_NUM) as audit_num,
0 as bad_num, -- 需根据实际情况调整
0 as good_num, -- 需根据实际情况调整
IF(be.`STATUS` = 50, 2, 0) as status,
pu.`NAME` as create_by,
be.CREATE_TIME
FROM
bpm_example be
LEFT JOIN bpm_back_form bbf on be.ID = bbf.EXAMPLE_ID
LEFT JOIN pm_user pu on be.CREATOR = pu.ID
WHERE be.DEFINITION_ID = 5
GROUP BY be.ID
"""
df = pd.read_sql(sql, source_engine)
df.to_sql('back_apply_details', target_engine, if_exists='append', index=False)
print(f"成功导入 {len(df)} 条退料申请明细")
return True
except Exception as e:
print(f"处理退料申请明细时出错: {str(e)}")
return False
def process_back_check_details():
"""处理退料验收明细"""
try:
sql = """
SELECT
(bbf.EXAMPLE_ID + 500000) as parent_id,
(bbf.MATYPE_ID + 6000) as type_id,
(bbf.MA_ID + 70000) as ma_id,
bbf.BACK_NUM as back_num,
CASE
WHEN bbf.BACK_STATUS = 19 THEN 1
WHEN bbf.BACK_STATUS = 20 THEN 0
ELSE 2
END AS back_status,
IF(bbf.BACK_STATUS = 19, bbf.BACK_NUM, 0) as good_num,
IF(bbf.BACK_STATUS IN (20,21), bbf.BACK_NUM, 0) as bad_num,
1 as status,
pu.`NAME` as create_by,
bbf.CREATE_TIME
FROM
bpm_back_form bbf
LEFT JOIN pm_user pu on bbf.CREATOR = pu.ID
"""
df = pd.read_sql(sql, source_engine)
df.to_sql('back_check_details', target_engine, if_exists='append', index=False)
print(f"成功导入 {len(df)} 条退料验收明细")
return True
except Exception as e:
print(f"处理退料验收明细时出错: {str(e)}")
return False
if __name__ == "__main__":
# 执行所有转换流程
results = [
process_tm_task(),
process_tm_task_agreement(),
process_back_apply_info(),
process_back_apply_details(),
process_back_check_details()
]
if all(results):
print("所有退料相关表转换完成!")
else:
print("部分转换失败,请检查错误日志")