Python/票据理赔自动化/template.html

727 lines
22 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>票据理赔自动化</title>
<style>
:root {
--arcoblue-1: #e8f3ff;
--arcoblue-2: #bedaff;
--arcoblue-3: #94bfff;
--arcoblue-4: #6aa1ff;
--arcoblue-5: #4080ff;
--arcoblue-6: #165dff;
--arcoblue-7: #0e42d2;
--arcoblue-8: #072ca6;
--arcoblue-9: #031a79;
--arcoblue-10: #000d4d;
--green-1: #e8ffea;
--green-2: #aff0b5;
--green-3: #7be188;
--green-4: #4cd263;
--green-5: #23c343;
--green-6: #00b42a;
--green-7: #009a29;
--green-8: #008026;
--green-9: #006622;
--green-10: #004d1c;
--red-1: #ffece8;
--red-2: #fdcdc5;
--red-3: #fbaca3;
--red-4: #f98981;
--red-5: #f76560;
--red-6: #f53f3f;
--red-7: #cb272d;
--red-8: #a1151e;
--red-9: #770611;
--red-10: #4d000a;
--orange-1: #fff7e8;
--orange-2: #ffe4ba;
--orange-3: #ffcf8b;
--orange-4: #ffb65d;
--orange-5: #ff9a2e;
--orange-6: #ff7d00;
--orange-7: #d25f00;
--orange-8: #a64500;
--orange-9: #792e00;
--orange-10: #4d1b00;
--gray-1: #f7f8fa;
--gray-2: #f2f3f5;
--gray-3: #e5e6eb;
--gray-4: #c9cdd4;
--gray-5: #a9aeb8;
--gray-6: #86909c;
--gray-7: #6b7785;
--gray-8: #4e5969;
--gray-9: #272e3b;
--gray-10: #1d2129;
--color-primary: var(--arcoblue-6);
--color-primary-light: var(--arcoblue-1);
--color-success: var(--green-6);
--color-warning: var(--orange-6);
--color-danger: var(--red-6);
--color-text: var(--gray-10);
--color-text-secondary: var(--gray-8);
--color-border: var(--gray-3);
--color-bg: var(--gray-1);
--color-bg-secondary: #ffffff;
--border-radius-small: 4px;
--border-radius-medium: 6px;
--border-radius-large: 8px;
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, "Noto Sans", sans-serif;
--box-shadow: 0 4px 10px rgba(0, 0, 0, 0.04);
--box-shadow-hover: 0 8px 20px rgba(0, 0, 0, 0.08);
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: var(--font-family);
}
body {
background-color: var(--color-bg);
color: var(--color-text);
line-height: 1.6;
padding: var(--spacing-lg);
min-height: 100vh;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: var(--color-bg-secondary);
border-radius: var(--border-radius-large);
box-shadow: var(--box-shadow);
overflow: hidden;
}
header {
background: var(--color-primary);
color: white;
padding: var(--spacing-xl);
position: relative;
}
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
h1 {
font-size: 20px;
font-weight: 600;
margin-bottom: var(--spacing-sm);
}
.header-info {
font-size: 14px;
opacity: 0.9;
}
.insurance-logo {
background: white;
padding: var(--spacing-xs) var(--spacing-md);
border-radius: 50px;
font-weight: 500;
color: var(--color-primary);
box-shadow: var(--box-shadow);
}
.section {
padding: var(--spacing-lg);
border-bottom: 1px solid var(--color-border);
}
.section:last-child {
border-bottom: none;
}
h2 {
color: var(--color-primary);
font-size: 16px;
margin-bottom: var(--spacing-lg);
padding-bottom: var(--spacing-sm);
border-bottom: 1px solid var(--color-primary-light);
display: flex;
align-items: center;
font-weight: 500;
}
h2:before {
content: "";
display: inline-block;
width: 3px;
height: 16px;
background: var(--color-primary);
border-radius: var(--border-radius-small);
margin-right: var(--spacing-sm);
}
.card-container {
display: grid;
grid-template-columns: 1fr;
gap: var(--spacing-md);
}
.card {
background: var(--color-bg-secondary);
border-radius: var(--border-radius-medium);
padding: var(--spacing-md);
border: 1px solid var(--color-border);
box-shadow: var(--box-shadow);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.card h3 {
color: var(--color-primary);
font-size: 14px;
margin-bottom: var(--spacing-md);
padding-bottom: var(--spacing-sm);
border-bottom: 1px dashed var(--color-border);
font-weight: 500;
}
/* 字段布局 */
.info-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--spacing-md) var(--spacing-lg);
font-size: 14px;
}
.info-item {
display: flex;
flex-direction: column;
margin-bottom: 12px;
}
.info-label {
font-size: 12px;
color: var(--color-text-secondary);
margin-bottom: 4px;
}
.info-value {
font-size: 15px;
font-weight: 500;
word-break: break-word;
padding: 4px 0;
}
.invoice-card {
background: var(--color-bg-secondary);
border-radius: var(--border-radius-medium);
padding: var(--spacing-md);
margin-bottom: var(--spacing-md);
box-shadow: var(--box-shadow);
border: 1px solid var(--color-border);
}
.invoice-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: var(--spacing-md);
padding-bottom: var(--spacing-sm);
border-bottom: 1px solid var(--color-border);
}
.invoice-number-container {
display: flex;
flex-direction: column;
}
.invoice-number {
font-size: 15px;
font-weight: 600;
color: var(--color-primary);
}
.invoice-reference {
margin-top: 4px;
font-size: 12px;
color: var(--color-text-secondary);
}
.invoice-verification {
display: flex;
align-items: center;
}
.verification-tag {
padding: 6px 12px;
border-radius: 50px;
font-weight: 600;
display: inline-block;
font-size: 13px;
border: 1px solid;
}
.verification-tag.valid {
background: var(--green-1);
color: var(--green-7);
border-color: var(--green-3);
}
.verification-tag.suspicious {
background: var(--orange-1);
color: var(--orange-7);
border-color: var(--orange-3);
}
.verification-tag.invalid {
background: var(--red-1);
color: var(--red-7);
border-color: var(--red-3);
}
.invoice-details {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: var(--spacing-md);
margin-bottom: var(--spacing-md);
font-size: 14px;
}
.detail-item {
display: flex;
flex-direction: column;
}
.detail-label {
font-size: 12px;
color: var(--color-text-secondary);
margin-bottom: 4px;
}
.detail-value {
font-size: 14px;
font-weight: 500;
}
table {
width: 100%;
margin-top: var(--spacing-md);
border-collapse: collapse;
border-radius: var(--border-radius-medium);
overflow: hidden;
box-shadow: var(--box-shadow);
font-size: 14px;
table-layout: fixed;
}
th {
background-color: var(--color-primary-light);
color: var(--color-primary);
font-weight: 500;
padding: 12px;
text-align: left;
width: 20%;
word-break: break-word;
}
td {
padding: 12px;
border-bottom: 1px solid var(--color-border);
width: 20%;
word-break: nowrap;
}
tr:nth-child(even) {
background-color: var(--color-bg);
}
tr:hover {
background-color: var(--color-primary-light);
}
.amount-total {
text-align: right;
font-weight: 600;
font-size: 15px;
color: var(--color-primary);
margin-top: var(--spacing-md);
padding-top: var(--spacing-md);
border-top: 1px solid var(--color-border);
}
footer {
text-align: center;
padding: var(--spacing-md);
color: var(--color-text-secondary);
font-size: 12px;
background: var(--color-bg);
border-top: 1px solid var(--color-border);
}
.highlight {
color: var(--color-danger);
font-weight: 500;
}
</style>
</head>
<body>
<div class="container">
<header>
<div class="header-container">
<div>
<h1>理赔报告</h1>
<div class="header-info">
<p>
保险分公司名称: {{ obj["report_layer"]["insurer_company"] }} |
报案时间: {{ obj["report_layer"]["report_time"] |
datetime_to_str }} | 赔案号:{{
obj["report_layer"]["case_number"] }}
</p>
</div>
</div>
</div>
</header>
<div class="section">
<h2>影像件层</h2>
<div>
签收影像件{{ obj["report_layer"]["images_counts"] }}张,其中:已分类{{
obj["classified_images_counts"] }}张,已识别{{
obj["recognized_images_counts"] }}张
</div>
<table>
<thead>
<tr>
<th>影像件编号</th>
<th>影像件路径</th>
<th>影像件类型</th>
<th>已识别</th>
</tr>
</thead>
<tbody>
{% for image_index,image in obj["images_layer"].items() %}
<tr>
<td>{{ image_index }}</td>
<td>{{ image["image_name"] }}</td>
<td>{{ image["image_type"] }}</td>
<td>{{ image["image_recognized"] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="section">
<h2>赔案层</h2>
<div class="card-container">
<div class="card">
<h3>出险人(即被保险人)信息</h3>
<div class="info-grid">
<div class="info-item">
<div class="info-label">姓名</div>
<div class="info-value">
{{ obj["insured_person_layer"]["insured_person"] }}
</div>
</div>
<div class="info-item">
<div class="info-label">出生</div>
<div class="info-value">
{{ obj["insured_person_layer"]["birth_date"] | datetime_to_str
}} | {{ obj["insured_person_layer"]["age"] }}岁
</div>
</div>
<div class="info-item">
<div class="info-label">性别</div>
<div class="info-value">
{{ obj["insured_person_layer"]["gender"] }}
</div>
</div>
<div class="info-item">
<div class="info-label">证件类型</div>
<div class="info-value">
{{ obj["insured_person_layer"]["identity_type"] }}
</div>
</div>
<div class="info-item">
<div class="info-label">证件号码</div>
<div class="info-value">
{{ obj["insured_person_layer"]["identity_number"] }}
</div>
</div>
<div class="info-item">
<div class="info-label">证件有效期</div>
<div class="info-value">
{{ obj["insured_person_layer"]["commencement_date"] |
datetime_to_str }} 至 {{
obj["insured_person_layer"]["termination_date"] |
datetime_to_str }}
</div>
</div>
<div class="info-item">
<div class="info-label">手机号</div>
<div class="info-value">
{{ obj["insured_person_layer"]["phone_number"] }}
</div>
</div>
<div class="info-item">
<div class="info-label">住址</div>
<div class="info-value">
{{ obj["insured_person_layer"]["province"] }} {{
obj["insured_person_layer"]["city"] }} {{
obj["insured_person_layer"]["district"] }}
</div>
<div class="info-value">
{{ obj["insured_person_layer"]["detailed_address"] }}
</div>
</div>
</div>
</div>
<div class="card">
<h3>领款信息</h3>
<div class="info-grid">
<div class="info-item">
<div class="info-label">开户银行</div>
<div class="info-value">
{{ obj["insured_person_layer"]["account_bank"] }}
</div>
</div>
<div class="info-item">
<div class="info-label">户名</div>
<div class="info-value">
{{ obj["insured_person_layer"]["account"] }}
</div>
</div>
<div class="info-item">
<div class="info-label">户号</div>
<div class="info-value">
{{ obj["insured_person_layer"]["account_number"] }}
</div>
</div>
</div>
</div>
<div class="card">
<h3>可理赔责任</h3>
<table>
<thead>
<tr>
<th>团单号</th>
<th>主被保险人</th>
<th>被保险人</th>
<th>与主被保险人关系</th>
<th>保险期</th>
<th>理赔责任</th>
</tr>
</thead>
<tbody>
{% for liability in obj["liabilities_layer"] %}
<tr>
<td>{{ liability["group_policy"] }}</td>
<td>{{ liability["master_insured_person"] }}</td>
<td>{{ liability["insured_person"] }}</td>
<td>{{ liability["relationship"] }}</td>
<td>
{{ liability["commencement_date"] | datetime_to_str }} 至 {{
liability["termination_date"] | datetime_to_str }}
</td>
<td>{{ liability["liability"] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<div class="section">
<h2>结论层</h2>
<div class="invoice-card">
<div class="invoice-details">
<div class="detail-item">
<div class="detail-label">理赔结论</div>
<div class="detail-value">
{{ obj["adjustment_layer"]["conclusion"] }}
</div>
</div>
<div class="detail-item">
<div class="detail-label">理算金额</div>
<div class="detail-value">
{{ obj["adjustment_layer"]["adjustment_amount"] }}
</div>
</div>
<div class="detail-item">
<div class="detail-label">结论说明</div>
<div class="detail-value">
{{ obj["adjustment_layer"]["explanation"] }}
</div>
</div>
</div>
</div>
</div>
<div class="section">
<h2>票据层</h2>
{% for receipt in obj["receipts_layer"] %}
<div class="invoice-card">
<div class="invoice-header">
<div class="invoice-number-container">
<div class="invoice-number">{{ receipt["number"] }}</div>
<span class="invoice-reference"
>关联影像件:
<a
href="file:///{{ receipt.image_path | replace('\\', '/') }}"
target="_blank"
>{{ receipt["image_index"] }}</a
></span
>
</div>
<div class="invoice-verification">
{% if receipt["verification"] == '真票' %}
<span class="verification-tag valid"
>{{ receipt["verification"] }}</span
>
{% elif receipt["verification"] == '无法查验' %}
<span class="verification-tag suspicious"
>{{ receipt["verification"] }}</span
>
{% else %}
<span class="verification-tag invalid"
>{{ receipt["verification"] }}</span
>
{% endif %}
</div>
</div>
<div class="invoice-details">
<div class="detail-item">
<div class="detail-label">出险人</div>
<!-- 出险人可为空值 -->
<div class="detail-value">{{ receipt["payer"] | str_to_str}}</div>
</div>
<div class="detail-item">
<div class="detail-label">票据代码</div>
<!-- 票据代码可为空值 -->
<div class="detail-value">{{ receipt["code"] | str_to_str}}</div>
</div>
<div class="detail-item">
<div class="detail-label">校验码</div>
<div class="detail-value">{{ receipt["check_code"] }}</div>
</div>
<div class="detail-item">
<div class="detail-label">开票日期</div>
<div class="detail-value">
{{ receipt["date"] | datetime_to_str }}
</div>
</div>
<div class="detail-item">
<div class="detail-label">开票金额</div>
<div class="detail-value">{{ receipt["amount"] }}元</div>
</div>
<div class="detail-item">
<div class="detail-label">购药及就医机构</div>
<div class="detail-value">
{{ receipt["institution_type"] }} | {{ receipt["institution"] }}
</div>
</div>
<div class="detail-item">
<div class="detail-label">医疗诊断</div>
<div class="detail-value">{{ receipt["diagnosis"] }}</div>
</div>
</div>
<table>
<thead>
<tr>
<th>药品/医疗服务</th>
<th>数量</th>
<th>金额</th>
<th>个人自费项</th>
<th>个人自付项</th>
<th>合理项</th>
</tr>
</thead>
<tbody>
{% for item in receipt["items"] %}
<tr>
<td>{{ item["category"] }} | {{ item["medicine"] }}</td>
<td>{{ item["quantity"] }}</td>
<td>{{ item["amount"] }}元</td>
<td>{{ item["personal_self_payment"] }}元</td>
<td>{{ item["non_medical_payment"] }}元</td>
<td>{{ item["reasonable_amount"] }}元</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="invoice-details">
<div class="detail-item">
<div class="detail-label">理赔类型</div>
<div class="detail-value">{{ receipt["accident"] }}</div>
</div>
<div class="detail-item">
<div class="detail-label">个人自费金额</div>
<div class="detail-value">
{{ receipt["personal_self_payment"] }}
</div>
</div>
<div class="detail-item">
<div class="detail-label">个人自付金额</div>
<div class="detail-value">
{{ receipt["non_medical_payment"] }}
</div>
</div>
<div class="detail-item">
<div class="detail-label">合理金额</div>
<div class="detail-value">{{ receipt["reasonable_amount"] }}</div>
</div>
</div>
<table>
<thead>
<tr>
<th>票据剩余金额</th>
<th>团单号</th>
<th>个单号</th>
<th>个单剩余保额</th>
<th>理赔责任</th>
<th>个人自费可理算金额</th>
<th>个人自付可理算金额</th>
<th>合理可理算金额</th>
<th>可理算金额</th>
<th>理算金额</th>
</tr>
</thead>
<tbody>
{% for adjustment in receipt["adjustments"] %}
<tr>
<td>{{ adjustment["remaining_amount"] }}</td>
<td>{{ adjustment["group_policy"] }}</td>
<td>{{ adjustment["person_policy"] }}</td>
<td>{{ adjustment["remaining_coverage_amount"] }}</td>
<td>{{ adjustment["liability"] }}</td>
<td>{{ adjustment["personal_self_adjustable_amount"] }}</td>
<td>{{ adjustment["non_medical_adjustable_amount"] }}</td>
<td>{{ adjustment["reasonable_adjustable_amount"] }}</td>
<td>{{ adjustment["adjustable_amount"] }}</td>
<td>{{ adjustment["adjustment_amount"] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="amount-total">
理算金额合计: {{ receipt["adjustment_amount"] }}元
</div>
</div>
{% endfor %}
</div>
<footer>
<p>@liubiren.cloud</p>
</footer>
</div>
</body>
</html>