| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- import json
- from fastapi import APIRouter, Depends, Request, Form
- from fastapi.responses import HTMLResponse, RedirectResponse
- from sqlalchemy import text # 新增这一行
- from sqlalchemy.orm import Session
- from database import SessionLocal
- from services.template_builder import build_estimate_packet
- router = APIRouter(prefix="/admin/template", tags=["template"])
- def get_db():
- db = SessionLocal()
- try:
- yield db
- finally:
- db.close()
- @router.get("/preview", response_class=HTMLResponse)
- def preview_template(
- request: Request,
- base_template_id: int,
- db: Session = Depends(get_db)
- ):
- packet = build_estimate_packet(db, base_template_id)
- json_data = {
- "templateId": base_template_id,
- "template": packet
- }
- # ------- HTML 渲染 -------
- html = f"""
- <h2>模板预览(Template ID:{base_template_id})</h2>
- <div style="display:flex;gap:30px">
- <div style="width:55%">
- """
- for step in packet:
- html += f"""
- <div style="border:1px solid #ccc;padding:10px;margin-bottom:10px">
- <h3>Step {step['step']} - {step['stepName']}</h3>
- """
- for prop in step["properties"]:
- html += f"""
- <div style="margin-left:20px">
- <b>{prop['name']}</b>
- {"(多选)" if prop.get("isMulti") else ""}
- {"(必填)" if prop.get("required") else ""}
- <ul>
- """
- for v in prop["values"]:
- html += f"""
- <li>
- {v['valueText']}
- {"✅" if v.get("isNormal") else "❌"}
- </li>
- """
- html += "</ul></div>"
- html += "</div>"
- html += f"""
- </div>
- <div style="width:45%">
- <h3>JSON 输出</h3>
- <pre style="background:#f6f6f6;padding:10px;max-height:800px;overflow:auto">
- {json.dumps(json_data, ensure_ascii=False, indent=2)}
- </pre>
- </div>
- </div>
- """
- return html
- # ---------------- 页面 ----------------
- @router.get("/generate", response_class=HTMLResponse)
- def generate_page(request: Request, db: Session = Depends(get_db)):
- machines = db.execute(text("""
- SELECT machine_id, brand_name, name
- FROM t_machine
- ORDER BY brand_name, name
- LIMIT 200
- """)).fetchall()
- templates = [
- (99181, "iPhone 国行基础模板"),
- (99198, "安卓通用模板"),
- (99197, "折叠屏模板"),
- ]
- # ✅ 从 step1_attr 读取所有可补充的属性
- step1_attrs = db.execute(text("""
- SELECT
- attr_key,
- attr_name,
- MIN(sort_order) AS sort_order
- FROM step1_attr
- GROUP BY attr_key, attr_name
- ORDER BY sort_order
- """)).fetchall()
- html = """
- <h2>生成机型模板</h2>
- <form method="post">
- <h3>① 选择机型</h3>
- <select name="machine_id">
- """
- for m in machines:
- html += f'<option value="{m.machine_id}">{m.brand_name} - {m.name}</option>'
- html += """
- </select>
- <h3>② 选择基础模板</h3>
- <select name="base_template_id">
- """
- for tid, tname in templates:
- html += f'<option value="{tid}">{tid} - {tname}</option>'
- html += """
- </select>
- <h3>③ Step1 补充配置(从 step1_attr 读取,逗号分隔)</h3>
- """
- # ✅ 动态输出所有属性输入框
- for a in step1_attrs:
- html += f"""
- <div style="margin-bottom:10px;">
- {a.attr_name}({a.attr_key}):<br>
- <input
- name="manual_{a.attr_key}"
- placeholder="例如:A,B,C"
- style="width:300px;"
- >
- </div>
- """
- html += """
- <button type="submit">④ 生成模板</button>
- </form>
- """
- return html
- @router.get("/generate1", response_class=HTMLResponse)
- def generate_page(request: Request, db: Session = Depends(get_db)):
- machines = db.execute(text("""
- SELECT machine_id, brand_name, name
- FROM t_machine
- ORDER BY brand_name, name
- LIMIT 200
- """)).fetchall()
- templates = [
- (99181, "iPhone 国行基础模板"),
- (99198, "安卓通用模板"),
- (99197, "折叠屏模板"),
- ]
- html = """
- <h2>生成机型模板</h2>
- <form method="post">
- <h3>① 选择机型</h3>
- <select name="machine_id">
- """
- for m in machines:
- html += f'<option value="{m.machine_id}">{m.brand_name} - {m.name}</option>'
- html += """
- </select>
- <h3>② 选择基础模板</h3>
- <select name="base_template_id">
- """
- for tid, tname in templates:
- html += f'<option value="{tid}">{tid} - {tname}</option>'
- html += """
- </select>
- <h3>③ Step1 补充配置(手动输入,逗号分隔)</h3>
- 容量(capacity):<br>
- <input name="capacity" placeholder="128G,256G,512G"><br><br>
- 颜色(color):<br>
- <input name="color" placeholder="黑色,白色,蓝色"><br><br>
- 保修(warranty):<br>
- <input name="warranty" placeholder="无保修,官方保修"><br><br>
- <button type="submit">④ 生成模板</button>
- </form>
- """
- return html
- @router.post("/generate")
- def generate_submit(
- request: Request,
- machine_id: int = Form(...),
- base_template_id: int = Form(...),
- db: Session = Depends(get_db)
- ):
- form = request._form # FastAPI 已解析
- # 1️⃣ 基础模板(step1_attr + release_option)
- packet = build_estimate_packet(db, base_template_id)
- # 2️⃣ 补充 step1(人工输入)
- step1 = packet[0]["properties"]
- # 所有 manual_xxx
- manual_inputs = {}
- for k, v in form.items():
- if k.startswith("manual_"):
- manual_inputs[k.replace("manual_", "")] = v
- # 读取 step1_attr 的定义(用于取 attr_name)
- attr_map = db.execute(text("""
- SELECT attr_key, attr_name
- FROM step1_attr
- GROUP BY attr_key, attr_name
- """)).fetchall()
- attr_name_map = {a.attr_key: a.attr_name for a in attr_map}
- for attr_key, value_str in manual_inputs.items():
- if not value_str:
- continue
- values = [x.strip() for x in value_str.split(",") if x.strip()]
- if not values:
- continue
- step1.append({
- "id": attr_key,
- "name": attr_name_map.get(attr_key, attr_key),
- "required": False,
- "isMulti": False,
- "values": [
- {
- "valueId": f"manual_{attr_key}_{v}",
- "valueText": v,
- "isNormal": True
- }
- for v in values
- ]
- })
- # 3️⃣ 保存模板
- db.execute(text("""
- INSERT INTO machine_temp(machine_id, temp_type, estimate_packet)
- VALUES (:mid, '00', :json)
- ON DUPLICATE KEY UPDATE estimate_packet=:json
- """), {
- "mid": machine_id,
- "json": json.dumps({
- "templateId": base_template_id,
- "template": packet
- }, ensure_ascii=False)
- })
- db.commit()
- return RedirectResponse("/admin/template/generate", status_code=302)
|