refactor: import logic moved to product_management, resource modules return data only

- import_categories_and_products now:
  1. Calls resource module for standardized data
  2. Categories: skip if exists (name+parent+org), else create
  3. Products: update if exists (resource_ref_id+org), else create
- product.json: added resource_ref_id field for resource module internal ID mapping
This commit is contained in:
Hermes Agent 2026-06-23 16:06:10 +08:00
parent 038162b5d9
commit 9115435441

View File

@ -1097,13 +1097,15 @@ class ProductManager:
parent_category_id, user_id):
"""Import sub-categories and products from a resource module.
Dynamically imports the resource module and calls its
load_product_category_product(parent_category_id) function,
which is responsible for both reading source data and writing
sub-categories + products under the given parent_category_id.
1. Calls resource module's load_product_category_product() to get standardized data
2. For categories: skip if exists (by name+parent_id+org_id), else create
3. For products: update if exists (by resource_ref_id+org_id), else create
"""
import importlib
import time
from appPublic.uniqueID import getID
# Step 1: Get standardized data from resource module
try:
mod = importlib.import_module(f'{resource_module}.init')
load_fn = getattr(mod, 'load_product_category_product', None)
@ -1118,10 +1120,115 @@ class ProductManager:
except Exception as e:
return {'success': False, 'error': f'调用 {resource_module}.load_product_category_product() 失败: {e}'}
if not result:
return {'success': False, 'error': f'资源模块 "{resource_module}" 未返回导入数据'}
if not result or not result.get('success'):
return {'success': False, 'error': result.get('error', '资源模块未返回有效数据') if result else '资源模块未返回数据'}
return result
categories = result.get('categories', [])
products = result.get('products', [])
if not categories and not products:
return {'success': False, 'error': '资源模块返回数据为空'}
dbname = self._get_dbname()
now = time.strftime('%Y-%m-%d %H:%M:%S')
source_to_id = {} # source_id -> product_category.id
created_cats = 0
skipped_cats = 0
created_prods = 0
updated_prods = 0
async with DBPools().sqlorContext(dbname) as sor:
# Step 2: Process categories — skip existing, create new
for cat in categories:
existing = await sor.sqlExe(
"""SELECT id FROM product_category
WHERE name = ${name}$ AND parent_id = ${parent_id}$ AND org_id = ${org_id}$""",
{'name': cat['name'], 'parent_id': parent_category_id, 'org_id': org_id}
)
if existing:
source_to_id[cat['source_id']] = existing[0].id
skipped_cats += 1
continue
new_id = getID()
source_to_id[cat['source_id']] = new_id
await sor.C('product_category', {
'id': new_id,
'parent_id': parent_category_id,
'name': cat['name'],
'description': cat.get('description', ''),
'has_product': '1',
'product_type': cat.get('product_type', ''),
'product_type_title': cat.get('product_type_title', ''),
'sort_order': str(cat.get('sort_order', 0)),
'icon': '',
'status': '1',
'resource_module': resource_module,
'org_id': org_id,
'created_by': user_id,
'created_at': now,
'updated_at': now
})
created_cats += 1
# Step 3: Process products — update existing, create new
for prod in products:
target_cat_id = source_to_id.get(prod.get('source_category_id'))
if not target_cat_id:
continue
resource_ref_id = prod.get('resource_ref_id', '')
# Check if product already exists by resource_ref_id + org_id
existing_prod = None
if resource_ref_id:
existing_prod = await sor.sqlExe(
"""SELECT id FROM product
WHERE resource_ref_id = ${ref_id}$ AND org_id = ${org_id}$""",
{'ref_id': resource_ref_id, 'org_id': org_id}
)
if existing_prod:
# Update existing product
await sor.U('product', {
'id': existing_prod[0].id,
'product_name': prod.get('product_name', ''),
'product_code': prod.get('product_code', ''),
'product_type': prod.get('product_type', ''),
'brief_intro': prod.get('brief_intro', ''),
'category_id': target_cat_id,
'sort_order': str(prod.get('sort_order', 0)),
'updated_at': now
})
updated_prods += 1
else:
# Create new product
prod_id = getID()
await sor.C('product', {
'id': prod_id,
'category_id': target_cat_id,
'product_code': prod.get('product_code', ''),
'resource_ref_id': resource_ref_id,
'product_name': prod.get('product_name', ''),
'product_type': prod.get('product_type', ''),
'brief_intro': prod.get('brief_intro', ''),
'status': '1',
'price_type': '1',
'price': '0',
'currency': 'CNY',
'sort_order': str(prod.get('sort_order', 0)),
'org_id': org_id,
'created_by': user_id,
'created_at': now,
'updated_at': now
})
created_prods += 1
return {
'success': True,
'message': f'导入完成: 新增 {created_cats} 个类别, {created_prods} 个产品; '
f'跳过 {skipped_cats} 个已有类别; 更新 {updated_prods} 个已有产品'
}
# ─── Resource Module Interface Dispatcher ───