feat(oa): add permission-controlled shared finance remarks to done center
Share one finance remark per approval instance across Web and mobile. Require the explicit permission and the current tenant user's own done task for every read and write; keep general instance responses free of financial remarks. Add idempotent MySQL migration without automatic role grants, cross-end editors, isolated backend and frontend tests, and rollout requirements. Refs #7; platform validation and target database migration remain pending.
This commit is contained in:
1 parent
86df360f35
commit
0e64b413ce
15 files changed
+1188
-78
No files matched your search
@@ -2,7 +2,7 @@
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -15,6 +15,7 @@ from app.crud import oa_instance_draft as oid_crud
|
||||
from app.crud import oa_receive_account as ora_crud
|
||||
from app.models.models import SysUser
|
||||
from app.services.oa_receive_account import normalize_account_fields
|
||||
from app.services import oa_finance_remark as finance_remark_svc
|
||||
|
||||
router = APIRouter(prefix="/web/admin/oa-approval", tags=["OA审批"])
|
||||
|
||||
@@ -1054,6 +1055,44 @@ async def list_oa_instance_form_attachments(
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
class OaFinanceRemarkBody(BaseModel):
|
||||
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
||||
finance_remark: str = Field(..., alias="financeRemark", max_length=512, strict=True)
|
||||
|
||||
|
||||
@router.get("/instances/{instance_id}/finance-remark")
|
||||
async def get_oa_finance_remark(
|
||||
instance_id: str,
|
||||
user: dict = Depends(require_admin_or_super_admin),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
try:
|
||||
access = finance_remark_svc.resolve_access(db, user)
|
||||
return success_response(finance_remark_svc.get_finance_remark(db, access, instance_id))
|
||||
except finance_remark_svc.OaFinanceRemarkError as exc:
|
||||
raise HTTPException(status_code=exc.status_code, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.put("/instances/{instance_id}/finance-remark")
|
||||
async def update_oa_finance_remark(
|
||||
instance_id: str,
|
||||
body: OaFinanceRemarkBody,
|
||||
user: dict = Depends(require_admin_or_super_admin),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
try:
|
||||
access = finance_remark_svc.resolve_access(db, user)
|
||||
result = finance_remark_svc.update_finance_remark(db, access, instance_id, body.finance_remark)
|
||||
db.commit()
|
||||
return success_response(result, message="财务备注已保存")
|
||||
except finance_remark_svc.OaFinanceRemarkError as exc:
|
||||
db.rollback()
|
||||
raise HTTPException(status_code=exc.status_code, detail=str(exc)) from exc
|
||||
except Exception:
|
||||
db.rollback()
|
||||
raise
|
||||
|
||||
|
||||
@router.get("/instances/{instance_id}/bank-receipts")
|
||||
async def list_oa_bank_receipts(
|
||||
instance_id: str,
|
||||
@@ -1365,7 +1404,8 @@ async def list_oa_tasks(
|
||||
from app.services.oa_engine import OaEngineError, list_tasks
|
||||
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
access = finance_remark_svc.resolve_access(db, user) if kind == "done" else None
|
||||
tenant_no = access.tenant_no if access else _get_tenant_no(db, user)
|
||||
data = list_tasks(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
@@ -1381,7 +1421,13 @@ async def list_oa_tasks(
|
||||
page=page,
|
||||
page_size=pageSize,
|
||||
)
|
||||
return success_response({"list": data.get("list") or [], "total": int(data.get("total") or 0)})
|
||||
result = {"list": data.get("list") or [], "total": int(data.get("total") or 0)}
|
||||
if access is not None:
|
||||
finance_remark_svc.add_list_remarks(db, access, result["list"])
|
||||
result["canManageFinanceRemark"] = access.can_manage
|
||||
return success_response(result)
|
||||
except finance_remark_svc.OaFinanceRemarkError as exc:
|
||||
raise HTTPException(status_code=exc.status_code, detail=str(exc)) from exc
|
||||
except OaEngineError as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
Reference in new issue
Block a user