chore: 优化图表

This commit is contained in:
王天骄
2026-06-17 10:25:23 +08:00
parent 3e21aa3f77
commit b951f17658
4 changed files with 65 additions and 17 deletions
+26 -3
View File
@@ -596,13 +596,25 @@ p {
}
.overview-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
display: flex;
flex-wrap: wrap;
align-items: stretch;
gap: 18px;
}
.overview-grid > .chart-panel,
.overview-grid > .data-section,
.overview-grid > .stats-grid {
flex: 1 1 calc(33.333% - 12px);
min-width: min(100%, 280px);
}
.wide-chart {
grid-column: span 2;
flex-basis: calc(66.666% - 6px);
}
.full-width-panel {
flex-basis: 100%;
}
.tall-chart {
@@ -1149,3 +1161,14 @@ p {
grid-template-columns: 1fr;
}
}
@media (max-width: 768px) {
.overview-grid > .chart-panel,
.overview-grid > .data-section,
.overview-grid > .stats-grid,
.wide-chart,
.full-width-panel {
flex-basis: 100%;
min-width: 0;
}
}
+7
View File
@@ -24,6 +24,7 @@ const props = defineProps<{
const chartRef = ref<HTMLDivElement>()
let chart: echarts.ECharts | null = null
let resizeObserver: ResizeObserver | null = null
const renderOption = computed(() => normalizeChartOption(props.option))
@@ -47,11 +48,17 @@ watch(renderOption, renderChart, { deep: true })
onMounted(() => {
renderChart()
if (chartRef.value && 'ResizeObserver' in window) {
resizeObserver = new ResizeObserver(handleResize)
resizeObserver.observe(chartRef.value)
}
window.addEventListener('resize', handleResize)
})
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize)
resizeObserver?.disconnect()
resizeObserver = null
chart?.dispose()
chart = null
})
+16 -7
View File
@@ -256,6 +256,13 @@ interface ExamItemForm {
result_text: string
}
const examItemFields: Array<{ key: keyof ExamItemForm; label: string }> = [
{ key: 'item_code', label: '项目编码' },
{ key: 'item_name', label: '项目名称' },
{ key: 'item_type', label: '项目类型' },
{ key: 'result_text', label: '结果文本' }
]
interface CaseDraftForm {
title: string
case_type: DraftCaseType
@@ -552,18 +559,20 @@ function createDefaultScoringRule(): CaseScoringRulePayload {
function normalizeExamItems(): CaseExamItemPayload[] {
const items = draftForm.exam_items
.map(item => ({
.map((item, index) => ({
index,
item_code: item.item_code.trim(),
item_name: item.item_name.trim(),
item_type: item.item_type.trim(),
result_text: item.result_text.trim()
}))
.filter(item => item.item_code || item.item_name || item.item_type || item.result_text)
.filter(item => examItemFields.some(({ key }) => item[key]))
const codes = new Set<string>()
for (const item of items) {
if (!item.item_code) {
throw new Error('检查/检验项目编码必填')
const missingLabels = examItemFields.filter(({ key }) => !item[key]).map(({ label }) => label)
if (missingLabels.length) {
throw new Error(`${item.index + 1}个检查/检验项目需完整填写,缺少:${missingLabels.join('、')}`)
}
if (codes.has(item.item_code)) {
throw new Error(`检查/检验项目编码重复:${item.item_code}`)
@@ -573,9 +582,9 @@ function normalizeExamItems(): CaseExamItemPayload[] {
return items.map(item => ({
item_code: item.item_code,
...(item.item_name ? { item_name: item.item_name } : {}),
...(item.item_type ? { item_type: item.item_type } : {}),
...(item.result_text ? { result_text: item.result_text } : {})
item_name: item.item_name,
item_type: item.item_type,
result_text: item.result_text
}))
}
+16 -7
View File
@@ -634,6 +634,13 @@ interface ExamItemForm {
result_text: string
}
const examItemFields: Array<{ key: keyof ExamItemForm; label: string }> = [
{ key: 'item_code', label: '项目编码' },
{ key: 'item_name', label: '项目名称' },
{ key: 'item_type', label: '项目类型' },
{ key: 'result_text', label: '结果文本' }
]
interface CaseDraftForm {
title: string
case_type: DraftCaseType
@@ -1201,18 +1208,20 @@ function createDefaultScoringRule(form: CaseDraftForm): CaseScoringRulePayload {
function normalizeExamItems(form: CaseDraftForm): CaseExamItemPayload[] {
const items = form.exam_items
.map(item => ({
.map((item, index) => ({
index,
item_code: item.item_code.trim(),
item_name: item.item_name.trim(),
item_type: item.item_type.trim(),
result_text: item.result_text.trim()
}))
.filter(item => item.item_code || item.item_name || item.item_type || item.result_text)
.filter(item => examItemFields.some(({ key }) => item[key]))
const codes = new Set<string>()
for (const item of items) {
if (!item.item_code) {
throw new Error('检查/检验项目编码必填')
const missingLabels = examItemFields.filter(({ key }) => !item[key]).map(({ label }) => label)
if (missingLabels.length) {
throw new Error(`${item.index + 1}个检查/检验项目需完整填写,缺少:${missingLabels.join('、')}`)
}
if (codes.has(item.item_code)) {
throw new Error(`检查/检验项目编码重复:${item.item_code}`)
@@ -1222,9 +1231,9 @@ function normalizeExamItems(form: CaseDraftForm): CaseExamItemPayload[] {
return items.map(item => ({
item_code: item.item_code,
...(item.item_name ? { item_name: item.item_name } : {}),
...(item.item_type ? { item_type: item.item_type } : {}),
...(item.result_text ? { result_text: item.result_text } : {})
item_name: item.item_name,
item_type: item.item_type,
result_text: item.result_text
}))
}