feat: 收款账户选项只返回当前登记人并带上所属人姓名
发起校验能识别已删除、他租户和他人账户,编辑账户不会改掉 create_by。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
bd669ea77e
commit
7aa685840f
3 files changed
+87
-9
No files matched your search
@@ -84,7 +84,15 @@ async def list_receive_account_options(
|
|||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
):
|
):
|
||||||
tenant_no = _get_tenant_no(db, user)
|
tenant_no = _get_tenant_no(db, user)
|
||||||
return success_response({"list": ora_crud.list_options(db, tenant_no=tenant_no)})
|
return success_response(
|
||||||
|
{
|
||||||
|
"list": ora_crud.list_options(
|
||||||
|
db,
|
||||||
|
tenant_no=tenant_no,
|
||||||
|
user_id=user.get("user_id") or "",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/receive-accounts/batch-delete")
|
@router.post("/receive-accounts/batch-delete")
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from sqlalchemy import func, or_
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.core.utils import generate_uuid
|
from app.core.utils import generate_uuid
|
||||||
from app.models.models import OaReceiveAccount
|
from app.models.models import OaReceiveAccount, SysUser
|
||||||
|
|
||||||
|
|
||||||
def row_to_dict(r: OaReceiveAccount) -> Dict[str, Any]:
|
def row_to_dict(r: OaReceiveAccount) -> Dict[str, Any]:
|
||||||
@@ -26,9 +26,26 @@ def row_to_dict(r: OaReceiveAccount) -> Dict[str, Any]:
|
|||||||
"remark": r.remark or "",
|
"remark": r.remark or "",
|
||||||
"createTime": r.create_time.strftime("%Y-%m-%d %H:%M:%S") if r.create_time else "",
|
"createTime": r.create_time.strftime("%Y-%m-%d %H:%M:%S") if r.create_time else "",
|
||||||
"updateTime": r.update_time.strftime("%Y-%m-%d %H:%M:%S") if r.update_time else "",
|
"updateTime": r.update_time.strftime("%Y-%m-%d %H:%M:%S") if r.update_time else "",
|
||||||
|
"ownerUserId": (r.create_by or "").strip(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _owner_name_map(db: Session, user_ids: List[str]) -> Dict[str, str]:
|
||||||
|
ids = [item for item in {uid.strip() for uid in user_ids if uid and uid.strip()}]
|
||||||
|
if not ids:
|
||||||
|
return {}
|
||||||
|
rows = db.query(SysUser.id, SysUser.nick_name).filter(SysUser.id.in_(ids)).all()
|
||||||
|
return {row.id: (row.nick_name or "").strip() for row in rows}
|
||||||
|
|
||||||
|
|
||||||
|
def _attach_owner_names(db: Session, items: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||||||
|
names = _owner_name_map(db, [item.get("ownerUserId") or "" for item in items])
|
||||||
|
for item in items:
|
||||||
|
uid = item.get("ownerUserId") or ""
|
||||||
|
item["ownerName"] = names.get(uid) or "—"
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
def _filtered_query(
|
def _filtered_query(
|
||||||
db: Session,
|
db: Session,
|
||||||
*,
|
*,
|
||||||
@@ -74,17 +91,24 @@ def list_accounts(
|
|||||||
.limit(page_size)
|
.limit(page_size)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
return [row_to_dict(x) for x in rows], int(total)
|
return _attach_owner_names(db, [row_to_dict(x) for x in rows]), int(total)
|
||||||
|
|
||||||
|
|
||||||
def list_options(db: Session, *, tenant_no: str) -> List[Dict[str, Any]]:
|
def list_options(db: Session, *, tenant_no: str, user_id: str) -> List[Dict[str, Any]]:
|
||||||
|
owner_id = (user_id or "").strip()
|
||||||
|
if not owner_id:
|
||||||
|
return []
|
||||||
rows = (
|
rows = (
|
||||||
db.query(OaReceiveAccount)
|
db.query(OaReceiveAccount)
|
||||||
.filter(OaReceiveAccount.tenant_no == tenant_no, OaReceiveAccount.del_flag == 0)
|
.filter(
|
||||||
|
OaReceiveAccount.tenant_no == tenant_no,
|
||||||
|
OaReceiveAccount.del_flag == 0,
|
||||||
|
func.trim(OaReceiveAccount.create_by) == owner_id,
|
||||||
|
)
|
||||||
.order_by(OaReceiveAccount.create_time.desc())
|
.order_by(OaReceiveAccount.create_time.desc())
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
return [row_to_dict(x) for x in rows]
|
return _attach_owner_names(db, [row_to_dict(x) for x in rows])
|
||||||
|
|
||||||
|
|
||||||
def get_account(db: Session, account_id: str, tenant_no: str) -> Optional[Dict[str, Any]]:
|
def get_account(db: Session, account_id: str, tenant_no: str) -> Optional[Dict[str, Any]]:
|
||||||
@@ -97,7 +121,7 @@ def get_account(db: Session, account_id: str, tenant_no: str) -> Optional[Dict[s
|
|||||||
)
|
)
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
return row_to_dict(row) if row else None
|
return _attach_owner_names(db, [row_to_dict(row)])[0] if row else None
|
||||||
|
|
||||||
|
|
||||||
def create_account(
|
def create_account(
|
||||||
@@ -131,7 +155,7 @@ def create_account(
|
|||||||
db.add(obj)
|
db.add(obj)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(obj)
|
db.refresh(obj)
|
||||||
return row_to_dict(obj)
|
return _attach_owner_names(db, [row_to_dict(obj)])[0]
|
||||||
|
|
||||||
|
|
||||||
def update_account(
|
def update_account(
|
||||||
@@ -168,7 +192,7 @@ def update_account(
|
|||||||
db.add(obj)
|
db.add(obj)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(obj)
|
db.refresh(obj)
|
||||||
return row_to_dict(obj)
|
return _attach_owner_names(db, [row_to_dict(obj)])[0]
|
||||||
|
|
||||||
|
|
||||||
def soft_delete_account(
|
def soft_delete_account(
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any, Dict, List, Optional, Tuple
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from app.models.models import OaReceiveAccount
|
||||||
|
|
||||||
ACCOUNT_TYPES = frozenset({"alipay", "personal", "corporate"})
|
ACCOUNT_TYPES = frozenset({"alipay", "personal", "corporate"})
|
||||||
|
|
||||||
_BANK_FIELD_ALIASES = {
|
_BANK_FIELD_ALIASES = {
|
||||||
@@ -199,3 +203,45 @@ def validate_receive_account_form_values(
|
|||||||
continue
|
continue
|
||||||
errors.extend(_validate_receive_account_rule(rule, data))
|
errors.extend(_validate_receive_account_rule(rule, data))
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
def validate_receive_account_ownership(
|
||||||
|
db: Session,
|
||||||
|
schema: Any,
|
||||||
|
form_data: Optional[Dict[str, Any]],
|
||||||
|
*,
|
||||||
|
tenant_no: str,
|
||||||
|
initiator_user_id: str,
|
||||||
|
) -> List[str]:
|
||||||
|
"""校验收款账户快照 id 属于发起人。调用前须已通过格式校验。"""
|
||||||
|
data = form_data or {}
|
||||||
|
owner_id = (initiator_user_id or "").strip()
|
||||||
|
for rule in _schema_rules(schema):
|
||||||
|
if str(rule.get("type") or "") != "receiveAccount":
|
||||||
|
continue
|
||||||
|
field = str(rule.get("field") or "").strip()
|
||||||
|
if not field:
|
||||||
|
continue
|
||||||
|
value = data.get(field)
|
||||||
|
if not isinstance(value, list):
|
||||||
|
continue
|
||||||
|
label = _field_label(rule)
|
||||||
|
for item in value:
|
||||||
|
if not isinstance(item, dict):
|
||||||
|
continue
|
||||||
|
item_id = str(item.get("id") or "").strip()
|
||||||
|
if not item_id:
|
||||||
|
continue
|
||||||
|
row = (
|
||||||
|
db.query(OaReceiveAccount)
|
||||||
|
.filter(
|
||||||
|
OaReceiveAccount.id == item_id,
|
||||||
|
OaReceiveAccount.tenant_no == tenant_no,
|
||||||
|
)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
if row is None or int(row.del_flag or 0) == 1:
|
||||||
|
return [f"「{label}」不存在或已删除"]
|
||||||
|
if (row.create_by or "").strip() != owner_id:
|
||||||
|
return [f"「{label}」不属于当前用户"]
|
||||||
|
return []
|
||||||
Reference in new issue
Block a user