test(web): update travel request detail tests and styles
- test_reimbursement_endpoints.py: update reimbursement endpoint tests - travel-request-detail-view.css: update travel request detail styles - TravelRequestDetailView.vue: update travel request detail view
This commit is contained in:
@@ -12,7 +12,9 @@ from sqlalchemy.pool import StaticPool
|
||||
from app.api.deps import get_db
|
||||
from app.db.base import Base
|
||||
from app.main import create_app
|
||||
from app.models.employee import Employee
|
||||
from app.models.financial_record import ExpenseClaim, ExpenseClaimItem
|
||||
from app.models.role import Role
|
||||
from app.schemas.ocr import OcrRecognizeBatchRead, OcrRecognizeDocumentRead
|
||||
from app.services.expense_claims import ExpenseClaimService
|
||||
from app.services.ocr import OcrService
|
||||
@@ -44,10 +46,34 @@ def build_client() -> tuple[TestClient, sessionmaker[Session]]:
|
||||
|
||||
|
||||
def seed_claim(db: Session) -> tuple[ExpenseClaim, ExpenseClaimItem]:
|
||||
manager = Employee(
|
||||
id="mgr-1",
|
||||
employee_no="E20001",
|
||||
name="李总",
|
||||
email="manager@example.com",
|
||||
position="市场总监",
|
||||
grade="P7",
|
||||
)
|
||||
role = Role(
|
||||
id="role-user",
|
||||
role_code="user",
|
||||
name="员工",
|
||||
description="普通员工",
|
||||
)
|
||||
employee = Employee(
|
||||
id="emp-1",
|
||||
employee_no="E10001",
|
||||
name="张三",
|
||||
email="zhangsan@example.com",
|
||||
position="招商主管",
|
||||
grade="P4",
|
||||
manager=manager,
|
||||
roles=[role],
|
||||
)
|
||||
claim = ExpenseClaim(
|
||||
id="claim-attachment-1",
|
||||
claim_no="EXP-202605-101",
|
||||
employee_id="emp-1",
|
||||
employee_id=employee.id,
|
||||
employee_name="张三",
|
||||
department_id="dept-1",
|
||||
department_name="市场部",
|
||||
@@ -75,6 +101,9 @@ def seed_claim(db: Session) -> tuple[ExpenseClaim, ExpenseClaimItem]:
|
||||
invoice_id=None,
|
||||
)
|
||||
claim.items = [item]
|
||||
db.add(manager)
|
||||
db.add(role)
|
||||
db.add(employee)
|
||||
db.add(claim)
|
||||
db.commit()
|
||||
return claim, item
|
||||
@@ -302,6 +331,10 @@ def test_claim_item_delete_removes_item_and_attachment(monkeypatch, tmp_path) ->
|
||||
detail_payload = detail_response.json()
|
||||
assert detail_payload["items"] == []
|
||||
assert detail_payload["invoice_count"] == 0
|
||||
assert detail_payload["employee_position"] == "招商主管"
|
||||
assert detail_payload["employee_grade"] == "P4"
|
||||
assert detail_payload["manager_name"] == "李总"
|
||||
assert detail_payload["role_labels"] == ["员工"]
|
||||
|
||||
deleted_meta_response = client.get(
|
||||
f"/api/v1/reimbursements/claims/{claim_id}/items/{item_id}/attachment/meta",
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
.applicant-card {
|
||||
display: grid;
|
||||
grid-template-columns: 48px minmax(0, 1fr);
|
||||
align-items: center;
|
||||
align-items: start;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
@@ -99,6 +99,41 @@
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.applicant-copy {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.applicant-meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 8px 14px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.applicant-meta-item {
|
||||
min-width: 0;
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.applicant-meta-item span {
|
||||
color: #94a3b8;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: .03em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.applicant-meta-item strong {
|
||||
color: #0f172a;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
line-height: 1.45;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.hero-stat-strip {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
@@ -1624,6 +1659,10 @@
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.applicant-meta {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.hero-stat-strip {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,15 @@
|
||||
<div class="hero-topline">
|
||||
<div class="applicant-card">
|
||||
<div class="portrait">{{ profile.avatar }}</div>
|
||||
<div>
|
||||
<div class="applicant-copy">
|
||||
<h2>{{ profile.name }} <span>{{ request.typeLabel }}</span></h2>
|
||||
<p>{{ profile.department }}</p>
|
||||
<p>{{ profile.position }} · {{ profile.identity }}</p>
|
||||
<div class="applicant-meta">
|
||||
<div v-for="item in profile.facts" :key="item.label" class="applicant-meta-item">
|
||||
<span>{{ item.label }}</span>
|
||||
<strong>{{ item.value }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user