| | |
| | | <el-card style="margin-bottom: 20px;"> |
| | | <div slot="header" class="clearfix"> |
| | | <h3>2. 器官弃用原因分析</h3> |
| | | <el-form :inline="true" style="float: right;"> |
| | | <el-form-item label="器官类型" style="margin-bottom: 0;"> |
| | | <el-select |
| | | v-model="abandonQuery.organType" |
| | | placeholder="请选择器官类型" |
| | | clearable |
| | | size="mini" |
| | | style="width: 150px" |
| | | @change="handleAbandonQuery" |
| | | > |
| | | <el-option |
| | | v-for="item in organOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <EChartsWrapper |
| | | v-if="useMock" |
| | | :id="'abandon-analysis-chart'" |
| | | :options="abandonChartOptions" |
| | | height="400px" |
| | | /> |
| | | <el-empty v-else description="后端暂未提供器官弃用原因统计接口"></el-empty> |
| | | </el-card> |
| | | |
| | | <!-- 第三部分:每供体器官获取数量 --> |
| | | <el-card> |
| | | <div slot="header" class="clearfix"> |
| | | <h3>3. 每供体器官获取数量</h3> |
| | | <el-form :inline="true" style="float: right;"> |
| | | <el-form-item label="年份" style="margin-bottom: 0;"> |
| | | <el-date-picker |
| | | v-model="perDonorQuery.year" |
| | | type="year" |
| | | placeholder="选择年份" |
| | | value-format="yyyy" |
| | | size="mini" |
| | | style="width: 120px" |
| | | @change="handlePerDonorQuery" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="器官类型" style="margin-bottom: 0;"> |
| | | <el-select |
| | | v-model="perDonorQuery.organType" |
| | | placeholder="请选择器官类型" |
| | | clearable |
| | | size="mini" |
| | | style="width: 150px" |
| | | @change="handlePerDonorQuery" |
| | | > |
| | | <el-option |
| | | v-for="item in organOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="tableData" |
| | | style="width: 100%" |
| | | border |
| | | stripe |
| | | > |
| | | <el-table-column label="年份" prop="year" align="center" /> |
| | | <el-table-column label="供体姓名" prop="donorName" align="center" /> |
| | | <el-table-column label="获取数量" prop="acquisitionCount" align="center" > |
| | | <template slot-scope="{ row }"> |
| | | <el-tag :type="getCountTag(row.acquisitionCount)" size="small"> |
| | | {{ row.acquisitionCount }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="全肝" prop="liver" align="center" /> |
| | | <el-table-column label="左半肝" prop="leftLiver" align="center" /> |
| | | <el-table-column label="右半肝" prop="rightLiver" align="center" /> |
| | | <el-table-column label="心脏" prop="heart" align="center" /> |
| | | <el-table-column label="小肠" prop="intestine" align="center" /> |
| | | <el-table-column label="胰腺" prop="pancreas" align="center" /> |
| | | <el-table-column label="左肾" prop="leftKidney" align="center" /> |
| | | <el-table-column label="右肾" prop="rightKidney" align="center" /> |
| | | <el-table-column label="全肺" prop="fullLung" align="center" /> |
| | | <el-table-column label="左肺" prop="leftLung" align="center" /> |
| | | <el-table-column label="右肺" prop="rightLung" align="center" /> |
| | | <el-table-column label="左眼角膜" prop="leftCornea" align="center" /> |
| | | <el-table-column label="右眼角膜" prop="rightCornea" align="center" /> |
| | | <el-table-column label="地区" prop="region" align="center" /> |
| | | <el-table-column label="操作" align="center" fixed="right"> |
| | | <template slot-scope="{ row }"> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="viewDonorDetail(row)" |
| | | > |
| | | 详情 |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <el-pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | :page.sync="query.page" |
| | | :limit.sync="query.limit" |
| | | @current-change="handlePagination" |
| | | @size-change="handlePageSizeChange" |
| | | style="margin-top: 20px;" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | /> |
| | | <template v-if="useMock"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="perDonorTable" |
| | | style="width: 100%" |
| | | border |
| | | stripe |
| | | > |
| | | <el-table-column label="年份" prop="year" align="center" /> |
| | | <el-table-column label="供体姓名" prop="donorName" align="center" /> |
| | | <el-table-column label="获取数量" prop="acquisitionCount" align="center"> |
| | | <template slot-scope="{ row }"> |
| | | <el-tag :type="getCountTag(row.acquisitionCount)" size="small"> |
| | | {{ row.acquisitionCount }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="全肝" prop="liver" align="center" /> |
| | | <el-table-column label="左半肝" prop="leftLiver" align="center" /> |
| | | <el-table-column label="右半肝" prop="rightLiver" align="center" /> |
| | | <el-table-column label="心脏" prop="heart" align="center" /> |
| | | <el-table-column label="小肠" prop="intestine" align="center" /> |
| | | <el-table-column label="胰腺" prop="pancreas" align="center" /> |
| | | <el-table-column label="左肾" prop="leftKidney" align="center" /> |
| | | <el-table-column label="右肾" prop="rightKidney" align="center" /> |
| | | <el-table-column label="全肺" prop="fullLung" align="center" /> |
| | | <el-table-column label="左肺" prop="leftLung" align="center" /> |
| | | <el-table-column label="右肺" prop="rightLung" align="center" /> |
| | | <el-table-column label="左眼角膜" prop="leftCornea" align="center" /> |
| | | <el-table-column label="右眼角膜" prop="rightCornea" align="center" /> |
| | | <el-table-column label="地区" prop="region" align="center" /> |
| | | </el-table> |
| | | </template> |
| | | <el-empty v-else description="后端暂未提供每供体器官获取明细接口"></el-empty> |
| | | </el-card> |
| | | </div> |
| | | </template> |
| | |
| | | <script> |
| | | import FilterPanel from '@/components/charts/FilterPanel.vue'; |
| | | import EChartsWrapper from '@/components/charts/EChartsWrapper.vue'; |
| | | import { organType } from '@/api/businessApi'; |
| | | import { toTotalsList, toNum } from '@/utils/totals'; |
| | | import statisticsMode, { isStatisticsMock } from '@/utils/statisticsMode'; |
| | | import { COLORS, axisTooltip, grid, xAxis, yAxis, legend, barSeries } from '@/utils/chartStyle'; |
| | | |
| | | export default { |
| | | name: 'OrganUtilization', |
| | |
| | | query: { |
| | | region: [], |
| | | monthRange: [], |
| | | ageRange: [], |
| | | chinaCategory: [], |
| | | organType: null, |
| | | page: 1, |
| | | limit: 10 |
| | |
| | | type: 'select', |
| | | multiple: true, |
| | | options: [ |
| | | { label: '青岛地区', value: 'qingdao' }, |
| | | { label: '日照地区', value: 'rizhao' }, |
| | | { label: '济南地区', value: 'jinan' }, |
| | | { label: '烟台地区', value: 'yantai' }, |
| | | { label: '威海地区', value: 'weihai' }, |
| | | { label: '潍坊地区', value: 'weifang' }, |
| | | { label: '临沂地区', value: 'linyi' } |
| | | { label: '青岛地区', value: '青岛地区' }, |
| | | { label: '日照地区', value: '日照地区' }, |
| | | { label: '济南地区', value: '济南地区' }, |
| | | { label: '烟台地区', value: '烟台地区' }, |
| | | { label: '威海地区', value: '威海地区' }, |
| | | { label: '潍坊地区', value: '潍坊地区' }, |
| | | { label: '临沂地区', value: '临沂地区' } |
| | | ], |
| | | width: '300px' |
| | | }, |
| | |
| | | width: '300px' |
| | | }, |
| | | { |
| | | label: '年龄段', |
| | | prop: 'ageRange', |
| | | type: 'select', |
| | | multiple: true, |
| | | options: [ |
| | | { label: '<17岁', value: '0-17' }, |
| | | { label: '18-49岁', value: '18-49' }, |
| | | { label: '50-69岁', value: '50-69' }, |
| | | { label: '>69岁', value: '70-100' } |
| | | ], |
| | | width: '200px' |
| | | }, |
| | | { |
| | | label: '中国分类', |
| | | prop: 'chinaCategory', |
| | | type: 'select', |
| | | multiple: true, |
| | | options: [ |
| | | { label: '中国一类(DBD)', value: '1' }, |
| | | { label: '中国二类(DCD)', value: '2' }, |
| | | { label: '中国三类(DBCD)', value: '3' } |
| | | ], |
| | | width: '200px' |
| | | }, |
| | | { |
| | | label: '器官类型', |
| | | prop: 'organType', |
| | | type: 'select', |
| | | options: [ |
| | | { label: '全肝', value: 'liver' }, |
| | | { label: '肾脏', value: 'kidney' }, |
| | | { label: '心脏', value: 'heart' }, |
| | | { label: '肺', value: 'lung' }, |
| | | { label: '眼角膜', value: 'cornea' } |
| | | { label: '全肝', value: '全肝' }, |
| | | { label: '肾脏', value: '肾脏' }, |
| | | { label: '心脏', value: '心脏' }, |
| | | { label: '肺', value: '肺' }, |
| | | { label: '胰腺', value: '胰腺' }, |
| | | { label: '眼角膜', value: '眼角膜' } |
| | | ], |
| | | width: '200px' |
| | | } |
| | | ], |
| | | |
| | | // 器官选项 |
| | | organOptions: [ |
| | | { label: '全肝', value: 'liver' }, |
| | | { label: '左半肝', value: 'leftLiver' }, |
| | | { label: '右半肝', value: 'rightLiver' }, |
| | | { label: '心脏', value: 'heart' }, |
| | | { label: '小肠', value: 'intestine' }, |
| | | { label: '胰腺', value: 'pancreas' }, |
| | | { label: '左肾', value: 'leftKidney' }, |
| | | { label: '右肾', value: 'rightKidney' }, |
| | | { label: '全肺', value: 'fullLung' }, |
| | | { label: '左肺', value: 'leftLung' }, |
| | | { label: '右肺', value: 'rightLung' }, |
| | | { label: '左眼角膜', value: 'leftCornea' }, |
| | | { label: '右眼角膜', value: 'rightCornea' } |
| | | ], |
| | | |
| | | // 加载状态 |
| | |
| | | |
| | | // 图表配置 |
| | | acquisitionChartOptions: {}, |
| | | abandonChartOptions: {}, |
| | | |
| | | // 表格数据 |
| | | tableData: [], |
| | | total: 0, |
| | | // 器官类型分布数据 |
| | | organData: [], |
| | | |
| | | // 弃用分析查询参数 |
| | | abandonQuery: { |
| | | organType: null |
| | | }, |
| | | |
| | | // 每供体查询参数 |
| | | perDonorQuery: { |
| | | year: '2024', |
| | | organType: null |
| | | }, |
| | | |
| | | // 模拟数据 |
| | | mockData: { |
| | | acquisition: [ |
| | | { |
| | | month: '2024-01', |
| | | region: '青岛地区', |
| | | liver: { acquisition: 8, transplant: 7 }, |
| | | kidney: { acquisition: 12, transplant: 10 }, |
| | | heart: { acquisition: 3, transplant: 3 }, |
| | | lung: { acquisition: 5, transplant: 4 }, |
| | | cornea: { acquisition: 20, transplant: 18 } |
| | | }, |
| | | { |
| | | month: '2024-02', |
| | | region: '青岛地区', |
| | | liver: { acquisition: 10, transplant: 9 }, |
| | | kidney: { acquisition: 15, transplant: 13 }, |
| | | heart: { acquisition: 4, transplant: 3 }, |
| | | lung: { acquisition: 6, transplant: 5 }, |
| | | cornea: { acquisition: 25, transplant: 22 } |
| | | }, |
| | | { |
| | | month: '2024-01', |
| | | region: '日照地区', |
| | | liver: { acquisition: 5, transplant: 4 }, |
| | | kidney: { acquisition: 8, transplant: 7 }, |
| | | heart: { acquisition: 2, transplant: 2 }, |
| | | lung: { acquisition: 3, transplant: 2 }, |
| | | cornea: { acquisition: 15, transplant: 13 } |
| | | } |
| | | ], |
| | | abandon: [ |
| | | { name: '器官质量不合格', value: 45 }, |
| | | { name: '供体疾病', value: 25 }, |
| | | { name: '运输问题', value: 15 }, |
| | | { name: '受体匹配问题', value: 10 }, |
| | | { name: '其他原因', value: 5 } |
| | | ], |
| | | table: [ |
| | | { |
| | | id: 1, |
| | | year: '2024', |
| | | donorName: '张三', |
| | | acquisitionCount: 5, |
| | | liver: 1, |
| | | leftLiver: 0, |
| | | rightLiver: 0, |
| | | heart: 0, |
| | | intestine: 0, |
| | | pancreas: 0, |
| | | leftKidney: 1, |
| | | rightKidney: 1, |
| | | fullLung: 0, |
| | | leftLung: 0, |
| | | rightLung: 0, |
| | | leftCornea: 1, |
| | | rightCornea: 1, |
| | | region: '青岛地区' |
| | | }, |
| | | { |
| | | id: 2, |
| | | year: '2024', |
| | | donorName: '李四', |
| | | acquisitionCount: 3, |
| | | liver: 0, |
| | | leftLiver: 0, |
| | | rightLiver: 0, |
| | | heart: 1, |
| | | intestine: 0, |
| | | pancreas: 0, |
| | | leftKidney: 0, |
| | | rightKidney: 0, |
| | | fullLung: 0, |
| | | leftLung: 1, |
| | | rightLung: 1, |
| | | leftCornea: 0, |
| | | rightCornea: 0, |
| | | region: '青岛地区' |
| | | }, |
| | | { |
| | | id: 3, |
| | | year: '2024', |
| | | donorName: '王五', |
| | | acquisitionCount: 6, |
| | | liver: 1, |
| | | leftLiver: 0, |
| | | rightLiver: 0, |
| | | heart: 0, |
| | | intestine: 0, |
| | | pancreas: 1, |
| | | leftKidney: 1, |
| | | rightKidney: 1, |
| | | fullLung: 0, |
| | | leftLung: 0, |
| | | rightLung: 0, |
| | | leftCornea: 1, |
| | | rightCornea: 1, |
| | | region: '日照地区' |
| | | }, |
| | | { |
| | | id: 4, |
| | | year: '2024', |
| | | donorName: '赵六', |
| | | acquisitionCount: 4, |
| | | liver: 0, |
| | | leftLiver: 0, |
| | | rightLiver: 0, |
| | | heart: 0, |
| | | intestine: 0, |
| | | pancreas: 0, |
| | | leftKidney: 1, |
| | | rightKidney: 1, |
| | | fullLung: 0, |
| | | leftLung: 0, |
| | | rightLung: 0, |
| | | leftCornea: 1, |
| | | rightCornea: 1, |
| | | region: '济南地区' |
| | | }, |
| | | { |
| | | id: 5, |
| | | year: '2023', |
| | | donorName: '钱七', |
| | | acquisitionCount: 3, |
| | | liver: 0, |
| | | leftLiver: 0, |
| | | rightLiver: 0, |
| | | heart: 1, |
| | | intestine: 0, |
| | | pancreas: 0, |
| | | leftKidney: 0, |
| | | rightKidney: 0, |
| | | fullLung: 1, |
| | | leftLung: 0, |
| | | rightLung: 1, |
| | | leftCornea: 0, |
| | | rightCornea: 0, |
| | | region: '烟台地区' |
| | | } |
| | | ] |
| | | } |
| | | // 无接口部分的模拟数据(仅 mock 模式展示) |
| | | abandonReasons: [ |
| | | { name: '器官质量不合格', value: 45 }, |
| | | { name: '供体疾病', value: 25 }, |
| | | { name: '运输问题', value: 15 }, |
| | | { name: '受体匹配问题', value: 10 }, |
| | | { name: '其他原因', value: 5 } |
| | | ], |
| | | perDonorTable: [ |
| | | { id: 1, year: '2024', donorName: '张三', acquisitionCount: 5, liver: 1, leftLiver: 0, rightLiver: 0, heart: 0, intestine: 0, pancreas: 0, leftKidney: 1, rightKidney: 1, fullLung: 0, leftLung: 0, rightLung: 0, leftCornea: 1, rightCornea: 1, region: '青岛地区' }, |
| | | { id: 2, year: '2024', donorName: '李四', acquisitionCount: 3, liver: 0, leftLiver: 0, rightLiver: 0, heart: 1, intestine: 0, pancreas: 0, leftKidney: 0, rightKidney: 0, fullLung: 0, leftLung: 1, rightLung: 1, leftCornea: 0, rightCornea: 0, region: '青岛地区' }, |
| | | { id: 3, year: '2024', donorName: '王五', acquisitionCount: 6, liver: 1, leftLiver: 0, rightLiver: 0, heart: 0, intestine: 0, pancreas: 1, leftKidney: 1, rightKidney: 1, fullLung: 0, leftLung: 0, rightLung: 0, leftCornea: 1, rightCornea: 1, region: '日照地区' }, |
| | | { id: 4, year: '2024', donorName: '赵六', acquisitionCount: 4, liver: 0, leftLiver: 0, rightLiver: 0, heart: 0, intestine: 0, pancreas: 0, leftKidney: 1, rightKidney: 1, fullLung: 0, leftLung: 0, rightLung: 0, leftCornea: 1, rightCornea: 1, region: '济南地区' }, |
| | | { id: 5, year: '2023', donorName: '钱七', acquisitionCount: 3, liver: 0, leftLiver: 0, rightLiver: 0, heart: 1, intestine: 0, pancreas: 0, leftKidney: 0, rightKidney: 0, fullLung: 1, leftLung: 0, rightLung: 1, leftCornea: 0, rightCornea: 0, region: '烟台地区' } |
| | | ] |
| | | }; |
| | | }, |
| | | created() { |
| | | this.loadData(); |
| | | }, |
| | | methods: { |
| | | // 加载数据 |
| | | async loadData() { |
| | | this.loading = true; |
| | | try { |
| | | await new Promise(resolve => setTimeout(resolve, 500)); |
| | | |
| | | // 处理表格数据 |
| | | let filteredData = [...this.mockData.table]; |
| | | |
| | | if (this.query.region.length > 0) { |
| | | filteredData = filteredData.filter(item => |
| | | this.query.region.includes(item.region.replace('地区', '').toLowerCase()) |
| | | ); |
| | | } |
| | | |
| | | if (this.query.monthRange && this.query.monthRange.length === 2) { |
| | | // 这里可以添加月份筛选逻辑 |
| | | } |
| | | |
| | | if (this.query.ageRange.length > 0) { |
| | | // 这里可以添加年龄筛选逻辑 |
| | | } |
| | | |
| | | if (this.query.chinaCategory.length > 0) { |
| | | // 这里可以添加中国分类筛选逻辑 |
| | | } |
| | | |
| | | if (this.query.organType) { |
| | | const organMap = { liver: 'liver', kidney: ['leftKidney', 'rightKidney'], heart: 'heart', lung: ['fullLung', 'leftLung', 'rightLung'], cornea: ['leftCornea', 'rightCornea'] }; |
| | | const organProp = organMap[this.query.organType]; |
| | | if (organProp) { |
| | | if (Array.isArray(organProp)) { |
| | | filteredData = filteredData.filter(item => |
| | | organProp.some(prop => item[prop] > 0) |
| | | ); |
| | | } else { |
| | | filteredData = filteredData.filter(item => item[organProp] > 0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 分页 |
| | | const start = (this.query.page - 1) * this.query.limit; |
| | | this.tableData = filteredData.slice(start, start + this.query.limit); |
| | | this.total = filteredData.length; |
| | | |
| | | // 更新图表 |
| | | this.updateCharts(); |
| | | |
| | | } catch (error) { |
| | | console.error('加载数据失败:', error); |
| | | this.$message.error('数据加载失败'); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | computed: { |
| | | useMock() { |
| | | return isStatisticsMock(); |
| | | }, |
| | | |
| | | // 更新图表 |
| | | updateCharts() { |
| | | // 获取移植统计图 |
| | | const regions = [...new Set(this.mockData.acquisition.map(item => item.region))]; |
| | | const months = [...new Set(this.mockData.acquisition.map(item => item.month))]; |
| | | const organTypes = ['liver', 'kidney', 'heart', 'lung', 'cornea']; |
| | | const organNames = ['肝脏', '肾脏', '心脏', '肺', '眼角膜']; |
| | | |
| | | const seriesData = []; |
| | | const xAxisData = []; |
| | | |
| | | // 生成x轴数据 |
| | | months.forEach(month => { |
| | | regions.forEach(region => { |
| | | xAxisData.push(`${month}\n${region}`); |
| | | }); |
| | | }); |
| | | |
| | | // 生成系列数据 |
| | | organTypes.forEach((organType, index) => { |
| | | const data = []; |
| | | months.forEach(month => { |
| | | regions.forEach(region => { |
| | | const item = this.mockData.acquisition.find(d => d.month === month && d.region === region); |
| | | if (item) { |
| | | data.push(item[organType]?.acquisition || 0); |
| | | } else { |
| | | data.push(0); |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | seriesData.push({ |
| | | name: `${organNames[index]}-获取`, |
| | | type: 'bar', |
| | | stack: '总量', |
| | | data: data, |
| | | itemStyle: this.getSeriesColor(index * 2) |
| | | }); |
| | | |
| | | const transplantData = []; |
| | | months.forEach(month => { |
| | | regions.forEach(region => { |
| | | const item = this.mockData.acquisition.find(d => d.month === month && d.region === region); |
| | | if (item) { |
| | | transplantData.push(item[organType]?.transplant || 0); |
| | | } else { |
| | | transplantData.push(0); |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | seriesData.push({ |
| | | name: `${organNames[index]}-移植`, |
| | | type: 'bar', |
| | | stack: '总量', |
| | | data: transplantData, |
| | | itemStyle: this.getSeriesColor(index * 2 + 1) |
| | | }); |
| | | }); |
| | | |
| | | this.acquisitionChartOptions = { |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'shadow' |
| | | } |
| | | }, |
| | | legend: { |
| | | data: seriesData.map(item => item.name), |
| | | top: 20 |
| | | }, |
| | | grid: { |
| | | left: '3%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | containLabel: true |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: xAxisData, |
| | | axisLabel: { |
| | | interval: 0, |
| | | rotate: 45 |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | name: '数量(个)' |
| | | }, |
| | | series: seriesData |
| | | }; |
| | | |
| | | // 弃用分析图 |
| | | this.abandonChartOptions = { |
| | | abandonChartOptions() { |
| | | return { |
| | | tooltip: { |
| | | trigger: 'item', |
| | | formatter: '{a} <br/>{b} : {c} ({d}%)' |
| | |
| | | legend: { |
| | | orient: 'vertical', |
| | | left: 'left', |
| | | data: this.mockData.abandon.map(item => item.name) |
| | | data: this.abandonReasons.map(item => item.name) |
| | | }, |
| | | series: [ |
| | | { |
| | |
| | | type: 'pie', |
| | | radius: '55%', |
| | | center: ['50%', '60%'], |
| | | data: this.mockData.abandon, |
| | | data: this.abandonReasons, |
| | | emphasis: { |
| | | itemStyle: { |
| | | shadowBlur: 10, |
| | |
| | | } |
| | | ] |
| | | }; |
| | | } |
| | | }, |
| | | created() { |
| | | this.loadData(); |
| | | // 数据源(mock/真实接口)切换时重新加载 |
| | | this.$watch(() => statisticsMode.useMock, () => this.loadData()); |
| | | }, |
| | | methods: { |
| | | // 组装查询条件 |
| | | buildQuery() { |
| | | const q = {}; |
| | | if (this.query.region && this.query.region.length) { |
| | | q.area = this.query.region.join(','); |
| | | } |
| | | if (this.query.monthRange && this.query.monthRange.length === 2) { |
| | | q.startTime = this.query.monthRange[0]; |
| | | q.endTime = this.query.monthRange[1]; |
| | | } |
| | | if (this.query.organType) { |
| | | q.organName = this.query.organType; |
| | | } |
| | | return q; |
| | | }, |
| | | |
| | | // 获取系列颜色 |
| | | getSeriesColor(index) { |
| | | const colors = [ |
| | | '#409EFF', '#8cc5ff', // 肝脏 |
| | | '#67C23A', '#95d475', // 肾脏 |
| | | '#E6A23C', '#f3c96b', // 心脏 |
| | | '#F56C6C', '#f89898', // 肺 |
| | | '#909399', '#b1b3b8' // 眼角膜 |
| | | ]; |
| | | return { color: colors[index % colors.length] }; |
| | | // 加载数据 |
| | | async loadData() { |
| | | this.loading = true; |
| | | try { |
| | | const q = this.buildQuery(); |
| | | const typeRes = await organType(q); |
| | | |
| | | this.organData = toTotalsList(typeRes).map(item => ({ |
| | | name: item.organName || '未知', |
| | | acquisition: toNum(item.getCount), |
| | | transplant: toNum(item.useCount) |
| | | })); |
| | | |
| | | this.updateCharts(); |
| | | } catch (error) { |
| | | console.error('加载数据失败:', error); |
| | | this.$message.error('数据加载失败'); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | |
| | | // 更新图表 |
| | | updateCharts() { |
| | | this.acquisitionChartOptions = { |
| | | tooltip: axisTooltip(), |
| | | legend: legend(['获取数量', '移植数量']), |
| | | grid: grid(), |
| | | xAxis: xAxis(this.organData.map(item => item.name)), |
| | | yAxis: yAxis('数量(个)'), |
| | | series: [ |
| | | barSeries('获取数量', this.organData.map(item => item.acquisition), COLORS.blue), |
| | | barSeries('移植数量', this.organData.map(item => item.transplant), COLORS.green) |
| | | ] |
| | | }; |
| | | }, |
| | | |
| | | // 获取数量标签 |
| | |
| | | this.query = { |
| | | region: [], |
| | | monthRange: [], |
| | | ageRange: [], |
| | | chinaCategory: [], |
| | | organType: null, |
| | | page: 1, |
| | | limit: 10 |
| | |
| | | this.loadData(); |
| | | }, |
| | | |
| | | // 处理分页 |
| | | handlePagination(page) { |
| | | this.query.page = page; |
| | | this.loadData(); |
| | | }, |
| | | |
| | | // 处理分页大小变化 |
| | | handlePageSizeChange(size) { |
| | | this.query.limit = size; |
| | | this.query.page = 1; |
| | | this.loadData(); |
| | | }, |
| | | |
| | | // 处理弃用查询 |
| | | handleAbandonQuery() { |
| | | // 这里可以根据abandonQuery筛选数据 |
| | | console.log('弃用查询:', this.abandonQuery); |
| | | }, |
| | | |
| | | // 处理每供体查询 |
| | | handlePerDonorQuery() { |
| | | this.loadData(); |
| | | }, |
| | | |
| | | // 处理导出 |
| | | handleExport() { |
| | | this.$message.info('导出功能开发中...'); |
| | | }, |
| | | |
| | | // 查看捐献者详情 |
| | | viewDonorDetail(row) { |
| | | this.$router.push({ |
| | | path: '/donor/detail', |
| | | query: { id: row.id } |
| | | }); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .statistics-page { |
| | | padding: 20px; |
| | | } |
| | | </style> |