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:
parent
038162b5d9
commit
9115435441
@ -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 ───
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user