Jelajahi Sumber

解决跨域

mengqiankang 2 bulan lalu
induk
melakukan
e08e35b3df

+ 9 - 0
alien_gateway/main.py

@@ -3,6 +3,7 @@ import os
 from typing import List
 import httpx
 from fastapi import FastAPI, Request, Response, HTTPException
+from fastapi.middleware.cors import CORSMiddleware
 from starlette.status import HTTP_502_BAD_GATEWAY
 from alien_gateway.config import settings
 
@@ -11,6 +12,14 @@ app = FastAPI(
     version="1.0.0"
 )
 
+app.add_middleware(
+    CORSMiddleware,
+    allow_origins=["*"],
+    allow_credentials=True,
+    allow_methods=["*"],
+    allow_headers=["*"],
+)
+
 # ------------------- 日志配置 -------------------
 LOG_DIR = os.path.join("common", "logs", "alien_gateway")
 os.makedirs(LOG_DIR, exist_ok=True)

+ 73 - 7
alien_store/api/router.py

@@ -176,6 +176,53 @@ async def list_contracts(
         "total_pages": total_pages
     }
 
+@router.get("/contracts/detail/{sign_flow_id}", response_model=Union[dict, ErrorResponse])
+async def get_contract_detail(
+    sign_flow_id: str,
+    templates_server: ContractServer = Depends(get_contract_service)
+) -> Union[dict, ErrorResponse]:
+    """
+    根据 sign_flow_id 获取合同详情
+    - status=0: 返回合同PDF链接(contract_url)和签署链接(sign_url)
+    - status=1: 拉取最新下载链接并更新数据库,返回 contract_download_url
+    """
+    row, item, items = await templates_server.get_contract_item_by_sign_flow_id(sign_flow_id)
+    if not item:
+        return ErrorResponse(success=False, message="未找到合同")
+
+    status = item.get("status")
+    if status == 0:
+        return {
+            "status": 0,
+            "contract_url": item.get("contract_url", ""),
+            "sign_url": item.get("sign_url", ""),
+            "sign_flow_id": sign_flow_id
+        }
+
+    if status == 1:
+        try:
+            download_resp = file_download_url(sign_flow_id)
+            download_json = json.loads(download_resp)
+            contract_download_url = download_json["data"]["files"][0]["downloadUrl"]
+        except Exception as e:
+            logger.error(f"file_download_url failed sign_flow_id={sign_flow_id}: {e}")
+            return ErrorResponse(success=False, message="获取合同下载链接失败", raw=str(e))
+
+        if row and isinstance(items, list):
+            for it in items:
+                if it.get("sign_flow_id") == sign_flow_id:
+                    it["contract_download_url"] = contract_download_url
+                    break
+            await templates_server.update_contract_items(row["id"], items)
+
+        return {
+            "status": 1,
+            "contract_download_url": contract_download_url,
+            "sign_flow_id": sign_flow_id
+        }
+
+    return ErrorResponse(success=False, message="未知合同状态", raw={"status": status})
+
 @router.get("/get_all_templates", response_model=PaginatedResponse)
 async def get_all_templates(
     page: int = Query(1, ge=1, description="页码,从1开始"),
@@ -264,12 +311,31 @@ async def esign_callback(
     logger.error(f"esign_callback ignored payload: {payload}")
     return ErrorResponse(success=False, message="未处理: signResult!=2 或手机号/签署流程缺失")
 
-@router.post("/esign/callback_auth", response_model=SuccessResponse)
-async def esign_callback_auth(
-    payload: dict, 
-    templates_server: ContractServer = Depends(get_contract_service)
-) -> SuccessResponse:
-    logger.info(f"esign_callback_auth payload: {payload}")
-    return SuccessResponse(code="200", msg="success")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# @router.post("/esign/callback_auth", response_model=SuccessResponse)
+# async def esign_callback_auth(
+#     payload: dict,
+#     templates_server: ContractServer = Depends(get_contract_service)
+# ) -> SuccessResponse:
+#     logger.info(f"esign_callback_auth payload: {payload}")
+#     return SuccessResponse(code="200", msg="success")
 
 

+ 9 - 0
alien_store/main.py

@@ -2,6 +2,7 @@ import logging
 import time
 from datetime import datetime
 from fastapi import FastAPI, Request
+from fastapi.middleware.cors import CORSMiddleware
 from alien_store.api.router import router
 from alien_gateway.config import settings
 
@@ -10,6 +11,14 @@ app = FastAPI(
     version="1.0.0"
 )
 
+app.add_middleware(
+    CORSMiddleware,
+    allow_origins=["*"],
+    allow_credentials=True,
+    allow_methods=["*"],
+    allow_headers=["*"],
+)
+
 logger = logging.getLogger("alien_store")
 
 # 轻量日志中间件:仅记录方法、路径、状态码、耗时和客户端

+ 35 - 0
alien_store/repositories/contract_repo.py

@@ -58,6 +58,41 @@ class ContractRepository:
         row = result.fetchone()
         return row[0] if row else None
 
+    async def get_contract_item_by_sign_flow_id(self, sign_flow_id: str):
+        """
+        根据 sign_flow_id 查找合同项,返回 (row, item, items)
+        """
+        result = await self._execute_with_retry(ContractStore.__table__.select())
+        rows = result.mappings().all()
+        for row in rows:
+            contract_url_raw = row.get("contract_url")
+            if not contract_url_raw:
+                continue
+            try:
+                items = json.loads(contract_url_raw)
+            except Exception:
+                items = None
+            if not isinstance(items, list):
+                continue
+            for item in items:
+                if item.get("sign_flow_id") == sign_flow_id:
+                    return dict(row), item, items
+        return None, None, None
+
+    async def update_contract_items(self, row_id: int, items: list) -> bool:
+        """
+        更新指定记录的 contract_url 列表
+        """
+        if not isinstance(items, list):
+            return False
+        await self._execute_with_retry(
+            ContractStore.__table__.update()
+            .where(ContractStore.id == row_id)
+            .values(contract_url=json.dumps(items, ensure_ascii=False))
+        )
+        await self.db.commit()
+        return True
+
     async def get_all(self):
         """查询所有合同"""
         result = await self._execute_with_retry(ContractStore.__table__.select())

+ 6 - 0
alien_store/services/contract_server.py

@@ -20,6 +20,12 @@ class ContractServer:
     async def get_store_reason(self, store_id: int) -> str | None:
         return await self.esign_repo.check_store_status(store_id)
 
+    async def get_contract_item_by_sign_flow_id(self, sign_flow_id: str):
+        return await self.esign_repo.get_contract_item_by_sign_flow_id(sign_flow_id)
+
+    async def update_contract_items(self, row_id: int, items: list) -> bool:
+        return await self.esign_repo.update_contract_items(row_id, items)
+
     async def list_all_paged(self, page: int, page_size: int = 10):
         items, total = await self.esign_repo.get_all_paged(page, page_size)
         return items, total