aBin 4 years ago
parent
commit
561daf0ea4
  1. 16268
      package-lock.json
  2. 98
      src/components/BiologicalSampleSearch/SampleTable.vue
  3. 116
      src/components/BiologicalSampleSearch/Search.vue
  4. 4
      src/components/BtnCom/BtnCon.vue
  5. 3
      src/components/QuillEditor/QuillEditor.vue
  6. 4
      src/config/api.js
  7. 24
      src/router/index.js
  8. 68
      src/views/BiologicalSampleSearch/BiologicalSampleSearch.vue
  9. 146
      src/views/BiologicalSamples/BiologicalSamples.vue
  10. 53
      src/views/Meeting/Meeting.vue
  11. 16
      src/views/MessagePush/MessagePush.vue
  12. 45
      src/views/PersonalStats/PersonalStats.vue

16268
package-lock.json

File diff suppressed because it is too large

98
src/components/BiologicalSampleSearch/SampleTable.vue

@ -0,0 +1,98 @@
<template>
<div>
<!-- search -->
<div style="width:100%" v-if="lists && lists.list && lists.list.length > 0">
<a-table
:columns="columns"
:data-source="lists.list"
:loading="loading"
:pagination="pagination"
:row-key="record => record.id"
@change="handleTableChange"
bordered
class="white pa-3"
>
<template slot="id" slot-scope="text, record, index">
<span>{{ index + 1 }}</span>
</template>
</a-table>
</div>
<a-empty v-else />
</div>
</template>
<script>
import { mapMutations, mapState } from 'vuex';
const columns = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
scopedSlots: { customRender: 'id' },
},
{
title: '医院',
align: 'center',
dataIndex: 'hospital',
key: 'hospital',
},
{
title: '住院号',
align: 'center',
dataIndex: 'hospitalization',
key: 'hospitalization',
},
{
title: '类型',
align: 'center',
dataIndex: 'type',
key: 'type',
},
{
title: '采集时间',
align: 'center',
dataIndex: 'acquisitionTime',
key: 'acquisitionTime',
},
];
export default {
name: 'PatientTable',
props: { lists: { type: Object, default: null } },
data() {
return {
columns,
loading: false,
};
},
computed: {
pagination() {
const { pageNum, pageSize, total } = this.lists;
return {
current: pageNum,
pageSize,
total: +total,
};
},
},
methods: {
...mapMutations('home', ['setPatientId']),
//
chooseItem(id) {
this.setPatientId(id);
},
handleTableChange(pagination) {
const { current } = pagination;
this.$emit('handleSelPatientMes', current);
},
},
};
</script>

116
src/components/BiologicalSampleSearch/Search.vue

@ -0,0 +1,116 @@
<template>
<!-- search -->
<div>
<div class="d-flex flex-row flex-nowrap">
<a-form
:form="form"
@submit="handleSubmit"
class="d-flex flex-nowrap align-center"
layout="inline"
>
<a-form-item>
<a-select placeholder="请选择医院" style="min-width: 150px" v-decorator="['hospital']">
<a-select-option
:key="item.id"
:value="item.id"
v-for="item in hospitals"
>{{ item.title }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-select placeholder="请选择样本类型" style="min-width: 150px" v-decorator="['sampleType']">
<a-select-option :key="item.id" :value="item.id" v-for="item in types">{{ item.title }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-input placeholder="患者住院号" style="width: 14em" v-decorator="['inpatientNumber']" />
</a-form-item>
<a-form-item>
<a-select
placeholder="请选择采集时间"
style="min-width: 150px"
v-decorator="['acquisitionTime']"
>
<a-select-option :key="t.id" :value="t.id" v-for="t in acquisitionTime">{{ t.title }}</a-select-option>
</a-select>
</a-form-item>
<a-button class="mr-4" html-type="submit" icon="search" type="primary">搜索</a-button>
</a-form>
<div class="flex-1"></div>
</div>
</div>
</template>
<script>
export default {
name: 'Search',
data() {
return {
form: this.$form.createForm(this, { name: 'search' }),
hospitals: [
{
id: 1,
title: '山西中医大学附属医院',
},
{
id: 2,
title: '山西人民医院',
},
{
id: 3,
title: '大同第五人民医院',
},
{
id: 4,
title: '大同国药同煤总医院',
},
],
types: [
{
id: 1,
title: '抗血凝10ml',
},
{
id: 2,
title: '促凝血5ml',
},
{
id: 3,
title: '晨尿10ml',
},
{
id: 4,
title: '24小时尿10ml',
},
],
acquisitionTime: [
{
id: 1,
title: '0天',
},
{
id: 2,
title: '14天',
},
{
id: 3,
title: '90天',
},
],
};
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFields(async (err, values) => {
if (!err) {
console.log('values: ', values);
this.$emit('searchPatientMes', values);
}
});
},
},
};
</script>

4
src/components/BtnCom/BtnCon.vue

@ -6,6 +6,10 @@
<div @click="jump('/patientInfo')" class="btn">患者信息录入</div>
<div @click="jump('/caseSearch')" class="btn">病例搜索</div>
<div @click="jump('/caseAnalysis')" class="btn">病例分析</div>
<div @click="jump('/biologicalSamples')" class="btn">生物样本</div>
<div @click="jump('/biologicalSampleSearch')" class="btn">生物样本搜索</div>
<div @click="jump('/messagePush')" class="btn">消息推送</div>
<div @click="jump('/personalStats')" class="btn">个人数据统计</div>
</div>
</template>

3
src/components/QuillEditor/QuillEditor.vue

@ -114,7 +114,8 @@ export default {
<style>
.ql-container {
overflow: auto;
max-height: 200px;
min-height: 150px;
max-height: 300px;
}
.ql-toolbar.ql-snow {
background: #f5f5f5;

4
src/config/api.js

@ -13,6 +13,7 @@ const patient = `${tcm}/patient`; // 患者相关接口
const imp = `${tcm}/import`; // 试题相关接口
const inpatient = `${tcm}/inpatient`; // 对照组接口
const statistics = `${tcm}/statistics`; // 数据统计相关接口
const conferenceRecords = `${tcm}/conferenceRecords`; // 会议纪要相关接口
// 保存患者病例信息
export const saveCaseMes = params => axios.post(`${patient}/saveCaseMes`, params);
@ -42,3 +43,6 @@ export const countAnalysis = params => axios.post(`${statistics}/countAnalysis`,
// 查询每日病例统计
export const countCase = params => axios.post(`${statistics}/countCase`, params);
// 添加会议记录
export const saveConferenceRecords = params => axios.post(`${conferenceRecords}/save`, params);

24
src/router/index.js

@ -54,6 +54,30 @@ const routes = [
name: 'CaseAnalysis',
component: () => import('@/views/CaseAnalysis/CaseAnalysis.vue'),
},
// 生物样本
{
path: '/biologicalSamples',
name: 'biologicalSamples',
component: () => import('@/views/BiologicalSamples/BiologicalSamples.vue'),
},
// 生物样本搜索
{
path: '/biologicalSampleSearch',
name: 'biologicalSampleSearch',
component: () => import('@/views/BiologicalSampleSearch/BiologicalSampleSearch.vue'),
},
// 消息推送
{
path: '/messagePush',
name: 'messagePush',
component: () => import('@/views/MessagePush/MessagePush.vue'),
},
// 个人数据统计
{
path: '/personalStats',
name: 'personalStats',
component: () => import('@/views/PersonalStats/PersonalStats.vue'),
},
];
const router = new VueRouter({

68
src/views/BiologicalSampleSearch/BiologicalSampleSearch.vue

@ -0,0 +1,68 @@
<template>
<div class="d-flex flex-column">
<search @searchPatientMes="searchPatientMes" />
<sample-table :lists="lists" @handleSelPatientMes="handleSelPatientMes" class="mt-3" />
</div>
</template>
<script>
import Search from 'components/BiologicalSampleSearch/Search.vue';
import SampleTable from 'components/BiologicalSampleSearch/SampleTable.vue';
import { selPatientMes } from 'config/api';
import { mapState, mapActions } from 'vuex';
export default {
name: 'BiologicalSampleSearch',
components: { Search, SampleTable },
data() {
return {
lists: { pageNum: 1, pageSize: 10, total: 1, list: [] },
hospitalization: '',
inpatientId: '',
};
},
created() {
this.handleSelPatientMes();
this.getControlGroups();
},
methods: {
...mapActions('home', ['getControlGroups']),
searchPatientMes(value) {
if (value) {
this.hospitalization = value.inpatientNumber;
this.inpatientId = value.groupValue;
}
this.handleSelPatientMes();
},
async handleSelPatientMes(pageNum = 1) {
try {
const { hospitalization, inpatientId } = this;
const params = {
param: {
hospitalization,
inpatientId,
pageNum,
pageSize: 10,
},
};
const res = await selPatientMes(params);
const { code, msg, data } = res.data;
if (code === 200) {
this.lists = data;
} else {
this.$message.error(msg || '查询失败');
throw msg;
}
} catch (error) {
throw new Error(`CaseSearch.vue method selSearchCriteriaList: ${error}`);
}
},
},
};
</script>
<style lang="stylus" scoped></style>

146
src/views/BiologicalSamples/BiologicalSamples.vue

@ -0,0 +1,146 @@
<template>
<div>
<div class="metting">
<a-card :bordered="false" title="生物样本">
<a-form :form="form" @submit="handleSubmit">
<!-- 住院号 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="住院号"
>
<a-input
placeholder="住院号"
v-decorator="[
'inpatientNumber',
{
rules: [
{ required: true, message: '住院号不能为空' },
{ whitespace: true, message: '住院号不能为空' },
{ max: 140, massage: '住院号最多140个字符' },
],
},
]"
/>
</a-form-item>
<!-- 样本类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="样本类型"
>
<a-select placeholder="请选择样本类型" style="min-width: 150px" v-decorator="['sampleType']">
<a-select-option
:key="item.id"
:value="item.id"
v-for="item in types"
>{{ item.title }}</a-select-option>
</a-select>
</a-form-item>
<!-- 样本类型 -->
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
label="样本类型"
>
<a-select
placeholder="请选择采集时间"
style="min-width: 150px"
v-decorator="['acquisitionTime']"
>
<a-select-option :key="t.id" :value="t.id" v-for="t in acquisitionTime">{{ t.title }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
<a-button class="white--text px-10" html-type="submit" type="primary">提交</a-button>
</a-form-item>
</a-form>
</a-card>
</div>
</div>
</template>
<script>
const formItemLayout = {
labelCol: { span: 4 },
wrapperCol: { span: 18 },
};
const tailItemLayout = { wrapperCol: { span: 18, offset: 4 } };
export default {
name: 'Meeting',
data() {
return {
formItemLayout,
tailItemLayout,
form: this.$form.createForm(this, { name: 'page-add' }),
inpatientNumber: '', //
types: [
{
id: 1,
title: '抗血凝10ml',
},
{
id: 2,
title: '促凝血5ml',
},
{
id: 3,
title: '晨尿10ml',
},
{
id: 4,
title: '24小时尿10ml',
},
],
acquisitionTime: [
{
id: 1,
title: '0天',
},
{
id: 2,
title: '14天',
},
{
id: 3,
title: '90天',
},
],
};
},
methods: {
//
handleSubmit(e) {
e.preventDefault();
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
// const param = values;
// const params = { param };
// console.log('params: ', params);
// const res = await addPage(params);
// const { data, msg, code } = res.data;
// this.$emit('closeModal');
// if (code === 200) {
// this.$message.success('');
// } else {
// throw msg;
// }
} catch (error) {
// this.$message.error(error || '');
}
}
});
},
},
};
</script>
<style lang="stylus" scoped>
.metting {
width: 100%;
// margin: 30px 10%;
}
</style>

53
src/views/Meeting/Meeting.vue

@ -16,7 +16,7 @@
<a-range-picker
:placeholder="['开始时间', '结束时间']"
@change="onChangeTime"
format="YYYY-MM-DD HH:mm"
format="YYYY-MM-DD HH:mm:ss"
show-time
style="width: 100%"
v-decorator="['time', rangeConfig]"
@ -68,7 +68,11 @@
:wrapper-col="formItemLayout.wrapperCol"
label="参会人员"
>
<quill-editor :max-size="maxSize" :placeholder="placeholderParticipants" />
<quill-editor
:max-size="maxSize"
:placeholder="placeholderParticipants"
v-model="participants"
/>
</a-form-item>
<!-- 研讨内容 -->
<a-form-item
@ -76,7 +80,11 @@
:wrapper-col="formItemLayout.wrapperCol"
label="研讨内容"
>
<quill-editor :max-size="maxSize" :placeholder="placeholderContent" />
<quill-editor
:max-size="maxSize"
:placeholder="placeholderContent"
v-model="discussionContent"
/>
</a-form-item>
<!-- 会议纪要 -->
<a-form-item
@ -84,7 +92,11 @@
:wrapper-col="formItemLayout.wrapperCol"
label="会议纪要"
>
<quill-editor :max-size="maxSize" :placeholder="placeholderMeeting" />
<quill-editor
:max-size="maxSize"
:placeholder="placeholderMeeting"
v-model="meetingMinutes"
/>
</a-form-item>
<a-form-item class="d-flex flex-row-reverse">
@ -99,6 +111,7 @@
<script>
import QuillEditor from 'components/QuillEditor/QuillEditor.vue';
import moment from 'moment';
import { saveConferenceRecords } from 'config/api';
const formItemLayout = {
labelCol: { span: 4 },
@ -115,11 +128,11 @@ export default {
tailItemLayout,
form: this.$form.createForm(this, { name: 'page-add' }),
rangeConfig: { rules: [{ type: 'array', required: true, message: '会议时间不能为空' }] },
place: '', //
host: '', //
participants: '', //
content: '', //
discussionContent: '', //
meetingMinutes: '', //
startTime: '', //
endTime: '', //
placeholderParticipants: '请在此输入参会人员...',
maxSize: 2048,
placeholderContent: '请在此输入研讨内容...',
@ -132,6 +145,8 @@ export default {
onChangeTime(dates, dateStrings) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
this.startTime = dateStrings[0];
this.endTime = dateStrings[1];
},
//
@ -140,19 +155,19 @@ export default {
this.form.validateFieldsAndScroll(async (err, values) => {
if (!err) {
try {
// const param = values;
// const params = { param };
// console.log('params: ', params);
// const res = await addPage(params);
// const { data, msg, code } = res.data;
// this.$emit('closeModal');
// if (code === 200) {
// this.$message.success('');
// } else {
// throw msg;
// }
const { host, place } = values;
const { startTime, endTime, participants, discussionContent, meetingMinutes } = this;
const params = { param: { host, place, startTime, endTime, participants, meetingMinutes, discussionContent, taskId: '0' } };
console.log('params: ', params);
const res = await saveConferenceRecords(params);
const { data, msg, code } = res.data;
if (code === 200) {
this.$message.success('提交成功');
} else {
throw msg;
}
} catch (error) {
// this.$message.error(error || '');
this.$message.error(error || '提交失败');
}
}
});

16
src/views/MessagePush/MessagePush.vue

@ -0,0 +1,16 @@
<template>
<div class="flex-column">消息推送</div>
</template>
<script>
export default {
name: 'CaseAnalysis',
data() {
return {};
},
methods: {},
};
</script>
<style lang="stylus" scoped></style>

45
src/views/PersonalStats/PersonalStats.vue

@ -0,0 +1,45 @@
<template>
<div class="flex-wrap">
<div class="fill-width mb-3">
<a-card style="width: 100%; height: 400px" title="病例统计">
<treemap />
</a-card>
</div>
<div class="fill-width mb-3">
<a-card style="width: 100%; height: 400px" title="各院病例分析">
<categorymap />
</a-card>
</div>
<div class="fill-width mb-3">
<a-card style="width: 100%; height: 400px" title="每日病例统计">
<cisualmap />
</a-card>
</div>
<div class="fill-width">
<a-card style="width: 100%; height: 400px" title="各医院生物样本统计">
<piemap />
</a-card>
</div>
</div>
</template>
<script>
import Treemap from 'components/Echarts/Treemap.vue';
import Cisualmap from 'components/Echarts/Cisualmap.vue';
import Categorymap from 'components/Echarts/Categorymap.vue';
import Piemap from 'components/Echarts/Piemap.vue';
export default {
name: 'Index',
components: { Treemap, Cisualmap, Categorymap, Piemap },
data() {
return {
str: '',
showVideo: false,
};
},
methods: {},
};
</script>
<style lang="stylus" scoped></style>
Loading…
Cancel
Save