| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- from fastapi import APIRouter, Request, Depends, Form
- from fastapi.responses import HTMLResponse
- from sqlalchemy.orm import Session
- from sqlalchemy import text
- from database import SessionLocal, redis_client
- from services.template_service import build_template
- from services.price_service import apply_adjust
- import json
- import uuid
- router = APIRouter(prefix="/estimate", tags=["estimate"])
- # ================= DB =================
- def get_db():
- db = SessionLocal()
- try:
- yield db
- finally:
- db.close()
- # ================= 页面 =================
- @router.get("/simulate", response_class=HTMLResponse)
- def simulate(machine_id: int, db: Session = Depends(get_db)):
- row = db.execute(text("""
- SELECT estimate_packet
- FROM machine_temp
- WHERE machine_id=:mid
- """), {"mid": machine_id}).fetchone()
- tpl = json.loads(row.estimate_packet)
- html = "<h2>估价模拟</h2>"
- html += '<form method="post">'
- for step in tpl["template"]:
- html += f"<h3>{step['stepName']}</h3>"
- for p in step["properties"]:
- html += f"<b>{p['name']}</b><br>"
- for v in p["values"]:
- html += f"""
- <label>
- <input type="checkbox" name="option_ids" value="{v['valueId']}">
- {v['valueText']}
- </label><br>
- """
- html += f"""
- <input type="hidden" name="machine_id" value="{machine_id}">
- <br>
- <button type="submit">开始估价</button>
- </form>
- """
- return html
- # ================= 提交估价 =================
- @router.post("/simulate", response_class=HTMLResponse)
- def simulate_calc(
- machine_id: int = Form(...),
- option_ids: list[str] = Form([]),
- db: Session = Depends(get_db)
- ):
- base_price = 1000.0
- factors = db.execute(text("""
- SELECT option_id,factor,absolute_deduct
- FROM price_option_factor
- WHERE option_id IN :ids
- """), {"ids": tuple(option_ids)}).fetchall()
- price = base_price
- for f in factors:
- if f.factor:
- price *= float(f.factor)
- if f.absolute_deduct:
- price -= float(f.absolute_deduct)
- # 机型调节
- adjust = db.execute(text("""
- SELECT factor FROM price_adjust_factor
- WHERE level='machine'
- AND ref_id=:mid
- """), {"mid": machine_id}).fetchone()
- if adjust:
- price *= float(adjust.factor)
- html = f"""
- <h2>估价结果</h2>
- 选择项:{",".join(option_ids)}<br>
- 估价:{round(price,2)} 元<br>
- <a href="/estimate/simulate?machine_id={machine_id}">返回</a>
- """
- return html
- @router.post("/estimate2", response_class=HTMLResponse)
- def estimate_submit(
- request: Request,
- machine_id: int = Form(...),
- capacity: str = Form(...),
- option_ids: list[int] = Form([]),
- db: Session = Depends(get_db)
- ):
- # ---------- 基础价格 ----------
- base_price = db.execute(
- text("""
- SELECT base_price
- FROM machine_base_price
- WHERE machine_id=:mid AND capacity=:cap
- """),
- {"mid": machine_id, "cap": capacity}
- ).scalar() or 0
- price = float(base_price)
- # ---------- 扣减项 ----------
- for oid in option_ids:
- r = db.execute(
- text("""
- SELECT factor, absolute_deduct
- FROM price_option_factor
- WHERE option_id=:oid
- """),
- {"oid": oid}
- ).fetchone()
- if r:
- price = price * float(r.factor) - float(r.absolute_deduct)
- # ---------- 调节系数 ----------
- brand_id = db.execute(
- text("""
- SELECT brand_id
- FROM t_machine
- WHERE machine_id=:mid
- """),
- {"mid": machine_id}
- ).scalar()
- price = apply_adjust(db, machine_id, brand_id, price)
- price = round(max(price, 0), 2)
- # ---------- 估价版本 ----------
- version_no = str(uuid.uuid4())[:8]
- db.execute(
- text("""
- INSERT INTO estimate_record
- (machine_id, capacity, option_ids, final_price, version_no)
- VALUES (:m, :c, :o, :p, :v)
- """),
- {
- "m": machine_id,
- "c": capacity,
- "o": ",".join(map(str, option_ids)),
- "p": price,
- "v": version_no
- }
- )
- db.commit()
- # ---------- 模板(Redis 缓存) ----------
- cache_key = f"template:{machine_id}"
- cached = redis_client.get(cache_key) if redis_client else None
- if cached:
- template = json.loads(cached)
- else:
- rows = db.execute(text("SELECT * FROM release_option")).fetchall()
- template = build_template(rows)
- if redis_client:
- redis_client.set(cache_key, json.dumps(template), ex=3600)
- # ---------- 重新加载页面 ----------
- machines = db.execute(
- text("""
- SELECT machine_id, name
- FROM t_machine
- ORDER BY brand_name, name
- """)
- ).fetchall()
- capacities = db.execute(
- text("""
- SELECT capacity
- FROM machine_base_price
- WHERE machine_id=:mid
- """),
- {"mid": machine_id}
- ).fetchall()
- return request.app.state.templates.TemplateResponse(
- "estimate.html",
- {
- "request": request,
- "machines": machines,
- "capacities": capacities,
- "template": template,
- "price": price,
- "version": version_no,
- "selected_machine": machine_id,
- "selected_capacity": capacity
- }
- )
|