96 lines
3.8 KiB
Python
96 lines
3.8 KiB
Python
|
|
from app.extensions import db, beijing_time
|
|||
|
|
from app.models.system import SysUser
|
|||
|
|
from datetime import datetime
|
|||
|
|
import json
|
|||
|
|
|
|||
|
|
|
|||
|
|
class BorrowApproval(db.Model):
|
|||
|
|
"""
|
|||
|
|
借库审批单模型
|
|||
|
|
用于管理借库申请的多级审批流程
|
|||
|
|
"""
|
|||
|
|
__tablename__ = 'borrow_approval'
|
|||
|
|
|
|||
|
|
id = db.Column(db.Integer, primary_key=True)
|
|||
|
|
# 审批单号
|
|||
|
|
request_no = db.Column(db.String(100), unique=True, nullable=False, index=True)
|
|||
|
|
# 申请人ID
|
|||
|
|
applicant_id = db.Column(db.Integer, nullable=False, index=True)
|
|||
|
|
# 申请说明
|
|||
|
|
remark = db.Column(db.Text)
|
|||
|
|
# 状态: 0-待审批, 1-已通过, 2-已驳回, 3-已完成(已借出)
|
|||
|
|
status = db.Column(db.Integer, default=0, nullable=False)
|
|||
|
|
# 允许审批的人员列表 (JSON格式)
|
|||
|
|
allowed_approvers = db.Column(db.Text)
|
|||
|
|
# 实际审批人ID
|
|||
|
|
actual_approver_id = db.Column(db.Integer, index=True)
|
|||
|
|
# 审批时间
|
|||
|
|
approved_at = db.Column(db.DateTime)
|
|||
|
|
# 驳回原因
|
|||
|
|
reject_reason = db.Column(db.Text)
|
|||
|
|
# 借库人姓名(申请时填写,审批通过后流转至 TransBorrow)
|
|||
|
|
borrower_name = db.Column(db.String(100))
|
|||
|
|
|
|||
|
|
# 明细快照 (存储借库物品的名称、规格、库位、数量等信息)
|
|||
|
|
items_json = db.Column(db.Text, nullable=False)
|
|||
|
|
|
|||
|
|
# 创建时间和更新时间
|
|||
|
|
created_at = db.Column(db.DateTime, default=beijing_time, nullable=False)
|
|||
|
|
updated_at = db.Column(db.DateTime, default=beijing_time, onupdate=beijing_time, nullable=False)
|
|||
|
|
|
|||
|
|
def _safe_parse_json(self, value):
|
|||
|
|
if value is None:
|
|||
|
|
return []
|
|||
|
|
if isinstance(value, (list, dict)):
|
|||
|
|
return value
|
|||
|
|
if isinstance(value, str):
|
|||
|
|
val = value.strip()
|
|||
|
|
if not val:
|
|||
|
|
return []
|
|||
|
|
try:
|
|||
|
|
parsed = json.loads(val)
|
|||
|
|
return parsed if isinstance(parsed, list) else []
|
|||
|
|
except (json.JSONDecodeError, TypeError, ValueError):
|
|||
|
|
return []
|
|||
|
|
return []
|
|||
|
|
|
|||
|
|
def get_items(self):
|
|||
|
|
return self._safe_parse_json(self.items_json)
|
|||
|
|
|
|||
|
|
def set_items(self, items):
|
|||
|
|
self.items_json = json.dumps(items, ensure_ascii=False) if items else '[]'
|
|||
|
|
|
|||
|
|
def get_allowed_approvers(self):
|
|||
|
|
return self._safe_parse_json(self.allowed_approvers)
|
|||
|
|
|
|||
|
|
def set_allowed_approvers(self, approvers):
|
|||
|
|
self.allowed_approvers = json.dumps(approvers, ensure_ascii=False) if approvers else '[]'
|
|||
|
|
|
|||
|
|
def to_dict(self):
|
|||
|
|
return {
|
|||
|
|
'id': self.id,
|
|||
|
|
'request_no': self.request_no,
|
|||
|
|
'applicant_id': self.applicant_id,
|
|||
|
|
'applicant_name': self._get_user_name(self.applicant_id),
|
|||
|
|
'remark': self.remark,
|
|||
|
|
'status': self.status,
|
|||
|
|
'status_text': ['待审批', '已通过', '已驳回', '已完成'][self.status] if self.status in [0, 1, 2, 3] else '未知',
|
|||
|
|
'allowed_approvers': self.get_allowed_approvers(),
|
|||
|
|
'actual_approver_id': self.actual_approver_id,
|
|||
|
|
'approver_name': self._get_user_name(self.actual_approver_id) if self.actual_approver_id else None,
|
|||
|
|
'approved_at': self.approved_at.strftime('%Y-%m-%d %H:%M:%S') if self.approved_at else None,
|
|||
|
|
'reject_reason': self.reject_reason,
|
|||
|
|
'borrower_name': self.borrower_name,
|
|||
|
|
'items': self.get_items(),
|
|||
|
|
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None,
|
|||
|
|
'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S') if self.updated_at else None,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def _get_user_name(self, user_id):
|
|||
|
|
if not user_id:
|
|||
|
|
return ""
|
|||
|
|
try:
|
|||
|
|
user = SysUser.query.get(user_id)
|
|||
|
|
return user.username if user else f"未知用户({user_id})"
|
|||
|
|
except Exception:
|
|||
|
|
return f"用户({user_id})"
|