Browse Source

提交体检报告

master
肖正 3 months ago
parent
commit
1e6e7fd005
  1. 4
      .env.development
  2. 1
      .gitignore
  3. 2
      public/config.js
  4. 19
      src/api/api.ts
  5. BIN
      src/assets/customer/bladder_cancer.png
  6. BIN
      src/assets/customer/breast_cancer.png
  7. BIN
      src/assets/customer/cervical_carcinoma.png
  8. BIN
      src/assets/customer/colorectal_cancer.png
  9. BIN
      src/assets/customer/endometrial_cancer.png
  10. BIN
      src/assets/customer/esophageal_cancer.png
  11. BIN
      src/assets/customer/gastric_cancer.png
  12. BIN
      src/assets/customer/glioma.png
  13. BIN
      src/assets/customer/liver_cancer.png
  14. BIN
      src/assets/customer/lung_cancer.png
  15. BIN
      src/assets/customer/ovarian_cancer.png
  16. BIN
      src/assets/customer/pancreatic_cancer.png
  17. BIN
      src/assets/customer/prostatic_cancer.png
  18. BIN
      src/assets/customer/renal_carcinoma.png
  19. BIN
      src/assets/customer/thyroid_cancer.png
  20. BIN
      src/assets/customer/xiaozheng.png
  21. 2
      src/views/customer/edit.vue
  22. 267
      src/views/customer/editGenetic.vue
  23. 21
      src/views/customer/index.vue
  24. 174
      src/views/customer/info.vue
  25. 9
      src/views/health.vue
  26. 2
      src/views/home/index.vue
  27. 6
      src/views/login/component/account.vue
  28. 8
      src/views/login/index.vue

4
.env.development

@ -2,7 +2,7 @@
ENV = development ENV = development
# 本地环境接口地址 # 本地环境接口地址
VITE_API_URL = http://localhost:5005 # VITE_API_URL = http://localhost:5005
# VITE_API_URL = http://192.168.88.206:5005 # VITE_API_URL = http://192.168.88.206:5005
# VITE_API_URL = http://192.168.88.76:5005 # VITE_API_URL = http://192.168.88.76:5005
# VITE_API_URL = http://cloud.bodk.com.cn VITE_API_URL = http://cloud.bodk.com.cn

1
.gitignore

@ -6,6 +6,7 @@ node_modules
# local env files # local env files
.env.local .env.local
.env.*.local .env.*.local
dist.zip
# Log files # Log files
npm-debug.log* npm-debug.log*

2
public/config.js

@ -3,5 +3,5 @@ window.__env__ = {
"VITE_OPEN": "false", "VITE_OPEN": "false",
"VITE_OPEN_CDN": "false", "VITE_OPEN_CDN": "false",
"VITE_PUBLIC_PATH": "", "VITE_PUBLIC_PATH": "",
"VITE_API_URL": "http://localhost:5005" "VITE_API_URL": ""
} }

19
src/api/api.ts

@ -27,3 +27,22 @@ export function del(api, id) {
method: 'post', method: 'post',
}); });
} }
export function getTumor(code) {
return request({
url: `/api/tumor/tumor/${code}`,
method: 'get',
});
}
export function addGeneReport(data) {
return request({
url: `/api/geneReport/report`,
method: 'post',
data,
});
}
export function getGeneReport(customerId) {
return request({
url: `/api/geneReport/list/${customerId}`,
method: 'get',
});
}

BIN
src/assets/customer/bladder_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
src/assets/customer/breast_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
src/assets/customer/cervical_carcinoma.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
src/assets/customer/colorectal_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
src/assets/customer/endometrial_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
src/assets/customer/esophageal_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
src/assets/customer/gastric_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
src/assets/customer/glioma.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
src/assets/customer/liver_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
src/assets/customer/lung_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
src/assets/customer/ovarian_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
src/assets/customer/pancreatic_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
src/assets/customer/prostatic_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
src/assets/customer/renal_carcinoma.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
src/assets/customer/thyroid_cancer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
src/assets/customer/xiaozheng.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

2
src/views/customer/edit.vue

@ -103,6 +103,7 @@ const state = reactive({
// //
const openDialog = (row: any) => { const openDialog = (row: any) => {
state.ruleForm = JSON.parse(JSON.stringify(row)); state.ruleForm = JSON.parse(JSON.stringify(row));
fileList.value = [];
state.isShowDialog = true; state.isShowDialog = true;
ruleFormRef.value?.resetFields(); ruleFormRef.value?.resetFields();
}; };
@ -122,6 +123,7 @@ const closeDialog = () => {
const handleAvatarSuccess: UploadProps['onSuccess'] = ( const handleAvatarSuccess: UploadProps['onSuccess'] = (
response response
) => { ) => {
// console.log(888, response);
state.ruleForm.imageUrl = response?.result?.url; state.ruleForm.imageUrl = response?.result?.url;
} }
// //

267
src/views/customer/editGenetic.vue

@ -0,0 +1,267 @@
<template>
<div class="sys-menu-container">
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="900px">
<template #header>
<div style="color: #fff">
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
<span> {{ props.title }} </span>
</div>
</template>
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
<el-row :gutter="5">
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="检测码" prop="barcode" :rules="[{ required: true, message: '检测码不能为空', trigger: 'blur' }]">
<el-input v-model="state.ruleForm.barcode" placeholder="检测码" clearable />
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="样本类型" prop="sampleType" :rules="[{ required: true, message: '样本类型不能为空', trigger: 'blur' }]">
<el-input v-model="state.ruleForm.sampleType" placeholder="样本类型" clearable />
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="检测项目" prop="testingType" :rules="[{ required: true, message: '检测项目不能为空', trigger: 'blur' }]">
<el-input v-model="state.ruleForm.testingType" placeholder="检测项目" clearable />
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="检测技术" prop="testingMethod" :rules="[{ required: true, message: '检测技术不能为空', trigger: 'blur' }]">
<el-input v-model="state.ruleForm.testingMethod" placeholder="检测技术" clearable />
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="送检日期" prop="submissionTime" :rules="[{ required: true, message: '送检日期不能为空', trigger: 'blur' }]">
<el-date-picker
v-model="state.ruleForm.submissionTime"
type="date"
/>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="报告日期" prop="reportTime" :rules="[{ required: true, message: '报告日期不能为空', trigger: 'blur' }]">
<el-date-picker
v-model="state.ruleForm.reportTime"
type="date"
/>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="样本采集">
<el-radio-group v-model="state.ruleForm.sampleQuality">
<el-radio :value="true">合格</el-radio>
<el-radio :value="false">不合格</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="DNA 抽提">
<el-radio-group v-model="state.ruleForm.dnaExtraction">
<el-radio :value="true">合格</el-radio>
<el-radio :value="false">不合格</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="PCR">
<el-radio-group v-model="state.ruleForm.pcr">
<el-radio :value="true">合格</el-radio>
<el-radio :value="false">不合格</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="飞行时间质谱">
<el-radio-group v-model="state.ruleForm.tofMs">
<el-radio :value="true">合格</el-radio>
<el-radio :value="false">不合格</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="基因分型分析">
<el-radio-group v-model="state.ruleForm.genotypingAnalysis">
<el-radio :value="true">合格</el-radio>
<el-radio :value="false">不合格</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="评估遗传风险">
<el-radio-group v-model="state.ruleForm.geneticRiskAssessment">
<el-radio :value="true">合格</el-radio>
<el-radio :value="false">不合格</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20" style="margin-bottom:0 !important">
<el-form-item label="基因检测报告">
<el-radio-group v-model="state.ruleForm.report">
<el-radio :value="true">合格</el-radio>
<el-radio :value="false">不合格</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="35" v-for="(item, i) in state.ruleForm.tumors" :key="i">
<el-divider border-style="dashed" content-position="center">
<!-- <div style="color: #b1b3b8">类型{{ i }}</div> -->
</el-divider>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="检测类型" :prop="'tumors.'+i+'.tumorId'" :rules="[{ required: true, message: '检测类型不能为空', trigger: 'blur' }]">
<el-select v-model="item.code" placeholder="检测类型" collapse-tags collapse-tags-tooltip class="w100" @change="cancerChange(i)">
<el-option v-for="cancer in state.cancerList" :key="cancer.id" :label="cancer.value" :value="cancer.code" />
</el-select>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20">
<el-form-item label="遗传风险值" :prop="'tumors.'+i+'.riskScore'" :rules="[{ required: true, message: '遗传风险值不能为空', trigger: 'blur' }]">
<el-input-number v-model="item.riskScore" placeholder="遗传风险值" class="w100" clearable />
</el-form-item>
</el-col>
<el-col :xs="12" :sm="8" :md="8" :lg="8" :xl="8" class="mb20" v-for="lo in item.loci" :key="lo.value">
<el-form-item :label="lo.label">
<el-select v-model="lo.riskId" :placeholder="lo.label" collapse-tags collapse-tags-tooltip class="w100">
<el-option v-for="cld in lo.children" :key="cld.id" :label="cld.label" :value="cld.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<div><el-button type="primary" @click="state.ruleForm.tumors.push({})">新增检测类型</el-button></div>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="cancel"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="editGenetic">
import { onMounted, reactive, ref } from 'vue';
import { addGeneReport, getTumor } from '/@/api/api';
// import { Plus } from '@element-plus/icons-vue'
import { Local } from '/@/utils/storage';
import { getAPI } from '/@/utils/axios-utils';
import { SysDictDataApi } from '/@/api-services/api';
// import { fa } from 'element-plus/es/locale';
const props = defineProps({
title: String,
});
const emits = defineEmits(['handleQuery']);
const ruleFormRef = ref();
const state = reactive({
isShowDialog: false,
dialogUploadVisible: false,
ruleForm: {
tumors: []
} as any,
tumorObj: {},
cancerList: [],
token: Local.get('access-token')
});
onMounted(async ()=>{
let resDicData = await getAPI(SysDictDataApi).apiSysDictDataDataListCodeGet('cancer');
state.cancerList = resDicData.data.result;
})
//
const openDialog = (row: any) => {
// state.ruleForm = JSON.parse(JSON.stringify(row));
state.ruleForm = {
customerId: row.id,
testingMethod: '飞行时间质谱',
sampleType: '口腔黏膜细胞',
testingType: (row.isMale?'女':'男') + '性肿瘤十项',
sampleQuality: true,
dnaExtraction: true,
pcr: true,
tofMs: true,
genotypingAnalysis: true,
geneticRiskAssessment: true,
report: true,
tumors: [{}]
};
state.ruleForm.customerId = row.id;
state.isShowDialog = true;
ruleFormRef.value?.resetFields();
};
//
const closeDialog = () => {
emits('handleQuery');
state.isShowDialog = false;
};
//
const cancel = () => {
state.isShowDialog = false;
};
const cancerChange = async (i) => {
let item = state.ruleForm.tumors[i]
item.loci = [];
let res = await getTumor(item.code)
item.tumorId = res.data?.result?.id;
res.data?.result?.geneLoci.map(g => {
let types = [];
g.types.map(type => {
types.push({
label: type.genekType,
value: type.id,
})
});
item.loci.push({
label: g.name+'-'+g.position,
locusId: g.id,
children: types
})
});
console.log(999, state.ruleForm);
// state.tumorObj[val] = res.data?.result?.geneLoci || null;
};
const getRiskLevel = (item) => {
let averageRiskScore = state.cancerList.find(_ => _.code == item.code);
// item.averageRiskScore = averageRiskScore?.extData - 0;
const val = item.riskScore/averageRiskScore?.extData;
if (val >= 5) {
return 7
} else if (val>=2) {
return 6
} else if (val>=1.1){
return 5
} else if (val >=0.9) {
return 4
} else if (val >= 0.5) {
return 3
} else if (val >= 0.2) {
return 2
} else {
return 1
}
}
//
const submit = () => {
ruleFormRef.value.validate(async (valid: boolean) => {
if (!valid) return;
state.ruleForm.tumors.map(item => {
item.riskLevel = getRiskLevel(item);
})
await addGeneReport(state.ruleForm);
closeDialog();
});
};
//
defineExpose({ openDialog });
</script>
<style scoped>
.avatar-uploader .avatar {
width: 178px;
height: 178px;
display: block;
}
</style>

21
src/views/customer/index.vue

@ -15,7 +15,7 @@
</el-button-group> </el-button-group>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="ele-Plus" @click="openAddMenu" v-auth="'sysMenu:add'"> 新增 </el-button> <el-button type="primary" icon="ele-Plus" @click="openAddMenu" v-auth="'customer:add'"> 新增 </el-button>
<!-- <el-button type="primary" icon="ele-Plus" @click="openInfo({})" v-auth="'sysMenu:add'"> 新增 </el-button> --> <!-- <el-button type="primary" icon="ele-Plus" @click="openInfo({})" v-auth="'sysMenu:add'"> 新增 </el-button> -->
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -38,7 +38,7 @@
<el-tag type="primary" v-else></el-tag> <el-tag type="primary" v-else></el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="修改记录" width="200" align="center" show-overflow-tooltip> <el-table-column label="修改记录" width="120" align="center" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
<el-popover placement="bottom" width="280" trigger="hover"> <el-popover placement="bottom" width="280" trigger="hover">
<template #reference> <template #reference>
@ -91,11 +91,12 @@
</el-popover> </el-popover>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="200" fixed="right" align="center" show-overflow-tooltip> <el-table-column label="操作" width="300" fixed="right" align="center" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
<el-button icon="ele-Edit" size="small" text type="primary" @click="openInfo(scope.row)" v-auth="'sysMenu:update'"> 详情 </el-button> <el-button icon="ele-Edit" size="small" text type="primary" @click="openGenetic(scope.row)"> 新增报告 </el-button>
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditMenu(scope.row)" v-auth="'sysMenu:update'"> 编辑 </el-button> <el-button icon="ele-Edit" size="small" text type="primary" @click="openInfo(scope.row)"> 详情 </el-button>
<el-button icon="ele-Delete" size="small" text type="danger" @click="delMenu(scope.row)" v-auth="'sysMenu:delete'"> 删除 </el-button> <el-button icon="ele-Edit" size="small" text type="primary" @click="openEditMenu(scope.row)" v-auth="'customer:update'"> 编辑 </el-button>
<el-button icon="ele-Delete" size="small" text type="danger" @click="delMenu(scope.row)" v-auth="'customer:delete'"> 删除 </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -113,12 +114,14 @@
</el-card> </el-card>
<EditCustomer ref="editRef" :title="state.editTitle" @handleQuery="handleQuery" /> <EditCustomer ref="editRef" :title="state.editTitle" @handleQuery="handleQuery" />
<CustomerInfo ref="infoRef" :title="state.infoTitle" @handleQuery="handleQuery" /> <CustomerInfo ref="infoRef" :title="state.infoTitle" @handleQuery="handleQuery" />
<EditGenetic ref="geneticRef" :title="state.infoTitle" @handleQuery="handleQuery" />
</div> </div>
</template> </template>
<script lang="ts" setup name="customer" > <script lang="ts" setup name="customer" >
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus'; import { ElMessageBox, ElMessage } from 'element-plus';
import EditGenetic from './editGenetic.vue';
import EditCustomer from './edit.vue'; import EditCustomer from './edit.vue';
import CustomerInfo from './info.vue'; import CustomerInfo from './info.vue';
import { SysMenu } from '/@/api-services/models'; import { SysMenu } from '/@/api-services/models';
@ -130,6 +133,7 @@ const { themeConfig } = storeToRefs(storesThemeConfig);
const editRef = ref(); const editRef = ref();
const infoRef = ref(); const infoRef = ref();
const geneticRef = ref();
const state = reactive({ const state = reactive({
loading: false, loading: false,
tableData: [] as Array<SysMenu>, tableData: [] as Array<SysMenu>,
@ -147,7 +151,6 @@ const state = reactive({
}); });
onMounted(async () => { onMounted(async () => {
console.log(888, themeConfig.value.isIsDark)
themeConfig.value.isIsDark = false; themeConfig.value.isIsDark = false;
handleQuery(); handleQuery();
}); });
@ -184,6 +187,10 @@ const openInfo = (row: any) => {
state.infoTitle = `${row.name} 的数字生命`; state.infoTitle = `${row.name} 的数字生命`;
infoRef.value?.openDrawer(row); infoRef.value?.openDrawer(row);
}; };
const openGenetic = (row: any) => {
state.infoTitle = `新增${row.name} 的体检报告`;
geneticRef.value?.openDialog(row);
};
// //
const delMenu = (row: any) => { const delMenu = (row: any) => {

174
src/views/customer/info.vue

@ -1,6 +1,7 @@
<template> <template>
<el-drawer v-model="drawer" :direction="direction" class="cursor-info" size="100%"> <el-drawer v-model="drawer" :direction="direction" class="cursor-info" size="100%">
<template #default> <template #default>
<div id="orido_tm_hero" style="height: 100vh;overflow-y: auto;" v-if="drawer">
<div class="orido_tm_hero"> <div class="orido_tm_hero">
<div class="close-box" @click="closeDrawer"> <div class="close-box" @click="closeDrawer">
<el-icon class="info-close"><CloseBold /></el-icon> <el-icon class="info-close"><CloseBold /></el-icon>
@ -11,46 +12,56 @@
<span class="badge">Hot</span> <span class="badge">Hot</span>
<span class="content">生命数据库</span> <span class="content">生命数据库</span>
</div> </div>
<h1 class="heading">肖正的生命数据库</h1> <h1 class="heading">{{state.ruleForm.name}}的生命数据库</h1>
<p class="pera-title">Obviously I'm a Web Designer. Web Developer with over 3 years of experience. Experienced with all stages of the development</p> <p class="pera-title">Obviously I'm a Web Designer. Web Developer with over 3 years of experience. Experienced with all stages of the development</p>
<div class="hero-btn"> <div class="hero-btn">
<el-button type="primary" size="default">体检报告</el-button> <el-button type="primary" size="default" @click="scrollTo('medical-report')">体检报告</el-button>
<el-button size="default">细胞储存信息</el-button> <el-button size="default" @click="scrollTo('cell-message')">细胞储存信息</el-button>
</div> </div>
</div> </div>
<img src="/@/assets/customer/xiaozheng.png" class="author" alt=""> <img :src="state.ruleForm.imageUrl" class="author" alt="">
<div class="video_button"> <div class="video_button">
<a class="popup-youtube" href="https://www.youtube.com/watch?v=7e90gBu4pas"> <a class="popup-youtube" @click="audioClick">
<img class="anim_circle" src="/@/assets/customer/welcome.png" alt=""> <img class="anim_circle" src="/@/assets/customer/welcome.png" alt="">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="25" viewBox="0 0 20 25" fill="none" class="svg replaced-svg"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="25" viewBox="0 0 20 25" fill="none" class="svg replaced-svg">
<path d="M0.693848 0.149658V24.7257L19.3059 12.4377L0.693848 0.149658Z" fill="white"></path> <path d="M0.693848 0.149658V24.7257L19.3059 12.4377L0.693848 0.149658Z" fill="white"></path>
</svg> </svg>
<audio :src="state.ruleForm.voiceUrl" ref="audioRef"></audio>
</a> </a>
</div> </div>
</div> </div>
</div> </div>
<div class="section bg-light"> <div class="section bg-light" id="medical-report">
<div class="container"> <div class="container">
<el-carousel :interval="5000" indicator-position="outside" height="auto">
<el-carousel-item v-for="(item,index) in state.geneticList" :key="index"
:style="{height: (Math.ceil(item.tumors.length/3)*255 + 190)+'px'}">
<div class="container-title"> <div class="container-title">
<h2>体检报告</h2> <h2>体检报告</h2>
<p class="pera-title">体检时间2024-07-31体检机构东莞松山湖基地</p> <p class="pera-title">体检时间{{item?.submissionTime.split(' ')[0]}}报告时间{{item.reportTime.split(' ')[0]}}
样本类型{{item.sampleType}}检测项目{{item.testingType}}检测技术{{item.testingMethod}}</p>
</div> </div>
<div class="content-box"> <div class="content-box">
<div class="content-item" v-for="(item, i) in 6" :key="i"> <div class="content-item" v-for="(tumor, i) in item.tumors" :key="i" @click="tumorShow(tumor)">
<div class="feature-widget"> <div class="feature-widget">
<div style="margin-bottom: 16px;"> <div style="margin-bottom: 16px;">
<el-icon size="38" class="info-icon"><House /></el-icon> <!-- <el-icon size="38" class="info-icon"><House /></el-icon> -->
<img :src="'/@/assets/customer/'+tumor.code+'.png'" alt="" style="width: 38px">
</div> </div>
<h3>肝癌</h3> <h3>{{tumor.tumorName}}</h3>
<p class="text-light-muted">中国人群肝癌平均遗传风险为 22.2您的遗传风险值为 10 是平均遗传风险的0.45 处于较低风险2 </p> <p class="text-light-muted after">中国人群{{ tumor.tumorName }}平均遗传风险为 <span class="risk-score">{{tumor.avaRiskScore}}</span>;</p>
<p>遗传相对风险指数<span>0.8</span></p> <p class="text-light-muted after">您的遗传风险值为 <span class="risk-score">{{ tumor.riskScore }}</span>
<p>遗传相对风险等级<span>略低</span></p> 是平均遗传风险的<span class="risk-score">{{ (tumor.riskScore/tumor.avaRiskScore).toFixed(2) }}</span>
处于<span class="risk-score" :style="tumor.riskScore/tumor.avaRiskScore>=1.1?'color:red':''"
>{{ getRiskLevel(tumor) }} </span>风险<span class="risk-score">{{ tumor.riskLevel }} </span> </p>
</div> </div>
</div> </div>
</div> </div>
</el-carousel-item>
</el-carousel>
</div> </div>
</div> </div>
<div class="device-box"> <div class="device-box" id="cell-message">
<div class="container"> <div class="container">
<el-carousel :interval="5000" height="600px" @change="changeImg" indicator-position="outside"> <el-carousel :interval="5000" height="600px" @change="changeImg" indicator-position="outside">
<el-carousel-item v-for="(item,index) in state.images" :key="index"> <el-carousel-item v-for="(item,index) in state.images" :key="index">
@ -59,7 +70,7 @@
<el-image <el-image
style="height:60%; margin-top: 30%" style="height:60%; margin-top: 30%"
:src="item.idView" :src="item.idView"
fit="fit"></el-image> fit="contain"></el-image>
<div class="cold-storage-content-tips" style="top: 210px; left: 0;"> <div class="cold-storage-content-tips" style="top: 210px; left: 0;">
<span class="cold-storage-content-tips-text">密封腔湿度{{ m9Msg.humidity }}</span> <span class="cold-storage-content-tips-text">密封腔湿度{{ m9Msg.humidity }}</span>
<span class="cold-storage-content-tips-line blue" style="width: 20px;"></span> <span class="cold-storage-content-tips-line blue" style="width: 20px;"></span>
@ -84,9 +95,16 @@
<span class="cold-storage-content-tips-line blue"></span> <span class="cold-storage-content-tips-line blue"></span>
<span class="cold-storage-content-tips-text">{{m9Msg.bottom}}</span> <span class="cold-storage-content-tips-text">{{m9Msg.bottom}}</span>
</div> </div>
<div> <div style="margin: 0 20px;">
<span>液氮高度{{ item.height }} mm</span> <el-progress
<span style="margin-left: 60px;" class="">转运区<span :style="{color: item.status === 0?'red':'green'}">{{item.status === 0?'无桶':'有桶'}}</span></span> :text-inside="true"
striped
:stroke-width="20"
:percentage="25.6"
/>
<div style="margin: 10px 20px 0; text-align: left;">
细胞储存信息<span style="float: right;">256/1000</span>
</div>
</div> </div>
</el-col> </el-col>
<el-col :span="15" class="cta-full-img-box"> <el-col :span="15" class="cta-full-img-box">
@ -105,6 +123,7 @@
</el-carousel> </el-carousel>
</div> </div>
</div> </div>
</div>
</template> </template>
<!-- <template #footer> <!-- <template #footer>
<div style="flex: auto"> <div style="flex: auto">
@ -113,16 +132,27 @@
</div> </div>
</template> --> </template> -->
</el-drawer> </el-drawer>
<el-dialog v-model="dialogTableVisible" :title="state.lociObj.tumorName" width="900" class="info-dialog">
<p class="pera-title">{{state.lociObj.description}}</p>
<el-table :data="state.lociObj?.loci">
<el-table-column align="center" property="locusName" label="基因" width="100" />
<el-table-column align="center" property="position" label="位点" width="100" />
<el-table-column align="center" label="正常/风险" width="100">
<template #default="scope">
<div :style="scope.row.risk?'color: red':''">{{scope.row.genekType+'('+(scope.row.risk?'风险':'正常')+')'}}</div>
</template>
</el-table-column>
<el-table-column align="center" property="description" label="基因功能/风险型描述" />
</el-table>
</el-dialog>
</template> </template>
<script lang="ts" setup name="customerInfo"> <script lang="ts" setup name="customerInfo">
import { ref, reactive, computed } from 'vue' import { ref, reactive, computed } from 'vue'
import { ElMessageBox, } from 'element-plus' // import { ElMessageBox, } from 'element-plus'
import { House, CloseBold } from '@element-plus/icons-vue' import { CloseBold } from '@element-plus/icons-vue'
import type { DrawerProps } from 'element-plus' import type { DrawerProps } from 'element-plus'
import { getGeneReport } from '/@/api/api';
import imgUrl from '/@/assets/M9.png' import imgUrl from '/@/assets/M9.png'
const props = defineProps({
title: String,
});
const tableData = [ const tableData = [
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'}, {type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'}, {type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
@ -133,14 +163,18 @@ const tableData = [
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'}, {type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'}, {type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
]; ];
const dialogTableVisible = ref(false)
const drawer = ref(false) const drawer = ref(false)
const audioRef = ref(null)
const direction = ref<DrawerProps['direction']>('rtl') const direction = ref<DrawerProps['direction']>('rtl')
const radio1 = ref('Option 1')
const emits = defineEmits(['handleQuery']);
let random = ref(0); let random = ref(0);
const state = reactive({ const state = reactive({
ruleForm: {} as any, ruleForm: {} as any,
className: "", className: "",
geneticList: [],
lociObj: {} as any,
audioPlay: false,
geneticHeight: 100,
images: [ images: [
{id: 0, idView: imgUrl, top: '-180.1℃', center: '-192.2℃', bottom: '-195.1℃', shi: '1%',height: 162, status: 0}, {id: 0, idView: imgUrl, top: '-180.1℃', center: '-192.2℃', bottom: '-195.1℃', shi: '1%',height: 162, status: 0},
{id: 1, idView: imgUrl, top: '-181.6℃', center: '-190.6℃', bottom: '-195.3℃', shi: '1.3%',height: 166, status: 1}, {id: 1, idView: imgUrl, top: '-181.6℃', center: '-190.6℃', bottom: '-195.3℃', shi: '1.3%',height: 166, status: 1},
@ -150,6 +184,22 @@ const state = reactive({
{id: 5, idView: imgUrl, top: '-182.2℃', center: '-192.9℃', bottom: '-195.4℃', shi: '2.3%',height: 169, status: 0}, {id: 5, idView: imgUrl, top: '-182.2℃', center: '-192.9℃', bottom: '-195.4℃', shi: '2.3%',height: 169, status: 0},
], ],
}); });
const audioClick = () => {
if (state.audioPlay)
audioRef.value.pause();
else
audioRef.value.play();
}
const tumorShow = (item) => {
// state.lociData = item.loci || [];
state.lociObj = item
dialogTableVisible.value = true;
}
const scrollTo = (id) => {
let box = document.getElementById('orido_tm_hero');
let dom = document.getElementById(id);
box.scrollBy({ top: dom.offsetTop, behavior: "smooth" });
}
const m9Msg = computed(() => { const m9Msg = computed(() => {
return { return {
humidity: (random.value + 10).toFixed(1), humidity: (random.value + 10).toFixed(1),
@ -159,15 +209,18 @@ const m9Msg = computed(() => {
}; };
}); });
// //
const openDrawer = (row: any) => { const openDrawer = async (row: any) => {
state.ruleForm = JSON.parse(JSON.stringify(row)); state.ruleForm = JSON.parse(JSON.stringify(row));
state.geneticList = [];
drawer.value = true; drawer.value = true;
// ruleFormRef.value?.resetFields(); let res = await getGeneReport(row.id);
state.geneticList = res.data?.result || [];
}; };
// //
const closeDrawer = () => { const closeDrawer = () => {
// emits('handleQuery'); // emits('handleQuery');
audioRef.value.pause();
drawer.value = false; drawer.value = false;
}; };
const changeImg = () => { const changeImg = () => {
@ -176,19 +229,35 @@ const changeImg = () => {
state.className = "lun-img"; state.className = "lun-img";
}, 300); }, 300);
} }
// const getRiskLevel = (item) => {
const cancel = () => { const val = item.riskScore/item.avaRiskScore;
drawer.value = false; if (val >= 5) {
return '高'
} else if (val>=2) {
return '较高'
} else if (val>=1.1){
return '略高'
} else if (val >=0.9) {
return '平均'
} else if (val >= 0.5) {
return '略低'
} else if (val >= 0.2) {
return '较低'
} else {
return '低'
}
}; };
function confirmClick() { // const tagClose=(i)=>{
ElMessageBox.confirm(`Are you confirm to chose ${radio1.value} ?`) // ElMessageBox.confirm(` ${state.geneticList[i].barcode} ?`)
.then(() => { // .then(async () => {
drawer.value = false // let res = await del('genetic', state.geneticList[i].id);
}) // console.log(999, res)
.catch(() => { // state.geneticList.splice(i, 1);
// catch error // })
}) // .catch(() => {
} // // catch error
// })
// }
// //
defineExpose({ openDrawer }); defineExpose({ openDrawer });
</script> </script>
@ -199,8 +268,14 @@ defineExpose({ openDrawer });
.cursor-info .el-drawer__body { .cursor-info .el-drawer__body {
background: #f8f9fa; background: #f8f9fa;
} }
.info-dialog .el-dialog__title {
color: #fff;
}
</style> </style>
<style scoped lang="scss"> <style scoped lang="scss">
.risk-score {
color: var(--el-color-primary);
}
.orido_tm_hero { .orido_tm_hero {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
@ -321,8 +396,9 @@ defineExpose({ openDrawer });
padding: .5rem 0.75rem 0; padding: .5rem 0.75rem 0;
margin-top: 1.5rem; margin-top: 1.5rem;
width: 33%; width: 33%;
cursor: pointer;
.feature-widget { .feature-widget {
padding: 30px 45px; padding: 30px 35px;
background-color: #fff; background-color: #fff;
box-shadow: -0.0625rem 0 .625rem 0 rgba(0, 0, 0, 0.07), 0.3125rem 1.25rem 2.5rem 0 rgba(0, 0, 0, 0.04); box-shadow: -0.0625rem 0 .625rem 0 rgba(0, 0, 0, 0.07), 0.3125rem 1.25rem 2.5rem 0 rgba(0, 0, 0, 0.04);
border-radius: 10px; border-radius: 10px;
@ -339,8 +415,22 @@ defineExpose({ openDrawer });
} }
} }
} }
$color: rgb(211, 130, 50);
.text-light-muted { .text-light-muted {
color: #8492a6; color: #8492a6;
position: relative;
padding-left: 15px;
&.after::after {
display: block;
content: '';
position: absolute;
left: 0;
top: 8px;
width: 10px;
height: 10px;
border-radius: 50%;
background: $color;
}
} }
.container-title { .container-title {
text-align: center; text-align: center;
@ -367,6 +457,10 @@ defineExpose({ openDrawer });
height: 100%; height: 100%;
position: relative; position: relative;
} }
.popup-youtube{
cursor: pointer;
display: inline-block;
}
.device-box { .device-box {
background: #fff; background: #fff;
.lun-img { .lun-img {

9
src/views/health.vue

@ -11,7 +11,14 @@
<img class="line3" src="/@/assets/home/lines3.png"> <img class="line3" src="/@/assets/home/lines3.png">
</div> </div>
<div id='mapDom' @click="dialogShow"> <div id='mapDom' @click="dialogShow">
<el-image width="100%" src="/@/assets/M9_01.png" alt="" /> <el-carousel :interval="5000" :height="(height-120)+'px'" arrow="never">
<el-carousel-item>
<img width="100%" src="/@/assets/M9_01.png" alt="" />
</el-carousel-item>
<el-carousel-item>
<img width="100%" src="/@/assets/M9.png" alt="" />
</el-carousel-item>
</el-carousel>
</div> </div>
</el-col> </el-col>
<el-col :span="8" class="right-area"> <el-col :span="8" class="right-area">

2
src/views/home/index.vue

@ -63,7 +63,7 @@
<el-image <el-image
style="height:90%" style="height:90%"
:src="item.idView" :src="item.idView"
fit="fit"></el-image> fit="contain"></el-image>
<div class="cold-storage-content-tips" style="top: 110px; left: -15%;"> <div class="cold-storage-content-tips" style="top: 110px; left: -15%;">
<span class="cold-storage-content-tips-text">密封腔湿度{{ m9Msg.humidity }}</span> <span class="cold-storage-content-tips-text">密封腔湿度{{ m9Msg.humidity }}</span>
<span class="cold-storage-content-tips-line blue" style="width: 50px;"></span> <span class="cold-storage-content-tips-line blue" style="width: 50px;"></span>

6
src/views/login/component/account.vue

@ -103,8 +103,10 @@ const dragRef: any = ref(null);
const state = reactive({ const state = reactive({
isShowPassword: false, isShowPassword: false,
ruleForm: { ruleForm: {
account: 'superadmin', account: '',
password: '123456', password: '',
// account: 'superadmin',
// password: '123456',
code: '', code: '',
codeId: 0, codeId: 0,
}, },

8
src/views/login/index.vue

@ -32,16 +32,16 @@
<el-tab-pane :label="$t('message.label.one1')" name="account"> <el-tab-pane :label="$t('message.label.one1')" name="account">
<Account /> <Account />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('message.label.two2')" name="mobile"> <!-- <el-tab-pane :label="$t('message.label.two2')" name="mobile">
<Mobile /> <Mobile />
</el-tab-pane> </el-tab-pane> -->
</el-tabs> </el-tabs>
</div> </div>
<Scan v-if="state.isScan" /> <Scan v-if="state.isScan" />
<div class="login-content-main-scan" @click="state.isScan = !state.isScan"> <!-- <div class="login-content-main-scan" @click="state.isScan = !state.isScan">
<i class="iconfont" :class="state.isScan ? 'icon-diannao1' : 'icon-barcode-qr'"></i> <i class="iconfont" :class="state.isScan ? 'icon-diannao1' : 'icon-barcode-qr'"></i>
<div class="login-content-main-scan-delta"></div> <div class="login-content-main-scan-delta"></div>
</div> </div> -->
</div> </div>
</div> </div>
</div> </div>

Loading…
Cancel
Save