152 lines
7.3 KiB
Python
152 lines
7.3 KiB
Python
"""种子数据脚本:
|
||
1. 创建默认企业/管理员(admin/123456)
|
||
2. 导入采集到的 254 套官方样板(drawing_data + 分类树 + 平面图)
|
||
用法: uv run python -m huamenchuang.scripts.seed
|
||
"""
|
||
import asyncio
|
||
import json
|
||
from pathlib import Path
|
||
|
||
DATA = Path(__file__).resolve().parents[3] / "data"
|
||
|
||
|
||
async def seed() -> None:
|
||
import huamenchuang.models # noqa: F401 确保全部模型注册到 metadata 后再建表
|
||
from huamenchuang.core.database import SessionLocal, init_db
|
||
from huamenchuang.models.user import User
|
||
from huamenchuang.models.windoor_template import WindoorCatelog, WindoorTemplate
|
||
from huamenchuang.services.auth_service import hash_password
|
||
|
||
await init_db()
|
||
async with SessionLocal() as db:
|
||
# 1) 管理员
|
||
if await db.get(User, 1) is None:
|
||
db.add(User(id=1, nickname="管理员", phone_number="13800000000",
|
||
password_hash=hash_password("123456"), company_id=1))
|
||
print("已创建管理员: 13800000000 / 123456")
|
||
|
||
# 2) 分类树(来自 default_windoor_catelog.json,取目标站原始 id 便于对照)
|
||
cat_file = DATA / "api-samples" / "default_windoor_catelog.json"
|
||
if cat_file.exists():
|
||
from sqlalchemy import select as _sel
|
||
cats = json.load(open(cat_file, encoding="utf-8"))["data"]
|
||
existing = set((await db.execute(_sel(WindoorCatelog.id))).scalars())
|
||
for top in cats:
|
||
if top["id"] not in existing:
|
||
db.add(WindoorCatelog(id=top["id"], name=top["name"], fid=0, company_id=1))
|
||
for ch in top.get("children", []):
|
||
if ch["id"] not in existing:
|
||
db.add(WindoorCatelog(id=ch["id"], name=ch["name"], fid=top["id"], company_id=1))
|
||
print("分类树导入完成")
|
||
|
||
# 3) 官方样板 254 套
|
||
templates = json.load(open(DATA / "api-samples" / "windoor-templates-clean.json", encoding="utf-8"))
|
||
drawings_dir = DATA / "windoor-drawings"
|
||
img_dir = DATA / "windoor-images"
|
||
from sqlalchemy import func, select
|
||
count = (await db.execute(select(func.count()).select_from(WindoorTemplate))).scalar_one()
|
||
if count == 0:
|
||
for t in templates:
|
||
dd_file = drawings_dir / f"{t['id']}.json"
|
||
if not dd_file.exists():
|
||
continue
|
||
detail = json.load(open(dd_file, encoding="utf-8"))
|
||
img = img_dir / f"{t['id']}.png"
|
||
img2 = img_dir / f"{t['id']}.jpg"
|
||
pic = "/static/windoor-images/" + (img.name if img.exists() else img2.name)
|
||
db.add(WindoorTemplate(
|
||
name=detail.get("name") or t.get("name") or f"样板{t['id']}",
|
||
drawing_data=detail["drawing_data"],
|
||
pic_url=pic,
|
||
catelog_id=t["catelog_id"],
|
||
note=detail.get("note") or "",
|
||
times=detail.get("times") or 0,
|
||
low_width=detail.get("low_width") or 0,
|
||
high_width=detail.get("high_width") or 0,
|
||
low_height=detail.get("low_height") or 0,
|
||
high_height=detail.get("high_height") or 0,
|
||
))
|
||
print(f"已导入样板 {len(templates)} 套")
|
||
else:
|
||
print(f"样板表已有 {count} 条, 跳过导入")
|
||
await db.commit()
|
||
print("种子数据完成")
|
||
|
||
# 4) 帮助文章(幂等:按标题去重)
|
||
async with SessionLocal() as db:
|
||
from huamenchuang.models.extend import Article
|
||
from huamenchuang.scripts.article_seed_data import ARTICLES
|
||
existing = {t for (t,) in (await db.execute(select(Article.title))).all()}
|
||
for i, (cat, title, content) in enumerate(ARTICLES):
|
||
if title not in existing:
|
||
db.add(Article(title=title, category=cat, content=content, sort=i))
|
||
await db.commit()
|
||
print("帮助文章就绪")
|
||
|
||
# 5) 平台公告(幂等:按名称去重)
|
||
async with SessionLocal() as db:
|
||
from huamenchuang.models.announcement import Announcement
|
||
ANNOUNCEMENTS = [
|
||
("AI 炫图功能上线", "选择样板一键生成多风格效果图,支持日景/黄昏/夜景与四种装修风格", 1),
|
||
("样板组合工场发布", "拖拽组合多个窗型样板,自由摆放、等高对齐、边缘吸附,支持 3D 预览", 2),
|
||
("3D 门窗开合演示", "3D 展示支持平开扇旋转、推拉扇滑动动画,可调节开合度", 3),
|
||
("优化下料引擎", "合同级汇总算料需求,一维优化切割提升型材利用率", 4),
|
||
]
|
||
existing = {n for (n,) in (await db.execute(select(Announcement.name))).all()}
|
||
for name, desc, sort in ANNOUNCEMENTS:
|
||
if name not in existing:
|
||
db.add(Announcement(name=name, desc=desc, sort=sort))
|
||
await db.commit()
|
||
print("平台公告就绪")
|
||
|
||
# 6) 价格脚本示例(幂等:按名称去重)
|
||
async with SessionLocal() as db:
|
||
from huamenchuang.models.business import PriceScript
|
||
SAMPLE_SCRIPTS = [
|
||
("断桥铝-55系列", "frame", "(w+h)*2/1000*52"),
|
||
("断桥铝-55系列", "mullion", "length*46"),
|
||
("断桥铝-55系列", "sash", "length*58"),
|
||
("双层中空玻璃", "glass", "max(110, area*135)"),
|
||
("标准五金", "hardware", "sashes*195"),
|
||
]
|
||
existing = {n for (n,) in (await db.execute(select(PriceScript.name))).all()}
|
||
for name, target, formula in SAMPLE_SCRIPTS:
|
||
if name not in existing:
|
||
db.add(PriceScript(name=name, target=target, formula=formula,
|
||
note="种子示例脚本,可在产品管理中修改"))
|
||
await db.commit()
|
||
print("价格脚本就绪")
|
||
|
||
# 7) 打印模板(幂等:按名称去重)
|
||
async with SessionLocal() as db:
|
||
from huamenchuang.models.extend import OrderFormat
|
||
FORMATS = [
|
||
("标准生产订单", [
|
||
{"type": "title", "text": "生产订单"},
|
||
{"type": "info", "fields": ["order_no", "customer_name", "phone", "address", "count", "money"]},
|
||
{"type": "image"},
|
||
{"type": "table", "kind": "process"},
|
||
{"type": "sign"},
|
||
], 1),
|
||
("生产订单+BOM下料单", [
|
||
{"type": "title", "text": "生产订单"},
|
||
{"type": "info", "fields": ["order_no", "customer_name", "phone", "address",
|
||
"count", "area", "money", "created_at"]},
|
||
{"type": "image"},
|
||
{"type": "table", "kind": "bom"},
|
||
{"type": "table", "kind": "process"},
|
||
{"type": "sign"},
|
||
], 0),
|
||
]
|
||
existing = {n for (n,) in (await db.execute(select(OrderFormat.name))).all()}
|
||
for i, (name, blocks, is_default) in enumerate(FORMATS):
|
||
if name not in existing:
|
||
db.add(OrderFormat(name=name, order_type=0, sort=i, is_default=is_default,
|
||
blocks=__import__("json").dumps(blocks, ensure_ascii=False)))
|
||
await db.commit()
|
||
print("打印模板就绪")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(seed())
|