admin_template.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import json
  2. from fastapi import APIRouter, Depends, Request, Form
  3. from fastapi.responses import HTMLResponse, RedirectResponse
  4. from sqlalchemy import text # 新增这一行
  5. from sqlalchemy.orm import Session
  6. from database import SessionLocal
  7. from services.template_builder import build_estimate_packet
  8. router = APIRouter(prefix="/admin/template", tags=["template"])
  9. def get_db():
  10. db = SessionLocal()
  11. try:
  12. yield db
  13. finally:
  14. db.close()
  15. @router.get("/preview", response_class=HTMLResponse)
  16. def preview_template(
  17. request: Request,
  18. base_template_id: int,
  19. db: Session = Depends(get_db)
  20. ):
  21. packet = build_estimate_packet(db, base_template_id)
  22. json_data = {
  23. "templateId": base_template_id,
  24. "template": packet
  25. }
  26. # ------- HTML 渲染 -------
  27. html = f"""
  28. <h2>模板预览(Template ID:{base_template_id})</h2>
  29. <div style="display:flex;gap:30px">
  30. <div style="width:55%">
  31. """
  32. for step in packet:
  33. html += f"""
  34. <div style="border:1px solid #ccc;padding:10px;margin-bottom:10px">
  35. <h3>Step {step['step']} - {step['stepName']}</h3>
  36. """
  37. for prop in step["properties"]:
  38. html += f"""
  39. <div style="margin-left:20px">
  40. <b>{prop['name']}</b>
  41. {"(多选)" if prop.get("isMulti") else ""}
  42. {"(必填)" if prop.get("required") else ""}
  43. <ul>
  44. """
  45. for v in prop["values"]:
  46. html += f"""
  47. <li>
  48. {v['valueText']}
  49. {"✅" if v.get("isNormal") else "❌"}
  50. </li>
  51. """
  52. html += "</ul></div>"
  53. html += "</div>"
  54. html += f"""
  55. </div>
  56. <div style="width:45%">
  57. <h3>JSON 输出</h3>
  58. <pre style="background:#f6f6f6;padding:10px;max-height:800px;overflow:auto">
  59. {json.dumps(json_data, ensure_ascii=False, indent=2)}
  60. </pre>
  61. </div>
  62. </div>
  63. """
  64. return html
  65. # ---------------- 页面 ----------------
  66. @router.get("/generate", response_class=HTMLResponse)
  67. def generate_page(request: Request, db: Session = Depends(get_db)):
  68. machines = db.execute(text("""
  69. SELECT machine_id, brand_name, name
  70. FROM t_machine
  71. ORDER BY brand_name, name
  72. LIMIT 200
  73. """)).fetchall()
  74. templates = [
  75. (99181, "iPhone 国行基础模板"),
  76. (99198, "安卓通用模板"),
  77. (99197, "折叠屏模板"),
  78. ]
  79. html = """
  80. <h2>生成机型模板</h2>
  81. <form method="post">
  82. <h3>① 选择机型</h3>
  83. <select name="machine_id">
  84. """
  85. for m in machines:
  86. html += f'<option value="{m.machine_id}">{m.brand_name} - {m.name}</option>'
  87. html += """
  88. </select>
  89. <h3>② 选择基础模板</h3>
  90. <select name="base_template_id">
  91. """
  92. for tid, tname in templates:
  93. html += f'<option value="{tid}">{tid} - {tname}</option>'
  94. html += """
  95. </select>
  96. <h3>③ Step1 补充配置(手动输入,逗号分隔)</h3>
  97. 容量(capacity):<br>
  98. <input name="capacity" placeholder="128G,256G,512G"><br><br>
  99. 颜色(color):<br>
  100. <input name="color" placeholder="黑色,白色,蓝色"><br><br>
  101. 保修(warranty):<br>
  102. <input name="warranty" placeholder="无保修,官方保修"><br><br>
  103. <button type="submit">④ 生成模板</button>
  104. </form>
  105. """
  106. return html
  107. @router.post("/generate")
  108. def generate_submit(
  109. machine_id: int = Form(...),
  110. base_template_id: int = Form(...),
  111. capacity: str = Form(""),
  112. color: str = Form(""),
  113. warranty: str = Form(""),
  114. db: Session = Depends(get_db)
  115. ):
  116. # 1️⃣ 基础模板(step1_attr + release_option)
  117. packet = build_estimate_packet(db, base_template_id)
  118. # 2️⃣ 补充 step1(人工输入)
  119. step1 = packet[0]["properties"]
  120. def append_property(key, name, values):
  121. if not values:
  122. return
  123. step1.append({
  124. "id": key,
  125. "name": name,
  126. "required": False,
  127. "isMulti": False,
  128. "values": [
  129. {
  130. "valueId": f"manual_{v.strip()}",
  131. "valueText": v.strip(),
  132. "isNormal": True
  133. }
  134. for v in values.split(",") if v.strip()
  135. ]
  136. })
  137. append_property("capacity", "容量", capacity)
  138. append_property("color", "颜色", color)
  139. append_property("warranty", "保修", warranty)
  140. # 3️⃣ 保存模板
  141. db.execute(text("""
  142. INSERT INTO machine_temp(machine_id,temp_type,estimate_packet)
  143. VALUES (:mid,'00',:json)
  144. ON DUPLICATE KEY UPDATE estimate_packet=:json
  145. """), {
  146. "mid": machine_id,
  147. "json": json.dumps({
  148. "templateId": base_template_id,
  149. "template": packet
  150. }, ensure_ascii=False)
  151. })
  152. db.commit()
  153. return RedirectResponse("/admin/template/generate", status_code=302)