Files
server-core/app/infrastructure/models.py
T
Pine 86c6d24b17 fix(pay): 所有支付小程序码 page 路径修正为 pages-extra 子包路径
统一修正3处支付相关小程序码的 page 参数(之前误写为主包 pages/ 路径,
扫码后微信找不到页面→白屏):

- app/pay/service.py: 算力充值支付 → pages-extra/pay/index
- app/market/service.py: 市场购买支付 → pages-extra/pay/index
- app/training/main.py: 活动报名支付 → pages-extra/pay-qr/index

加上之前修复的 scan-login(auth.py + wechat.py 默认参数),
后端所有 get_wxacode 调用的 page 路径现已全部正确。
2026-09-02 11:47:34 +08:00

1540 lines
87 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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。
历史接单流水见 TaskClaimclaim 记录 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="") # 加宽封面图 URL3.35:1
cover_small: Mapped[str] = mapped_column(String, default="") # 小封面图 URL1: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/offlinepending=待审核)
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="") # 投标/报名材料(URL0035)
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="") # 微信支付单号(收单来源)
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
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 ⇄ offlinepending → rejectedrejected → draft。
定价:plugin / app 支持 price_fen0=免费);skill 恒为 0。
"""
__tablename__ = "market_items"
id: Mapped[str] = mapped_column(String, primary_key=True) # mi_<hex>
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 内嵌)
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_<hex>
order_no: Mapped[str] = mapped_column(String, unique=True, index=True) # MK_<ts>_<hex8>,微信 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_<hex>
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 / cancelledaccepted|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 / rejectedsubmitted 未审核可撤回 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_<hex>
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_<hex>
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_<hex>
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_<hex>
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="")