<script setup lang="ts">
|
import { computed, ref } from 'vue';
|
|
defineOptions({
|
name: 'SilkStorageOutputReport'
|
});
|
|
type SegmentKey = 'boxMark' | 'tiaoheMark' | 'heBarcode' | 'tiaoheBarcode' | 'syncResult';
|
type BottomKey =
|
| 'boxPack'
|
| 'tiaoPack'
|
| 'hePack'
|
| 'appearance'
|
| 'hotStamp'
|
| 'endFade'
|
| 'impurityRate'
|
| 'moistureRate'
|
| 'length'
|
| 'composite';
|
|
const zoom = ref(1);
|
const activeSegment = ref<SegmentKey>('syncResult');
|
const activeBottom = ref<BottomKey>('composite');
|
|
const segmentOptions: { key: SegmentKey; label: string; tone: 'warning' | 'info' | 'success' }[] = [
|
{ key: 'boxMark', label: '箱标识', tone: 'warning' },
|
{ key: 'tiaoheMark', label: '条盒标识', tone: 'warning' },
|
{ key: 'heBarcode', label: '盒条码', tone: 'success' },
|
{ key: 'tiaoheBarcode', label: '条盒码', tone: 'success' },
|
{ key: 'syncResult', label: '同步现场结果', tone: 'info' }
|
];
|
|
const bottomOptions: { key: BottomKey; label: string; tone: 'warning' | 'success' }[] = [
|
{ key: 'boxPack', label: '箱包装质量', tone: 'warning' },
|
{ key: 'tiaoPack', label: '条包装质量', tone: 'warning' },
|
{ key: 'hePack', label: '盒包装质量', tone: 'warning' },
|
{ key: 'appearance', label: '外观', tone: 'warning' },
|
{ key: 'hotStamp', label: '烫火', tone: 'warning' },
|
{ key: 'endFade', label: '端部落色', tone: 'success' },
|
{ key: 'impurityRate', label: '含杂率', tone: 'success' },
|
{ key: 'moistureRate', label: '含水率', tone: 'success' },
|
{ key: 'length', label: '长度', tone: 'success' },
|
{ key: 'composite', label: '综合项', tone: 'success' }
|
];
|
|
const activeSegmentLabel = computed(() => segmentOptions.find(o => o.key === activeSegment.value)?.label ?? '');
|
|
const summaryRows = ref([
|
{
|
sampleNo: 'DAC250312001',
|
brand: '金圣(软)',
|
factory: '中烟卷烟厂',
|
spec: '84.0 (Ø24.0±0.6), 0.0mm×24.0mm',
|
tiaoCode: '6901028133241',
|
heCode: '6901028133234',
|
inspectMode: '实验室检查',
|
boxMark: 0,
|
tiaoheMark: 0,
|
heBarcode: 0,
|
tiaoheBarcode: 0,
|
syncResult: 0,
|
gradeA: 0,
|
gradeB: 0,
|
gradeC: 0,
|
appearance: 0,
|
score: 100,
|
conclusion: '/',
|
remark: '/'
|
}
|
]);
|
|
const detailRows = ref([
|
{
|
index: 1,
|
sampleNo: 'DAC250312001',
|
brand: '金圣(软)',
|
factory: '中烟卷烟厂',
|
productDate: '2025-03-11',
|
minor: 0,
|
medium: 0,
|
major: 0,
|
total: 0,
|
appearanceScore: 0,
|
appearanceDesc: '图文清晰度,整洁度符合要求;表面无破损',
|
compositeScore: 0,
|
compositeConclusion: '/',
|
remark: '/'
|
}
|
]);
|
|
const detailScrollRef = ref<HTMLElement | null>(null);
|
const activeCell = ref<{ table: 'summary' | 'detail'; rowIndex: number; field: string } | null>(null);
|
const editModalOpen = ref(false);
|
const editValue = ref('');
|
const editMeta = ref<{ table: 'summary' | 'detail'; rowIndex: number; field: string; label: string } | null>(null);
|
|
const summaryFieldLabels: Record<string, string> = {
|
sampleNo: '样品编号',
|
brand: '牌号',
|
factory: '生产厂',
|
spec: '规格',
|
tiaoCode: '条码',
|
heCode: '盒码',
|
inspectMode: '检测形式',
|
boxMark: '箱标识',
|
tiaoheMark: '条盒标识',
|
heBarcode: '盒条码',
|
tiaoheBarcode: '条盒码',
|
syncResult: '同步现场结果',
|
gradeA: '等级A',
|
gradeB: '等级B',
|
gradeC: '等级C',
|
appearance: '外观扣分',
|
score: '得分',
|
conclusion: '结论',
|
remark: '备注'
|
};
|
|
const detailFieldLabels: Record<string, string> = {
|
index: '序号',
|
sampleNo: '样品编号',
|
brand: '牌号',
|
factory: '生产厂',
|
productDate: '生产日期',
|
minor: '小项扣分',
|
medium: '中项扣分',
|
major: '大项扣分',
|
total: '合计',
|
appearanceScore: '扣分',
|
appearanceDesc: '描述',
|
compositeScore: '扣分',
|
compositeConclusion: '结论',
|
remark: '备注'
|
};
|
|
function setZoom(next: number) {
|
const v = Math.max(0.6, Math.min(1.2, Number(next)));
|
zoom.value = Number.isFinite(v) ? v : 1;
|
}
|
|
function handlePrint() {
|
window.print();
|
}
|
|
function handleReset() {
|
activeSegment.value = 'syncResult';
|
activeBottom.value = 'composite';
|
setZoom(1);
|
}
|
|
function handleDetailScroll(direction: 'left' | 'right') {
|
const el = detailScrollRef.value;
|
if (!el) return;
|
const step = Math.max(200, Math.round(el.clientWidth * 0.6));
|
el.scrollBy({ left: direction === 'left' ? -step : step, behavior: 'smooth' });
|
}
|
|
function setActiveCell(table: 'summary' | 'detail', rowIndex: number, field: string) {
|
activeCell.value = { table, rowIndex, field };
|
}
|
|
function isActiveCell(table: 'summary' | 'detail', rowIndex: number, field: string) {
|
return (
|
activeCell.value?.table === table && activeCell.value?.rowIndex === rowIndex && activeCell.value?.field === field
|
);
|
}
|
|
function openEditModal(table: 'summary' | 'detail', rowIndex: number, field: string) {
|
setActiveCell(table, rowIndex, field);
|
const rows = table === 'summary' ? summaryRows.value : detailRows.value;
|
const row = rows[rowIndex];
|
if (!row) return;
|
const labelMap = table === 'summary' ? summaryFieldLabels : detailFieldLabels;
|
editMeta.value = {
|
table,
|
rowIndex,
|
field,
|
label: labelMap[field] ?? field
|
};
|
editValue.value = row[field as keyof typeof row] as string;
|
editModalOpen.value = true;
|
}
|
|
function handleEditConfirm() {
|
if (!editMeta.value) return;
|
const { table, rowIndex, field } = editMeta.value;
|
const rows = table === 'summary' ? summaryRows.value : detailRows.value;
|
const row = rows[rowIndex];
|
if (!row) return;
|
row[field as keyof typeof row] = editValue.value as never;
|
editModalOpen.value = false;
|
}
|
</script>
|
|
<template>
|
<div class="h-full min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
<NCard
|
:bordered="false"
|
size="small"
|
class="flex flex-col card-wrapper sm:flex-1-hidden"
|
content-style="padding: 0; flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column;"
|
>
|
<div class="report-root">
|
<div class="report-toolbar">
|
<div class="flex-y-center gap-8px">
|
<NButton size="small" @click="handleReset">刷新</NButton>
|
<NButton size="small" type="primary" @click="handlePrint">打印</NButton>
|
</div>
|
<div class="flex-y-center gap-8px">
|
<span class="report-toolbar__label">缩放</span>
|
<NButton size="small" @click="setZoom(zoom - 0.1)">-</NButton>
|
<NInputNumber v-model:value="zoom" size="small" :min="0.6" :max="1.2" :step="0.1" class="w-90px" />
|
<NButton size="small" @click="setZoom(zoom + 0.1)">+</NButton>
|
</div>
|
</div>
|
|
<div class="report-stage">
|
<div class="report-sheet" :style="{ transform: `scale(${zoom})` }">
|
<div class="report-title">卷烟产品包装标识质量检验结果汇总表</div>
|
|
<div class="report-table-scroll">
|
<table class="report-table">
|
<thead>
|
<tr>
|
<th rowspan="2">样品编号</th>
|
<th rowspan="2">牌号</th>
|
<th rowspan="2">生产厂</th>
|
<th rowspan="2">规格</th>
|
<th rowspan="2">条码</th>
|
<th rowspan="2">盒码</th>
|
<th rowspan="2">检测形式</th>
|
<th colspan="5">包装标识</th>
|
<th colspan="3">条码识别等级</th>
|
<th rowspan="2">外观扣分</th>
|
<th rowspan="2">得分</th>
|
<th rowspan="2">结论</th>
|
<th rowspan="2">备注(缺陷描述/问题内容)</th>
|
</tr>
|
<tr>
|
<th>箱标识</th>
|
<th>条盒标识</th>
|
<th>盒条码</th>
|
<th>条盒码</th>
|
<th>同步现场结果</th>
|
<th>等级A</th>
|
<th>等级B</th>
|
<th>等级C</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr v-for="(row, rowIndex) in summaryRows" :key="row.sampleNo">
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'sampleNo') }"
|
@click="setActiveCell('summary', rowIndex, 'sampleNo')"
|
@dblclick="openEditModal('summary', rowIndex, 'sampleNo')"
|
>
|
{{ row.sampleNo }}
|
</td>
|
<td
|
class="report-cell report-link"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'brand') }"
|
@click="setActiveCell('summary', rowIndex, 'brand')"
|
@dblclick="openEditModal('summary', rowIndex, 'brand')"
|
>
|
{{ row.brand }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'factory') }"
|
@click="setActiveCell('summary', rowIndex, 'factory')"
|
@dblclick="openEditModal('summary', rowIndex, 'factory')"
|
>
|
{{ row.factory }}
|
</td>
|
<td
|
class="report-cell report-left"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'spec') }"
|
@click="setActiveCell('summary', rowIndex, 'spec')"
|
@dblclick="openEditModal('summary', rowIndex, 'spec')"
|
>
|
{{ row.spec }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'tiaoCode') }"
|
@click="setActiveCell('summary', rowIndex, 'tiaoCode')"
|
@dblclick="openEditModal('summary', rowIndex, 'tiaoCode')"
|
>
|
{{ row.tiaoCode }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'heCode') }"
|
@click="setActiveCell('summary', rowIndex, 'heCode')"
|
@dblclick="openEditModal('summary', rowIndex, 'heCode')"
|
>
|
{{ row.heCode }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'inspectMode') }"
|
@click="setActiveCell('summary', rowIndex, 'inspectMode')"
|
@dblclick="openEditModal('summary', rowIndex, 'inspectMode')"
|
>
|
{{ row.inspectMode }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'boxMark') }"
|
@click="setActiveCell('summary', rowIndex, 'boxMark')"
|
@dblclick="openEditModal('summary', rowIndex, 'boxMark')"
|
>
|
{{ row.boxMark }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'tiaoheMark') }"
|
@click="setActiveCell('summary', rowIndex, 'tiaoheMark')"
|
@dblclick="openEditModal('summary', rowIndex, 'tiaoheMark')"
|
>
|
{{ row.tiaoheMark }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'heBarcode') }"
|
@click="setActiveCell('summary', rowIndex, 'heBarcode')"
|
@dblclick="openEditModal('summary', rowIndex, 'heBarcode')"
|
>
|
{{ row.heBarcode }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'tiaoheBarcode') }"
|
@click="setActiveCell('summary', rowIndex, 'tiaoheBarcode')"
|
@dblclick="openEditModal('summary', rowIndex, 'tiaoheBarcode')"
|
>
|
{{ row.tiaoheBarcode }}
|
</td>
|
<td
|
class="report-cell report-cell--active"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'syncResult') }"
|
@click="setActiveCell('summary', rowIndex, 'syncResult')"
|
@dblclick="openEditModal('summary', rowIndex, 'syncResult')"
|
>
|
{{ row.syncResult }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'gradeA') }"
|
@click="setActiveCell('summary', rowIndex, 'gradeA')"
|
@dblclick="openEditModal('summary', rowIndex, 'gradeA')"
|
>
|
{{ row.gradeA }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'gradeB') }"
|
@click="setActiveCell('summary', rowIndex, 'gradeB')"
|
@dblclick="openEditModal('summary', rowIndex, 'gradeB')"
|
>
|
{{ row.gradeB }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'gradeC') }"
|
@click="setActiveCell('summary', rowIndex, 'gradeC')"
|
@dblclick="openEditModal('summary', rowIndex, 'gradeC')"
|
>
|
{{ row.gradeC }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'appearance') }"
|
@click="setActiveCell('summary', rowIndex, 'appearance')"
|
@dblclick="openEditModal('summary', rowIndex, 'appearance')"
|
>
|
{{ row.appearance }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'score') }"
|
@click="setActiveCell('summary', rowIndex, 'score')"
|
@dblclick="openEditModal('summary', rowIndex, 'score')"
|
>
|
{{ row.score }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'conclusion') }"
|
@click="setActiveCell('summary', rowIndex, 'conclusion')"
|
@dblclick="openEditModal('summary', rowIndex, 'conclusion')"
|
>
|
{{ row.conclusion }}
|
</td>
|
<td
|
class="report-cell report-left"
|
:class="{ 'report-cell--selected': isActiveCell('summary', rowIndex, 'remark') }"
|
@click="setActiveCell('summary', rowIndex, 'remark')"
|
@dblclick="openEditModal('summary', rowIndex, 'remark')"
|
>
|
{{ row.remark }}
|
</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
|
<div class="report-signature">
|
<div>批检人:</div>
|
<div>审核人:</div>
|
<div>制表人:</div>
|
</div>
|
|
<div class="report-segment">
|
<div class="report-segment__inner">
|
<button
|
v-for="opt in segmentOptions"
|
:key="opt.key"
|
class="report-pill"
|
:class="[`report-pill--${opt.tone}`, { 'report-pill--active': opt.key === activeSegment }]"
|
type="button"
|
@click="activeSegment = opt.key"
|
>
|
{{ opt.label }}
|
</button>
|
</div>
|
</div>
|
|
<div class="report-title report-title--sub">卷烟包装检验结果汇总表</div>
|
|
<div ref="detailScrollRef" class="report-table-scroll">
|
<table class="report-table report-table--detail">
|
<thead>
|
<tr>
|
<th rowspan="2">序号</th>
|
<th rowspan="2">样品编号</th>
|
<th rowspan="2">牌号</th>
|
<th rowspan="2">生产厂</th>
|
<th rowspan="2">生产日期</th>
|
<th colspan="4">{{ activeSegmentLabel }}</th>
|
<th colspan="2">外观</th>
|
<th colspan="2">综合项</th>
|
<th rowspan="2">备注</th>
|
</tr>
|
<tr>
|
<th>小项扣分</th>
|
<th>中项扣分</th>
|
<th>大项扣分</th>
|
<th>合计</th>
|
<th>扣分</th>
|
<th>描述</th>
|
<th>扣分</th>
|
<th>结论</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr v-for="(row, rowIndex) in detailRows" :key="row.index">
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'index') }"
|
@click="setActiveCell('detail', rowIndex, 'index')"
|
@dblclick="openEditModal('detail', rowIndex, 'index')"
|
>
|
{{ row.index }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'sampleNo') }"
|
@click="setActiveCell('detail', rowIndex, 'sampleNo')"
|
@dblclick="openEditModal('detail', rowIndex, 'sampleNo')"
|
>
|
{{ row.sampleNo }}
|
</td>
|
<td
|
class="report-cell report-link"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'brand') }"
|
@click="setActiveCell('detail', rowIndex, 'brand')"
|
@dblclick="openEditModal('detail', rowIndex, 'brand')"
|
>
|
{{ row.brand }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'factory') }"
|
@click="setActiveCell('detail', rowIndex, 'factory')"
|
@dblclick="openEditModal('detail', rowIndex, 'factory')"
|
>
|
{{ row.factory }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'productDate') }"
|
@click="setActiveCell('detail', rowIndex, 'productDate')"
|
@dblclick="openEditModal('detail', rowIndex, 'productDate')"
|
>
|
{{ row.productDate }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'minor') }"
|
@click="setActiveCell('detail', rowIndex, 'minor')"
|
@dblclick="openEditModal('detail', rowIndex, 'minor')"
|
>
|
{{ row.minor }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'medium') }"
|
@click="setActiveCell('detail', rowIndex, 'medium')"
|
@dblclick="openEditModal('detail', rowIndex, 'medium')"
|
>
|
{{ row.medium }}
|
</td>
|
<td
|
class="report-cell report-cell--danger"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'major') }"
|
@click="setActiveCell('detail', rowIndex, 'major')"
|
@dblclick="openEditModal('detail', rowIndex, 'major')"
|
>
|
{{ row.major }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'total') }"
|
@click="setActiveCell('detail', rowIndex, 'total')"
|
@dblclick="openEditModal('detail', rowIndex, 'total')"
|
>
|
{{ row.total }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'appearanceScore') }"
|
@click="setActiveCell('detail', rowIndex, 'appearanceScore')"
|
@dblclick="openEditModal('detail', rowIndex, 'appearanceScore')"
|
>
|
{{ row.appearanceScore }}
|
</td>
|
<td
|
class="report-cell report-left report-cell--hint"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'appearanceDesc') }"
|
@click="setActiveCell('detail', rowIndex, 'appearanceDesc')"
|
@dblclick="openEditModal('detail', rowIndex, 'appearanceDesc')"
|
>
|
{{ row.appearanceDesc }}
|
</td>
|
<td
|
class="report-cell"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'compositeScore') }"
|
@click="setActiveCell('detail', rowIndex, 'compositeScore')"
|
@dblclick="openEditModal('detail', rowIndex, 'compositeScore')"
|
>
|
{{ row.compositeScore }}
|
</td>
|
<td
|
class="report-cell report-cell--hint"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'compositeConclusion') }"
|
@click="setActiveCell('detail', rowIndex, 'compositeConclusion')"
|
@dblclick="openEditModal('detail', rowIndex, 'compositeConclusion')"
|
>
|
{{ row.compositeConclusion }}
|
</td>
|
<td
|
class="report-cell report-left report-cell--hint"
|
:class="{ 'report-cell--selected': isActiveCell('detail', rowIndex, 'remark') }"
|
@click="setActiveCell('detail', rowIndex, 'remark')"
|
@dblclick="openEditModal('detail', rowIndex, 'remark')"
|
>
|
{{ row.remark }}
|
</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
|
<div class="report-pager">
|
<button class="report-pager__btn" type="button" @click="handleDetailScroll('left')">‹</button>
|
<div class="report-pager__bar"></div>
|
<button class="report-pager__btn" type="button" @click="handleDetailScroll('right')">›</button>
|
</div>
|
|
<div class="report-bottom">
|
<div class="report-bottom__chips">
|
<button
|
v-for="opt in bottomOptions"
|
:key="opt.key"
|
class="report-pill report-pill--bottom"
|
:class="[`report-pill--${opt.tone}`, { 'report-pill--active': opt.key === activeBottom }]"
|
type="button"
|
@click="activeBottom = opt.key"
|
>
|
{{ opt.label }}
|
</button>
|
</div>
|
|
<div class="report-bottom__actions">
|
<NButton size="small" secondary @click="handleReset">刷新</NButton>
|
<NButton size="small" secondary @click="handlePrint">打印</NButton>
|
<NButton size="small" type="primary">推送</NButton>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</NCard>
|
<NModal v-model:show="editModalOpen" :mask-closable="false">
|
<NCard
|
:title="editMeta ? `修改${editMeta.label}` : '修改内容'"
|
style="width: 420px"
|
size="small"
|
closable
|
@close="editModalOpen = false"
|
>
|
<div class="flex flex-col gap-12px">
|
<NInput v-model:value="editValue" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" />
|
<div class="flex justify-end gap-8px">
|
<NButton size="small" @click="editModalOpen = false">取消</NButton>
|
<NButton size="small" type="primary" @click="handleEditConfirm">确定</NButton>
|
</div>
|
</div>
|
</NCard>
|
</NModal>
|
</div>
|
</template>
|
|
<style scoped>
|
.report-root {
|
background: #f3f4f6;
|
padding: 12px;
|
display: flex;
|
flex-direction: column;
|
flex: 1;
|
min-height: 0;
|
}
|
|
.report-toolbar {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 8px 12px;
|
background: #fff;
|
border-bottom: 1px solid #e5e7eb;
|
flex: none;
|
}
|
|
.report-toolbar__label {
|
font-size: 12px;
|
color: #6b7280;
|
}
|
|
.report-stage {
|
padding: 12px;
|
overflow: auto;
|
flex: 1;
|
min-height: 0;
|
}
|
|
.report-sheet {
|
transform-origin: top center;
|
background: #fff;
|
width: 1200px;
|
margin: 0 auto;
|
padding: 18px 18px 16px;
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
}
|
|
.report-title {
|
text-align: center;
|
font-size: 18px;
|
font-weight: 600;
|
padding: 10px 0 12px;
|
color: #111827;
|
}
|
|
.report-title--sub {
|
font-size: 16px;
|
padding-top: 14px;
|
}
|
|
.report-table-scroll {
|
width: 100%;
|
overflow-x: auto;
|
overflow-y: hidden;
|
}
|
|
.report-table {
|
width: 100%;
|
min-width: 1160px;
|
border-collapse: collapse;
|
table-layout: fixed;
|
font-size: 12px;
|
color: #111827;
|
}
|
|
.report-table--detail {
|
min-width: 1400px;
|
}
|
|
.report-table th,
|
.report-table td {
|
border: 1px solid #3f3f46;
|
padding: 6px 6px;
|
text-align: center;
|
vertical-align: middle;
|
line-height: 1.2;
|
}
|
|
.report-table th {
|
background: #fafafa;
|
font-weight: 600;
|
}
|
|
.report-left {
|
text-align: left;
|
}
|
|
.report-link {
|
color: #2563eb;
|
cursor: pointer;
|
}
|
|
.report-cell--selected {
|
outline: 2px solid rgb(var(--primary-color));
|
outline-offset: -2px;
|
}
|
|
.report-signature {
|
display: grid;
|
grid-template-columns: 1fr 1fr 1fr;
|
gap: 8px;
|
padding: 8px 0 2px;
|
color: #111827;
|
font-size: 12px;
|
}
|
|
.report-segment {
|
margin: 10px 0 12px;
|
background: #efefef;
|
padding: 10px 10px;
|
}
|
|
.report-segment__inner {
|
display: flex;
|
justify-content: center;
|
gap: 10px;
|
flex-wrap: wrap;
|
}
|
|
.report-pill {
|
border: 1px solid rgba(0, 0, 0, 0.08);
|
padding: 6px 14px;
|
font-size: 12px;
|
border-radius: 3px;
|
color: #111827;
|
background: #fff;
|
cursor: pointer;
|
user-select: none;
|
}
|
|
.report-pill--bottom {
|
padding: 6px 12px;
|
}
|
|
.report-pill--warning {
|
background: #f59e0b;
|
color: #fff;
|
}
|
|
.report-pill--success {
|
background: #10b981;
|
color: #fff;
|
}
|
|
.report-pill--info {
|
background: #0ea5e9;
|
color: #fff;
|
}
|
|
.report-pill--active {
|
outline: 2px solid rgba(17, 24, 39, 0.25);
|
outline-offset: 1px;
|
}
|
|
.report-cell--active {
|
background: #a5b4fc;
|
}
|
|
.report-cell--hint {
|
background: #c4b5fd;
|
}
|
|
.report-cell--danger {
|
color: #ef4444;
|
background: #fef2f2;
|
font-weight: 700;
|
}
|
|
.report-pager {
|
display: flex;
|
align-items: center;
|
gap: 12px;
|
padding: 10px 0 14px;
|
}
|
|
.report-pager__btn {
|
width: 28px;
|
height: 28px;
|
border: 1px solid #e5e7eb;
|
border-radius: 999px;
|
background: #fff;
|
cursor: pointer;
|
color: #111827;
|
font-size: 18px;
|
line-height: 26px;
|
text-align: center;
|
}
|
|
.report-pager__bar {
|
flex: 1;
|
height: 10px;
|
background: #d4d4d8;
|
border-radius: 999px;
|
}
|
|
.report-bottom {
|
background: #efefef;
|
padding: 12px 10px;
|
}
|
|
.report-bottom__chips {
|
display: flex;
|
justify-content: center;
|
flex-wrap: wrap;
|
gap: 10px;
|
margin-bottom: 12px;
|
}
|
|
.report-bottom__actions {
|
display: flex;
|
justify-content: center;
|
gap: 12px;
|
}
|
|
@media print {
|
.report-root {
|
background: #fff;
|
padding: 0;
|
}
|
|
.report-toolbar,
|
.report-pager,
|
.report-bottom {
|
display: none;
|
}
|
|
.report-stage {
|
padding: 0;
|
overflow: visible;
|
}
|
|
.report-sheet {
|
width: auto;
|
margin: 0;
|
padding: 0;
|
box-shadow: none;
|
transform: none !important;
|
}
|
}
|
</style>
|