refactor: load_product_category_product returns data only, no DB writes

- Returns standardized {categories, products} format
- product_management handles dedup/update logic
- Categories: source_id, name, description, product_type, sort_order
- Products: source_category_id, resource_ref_id, product_code, product_name, etc.
This commit is contained in:
Hermes Agent 2026-06-23 16:06:09 +08:00
parent a060dd1405
commit 64f10e177b

View File

@ -56,18 +56,22 @@ from .product_interface import (
async def load_product_category_product(parent_category_id): async def load_product_category_product(parent_category_id):
"""Load llmage catalogs and published models as product sub-categories and products. """Return llmage catalogs and published models as standardized import data.
Called by product_management.import_categories_and_products() when resource_module='llmage'. Called by product_management.import_categories_and_products().
Responsible for reading source data AND writing to product_management tables. Only reads source data and returns it in the standard format.
Does NOT write to product_management tables that's product_management's job.
Returns:
{
'success': True,
'categories': [{'source_id', 'name', 'description', 'product_type', 'product_type_title', 'sort_order'}, ...],
'products': [{'source_category_id', 'resource_ref_id', 'product_code', 'product_name', 'product_type', 'brief_intro', 'sort_order'}, ...]
}
""" """
import time
from appPublic.uniqueID import getID
env = ServerEnv() env = ServerEnv()
pm_dbname = env.get_module_dbname('product_management')
# Step 1: Read source data from llmage # Read source data from llmage
async with get_sor_context(env, 'llmage') as sor: async with get_sor_context(env, 'llmage') as sor:
catelogs = await sor.R('llmcatelog', {}) catelogs = await sor.R('llmcatelog', {})
if not catelogs: if not catelogs:
@ -82,97 +86,35 @@ where m.isdefaultcatelog = '1' and a.status = 'published'
order by lc.sort_order, lc.name, a.name""" order by lc.sort_order, lc.name, a.name"""
llms = await sor.sqlExe(llm_sql, {}) llms = await sor.sqlExe(llm_sql, {})
# Step 2: Get parent category's org_id from product_management # Build standardized categories
now = time.strftime('%Y-%m-%d %H:%M:%S') categories = []
async with DBPools().sqlorContext(pm_dbname) as sor: for c in catelogs:
parent_rows = await sor.sqlExe( categories.append({
"SELECT org_id FROM product_category WHERE id = ${id}$", 'source_id': c.id,
{'id': parent_category_id} 'name': c.name,
) 'description': getattr(c, 'description', '') or '',
if not parent_rows: 'product_type': 'llm_model',
return {'success': False, 'error': f'父类别 {parent_category_id} 不存在'} 'product_type_title': '大模型按量',
org_id = parent_rows[0].org_id 'sort_order': int(getattr(c, 'sort_order', 0) or 0),
})
# Step 3: Write sub-categories and products # Build standardized products
source_to_id = {} products = []
created_cats = 0 for llm in (llms or []):
skipped_cats = 0 products.append({
created_prods = 0 'source_category_id': llm.llmcatelogid,
skipped_prods = 0 'resource_ref_id': llm.id,
'product_code': llm.model,
async with DBPools().sqlorContext(pm_dbname) as sor: 'product_name': llm.name,
for c in catelogs: 'product_type': 'llm_model',
existing = await sor.sqlExe( 'brief_intro': getattr(llm, 'description', '') or '',
"""SELECT id FROM product_category 'sort_order': 0,
WHERE name = ${name}$ AND parent_id = ${parent_id}$ AND org_id = ${org_id}$""", })
{'name': c.name, 'parent_id': parent_category_id, 'org_id': org_id}
)
if existing:
source_to_id[c.id] = existing[0].id
skipped_cats += 1
continue
new_id = getID()
source_to_id[c.id] = new_id
cat_data = {
'id': new_id,
'parent_id': parent_category_id,
'name': c.name,
'description': getattr(c, 'description', '') or '',
'has_product': '1',
'product_type': 'llm_model',
'product_type_title': '大模型按量',
'sort_order': str(getattr(c, 'sort_order', 0) or 0),
'icon': '',
'status': '1',
'resource_module': 'llmage',
'org_id': org_id,
'created_at': now,
'updated_at': now
}
await sor.C('product_category', cat_data)
created_cats += 1
for llm in (llms or []):
target_cat_id = source_to_id.get(llm.llmcatelogid)
if not target_cat_id:
skipped_prods += 1
continue
existing_prod = await sor.sqlExe(
"""SELECT id FROM product
WHERE product_code = ${code}$ AND org_id = ${org_id}$""",
{'code': llm.model, 'org_id': org_id}
)
if existing_prod:
skipped_prods += 1
continue
prod_id = getID()
prod_data = {
'id': prod_id,
'category_id': target_cat_id,
'product_code': llm.model,
'resource_ref_id': llm.id,
'product_name': llm.name,
'product_type': 'llm_model',
'brief_intro': getattr(llm, 'description', '') or '',
'status': '1',
'price_type': '1',
'price': '0',
'currency': 'CNY',
'sort_order': '0',
'org_id': org_id,
'created_at': now,
'updated_at': now
}
await sor.C('product', prod_data)
created_prods += 1
return { return {
'success': True, 'success': True,
'message': f'llmage导入完成: 新增 {created_cats} 个子类别, {created_prods} 个产品; ' 'categories': categories,
f'跳过 {skipped_cats} 个已存在类别, {skipped_prods} 个已存在产品' 'products': products,
} }