|
@@ -0,0 +1,337 @@
|
|
|
+<template>
|
|
|
+ <el-dialog :title="'添加疾病标签'" v-model="visible" width="1300px" append-to-body class="disease-label-dialog" :close-on-click-modal="false" :destroy-on-close="true" top="40px">
|
|
|
+ <div class="dialog-header-tabs">
|
|
|
+ <el-tabs v-model="activeTab" @tab-click="onTabChange" class="custom-tabs">
|
|
|
+ <el-tab-pane label="常见营养诊断" name="1" />
|
|
|
+ <el-tab-pane label="ICD诊断" name="2" />
|
|
|
+ <el-tab-pane label="营养诊断" name="3" />
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+ <div class="dialog-body-flex">
|
|
|
+ <div class="left-panel">
|
|
|
+ <div class="search-bar">
|
|
|
+ <el-input v-model="search" placeholder="疾病名称/疾病编码" class="search-input" clearable @keyup.enter="fetchData" />
|
|
|
+ <el-button type="primary" class="search-btn" @click="fetchData">查询</el-button>
|
|
|
+ <el-button class="add-btn" @click="addDialogVisible = true">新增疾病标签</el-button>
|
|
|
+ </div>
|
|
|
+ <el-table :data="tableData" border class="disease-table" style="width: 100%; min-height: 360px" @selection-change="handleSelectionChange" :row-class-name="rowClassName">
|
|
|
+ <el-table-column type="selection" width="48" align="center" />
|
|
|
+ <el-table-column prop="labelName" label="疾病/部位名称" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="categoryName" label="所属分类" min-width="100" align="center" />
|
|
|
+ <el-table-column prop="labelCode" label="疾病/部位编码" min-width="120" align="center" />
|
|
|
+ </el-table>
|
|
|
+ <div v-if="!tableData.length" class="no-data">暂无数据</div>
|
|
|
+ <el-pagination v-if="total > 0" class="custom-pagination" background layout="total, sizes, prev, pager, next" :total="total" :page-size="pageSize" :current-page="pageNum" :page-sizes="[10, 20, 50]" @size-change="handleSizeChange" @current-change="handlePageChange" />
|
|
|
+ </div>
|
|
|
+ <div class="right-panel">
|
|
|
+ <div class="right-title">已选疾病标签</div>
|
|
|
+ <el-table :data="selectedLabels" border class="selected-table" style="width: 100%; min-height: 360px">
|
|
|
+ <el-table-column prop="labelName" label="疾病/部位名称" min-width="120" align="center" />
|
|
|
+ <el-table-column prop="categoryName" label="所属分类" min-width="100" align="center" />
|
|
|
+ <el-table-column prop="labelCode" label="疾病/部位编码" min-width="120" align="center" />
|
|
|
+ <el-table-column label="操作" width="60" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-button link type="danger" size="small" @click="removeLabel(row)">删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div v-if="!selectedLabels.length" class="no-data">暂无数据</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="dialog-footer-btns">
|
|
|
+ <el-button type="primary" class="confirm-btn" @click="handleConfirm">确定</el-button>
|
|
|
+ <el-button class="cancel-btn" @click="handleCancel">取消</el-button>
|
|
|
+ </div>
|
|
|
+ <!-- 新增疾病标签弹窗 -->
|
|
|
+ <el-dialog :title="'新增疾病标签'" v-model="addDialogVisible" width="500px" append-to-body @closed="resetAddForm">
|
|
|
+ <el-form ref="addFormRef" :model="addForm" :rules="addRules" label-width="150px">
|
|
|
+ <el-form-item label="疾病/部位名称" prop="labelName">
|
|
|
+ <el-input v-model="addForm.labelName" placeholder="请输入" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="所属分类" prop="category">
|
|
|
+ <el-select v-model="addForm.category" placeholder="请选择">
|
|
|
+ <el-option label="常见营养诊断" value="1" />
|
|
|
+ <el-option label="ICD诊断" value="2" />
|
|
|
+ <el-option label="营养诊断" value="3" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="疾病/部位编码" prop="labelCode">
|
|
|
+ <el-input v-model="addForm.labelCode" placeholder="请输入" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="submitAddForm">确 定</el-button>
|
|
|
+ <el-button @click="addDialogVisible = false">取 消</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+ import { ref, watch, defineProps, defineEmits } from 'vue';
|
|
|
+ import { listDiseaseLabel, addDiseaseLabel } from '@/api/system/diseaseLabel';
|
|
|
+ const props = defineProps < { modelValue: boolean } > ();
|
|
|
+ const emit = defineEmits(['update:modelValue', 'confirm']);
|
|
|
+ const visible = ref(props.modelValue);
|
|
|
+ watch(() => props.modelValue, (v) => { visible.value = v; });
|
|
|
+ watch(visible, (v) => { emit('update:modelValue', v); });
|
|
|
+
|
|
|
+ const activeTab = ref('1');
|
|
|
+ const search = ref('');
|
|
|
+ const tableData = ref < any[] > ([]);
|
|
|
+ const total = ref(0);
|
|
|
+ const pageNum = ref(1);
|
|
|
+ const pageSize = ref(10);
|
|
|
+ const selectedLabels = ref < any[] > ([]);
|
|
|
+
|
|
|
+ // 新增弹窗相关
|
|
|
+ const addDialogVisible = ref(false);
|
|
|
+ const addFormRef = ref();
|
|
|
+ const addForm = ref({ labelName: '', category: '', labelCode: '' });
|
|
|
+ const addRules = {
|
|
|
+ labelName: [{ required: true, message: '请输入疾病/部位名称', trigger: 'blur' }],
|
|
|
+ category: [{ required: true, message: '请选择所属分类', trigger: 'change' }],
|
|
|
+ labelCode: [{ required: true, message: '请输入疾病/部位编码', trigger: 'blur' }],
|
|
|
+ };
|
|
|
+
|
|
|
+ function resetAddForm() {
|
|
|
+ addForm.value = { labelName: '', category: '', labelCode: '' };
|
|
|
+ addFormRef.value ?.resetFields();
|
|
|
+ }
|
|
|
+
|
|
|
+ function submitAddForm() {
|
|
|
+ addFormRef.value ?.validate(async (valid: boolean) => {
|
|
|
+ console.log(addForm.value);
|
|
|
+ if (valid) {
|
|
|
+ await addDiseaseLabel(addForm.value);
|
|
|
+ addDialogVisible.value = false;
|
|
|
+ fetchData();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function fetchData() {
|
|
|
+ listDiseaseLabel({
|
|
|
+ pageNum: pageNum.value,
|
|
|
+ pageSize: pageSize.value,
|
|
|
+ labelName: search.value,
|
|
|
+ labelCode: search.value,
|
|
|
+ category: activeTab.value,
|
|
|
+ params: {}
|
|
|
+ }).then((res) => {
|
|
|
+ let arr: any[] = [];
|
|
|
+ let t = 0;
|
|
|
+ if (Array.isArray(res.rows)) {
|
|
|
+ arr = res.rows;
|
|
|
+ t = res.total || arr.length || 0;
|
|
|
+ } else if (Array.isArray(res.data)) {
|
|
|
+ arr = res.data;
|
|
|
+ t = arr.length;
|
|
|
+ } else if (res.data && Array.isArray((res.data as any).rows)) {
|
|
|
+ arr = (res.data as any).rows;
|
|
|
+ t = (res.data as any).total || arr.length || 0;
|
|
|
+ }
|
|
|
+ tableData.value = arr;
|
|
|
+ total.value = t;
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('fetchData error:', error);
|
|
|
+ tableData.value = [];
|
|
|
+ total.value = 0;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function onTabChange() {
|
|
|
+ pageNum.value = 1;
|
|
|
+ fetchData();
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleSelectionChange(val: any[]) {
|
|
|
+ selectedLabels.value = val;
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleSizeChange(size: number) {
|
|
|
+ pageSize.value = size;
|
|
|
+ pageNum.value = 1;
|
|
|
+ fetchData();
|
|
|
+ }
|
|
|
+
|
|
|
+ function handlePageChange(page: number) {
|
|
|
+ pageNum.value = page;
|
|
|
+ fetchData();
|
|
|
+ }
|
|
|
+
|
|
|
+ function removeLabel(row: any) {
|
|
|
+ selectedLabels.value = selectedLabels.value.filter((l) => l.labelCode !== row.labelCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleConfirm() {
|
|
|
+ emit('confirm', selectedLabels.value);
|
|
|
+ visible.value = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleCancel() {
|
|
|
+ visible.value = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ function rowClassName({ rowIndex }: { rowIndex: number }) {
|
|
|
+ return rowIndex % 2 === 1 ? 'table-row-stripe' : '';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 初始化
|
|
|
+ fetchData();
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+ .disease-label-dialog {
|
|
|
+ --el-dialog-padding-primary: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialog-header-tabs {
|
|
|
+ padding: 0 32px 0 24px;
|
|
|
+ border-bottom: 1px solid #f0f0f0;
|
|
|
+ background: #fafbfc;
|
|
|
+ }
|
|
|
+
|
|
|
+ .custom-tabs {
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .custom-tabs .el-tabs__nav {
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .custom-tabs .el-tabs__item {
|
|
|
+ font-size: 16px;
|
|
|
+ padding: 0 32px;
|
|
|
+ height: 48px;
|
|
|
+ line-height: 48px;
|
|
|
+ color: #333;
|
|
|
+ border-radius: 6px 6px 0 0;
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .custom-tabs .el-tabs__item.is-active {
|
|
|
+ background: #fff;
|
|
|
+ color: #409eff;
|
|
|
+ border-bottom: 2px solid #409eff;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialog-body-flex {
|
|
|
+ display: flex;
|
|
|
+ padding: 24px 32px 0 24px;
|
|
|
+ min-height: 400px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .left-panel {
|
|
|
+ flex: 3;
|
|
|
+ margin-right: 16px;
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #f0f0f0;
|
|
|
+ border-radius: 6px;
|
|
|
+ padding: 16px 16px 0 16px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right-panel {
|
|
|
+ flex: 2;
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #f0f0f0;
|
|
|
+ border-radius: 6px;
|
|
|
+ padding: 16px 16px 0 16px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right-title {
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-bar {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-input {
|
|
|
+ width: 220px;
|
|
|
+ margin-right: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-btn {
|
|
|
+ margin-right: 8px;
|
|
|
+ background: #409eff;
|
|
|
+ color: #fff;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .add-btn {
|
|
|
+ background: #f5f7fa;
|
|
|
+ color: #409eff;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ }
|
|
|
+
|
|
|
+ .disease-table,
|
|
|
+ .selected-table {
|
|
|
+ margin-bottom: 0;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .disease-table .el-table__header th,
|
|
|
+ .selected-table .el-table__header th {
|
|
|
+ background: #f8f9fa;
|
|
|
+ color: #666;
|
|
|
+ font-weight: 500;
|
|
|
+ border-bottom: 1px solid #ebeef5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .disease-table .el-table__row.table-row-stripe {
|
|
|
+ background: #fafbfc;
|
|
|
+ }
|
|
|
+
|
|
|
+ .no-data {
|
|
|
+ text-align: center;
|
|
|
+ color: #bfbfbf;
|
|
|
+ font-size: 15px;
|
|
|
+ margin: 32px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .custom-pagination {
|
|
|
+ margin: 12px 0 0 0;
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialog-footer-btns {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ padding: 24px 0 16px 0;
|
|
|
+ background: #fafbfc;
|
|
|
+ border-top: 1px solid #f0f0f0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .confirm-btn {
|
|
|
+ min-width: 96px;
|
|
|
+ background: #409eff;
|
|
|
+ color: #fff;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-right: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cancel-btn {
|
|
|
+ min-width: 96px;
|
|
|
+ background: #fff;
|
|
|
+ color: #606266;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ }
|
|
|
+</style>
|