entity/entity/init.py

176 lines
5.4 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.

"""entity 模块:实体管理 + 实体导入。
通过 load_entity() 挂载到 ServerEnv函数被 .dspy 以全局方式直接调用。
"""
import csv
import io
import json
from appPublic.timeUtils import curDateString, timestampstr
from appPublic.uniqueID import getID
from sqlor.dbpools import DBPools
def _get_dbname():
"""取库名(由宿主应用决定,禁止硬编码)。"""
from ahserver import ServerEnv
return ServerEnv().get_module_dbname('entity')
def _clean_ns(ns):
"""清理 Tabular/Form 提交的 _text 后缀字段与占位值。"""
for k in list(ns.keys()):
if k.endswith('_text'):
ns.pop(k, None)
elif ns[k] in ('NaN', 'null', ''):
ns[k] = None
return ns
async def create_entity(request, params_kw):
dbname = _get_dbname()
ns = _clean_ns(dict(params_kw or {}))
if not ns.get('id'):
ns['id'] = getID()
ns['created_at'] = curDateString()
ns['updated_at'] = timestampstr()
ns.setdefault('entity_type', '0')
ns.setdefault('status', '0')
db = DBPools()
async with db.sqlorContext(dbname) as sor:
await sor.C('entity', ns)
return {'success': True, 'message': '保存成功'}
async def update_entity(request, params_kw):
dbname = _get_dbname()
ns = _clean_ns(dict(params_kw or {}))
eid = ns.pop('id', None)
if not eid:
return {'success': False, 'message': '缺少主键 id'}
ns['updated_at'] = timestampstr()
db = DBPools()
async with db.sqlorContext(dbname) as sor:
await sor.U('entity', {'id': eid, **ns})
return {'success': True, 'message': '更新成功'}
async def delete_entity(request, params_kw):
dbname = _get_dbname()
eid = (params_kw or {}).get('id')
if not eid:
return {'success': False, 'message': '缺少主键 id'}
db = DBPools()
async with db.sqlorContext(dbname) as sor:
await sor.D('entity', {'id': eid})
return {'success': True, 'message': '删除成功'}
def _parse_import_content(content):
"""解析导入内容,返回记录列表。支持 JSON 数组/对象 或 CSV首行表头"""
text = (content or '').strip()
if not text:
return []
if text.startswith('[') or text.startswith('{'):
data = json.loads(text)
return data if isinstance(data, list) else [data]
reader = csv.DictReader(io.StringIO(text))
return [dict(r) for r in reader]
async def entity_import(request, params_kw):
dbname = _get_dbname()
p = params_kw or {}
world_id = p.get('world_id', '')
scene_id = p.get('scene_id') or None
file_obj = p.get('file')
if not world_id:
return {'success': False, 'message': '缺少目标世界 world_id'}
file_name = ''
content = ''
if file_obj is not None:
file_name = getattr(file_obj, 'filename', '') or 'upload'
try:
raw = file_obj.read()
content = raw.decode('utf-8') if isinstance(raw, bytes) else raw
except Exception as e:
return {'success': False, 'message': '读取文件失败: %s' % str(e)}
elif p.get('file_content'):
content = p.get('file_content')
file_name = p.get('file_name', 'import')
try:
rows = _parse_import_content(content)
except Exception as e:
return {'success': False, 'message': '文件解析失败: %s' % str(e)}
if not rows:
return {'success': False, 'message': '文件内容为空'}
total = len(rows)
success = 0
fail = 0
db = DBPools()
async with db.sqlorContext(dbname) as sor:
for row in rows:
try:
name = str(row.get('name') or '').strip()
code = str(row.get('code') or '').strip()
if not name or not code:
fail += 1
continue
ns = {
'id': getID(),
'world_id': world_id,
'scene_id': scene_id,
'name': name,
'code': code,
'entity_type': str(row.get('entity_type') or '0'),
'status': str(row.get('status') or '0'),
'attributes_json': row.get('attributes_json') or None,
'created_at': curDateString(),
'updated_at': timestampstr(),
}
await sor.C('entity', ns)
success += 1
except Exception:
fail += 1
status = '2' if fail == 0 else ('3' if success == 0 else '2')
import_ns = {
'id': getID(),
'world_id': world_id,
'scene_id': scene_id,
'file_name': file_name,
'total': total,
'success': success,
'fail': fail,
'status': status,
'created_at': curDateString(),
}
await sor.C('entity_import', import_ns)
return {
'success': True,
'total': total,
'success_count': success,
'fail': fail,
'file_name': file_name,
}
async def load_entity():
from ahserver import ServerEnv
env = ServerEnv()
env.create_entity = create_entity
env.create_entitys = create_entity
env.update_entity = update_entity
env.update_entitys = update_entity
env.delete_entity = delete_entity
env.delete_entitys = delete_entity
env.entity_import = entity_import