oa_instance_comment.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """OA 审批实例评论:附件枚举、校验、CRUD"""
  2. from __future__ import annotations
  3. import json
  4. from datetime import datetime
  5. from typing import Any, Dict, List, Optional
  6. from sqlalchemy.orm import Session
  7. from app.core.utils import generate_uuid
  8. from app.models.models import OaAppVersion, OaInstance, OaInstanceComment
  9. from app.services.oa_engine import OaEngineError, _get_instance, _loads, _user_name_map
  10. from app.services.oa_related_approval import (
  11. UPLOAD_TYPES,
  12. _extract_upload_urls,
  13. _schema_rules,
  14. _upload_display_name,
  15. )
  16. CONTENT_MAX = 1024
  17. def enumerate_form_attachments(
  18. schema: Any, form_data: Optional[Dict[str, Any]]
  19. ) -> List[Dict[str, Any]]:
  20. data = form_data or {}
  21. items: List[Dict[str, Any]] = []
  22. for rule in _schema_rules(schema):
  23. t = str(rule.get("type") or "")
  24. if t not in UPLOAD_TYPES:
  25. continue
  26. field = str(rule.get("field") or rule.get("name") or "").strip()
  27. if not field:
  28. continue
  29. label = str(rule.get("title") or rule.get("label") or field).strip() or field
  30. raw = data.get(field)
  31. files: List[Dict[str, str]] = []
  32. if isinstance(raw, list):
  33. for it in raw:
  34. if isinstance(it, dict):
  35. u = (_extract_upload_urls(it) or [""])[0]
  36. if not u:
  37. continue
  38. files.append(
  39. {
  40. "url": u,
  41. "fileName": _upload_display_name(it, u),
  42. }
  43. )
  44. else:
  45. for u in _extract_upload_urls(it):
  46. files.append({"url": u, "fileName": _upload_display_name(it, u)})
  47. else:
  48. for u in _extract_upload_urls(raw):
  49. files.append({"url": u, "fileName": _upload_display_name(raw, u)})
  50. if not files:
  51. continue
  52. items.append({"fieldKey": field, "fieldLabel": label, "files": files})
  53. return items
  54. def _allowed_url_index(
  55. schema: Any, form_data: Optional[Dict[str, Any]]
  56. ) -> Dict[str, Dict[str, str]]:
  57. """url -> {fieldKey, fieldLabel, fileName}"""
  58. index: Dict[str, Dict[str, str]] = {}
  59. for group in enumerate_form_attachments(schema, form_data):
  60. for f in group["files"]:
  61. u = str(f.get("url") or "").strip()
  62. if not u:
  63. continue
  64. index[u] = {
  65. "fieldKey": group["fieldKey"],
  66. "fieldLabel": group["fieldLabel"],
  67. "fileName": str(f.get("fileName") or "").strip() or u,
  68. }
  69. return index
  70. def normalize_attachment_refs(
  71. schema: Any,
  72. form_data: Optional[Dict[str, Any]],
  73. refs: Optional[List[Dict[str, Any]]],
  74. ) -> List[Dict[str, str]]:
  75. if not refs:
  76. return []
  77. if not isinstance(refs, list):
  78. raise OaEngineError("attachmentRefs 格式无效")
  79. index = _allowed_url_index(schema, form_data)
  80. out: List[Dict[str, str]] = []
  81. seen = set()
  82. for raw in refs:
  83. if not isinstance(raw, dict):
  84. raise OaEngineError("引用的附件不存在或不属于本表单")
  85. url = str(raw.get("url") or "").strip()
  86. if not url or url not in index:
  87. raise OaEngineError("引用的附件不存在或不属于本表单")
  88. if url in seen:
  89. continue
  90. seen.add(url)
  91. meta = index[url]
  92. out.append(
  93. {
  94. "fieldKey": meta["fieldKey"],
  95. "fieldLabel": meta["fieldLabel"],
  96. "url": url,
  97. "fileName": meta["fileName"],
  98. }
  99. )
  100. return out