#!/usr/bin/env python3 """ ERP API 迁移脚本 将硬编码的CustomerController API转换为动态配置 """ import pymysql import os from datetime import datetime # MySQL连接配置 MYSQL_HOST = os.getenv('MYSQL_HOST', '192.168.120.60') MYSQL_PORT = int(os.getenv('MYSQL_PORT', '3306')) MYSQL_DB = os.getenv('MYSQL_DB', 'hzhub') MYSQL_USER = os.getenv('MYSQL_USERNAME', 'root') MYSQL_PASSWORD = os.getenv('MYSQL_PASSWORD', 'hzhub123') print(f"连接MySQL: {MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DB}") conn = pymysql.connect( host=MYSQL_HOST, port=MYSQL_PORT, database=MYSQL_DB, user=MYSQL_USER, password=MYSQL_PASSWORD, charset='utf8mb4' ) cursor = conn.cursor() # API配置数据 api_configs = [ { 'api_name': '客户列表查询', 'api_path': '/erp/dynamic/v1/customer/list', 'api_method': 'GET', 'api_desc': '分页查询客户档案列表,支持多条件筛选', 'api_version': 'v1', 'data_source': 'erp', 'sql_template': ''' SELECT TOP #{pageSize} * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY CLTCODE) AS rn, CLTCODE AS customerCode, CLTNAME AS customerName, COMPANY_ID AS companyCode, COMPANY_NAME AS companyName, BRAND AS brand, BRANDNAME AS brandName, LINKMAN AS contactName, AREAID AS salesAreaCode, AREANAME AS salesAreaName, SALESID_T AS salesPersonCode, SALESNAME_T AS salesPersonName, SALEDOCID AS saleDocCode, SALEDOCNAME AS saleDocName, CLTPRICENO AS pricePlanCode, CLTPRICENAME AS pricePlanName, CLTTYPE AS customerType, STREET AS address, TEL1 AS phone, EMAIL AS email, SDORGID AS sdOrgCode, SDORGNAME AS sdOrgName, province, city, ISSTOP AS isStop FROM SCLTGENERAL WHERE 1=1 AND #{keyword} IS NOT NULL THEN (CLTCODE LIKE '%#{keyword}%' OR CLTNAME LIKE '%#{keyword}%' OR LINKMAN LIKE '%#{keyword}%' OR AREANAME LIKE '%#{keyword}%' OR SALESNAME_T LIKE '%#{keyword}%') AND #{companyCode} IS NOT NULL THEN COMPANY_ID = #{companyCode} AND #{salesAreaCode} IS NOT NULL THEN AREAID = #{salesAreaCode} AND #{brand} IS NOT NULL THEN BRAND = #{brand} ) t WHERE rn > (#{pageNum} - 1) * #{pageSize} ORDER BY rn ''', 'result_type': 'LIST', 'support_pagination': 1, 'page_param_name': 'pageNum', 'size_param_name': 'pageSize', 'require_auth': 0, 'permission_code': None, 'enable_cache': 0, 'source_table': 'SCLTGENERAL', 'source_table_comment': '客户档案主表', 'status': 1, 'params': [ {'param_name': 'pageNum', 'param_desc': '页码', 'param_type': 'Integer', 'param_position': 'QUERY', 'is_required': 0, 'default_value': '1', 'sort': 1}, {'param_name': 'pageSize', 'param_desc': '页大小', 'param_type': 'Integer', 'param_position': 'QUERY', 'is_required': 0, 'default_value': '10', 'sort': 2}, {'param_name': 'keyword', 'param_desc': '关键词(客户编码/名称/联系人/销区/销售员)', 'param_type': 'String', 'param_position': 'QUERY', 'is_required': 0, 'default_value': None, 'sort': 3}, {'param_name': 'companyCode', 'param_desc': '公司编码', 'param_type': 'String', 'param_position': 'QUERY', 'is_required': 0, 'default_value': None, 'sort': 4}, {'param_name': 'salesAreaCode', 'param_desc': '销区编码', 'param_type': 'String', 'param_position': 'QUERY', 'is_required': 0, 'default_value': None, 'sort': 5}, {'param_name': 'brand', 'param_desc': '品牌编码', 'param_type': 'String', 'param_position': 'QUERY', 'is_required': 0, 'default_value': None, 'sort': 6}, ] }, { 'api_name': '客户详情查询', 'api_path': '/erp/dynamic/v1/customer/detail', 'api_method': 'GET', 'api_desc': '根据客户编码查询客户详细信息', 'api_version': 'v1', 'data_source': 'erp', 'sql_template': ''' SELECT CLTCODE AS customerCode, CLTNAME AS customerName, COMPANY_ID AS companyCode, COMPANY_NAME AS companyName, BRAND AS brand, BRANDNAME AS brandName, LINKMAN AS contactName, AREAID AS salesAreaCode, AREANAME AS salesAreaName, SALESID_T AS salesPersonCode, SALESNAME_T AS salesPersonName, SALEDOCID AS saleDocCode, SALEDOCNAME AS saleDocName, CLTPRICENO AS pricePlanCode, CLTPRICENAME AS pricePlanName, CLTTYPE AS customerType, STREET AS address, TEL1 AS phone, EMAIL AS email, SDORGID AS sdOrgCode, SDORGNAME AS sdOrgName, province, city, ISSTOP AS isStop FROM SCLTGENERAL WHERE CLTCODE = #{customerCode} ''', 'result_type': 'SINGLE', 'support_pagination': 0, 'require_auth': 0, 'enable_cache': 1, 'cache_key_template': 'customer:#{customerCode}', 'cache_ttl': 600, 'source_table': 'SCLTGENERAL', 'source_table_comment': '客户档案主表', 'status': 1, 'params': [ {'param_name': 'customerCode', 'param_desc': '客户编码', 'param_type': 'String', 'param_position': 'QUERY', 'is_required': 1, 'default_value': None, 'sort': 1}, ] }, { 'api_name': '销区列表查询', 'api_path': '/erp/dynamic/v1/customer/sales-areas', 'api_method': 'GET', 'api_desc': '获取所有销区列表(从OSDORG销售组织表)', 'api_version': 'v1', 'data_source': 'erp', 'sql_template': ''' SELECT DISTINCT ORGCODE AS salesAreaCode, ORGNAME AS salesAreaName FROM OSDORG WHERE ORGLEVEL = 3 AND ORGCODE IS NOT NULL AND ORGNAME IS NOT NULL AND ISENABLE = 1 ORDER BY ORGCODE ''', 'result_type': 'LIST', 'support_pagination': 0, 'require_auth': 0, 'enable_cache': 1, 'cache_key_template': 'sales-areas', 'cache_ttl': 3600, 'source_table': 'OSDORG', 'source_table_comment': '销售组织表', 'status': 1, 'params': [] }, { 'api_name': '品牌列表查询', 'api_path': '/erp/dynamic/v1/customer/brands', 'api_method': 'GET', 'api_desc': '获取所有品牌列表', 'api_version': 'v1', 'data_source': 'erp', 'sql_template': ''' SELECT DISTINCT BRAND AS brand, BRANDNAME AS brandName FROM SCLTGENERAL WHERE BRAND IS NOT NULL AND BRANDNAME IS NOT NULL ORDER BY BRAND ''', 'result_type': 'LIST', 'support_pagination': 0, 'require_auth': 0, 'enable_cache': 1, 'cache_key_template': 'brands', 'cache_ttl': 3600, 'source_table': 'SCLTGENERAL', 'source_table_comment': '客户档案主表', 'status': 1, 'params': [] }, ] # 插入API配置 print("\n开始迁移ERP API配置...") for api in api_configs: print(f"\n处理API: {api['api_name']}") # 插入主表 sql_insert_config = """ INSERT INTO erp_api_config ( api_name, api_path, api_method, api_desc, api_version, data_source, sql_template, result_type, support_pagination, page_param_name, size_param_name, require_auth, permission_code, enable_cache, cache_key_template, cache_ttl, source_table, source_table_comment, status, create_time, create_by ) VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s ) """ cursor.execute(sql_insert_config, ( api['api_name'], api['api_path'], api['api_method'], api['api_desc'], api['api_version'], api['data_source'], api['sql_template'].strip(), api['result_type'], api['support_pagination'], api.get('page_param_name', 'pageNum'), api.get('size_param_name', 'pageSize'), api['require_auth'], api.get('permission_code'), api['enable_cache'], api.get('cache_key_template'), api.get('cache_ttl', 300), api['source_table'], api['source_table_comment'], api['status'], datetime.now(), 'admin' )) api_id = cursor.lastrowid print(f" ✓ API配置已插入 (api_id: {api_id})") # 插入参数表 for param in api['params']: sql_insert_param = """ INSERT INTO erp_api_param ( api_id, param_name, param_desc, param_type, param_position, is_required, default_value, sort, create_time ) VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s ) """ cursor.execute(sql_insert_param, ( api_id, param['param_name'], param['param_desc'], param['param_type'], param['param_position'], param['is_required'], param.get('default_value'), param['sort'], datetime.now() )) if api['params']: print(f" ✓ 已插入 {len(api['params'])} 个参数配置") conn.commit() # 验证插入结果 print("\n验证迁移结果:") cursor.execute("SELECT COUNT(*) FROM erp_api_config") total_configs = cursor.fetchone()[0] print(f" ✓ erp_api_config: {total_configs} 条记录") cursor.execute("SELECT COUNT(*) FROM erp_api_param") total_params = cursor.fetchone()[0] print(f" ✓ erp_api_param: {total_params} 条记录") # 显示插入的API列表 print("\n已迁移的API列表:") cursor.execute(""" SELECT api_id, api_name, api_path, api_method, result_type, support_pagination FROM erp_api_config ORDER BY api_id """) for row in cursor.fetchall(): api_id, name, path, method, result_type, pagination = row pagination_str = "分页" if pagination else "不分页" print(f" [{api_id}] {name} - {method} {path} ({result_type}, {pagination_str})") cursor.close() conn.close() print("\n✅ ERP API迁移完成!") print("\n下一步:") print(" 1. 测试动态API:") print(" curl 'http://192.168.120.60:8080/erp/dynamic/v1/customer/list?pageNum=1&pageSize=10'") print(" 2. 前端访问动态API管理界面:") print(" http://192.168.120.60:5666/erp/api") print(" 3. 可选:废弃旧的CustomerController(保留作为备用或对比测试)")