111 lines
4.2 KiB
Python
111 lines
4.2 KiB
Python
|
|
"""
|
|||
|
|
模板应用工具:把 CardTemplate 的预设(theme + background + design)应用到 Project。
|
|||
|
|
- 复制 LibraryAsset 中的素材到 projects/<pid>/<asset_type>/<asset_key>_xxx.png
|
|||
|
|
- 在 Project 的 design 中写 background_color / border_color / suit_colors 等
|
|||
|
|
"""
|
|||
|
|
import os
|
|||
|
|
import shutil
|
|||
|
|
from time import time
|
|||
|
|
from django.conf import settings
|
|||
|
|
from apps.projects.models import Project, Asset, LibraryAsset
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _copy_lib_to_project(project, lib, asset_type, asset_key):
|
|||
|
|
"""把 LibraryAsset 的文件复制到 projects/<pid>/<asset_type>/ 下,并在 Project.assets 建记录"""
|
|||
|
|
project_media_dir = f'projects/{project.id}/{asset_type}'
|
|||
|
|
full_dir = os.path.join(settings.MEDIA_ROOT, project_media_dir)
|
|||
|
|
os.makedirs(full_dir, exist_ok=True)
|
|||
|
|
|
|||
|
|
src = os.path.join(settings.MEDIA_ROOT, lib.file_path)
|
|||
|
|
if not os.path.exists(src):
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
ts = int(time() * 1000)
|
|||
|
|
fn = f'{asset_key}_{ts}_{lib.file_name}'
|
|||
|
|
dst_rel = f'{project_media_dir}/{fn}'
|
|||
|
|
shutil.copy2(src, os.path.join(settings.MEDIA_ROOT, dst_rel))
|
|||
|
|
|
|||
|
|
# 读图尺寸
|
|||
|
|
width = height = None
|
|||
|
|
try:
|
|||
|
|
from PIL import Image
|
|||
|
|
with Image.open(os.path.join(settings.MEDIA_ROOT, dst_rel)) as im:
|
|||
|
|
width, height = im.size
|
|||
|
|
except Exception:
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
# 删除同 (asset_type, asset_key) 的旧记录
|
|||
|
|
Asset.objects.filter(project=project, asset_type=asset_type, asset_key=asset_key).delete()
|
|||
|
|
return Asset.objects.create(
|
|||
|
|
project=project,
|
|||
|
|
asset_type=asset_type,
|
|||
|
|
asset_key=asset_key,
|
|||
|
|
file_path=dst_rel,
|
|||
|
|
file_name=fn,
|
|||
|
|
width=width,
|
|||
|
|
height=height,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def apply_template_to_project(project, template):
|
|||
|
|
"""根据 CardTemplate 的预设填充项目:写 design + 复制 JQK/Joker 素材
|
|||
|
|
|
|||
|
|
默认行为:
|
|||
|
|
- 整副牌 background_color / border_color 等设计项按模板的 design_override 写入
|
|||
|
|
- 模板绑定的 theme_id 对应的所有 LibraryAsset 复制成 JQK/Joker 资产
|
|||
|
|
- 应用到所有 4 个花色 + 大小王
|
|||
|
|
"""
|
|||
|
|
# 1. 应用 design 覆盖
|
|||
|
|
base_design = dict(project.design or {})
|
|||
|
|
override = template.design_override or {}
|
|||
|
|
base_design.update(override)
|
|||
|
|
# 同步花色颜色
|
|||
|
|
if 'suit_symbols' not in base_design:
|
|||
|
|
base_design['suit_symbols'] = {}
|
|||
|
|
base_design['suit_symbols']['spade'] = {'type': 'text', 'value': '♠', 'color': template.color_spade, 'asset_id': None}
|
|||
|
|
base_design['suit_symbols']['heart'] = {'type': 'text', 'value': '♥', 'color': template.color_heart, 'asset_id': None}
|
|||
|
|
base_design['suit_symbols']['club'] = {'type': 'text', 'value': '♣', 'color': template.color_club, 'asset_id': None}
|
|||
|
|
base_design['suit_symbols']['diamond'] = {'type': 'text', 'value': '♦', 'color': template.color_diamond, 'asset_id': None}
|
|||
|
|
# 背景色
|
|||
|
|
base_design['background_color'] = template.color_background
|
|||
|
|
project.design = base_design
|
|||
|
|
project.save()
|
|||
|
|
|
|||
|
|
# 2. 复制主题素材(如果绑定了 theme_id)
|
|||
|
|
theme_id = template.theme_id
|
|||
|
|
if not theme_id:
|
|||
|
|
return {'applied': 0, 'theme_id': None}
|
|||
|
|
|
|||
|
|
libs = LibraryAsset.objects.filter(theme_id=theme_id)
|
|||
|
|
if not libs.exists():
|
|||
|
|
return {'applied': 0, 'theme_id': theme_id, 'warning': f'no library assets for theme {theme_id}'}
|
|||
|
|
|
|||
|
|
applied = []
|
|||
|
|
for lib in libs:
|
|||
|
|
# asset_type: J/Q/K -> face_card;joker -> joker
|
|||
|
|
if lib.role == 'joker':
|
|||
|
|
asset_type = 'joker'
|
|||
|
|
# 默认应用到 joker-big
|
|||
|
|
asset_key = 'joker-big'
|
|||
|
|
# 同主题如果有 small 的角色素材就分别处理
|
|||
|
|
if lib.asset_id == 'small':
|
|||
|
|
asset_key = 'joker-small'
|
|||
|
|
else:
|
|||
|
|
asset_type = 'face_card'
|
|||
|
|
# 4 个花色都复制
|
|||
|
|
for suit in ('spade', 'heart', 'club', 'diamond'):
|
|||
|
|
asset_key = f'{suit}-{lib.role}'
|
|||
|
|
a = _copy_lib_to_project(project, lib, asset_type, asset_key)
|
|||
|
|
if a:
|
|||
|
|
applied.append(a.id)
|
|||
|
|
continue
|
|||
|
|
a = _copy_lib_to_project(project, lib, asset_type, asset_key)
|
|||
|
|
if a:
|
|||
|
|
applied.append(a.id)
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
'applied': len(applied),
|
|||
|
|
'theme_id': theme_id,
|
|||
|
|
'asset_ids': applied,
|
|||
|
|
}
|