Quellcode durchsuchen

搭建e签宝项目框架 和初步实现雪花算法

mengqiankang vor 2 Monaten
Ursprung
Commit
4bc14e262b
61 geänderte Dateien mit 363 neuen und 18 gelöschten Zeilen
  1. 64 0
      alien_3rd_esign/README.md
  2. 1 0
      alien_3rd_esign/__init__.py
  3. 9 0
      alien_3rd_esign/api/deps.py
  4. 8 0
      alien_3rd_esign/api/router.py
  5. 0 0
      alien_3rd_esign/db/models/__init__.py
  6. 3 5
      alien_3rd_esign/db/models/contract_store.py
  7. 26 0
      alien_3rd_esign/main.py
  8. 8 0
      alien_3rd_esign/repositories/contract_repo.py
  9. 0 7
      alien_3rd_esign/router.py
  10. 0 0
      alien_3rd_esign/schemas/request/__init__.py
  11. 0 0
      alien_3rd_esign/schemas/request/contract_store.py
  12. 0 0
      alien_3rd_esign/schemas/response/__init__.py
  13. 0 0
      alien_3rd_esign/schemas/response/contract_store.py
  14. 0 1
      alien_3rd_esign/services.py
  15. 8 0
      alien_3rd_esign/services/contract_server.py
  16. 1 0
      alien_entity/base.py
  17. 4 4
      alien_gateway/config.py
  18. 53 0
      alien_snowflake/README.md
  19. 13 0
      alien_snowflake/__init__.py
  20. 160 0
      alien_snowflake/generator.py
  21. 0 0
      alien_util/esigntool/__init__.py
  22. 0 0
      alien_util/esigntool/esign_algorithm.py
  23. 0 0
      alien_util/esigntool/esign_config.py
  24. 0 0
      alien_util/esigntool/esign_emun.py
  25. 0 0
      alien_util/esigntool/esign_file.py
  26. 0 0
      alien_util/esigntool/esign_tool_info.py
  27. 0 0
      alien_util/run/__init__.py
  28. 0 0
      alien_util/run/moduledemo/__init__.py
  29. 0 0
      alien_util/run/moduledemo/auth/__init__.py
  30. 0 0
      alien_util/run/moduledemo/auth/auth_launch.py
  31. 0 0
      alien_util/run/moduledemo/auth/auth_query.py
  32. 0 0
      alien_util/run/moduledemo/fileandtemplate/__init__.py
  33. 0 0
      alien_util/run/moduledemo/fileandtemplate/expand.py
  34. 0 0
      alien_util/run/moduledemo/fileandtemplate/file.py
  35. 0 0
      alien_util/run/moduledemo/fileandtemplate/template.py
  36. 0 0
      alien_util/run/moduledemo/members/__init__.py
  37. 0 0
      alien_util/run/moduledemo/members/org_member.py
  38. 0 0
      alien_util/run/moduledemo/order/__init__.py
  39. 0 0
      alien_util/run/moduledemo/order/order_buy.py
  40. 0 0
      alien_util/run/moduledemo/order/order_query.py
  41. 0 0
      alien_util/run/moduledemo/seal/__init__.py
  42. 0 0
      alien_util/run/moduledemo/seal/org_seals.py
  43. 0 0
      alien_util/run/moduledemo/seal/psn_seals.py
  44. 0 0
      alien_util/run/moduledemo/seal/upload_url.py
  45. 0 0
      alien_util/run/moduledemo/sign/__init__.py
  46. 0 0
      alien_util/run/moduledemo/sign/attachments_change.py
  47. 0 0
      alien_util/run/moduledemo/sign/copiers_change.py
  48. 0 0
      alien_util/run/moduledemo/sign/signfields_change.py
  49. 0 0
      alien_util/run/moduledemo/sign/signflow_change.py
  50. 0 0
      alien_util/run/moduledemo/sign/signflow_download.py
  51. 0 0
      alien_util/run/moduledemo/sign/signflow_launch.py
  52. 0 0
      alien_util/run/moduledemo/sign/signflow_query.py
  53. 0 0
      alien_util/run/moduledemo/sign/signflow_rescission.py
  54. 0 0
      alien_util/run/scenedome/__init__.py
  55. 0 0
      alien_util/run/scenedome/b2b_autosign_demo.py
  56. 0 0
      alien_util/run/scenedome/b2b_handsign_demo.py
  57. 0 0
      alien_util/run/scenedome/b2c_handsign_demo.py
  58. 0 0
      alien_util/run/scenedome/dynamic_table_demo.py
  59. 0 0
      alien_util/run/scenedome/order_demo.py
  60. 0 0
      alien_util/run/scenedome/signature_check_demo.py
  61. 5 1
      main.py

+ 64 - 0
alien_3rd_esign/README.md

@@ -0,0 +1,64 @@
+# Alien 3rd Esign 模块开发文档
+
+## 概览
+基于 FastAPI 的电子签约子模块,负责店铺合同签约相关的接口、服务与数据访问。当前实现为骨架,需在此基础上补充业务逻辑。
+
+## 目录结构
+```
+alien_3rd_esign/
+├── main.py                    # 应用入口,挂载路由与健康检查
+├── api/
+│   ├── router.py              # 路由分组,当前仅根路径
+│   └── deps.py                # 依赖注入,提供 ContractServer
+├── db/
+│   └── models/
+│       └── contract_store.py  # 店铺合同表模型
+├── repositories/
+│   └── contract_repo.py       # 合同仓储(待实现)
+├── services/
+│   └── contract_server.py     # 合同服务层(待实现)
+├── schemas/
+│   ├── request/               # 请求 Pydantic 模型(待补充)
+│   └── response/              # 响应 Pydantic 模型(待补充)
+└── __init__.py
+```
+
+## 运行与环境
+- 依赖外部配置 `alien_gateway.config.settings`,至少包含 `PROJECT_NAME`,以及数据库配置(见上游网关项目)。
+- 数据库会话来自 `alien_database.session.get_db`,确保上游已配置 SQLAlchemy Engine/Session。
+- 安装依赖后本地运行示例:
+  ```
+  uvicorn alien_3rd_esign.main:app --host 0.0.0.0 --port 8006 --reload
+  ```
+
+## 现有 API
+- `GET /api/esign/`:模块存活确认,返回 `{"module": "Contract", "status": "Ok"}`。
+- `GET /health`:健康检查,返回 `{"service": "sign", "status": "ok"}`。
+
+## 数据模型
+- `ContractStore`(表名 `contract_store`)
+  - `store_id` (BigInteger, PK) 店铺 ID
+  - `business_segment` (String) 经营板块
+  - `merchant_name` (String) 商家姓名
+  - `contact_phone` (String) 联系电话
+  - `signing_status` (String, 默认“未签署”) 状态:已签署/未签署/已到期
+  - `signing_time` (DateTime, 可空) 签署时间
+  - `effective_time` (DateTime, 可空) 生效时间
+  - `expiry_time` (DateTime, 可空) 到期时间
+  - 继承 `AuditMixin`,包含审计字段(创建/更新人、时间等,具体见 `alien_database.base`)。
+
+## 开发指引
+- 路由层:在 `api/router.py` 按资源划分路由,通过 `Depends(get_contract_service)` 注入服务。
+- 服务层:在 `services/contract_server.py` 编写业务逻辑(状态流转、有效期计算、外部电子签平台集成、权限校验)。
+- 仓储层:在 `repositories/contract_repo.py` 实现对 `ContractStore` 的 CRUD、列表分页、状态更新等。
+- Schema:在 `schemas/request/` 与 `schemas/response/` 定义 Pydantic 模型,约束字段、枚举和值域。
+- 异常与校验:使用 FastAPI/HTTPException 统一错误响应;对输入做类型与业务校验。
+- 测试:为服务和仓储编写单元/集成测试,可使用 SQLite 内存库或测试数据库。
+
+## 后续待办(建议)
+- 补充合同创建、查询、签署、续签、到期提醒等接口。
+- 定义请求/响应 schema 与枚举,完善文档化(可结合 FastAPI OpenAPI/Swagger)。
+- 增加仓储实现与事务管理,补齐状态机校验。
+- 编写自动化测试与示例请求(如 HTTPie/Thunder Client 集合)。
+
+

+ 1 - 0
alien_3rd_esign/__init__.py

@@ -0,0 +1 @@
+# FastAPI应用包

+ 9 - 0
alien_3rd_esign/api/deps.py

@@ -0,0 +1,9 @@
+from fastapi import Depends, HTTPException, status
+from sqlalchemy.orm import Session
+from alien_database.session import get_db
+from ..services.contract_server import ContractServer
+
+
+
+def get_contract_service(db: Session = Depends(get_db)) -> ContractServer:
+    return ContractServer(db)

+ 8 - 0
alien_3rd_esign/api/router.py

@@ -0,0 +1,8 @@
+from fastapi import APIRouter
+from ..services.contract_server import ContractServer
+router = APIRouter()
+
+@router.get("/")
+async def index():
+    return {"module": "Contract", "status": "Ok"}
+

+ 0 - 0
alien_3rd_esign/client.py → alien_3rd_esign/db/models/__init__.py


+ 3 - 5
alien_3rd_esign/models.py → alien_3rd_esign/db/models/contract_store.py

@@ -4,13 +4,11 @@ from sqlalchemy import String, DateTime, BigInteger
 from sqlalchemy.orm import Mapped, mapped_column
 
 from alien_database.base import Base, AuditMixin
-
-
-class Esign_Store(Base, AuditMixin):
+class ContractStore(Base, AuditMixin):
     """
-    店铺模型
+    店铺合同模型
     """
-    __tablename__ = "esign_store"
+    __tablename__ = "contract_store"
 
     store_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, comment="店铺id")
     business_segment: Mapped[str] = mapped_column(String(100), comment="经营板块")

+ 26 - 0
alien_3rd_esign/main.py

@@ -0,0 +1,26 @@
+from fastapi import FastAPI
+from alien_3rd_esign.api.router import router
+from alien_gateway.config import settings
+from fastapi.middleware.cors import CORSMiddleware
+app = FastAPI(
+    title=f"{settings.PROJECT_NAME} - Alien Esign",
+    version="1.0.0"
+)
+
+app.add_middleware(
+    CORSMiddleware,
+    allow_credentials=True,
+    allow_methods=["*"],
+    allow_headers=["*"],
+
+)
+
+app.include_router(router, prefix="/api/esign", tags=["Esign"])
+
+@app.get("/health")
+async def health():
+    return {"service": "sign", "status": "ok"}
+
+if __name__ == "__main__":
+    import uvicorn
+    uvicorn.run(app, host="0.0.0.0", port=8006)

+ 8 - 0
alien_3rd_esign/repositories/contract_repo.py

@@ -0,0 +1,8 @@
+from sqlalchemy.orm import Session
+from ..db.models.contract_store import ContractStore
+
+
+class ContractRepository:
+
+    def __init__(self, db: Session):
+        self.db = db

+ 0 - 7
alien_3rd_esign/router.py

@@ -1,7 +0,0 @@
-from fastapi import APIRouter
-
-router = APIRouter()
-
-@router.get("/")
-async def index():
-    return {"module": "alien_second", "status": "initialized"}

+ 0 - 0
alien_3rd_esign/schemas.py → alien_3rd_esign/schemas/request/__init__.py


+ 0 - 0
alien_3rd_esign/schemas/request/contract_store.py


+ 0 - 0
alien_3rd_esign/schemas/response/__init__.py


+ 0 - 0
alien_3rd_esign/schemas/response/contract_store.py


+ 0 - 1
alien_3rd_esign/services.py

@@ -1 +0,0 @@
-from alien_database.session import get_db

+ 8 - 0
alien_3rd_esign/services/contract_server.py

@@ -0,0 +1,8 @@
+from sqlalchemy.orm import Session
+from ..repositories.contract_repo import ContractRepository
+
+
+class ContractServer:
+    def __init__(self, db: Session):
+        self.db = db
+        self.esign_repo = ContractRepository(db)

+ 1 - 0
alien_entity/base.py

@@ -2,6 +2,7 @@ from pydantic import BaseModel, ConfigDict
 from datetime import datetime
 from typing import Optional
 
+
 class BaseSchema(BaseModel):
     """基础数据模型,对应原 alien-entity 的公共基类"""
     model_config = ConfigDict(from_attributes=True)

+ 4 - 4
alien_gateway/config.py

@@ -13,10 +13,10 @@ class Settings(BaseSettings):
     
     # 数据库配置
     DB_USER: str = "root"
-    DB_PASSWORD: str = "password"
-    DB_HOST: str = "localhost"
-    DB_PORT: int = 3306
-    DB_NAME: str = "alien_cloud"
+    DB_PASSWORD: str = "Alien123456"
+    DB_HOST: str = "120.26.186.130"
+    DB_PORT: int = 30001
+    DB_NAME: str = "alien_sit"
 
     @property
     def SQLALCHEMY_DATABASE_URI(self) -> str:

+ 53 - 0
alien_snowflake/README.md

@@ -0,0 +1,53 @@
+# Alien Snowflake 主键方案
+
+适用于三台 MySQL 服务器(IP 尾段 251/252/253)的分布式雪花算法实现。
+
+## 设计要点
+- Snowflake 位分配:`41-bit 时间戳 | 5-bit 机房 | 5-bit 节点 | 12-bit 序列`。
+- 时间基准:2024-01-01 00:00:00 UTC(`EPOCH_MS=1704067200000`)。
+- 节点映射:默认将 IP 尾段 `251/252/253` 映射为 `worker_id=1/2/3`,可通过环境变量覆盖。
+- 线程安全:内部使用锁,确保并发安全;发生时钟回拨时抛出异常。
+
+## 使用方法
+### 1) 直接取号
+```python
+from alien_snowflake import next_id
+
+pk = next_id()
+```
+
+### 2) 在 SQLAlchemy 模型中用作主键默认值
+```python
+from sqlalchemy import BigInteger
+from sqlalchemy.orm import mapped_column, Mapped
+from alien_snowflake import next_id
+from alien_database.base import Base
+
+class Example(Base):
+    __tablename__ = "example"
+    id: Mapped[int] = mapped_column(BigInteger, primary_key=True, default=next_id)
+```
+
+### 3) 自定义机房或映射
+```python
+from alien_snowflake import SnowflakeGenerator, resolve_worker_id
+
+worker_id = resolve_worker_id()  # 自动根据本机 IP 或环境变量映射
+gen = SnowflakeGenerator(datacenter_id=0, worker_id=worker_id)
+pk = gen.next_id()
+```
+
+## IP 映射规则
+- 环境变量优先:`SNOWFLAKE_WORKER_IP`(可填完整 IP 或尾段,如 `192.168.0.251` 或 `251`)。
+- 默认映射表(`DEFAULT_IP_WORKER_MAP`):
+  - 251 → worker_id=1
+  - 252 → worker_id=2
+  - 253 → worker_id=3
+- 若需要调整,请修改 `alien_snowflake/generator.py` 中的 `DEFAULT_IP_WORKER_MAP`,或在初始化时传入自定义 `ip_worker_map`。
+
+## 部署建议
+- 确认三台服务器的 IP 与映射一致,或在启动前设定 `SNOWFLAKE_WORKER_IP`。
+- 保障服务器时间同步(NTP),避免时钟回拨;若检测到回拨将抛出异常终止发号。
+- 若需更大规模,可扩展 `datacenter_id` / `worker_id` 映射,但需保持各节点唯一性。
+
+

+ 13 - 0
alien_snowflake/__init__.py

@@ -0,0 +1,13 @@
+from .generator import (
+    SnowflakeGenerator,
+    default_generator,
+    next_id,
+    resolve_worker_id,
+)
+
+__all__ = [
+    "SnowflakeGenerator",
+    "default_generator",
+    "next_id",
+    "resolve_worker_id",
+]

+ 160 - 0
alien_snowflake/generator.py

@@ -0,0 +1,160 @@
+"""
+Snowflake ID 生成器,适配三台 MySQL 服务器(IP 尾号 251/252/253)。
+"""
+import os
+import socket
+import threading
+import time
+import warnings
+from typing import Dict, Optional
+
+# Snowflake 位分配:41-bit 时间戳 | 5-bit 机房 | 5-bit 节点 | 12-bit 自增序列
+EPOCH_MS = 1704067200000  # 2024-01-01 00:00:00 UTC
+WORKER_ID_BITS = 5
+DATACENTER_ID_BITS = 5
+SEQUENCE_BITS = 12
+
+MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1
+MAX_DATACENTER_ID = (1 << DATACENTER_ID_BITS) - 1
+SEQUENCE_MASK = (1 << SEQUENCE_BITS) - 1
+
+WORKER_SHIFT = SEQUENCE_BITS
+DATACENTER_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS
+TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS
+
+# 默认映射:将三台 MySQL 服务器 IP(或尾段)映射到 worker_id
+# DEFAULT_IP_WORKER_MAP: Dict[str, int] = {
+#     "251": 1,
+#     "252": 2,
+#     "253": 3,
+# }
+
+
+# 单机
+DEFAULT_IP_WORKER_MAP: Dict[str, int] = {
+    "168": 1,
+}
+
+
+def _now_ms() -> int:
+    return int(time.time() * 1000)
+
+
+def _wait_next_ms(last_ts: int) -> int:
+    ts = _now_ms()
+    while ts <= last_ts:
+        ts = _now_ms()
+    return ts
+
+
+def _get_host_ip() -> str:
+    """获取当前主机的主 IP 地址。"""
+    s = None
+    try:
+        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        # 连接一个无需真实可达的地址,只为获取本机出站 IP
+        s.connect(("10.255.255.255", 1))
+        ip = s.getsockname()[0]
+    except Exception:
+        ip = socket.gethostbyname(socket.gethostname())
+    finally:
+        if s is not None:
+            s.close()
+    return ip
+
+
+def resolve_worker_id(
+    ip_worker_map: Optional[Dict[str, int]] = None,
+    override_ip: Optional[str] = None,
+) -> int:
+    """
+    根据主机 IP 推导 worker_id。
+    - 优先读取环境变量 SNOWFLAKE_WORKER_IP 作为 IP。
+    - 其次使用 override_ip。
+    - 再次使用本机 IP。
+    - 支持完整 IP 匹配和末段匹配(如 "192.168.0.251" 或 "251")。
+    """
+    ip_worker_map = ip_worker_map or DEFAULT_IP_WORKER_MAP
+    chosen_ip = os.getenv("SNOWFLAKE_WORKER_IP") or override_ip or _get_host_ip()
+    if chosen_ip in ip_worker_map:
+        return ip_worker_map[chosen_ip]
+    last_octet = chosen_ip.split(".")[-1]
+    if last_octet in ip_worker_map:
+        return ip_worker_map[last_octet]
+    raise ValueError(
+        f"未能为 IP {chosen_ip} 匹配到 worker_id,请检查映射或设置 SNOWFLAKE_WORKER_IP。"
+    )
+
+
+class SnowflakeGenerator:
+    """
+    线程安全的 Snowflake ID 生成器。
+    默认 datacenter_id=0;worker_id 将根据 IP 映射推导。
+    """
+
+    def __init__(
+        self,
+        datacenter_id: int = 0,
+        worker_id: Optional[int] = None,
+        epoch_ms: int = EPOCH_MS,
+        ip_worker_map: Optional[Dict[str, int]] = None,
+    ):
+        self.datacenter_id = datacenter_id
+        self.worker_id = worker_id or resolve_worker_id(ip_worker_map)
+        self.epoch_ms = epoch_ms
+
+        if not 0 <= self.worker_id <= MAX_WORKER_ID:
+            raise ValueError(f"worker_id 必须在 0-{MAX_WORKER_ID} 之间")
+        if not 0 <= self.datacenter_id <= MAX_DATACENTER_ID:
+            raise ValueError(f"datacenter_id 必须在 0-{MAX_DATACENTER_ID} 之间")
+
+        self.sequence = 0
+        self.last_timestamp = -1
+        self._lock = threading.Lock()
+
+    def next_id(self) -> int:
+        """生成下一个全局唯一 ID。"""
+        with self._lock:
+            timestamp = _now_ms()
+
+            if timestamp < self.last_timestamp:
+                # 时钟回拨保护
+                raise RuntimeError("检测到系统时钟回拨,停止发号。")
+
+            if timestamp == self.last_timestamp:
+                self.sequence = (self.sequence + 1) & SEQUENCE_MASK
+                if self.sequence == 0:
+                    timestamp = _wait_next_ms(self.last_timestamp)
+            else:
+                self.sequence = 0
+
+            self.last_timestamp = timestamp
+            return (
+                ((timestamp - self.epoch_ms) << TIMESTAMP_SHIFT)
+                | (self.datacenter_id << DATACENTER_SHIFT)
+                | (self.worker_id << WORKER_SHIFT)
+                | self.sequence
+            )
+
+
+# 默认生成器:datacenter_id=0,worker_id 按 IP 映射自动推导
+def _build_default_generator() -> SnowflakeGenerator:
+    try:
+        return SnowflakeGenerator()
+    except ValueError as exc:
+        warnings.warn(
+            f"Snowflake 默认生成器未找到匹配的 IP,退回 worker_id=0。详情:{exc}",
+            RuntimeWarning,
+        )
+        return SnowflakeGenerator(worker_id=0)
+
+
+default_generator = _build_default_generator()
+
+
+def next_id() -> int:
+    """便捷函数,返回默认生成器的下一个 ID。"""
+    return default_generator.next_id()
+
+
+

+ 0 - 0
alien_3rd_esign/esigntool/__init__.py → alien_util/esigntool/__init__.py


+ 0 - 0
alien_3rd_esign/esigntool/esign_algorithm.py → alien_util/esigntool/esign_algorithm.py


+ 0 - 0
alien_3rd_esign/esigntool/esign_config.py → alien_util/esigntool/esign_config.py


+ 0 - 0
alien_3rd_esign/esigntool/esign_emun.py → alien_util/esigntool/esign_emun.py


+ 0 - 0
alien_3rd_esign/esigntool/esign_file.py → alien_util/esigntool/esign_file.py


+ 0 - 0
alien_3rd_esign/esigntool/esign_tool_info.py → alien_util/esigntool/esign_tool_info.py


+ 0 - 0
alien_util/run/__init__.py


+ 0 - 0
alien_util/run/moduledemo/__init__.py


+ 0 - 0
alien_util/run/moduledemo/auth/__init__.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/auth/auth_launch.py → alien_util/run/moduledemo/auth/auth_launch.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/auth/auth_query.py → alien_util/run/moduledemo/auth/auth_query.py


+ 0 - 0
alien_util/run/moduledemo/fileandtemplate/__init__.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/fileandtemplate/expand.py → alien_util/run/moduledemo/fileandtemplate/expand.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/fileandtemplate/file.py → alien_util/run/moduledemo/fileandtemplate/file.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/fileandtemplate/template.py → alien_util/run/moduledemo/fileandtemplate/template.py


+ 0 - 0
alien_util/run/moduledemo/members/__init__.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/members/org_member.py → alien_util/run/moduledemo/members/org_member.py


+ 0 - 0
alien_util/run/moduledemo/order/__init__.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/order/order_buy.py → alien_util/run/moduledemo/order/order_buy.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/order/order_query.py → alien_util/run/moduledemo/order/order_query.py


+ 0 - 0
alien_util/run/moduledemo/seal/__init__.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/seal/org_seals.py → alien_util/run/moduledemo/seal/org_seals.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/seal/psn_seals.py → alien_util/run/moduledemo/seal/psn_seals.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/seal/upload_url.py → alien_util/run/moduledemo/seal/upload_url.py


+ 0 - 0
alien_util/run/moduledemo/sign/__init__.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/sign/attachments_change.py → alien_util/run/moduledemo/sign/attachments_change.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/sign/copiers_change.py → alien_util/run/moduledemo/sign/copiers_change.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/sign/signfields_change.py → alien_util/run/moduledemo/sign/signfields_change.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/sign/signflow_change.py → alien_util/run/moduledemo/sign/signflow_change.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/sign/signflow_download.py → alien_util/run/moduledemo/sign/signflow_download.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/sign/signflow_launch.py → alien_util/run/moduledemo/sign/signflow_launch.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/sign/signflow_query.py → alien_util/run/moduledemo/sign/signflow_query.py


+ 0 - 0
alien_3rd_esign/run/moduledemo/sign/signflow_rescission.py → alien_util/run/moduledemo/sign/signflow_rescission.py


+ 0 - 0
alien_util/run/scenedome/__init__.py


+ 0 - 0
alien_3rd_esign/run/scenedome/b2b_autosign_demo.py → alien_util/run/scenedome/b2b_autosign_demo.py


+ 0 - 0
alien_3rd_esign/run/scenedome/b2b_handsign_demo.py → alien_util/run/scenedome/b2b_handsign_demo.py


+ 0 - 0
alien_3rd_esign/run/scenedome/b2c_handsign_demo.py → alien_util/run/scenedome/b2c_handsign_demo.py


+ 0 - 0
alien_3rd_esign/run/scenedome/dynamic_table_demo.py → alien_util/run/scenedome/dynamic_table_demo.py


+ 0 - 0
alien_3rd_esign/run/scenedome/order_demo.py → alien_util/run/scenedome/order_demo.py


+ 0 - 0
alien_3rd_esign/run/scenedome/signature_check_demo.py → alien_util/run/scenedome/signature_check_demo.py


+ 5 - 1
main.py

@@ -3,7 +3,7 @@ from alien_store.router import router as store_router
 from alien_store_platform.router import router as platform_router
 from alien_second.router import router as second_router
 from alien_lawyer.router import router as lawyer_router
-from alien_3rd_esign.router import router as alien_3rd_esign
+from alien_3rd_esign.api.router import router as alien_3rd_esign
 from alien_gateway.config import settings
 
 
@@ -27,3 +27,7 @@ async def root():
         "version": "3.12",
         "documentation": "/docs"
     }
+
+if __name__ == "__main__":
+    import uvicorn
+    uvicorn.run(app, host="0.0.0.0", port=9999)