# -*- coding: utf-8 -*- """SQLAlchemy ORM 模型(auth/RBAC 域)+ Pydantic 请求/响应模型。 - ORM 模型对应统一总库各表(users/roles/permissions/organizations/regions/ sessions/audit_logs/agents;方言由 DATABASE_URL 决定,SQLite/MySQL)。 - Pydantic 模型与 PineAgents 主后端 ``src/pineagents/app/routers/auth.py`` 中的请求/响应模型一一对应,转发层透传时不会丢字段。 """ from __future__ import annotations from pydantic import BaseModel, Field from sqlalchemy import ( Boolean, Float, ForeignKey, Integer, PrimaryKeyConstraint, String, Text, UniqueConstraint, ) from sqlalchemy.orm import Mapped, mapped_column from .db import Base # =========================================================================== # SQLAlchemy ORM 模型 # =========================================================================== class User(Base): __tablename__ = "users" __table_args__ = {"sqlite_autoincrement": True} id: Mapped[str] = mapped_column(String, primary_key=True) username: Mapped[str] = mapped_column(String, unique=True, nullable=False) password_hash: Mapped[str] = mapped_column(String, nullable=False) password_salt: Mapped[str] = mapped_column(String, nullable=False) # 统一登录:微信 openid(登录即建 opc_member 身份);phone 与 username(手机号)对齐 wx_openid: Mapped[str] = mapped_column(String, default="", index=True) # 公众号/网页开放平台 wx_unionid: Mapped[str] = mapped_column(String, default="", index=True) # 微信 unionid(跨应用统一) wx_mini_openid: Mapped[str] = mapped_column(String, default="", index=True) # 小程序 openid(与网页不同) phone: Mapped[str] = mapped_column(String, default="") email: Mapped[str] = mapped_column(String, default="") nickname: Mapped[str] = mapped_column(String, default="") account: Mapped[str] = mapped_column(String, default="") company: Mapped[str] = mapped_column(String, default="") room: Mapped[str] = mapped_column(String, default="") avatar: Mapped[str] = mapped_column(String, default="") company_avatar: Mapped[str] = mapped_column(String, default="") gender: Mapped[str] = mapped_column(String, default="") # male|female|unknown birthday: Mapped[str] = mapped_column(String, default="") # YYYY-MM-DD # 用户详细资料(参考入园申请表 §一 申请人信息) id_card: Mapped[str] = mapped_column(String, default="") # 身份证号 ethnicity: Mapped[str] = mapped_column(String, default="") # 民族 grad_school_major: Mapped[str] = mapped_column(String, default="") # 毕业院校及专业 grad_time: Mapped[str] = mapped_column(String, default="") # 毕业时间 # RBAC role: Mapped[str] = mapped_column(String, default="opc_member") # 业务角色 sub_role: Mapped[str] = mapped_column(String, nullable=True) # 政务级/运营方内部 org_id: Mapped[str | None] = mapped_column(ForeignKey("organizations.id"), nullable=True) region_id: Mapped[str | None] = mapped_column(ForeignKey("regions.id"), nullable=True) status: Mapped[str] = mapped_column(String, default="active") # active | disabled token_version: Mapped[int] = mapped_column(Integer, default=0) # revoke-all 递增 # ── 来源与登录跟踪(全局用户统一,记录准确来源) ── source: Mapped[str] = mapped_column(String, default="") # mini_program|web|desktop|park|admin|seed|wx|phone|unknown auth_type: Mapped[str] = mapped_column(String, default="") # password|phone|wx_openid|admin register_ip: Mapped[str] = mapped_column(String, default="") last_login_ip: Mapped[str] = mapped_column(String, default="") last_login_at: Mapped[str] = mapped_column(String, default="") # ── 算力(引擎用户镜像,全局一致) ── compute_provisioned: Mapped[bool] = mapped_column(Boolean, default=False) # 是否已在算力引擎建号 compute_username: Mapped[str] = mapped_column(String, default="") # 引擎用户名(= username) compute_quota: Mapped[int] = mapped_column(Integer, default=0) # 缓存引擎可用额度 compute_used_quota: Mapped[int] = mapped_column(Integer, default=0) # 缓存引擎已用额度 # ── 状态与身份分类 ── certification_status: Mapped[str] = mapped_column(String, default="uncertified") # uncertified|pending|certified|rejected certification_time: Mapped[str] = mapped_column(String, default="") affiliation: Mapped[str] = mapped_column(String, default="independent") # independent:独立OPC | park:所属园区 park_id: Mapped[str] = mapped_column(String, default="") # 所属园区(id) park_name: Mapped[str] = mapped_column(String, default="") # 所属园区(名) park_company_id: Mapped[str | None] = mapped_column(String, nullable=True) # 所属园区企业(id),成员归属一家企业 account_type: Mapped[str] = mapped_column(String, default="opc_default") # opc_default|park_staff|platform_staff|provider|enterprise # 小程序/网页「报名资料」字段(现状标签 + 关注主题 JSON) opc_status: Mapped[str] = mapped_column(String, default="") topics: Mapped[str] = mapped_column(String, default="") # ── 邀请归因 ── inviter_id: Mapped[str] = mapped_column(String, default="", index=True) # 邀请人用户ID invite_code: Mapped[str] = mapped_column(String, default="", unique=True, index=True) # 我的邀请码 invited_at: Mapped[str] = mapped_column(String, default="") # 被邀请时间 invite_share_count: Mapped[int] = mapped_column(Integer, default=0) # 分享次数 created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class Role(Base): __tablename__ = "roles" id: Mapped[str] = mapped_column(String, primary_key=True) # 角色码 name: Mapped[str] = mapped_column(String, nullable=False) # 展示名 scope_type: Mapped[str] = mapped_column(String, default="business") # business|operator-internal|government-level description: Mapped[str] = mapped_column(String, default="") class Permission(Base): __tablename__ = "permissions" id: Mapped[str] = mapped_column(String, primary_key=True) # 权限码 menu:xx / action:xx name: Mapped[str] = mapped_column(String, nullable=False) category: Mapped[str] = mapped_column(String, default="action") # menu | action module: Mapped[str] = mapped_column(String, default="") # admin|government|... description: Mapped[str] = mapped_column(String, default="") class RolePermission(Base): __tablename__ = "role_permissions" role_id: Mapped[str] = mapped_column( ForeignKey("roles.id", ondelete="CASCADE"), primary_key=True, ) permission_id: Mapped[str] = mapped_column( ForeignKey("permissions.id", ondelete="CASCADE"), primary_key=True, ) class Organization(Base): __tablename__ = "organizations" id: Mapped[str] = mapped_column(String, primary_key=True) name: Mapped[str] = mapped_column(String, nullable=False) type: Mapped[str] = mapped_column(String, default="enterprise") # enterprise|carrier|provider region_id: Mapped[str | None] = mapped_column(ForeignKey("regions.id"), nullable=True) parent_id: Mapped[str | None] = mapped_column(ForeignKey("organizations.id"), nullable=True) status: Mapped[str] = mapped_column(String, default="active") created_at: Mapped[str] = mapped_column(String, default="") class OrganizationMember(Base): """机构成员(机构主账号 + 机构内子账号):一个账号可挂多个机构。""" __tablename__ = "organization_members" org_id: Mapped[str] = mapped_column( ForeignKey("organizations.id", ondelete="CASCADE"), primary_key=True, ) user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), primary_key=True, ) role: Mapped[str] = mapped_column(String, default="member") # admin/finance/publisher/service_executor/service_deliverer/clerk/... is_admin: Mapped[bool] = mapped_column(Boolean, default=False) # 机构主账号/管理员 status: Mapped[str] = mapped_column(String, default="active") joined_at: Mapped[str] = mapped_column(String, default="") class Region(Base): __tablename__ = "regions" id: Mapped[str] = mapped_column(String, primary_key=True) name: Mapped[str] = mapped_column(String, nullable=False) level: Mapped[str] = mapped_column(String, default="district") # province|city|district parent_id: Mapped[str | None] = mapped_column(ForeignKey("regions.id"), nullable=True) created_at: Mapped[str] = mapped_column(String, default="") class SessionToken(Base): __tablename__ = "sessions" id: Mapped[str] = mapped_column(String, primary_key=True) jti: Mapped[str] = mapped_column(String, unique=True, nullable=False) token: Mapped[str] = mapped_column(String(2048), default="") # 完整 JWT(调试用;MySQL 需显式长度,存量可达 1.5KB) user_id: Mapped[str] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), nullable=False) username: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") expires_at: Mapped[str] = mapped_column(String, default="") revoked: Mapped[bool] = mapped_column(Boolean, default=False) class AuditLog(Base): __tablename__ = "audit_logs" id: Mapped[str] = mapped_column(String, primary_key=True) user_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) action: Mapped[str] = mapped_column(String, default="") # login|role.assign|data.view|... resource: Mapped[str] = mapped_column(String, default="") # user|role|enterprise|region|... resource_id: Mapped[str] = mapped_column(String, default="") detail: Mapped[str] = mapped_column(Text, default="") ip: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class Agent(Base): __tablename__ = "agents" # id + user_id + port 复合主键:每个用户在每个端口持有独立的默认/QA 智能体(多端口彻底隔离) __table_args__ = (PrimaryKeyConstraint("id", "user_id", "port"),) id: Mapped[str] = mapped_column(String) user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False, ) port: Mapped[str] = mapped_column(String, default="opc") # opc/operator/government/... 端口隔离 name: Mapped[str] = mapped_column(String, default="") description: Mapped[str] = mapped_column(Text, default="") language: Mapped[str] = mapped_column(String, default="zh") model_name: Mapped[str] = mapped_column(String, default="") deletable: Mapped[bool] = mapped_column(Boolean, default=True) use_fixed_soul: Mapped[bool] = mapped_column(Boolean, default=False) created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") # ── 运营端业务模型(平台运营/任务/服务商/内容/配置)──────────────────────── class Task(Base): """平台任务(运营端可审核/下架;后续各端口接入)。 状态机(扩展支持扫码接单):draft/pending/review/published/claimed/doing/completed/cancelled。 扫码接单流转:published → claimed(claimed_by/claimed_at) → doing(doing_at) → completed。 历史接单流水见 TaskClaim;claim 记录 claimed_by/claimed_at/doing_at。 """ __tablename__ = "tasks" id: Mapped[str] = mapped_column(String, primary_key=True) task_code: Mapped[str] = mapped_column(String, default="", index=True) # 展示/扫码短码(唯一) title: Mapped[str] = mapped_column(String, default="") category: Mapped[str] = mapped_column(String, default="") # 分类字典 name(见 TaskCategory) category_id: Mapped[str | None] = mapped_column(ForeignKey("task_categories.id"), nullable=True) sub_category: Mapped[str] = mapped_column(String, default="") description: Mapped[str] = mapped_column(Text, default="") tags: Mapped[str] = mapped_column(String, default="") # 逗号分隔展示标签 mode: Mapped[str] = mapped_column(String, default="grab") # grab/bid/assign/recommend(旧 designated→assign/dispatch→recommend) budget_min: Mapped[int] = mapped_column(Integer, default=0) budget_max: Mapped[int] = mapped_column(Integer, default=0) deadline: Mapped[str] = mapped_column(String, default="") # 报名/接单截止时间 delivery_days: Mapped[int] = mapped_column(Integer, default=0) # 交付时限(接单后 N 天) headcount: Mapped[int] = mapped_column(Integer, default=0) # 限制接单人数(0=不限) exclusive: Mapped[bool] = mapped_column(Boolean, default=False) # 是否独占(仅一人可接) display_priority: Mapped[int] = mapped_column(Integer, default=0) # 大屏展示排序(越大越前) status: Mapped[str] = mapped_column(String, default="draft") # draft/pending/review/published/claimed/doing/completed/cancelled published_at: Mapped[str] = mapped_column(String, default="") # 发布时间(→published 时) claimed_by: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) claimed_at: Mapped[str] = mapped_column(String, default="") doing_at: Mapped[str] = mapped_column(String, default="") publisher_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) # 发包方(用户) publisher_org_id: Mapped[str | None] = mapped_column(ForeignKey("organizations.id"), nullable=True) publisher_name: Mapped[str] = mapped_column(String, default="") # ── 多端任务体系扩展字段 ── publisher_role: Mapped[str] = mapped_column(String, default="") # enterprise/operator/park visibility: Mapped[str] = mapped_column(String, default="public") # public/assigned_only/c_visible c_visible: Mapped[bool] = mapped_column(Boolean, default=True) # 是否进 C 端任务广场 park_public: Mapped[bool] = mapped_column(Boolean, default=False) # 是否公有任务(各园区大屏可见/本园可接) assign_type: Mapped[str] = mapped_column(String, default="") # opc/park(指派模式) assign_park_id: Mapped[str | None] = mapped_column(String, nullable=True) # 指派给某园区 assign_opc_id: Mapped[str | None] = mapped_column(String, nullable=True) # 指派给某 OPC park_id: Mapped[str | None] = mapped_column(String, nullable=True) # 归属园区(园区发布/专属) park_released: Mapped[bool] = mapped_column(Boolean, default=False) # 园区内已发单(园区企业可抢) bid_quota: Mapped[int] = mapped_column(Integer, default=0) # 竞标报名人数上限(0=不限) win_quota: Mapped[int] = mapped_column(Integer, default=0) # 竞标中标人数(默认1) register_quota: Mapped[int] = mapped_column(Integer, default=0) # 报名模式人数上限(0=不限)(0035) eligibility: Mapped[str] = mapped_column(Text, default="{}") # 接单资格条件(JSON 集) settle_mode: Mapped[str] = mapped_column(String, default="operator_escrow") # 资金托管方式 created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class TaskClaim(Base): """任务接单流水(扫码/抢单/投标/指派/推荐),rich 记录任务状态流转历史。""" __tablename__ = "task_claims" id: Mapped[str] = mapped_column(String, primary_key=True) task_id: Mapped[str] = mapped_column( ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, index=True, ) claimer_user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="SET NULL"), nullable=True, ) claimer_name: Mapped[str] = mapped_column(String, default="") claim_source: Mapped[str] = mapped_column(String, default="scan") # scan/grab/bid/assign/recommend claimed_at: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="claimed") # claimed/doing/completed/withdrawn/assigned/recommended created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class TaskParkVisibility(Base): """载体/园区对平台级任务的展示开关(载体端可下架/上架,不可编辑任务内容)。 缺省 = 该载体对该任务可见(平台级任务自动下发到各载体);载体在任务管理中 手动下架后 visible=False(仅本园区生效),恢复上架置回 True。 """ __tablename__ = "task_park_visibility" __table_args__ = (UniqueConstraint("task_id", "park_id", name="uq_task_park_vis"),) id: Mapped[str] = mapped_column(String, primary_key=True) task_id: Mapped[str] = mapped_column( ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, index=True, ) park_id: Mapped[str] = mapped_column(String, default="", index=True) visible: Mapped[bool] = mapped_column(Boolean, default=True) # False=该载体下架 updated_by: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class TaskCategory(Base): """任务分类字典(顶层 35 类,取自 任务类别.json)。""" __tablename__ = "task_categories" id: Mapped[str] = mapped_column(String, primary_key=True) name: Mapped[str] = mapped_column(String, default="", index=True) sort: Mapped[int] = mapped_column(Integer, default=0) modes: Mapped[str] = mapped_column(String, default="") # 兼容位掩码 hint(逗号分隔,可选) status: Mapped[str] = mapped_column(String, default="active") # active/disabled class ServiceProvider(Base): """服务商(运营端审核/评级/考核)。""" __tablename__ = "service_providers" id: Mapped[str] = mapped_column(String, primary_key=True) name: Mapped[str] = mapped_column(String, default="") category: Mapped[str] = mapped_column(String, default="") # 财税/工商/法务/知识产权/云服务... org_id: Mapped[str | None] = mapped_column(ForeignKey("organizations.id"), nullable=True) level: Mapped[str] = mapped_column(String, default="certified") # certified/premium/gold/official rating: Mapped[float] = mapped_column(Float, default=5.0) order_count: Mapped[int] = mapped_column(Integer, default=0) status: Mapped[str] = mapped_column(String, default="pending") # pending/active/blacklisted contact: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class ContentItem(Base): """平台内容(政策/课程/资讯/公告/活动)。""" __tablename__ = "content_items" id: Mapped[str] = mapped_column(String, primary_key=True) type: Mapped[str] = mapped_column(String, default="news") # policy/course/news/notice/activity title: Mapped[str] = mapped_column(String, default="") summary: Mapped[str] = mapped_column(String, default="") body: Mapped[str] = mapped_column(Text, default="") publisher_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) # 资讯富字段:封面/图集/视频/外链/发布人 cover: Mapped[str] = mapped_column(String, default="") # 加宽封面图 URL(3.35:1) cover_small: Mapped[str] = mapped_column(String, default="") # 小封面图 URL(1:1,可选) images_json: Mapped[str] = mapped_column(Text, default="[]") # 图集(JSON url 数组) video: Mapped[str] = mapped_column(String, default="") # 视频 URL video_cover: Mapped[str] = mapped_column(String, default="") # 视频封面 link: Mapped[str] = mapped_column(String, default="") # 外链 publisher_name: Mapped[str] = mapped_column(String, default="") # 发布人昵称快照 publisher_avatar: Mapped[str] = mapped_column(String, default="") # 发布人头像快照 read_count: Mapped[int] = mapped_column(Integer, default=0) # 阅读数 like_count: Mapped[int] = mapped_column(Integer, default=0) # 点赞数 share_count: Mapped[int] = mapped_column(Integer, default=0) # 分享数(每转发一次 +1) card_mode: Mapped[str] = mapped_column(String, default="big") # big 大图 | small 小图(运营端设) is_public: Mapped[bool] = mapped_column(Boolean, default=True) # 是否公开(公开=C端,否则仅园区大屏) source: Mapped[str] = mapped_column(String, default="operator") # operator 运营端 | carrier 园区端 tenant_id: Mapped[str] = mapped_column(String, default="") # 园区端发布所属园区 priority: Mapped[int] = mapped_column(Integer, default=0) # 优先级 0-999 越大越靠前(C端排序) status: Mapped[str] = mapped_column(String, default="draft") # draft/pending/published/offline(pending=待审核) published_at: Mapped[str] = mapped_column(String, default="") # 发布时间(可未来=定时发布;C端到点才可见) created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class ContentLike(Base): """资讯点赞(一人一赞,可取消)。""" __tablename__ = "content_likes" id: Mapped[str] = mapped_column(String, primary_key=True) content_id: Mapped[str] = mapped_column(String, default="", index=True) user_id: Mapped[str] = mapped_column(String, default="", index=True) created_at: Mapped[str] = mapped_column(String, default="") class ContentComment(Base): """资讯留言(支持回复:reply_to 为空=顶层,否则为父评论 id)。""" __tablename__ = "content_comments" id: Mapped[str] = mapped_column(String, primary_key=True) content_id: Mapped[str] = mapped_column(String, default="", index=True) user_id: Mapped[str] = mapped_column(String, default="") username: Mapped[str] = mapped_column(String, default="") nickname: Mapped[str] = mapped_column(String, default="") avatar: Mapped[str] = mapped_column(String, default="") content: Mapped[str] = mapped_column(Text, default="") reply_to: Mapped[str] = mapped_column(String, default="") # 父评论 id(回复嵌套) like_count: Mapped[int] = mapped_column(Integer, default=0) # 评论点赞数 created_at: Mapped[str] = mapped_column(String, default="") class ContentCommentLike(Base): """资讯评论点赞(一人一赞,可取消)。""" __tablename__ = "content_comment_likes" id: Mapped[str] = mapped_column(String, primary_key=True) comment_id: Mapped[str] = mapped_column(String, default="", index=True) user_id: Mapped[str] = mapped_column(String, default="", index=True) created_at: Mapped[str] = mapped_column(String, default="") class SystemConfig(Base): """平台系统配置(键值)。""" __tablename__ = "system_configs" key: Mapped[str] = mapped_column(String, primary_key=True) value: Mapped[str] = mapped_column(Text, default="") # 配置值(存量可达 300+ 字节,MySQL 用 MEDIUMTEXT) description: Mapped[str] = mapped_column(String, default="") # 配置说明(0037 补回:此前模型误删) updated_at: Mapped[str] = mapped_column(String, default="") class PortalDashboard(Base): """端口工作台聚合数据(按端口存 JSON 载荷,全部由服务端提供)。""" __tablename__ = "portal_dashboards" port: Mapped[str] = mapped_column(String, primary_key=True) payload: Mapped[str] = mapped_column(Text, default="{}") updated_at: Mapped[str] = mapped_column(String, default="") class PortalPage(Base): """端口子页面数据(按 端口+页面 存 JSON 载荷,全部由服务端提供)。""" __tablename__ = "portal_pages" port: Mapped[str] = mapped_column(String, primary_key=True) page: Mapped[str] = mapped_column(String, primary_key=True) payload: Mapped[str] = mapped_column(Text, default="{}") updated_at: Mapped[str] = mapped_column(String, default="") # ── 投资人端(投融资 · 路演 · 培训)────────────────────────────────────── class InvestorPreference(Base): """投资人投资方向偏好。""" __tablename__ = "investor_preferences" user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), primary_key=True, ) industries: Mapped[str] = mapped_column(String, default="[]") # JSON list stage: Mapped[str] = mapped_column(String, default="") # seed/angel/series_a/... amount_min: Mapped[int] = mapped_column(Integer, default=0) amount_max: Mapped[int] = mapped_column(Integer, default=0) region_id: Mapped[str | None] = mapped_column(ForeignKey("regions.id"), nullable=True) updated_at: Mapped[str] = mapped_column(String, default="") class Roadshow(Base): """投融资路演活动(线上/线下/混合),支持按发布主体与范围审核。""" __tablename__ = "roadshows" id: Mapped[str] = mapped_column(String, primary_key=True) publisher_id: Mapped[str] = mapped_column(String, default="") publisher_role: Mapped[str] = mapped_column(String, default="investor") # investor/government/operator/carrier/enterprise title: Mapped[str] = mapped_column(String, default="") summary: Mapped[str] = mapped_column(String, default="") activity_type: Mapped[str] = mapped_column(String, default="online") # online/offline/hybrid scope_type: Mapped[str] = mapped_column(String, default="all") # all/region/org region_id: Mapped[str | None] = mapped_column(ForeignKey("regions.id"), nullable=True) start_at: Mapped[str] = mapped_column(String, default="") end_at: Mapped[str] = mapped_column(String, default="") register_deadline: Mapped[str] = mapped_column(String, default="") quota: Mapped[int] = mapped_column(Integer, default=0) venue: Mapped[str] = mapped_column(String, default="") # 线下地点/直播间 live_url: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="draft") # draft/submitted/reviewing/published/registering/ongoing/ended/archived/rejected/cancelled review_comment: Mapped[str] = mapped_column(String, default="") need_review: Mapped[bool] = mapped_column(Boolean, default=True) created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class RoadshowRegistration(Base): """路演活动报名(项目方/投资人)。""" __tablename__ = "roadshow_registrations" id: Mapped[str] = mapped_column(String, primary_key=True) roadshow_id: Mapped[str] = mapped_column( ForeignKey("roadshows.id", ondelete="CASCADE"), nullable=False, ) user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False, ) role: Mapped[str] = mapped_column(String, default="investor") # investor/project status: Mapped[str] = mapped_column(String, default="applying") # applying/approved/attended/absent note: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class InvestmentIntent(Base): """投资意向/约谈/尽调。""" __tablename__ = "investment_intents" id: Mapped[str] = mapped_column(String, primary_key=True) investor_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False, ) project_id: Mapped[str] = mapped_column(String, default="") project_name: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="interested") # interested/contacted/meeting/term_sheet/invested/declined message: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class Bid(Base): """任务竞标(企业端竞标模式发标)。""" __tablename__ = "bids" id: Mapped[str] = mapped_column(String, primary_key=True) task_id: Mapped[str] = mapped_column( ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, ) opc_id: Mapped[str] = mapped_column(String, default="") opc_name: Mapped[str] = mapped_column(String, default="") quote: Mapped[int] = mapped_column(Integer, default=0) plan: Mapped[str] = mapped_column(String, default="") material: Mapped[str] = mapped_column(String, default="") # 投标/报名材料(URL,0035) status: Mapped[str] = mapped_column(String, default="submitted") # submitted/win/lost created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class SubsidyApplication(Base): """补贴申报(政务三级审批:区县→市→省→发放)。""" __tablename__ = "subsidy_applications" id: Mapped[str] = mapped_column(String, primary_key=True) opc_id: Mapped[str] = mapped_column(String, default="") opc_name: Mapped[str] = mapped_column(String, default="") title: Mapped[str] = mapped_column(String, default="") amount: Mapped[int] = mapped_column(Integer, default=0) region_id: Mapped[str | None] = mapped_column(ForeignKey("regions.id"), nullable=True) status: Mapped[str] = mapped_column(String, default="applying") # applying/district_review/city_review/province_review/approved/paid/rejected comment: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class ServiceReferral(Base): """载体-服务商引荐(三方绑定:载体引荐服务商→服务园区内 OPC)。""" __tablename__ = "service_referrals" id: Mapped[str] = mapped_column(String, primary_key=True) carrier_id: Mapped[str] = mapped_column(String, default="") provider_id: Mapped[str] = mapped_column(String, default="") provider_name: Mapped[str] = mapped_column(String, default="") opc_id: Mapped[str] = mapped_column(String, default="") opc_name: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="referred") # referred/accepted/completed/declined created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class InviteRecord(Base): """邀请归因记录:每次分享/扫码/注册都记录,支持完整归因链。""" __tablename__ = "invite_records" id: Mapped[str] = mapped_column(String, primary_key=True) inviter_id: Mapped[str] = mapped_column(String, default="", index=True) # 邀请人 invite_code: Mapped[str] = mapped_column(String, default="", index=True) # 邀请码 invitee_id: Mapped[str] = mapped_column(String, default="", index=True) # 被邀请人(注册后填充) invitee_openid: Mapped[str] = mapped_column(String, default="") # 被邀请人openid(扫码时记录) action: Mapped[str] = mapped_column(String, default="") # share|scan|register channel: Mapped[str] = mapped_column(String, default="") # qrcode|share_app|share_timeline|link scene: Mapped[str] = mapped_column(String, default="") # 场景:test_result|profile|home等 env: Mapped[str] = mapped_column(String, default="trial") # trial|release ip: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class TrainingEnrollment(Base): """投融资培训报名/证书。""" __tablename__ = "training_enrollments" id: Mapped[str] = mapped_column(String, primary_key=True) training_id: Mapped[str] = mapped_column(String, default="") training_name: Mapped[str] = mapped_column(String, default="") user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False, ) status: Mapped[str] = mapped_column(String, default="applying") # applying/enrolled/completed/certificate created_at: Mapped[str] = mapped_column(String, default="") # ── 横切能力:结算/合同/争议/评价/通知 ──────────────────────────────────── class Escrow(Base): """任务资金托管/结算。""" __tablename__ = "escrows" id: Mapped[str] = mapped_column(String, primary_key=True) task_id: Mapped[str] = mapped_column( ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, ) task_title: Mapped[str] = mapped_column(String, default="") amount: Mapped[int] = mapped_column(Integer, default=0) commission: Mapped[int] = mapped_column(Integer, default=0) # 平台佣金 status: Mapped[str] = mapped_column(String, default="deposited") # deposited/frozen/released/refunded # ── 微信服务商分账(资金托管)字段 ── channel: Mapped[str] = mapped_column(String, default="wx_split") # wx_split | bank_escrow | direct_pay | manual transaction_id: Mapped[str] = mapped_column(String, default="") # 微信支付单号(收单来源) payer_sub_mchid: Mapped[str] = mapped_column(String, default="") # 出资(收单)特约商户号,即分账出资方 share_order_no: Mapped[str] = mapped_column(String, default="") # 分账单号(幂等键) share_status: Mapped[str] = mapped_column(String, default="pending") # pending/sharing/shared/failed receiver_binding_id: Mapped[str] = mapped_column(String, default="") # 接单者收款绑定 id split_detail: Mapped[str] = mapped_column(Text, default="{}") # 分账生命周期快照(剩余待分/解冻/结果) created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class Contract(Base): """任务电子合同。""" __tablename__ = "contracts" id: Mapped[str] = mapped_column(String, primary_key=True) task_id: Mapped[str] = mapped_column( ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, ) task_title: Mapped[str] = mapped_column(String, default="") enterprise_id: Mapped[str] = mapped_column(String, default="") opc_id: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="signed") # draft/signed/terminated content: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class Dispute(Base): """任务争议。""" __tablename__ = "disputes" id: Mapped[str] = mapped_column(String, primary_key=True) task_id: Mapped[str] = mapped_column( ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, ) task_title: Mapped[str] = mapped_column(String, default="") initiator: Mapped[str] = mapped_column(String, default="") reason: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="opened") # opened/mediating/resolved/closed resolution: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class Rating(Base): """任务互评。""" __tablename__ = "ratings" id: Mapped[str] = mapped_column(String, primary_key=True) task_id: Mapped[str] = mapped_column( ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, ) from_id: Mapped[str] = mapped_column(String, default="") to_id: Mapped[str] = mapped_column(String, default="") score: Mapped[int] = mapped_column(Integer, default=5) # 1..5 comment: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class Notification(Base): """站内通知。""" __tablename__ = "notifications" id: Mapped[str] = mapped_column(String, primary_key=True) user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False, ) type: Mapped[str] = mapped_column(String, default="system") # task/policy/order/subsidy/system title: Mapped[str] = mapped_column(String, default="") content: Mapped[str] = mapped_column(String, default="") read: Mapped[bool] = mapped_column(Boolean, default=False) created_at: Mapped[str] = mapped_column(String, default="") # ── OPC 超级个体业务模型(工作台/我的任务/财务/消息)──────────────────── class OpcProfile(Base): """OPC 超级个体档案(信用评分等)。""" __tablename__ = "opc_profiles" user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), primary_key=True, ) credit_score: Mapped[int] = mapped_column(Integer, default=80) created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class FinanceRecord(Base): """OPC 财务流水(收入/支出)。""" __tablename__ = "finance_records" id: Mapped[str] = mapped_column(String, primary_key=True) user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False, ) category: Mapped[str] = mapped_column(String, default="income") # income | expense amount: Mapped[int] = mapped_column(Integer, default=0) date: Mapped[str] = mapped_column(String, default="") # YYYY-MM-DD note: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class Message(Base): """OPC 站内消息。""" __tablename__ = "messages" id: Mapped[str] = mapped_column(String, primary_key=True) user_id: Mapped[str] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False, ) msg_type: Mapped[str] = mapped_column(String, default="system") # task/policy/service/agent/system title: Mapped[str] = mapped_column(String, default="") content: Mapped[str] = mapped_column(String, default="") read: Mapped[bool] = mapped_column(Boolean, default=False) created_at: Mapped[str] = mapped_column(String, default="") # =+ # 培训业务子应用(原 app/training 独立 opc.db → 并入唯一总库) # =========================================================================== class TrainingAccount(Base): """培训站账号(原 accounts,含手机/微信登录)。""" __tablename__ = "accounts" id: Mapped[str | None] = mapped_column(String, primary_key=True) username: Mapped[str | None] = mapped_column(String, unique=True, nullable=False) wxid: Mapped[str | None] = mapped_column(String, default="") phone: Mapped[str | None] = mapped_column(String, default="") contact: Mapped[str | None] = mapped_column(String, default="") name: Mapped[str | None] = mapped_column(String, default="") avatar: Mapped[str | None] = mapped_column(String, default="") password: Mapped[str | None] = mapped_column(String, default="") phone_bound: Mapped[int | None] = mapped_column(Integer, default=0) identities: Mapped[str | None] = mapped_column(Text, default="[]") status_label: Mapped[str | None] = mapped_column(String, default="") topics: Mapped[str | None] = mapped_column(Text, default="") source: Mapped[str | None] = mapped_column(String, default="") created_at: Mapped[str | None] = mapped_column(String, default="") class Event(Base): __tablename__ = "events" id: Mapped[str | None] = mapped_column(String, primary_key=True) type: Mapped[str | None] = mapped_column(String, default="") mode: Mapped[str | None] = mapped_column(String, default="offline") title: Mapped[str | None] = mapped_column(String, default="") subtitle: Mapped[str | None] = mapped_column(String, default="") desc: Mapped[str | None] = mapped_column(Text, default="") location: Mapped[str | None] = mapped_column(String, default="") host: Mapped[str | None] = mapped_column(String, default="") image: Mapped[str | None] = mapped_column(String, default="") link: Mapped[str | None] = mapped_column(String, default="") start_at: Mapped[str | None] = mapped_column(String, default="") end_at: Mapped[str | None] = mapped_column(String, default="") checkin_at: Mapped[str | None] = mapped_column(String, default="") duration_min: Mapped[int | None] = mapped_column(Integer, default=90) capacity: Mapped[int | None] = mapped_column(Integer, default=0) show_capacity: Mapped[int | None] = mapped_column(Integer, default=0) audit_mode: Mapped[str | None] = mapped_column(String, default="auto") status: Mapped[str | None] = mapped_column(String, default="open") price_fen: Mapped[int | None] = mapped_column(Integer, default=0) # 定价(分),0=免费 # ── 活动体系扩展(区域/类型/范围/审核/富文本/外链报名) ── region: Mapped[str | None] = mapped_column(String, default="") # 昆明/曲靖/大理/丽江/版纳/楚雄/红河/其他 category: Mapped[str | None] = mapped_column(String, default="") # 峰会/竞赛/沙龙/培训/展会/投融资 scope: Mapped[str | None] = mapped_column(String, default="public") # park 本园区 | public 公开 target_tenant_id: Mapped[str | None] = mapped_column(String, default="") # scope=park 时目标园区 id review_status: Mapped[str | None] = mapped_column(String, default="approved") # draft|pending|approved|rejected review_comment: Mapped[str | None] = mapped_column(String, default="") review_by: Mapped[str | None] = mapped_column(String, default="") review_at: Mapped[str | None] = mapped_column(String, default="") body: Mapped[str | None] = mapped_column(Text, default="") # 活动介绍(富文本 HTML) notice: Mapped[str | None] = mapped_column(Text, default="") # 活动注意事项(与时间/地点/人数一并展示) external_url: Mapped[str | None] = mapped_column(String, default="") # 外链报名地址 signup_mode: Mapped[str | None] = mapped_column(String, default="mini") # mini 小程序报名 | external 外链报名 publisher_id: Mapped[str | None] = mapped_column(String, default="") # 发布者 publisher_name: Mapped[str | None] = mapped_column(String, default="") class Booking(Base): __tablename__ = "bookings" id: Mapped[str | None] = mapped_column(String, primary_key=True) created_at: Mapped[str | None] = mapped_column(String, default="") status: Mapped[str | None] = mapped_column(String, default="pending") audit_status: Mapped[str | None] = mapped_column(String, default="pending") username: Mapped[str | None] = mapped_column(String, default="") name: Mapped[str | None] = mapped_column(String, default="") contact: Mapped[str | None] = mapped_column(String, default="") status_label: Mapped[str | None] = mapped_column(String, default="") want: Mapped[str | None] = mapped_column(Text, default="") event_id: Mapped[str | None] = mapped_column(String, default="") event_title: Mapped[str | None] = mapped_column(String, default="") event_start: Mapped[str | None] = mapped_column(String, default="") topics: Mapped[str | None] = mapped_column(Text, default="") question: Mapped[str | None] = mapped_column(Text, default="") source: Mapped[str | None] = mapped_column(String, default="") checkin_at: Mapped[str | None] = mapped_column(String, default="") pay_status: Mapped[str | None] = mapped_column(String, default="") # ''|unpaid|paid(付费活动) order_no: Mapped[str | None] = mapped_column(String, default="") # 关联 event_orders.order_no appeal_status: Mapped[str | None] = mapped_column(String, default="") # ''|pending|approved|rejected(爽约申诉) appeal_reason: Mapped[str | None] = mapped_column(Text, default="") appeal_at: Mapped[str | None] = mapped_column(String, default="") class Test(Base): __tablename__ = "tests" id: Mapped[str | None] = mapped_column(String, primary_key=True) created_at: Mapped[str | None] = mapped_column(String, default="") username: Mapped[str | None] = mapped_column(String, default="") type_code: Mapped[str | None] = mapped_column(String, default="") persona: Mapped[str | None] = mapped_column(String, default="") adapt_index: Mapped[int | None] = mapped_column(Integer, default=0) adapt_level: Mapped[str | None] = mapped_column(String, default="") tracks: Mapped[str | None] = mapped_column(Text, default="") version: Mapped[str | None] = mapped_column(String, default="") class Course(Base): __tablename__ = "courses" id: Mapped[str | None] = mapped_column(String, primary_key=True) category: Mapped[str | None] = mapped_column(String, default="") level: Mapped[str | None] = mapped_column(String, default="") title: Mapped[str | None] = mapped_column(String, default="") subtitle: Mapped[str | None] = mapped_column(String, default="") desc: Mapped[str | None] = mapped_column(Text, default="") price: Mapped[float | None] = mapped_column(Float, default=0.0) status: Mapped[str | None] = mapped_column(String, default="draft") start_at: Mapped[str | None] = mapped_column(String, default="") end_at: Mapped[str | None] = mapped_column(String, default="") venue: Mapped[str | None] = mapped_column(String, default="") quota: Mapped[int | None] = mapped_column(Integer, default=0) image: Mapped[str | None] = mapped_column(String, default="") host: Mapped[str | None] = mapped_column(String, default="") created_at: Mapped[str | None] = mapped_column(String, default="") class PolicyLog(Base): __tablename__ = "policy_logs" id: Mapped[str | None] = mapped_column(String, primary_key=True) created_at: Mapped[str | None] = mapped_column(String, default="") username: Mapped[str | None] = mapped_column(String, default="") answers: Mapped[str | None] = mapped_column(Text, default="") policies_count: Mapped[int | None] = mapped_column(Integer, default=0) subsidies_count: Mapped[int | None] = mapped_column(Integer, default=0) loans_count: Mapped[int | None] = mapped_column(Integer, default=0) summary: Mapped[str | None] = mapped_column(Text, default="") class PlanLog(Base): __tablename__ = "plan_logs" id: Mapped[str | None] = mapped_column(String, primary_key=True) created_at: Mapped[str | None] = mapped_column(String, default="") username: Mapped[str | None] = mapped_column(String, default="") region: Mapped[str | None] = mapped_column(String, default="") status: Mapped[str | None] = mapped_column(String, default="") need_park: Mapped[int | None] = mapped_column(Integer, default=0) has_staff: Mapped[int | None] = mapped_column(Integer, default=0) steps_count: Mapped[int | None] = mapped_column(Integer, default=0) class SurveyLog(Base): __tablename__ = "survey_logs" id: Mapped[str | None] = mapped_column(String, primary_key=True) created_at: Mapped[str | None] = mapped_column(String, default="") username: Mapped[str | None] = mapped_column(String, default="") source: Mapped[str | None] = mapped_column(String, default="") answers: Mapped[str | None] = mapped_column(Text, default="") # =========================================================================== # 园区子应用(原 app/park 独立 park.db → 并入唯一总库) # =========================================================================== class ParkTenant(Base): __tablename__ = "park_tenants" id: Mapped[str] = mapped_column(String, primary_key=True) name: Mapped[str] = mapped_column(String, default="") intro_json: Mapped[str] = mapped_column(Text, default="[]") username: Mapped[str] = mapped_column(String, default="") salt: Mapped[str] = mapped_column(String, default="") password_hash: Mapped[str] = mapped_column(String, default="") admin_username: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="active") data_json: Mapped[str] = mapped_column(Text, default="{}") agent_json: Mapped[str] = mapped_column(Text, default="{}") operator_user_id: Mapped[str] = mapped_column(String, default="") # 园区归属载体账号,园区端据此只审本园区 # ── 载体资料(云南载体地图对外展示,0034) ── lng: Mapped[float | None] = mapped_column(Float, nullable=True) # 经度(点阵地图渲染) lat: Mapped[float | None] = mapped_column(Float, nullable=True) # 纬度 cover: Mapped[str] = mapped_column(String, default="") # 封面图 URL address: Mapped[str] = mapped_column(String, default="") # 详细地址 city: Mapped[str] = mapped_column(String, default="") # 区域(昆明/曲靖/大理/丽江/版纳/楚雄/红河/其他) intro_html: Mapped[str] = mapped_column(Text, default="") # 园区介绍(富文本 HTML) policy_html: Mapped[str] = mapped_column(Text, default="") # 政策支持(富文本 HTML) admission_html: Mapped[str] = mapped_column(Text, default="") # 入驻流程(富文本 HTML) contact: Mapped[str] = mapped_column(String, default="") # 联系方式 tags: Mapped[str] = mapped_column(String, default="") # 标签(逗号分隔) stats_json: Mapped[str] = mapped_column(Text, default="") # 展示统计 JSON [{label,value}] area_m2: Mapped[int] = mapped_column(Integer, default=0) # 面积(m²,0035 实体社区) services_json: Mapped[str] = mapped_column(Text, default="[]") # 服务内容(JSON 数组,0035 实体社区) profile_status: Mapped[str] = mapped_column(String, default="approved") # approved 已生效 | pending 载体端改动待审 profile_draft_json: Mapped[str] = mapped_column(Text, default="") # 载体端待审草案(JSON) profile_review_comment: Mapped[str] = mapped_column(String, default="") profile_reviewed_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class ParkCompany(Base): __tablename__ = "park_companies" id: Mapped[str] = mapped_column(String, primary_key=True) tenant_id: Mapped[str | None] = mapped_column(ForeignKey("park_tenants.id", ondelete="CASCADE"), nullable=True, index=True) company_kind: Mapped[str] = mapped_column(String, default="park_entered") # park_entered 园区入驻 | independent 独立(tenant_id 为空) name: Mapped[str] = mapped_column(String, default="") zone: Mapped[str] = mapped_column(String, default="") room: Mapped[str] = mapped_column(String, default="") industry: Mapped[str] = mapped_column(String, default="") bio: Mapped[str] = mapped_column(Text, default="") founder: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="applying") employees: Mapped[int | None] = mapped_column(Integer, nullable=True) # 企业丰富资料(参考入园申请表 §二 企业信息) legal_person: Mapped[str] = mapped_column(String, default="") # 法定代表人 legal_phone: Mapped[str] = mapped_column(String, default="") # 法人联系电话 registered_capital: Mapped[str] = mapped_column(String, default="") # 注册资本(万元) company_type: Mapped[str] = mapped_column(String, default="") # 企业类型/性质 honors: Mapped[str] = mapped_column(Text, default="") # 所获政策/荣誉 address: Mapped[str] = mapped_column(String, default="") # 企业地址 contact_phone: Mapped[str] = mapped_column(String, default="") # 企业联系人电话 founded_at: Mapped[str] = mapped_column(String, default="") # 成立时间 emp_total: Mapped[int | None] = mapped_column(Integer, nullable=True) # 职工总数 emp_grad: Mapped[int | None] = mapped_column(Integer, nullable=True) # 毕业大学生 emp_layoff: Mapped[int | None] = mapped_column(Integer, nullable=True) # 失业人员 emp_veteran: Mapped[int | None] = mapped_column(Integer, nullable=True) # 退役军人 emp_migrant: Mapped[int | None] = mapped_column(Integer, nullable=True) # 返乡农民工 # 企业算力(只增不减):折扣% off 模型价;配额为发放给成员的算力额度 compute_discount: Mapped[int] = mapped_column(Integer, default=0) # 折扣%(0-100,单调非降) compute_quota: Mapped[int] = mapped_column(Integer, default=0) # 企业算力配额(单调非降/增量) compute_quota_used: Mapped[int] = mapped_column(Integer, default=0) # 已分配/已用配额(统计) engine_group: Mapped[str] = mapped_column(String, default="") # 引擎用户组名(折扣倍率载体) owner_user_id: Mapped[str] = mapped_column(String, default="") # 负责人/管理员账号id(必填) created_at: Mapped[str] = mapped_column(String, default="") class ParkKbDoc(Base): __tablename__ = "park_kb_docs" id: Mapped[str] = mapped_column(String, primary_key=True) tenant_id: Mapped[str] = mapped_column(ForeignKey("park_tenants.id", ondelete="CASCADE"), nullable=False, index=True) grp: Mapped[str] = mapped_column(String, default="general") title: Mapped[str] = mapped_column(String, default="") content_md: Mapped[str] = mapped_column(Text, default="") created_at: Mapped[str] = mapped_column(String, default="") class ParkSetting(Base): """园区全局配置 kv(如视频识别开关/地址),admin 经 /park/admin/* 读写,运行时不建表/不灌种子。""" __tablename__ = "park_settings" key: Mapped[str] = mapped_column(String, primary_key=True) value: Mapped[str] = mapped_column(Text, default="") updated_at: Mapped[str] = mapped_column(String, default="") class ParkAdmission(Base): """园区入驻申请(C端 小程序/网页提交,园区/运营端审核)。 表单字段以 JSON 存入 form_json(申请人/企业/项目/入驻需求), 上传资料 URL 存 docs_json(创业计划书/身份证/学历/执照/资质等)。 """ __tablename__ = "park_admissions" id: Mapped[str] = mapped_column(String, primary_key=True) tenant_id: Mapped[str] = mapped_column(String, default="") # 所选园区 id tenant_name: Mapped[str] = mapped_column(String, default="") # 冗余园区名(展示) user_id: Mapped[str] = mapped_column(String, default="", index=True) # 申请人平台用户 id username: Mapped[str] = mapped_column(String, default="") # 申请人登录名 applicant_name: Mapped[str] = mapped_column(String, default="") # 申请人姓名(快速列表展示) contact_phone: Mapped[str] = mapped_column(String, default="") # 联系电话(列表展示) status: Mapped[str] = mapped_column(String, default="pending") # pending/reviewing/approved/rejected form_json: Mapped[str] = mapped_column(Text, default="{}") # 结构化表单(申请人/企业/项目/需求) docs_json: Mapped[str] = mapped_column(Text, default="{}") # 上传资料 URL 集合 source: Mapped[str] = mapped_column(String, default="miniprogram") # miniprogram|web review_comment: Mapped[str] = mapped_column(String, default="") reviewed_by: Mapped[str] = mapped_column(String, default="") reviewed_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class ParkScreen(Base): __tablename__ = "park_screens" id: Mapped[str] = mapped_column(String, primary_key=True) tenant_id: Mapped[str | None] = mapped_column(ForeignKey("park_tenants.id", ondelete="CASCADE"), nullable=True, index=True) device_id: Mapped[str] = mapped_column(String, default="", index=True) name: Mapped[str] = mapped_column(String, default="") role: Mapped[str] = mapped_column(String, default="main") location: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="unbound") # unbound | bound code: Mapped[str] = mapped_column(String, default="") # 待绑定连接码 code_expires: Mapped[str] = mapped_column(String, default="") # 码过期时间(ISO) bound_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class OpcCertification(Base): """OPC 认证申请表(用户提交资料 → 运营方审核)。""" __tablename__ = "opc_certifications" id: Mapped[str] = mapped_column(String, primary_key=True) user_id: Mapped[str] = mapped_column(String, default="", index=True) username: Mapped[str] = mapped_column(String, default="") real_name: Mapped[str] = mapped_column(String, default="") gender: Mapped[str] = mapped_column(String, default="") address: Mapped[str] = mapped_column(String, default="") industry: Mapped[str] = mapped_column(String, default="") ability: Mapped[str] = mapped_column(Text, default="") phone: Mapped[str] = mapped_column(String, default="") docs_json: Mapped[str] = mapped_column(Text, default="{}") status: Mapped[str] = mapped_column(String, default="pending") review_comment: Mapped[str] = mapped_column(String, default="") reviewed_by: Mapped[str] = mapped_column(String, default="") reviewed_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class ParkTransfer(Base): """OPC/企业 转园申请表(运营端/园区端/企业管理员/用户本人发起 → 转出园区+转入园区两级审核,运营端兜底)。""" __tablename__ = "park_transfers" id: Mapped[str] = mapped_column(String, primary_key=True) user_id: Mapped[str] = mapped_column(String, default="", index=True) username: Mapped[str] = mapped_column(String, default="") from_park_id: Mapped[str] = mapped_column(String, default="") from_park_name: Mapped[str] = mapped_column(String, default="") to_park_id: Mapped[str] = mapped_column(String, default="") to_park_name: Mapped[str] = mapped_column(String, default="") reason: Mapped[str] = mapped_column(Text, default="") status: Mapped[str] = mapped_column(String, default="pending") # 当前阶段冗余(对外展示) # ── 两级审核状态机 ── stage: Mapped[str] = mapped_column(String, default="pending_from") # pending_from→pending_to→approved/rejected/cancelled from_status: Mapped[str] = mapped_column(String, default="pending") # pending/approved/rejected to_status: Mapped[str] = mapped_column(String, default="pending") from_reviewer_id: Mapped[str] = mapped_column(String, default="") to_reviewer_id: Mapped[str] = mapped_column(String, default="") operator_reviewer_id: Mapped[str] = mapped_column(String, default="") # 运营端兜底终审人 from_reviewed_at: Mapped[str] = mapped_column(String, default="") to_reviewed_at: Mapped[str] = mapped_column(String, default="") review_comment: Mapped[str] = mapped_column(String, default="") reviewed_by: Mapped[str] = mapped_column(String, default="") reviewed_at: Mapped[str] = mapped_column(String, default="") # ── 扩展:发起方与目标 ── initiator_role: Mapped[str] = mapped_column(String, default="user") # operator/carrier/enterprise/user target_kind: Mapped[str] = mapped_column(String, default="user") # user 用户转园 | company 企业整体转园 company_id: Mapped[str] = mapped_column(String, default="") # target_kind=company 时的企业 id created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class ParkMember(Base): """用户↔园区 成员关系(多对多)。 用户可同时归属多个园区;users.affiliation/park_id/park_name 为派生展示冗余 (由 services.membership.sync_user_affiliation 统一刷新),任何端口不得直接改写。 """ __tablename__ = "park_members" __table_args__ = (UniqueConstraint("user_id", "park_id", name="uq_park_member"),) id: Mapped[str] = mapped_column(String, primary_key=True) user_id: Mapped[str] = mapped_column(String, index=True) park_id: Mapped[str] = mapped_column(String, index=True) member_type: Mapped[str] = mapped_column(String, default="staff") # admin 园区管理员 | staff 园区成员 | migrated 迁移 status: Mapped[str] = mapped_column(String, default="active") # active | disabled created_by: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class CompanyMember(Base): """用户↔企业 成员关系(多对多)。 每家企业至多一名 is_admin=True 的企业管理员(与 park_companies.owner_user_id 同步维护)。 """ __tablename__ = "company_members" __table_args__ = (UniqueConstraint("user_id", "company_id", name="uq_company_member"),) id: Mapped[str] = mapped_column(String, primary_key=True) user_id: Mapped[str] = mapped_column(String, index=True) company_id: Mapped[str] = mapped_column(String, index=True) is_admin: Mapped[bool] = mapped_column(Boolean, default=False) # 企业管理员 member_type: Mapped[str] = mapped_column(String, default="staff") # admin/staff/owner/migrated status: Mapped[str] = mapped_column(String, default="active") created_by: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") # =========================================================================== # 大厅 + 社区(大厅与社区升级设计 0035) # =========================================================================== class Job(Base): """岗位(企业招聘需求,岗位大厅;admin 审核后发布)。""" __tablename__ = "jobs" id: Mapped[str] = mapped_column(String, primary_key=True) company_id: Mapped[str | None] = mapped_column(ForeignKey("organizations.id"), nullable=True) company_name: Mapped[str] = mapped_column(String, default="") title: Mapped[str] = mapped_column(String, default="") category: Mapped[str] = mapped_column(String, default="") # 技术/设计/运营/市场/职能 description: Mapped[str] = mapped_column(Text, default="") # 岗位职责 requirement: Mapped[str] = mapped_column(Text, default="") # 任职要求 tags: Mapped[str] = mapped_column(String, default="") # 逗号分隔 salary_min: Mapped[int] = mapped_column(Integer, default=0) # 月薪下限(元,0=面议) salary_max: Mapped[int] = mapped_column(Integer, default=0) location: Mapped[str] = mapped_column(String, default="") # 工作地点(云南省内) work_type: Mapped[str] = mapped_column(String, default="fulltime") # fulltime/parttime/intern/remote headcount: Mapped[int] = mapped_column(Integer, default=1) contact: Mapped[str] = mapped_column(String, default="") publisher_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) status: Mapped[str] = mapped_column(String, default="pending") # pending/published/closed published_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class JobApplication(Base): """岗位投递(OPC/求职者 → 岗位;企业端可见)。""" __tablename__ = "job_applications" id: Mapped[str] = mapped_column(String, primary_key=True) job_id: Mapped[str] = mapped_column(ForeignKey("jobs.id", ondelete="CASCADE"), index=True) user_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) user_name: Mapped[str] = mapped_column(String, default="") contact: Mapped[str] = mapped_column(String, default="") # 联系方式 note: Mapped[str] = mapped_column(Text, default="") # 意向说明 status: Mapped[str] = mapped_column(String, default="submitted") # submitted/viewed/accepted/rejected created_at: Mapped[str] = mapped_column(String, default="") class OpcService(Base): """OPC 服务与产品(个人服务,服务大厅主体;区别于机构 service_providers)。""" __tablename__ = "opc_services" id: Mapped[str] = mapped_column(String, primary_key=True) opc_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) opc_name: Mapped[str] = mapped_column(String, default="") title: Mapped[str] = mapped_column(String, default="") category: Mapped[str] = mapped_column(String, default="") # 复用任务分类(isPublishService) description: Mapped[str] = mapped_column(Text, default="") cover: Mapped[str] = mapped_column(String, default="") gallery_json: Mapped[str] = mapped_column(Text, default="[]") # 作品集 URL 数组 price: Mapped[int] = mapped_column(Integer, default=0) # 定价(元,0=面议) delivery_days: Mapped[int] = mapped_column(Integer, default=0) # 交付时限(天) tags: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="pending") # pending/published/offline rating: Mapped[float] = mapped_column(Float, default=5.0) order_count: Mapped[int] = mapped_column(Integer, default=0) created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class ServiceInquiry(Base): """服务询单/下单意向(首版落站内联系,后续可接托管结算)。""" __tablename__ = "service_inquiries" id: Mapped[str] = mapped_column(String, primary_key=True) service_id: Mapped[str] = mapped_column(ForeignKey("opc_services.id", ondelete="CASCADE"), index=True) user_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) user_name: Mapped[str] = mapped_column(String, default="") contact: Mapped[str] = mapped_column(String, default="") note: Mapped[str] = mapped_column(Text, default="") status: Mapped[str] = mapped_column(String, default="open") # open/contacted/closed created_at: Mapped[str] = mapped_column(String, default="") class TalentProfile(Base): """人才档案(OPC + 求职者唯一主表;opc_profiles 保留信用分/资格)。""" __tablename__ = "talent_profiles" user_id: Mapped[str] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), primary_key=True) talent_type: Mapped[str] = mapped_column(String, default="opc") # opc/seeker display_name: Mapped[str] = mapped_column(String, default="") avatar: Mapped[str] = mapped_column(String, default="") headline: Mapped[str] = mapped_column(String, default="") # 一句话头衔 bio: Mapped[str] = mapped_column(Text, default="") # 自我介绍 fields_json: Mapped[str] = mapped_column(Text, default="[]") # 领域数组 skills_json: Mapped[str] = mapped_column(Text, default="[]") # 技能数组 work_years: Mapped[int] = mapped_column(Integer, default=0) education: Mapped[str] = mapped_column(String, default="") region: Mapped[str] = mapped_column(String, default="") # 常驻地区(云南省内) cases_count: Mapped[int] = mapped_column(Integer, default=0) contact_ok: Mapped[bool] = mapped_column(Boolean, default=True) # 是否允许企业联系 published: Mapped[bool] = mapped_column(Boolean, default=True) # 是否上架人才大厅 created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class CommunityPost(Base): """线上社区帖子(OPC 交流;admin 可置顶/隐藏)。""" __tablename__ = "community_posts" id: Mapped[str] = mapped_column(String, primary_key=True) author_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) author_name: Mapped[str] = mapped_column(String, default="") avatar: Mapped[str] = mapped_column(String, default="") topic: Mapped[str] = mapped_column(String, default="交流") # 交流/求助/资源/经验/公告 title: Mapped[str] = mapped_column(String, default="") content: Mapped[str] = mapped_column(Text, default="") images_json: Mapped[str] = mapped_column(Text, default="[]") like_count: Mapped[int] = mapped_column(Integer, default=0) comment_count: Mapped[int] = mapped_column(Integer, default=0) status: Mapped[str] = mapped_column(String, default="published") # pending/published/hidden pinned: Mapped[bool] = mapped_column(Boolean, default=False) created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class CommunityComment(Base): """社区评论(楼中楼:parent_id 指向父评论)。""" __tablename__ = "community_comments" id: Mapped[str] = mapped_column(String, primary_key=True) post_id: Mapped[str] = mapped_column(ForeignKey("community_posts.id", ondelete="CASCADE"), index=True) author_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) author_name: Mapped[str] = mapped_column(String, default="") parent_id: Mapped[str] = mapped_column(String, default="") content: Mapped[str] = mapped_column(Text, default="") created_at: Mapped[str] = mapped_column(String, default="") class CommunityLike(Base): """社区点赞(帖子/评论;一人一目标一条)。""" __tablename__ = "community_likes" __table_args__ = (UniqueConstraint("target_type", "target_id", "user_id", name="uq_community_like"),) id: Mapped[str] = mapped_column(String, primary_key=True) target_type: Mapped[str] = mapped_column(String, default="post") # post/comment target_id: Mapped[str] = mapped_column(String, index=True) user_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) created_at: Mapped[str] = mapped_column(String, default="") class CommunityFollow(Base): """社区关注(人与帖子/作者/载体)。""" __tablename__ = "community_follows" id: Mapped[str] = mapped_column(String, primary_key=True) follower_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) target_type: Mapped[str] = mapped_column(String, default="carrier") # carrier/author target_id: Mapped[str] = mapped_column(String, index=True) created_at: Mapped[str] = mapped_column(String, default="") # =========================================================================== # 市场子应用(技能 / 插件 / 应用统一官方市场) # =========================================================================== class MarketItem(Base): """市场目录条目(skill / plugin / app 三类商品统一表)。 状态机:draft → pending → published ⇄ offline;pending → rejected;rejected → draft。 定价:plugin / app 支持 price_fen(0=免费);skill 恒为 0。 """ __tablename__ = "market_items" id: Mapped[str] = mapped_column(String, primary_key=True) # mi_ item_type: Mapped[str] = mapped_column(String, default="skill", index=True) # skill|plugin|app slug: Mapped[str] = mapped_column(String, default="") # 唯一业务标识(同 type 内唯一) name: Mapped[str] = mapped_column(String, default="") description: Mapped[str] = mapped_column(Text, default="") version: Mapped[str] = mapped_column(String, default="1.0.0") author: Mapped[str] = mapped_column(String, default="") owner: Mapped[str] = mapped_column(String, default="") # 开发方/归属 icon_url: Mapped[str] = mapped_column(String, default="") # OSS 对象路径 category: Mapped[str] = mapped_column(String, default="") tags_json: Mapped[str] = mapped_column(Text, default="[]") locale_json: Mapped[str] = mapped_column(Text, default="{}") bundle_json: Mapped[str] = mapped_column(Text, default="{}") # 安装包元数据(skill 内嵌完整 SKILL.md;MySQL 已 ALTER 为 MEDIUMTEXT) bundle_url: Mapped[str] = mapped_column(String, default="") # OSS 对象路径(plugin/app zip) bundle_sha256: Mapped[str] = mapped_column(String, default="") price_fen: Mapped[int] = mapped_column(Integer, default=0) # 定价(分);0=免费(skill 恒 0) stats_json: Mapped[str] = mapped_column(Text, default="{}") # {"downloads":0,"views":0,"likes":0} is_featured: Mapped[int] = mapped_column(Integer, default=0) status: Mapped[str] = mapped_column(String, default="draft", index=True) # draft|pending|published|rejected|offline reject_reason: Mapped[str] = mapped_column(String, default="") publisher_id: Mapped[str] = mapped_column(String, default="") published_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class MarketPurchaseOrder(Base): """市场购买订单(插件 / 应用定价消费,微信支付 V3,复用充值 mp 扫码→小程序支付)。 状态机与充值订单一致:pending → paid(支付成功)→ credited(权益发放完成); pending 超时未支付 → closed;发放异常 → failed(对账补单)。 """ __tablename__ = "market_purchase_orders" id: Mapped[str] = mapped_column(String, primary_key=True) # mo_ order_no: Mapped[str] = mapped_column(String, unique=True, index=True) # MK__,微信 out_trade_no item_id: Mapped[str] = mapped_column(String, default="", index=True) # market_items.id item_type: Mapped[str] = mapped_column(String, default="plugin") item_name: Mapped[str] = mapped_column(String, default="") user_id: Mapped[str] = mapped_column(String, default="", index=True) username: Mapped[str] = mapped_column(String, default="") amount_fen: Mapped[int] = mapped_column(Integer, default=0) # 实付金额(分) client_type: Mapped[str] = mapped_column(String, default="mp") # mp(小程序码) | jsapi | native appid: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="pending", index=True) prepay_id: Mapped[str] = mapped_column(String, default="") transaction_id: Mapped[str] = mapped_column(String, default="", index=True) code_url: Mapped[str] = mapped_column(String, default="") expires_at: Mapped[str] = mapped_column(String, default="") paid_at: Mapped[str] = mapped_column(String, default="") credited_at: Mapped[str] = mapped_column(String, default="") notify_payload: Mapped[str] = mapped_column(Text, default="") created_at: Mapped[str] = mapped_column(String, default="", index=True) updated_at: Mapped[str] = mapped_column(String, default="") class MarketPurchase(Base): """购买权益记录(支付到账后发放;免费安装也写一条,金额 0)。 桌面端安装插件/应用前据此判断「已购 / 未购」。 """ __tablename__ = "market_purchases" id: Mapped[str] = mapped_column(String, primary_key=True) # mp_ user_id: Mapped[str] = mapped_column(String, default="", index=True) item_id: Mapped[str] = mapped_column(String, default="", index=True) item_type: Mapped[str] = mapped_column(String, default="plugin") amount_fen: Mapped[int] = mapped_column(Integer, default=0) order_no: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class ServiceOrder(Base): """服务订单(服务大厅:预约/下单 → 卖方接单 → 交付 → 买方完成)。 状态机:pending → accepted → in_progress → delivered → completed; pending → rejected / cancelled;accepted|in_progress → cancelled。 """ __tablename__ = "service_orders" id: Mapped[str] = mapped_column(String, primary_key=True) service_id: Mapped[str] = mapped_column(ForeignKey("opc_services.id", ondelete="CASCADE"), index=True) opc_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) # 服务提供者 buyer_id: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True) buyer_name: Mapped[str] = mapped_column(String, default="") contact: Mapped[str] = mapped_column(String, default="") schedule_at: Mapped[str] = mapped_column(String, default="") # 预约时间 price: Mapped[int] = mapped_column(Integer, default=0) # 成交价(元,0=按服务定价) note: Mapped[str] = mapped_column(Text, default="") status: Mapped[str] = mapped_column(String, default="pending") accept_at: Mapped[str] = mapped_column(String, default="") delivered_at: Mapped[str] = mapped_column(String, default="") completed_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") # =========================================================================== # 创业园运营子应用(incubator 0040)—— 月度报告 / 共享区域 / 使用申请 # =========================================================================== class IncubatorMonthlyReport(Base): """创业园月度运行情况报告(对齐《入驻创业企业(项目)运行情况统计表》)。 一企业一月一报告(tenant_id + company_id + report_month 唯一)。 状态机:draft → submitted → approved / rejected(submitted 未审核可撤回 draft 重改)。 """ __tablename__ = "incubator_monthly_reports" __table_args__ = ( UniqueConstraint("tenant_id", "company_id", "report_month", name="uq_incubator_report_company_month"), ) id: Mapped[str] = mapped_column(String, primary_key=True) # mr_ tenant_id: Mapped[str] = mapped_column(String, default="", index=True) company_id: Mapped[str] = mapped_column(String, default="", index=True) company_name: Mapped[str] = mapped_column(String, default="") report_month: Mapped[str] = mapped_column(String, default="") # 2026-08 status: Mapped[str] = mapped_column(String, default="draft", index=True) # draft|submitted|approved|rejected # —— 企业基础信息(统计表前段,填报时自动带出可改) —— zone: Mapped[str] = mapped_column(String, default="") # 孵化区域 unit_no: Mapped[str] = mapped_column(String, default="") # 单元号 park_entry_date: Mapped[str] = mapped_column(String, default="") # 入园时间 leader_name: Mapped[str] = mapped_column(String, default="") # 负责人姓名 registered_at: Mapped[str] = mapped_column(String, default="") # 注册时间 registered_capital_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 注册资金(万元) credit_code: Mapped[str] = mapped_column(String, default="") # 统一信用代码 # —— 当月经营指标(统计表) —— rd_invest_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 研发当月投入(万) month_revenue_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 当月营业额(万) avg_year_revenue_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 年平均营业额(万) month_gross_profit_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 当月毛利润(万) month_tax_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 当月缴税(万) avg_year_tax_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 年平均缴税(万) loan_startup_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 创业担保贷款(万) loan_yunling_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 云岭创业贷款(万) contest_award_wan: Mapped[float | None] = mapped_column(Float, nullable=True) # 创业大赛扶持(万) patents: Mapped[int | None] = mapped_column(Integer, nullable=True) # 获得专利(项) jobs_created: Mapped[int | None] = mapped_column(Integer, nullable=True) # 带动就业人数 # —— 团队 / 经营 / 建议 —— team_json: Mapped[str] = mapped_column(Text, default="[]") # [{name, school_major, grad_time, position}] business_note: Mapped[str] = mapped_column(Text, default="") # 公司经营状况 suggestion: Mapped[str] = mapped_column(Text, default="") # 对园区建议意见 # —— 落款 / 审核 —— filler_name: Mapped[str] = mapped_column(String, default="") # 填表人 filler_email: Mapped[str] = mapped_column(String, default="") # 邮箱 submitted_at: Mapped[str] = mapped_column(String, default="") # 填表时间 reviewer_id: Mapped[str] = mapped_column(String, default="") review_comment: Mapped[str] = mapped_column(Text, default="") reviewed_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class IncubatorSharedArea(Base): """创业园共享区域资源(共享直播间 / 会议室)。 对齐《共享区域使用登记表》"□共享直播间 / □会议室";用途活动/会议在申请单填写。 """ __tablename__ = "incubator_shared_areas" id: Mapped[str] = mapped_column(String, primary_key=True) # area_ tenant_id: Mapped[str] = mapped_column(String, default="", index=True) name: Mapped[str] = mapped_column(String, default="") area_type: Mapped[str] = mapped_column(String, default="meeting", index=True) # live|meeting location: Mapped[str] = mapped_column(String, default="") capacity: Mapped[int | None] = mapped_column(Integer, nullable=True) facilities_json: Mapped[str] = mapped_column(Text, default="[]") cover_url: Mapped[str] = mapped_column(String, default="") open_hour_start: Mapped[str] = mapped_column(String, default="09:00") open_hour_end: Mapped[str] = mapped_column(String, default="18:00") max_minutes: Mapped[int | None] = mapped_column(Integer, nullable=True) enabled: Mapped[bool] = mapped_column(Boolean, default=True) status: Mapped[str] = mapped_column(String, default="normal") # normal|maintenance|closed 运营标记 status_note: Mapped[str] = mapped_column(Text, default="") # 标记说明(如"设备检修中") created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class IncubatorAreaReservation(Base): """共享区域使用申请(对齐《共享区域使用登记表》全部字段)。 状态机:pending → approved / rejected / cancelled → finished。 备案字段(已接收备案 / 已告知安全注意事项 + 经办人 + 日期)由管理方审批时填写。 """ __tablename__ = "incubator_area_reservations" id: Mapped[str] = mapped_column(String, primary_key=True) # rsv_ tenant_id: Mapped[str] = mapped_column(String, default="", index=True) area_id: Mapped[str] = mapped_column(String, default="", index=True) area_name: Mapped[str] = mapped_column(String, default="") area_type: Mapped[str] = mapped_column(String, default="meeting") company_id: Mapped[str] = mapped_column(String, default="", index=True) company_name: Mapped[str] = mapped_column(String, default="") # 申请企业名称(填写全称) user_id: Mapped[str] = mapped_column(String, default="") start_at: Mapped[str] = mapped_column(String, default="") # 使用日期起(月 日 时) end_at: Mapped[str] = mapped_column(String, default="") # 使用日期止(支持跨天) attendees: Mapped[int | None] = mapped_column(Integer, nullable=True) # 使用总人数 purpose: Mapped[str] = mapped_column(String, default="meeting") # activity|meeting 用途(活动|会议) leader_name: Mapped[str] = mapped_column(String, default="") # 企业负责人姓名 leader_phone: Mapped[str] = mapped_column(String, default="") # 企业负责人手机 contact_name: Mapped[str] = mapped_column(String, default="") # 紧急备用联系人姓名 contact_phone: Mapped[str] = mapped_column(String, default="") # 紧急备用联系人手机 agreed_commitment: Mapped[bool] = mapped_column(Boolean, default=False) # 企业承诺(勾选) signer_name: Mapped[str] = mapped_column(String, default="") # 负责人签字 status: Mapped[str] = mapped_column(String, default="pending", index=True) # pending|approved|rejected|cancelled|finished reviewer_id: Mapped[str] = mapped_column(String, default="") review_comment: Mapped[str] = mapped_column(Text, default="") reviewed_at: Mapped[str] = mapped_column(String, default="") # 园区管理办公室备案 record_received: Mapped[bool] = mapped_column(Boolean, default=False) # 已接收备案 record_safety_notified: Mapped[bool] = mapped_column(Boolean, default=False) # 已告知安全注意事项 record_handler: Mapped[str] = mapped_column(String, default="") # 经办人 record_at: Mapped[str] = mapped_column(String, default="") # 备案日期 created_at: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="") class DmMessage(Base): """站内私信(点对点;会话按收发双方聚合,read_at 空=未读)。""" __tablename__ = "dm_messages" id: Mapped[str] = mapped_column(String, primary_key=True) sender_id: Mapped[str] = mapped_column(String, index=True) receiver_id: Mapped[str] = mapped_column(String, index=True) content: Mapped[str] = mapped_column(Text, default="") read_at: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="") class IncubatorSetting(Base): """创业园应用园区级设置(申请注意事项 / 开放说明 / 月报说明)。 一园区一行(tenant_id 唯一)。管理方在应用"园区设置"页维护, 提交方读取展示在申请/填报页面顶部。 """ __tablename__ = "incubator_settings" __table_args__ = (UniqueConstraint("tenant_id", name="uq_incubator_setting_tenant"),) id: Mapped[str] = mapped_column(String, primary_key=True) # set_ tenant_id: Mapped[str] = mapped_column(String, default="", index=True) reservation_notice: Mapped[str] = mapped_column(Text, default="") # 共享区域申请注意事项/须知 report_notice: Mapped[str] = mapped_column(Text, default="") # 月报填报说明 open_summary: Mapped[str] = mapped_column(Text, default="") # 开放区域总览说明 updated_by: Mapped[str] = mapped_column(String, default="") updated_at: Mapped[str] = mapped_column(String, default="")