| 1234567891011121314151617181920212223242526272829303132333435363738394041424344 |
- from __future__ import annotations
- import json
- from flask import g, jsonify, request
- from sqlalchemy import text
- from app import db
- from app.api.system import bp
- from app.core.system.permissions import READ_GOVERNANCE, require_permissions
- from app.core.workbench.registry import DEFAULT_LAYOUT, WIDGET_REGISTRY, validate_layout
- from app.models.result import failed, success
- @bp.route("/workbench/registry", methods=["GET"])
- @require_permissions(READ_GOVERNANCE)
- def workbench_registry():
- return jsonify(success(WIDGET_REGISTRY))
- @bp.route("/workbench/layout", methods=["GET"])
- @require_permissions(READ_GOVERNANCE)
- def get_workbench_layout():
- row = db.session.execute(text("SELECT layout_version, widgets FROM public.workbench_layouts WHERE user_id = CAST(:id AS uuid)"), {"id": g.current_user["id"]}).one_or_none()
- data = {"version": row[0], "widgets": row[1]} if row else {"version": 0, "widgets": DEFAULT_LAYOUT}
- return jsonify(success(data))
- @bp.route("/workbench/layout", methods=["PUT"])
- @require_permissions(READ_GOVERNANCE)
- def put_workbench_layout():
- body = request.get_json(silent=True) or {}
- try:
- widgets = validate_layout(body.get("widgets"))
- expected = int(request.headers.get("If-Match", body.get("version", 0)))
- except (ValueError, TypeError) as exc:
- return jsonify(failed(str(exc), code=400)), 400
- current = db.session.execute(text("SELECT layout_version FROM public.workbench_layouts WHERE user_id = CAST(:id AS uuid) FOR UPDATE"), {"id": g.current_user["id"]}).scalar_one_or_none()
- if (current or 0) != expected:
- db.session.rollback()
- return jsonify(failed("布局已被其他会话修改", code=409, data={"current_version": current or 0})), 409
- new_version = expected + 1
- db.session.execute(text("INSERT INTO public.workbench_layouts (user_id, layout_version, widgets) VALUES (CAST(:id AS uuid), :version, CAST(:widgets AS jsonb)) ON CONFLICT (user_id) DO UPDATE SET layout_version = EXCLUDED.layout_version, widgets = EXCLUDED.widgets, updated_at = CURRENT_TIMESTAMP"), {"id": g.current_user["id"], "version": new_version, "widgets": json.dumps(widgets)})
- db.session.commit()
- return jsonify(success({"version": new_version, "widgets": widgets}))
|