3a1bb75417
- claims/reviews、companies/applies/reviews:运营方可见全部待审园区级申请 - review_claim/review_apply:park_admin 级允许运营方兜底审核
520 lines
24 KiB
Python
520 lines
24 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""企业身份链路(/admin/ent 扩展):认领企业 + 企业入驻申请。
|
||
|
||
**认领企业**(未绑定企业用户 → 认领园区入驻企业):
|
||
- 仅支持搜索(选园区 → 搜企业),不支持列表;
|
||
- 认领目标必须是「园区入驻企业」(tenant_id 非空);
|
||
- claim_role=admin:仅当企业无管理员时可认领,园区管理员审核;
|
||
- claim_role=member:有企业管理员则企业管理员审核,无则园区管理员审核;
|
||
- 证明资料(姓名/身份证/手机号)仅存证供审核端查看。
|
||
|
||
**企业入驻申请**(已有企业加入平台):
|
||
- entry_type=park_entered:入驻园区,园区管理员审核;
|
||
- entry_type=independent:不入驻园区,运营方审核;
|
||
- 审核通过后创建 ParkCompany,提交人自动成为企业管理员。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
|
||
from fastapi import APIRouter, Depends, HTTPException, Request
|
||
from pydantic import BaseModel
|
||
from sqlalchemy import select
|
||
|
||
from ..dependencies import get_db, get_current_user
|
||
from ...rbac import write_audit
|
||
from ...infrastructure.models import (
|
||
CompanyApplyRequest, CompanyClaimRequest, CompanyMember,
|
||
ParkCompany, ParkTenant, User,
|
||
)
|
||
from ...infrastructure.repositories import Database, new_id, utcnow_iso
|
||
|
||
router = APIRouter(prefix="/admin/ent", tags=["enterprise-onboard"])
|
||
|
||
|
||
def _now() -> str:
|
||
return utcnow_iso()
|
||
|
||
|
||
def _claim_dict(c) -> dict:
|
||
return {
|
||
"id": c.id, "user_id": c.user_id, "username": c.username,
|
||
"company_id": c.company_id, "company_name": c.company_name,
|
||
"tenant_id": c.tenant_id, "tenant_name": c.tenant_name,
|
||
"claim_role": c.claim_role, "real_name": c.real_name,
|
||
"id_card": c.id_card, "phone": c.phone,
|
||
"status": c.status, "review_level": c.review_level,
|
||
"reviewer_id": c.reviewer_id, "reviewer_name": c.reviewer_name,
|
||
"review_comment": c.review_comment, "reviewed_at": c.reviewed_at,
|
||
"created_at": c.created_at,
|
||
}
|
||
|
||
|
||
def _apply_dict(a) -> dict:
|
||
try:
|
||
docs = json.loads(a.docs_json or "{}")
|
||
except Exception: # noqa: BLE001
|
||
docs = {}
|
||
return {
|
||
"id": a.id, "user_id": a.user_id, "username": a.username,
|
||
"entry_type": a.entry_type, "tenant_id": a.tenant_id,
|
||
"tenant_name": a.tenant_name, "company_name": a.company_name,
|
||
"legal_person": a.legal_person, "legal_phone": a.legal_phone,
|
||
"contact_phone": a.contact_phone, "address": a.address,
|
||
"industry": a.industry, "registered_capital": a.registered_capital,
|
||
"company_type": a.company_type, "bio": a.bio, "docs": docs,
|
||
"upgrade_from_team_id": a.upgrade_from_team_id,
|
||
"status": a.status, "review_level": a.review_level,
|
||
"reviewer_id": a.reviewer_id, "reviewer_name": a.reviewer_name,
|
||
"review_comment": a.review_comment, "reviewed_at": a.reviewed_at,
|
||
"created_at": a.created_at,
|
||
}
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 认领企业
|
||
# ---------------------------------------------------------------------------
|
||
|
||
|
||
class ClaimSubmit(BaseModel):
|
||
company_id: str
|
||
claim_role: str = "member" # admin/member
|
||
real_name: str = ""
|
||
id_card: str = ""
|
||
phone: str = ""
|
||
|
||
|
||
@router.get("/claims/search", summary="认领企业搜索(仅园区入驻企业,按园区过滤)")
|
||
async def claim_search(
|
||
tenant_id: str,
|
||
q: str = "",
|
||
db: Database = Depends(get_db),
|
||
user: dict = Depends(get_current_user),
|
||
):
|
||
tenant_id = (tenant_id or "").strip()
|
||
if not tenant_id:
|
||
raise HTTPException(status_code=400, detail="请先选择园区")
|
||
t = (await db.session.execute(
|
||
select(ParkTenant).where(ParkTenant.id == tenant_id))).scalars().first()
|
||
if t is None:
|
||
raise HTTPException(status_code=404, detail="园区不存在")
|
||
stmt = select(ParkCompany).where(
|
||
ParkCompany.tenant_id == tenant_id,
|
||
ParkCompany.status == "active",
|
||
ParkCompany.company_kind == "park_entered",
|
||
)
|
||
kw = (q or "").strip()
|
||
if kw:
|
||
stmt = stmt.where(ParkCompany.name.like(f"%{kw}%"))
|
||
rows = (await db.session.scalars(stmt.order_by(ParkCompany.created_at.desc()).limit(50))).all()
|
||
items = []
|
||
for c in rows:
|
||
admins = (await db.session.scalars(
|
||
select(CompanyMember).where(CompanyMember.company_id == c.id,
|
||
CompanyMember.is_admin.is_(True),
|
||
CompanyMember.status == "active"))).all()
|
||
items.append({
|
||
"id": c.id, "name": c.name, "zone": c.zone, "room": c.room,
|
||
"industry": c.industry, "bio": c.bio,
|
||
"has_admin": bool(admins),
|
||
})
|
||
return {"items": items}
|
||
|
||
|
||
@router.post("/claims", summary="提交企业认领申请")
|
||
async def submit_claim(
|
||
body: ClaimSubmit,
|
||
request: Request,
|
||
db: Database = Depends(get_db),
|
||
user: dict = Depends(get_current_user),
|
||
):
|
||
cid = (body.company_id or "").strip()
|
||
role = (body.claim_role or "member").strip()
|
||
if role not in ("admin", "member"):
|
||
raise HTTPException(status_code=400, detail="认领角色不合法(admin/member)")
|
||
if not (body.real_name.strip() and body.id_card.strip() and body.phone.strip()):
|
||
raise HTTPException(status_code=400, detail="请填写姓名、身份证号码、手机号证明资料")
|
||
comp = (await db.session.execute(
|
||
select(ParkCompany).where(ParkCompany.id == cid))).scalars().first()
|
||
if comp is None:
|
||
raise HTTPException(status_code=404, detail="企业不存在")
|
||
if comp.tenant_id is None or not comp.tenant_id:
|
||
raise HTTPException(status_code=400, detail="仅可认领园区入驻企业")
|
||
# 已绑定该企业则无需认领
|
||
existing = await db.company_members.get(user["id"], cid)
|
||
if existing is not None and existing.get("status") == "active":
|
||
raise HTTPException(status_code=400, detail="你已在该企业中,无需认领")
|
||
dup = (await db.session.scalar(
|
||
select(CompanyClaimRequest).where(
|
||
CompanyClaimRequest.user_id == user["id"],
|
||
CompanyClaimRequest.company_id == cid,
|
||
CompanyClaimRequest.status == "pending")))
|
||
if dup is not None:
|
||
raise HTTPException(status_code=400, detail="已有待审核的认领申请")
|
||
admins = (await db.session.scalars(
|
||
select(CompanyMember).where(CompanyMember.company_id == cid,
|
||
CompanyMember.is_admin.is_(True),
|
||
CompanyMember.status == "active"))).all()
|
||
has_admin = bool(admins)
|
||
if role == "admin" and has_admin:
|
||
raise HTTPException(status_code=400, detail="该企业已有管理员,只能认领为企业成员")
|
||
# 审核人:admin→园区管理员;member→有企业管理员则企业管理员,否则园区管理员
|
||
review_level = "park_admin"
|
||
if role == "member" and has_admin:
|
||
review_level = "company_admin"
|
||
t = (await db.session.execute(
|
||
select(ParkTenant).where(ParkTenant.id == comp.tenant_id))).scalars().first()
|
||
req = CompanyClaimRequest(
|
||
id=new_id("claim"), user_id=user["id"], username=user.get("username", ""),
|
||
company_id=cid, company_name=comp.name,
|
||
tenant_id=comp.tenant_id or "", tenant_name=(t.name if t else "") or "",
|
||
claim_role=role, real_name=body.real_name.strip(),
|
||
id_card=body.id_card.strip(), phone=body.phone.strip(),
|
||
status="pending", review_level=review_level, created_at=_now(),
|
||
)
|
||
db.session.add(req)
|
||
await db.session.commit()
|
||
await write_audit(db, action="ent.claim_submit", resource="company_claim_request",
|
||
resource_id=req.id, detail=f"company={comp.name} role={role}", user=user, request=request)
|
||
return {"ok": True, "id": req.id, "review_level": review_level}
|
||
|
||
|
||
@router.get("/claims/mine", summary="我的认领申请")
|
||
async def my_claims(
|
||
db: Database = Depends(get_db),
|
||
user: dict = Depends(get_current_user),
|
||
):
|
||
rows = (await db.session.scalars(
|
||
select(CompanyClaimRequest).where(CompanyClaimRequest.user_id == user["id"])
|
||
.order_by(CompanyClaimRequest.created_at.desc()))).all()
|
||
return {"items": [_claim_dict(r) for r in rows]}
|
||
|
||
|
||
async def _is_park_admin(db: Database, tenant_id: str, user: dict) -> bool:
|
||
"""当前用户是否为该园区管理员(载体账号绑定)。"""
|
||
if not tenant_id:
|
||
return False
|
||
t = (await db.session.execute(
|
||
select(ParkTenant).where(ParkTenant.id == tenant_id))).scalars().first()
|
||
return bool(t and t.operator_user_id and t.operator_user_id == user.get("id", ""))
|
||
|
||
|
||
@router.get("/claims/reviews", summary="待我审核的认领申请(园区管理员/企业管理员/运营方兜底)")
|
||
async def claim_reviews(
|
||
db: Database = Depends(get_db),
|
||
user: dict = Depends(get_current_user),
|
||
):
|
||
items = []
|
||
# 园区管理员:本园区的 park_admin 认领(admin 认领 + 无管理员的成员认领)
|
||
tids = (await db.session.scalars(
|
||
select(ParkTenant.id).where(ParkTenant.operator_user_id == user.get("id", "")))).all()
|
||
if tids:
|
||
park_rows = (await db.session.scalars(
|
||
select(CompanyClaimRequest).where(
|
||
CompanyClaimRequest.tenant_id.in_(tids),
|
||
CompanyClaimRequest.status == "pending",
|
||
CompanyClaimRequest.review_level == "park_admin")
|
||
.order_by(CompanyClaimRequest.created_at.desc()))).all()
|
||
items += [_claim_dict(r) for r in park_rows]
|
||
# 运营方(admin 端园区详情兜底):全部待审园区级认领
|
||
elif user.get("role") == "operator":
|
||
op_rows = (await db.session.scalars(
|
||
select(CompanyClaimRequest).where(
|
||
CompanyClaimRequest.status == "pending",
|
||
CompanyClaimRequest.review_level == "park_admin")
|
||
.order_by(CompanyClaimRequest.created_at.desc()))).all()
|
||
items += [_claim_dict(r) for r in op_rows]
|
||
# 企业管理员:本企业的 company_admin 认领
|
||
for m in await db.company_members.admin_of(user["id"]):
|
||
co_rows = (await db.session.scalars(
|
||
select(CompanyClaimRequest).where(
|
||
CompanyClaimRequest.company_id == m["company_id"],
|
||
CompanyClaimRequest.status == "pending",
|
||
CompanyClaimRequest.review_level == "company_admin")
|
||
.order_by(CompanyClaimRequest.created_at.desc()))).all()
|
||
items += [_claim_dict(r) for r in co_rows]
|
||
return {"items": items}
|
||
|
||
|
||
class ReviewAction(BaseModel):
|
||
action: str = "approve" # approve/reject
|
||
comment: str = ""
|
||
|
||
|
||
@router.post("/claims/{cid}/review", summary="认领申请审核")
|
||
async def review_claim(
|
||
cid: str,
|
||
body: ReviewAction,
|
||
request: Request,
|
||
db: Database = Depends(get_db),
|
||
user: dict = Depends(get_current_user),
|
||
):
|
||
if body.action not in ("approve", "reject"):
|
||
raise HTTPException(status_code=400, detail="审核动作不合法")
|
||
req = (await db.session.execute(
|
||
select(CompanyClaimRequest).where(CompanyClaimRequest.id == cid))).scalars().first()
|
||
if req is None:
|
||
raise HTTPException(status_code=404, detail="申请不存在")
|
||
if req.status != "pending":
|
||
raise HTTPException(status_code=400, detail="该申请已处理")
|
||
# 审核权校验(运营方兜底园区级审核,admin 端园区详情可用)
|
||
if req.review_level == "park_admin":
|
||
if not await _is_park_admin(db, req.tenant_id, user) and user.get("role") != "operator":
|
||
raise HTTPException(status_code=403, detail="仅该园区管理员可审核")
|
||
else: # company_admin
|
||
mine = await db.company_members.get(user["id"], req.company_id)
|
||
if mine is None or not mine.get("is_admin") or mine.get("status") != "active":
|
||
raise HTTPException(status_code=403, detail="仅该企业管理员可审核")
|
||
if body.action == "reject":
|
||
req.status = "rejected"
|
||
req.review_comment = body.comment.strip()
|
||
req.reviewer_id = user.get("id", "")
|
||
req.reviewer_name = user.get("username", "")
|
||
req.reviewed_at = _now()
|
||
await db.session.commit()
|
||
await write_audit(db, action="ent.claim_reject", resource="company_claim_request",
|
||
resource_id=req.id, detail=f"company={req.company_name}", user=user, request=request)
|
||
return {"ok": True, "status": "rejected"}
|
||
# approve:复查约束后落成员关系
|
||
admins = (await db.session.scalars(
|
||
select(CompanyMember).where(CompanyMember.company_id == req.company_id,
|
||
CompanyMember.is_admin.is_(True),
|
||
CompanyMember.status == "active"))).all()
|
||
if req.claim_role == "admin" and admins:
|
||
req.status = "rejected"
|
||
req.review_comment = "该企业已有管理员,认领失败"
|
||
req.reviewer_id = user.get("id", "")
|
||
req.reviewer_name = user.get("username", "")
|
||
req.reviewed_at = _now()
|
||
await db.session.commit()
|
||
return {"ok": False, "status": "rejected", "reason": "该企业已有管理员"}
|
||
is_admin = req.claim_role == "admin"
|
||
await db.company_members.add(
|
||
req.user_id, req.company_id,
|
||
is_admin=is_admin,
|
||
member_type="admin" if is_admin else "staff",
|
||
created_by=user.get("id", ""),
|
||
)
|
||
if is_admin:
|
||
comp = (await db.session.execute(
|
||
select(ParkCompany).where(ParkCompany.id == req.company_id))).scalars().first()
|
||
if comp is not None:
|
||
comp.owner_user_id = req.user_id
|
||
req.status = "approved"
|
||
req.review_comment = body.comment.strip()
|
||
req.reviewer_id = user.get("id", "")
|
||
req.reviewer_name = user.get("username", "")
|
||
req.reviewed_at = _now()
|
||
await db.session.commit()
|
||
await write_audit(db, action="ent.claim_approve", resource="company_claim_request",
|
||
resource_id=req.id, detail=f"company={req.company_name} role={req.claim_role}",
|
||
user=user, request=request)
|
||
return {"ok": True, "status": "approved"}
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 企业入驻申请
|
||
# ---------------------------------------------------------------------------
|
||
|
||
|
||
class CompanyApply(BaseModel):
|
||
entry_type: str = "park_entered" # park_entered/independent
|
||
tenant_id: str = "" # park_entered 必填
|
||
company_name: str
|
||
legal_person: str = ""
|
||
legal_phone: str = ""
|
||
contact_phone: str = ""
|
||
address: str = ""
|
||
industry: str = ""
|
||
registered_capital: str = ""
|
||
company_type: str = ""
|
||
bio: str = ""
|
||
docs: dict = {}
|
||
upgrade_from_team_id: str = ""
|
||
|
||
|
||
@router.post("/companies/apply", summary="企业入驻申请(已有企业加入平台)")
|
||
async def apply_company(
|
||
body: CompanyApply,
|
||
request: Request,
|
||
db: Database = Depends(get_db),
|
||
user: dict = Depends(get_current_user),
|
||
):
|
||
return await _apply_company_impl(db, user, request, body)
|
||
|
||
|
||
async def _apply_company_impl(db: Database, user: dict, request: Request, body: CompanyApply) -> dict:
|
||
"""企业入驻申请校验+落库(供 /ent/teams/{tid}/upgrade 复用)。"""
|
||
entry = (body.entry_type or "park_entered").strip()
|
||
if entry not in ("park_entered", "independent"):
|
||
raise HTTPException(status_code=400, detail="入驻类型不合法")
|
||
name = (body.company_name or "").strip()
|
||
if not name:
|
||
raise HTTPException(status_code=400, detail="请填写企业名称")
|
||
tenant_id = (body.tenant_id or "").strip()
|
||
if entry == "park_entered":
|
||
if not tenant_id:
|
||
raise HTTPException(status_code=400, detail="入驻园区必须选择园区")
|
||
t = (await db.session.execute(
|
||
select(ParkTenant).where(ParkTenant.id == tenant_id))).scalars().first()
|
||
if t is None:
|
||
raise HTTPException(status_code=404, detail="园区不存在")
|
||
tenant_name = t.name
|
||
else:
|
||
tenant_id = ""
|
||
tenant_name = ""
|
||
# 同名企业已存在则不能重复入驻
|
||
dup_co = (await db.session.scalar(
|
||
select(ParkCompany).where(ParkCompany.name == name)))
|
||
if dup_co is not None:
|
||
raise HTTPException(status_code=400, detail="该企业已入驻平台,可前往「认领企业」认领")
|
||
dup = (await db.session.scalar(
|
||
select(CompanyApplyRequest).where(
|
||
CompanyApplyRequest.user_id == user["id"],
|
||
CompanyApplyRequest.company_name == name,
|
||
CompanyApplyRequest.status == "pending")))
|
||
if dup is not None:
|
||
raise HTTPException(status_code=400, detail="已有同名企业待审核申请")
|
||
review_level = "park_admin" if entry == "park_entered" else "operator"
|
||
rec = CompanyApplyRequest(
|
||
id=new_id("apply"), user_id=user["id"], username=user.get("username", ""),
|
||
entry_type=entry, tenant_id=tenant_id, tenant_name=tenant_name,
|
||
company_name=name, legal_person=body.legal_person.strip(),
|
||
legal_phone=body.legal_phone.strip(), contact_phone=body.contact_phone.strip(),
|
||
address=body.address.strip(), industry=body.industry.strip(),
|
||
registered_capital=body.registered_capital.strip(),
|
||
company_type=body.company_type.strip(), bio=body.bio.strip(),
|
||
docs_json=json.dumps(body.docs or {}, ensure_ascii=False),
|
||
upgrade_from_team_id=(body.upgrade_from_team_id or "").strip(),
|
||
status="pending", review_level=review_level, created_at=_now(),
|
||
)
|
||
db.session.add(rec)
|
||
await db.session.commit()
|
||
await write_audit(db, action="ent.company_apply", resource="company_apply_request",
|
||
resource_id=rec.id, detail=f"company={name} entry={entry}",
|
||
user=user, request=request)
|
||
return {"ok": True, "id": rec.id, "review_level": review_level}
|
||
|
||
|
||
@router.get("/companies/applies/mine", summary="我的企业入驻申请")
|
||
async def my_applies(
|
||
db: Database = Depends(get_db),
|
||
user: dict = Depends(get_current_user),
|
||
):
|
||
rows = (await db.session.scalars(
|
||
select(CompanyApplyRequest).where(CompanyApplyRequest.user_id == user["id"])
|
||
.order_by(CompanyApplyRequest.created_at.desc()))).all()
|
||
return {"items": [_apply_dict(r) for r in rows]}
|
||
|
||
|
||
@router.get("/companies/applies/reviews", summary="待审企业入驻申请(园区管理员/运营方)")
|
||
async def apply_reviews(
|
||
db: Database = Depends(get_db),
|
||
user: dict = Depends(get_current_user),
|
||
):
|
||
items = []
|
||
if user.get("role") == "operator":
|
||
op_rows = (await db.session.scalars(
|
||
select(CompanyApplyRequest).where(
|
||
CompanyApplyRequest.status == "pending",
|
||
CompanyApplyRequest.review_level == "operator")
|
||
.order_by(CompanyApplyRequest.created_at.desc()))).all()
|
||
items += [_apply_dict(r) for r in op_rows]
|
||
# 运营方兜底:全部园区级企业入驻申请(admin 园区详情按园区过滤)
|
||
park_op_rows = (await db.session.scalars(
|
||
select(CompanyApplyRequest).where(
|
||
CompanyApplyRequest.status == "pending",
|
||
CompanyApplyRequest.review_level == "park_admin")
|
||
.order_by(CompanyApplyRequest.created_at.desc()))).all()
|
||
items += [_apply_dict(r) for r in park_op_rows]
|
||
tids = (await db.session.scalars(
|
||
select(ParkTenant.id).where(ParkTenant.operator_user_id == user.get("id", "")))).all()
|
||
if tids:
|
||
park_rows = (await db.session.scalars(
|
||
select(CompanyApplyRequest).where(
|
||
CompanyApplyRequest.tenant_id.in_(tids),
|
||
CompanyApplyRequest.status == "pending",
|
||
CompanyApplyRequest.review_level == "park_admin")
|
||
.order_by(CompanyApplyRequest.created_at.desc()))).all()
|
||
items += [_apply_dict(r) for r in park_rows]
|
||
return {"items": items}
|
||
|
||
|
||
@router.post("/companies/applies/{aid}/review", summary="企业入驻申请审核")
|
||
async def review_apply(
|
||
aid: str,
|
||
body: ReviewAction,
|
||
request: Request,
|
||
db: Database = Depends(get_db),
|
||
user: dict = Depends(get_current_user),
|
||
):
|
||
if body.action not in ("approve", "reject"):
|
||
raise HTTPException(status_code=400, detail="审核动作不合法")
|
||
rec = (await db.session.execute(
|
||
select(CompanyApplyRequest).where(CompanyApplyRequest.id == aid))).scalars().first()
|
||
if rec is None:
|
||
raise HTTPException(status_code=404, detail="申请不存在")
|
||
if rec.status != "pending":
|
||
raise HTTPException(status_code=400, detail="该申请已处理")
|
||
# 审核权校验(运营方兜底园区级审核)
|
||
if rec.review_level == "operator":
|
||
if user.get("role") != "operator":
|
||
raise HTTPException(status_code=403, detail="仅运营方可审核该申请")
|
||
else:
|
||
if not await _is_park_admin(db, rec.tenant_id, user) and user.get("role") != "operator":
|
||
raise HTTPException(status_code=403, detail="仅该园区管理员可审核")
|
||
if body.action == "reject":
|
||
rec.status = "rejected"
|
||
rec.review_comment = body.comment.strip()
|
||
rec.reviewer_id = user.get("id", "")
|
||
rec.reviewer_name = user.get("username", "")
|
||
rec.reviewed_at = _now()
|
||
await db.session.commit()
|
||
await write_audit(db, action="ent.company_apply_reject", resource="company_apply_request",
|
||
resource_id=rec.id, detail=f"company={rec.company_name}", user=user, request=request)
|
||
return {"ok": True, "status": "rejected"}
|
||
# approve:同名企业复查 → 创建企业 + 提交人设管理员
|
||
dup_co = (await db.session.scalar(
|
||
select(ParkCompany).where(ParkCompany.name == rec.company_name)))
|
||
if dup_co is not None:
|
||
rec.status = "rejected"
|
||
rec.review_comment = "企业已存在,请改用认领"
|
||
rec.reviewer_id = user.get("id", "")
|
||
rec.reviewer_name = user.get("username", "")
|
||
rec.reviewed_at = _now()
|
||
await db.session.commit()
|
||
return {"ok": False, "status": "rejected", "reason": "企业已存在"}
|
||
kind = "park_entered" if rec.entry_type == "park_entered" else "independent"
|
||
comp = ParkCompany(
|
||
id=new_id("PC"), tenant_id=rec.tenant_id or None,
|
||
company_kind=kind, name=rec.company_name,
|
||
industry=rec.industry, bio=rec.bio, founder=rec.legal_person,
|
||
status="active", legal_person=rec.legal_person, legal_phone=rec.legal_phone,
|
||
contact_phone=rec.contact_phone, address=rec.address,
|
||
registered_capital=rec.registered_capital, company_type=rec.company_type,
|
||
owner_user_id=rec.user_id, created_at=_now(),
|
||
)
|
||
db.session.add(comp)
|
||
await db.session.flush()
|
||
await db.company_members.add(rec.user_id, comp.id, is_admin=True,
|
||
member_type="owner", created_by=user.get("id", ""))
|
||
rec.status = "approved"
|
||
rec.review_comment = body.comment.strip()
|
||
rec.reviewer_id = user.get("id", "")
|
||
rec.reviewer_name = user.get("username", "")
|
||
rec.reviewed_at = _now()
|
||
await db.session.commit()
|
||
# 团队升级:标记团队已升级并关联企业
|
||
if rec.upgrade_from_team_id:
|
||
from ...infrastructure.models import Team
|
||
team = (await db.session.execute(
|
||
select(Team).where(Team.id == rec.upgrade_from_team_id))).scalars().first()
|
||
if team is not None and team.owner_user_id == rec.user_id:
|
||
team.status = "upgraded"
|
||
team.upgraded_company_id = comp.id
|
||
await db.session.commit()
|
||
await write_audit(db, action="ent.company_apply_approve", resource="company_apply_request",
|
||
resource_id=rec.id, detail=f"company={rec.company_name} company_id={comp.id}",
|
||
user=user, request=request)
|
||
return {"ok": True, "status": "approved", "company_id": comp.id}
|