2218 lines
127 KiB
Python
2218 lines
127 KiB
Python
# -*- 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 OfficialAgent(Base):
|
||
"""官方预置智能体配置(管理后台可配置,全局共享,非 per-user)。
|
||
|
||
替代原硬编码 ``AGENT_SEED``:官方预置智能体由运营端管理后台配置,
|
||
桌面端每次登录经 ``/agent-bootstrap`` 拉取并按此初始化本地 workspace。
|
||
"""
|
||
|
||
__tablename__ = "official_agents"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
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="")
|
||
template_type: Mapped[str] = mapped_column(String, default="common") # common/qa/local
|
||
deletable: Mapped[bool] = mapped_column(Boolean, default=True) # 是否允许用户在桌面端删除
|
||
use_fixed_soul: Mapped[bool] = mapped_column(Boolean, default=False) # 是否强制使用全局 fixed_soul
|
||
scope: Mapped[str] = mapped_column(String, default="opc") # 身份级别:opc(桌面端)/park(园区端)/operator(运营端),逗号分隔多选,all=全部
|
||
soul: Mapped[str] = mapped_column(Text, default="{}") # JSON {"user": 用户可编辑段, "server": 服务端隐藏注入段}
|
||
profile: Mapped[str] = mapped_column(Text, default="{}") # 同上(PROFILE.md)
|
||
heartbeat: Mapped[str] = mapped_column(Text, default="{}") # 同上(HEARTBEAT.md)
|
||
memory: Mapped[str] = mapped_column(Text, default="{}") # 同上(MEMORY.md)
|
||
enabled: Mapped[bool] = mapped_column(Boolean, default=True) # 是否下发(登录同步时启用才初始化)
|
||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||
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/assigned/claimed/signed/doing/delivered/completed/cancelled
|
||
published_at: Mapped[str] = mapped_column(String, default="") # 发布时间(→published 时)
|
||
assigned_at: Mapped[str] = mapped_column(String, default="") # 指派/邀约发出时间(assign/recommend → assigned)
|
||
signed_at: Mapped[str] = mapped_column(String, default="") # 签约托管时间(claimed → signed,发布方支付)
|
||
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 集)
|
||
min_credit_score: Mapped[int] = mapped_column(Integer, default=0) # 最低信用分要求(0=不限制)
|
||
required_badges: Mapped[str] = mapped_column(Text, default="[]") # 要求徽章 code 列表(JSON)
|
||
required_certifications: Mapped[str] = mapped_column(Text, default="[]") # 要求认证 code 列表(JSON)
|
||
settle_mode: Mapped[str] = mapped_column(String, default="operator_escrow") # 资金托管方式
|
||
# ── 任务系统 v2 扩展字段(0056)──
|
||
resource_support_json: Mapped[str] = mapped_column(Text, default="{}") # 提供的支持(算力/数据/场地/工具/对接/资金)
|
||
raw_materials_json: Mapped[str] = mapped_column(Text, default="[]") # 原始资料/素材附件 URL
|
||
deliver_way: Mapped[str] = mapped_column(String, default="online") # online/offline/mixed
|
||
deliver_items: Mapped[str] = mapped_column(Text, default="[]") # 交付内容清单(JSON 数组)
|
||
accept_standard: Mapped[str] = mapped_column(Text, default="") # 验收标准(富文本/清单)
|
||
price_type: Mapped[str] = mapped_column(String, default="fixed") # fixed/hourly/unit/revshare
|
||
pay_type: Mapped[str] = mapped_column(String, default="escrow") # escrow/stage/offline
|
||
escrow_ratio: Mapped[int] = mapped_column(Integer, default=100) # 托管比例(%)
|
||
invoice_req: Mapped[str] = mapped_column(Text, default="{}") # 发票要求(JSON)
|
||
milestone_json: Mapped[str] = mapped_column(Text, default="[]") # 里程碑配置(JSON)
|
||
attachments_json: Mapped[str] = mapped_column(Text, default="[]") # 交付物附件(JSON)
|
||
deliver_at: Mapped[str] = mapped_column(String, default="") # 交付时间
|
||
accepted_at: Mapped[str] = mapped_column(String, default="") # 验收通过时间
|
||
reject_count: Mapped[int] = mapped_column(Integer, default=0) # 返工次数
|
||
settle_status: Mapped[str] = mapped_column(String, default="") # none/pending/released
|
||
settled_at: Mapped[str] = mapped_column(String, default="") # 结算时间
|
||
on_time: Mapped[bool | None] = mapped_column(Boolean, nullable=True) # 是否按时交付(验收时判定)
|
||
contract_status: Mapped[str] = mapped_column(String, default="") # none/pending/signed
|
||
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
|
||
form_json: Mapped[str] = mapped_column(Text, default="{}") # 申请表单(报名/抢单备注:intro/skills/quote/contact/remark/attachments)
|
||
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(Text, 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)
|
||
# ── 标书 v2 扩展(0056)──
|
||
deliver_days: Mapped[int] = mapped_column(Integer, default=0) # 承诺交付周期(天)
|
||
team_json: Mapped[str] = mapped_column(Text, default="[]") # 团队构成(JSON)
|
||
cases_json: Mapped[str] = mapped_column(Text, default="[]") # 相关案例(JSON)
|
||
commit_json: Mapped[str] = mapped_column(Text, default="{}") # 服务承诺(售后/修改/响应)
|
||
score_total: Mapped[float] = mapped_column(Float, default=0) # 评审综合得分
|
||
score_json: Mapped[str] = mapped_column(Text, default="{}") # 各维度得分快照
|
||
review_note: Mapped[str] = mapped_column(String, default="") # 评审备注
|
||
status: Mapped[str] = mapped_column(String, default="submitted") # submitted/win/lost/closed
|
||
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):
|
||
"""任务互评(一人一评:task_id+from_id 唯一)。"""
|
||
|
||
__tablename__ = "ratings"
|
||
__table_args__ = (UniqueConstraint("task_id", "from_id", name="uq_rating_task_from"),)
|
||
|
||
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="")
|
||
rating_type: Mapped[str] = mapped_column(String, default="fulfill") # fulfill=评接单人 collab=评发包方
|
||
score: Mapped[int] = mapped_column(Integer, default=5) # 1..5
|
||
dims_json: Mapped[str] = mapped_column(Text, default="{}") # 维度星级
|
||
tags_json: Mapped[str] = mapped_column(Text, default="[]") # 评价标签
|
||
comment: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
# ── 任务系统 v2:交付 / 里程碑 / 验收 / 发票(0056)────────────────────────
|
||
|
||
class TaskDelivery(Base):
|
||
"""任务交付历史(版本化:返工后新版本)。"""
|
||
|
||
__tablename__ = "task_deliveries"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
task_id: Mapped[str] = mapped_column(
|
||
ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, index=True,
|
||
)
|
||
milestone_id: Mapped[str] = mapped_column(String, default="") # 关联里程碑(空=整体交付)
|
||
version: Mapped[int] = mapped_column(Integer, default=1)
|
||
attachments_json: Mapped[str] = mapped_column(Text, default="[]")
|
||
note: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class TaskMilestone(Base):
|
||
"""任务里程碑实例(配置来自 tasks.milestone_json)。"""
|
||
|
||
__tablename__ = "task_milestones"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
task_id: Mapped[str] = mapped_column(
|
||
ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, index=True,
|
||
)
|
||
index: Mapped[int] = mapped_column(Integer, default=1)
|
||
name: Mapped[str] = mapped_column(String, default="")
|
||
desc: Mapped[str] = mapped_column(String, default="")
|
||
days: Mapped[int] = mapped_column(Integer, default=0)
|
||
deliverables_json: Mapped[str] = mapped_column(Text, default="[]")
|
||
payment_ratio: Mapped[float] = mapped_column(Float, default=0)
|
||
status: Mapped[str] = mapped_column(String, default="pending") # pending/doing/delivered/accepted
|
||
delivered_at: Mapped[str] = mapped_column(String, default="")
|
||
accepted_at: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class TaskAcceptance(Base):
|
||
"""任务/里程碑验收记录。"""
|
||
|
||
__tablename__ = "task_acceptances"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
task_id: Mapped[str] = mapped_column(
|
||
ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, index=True,
|
||
)
|
||
delivery_id: Mapped[str] = mapped_column(String, default="")
|
||
milestone_id: Mapped[str] = mapped_column(String, default="")
|
||
checklist_json: Mapped[str] = mapped_column(Text, default="[]") # 验收清单核对结果
|
||
score_json: Mapped[str] = mapped_column(Text, default="{}") # 量化指标打分
|
||
result: Mapped[str] = mapped_column(String, default="pass") # pass/reject
|
||
comment: Mapped[str] = mapped_column(String, default="")
|
||
reviewer_id: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class Invoice(Base):
|
||
"""任务发票(结算后接单人开票申请 → 台账 → 电子发票)。"""
|
||
|
||
__tablename__ = "invoices"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
task_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
escrow_id: Mapped[str] = mapped_column(String, default="")
|
||
issuer_id: Mapped[str] = mapped_column(String, default="") # 开票方(接单人)
|
||
issuer_name: Mapped[str] = mapped_column(String, default="")
|
||
payer_name: Mapped[str] = mapped_column(String, default="") # 抬头(发包方)
|
||
amount: Mapped[int] = mapped_column(Integer, default=0)
|
||
tax_rate: Mapped[float] = mapped_column(Float, default=0.01)
|
||
invoice_type: Mapped[str] = mapped_column(String, default="personal") # personal/vat
|
||
status: Mapped[str] = mapped_column(String, default="applied") # applied/issued/rejected
|
||
invoice_no: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
issued_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="")
|
||
# ── 通知体系 v2:分类 / 事件码 / 级别 / 深链 / 业务引用 / 已读时间 ──
|
||
category: Mapped[str] = mapped_column(String, default="system") # task/cert/credit/training/social/news/pay/system/ops
|
||
event_code: Mapped[str] = mapped_column(String, default="") # task.bid_received 等
|
||
level: Mapped[str] = mapped_column(String, default="info") # info/success/warning/danger
|
||
link: Mapped[str] = mapped_column(String, default="") # 前端深链
|
||
ref_type: Mapped[str] = mapped_column(String, default="") # task/cert/course...
|
||
ref_id: Mapped[str] = mapped_column(String, default="") # 业务对象 id
|
||
read_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class Announcement(Base):
|
||
"""平台公告/广播(广播通知不逐用户落库,存此表供通知页顶部展示)。"""
|
||
|
||
__tablename__ = "announcements"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
title: Mapped[str] = mapped_column(String, default="")
|
||
content: Mapped[str] = mapped_column(String, default="")
|
||
category: Mapped[str] = mapped_column(String, default="system") # system/news/ops
|
||
level: Mapped[str] = mapped_column(String, default="info")
|
||
link: Mapped[str] = mapped_column(String, default="")
|
||
created_by: Mapped[str] = mapped_column(String, default="")
|
||
published_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="")
|
||
# ── 载体折扣设置(多级折扣体系,0056) ──
|
||
default_company_discount: Mapped[int] = mapped_column(Integer, default=100) # 下属企业默认折扣(百分比,100=无折扣)
|
||
default_user_discount: Mapped[int] = mapped_column(Integer, default=100) # 下属个人账号默认折扣
|
||
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(必填)
|
||
# ── 企业算力余额(企业管理员充值后分配给成员,0056) ──
|
||
compute_balance: Mapped[int] = mapped_column(Integer, default=0) # 企业算力余额(分)
|
||
compute_balance_used: Mapped[int] = mapped_column(Integer, default=0) # 已分配给成员的余额(分)
|
||
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
|
||
role: Mapped[str] = mapped_column(String, default="staff") # 企业内角色(admin/finance/hr/staff,0056)
|
||
status: Mapped[str] = mapped_column(String, default="active") # active/left
|
||
# ── 成员算力余额(从企业分配,0056) ──
|
||
compute_balance: Mapped[int] = mapped_column(Integer, default=0) # 成员个人余额(分)
|
||
compute_balance_used: Mapped[int] = mapped_column(Integer, default=0) # 已使用余额(分)
|
||
# ── 退出企业(0056) ──
|
||
left_at: Mapped[str] = mapped_column(String, default="") # 退出时间
|
||
left_reason: Mapped[str] = mapped_column(String, default="") # 退出原因
|
||
created_by: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
# ===========================================================================
|
||
# 算力多级折扣与企业余额体系(0056)
|
||
# ===========================================================================
|
||
|
||
|
||
class TenantDiscount(Base):
|
||
"""运营端给载体设置的折扣(载体进货价)。
|
||
|
||
discount: 0-100,0=无折扣,100=全免费;实际价格=标准价×(1-discount/100)
|
||
"""
|
||
__tablename__ = "tenant_discounts"
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
tenant_id: Mapped[str] = mapped_column(String, unique=True, index=True)
|
||
discount: Mapped[int] = mapped_column(Integer, default=0) # 折扣百分比(0-100)
|
||
effective_date: Mapped[str] = mapped_column(String, default="")
|
||
expire_date: Mapped[str] = mapped_column(String, default="")
|
||
reason: Mapped[str] = mapped_column(Text, default="")
|
||
created_by: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class TenantUserDiscount(Base):
|
||
"""载体端给特定个人账号设置的折扣(优先级最高)。"""
|
||
__tablename__ = "tenant_user_discounts"
|
||
__table_args__ = (UniqueConstraint("tenant_id", "user_id", name="uq_tenant_user_discount"),)
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
tenant_id: Mapped[str] = mapped_column(String, index=True)
|
||
user_id: Mapped[str] = mapped_column(String, index=True)
|
||
discount: Mapped[int] = mapped_column(Integer, default=0) # 折扣百分比(0-100)
|
||
reason: Mapped[str] = mapped_column(Text, default="")
|
||
created_by: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class ComputeRecharge(Base):
|
||
"""算力充值记录(企业管理员充值或个人充值)。"""
|
||
__tablename__ = "compute_recharges"
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
company_id: Mapped[str] = mapped_column(String, default="", index=True) # 企业充值时填写
|
||
user_id: Mapped[str] = mapped_column(String, default="", index=True) # 个人充值时填写
|
||
amount: Mapped[int] = mapped_column(Integer, default=0) # 充值金额(分)
|
||
compute_amount: Mapped[int] = mapped_column(Integer, default=0) # 到账算力(分)
|
||
payment_method: Mapped[str] = mapped_column(String, default="")
|
||
payment_status: Mapped[str] = mapped_column(String, default="pending") # pending/paid/failed
|
||
transaction_id: Mapped[str] = mapped_column(String, default="")
|
||
recharged_by: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
paid_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class ComputeBalanceAllocation(Base):
|
||
"""企业余额分配给成员的记录。"""
|
||
__tablename__ = "compute_balance_allocations"
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
company_id: Mapped[str] = mapped_column(String, index=True)
|
||
from_user_id: Mapped[str] = mapped_column(String, default="") # 分配人(企业管理员)
|
||
to_user_id: Mapped[str] = mapped_column(String, index=True) # 接收成员
|
||
amount: Mapped[int] = mapped_column(Integer, default=0) # 分配金额(分)
|
||
type: Mapped[str] = mapped_column(String, default="allocate") # allocate/reclaim(分配/回收)
|
||
reason: Mapped[str] = mapped_column(Text, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class ComputeUsageRecord(Base):
|
||
"""算力使用扣费记录。"""
|
||
__tablename__ = "compute_usage_records"
|
||
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, default="", index=True) # 从企业余额扣费时填写
|
||
model: Mapped[str] = mapped_column(String, default="")
|
||
token_count: Mapped[int] = mapped_column(Integer, default=0)
|
||
standard_price: Mapped[int] = mapped_column(Integer, default=0) # 标准价(分)
|
||
discount: Mapped[int] = mapped_column(Integer, default=0) # 实际折扣(0-100)
|
||
discount_source: Mapped[str] = mapped_column(String, default="standard") # standard/tenant/company/tenant_user
|
||
actual_amount: Mapped[int] = mapped_column(Integer, default=0) # 实际扣费(分)
|
||
balance_source: Mapped[str] = mapped_column(String, default="personal") # company/personal
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
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_<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 对象路径(图标)
|
||
cover_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 MarketCategory(Base):
|
||
"""市场分类字典(skill / plugin / app 各自独立,admin 端弹窗维护)。
|
||
|
||
分类在「market_items.category」中以稳定编码 ``key`` 存储;
|
||
展示名分中英文(label_zh / label_en),可在线增删改排序。
|
||
"""
|
||
__tablename__ = "market_categories"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True) # mc_<hex>
|
||
item_type: Mapped[str] = mapped_column(String, default="skill", index=True) # skill|plugin|app
|
||
key: Mapped[str] = mapped_column(String, default="") # 稳定编码(存入 market_items.category)
|
||
label_zh: Mapped[str] = mapped_column(String, default="")
|
||
label_en: Mapped[str] = mapped_column(String, default="")
|
||
sort: Mapped[int] = mapped_column(Integer, default=0)
|
||
enabled: Mapped[int] = mapped_column(Integer, default=1)
|
||
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 / 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_<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="")
|
||
|
||
|
||
# ===========================================================================
|
||
# 信用认证体系(个人认证 / 企业认证 / OPC人才认证 / 技能认证)
|
||
# ===========================================================================
|
||
|
||
class CertificationType(Base):
|
||
"""认证类型配置表(运营可配置扩展)。"""
|
||
__tablename__ = "certification_types"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
code: Mapped[str] = mapped_column(String, unique=True, index=True, default="")
|
||
category: Mapped[str] = mapped_column(String, default="personal") # personal/enterprise/opc_talent/skill
|
||
name: Mapped[str] = mapped_column(String, default="")
|
||
description: Mapped[str] = mapped_column(Text, default="")
|
||
fee: Mapped[int] = mapped_column(Integer, default=0) # 分,0=免费
|
||
validity_days: Mapped[int] = mapped_column(Integer, default=0) # 0=永久
|
||
credit_points: Mapped[int] = mapped_column(Integer, default=0)
|
||
levels_json: Mapped[str] = mapped_column(Text, default="[]") # 等级配置JSON
|
||
materials_schema: Mapped[str] = mapped_column(Text, default="{}") # 表单JSON Schema
|
||
review_mode: Mapped[str] = mapped_column(String, default="manual") # auto/manual/hybrid
|
||
api_provider: Mapped[str] = mapped_column(String, default="")
|
||
badge_icon: Mapped[str] = mapped_column(String, default="")
|
||
badge_color: Mapped[str] = mapped_column(String, default="")
|
||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
|
||
prerequisite: Mapped[str] = mapped_column(String, default="") # 前置认证类型code,空=无前置要求
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class Certification(Base):
|
||
"""认证申请表(统一所有认证类型,替代旧 opc_certifications)。"""
|
||
__tablename__ = "certifications"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
user_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
enterprise_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
cert_type: Mapped[str] = mapped_column(String, default="", index=True) # 类型编码
|
||
cert_category: Mapped[str] = mapped_column(String, default="personal") # 大类
|
||
level: Mapped[str] = mapped_column(String, default="") # 等级
|
||
status: Mapped[str] = mapped_column(String, default="not_started", index=True)
|
||
# not_started/pending/approved/rejected/active/expiring/expired/revoked
|
||
materials_json: Mapped[str] = mapped_column(Text, default="{}") # 提交材料(脱敏)
|
||
score: Mapped[int] = mapped_column(Integer, default=0) # 认证分数(技能测试用)
|
||
credit_points: Mapped[int] = mapped_column(Integer, default=0) # 获得的信用加分
|
||
fee_amount: Mapped[int] = mapped_column(Integer, default=0) # 费用(分)
|
||
payment_id: Mapped[str] = mapped_column(String, default="")
|
||
submitted_at: Mapped[str] = mapped_column(String, default="")
|
||
approved_at: Mapped[str] = mapped_column(String, default="")
|
||
expires_at: Mapped[str] = mapped_column(String, default="")
|
||
reviewer_id: Mapped[str] = mapped_column(String, default="")
|
||
review_note: Mapped[str] = mapped_column(Text, default="")
|
||
revoke_reason: Mapped[str] = mapped_column(Text, default="")
|
||
revoked_at: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class SkillTest(Base):
|
||
"""技能测试记录表。"""
|
||
__tablename__ = "skill_tests"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
user_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
skill_domain: Mapped[str] = mapped_column(String, default="", index=True)
|
||
status: Mapped[str] = mapped_column(String, default="paid")
|
||
# paid/in_progress/submitted/scored/completed/expired
|
||
score: Mapped[int] = mapped_column(Integer, default=0)
|
||
level: Mapped[str] = mapped_column(String, default="")
|
||
objective_score: Mapped[int] = mapped_column(Integer, default=0)
|
||
subjective_score: Mapped[int] = mapped_column(Integer, default=0)
|
||
answers_json: Mapped[str] = mapped_column(Text, default="{}")
|
||
cheating_flags: Mapped[int] = mapped_column(Integer, default=0)
|
||
started_at: Mapped[str] = mapped_column(String, default="")
|
||
submitted_at: Mapped[str] = mapped_column(String, default="")
|
||
scored_at: Mapped[str] = mapped_column(String, default="")
|
||
certification_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
# ═══════════════════════════════════════════════════════════════
|
||
# 培训与技能认证体系
|
||
# ═══════════════════════════════════════════════════════════════
|
||
|
||
class TrainingCourse(Base):
|
||
"""课程表。"""
|
||
__tablename__ = "training_courses"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
title: Mapped[str] = mapped_column(String, default="")
|
||
subtitle: Mapped[str] = mapped_column(String, default="")
|
||
description: Mapped[str] = mapped_column(Text, default="")
|
||
cover_url: Mapped[str] = mapped_column(String, default="")
|
||
category: Mapped[str] = mapped_column(String, default="", index=True)
|
||
# ui_design/graphic_design/frontend_dev/backend_dev/copywriting/translation/data_analysis/project_management
|
||
level: Mapped[str] = mapped_column(String, default="beginner")
|
||
# beginner/intermediate/advanced/expert
|
||
price: Mapped[int] = mapped_column(Integer, default=0) # 分,0=免费
|
||
duration_minutes: Mapped[int] = mapped_column(Integer, default=0)
|
||
lesson_count: Mapped[int] = mapped_column(Integer, default=0)
|
||
chapter_count: Mapped[int] = mapped_column(Integer, default=0)
|
||
instructor_id: Mapped[str] = mapped_column(String, default="")
|
||
instructor_name: Mapped[str] = mapped_column(String, default="")
|
||
instructor_title: Mapped[str] = mapped_column(String, default="")
|
||
instructor_avatar: Mapped[str] = mapped_column(String, default="")
|
||
tags_json: Mapped[str] = mapped_column(Text, default="[]")
|
||
prerequisites: Mapped[str] = mapped_column(Text, default="")
|
||
learning_outcomes: Mapped[str] = mapped_column(Text, default="")
|
||
status: Mapped[str] = mapped_column(String, default="draft") # draft/published/archived
|
||
is_featured: Mapped[int] = mapped_column(Integer, default=0)
|
||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||
enroll_count: Mapped[int] = mapped_column(Integer, default=0)
|
||
rating: Mapped[float] = mapped_column(Float, default=0.0)
|
||
rating_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 TrainingChapter(Base):
|
||
"""课程章节表。"""
|
||
__tablename__ = "training_chapters"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
course_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
title: Mapped[str] = mapped_column(String, default="")
|
||
description: Mapped[str] = mapped_column(String, default="")
|
||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class TrainingLesson(Base):
|
||
"""课程课时表。"""
|
||
__tablename__ = "training_lessons"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
chapter_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
course_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
title: Mapped[str] = mapped_column(String, default="")
|
||
type: Mapped[str] = mapped_column(String, default="video") # video/article/quiz/exam
|
||
content: Mapped[str] = mapped_column(Text, default="")
|
||
duration_minutes: Mapped[int] = mapped_column(Integer, default=0)
|
||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||
is_free: Mapped[int] = mapped_column(Integer, default=0)
|
||
is_exam: Mapped[int] = mapped_column(Integer, default=0)
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class TrainingCourseEnrollment(Base):
|
||
"""课程报名记录表。"""
|
||
__tablename__ = "training_course_enrollments"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
user_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
course_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
status: Mapped[str] = mapped_column(String, default="enrolled")
|
||
# enrolled/in_progress/completed/dropped
|
||
progress_percent: Mapped[int] = mapped_column(Integer, default=0)
|
||
completed_lessons: Mapped[int] = mapped_column(Integer, default=0)
|
||
total_lessons: Mapped[int] = mapped_column(Integer, default=0)
|
||
last_lesson_id: Mapped[str] = mapped_column(String, default="")
|
||
last_studied_at: Mapped[str] = mapped_column(String, default="")
|
||
total_watch_seconds: Mapped[int] = mapped_column(Integer, default=0)
|
||
enrolled_at: Mapped[str] = mapped_column(String, default="")
|
||
completed_at: Mapped[str] = mapped_column(String, default="")
|
||
price_paid: Mapped[int] = mapped_column(Integer, default=0)
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class TrainingLessonProgress(Base):
|
||
"""课时学习进度表。"""
|
||
__tablename__ = "training_lesson_progress"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
enrollment_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
user_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
lesson_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
course_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
status: Mapped[str] = mapped_column(String, default="not_started")
|
||
# not_started/in_progress/completed
|
||
watch_seconds: Mapped[int] = mapped_column(Integer, default=0)
|
||
quiz_score: Mapped[int] = mapped_column(Integer, default=0)
|
||
started_at: Mapped[str] = mapped_column(String, default="")
|
||
completed_at: Mapped[str] = mapped_column(String, default="")
|
||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class TrainingCertificate(Base):
|
||
"""结业证书表。"""
|
||
__tablename__ = "training_certificates"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
certificate_no: Mapped[str] = mapped_column(String, default="", index=True)
|
||
user_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
course_id: Mapped[str] = mapped_column(String, default="", index=True)
|
||
course_title: Mapped[str] = mapped_column(String, default="")
|
||
instructor_name: Mapped[str] = mapped_column(String, default="")
|
||
duration_minutes: Mapped[int] = mapped_column(Integer, default=0)
|
||
final_score: Mapped[int] = mapped_column(Integer, default=0)
|
||
issued_at: Mapped[str] = mapped_column(String, default="")
|
||
badge_id: Mapped[str] = mapped_column(String, default="")
|
||
is_verified: Mapped[int] = mapped_column(Integer, default=1)
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class UserPage(Base):
|
||
"""个人主页(OPC 公开名片页):每位用户可自写 HTML 或嵌入第三方网页。
|
||
|
||
- page_type: html 自写 HTML(沙箱渲染)| embed 第三方网页地址(iframe)
|
||
- html_url: HTML 模式下,HTML 文件在 OSS 的相对路径(/oss/...);数据库不存 HTML 源码
|
||
- embed_url: embed 模式下的第三方网页 https 地址
|
||
- capabilities_json: 接入的平台能力声明 [{key,name,desc,scope}];embed 模式强制为空
|
||
- review_status: draft 草稿 | pending 待审核 | approved 已通过 | rejected 已拒绝
|
||
- published: 是否上架对外展示(仅 approved 状态可上架)
|
||
"""
|
||
__tablename__ = "user_pages"
|
||
|
||
user_id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
page_type: Mapped[str] = mapped_column(String, default="html") # html | embed
|
||
html_content: Mapped[str] = mapped_column(Text, default="") # 兼容旧数据,新数据存 OSS
|
||
html_url: Mapped[str] = mapped_column(String, default="") # OSS 相对路径 /oss/...
|
||
embed_url: Mapped[str] = mapped_column(String, default="") # 第三方网页 https 地址
|
||
capabilities_json: Mapped[str] = mapped_column(Text, default="[]")
|
||
review_status: Mapped[str] = mapped_column(String, default="draft") # draft|pending|approved|rejected
|
||
review_note: Mapped[str] = mapped_column(Text, default="")
|
||
submitted_at: Mapped[str] = mapped_column(String, default="")
|
||
reviewed_at: Mapped[str] = mapped_column(String, default="")
|
||
published: Mapped[bool] = mapped_column(Boolean, default=False)
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class UserPageReviewLog(Base):
|
||
"""个人主页审核日志:记录用户提交、管理员通过/驳回等操作。"""
|
||
__tablename__ = "user_page_review_logs"
|
||
|
||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||
user_id: Mapped[str] = mapped_column(String(64), index=True)
|
||
action: Mapped[str] = mapped_column(String(32)) # submit | approve | reject
|
||
operator_id: Mapped[str] = mapped_column(String(64))
|
||
operator_name: Mapped[str] = mapped_column(String(128), default="")
|
||
note: Mapped[str] = mapped_column(Text, default="")
|
||
created_at: Mapped[str] = mapped_column(String(32), default="")
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 信用体系与徽章体系(0055)
|
||
# ---------------------------------------------------------------------------
|
||
|
||
class CreditRule(Base):
|
||
"""信用事件规则:事件 → 维度/分值/封顶/衰减(运营可配置)。"""
|
||
__tablename__ = "credit_rules"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
event_code: Mapped[str] = mapped_column(String, unique=True, index=True)
|
||
name: Mapped[str] = mapped_column(String, default="")
|
||
dimension: Mapped[str] = mapped_column(String, default="system") # performance/reputation/capability/domain/compliance/activity/system
|
||
base_delta: Mapped[int] = mapped_column(Integer, default=0) # 基础分值(正加负扣)
|
||
delta_mode: Mapped[str] = mapped_column(String, default="fixed") # fixed | by_score | by_level | by_hours
|
||
delta_config_json: Mapped[str] = mapped_column(Text, default="{}") # by_* 模式的映射 {"5":15,"4":10,...}
|
||
cap_single: Mapped[int] = mapped_column(Integer, default=50) # 单事件封顶
|
||
monthly_cap: Mapped[int] = mapped_column(Integer, default=0) # 月度累计上限(0=不限)
|
||
decay_months: Mapped[int] = mapped_column(Integer, default=0) # 时间衰减月数(0=不衰减)
|
||
unique_per_user: Mapped[int] = mapped_column(Integer, default=0) # 1=同用户只计一次(认证类)
|
||
is_active: Mapped[int] = mapped_column(Integer, default=1)
|
||
description: Mapped[str] = mapped_column(Text, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class CreditDimension(Base):
|
||
"""六维画像配置(权重仅用于画像归一化,不参与总分)。"""
|
||
__tablename__ = "credit_dimensions"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
code: Mapped[str] = mapped_column(String, unique=True, index=True)
|
||
name: Mapped[str] = mapped_column(String, default="")
|
||
weight: Mapped[float] = mapped_column(Float, default=0.0) # 画像权重(总和 1.0)
|
||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||
is_active: Mapped[int] = mapped_column(Integer, default=1)
|
||
description: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class CreditScore(Base):
|
||
"""用户信用分缓存:累计总分(无上限)+ 等级 + 六维画像。"""
|
||
__tablename__ = "credit_scores"
|
||
|
||
user_id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
total_score: Mapped[int] = mapped_column(Integer, default=0) # 累加积分,无上限
|
||
level: Mapped[str] = mapped_column(String, default="L1") # L1-L8
|
||
dimensions_json: Mapped[str] = mapped_column(Text, default="[]") # [{code,name,score 0-100}]
|
||
rating_avg: Mapped[float] = mapped_column(Float, default=0.0)
|
||
rating_count: Mapped[int] = mapped_column(Integer, default=0)
|
||
task_count: Mapped[int] = mapped_column(Integer, default=0)
|
||
on_time_rate: Mapped[float] = mapped_column(Float, default=0.0)
|
||
percentile: Mapped[int] = mapped_column(Integer, default=0)
|
||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class CreditLedger(Base):
|
||
"""信用流水账本(时间线/审计/申诉依据)。"""
|
||
__tablename__ = "credit_ledger"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
user_id: Mapped[str] = mapped_column(String, index=True)
|
||
event_code: Mapped[str] = mapped_column(String, default="", index=True)
|
||
dimension: Mapped[str] = mapped_column(String, default="system")
|
||
delta: Mapped[int] = mapped_column(Integer, default=0)
|
||
balance: Mapped[int] = mapped_column(Integer, default=0)
|
||
reason: Mapped[str] = mapped_column(String, default="")
|
||
ref_type: Mapped[str] = mapped_column(String, default="")
|
||
ref_id: Mapped[str] = mapped_column(String, default="")
|
||
source: Mapped[str] = mapped_column(String, default="system") # system/operator/backfill
|
||
operator_id: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class CreditLevel(Base):
|
||
"""信用等级配置(L1-L8,阈值递增,L8+ 不封顶)。"""
|
||
__tablename__ = "credit_levels"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
level: Mapped[str] = mapped_column(String, unique=True, index=True)
|
||
min_score: Mapped[int] = mapped_column(Integer, default=0)
|
||
max_score: Mapped[int] = mapped_column(Integer, default=0) # L8 为极大值
|
||
name: Mapped[str] = mapped_column(String, default="")
|
||
tier: Mapped[str] = mapped_column(String, default="bronze") # bronze/silver/gold/platinum/diamond/crown
|
||
color: Mapped[str] = mapped_column(String, default="#8C8C8C")
|
||
benefits_json: Mapped[str] = mapped_column(Text, default="[]")
|
||
badge_code: Mapped[str] = mapped_column(String, default="")
|
||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class Badge(Base):
|
||
"""徽章定义 + 授予规则。"""
|
||
__tablename__ = "badges"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
code: Mapped[str] = mapped_column(String, unique=True, index=True)
|
||
name: Mapped[str] = mapped_column(String, default="")
|
||
category: Mapped[str] = mapped_column(String, default="ability") # identity/level/ability/behavior/activity/special
|
||
tier: Mapped[str] = mapped_column(String, default="bronze")
|
||
icon: Mapped[str] = mapped_column(String, default="StarFilled")
|
||
description: Mapped[str] = mapped_column(String, default="")
|
||
condition: Mapped[str] = mapped_column(String, default="")
|
||
grant_rule_json: Mapped[str] = mapped_column(Text, default="{}")
|
||
credit_bonus: Mapped[int] = mapped_column(Integer, default=0)
|
||
lifetime: Mapped[int] = mapped_column(Integer, default=1)
|
||
revocable: Mapped[int] = mapped_column(Integer, default=1)
|
||
expiry_days: Mapped[int] = mapped_column(Integer, default=0)
|
||
priority: Mapped[int] = mapped_column(Integer, default=0)
|
||
status: Mapped[str] = mapped_column(String, default="active")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
class UserBadge(Base):
|
||
"""用户徽章持有/撤销/过期。"""
|
||
__tablename__ = "user_badges"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
user_id: Mapped[str] = mapped_column(String, index=True)
|
||
badge_id: Mapped[str] = mapped_column(String, index=True)
|
||
badge_code: Mapped[str] = mapped_column(String, default="", index=True)
|
||
source: Mapped[str] = mapped_column(String, default="auto") # auto/certification/activity/manual/backfill
|
||
ref_id: Mapped[str] = mapped_column(String, default="")
|
||
status: Mapped[str] = mapped_column(String, default="active") # active/revoked/expired
|
||
granted_at: Mapped[str] = mapped_column(String, default="")
|
||
expires_at: Mapped[str] = mapped_column(String, default="")
|
||
revoke_reason: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 桌面端版本管理(PineAgents 自动更新,0063)
|
||
# ---------------------------------------------------------------------------
|
||
|
||
class DesktopVersion(Base):
|
||
"""桌面端(PineAgents)更新版本:构建产物 + 发布控制。
|
||
|
||
- version semver(如 0.3.0),唯一;与桌面端 tauri.conf.json 版本一致
|
||
- status draft(草稿) | rolling(灰度) | published(全量) | archived(下架)
|
||
- rollout 灰度比例 0-100,status=rolling 时按客户端版本号取模命中
|
||
- min_version 强制升级最低版本:低于此版本的客户端必须更新
|
||
- artifacts_json {"<target>": {"filename","url","signature","sha256","size"}}
|
||
target ∈ darwin-aarch64 / darwin-x86_64 / windows-x86_64 / linux-x86_64
|
||
"""
|
||
__tablename__ = "desktop_versions"
|
||
|
||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||
version: Mapped[str] = mapped_column(String, unique=True, index=True)
|
||
channel: Mapped[str] = mapped_column(String, default="stable") # stable | beta
|
||
notes: Mapped[str] = mapped_column(Text, default="") # 发布说明(Markdown)
|
||
status: Mapped[str] = mapped_column(String, default="draft")
|
||
rollout: Mapped[int] = mapped_column(Integer, default=0)
|
||
min_version: Mapped[str] = mapped_column(String, default="")
|
||
artifacts_json: Mapped[str] = mapped_column(Text, default="{}")
|
||
pub_date: Mapped[str] = mapped_column(String, default="")
|
||
created_by: Mapped[str] = mapped_column(String, default="")
|
||
created_at: Mapped[str] = mapped_column(String, default="")
|
||
updated_at: Mapped[str] = mapped_column(String, default="")
|