@@ -32,7 +32,7 @@ export function getMedicalLabel(query) { | |||||
// 获取所有医生 | // 获取所有医生 | ||||
export function getDoctorAllList(query) { | export function getDoctorAllList(query) { | ||||
return request({ | return request({ | ||||
url: `/common/patient/doctor/list`, | |||||
url: `/common/doctor/list`, | |||||
method: "get", | method: "get", | ||||
params: query, | params: query, | ||||
}); | }); | ||||
@@ -1,7 +1,7 @@ | |||||
<template> | <template> | ||||
<div class="article-preview" v-loading="loading"> | <div class="article-preview" v-loading="loading"> | ||||
<template v-if="detail"> | <template v-if="detail"> | ||||
<template v-if="detail.type == articleTypeMap.edit"> | |||||
<template v-if="detail.type == ARTICLE_TYPE.getValueByName('edit')"> | |||||
<h1 class="article-preview__title">{{ detail.name }}</h1> | <h1 class="article-preview__title">{{ detail.name }}</h1> | ||||
<p v-if="detail.author" class="article-preview__author">作者: {{ detail.author }}</p> | <p v-if="detail.author" class="article-preview__author">作者: {{ detail.author }}</p> | ||||
<div class="article-preview__content" v-html="detail.content" /> | <div class="article-preview__content" v-html="detail.content" /> | ||||
@@ -20,9 +20,9 @@ | |||||
<script> | <script> | ||||
import { getArticleTemp, getArticleSnapshot } from "@/api/common"; | import { getArticleTemp, getArticleSnapshot } from "@/api/common"; | ||||
import { ARTICLE_TYPE } from '@/enums/index' | |||||
export default { | export default { | ||||
name: "ArticlePreview", | name: "ArticlePreview", | ||||
enums: ["articleTypeMap"], | |||||
props: { | props: { | ||||
articleId: { | articleId: { | ||||
type: [String, Number], | type: [String, Number], | ||||
@@ -34,6 +34,7 @@ export default { | |||||
}, | }, | ||||
data() { | data() { | ||||
return { | return { | ||||
ARTICLE_TYPE, | |||||
detail: null, | detail: null, | ||||
loading: false, | loading: false, | ||||
}; | }; | ||||
@@ -0,0 +1,20 @@ | |||||
<template> | |||||
<div> | |||||
<el-tag v-if="type" :type="type"> | |||||
<slot></slot> | |||||
</el-tag> | |||||
<span v-else>--</span> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
name: 'MyTag', | |||||
props: ["type"], | |||||
data() { | |||||
return { | |||||
} | |||||
} | |||||
} | |||||
</script> |
@@ -1,130 +0,0 @@ | |||||
import { createOptionsEnum } from "./tool"; | |||||
export const todoItemTypeMap = { | |||||
survey: 1, | |||||
article: 2, | |||||
remark: 3, | |||||
remind: 4 | |||||
}; | |||||
// 文章创作类型 | |||||
export const articleTypeMap = { | |||||
edit: 0, // 内容编辑 | |||||
link: 1, //链接 | |||||
}; | |||||
export const sysStatusMap = { | |||||
enabled: 0, | |||||
disabled: 1, | |||||
}; | |||||
export const periodUnitMap = { | |||||
day: 0, | |||||
month: 1, | |||||
year: 2, | |||||
}; | |||||
export const periodUnitEnum = createOptionsEnum([ | |||||
{ label: "天", value: periodUnitMap.day }, | |||||
{ label: "月", value: periodUnitMap.month }, | |||||
{ label: "年", value: periodUnitMap.year }, | |||||
]); | |||||
export const sysStatusEnum = createOptionsEnum([ | |||||
{ label: "启用", value: sysStatusMap.enabled }, | |||||
{ label: "停用", value: sysStatusMap.disabled }, | |||||
]); | |||||
// 待办事项类型 | |||||
export const todoItemTypeEnum = createOptionsEnum([ | |||||
{ label: "随访问卷", value: todoItemTypeMap.survey }, | |||||
{ label: "患教文章", value: todoItemTypeMap.article }, | |||||
{ label: "备注", value: todoItemTypeMap.remark }, | |||||
{ label: '提醒', value: todoItemTypeMap.remind } | |||||
]); | |||||
// 待办事项类型 | |||||
export const todoItemStatusEnum = createOptionsEnum([ | |||||
{ label: "未完成", value: "0" }, | |||||
{ label: "已完成", value: "1" }, | |||||
]); | |||||
export const cardTypeEnum = createOptionsEnum([{ label: "身份证", value: "SF" }]); | |||||
// 随访单状态 | |||||
export const followItemStatusEnum = createOptionsEnum([ | |||||
{ label: "待开始", value: 0, color: "#E6A23C" }, | |||||
{ label: "进行中", value: 1, color: "#67c23a" }, | |||||
{ label: "已完成", value: 2, color: "#909399" }, | |||||
{ label: "已过期", value: 3, color: "#909399" }, | |||||
{ label: "已终止", value: 4, color: "#F56C6C" }, | |||||
]); | |||||
// 随访问卷|状态 | |||||
export const surveyTempMap = { | |||||
drafts: 0, | |||||
save: 1, | |||||
online: 2, | |||||
offline: 3, | |||||
}; | |||||
export const surveyTempEnum = createOptionsEnum([ | |||||
{ label: "草稿", value: surveyTempMap.drafts, color: "#909399" }, | |||||
{ label: "待发布", value: surveyTempMap.save, color: "#E6A23C" }, | |||||
{ label: "已发布", value: surveyTempMap.online, color: "#67c23a" }, | |||||
{ label: "已下线", value: surveyTempMap.offline, color: "#E6A23C" }, | |||||
]); | |||||
// | |||||
export const reportStatusEnum = createOptionsEnum([ | |||||
{ | |||||
label: "待报到", | |||||
value: 0, | |||||
color: "#E6A23C" | |||||
}, | |||||
{ | |||||
label: "已入组", | |||||
value: 1, | |||||
color: "#67c23a" | |||||
} | |||||
// { label: "待报到", value: null, color: "#909399" }, | |||||
// { label: "待审核", value: 0, color: "#E6A23C" }, | |||||
// { label: "待分配", value: 1, color: "#E6A23C" }, | |||||
// { label: "已入组", value: 2, color: "#67c23a" }, | |||||
// { label: "已拒绝", value: 3, color: "#F56C6C" }, | |||||
]); | |||||
// 性别 | |||||
export const sexMap = { | |||||
female: "女", | |||||
male: "男", | |||||
}; | |||||
export const sexEnum = createOptionsEnum([ | |||||
{ label: "女", value: sexMap.female }, | |||||
{ label: "男", value: sexMap.male }, | |||||
]); | |||||
// 就诊类型 | |||||
export const treatmentEnum = createOptionsEnum([ | |||||
{ label: "住院", value: "住院" }, | |||||
{ label: "门诊", value: "门诊" }, | |||||
]); | |||||
// 婚姻状况 | |||||
export const maritalStatusEnum = createOptionsEnum([ | |||||
{ label: "未婚", value: 0 }, | |||||
{ label: "已婚", value: 1 }, | |||||
{ label: "已婚已育", value: 2 }, | |||||
]); | |||||
// 吸烟史 | |||||
export const smokingEnum = createOptionsEnum([ | |||||
{ label: "有", value: 1 }, | |||||
{ label: "无", value: 0 }, | |||||
{ label: "有,现已戒烟", value: 2 }, | |||||
]); | |||||
// 喝酒史 | |||||
export const drinkingEnum = createOptionsEnum([ | |||||
{ label: "有", value: 1 }, | |||||
{ label: "无", value: 0 }, | |||||
{ label: "有,现已戒酒", value: 2 }, | |||||
]); |
@@ -1,13 +0,0 @@ | |||||
import * as Constant from "@/constant"; | |||||
export default { | |||||
data() { | |||||
if (this.$options === undefined || this.$options.enums === undefined) { | |||||
return {}; | |||||
} | |||||
const data = {}; | |||||
this.$options.enums.forEach((key) => { | |||||
data[key] = Constant[key]; | |||||
}); | |||||
return data; | |||||
}, | |||||
}; |
@@ -1,50 +0,0 @@ | |||||
/** | |||||
* 将KeyValue数组转换为对象 | |||||
* @param {Array} keyValues | |||||
* @returns {Object} | |||||
*/ | |||||
function keyValueToMap(keyValues) { | |||||
return keyValues.reduce((map, kv) => { | |||||
map[kv.value] = kv; | |||||
return map; | |||||
}, {}); | |||||
} | |||||
/** | |||||
* 根据value从KeyValue中查找label | |||||
* @param {Array} keyValues | |||||
* @param {string|number} value | |||||
* @returns {string} | |||||
*/ | |||||
function getLabelFromKeyValue(keyValues, value) { | |||||
const kv = keyValues.find((kv) => kv.value == value); | |||||
return kv?.label || "-"; | |||||
} | |||||
/** | |||||
* 根据label从KeyValue中查找value | |||||
* @param {Array} keyValues | |||||
* @param {string} label | |||||
* @returns {string|number|null} | |||||
*/ | |||||
function getValueFromLabel(keyValues, label) { | |||||
const kv = keyValues.find((kv) => kv.label === label); | |||||
return kv?.value || null; | |||||
} | |||||
// 同样改写getOther和getEnabled函数 | |||||
/** | |||||
* OptionsEnum对象 | |||||
*/ | |||||
export function createOptionsEnum(keyValues) { | |||||
const options = keyValues; | |||||
return { | |||||
options, | |||||
enum: keyValueToMap(keyValues), | |||||
getLabel: (value) => getLabelFromKeyValue(options, value), | |||||
getValue: (label) => getValueFromLabel(options, label), | |||||
// 其他函数 | |||||
}; | |||||
} |
@@ -10,16 +10,16 @@ export default function createEnum(dictList) { | |||||
...nameToItemMap, | ...nameToItemMap, | ||||
options: dictList, | options: dictList, | ||||
getValueByName(enumName) { | getValueByName(enumName) { | ||||
return nameToItemMap[enumName].value; | |||||
return nameToItemMap && nameToItemMap[enumName].value; | |||||
}, | }, | ||||
getLabelByValue(value) { | getLabelByValue(value) { | ||||
return valueToItemMap[value].label || ''; | |||||
return valueToItemMap[value] && valueToItemMap[value].label || ''; | |||||
}, | }, | ||||
getLabelByName(name) { | getLabelByName(name) { | ||||
return nameToItemMap[name].label | |||||
return nameToItemMap && nameToItemMap[name].label | |||||
}, | }, | ||||
getTagByValue(value) { | getTagByValue(value) { | ||||
return valueToItemMap[value].tag || '' | |||||
return valueToItemMap[value] && valueToItemMap[value].tag || '' | |||||
} | } | ||||
}; | }; | ||||
} | } | ||||
@@ -110,6 +110,55 @@ export const FOLLOWUP_STATUS = createEnum([ | |||||
tag: 'danger' | tag: 'danger' | ||||
} | } | ||||
]) | ]) | ||||
// 待办事项类型 | |||||
export const TODO_TYPE = createEnum([ | |||||
{ | |||||
value: 1, | |||||
label: '随访问卷', | |||||
name: 'survey' | |||||
}, | |||||
{ | |||||
value: 2, | |||||
label: '患教文章', | |||||
name: 'article' | |||||
}, | |||||
{ | |||||
value: 3, | |||||
label: '备注', | |||||
name: 'remark' | |||||
}, | |||||
{ | |||||
value: 4, | |||||
label: '提醒', | |||||
name: 'remind' | |||||
} | |||||
]) | |||||
// 待办事项状态 | |||||
export const TODO_STATUS = createEnum([ | |||||
{ | |||||
value: 0, | |||||
label: '未完成', | |||||
name: 'unfinished' | |||||
}, | |||||
{ | |||||
value: 1, | |||||
label: '已完成', | |||||
name: 'finished' | |||||
} | |||||
]) | |||||
// 文章创作类型 | |||||
export const ARTICLE_TYPE = createEnum([ | |||||
{ | |||||
label: '内容编辑', | |||||
value: 0, | |||||
name: 'edit' | |||||
}, | |||||
{ | |||||
label: '链接', | |||||
value: 1, | |||||
name: 'link' | |||||
} | |||||
]) | |||||
// 日期单位 | // 日期单位 | ||||
export const PERIOD_UNIT = createEnum([ | export const PERIOD_UNIT = createEnum([ | ||||
{ | { | ||||
@@ -25,7 +25,6 @@ import { | |||||
selectDictLabels, | selectDictLabels, | ||||
handleTree, | handleTree, | ||||
} from "@/utils/ruoyi"; | } from "@/utils/ruoyi"; | ||||
import constMixin from "@/constant/mixin"; | |||||
// 分页组件 | // 分页组件 | ||||
import Pagination from "@/components/Pagination"; | import Pagination from "@/components/Pagination"; | ||||
// 自定义表格工具组件 | // 自定义表格工具组件 | ||||
@@ -68,7 +67,6 @@ Vue.use(directive); | |||||
Vue.use(plugins); | Vue.use(plugins); | ||||
Vue.use(registComps); | Vue.use(registComps); | ||||
Vue.use(VueMeta); | Vue.use(VueMeta); | ||||
Vue.mixin(constMixin); | |||||
/** | /** | ||||
* If you don't want to use mock-server | * If you don't want to use mock-server | ||||
@@ -1,7 +1,9 @@ | |||||
import CommonModal from '@/components/CommonModal' | import CommonModal from '@/components/CommonModal' | ||||
import MyTag from '@/components/MyTag' | |||||
export default { | export default { | ||||
install(app) { | install(app) { | ||||
app.component("CommonModal", CommonModal); | app.component("CommonModal", CommonModal); | ||||
app.component("MyTag", MyTag); | |||||
} | } | ||||
} | } |
@@ -2,7 +2,6 @@ | |||||
* 通用js方法封装处理 | * 通用js方法封装处理 | ||||
* Copyright (c) 2019 ruoyi | * Copyright (c) 2019 ruoyi | ||||
*/ | */ | ||||
import { sexMap } from "@/constant"; | |||||
// 日期格式化 | // 日期格式化 | ||||
export function parseTime(time, pattern) { | export function parseTime(time, pattern) { | ||||
if (arguments.length === 0 || !time) { | if (arguments.length === 0 || !time) { | ||||
@@ -253,7 +252,7 @@ export function parseIDCard(idCard) { | |||||
// 提取性别(奇数为男,偶数为女) | // 提取性别(奇数为男,偶数为女) | ||||
const genderDigit = parseInt(idCard.charAt(16), 10); | const genderDigit = parseInt(idCard.charAt(16), 10); | ||||
const gender = genderDigit % 2 === 0 ? sexMap.female : sexMap.male; | |||||
const gender = genderDigit % 2 === 0 ? '女' : '男'; | |||||
return { | return { | ||||
birthYear: birthYear, | birthYear: birthYear, | ||||
@@ -1,48 +0,0 @@ | |||||
<template> | |||||
<Popup ref="popup" title="" width="600px" :isCrud="false"> | |||||
<ArticlePreview style="height: 75vh; overflow-y: auto" :articleId="articleId" /> | |||||
</Popup> | |||||
</template> | |||||
<script> | |||||
import Popup from "@/components/Popup"; | |||||
import ArticlePreview from "@/components/ArticlePreview"; | |||||
export default { | |||||
name: "ArticlePreviewPopup", | |||||
components: { | |||||
Popup, | |||||
ArticlePreview, | |||||
}, | |||||
data() { | |||||
return { | |||||
articleId: "", | |||||
}; | |||||
}, | |||||
methods: { | |||||
open(id) { | |||||
this.articleId = id; | |||||
this.$refs.popup.open(); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.article-preview { | |||||
padding: 15px; | |||||
&__title { | |||||
font-size: 19px; | |||||
font-weight: 500; | |||||
color: #12111e; | |||||
line-height: 27px; | |||||
} | |||||
&__author { | |||||
font-size: 13px; | |||||
color: #00b191; | |||||
line-height: 19px; | |||||
margin-top: 10px; | |||||
} | |||||
&__content { | |||||
} | |||||
} | |||||
</style> |
@@ -1,147 +0,0 @@ | |||||
<template> | |||||
<div class="plan-base-form"> | |||||
<!--判断预览页 禁用状态设置--> | |||||
<el-form :model="form" :rules="rules" ref="form" label-width="110px" style="height: 100%" :disabled="isPreview === 'preview' ? true : false"> | |||||
<el-form-item label="模板名称" prop="name" required> | |||||
<el-input v-model="form.name" maxlength="32"></el-input> | |||||
</el-form-item> | |||||
<el-row> | |||||
<el-col :span="12"> | |||||
<el-form-item label="应用科室" prop="deptId"> | |||||
<TreeDept | |||||
ref="treeDept" | |||||
:defaultName="defaultDeptName" | |||||
v-model="form.deptId" | |||||
@change="onChangeDept" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item label="随访周期" prop="periodNumber" required> | |||||
<PeriodSelector | |||||
:value="{ quantity: form.periodNumber, unit: form.periodUnit }" | |||||
@change="hanldeSelectorTimeChange" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="应用疾病" prop="labelId"> | |||||
<el-select v-model="form.labelId" filterable> | |||||
<el-option | |||||
v-for="item in diseaseList" | |||||
:key="item.id" | |||||
:label="item.name" | |||||
:value="item.id" | |||||
></el-option> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="是否自动匹配" prop="isMatch"> | |||||
<el-radio-group v-model="form.isMatch"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { getMedicalLabel } from "@/api/hospital"; | |||||
import TreeDept from "@/components/TreeDept"; | |||||
import PeriodSelector from "../PeriodSelector"; | |||||
export default { | |||||
enums: ["periodUnitMap"], | |||||
components: { | |||||
PeriodSelector, | |||||
TreeDept, | |||||
}, | |||||
data() { | |||||
return { | |||||
form: { | |||||
name: "", | |||||
deptId: "", | |||||
labelId: "", | |||||
periodNumber: "", | |||||
periodUnit: "", | |||||
isMatch: 0, | |||||
wardId: null | |||||
}, | |||||
rules: { | |||||
name: [ | |||||
{ required: true, message: "请输入模板名称", trigger: "blur" }, | |||||
{ max: 32, message: "长度不能超过32个字符", trigger: "blur" }, | |||||
], | |||||
deptId: [{ required: true, message: "请选择应用科室", trigger: "change" }], | |||||
labelId: [{ required: true, message: "请选择应用疾病", trigger: "change" }], | |||||
periodNumber: [{ required: true, message: "请选择随访周期", trigger: "change" }], | |||||
isMatch: [ | |||||
{ | |||||
required: true, | |||||
message: '请选择是否字动匹配', | |||||
trigger: ['blur', 'change'] | |||||
} | |||||
] | |||||
}, | |||||
diseaseList: [], | |||||
defaultDeptName: "", | |||||
}; | |||||
}, | |||||
created() { | |||||
this.form.periodUnit = this.periodUnitMap.day; | |||||
}, | |||||
watch: { | |||||
"form.deptId": { | |||||
handler: "loadDisease", | |||||
}, | |||||
}, | |||||
props: { | |||||
isPreview: { // 预览标记 | |||||
type: String, | |||||
}, | |||||
}, | |||||
methods: { | |||||
init(params) { | |||||
for (const key of Object.keys(this.form)) { | |||||
this.form[key] = params[key]; | |||||
this.defaultDeptName = params.deptName; | |||||
} | |||||
}, | |||||
submit() { | |||||
return new Promise((resolve, reject) => { | |||||
this.$refs.form.validate((valid) => { | |||||
if (valid) { | |||||
resolve(this.form); | |||||
} else { | |||||
reject(new Error("校验不通过")); | |||||
console.log("error submit!!"); | |||||
return false; | |||||
} | |||||
}); | |||||
}); | |||||
}, | |||||
resetForm() { | |||||
this.resetForm("form"); | |||||
}, | |||||
onChangeDept(val, selectItem) { | |||||
console.log('val=', val, selectItem) | |||||
this.form.labelId = '' | |||||
this.form.wardId = selectItem?.wardId || null | |||||
}, | |||||
hanldeSelectorTimeChange({ quantity, unit }) { | |||||
this.form.periodNumber = quantity; | |||||
this.form.periodUnit = unit; | |||||
}, | |||||
async loadDisease() { | |||||
const res = await getMedicalLabel({ deptId: this.form.deptId || "" }); | |||||
this.diseaseList = res.data || []; | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.plan-base-form { | |||||
} | |||||
</style> |
@@ -1,169 +0,0 @@ | |||||
<template> | |||||
<div class="follow-task"> | |||||
<el-steps direction="vertical" :active="value.length + 1"> | |||||
<el-step v-for="(item, index) in value" :key="index"> | |||||
<template slot="title"> | |||||
<div style="display: flex; align-items: center"> | |||||
<span>第{{ index + 1 }}次随访任务</span> | |||||
<span class="ml10" style="font-size: 14px; color: #cccccc">基线时间+</span> | |||||
<div class="ml10"> | |||||
<el-input-number | |||||
size="mini" | |||||
v-model="item.lagNumber" | |||||
v-bind="getTaskTimeRange(item, index)" | |||||
:disabled="!!isPreview" | |||||
></el-input-number> | |||||
<span class="ml5" style="font-size: 12px; color: #000">天</span> | |||||
<!-- <PeriodSelector | |||||
:hasZero="index === 0" | |||||
size="mini" | |||||
:value="{ quantity: item.lagNumber, unit: item.lagUnit }" | |||||
@change=" | |||||
item.lagNumber = $event.quantity; | |||||
item.lagUnit = $event.unit; | |||||
" | |||||
/> --> | |||||
</div> | |||||
<span :class="['ml20', isPreview ? 'gary-button': '']" v-if="value.length - 1 === index"> | |||||
<i | |||||
@click="handleDelTask(index)" | |||||
class="el-icon-remove mr5" | |||||
style="cursor: pointer" | |||||
></i> | |||||
<i | |||||
v-if="value.length < 10 && (!item.lagNumber || item.lagNumber < maxDays)" | |||||
@click="handleAddTask" | |||||
class="el-icon-circle-plus" | |||||
style="cursor: pointer" | |||||
></i> | |||||
</span> | |||||
</div> | |||||
</template> | |||||
<template slot="description"> | |||||
<el-table :data="item.items" border emptyText="暂无待办事项" class="mt10"> | |||||
<el-table-column align="center" property="targetType" label="待办类型"> | |||||
<template slot-scope="scope"> | |||||
{{ todoItemTypeEnum.getLabel(scope.row.targetType) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="targetName" label="名称" /> | |||||
<el-table-column align="center" label="操作"> | |||||
<template slot-scope="scope"> | |||||
<el-button size="mini" type="text" @click="handlePrewviewItem(scope.row)"> | |||||
查看 | |||||
</el-button> | |||||
<el-button size="mini" type="text" @click="hanldeDelTodoItem(scope.$index, index)" v-if="!isPreview"> | |||||
删除 | |||||
</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<el-button | |||||
v-if="item.items.length < 10" | |||||
@click="handleAddTodo(index)" | |||||
class="mb20" | |||||
type="primary" | |||||
style="width: 100%" | |||||
:disabled="!!isPreview" | |||||
> | |||||
添加待办事项 | |||||
</el-button> | |||||
</template> | |||||
</el-step> | |||||
</el-steps> | |||||
<ArticlePreviewPopup ref="previewArticle" /> | |||||
<SurveyPreviewPopup ref="previewSurvey" /> | |||||
<RemindPreviewPopup ref="previewRemind" /> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import PeriodSelector from "../PeriodSelector"; | |||||
import TodoItemSelector from "../TodoItemSelector"; | |||||
import ArticlePreviewPopup from "../ArticlePreviewPopup"; | |||||
import SurveyPreviewPopup from "../SurveyPreviewPopup"; | |||||
import RemindPreviewPopup from "../RemindPreviewPopup"; | |||||
export default { | |||||
enums: ["todoItemTypeEnum", "periodUnitMap", "todoItemTypeMap"], | |||||
components: { | |||||
PeriodSelector, | |||||
TodoItemSelector, | |||||
ArticlePreviewPopup, | |||||
SurveyPreviewPopup, | |||||
RemindPreviewPopup | |||||
}, | |||||
props: { | |||||
value: { | |||||
type: Array, | |||||
default: () => [], | |||||
}, | |||||
maxDays: { | |||||
type: Number, | |||||
}, | |||||
isPreview: { // 预览标记 | |||||
type: String, | |||||
}, | |||||
}, | |||||
created() { | |||||
if (this.value.length === 0) { | |||||
// 自动插入一条 | |||||
this.handleAddTask(); | |||||
} | |||||
}, | |||||
methods: { | |||||
getTaskTimeRange(item, index) { | |||||
const range = { | |||||
min: index === 0 ? 0 : this.value[index - 1].lagNumber + 1, | |||||
max: this.maxDays - 1, | |||||
}; | |||||
console.log(range); | |||||
return range; | |||||
}, | |||||
handleAddTask() { | |||||
if (this.isPreview === 'preview') return false; | |||||
this.$emit("input", [ | |||||
...this.value, | |||||
{ | |||||
lagNumber: undefined, | |||||
lagUnit: this.periodUnitMap.day, | |||||
items: [], | |||||
}, | |||||
]); | |||||
}, | |||||
handleDelTask(index) { | |||||
if (this.isPreview === 'preview') return false; | |||||
if (index === 0) { | |||||
return this.$message.warning("至少包含一个任务"); | |||||
} | |||||
const taskList = [...this.value]; | |||||
taskList.splice(index); | |||||
this.$emit("input", taskList); | |||||
}, | |||||
// 修改添加待办事项 | |||||
handleAddTodo(index) { | |||||
this.$emit("selectTodo", index); | |||||
}, | |||||
// 查看预览待办事项 | |||||
handlePrewviewItem(item) { | |||||
if (item.targetType === this.todoItemTypeMap.article) { | |||||
this.$refs.previewArticle.open(item.targetId); | |||||
} else if (item.targetType === this.todoItemTypeMap.survey) { | |||||
this.$refs.previewSurvey.open(item.surveyId); | |||||
} else if (item.targetType === this.todoItemTypeMap.remind) { | |||||
this.$refs.previewRemind.open(item.targetId) | |||||
} | |||||
}, | |||||
// 删除待办事项 | |||||
hanldeDelTodoItem(todoIndex, taskIndex) { | |||||
const taskList = [...this.value]; | |||||
taskList[taskIndex].items.splice(todoIndex, 1); | |||||
this.$emit("change", taskList); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.follow-task { | |||||
} | |||||
</style> |
@@ -1,126 +0,0 @@ | |||||
<template> | |||||
<div class="time-selector"> | |||||
<el-select | |||||
class="quantity mr10" | |||||
:size="size" | |||||
:value="value.quantity" | |||||
@change="handleChange('quantity', $event)" | |||||
placeholder="请选择" | |||||
no-data-text="选择单位后载入数据" | |||||
:clearable="isClearable" | |||||
> | |||||
<el-option v-if="hasZero && value.unit === periodUnitMap.day" key="0" label="0" :value="0" /> | |||||
<el-option | |||||
v-for="quantity in quantities" | |||||
:key="quantity" | |||||
:label="quantity.toString()" | |||||
:value="quantity" | |||||
/> | |||||
</el-select> | |||||
<el-select | |||||
class="unit" | |||||
:size="size" | |||||
:value="value.unit" | |||||
@change="handleChange('unit', $event)" | |||||
placeholder="请选择" | |||||
:clearable="isClearable" | |||||
style="width: 120px" | |||||
> | |||||
<el-option | |||||
:label="item.label" | |||||
:value="item.value" | |||||
v-for="item in periodUnitEnum.options" | |||||
:key="item.value" | |||||
/> | |||||
</el-select> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { periodUnitMap } from "@/constant"; | |||||
export default { | |||||
enums: ["periodUnitMap", "periodUnitEnum"], | |||||
data() { | |||||
return { | |||||
quantities: [], | |||||
}; | |||||
}, | |||||
props: { | |||||
size: String, | |||||
value: { | |||||
type: Object, | |||||
defualt: {}, | |||||
}, | |||||
hasZero: { | |||||
type: Boolean, | |||||
default: false, | |||||
}, | |||||
clearable: { | |||||
type: Boolean, | |||||
default: false, | |||||
}, | |||||
defaultUnit: { | |||||
type: [Number, String], | |||||
default: periodUnitMap.day, | |||||
}, | |||||
}, | |||||
created() { | |||||
if (!this.value.unit && this.defaultUnit) { | |||||
this.handleChange("unit", this.defaultUnit); | |||||
} | |||||
this.init(); | |||||
}, | |||||
computed: { | |||||
isClearable() { | |||||
return this.clearable || this.clearable === ""; | |||||
}, | |||||
}, | |||||
watch: { | |||||
"value.unit"() { | |||||
this.init(); | |||||
}, | |||||
}, | |||||
methods: { | |||||
init() { | |||||
const { unit, quantity } = this.value; | |||||
if (unit === this.periodUnitMap.day) { | |||||
this.quantities = Array.from({ length: 30 }, (_, i) => i + 1); | |||||
if (quantity > 30) { | |||||
this.handleChange("quantity", 30); | |||||
} | |||||
} else if (unit === this.periodUnitMap.month) { | |||||
this.quantities = Array.from({ length: 12 }, (_, i) => i + 1); | |||||
if (quantity > 12) { | |||||
this.handleChange("quantity", 12); | |||||
} | |||||
} else if (unit === this.periodUnitMap.year) { | |||||
this.quantities = Array.from({ length: 10 }, (_, i) => i + 1); | |||||
if (quantity > 10) { | |||||
this.handleChange("quantity", 10); | |||||
} | |||||
} else { | |||||
this.quantities = []; | |||||
this.handleChange("quantity", ""); | |||||
} | |||||
}, | |||||
handleChange(field, value) { | |||||
this.$emit("change", { | |||||
unit: this.value.unit, | |||||
quantity: this.value.quantity, | |||||
[field]: value, | |||||
}); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.time-selector { | |||||
display: flex; | |||||
align-items: center; | |||||
.unit { | |||||
width: 80px; | |||||
} | |||||
} | |||||
</style> |
@@ -1,27 +0,0 @@ | |||||
<template> | |||||
<Popup ref="popup" title="提醒详情" width="400px" :isCrud="false"> | |||||
<RemindPreview v-if="id" :id="id"/> | |||||
</Popup> | |||||
</template> | |||||
<script> | |||||
import Popup from "@/components/Popup"; | |||||
import RemindPreview from '@/components/RemindPreview' | |||||
export default { | |||||
name: 'RemindPreviewPopup', | |||||
components: { | |||||
Popup, | |||||
RemindPreview | |||||
}, | |||||
data() { | |||||
return { | |||||
id: null, | |||||
} | |||||
}, | |||||
methods: { | |||||
open(id) { | |||||
this.id = id; | |||||
this.$refs.popup.open() | |||||
} | |||||
}, | |||||
} | |||||
</script> |
@@ -1,33 +0,0 @@ | |||||
<template> | |||||
<Popup ref="popup" title="" width="1000px" :isCrud="false"> | |||||
<DWViewer style="height: 75vh; overflow-y: auto" :url="url" /> | |||||
</Popup> | |||||
</template> | |||||
<script> | |||||
import Popup from "@/components/Popup"; | |||||
import DWViewer from "@/components/DWViewer"; | |||||
export default { | |||||
name: "SurveyPreviewPopup", | |||||
components: { | |||||
Popup, | |||||
DWViewer, | |||||
}, | |||||
data() { | |||||
return { | |||||
surveyId: "", | |||||
}; | |||||
}, | |||||
computed: { | |||||
url() { | |||||
return `${process.env.VUE_APP_SURVEY_PREFIX}/survey/diaowen-m.html?surveyId=${this.surveyId}&sid=&tag=p-auth-0`; | |||||
}, | |||||
}, | |||||
methods: { | |||||
open(id) { | |||||
this.surveyId = id; | |||||
this.$refs.popup.open(); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> |
@@ -1,269 +0,0 @@ | |||||
<template> | |||||
<div class="todo-selector" v-show="visible"> | |||||
<div class="sf-title mb5">添加待办事项</div> | |||||
<el-card> | |||||
<el-form ref="form" inline> | |||||
<el-form-item label="类型" prop="targetType" placeholder="请选择" style="margin: 0"> | |||||
<el-select v-model="targetType"> | |||||
<el-option | |||||
v-for="item in targetTypeOptions" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
:key="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item | |||||
label="状态" | |||||
prop="selectType" | |||||
placeholder="请选择" | |||||
style="margin: 0; margin-left: 20px" | |||||
> | |||||
<el-select v-model="queryParams.selectType"> | |||||
<el-option label="全部" value="" /> | |||||
<el-option label="已选" value="1" /> | |||||
<el-option label="未选" value="2" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item label="" prop="keyword" style="margin: 0; margin-left: 20px"> | |||||
<el-input | |||||
v-model="queryParams.keyword" | |||||
placeholder="请输入待办事项名称进行搜索" | |||||
></el-input> | |||||
</el-form-item> | |||||
</el-form> | |||||
</el-card> | |||||
<div class="table"> | |||||
<el-table :data="paginatedData" border class="mt20"> | |||||
<el-table-column align="center" width="300" property="targetName" label="名称" /> | |||||
<el-table-column align="center" property="targetType" label="类型"> | |||||
<template slot-scope="scope"> | |||||
{{ todoItemTypeEnum.getLabel(scope.row.targetType) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="status" label="状态"> | |||||
<template slot-scope="scope"> | |||||
<div :class="[getCheckedStatus(scope.row) ? 'green-button' : 'gary-button']">{{ getCheckedStatus(scope.row) ? "已选" : "未选" }}</div> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" label="操作"> | |||||
<template slot-scope="scope"> | |||||
<el-checkbox | |||||
:value="getCheckedStatus(scope.row)" | |||||
@change="handleCheckedChange(scope.row, $event)" | |||||
></el-checkbox> | |||||
<el-button @click="handlePreview(scope.row)" class="ml10" size="mini" type="text"> | |||||
详情 | |||||
</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<pagination | |||||
v-show="searchData.length > 0" | |||||
:total="searchData.length" | |||||
:page.sync="pageNum" | |||||
:limit.sync="pageSize" | |||||
/> | |||||
<el-card class="mt20"> | |||||
<div class="footer"> | |||||
<el-button @click="handleCancel">取 消</el-button> | |||||
<el-button type="primary" @click="handleConfirm">确定</el-button> | |||||
</div> | |||||
</el-card> | |||||
</div> | |||||
<ArticlePreviewPopup ref="previewArticle" /> | |||||
<SurveyPreviewPopup ref="previewSurvey" /> | |||||
<RemindPreviewPopup ref="previewRemind" /> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { getPlanItemList } from "@/api/hospital"; | |||||
import { todoItemTypeMap } from "@/constant"; | |||||
import ArticlePreviewPopup from "../ArticlePreviewPopup"; | |||||
import SurveyPreviewPopup from "../SurveyPreviewPopup"; | |||||
import RemindPreviewPopup from "../RemindPreviewPopup"; | |||||
export default { | |||||
enums: ["todoItemTypeEnum", "todoItemTypeMap"], | |||||
components: { | |||||
ArticlePreviewPopup, | |||||
SurveyPreviewPopup, | |||||
RemindPreviewPopup | |||||
}, | |||||
props: { | |||||
defaultValue: { | |||||
type: Array, | |||||
default: () => [], | |||||
}, | |||||
form: { | |||||
type: Object, | |||||
default: () => ({}), | |||||
}, | |||||
}, | |||||
data() { | |||||
return { | |||||
pageNum: 1, | |||||
pageSize: 10, | |||||
targetType: todoItemTypeMap.survey, | |||||
queryParams: { | |||||
selectType: "", | |||||
keyword: "", | |||||
}, | |||||
listMap: { | |||||
[todoItemTypeMap.article]: 'allArticleList', | |||||
[todoItemTypeMap.survey]: 'allSurveyList', | |||||
[todoItemTypeMap.remind]: 'allRemindList' | |||||
}, | |||||
allArticleList: null, // 文章 | |||||
allSurveyList: null, // 问卷数据 | |||||
allRemindList: null, | |||||
selectList: [], | |||||
visible: false, | |||||
}; | |||||
}, | |||||
computed: { | |||||
// 分页后数据 | |||||
paginatedData() { | |||||
const startIndex = (this.pageNum - 1) * this.pageSize; | |||||
const endIndex = startIndex + this.pageSize; | |||||
return this.searchData.slice(startIndex, endIndex); | |||||
}, | |||||
listField() { | |||||
return this.listMap[this.targetType] | |||||
}, | |||||
// 过滤查询的数据 | |||||
searchData() { | |||||
const allData = this[this.listField] || [] | |||||
return allData.filter((item) => { | |||||
// 未选/已选 | |||||
if (this.queryParams.selectType) { | |||||
const checked = this.getCheckedStatus(item); | |||||
if (this.queryParams.selectType === "1" && !checked) { | |||||
return false; | |||||
} | |||||
if (this.queryParams.selectType === "2" && checked) { | |||||
return false; | |||||
} | |||||
} | |||||
// 按名称搜索 | |||||
if (this.queryParams.keyword) { | |||||
return item.targetName.includes(this.queryParams.keyword); | |||||
} | |||||
return true; | |||||
}); | |||||
}, | |||||
targetTypeOptions() { | |||||
return this.todoItemTypeEnum.options.filter(item => item.value !== todoItemTypeMap.remark) | |||||
} | |||||
}, | |||||
watch: { | |||||
targetType: "getList", | |||||
"form.labelId"() { | |||||
// 修改疾病,清空数据 | |||||
this.allArticleList = null; | |||||
this.allSurveyList = null; | |||||
}, | |||||
}, | |||||
methods: { | |||||
open(defaultValue = []) { | |||||
this.getList(); | |||||
this.selectList = [...defaultValue]; | |||||
this.defaultCheckIds = this.getCheckedIds(this.selectList); | |||||
this.visible = true; | |||||
this.promise = {}; | |||||
return new Promise((resolve, reject) => { | |||||
this.promise.resolve = resolve; | |||||
this.promise.reject = reject; | |||||
}); | |||||
}, | |||||
getList() { | |||||
if (this[this.listField]) return; | |||||
getPlanItemList({ targetType: this.targetType, labelId: this.form.labelId }).then((res) => { | |||||
this[this.listField] = res.data || []; | |||||
}); | |||||
}, | |||||
getCheckedIds(list) { | |||||
return list | |||||
.map((item) => item.targetId) | |||||
.sort() | |||||
.join(","); | |||||
}, | |||||
reset() { | |||||
this.visible = false; | |||||
this.queryParams.selectType = ""; | |||||
this.queryParams.keyword = ""; | |||||
this.targetType = todoItemTypeMap.survey; | |||||
}, | |||||
handleCancel() { | |||||
const newCheckedIds = this.getCheckedIds(this.selectList); | |||||
const close = () => { | |||||
this.reset(); | |||||
this.promise.reject(); | |||||
}; | |||||
if (this.defaultCheckIds !== newCheckedIds) { | |||||
this.$modal.confirm("页面内信息尚未保存,是否继续确定退出?").then(close); | |||||
return false; | |||||
} | |||||
close(); | |||||
}, | |||||
handleConfirm() { | |||||
if (this.selectList.length === 0) { | |||||
this.$message.error("至少选择一个待办事项"); | |||||
return; | |||||
} | |||||
this.reset(); | |||||
this.promise.resolve(this.selectList); | |||||
}, | |||||
getCheckedStatus(row) { | |||||
return this.selectList.some( | |||||
(item) => item.targetId === row.targetId && item.targetType === row.targetType | |||||
); | |||||
}, | |||||
handleCheckedChange(row, checked) { | |||||
console.log('row=', checked) | |||||
const selectList = this.selectList.filter((item) => item.targetType === row.targetType); | |||||
if (checked) { | |||||
if (selectList.length >= 5) { | |||||
this.$message.error("同一类型待办事项最多5个"); | |||||
return; | |||||
} | |||||
this.selectList.push({ ...row }); | |||||
} else { | |||||
const index = this.selectList.findIndex( | |||||
(item) => item.targetId === row.targetId && item.targetType === row.targetType | |||||
); | |||||
if (index > -1) { | |||||
this.selectList.splice(index, 1); | |||||
} | |||||
} | |||||
}, | |||||
// 预览文章/问卷 | |||||
handlePreview(item) { | |||||
if (item.targetType === this.todoItemTypeMap.article) { | |||||
this.$refs.previewArticle.open(item.targetId); | |||||
} else if(item.targetType === this.todoItemTypeMap.survey) { | |||||
this.$refs.previewSurvey.open(item.surveyId); | |||||
} else if (item.targetType === this.todoItemTypeMap.remind) { | |||||
this.$refs.previewRemind.open(item.targetId) | |||||
} | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.todo-selector { | |||||
max-width: 1000px; | |||||
.tree-menus { | |||||
border: 1px solid #dfe4ed; | |||||
height: 200px; | |||||
border-radius: 4px; | |||||
overflow-y: auto; | |||||
} | |||||
.footer { | |||||
text-align: center; | |||||
} | |||||
} | |||||
</style> |
@@ -1,225 +0,0 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<el-card v-show="!visiable" class="card" :body-style="{ height: '100%', maxWidth: '1000px' }"> | |||||
<div class="main"> | |||||
<div class="form" v-show="step === 1"> | |||||
<BaseForm ref="form" :isPreview="isPreview"/> | |||||
</div> | |||||
<template v-if="step === 2"> | |||||
<el-form> | |||||
<el-form-item label="随访任务" prop="tasks" required> | |||||
<span style="color: #f56c6c; font-size: 12px"> | |||||
单个任务最多添加10个待办事项(5篇患教文章+5个随访问卷) | |||||
</span> | |||||
</el-form-item> | |||||
</el-form> | |||||
<el-card class="tasks"> | |||||
<FollowTaskSetting :maxDays="maxDays" :isPreview="isPreview" v-model="tasks" @selectTodo="handleSelectTodo" /> | |||||
</el-card> | |||||
</template> | |||||
</div> | |||||
<div class="footer"> | |||||
<el-button @click="handleBack">取消</el-button> | |||||
<el-button key="next" type="primary" v-if="step === 1" @click="handleNextStep"> | |||||
下一步 | |||||
</el-button> | |||||
<template v-else> | |||||
<el-button key="prev" type="warning" @click="handlePrevStep" plain>上一步</el-button> | |||||
<template v-if="!isPreview"><!--非预览展示操作按钮--> | |||||
<el-button type="primary" @click="handleSaveDrafts" plain>保存草稿</el-button> | |||||
<el-button type="primary" @click="handleSubmit">提交</el-button> | |||||
</template> | |||||
</template> | |||||
</div> | |||||
</el-card> | |||||
<el-collapse-transition> | |||||
<TodoItemSelector ref="todoSelector" :form="formData" /> | |||||
</el-collapse-transition> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { addFollowUpPlan, updateFollowUpPlan, getPlanDetail } from "@/api/hospital"; | |||||
import BaseForm from "./components/BaseForm"; | |||||
import TodoItemSelector from "./components/TodoItemSelector"; | |||||
import FollowTaskSetting from "./components/FollowTaskSetting"; | |||||
export default { | |||||
name: "AddPlan", | |||||
enums: ["periodUnitMap", "surveyTempMap"], | |||||
components: { | |||||
BaseForm, | |||||
FollowTaskSetting, | |||||
TodoItemSelector, | |||||
}, | |||||
data() { | |||||
return { | |||||
step: 1, | |||||
formData: {}, | |||||
tasks: [], | |||||
maxDays: 0, // 随访周期 | |||||
editId: this.$route.params.id, | |||||
isPreview: this.$route.params.isPreview, // 预览标记 'preview' | |||||
visiable: false, | |||||
}; | |||||
}, | |||||
created() { | |||||
if (this.editId) { | |||||
this.getDetail(); | |||||
} | |||||
}, | |||||
computed: { | |||||
saveParams() { | |||||
return { | |||||
...this.formData, | |||||
followTaskTemplates: this.tasks.map((task, index) => { | |||||
return { | |||||
...task, | |||||
batchNo: index + 1, | |||||
items: task.items.map((item, i) => { | |||||
return { | |||||
...item, | |||||
serialNo: i + 1, | |||||
}; | |||||
}), | |||||
}; | |||||
}), | |||||
}; | |||||
}, | |||||
}, | |||||
methods: { | |||||
getDetail() { | |||||
getPlanDetail(this.editId).then((res) => { | |||||
const { taskList, ...params } = res.data; | |||||
this.tasks = taskList; | |||||
this.$refs.form.init(params); | |||||
}); | |||||
}, | |||||
// 取消 | |||||
handleBack() { | |||||
this.$tab.closePage(undefined, { name: "PlanManage" }); | |||||
}, | |||||
// 上一步 | |||||
handlePrevStep() { | |||||
this.step = 1; | |||||
}, | |||||
// 下一步 | |||||
handleNextStep() { | |||||
this.$refs.form.submit().then((data) => { | |||||
this.formData = { ...data }; | |||||
this.maxDays = this.getDays(this.formData.periodNumber, this.formData.periodUnit); | |||||
this.step = 2; | |||||
}); | |||||
}, | |||||
// 选择待办事项 | |||||
handleSelectTodo(index) { | |||||
const curTask = this.tasks[index]; | |||||
this.visiable = true; | |||||
this.$refs.todoSelector | |||||
.open(curTask.items) | |||||
.then((items) => { | |||||
this.tasks.splice(index, 1, { | |||||
...curTask, | |||||
items, | |||||
}); | |||||
this.visiable = false; | |||||
}) | |||||
.catch(() => { | |||||
this.visiable = false; | |||||
}); | |||||
}, | |||||
validate() { | |||||
if (this.tasks.length === 0) { | |||||
this.$message.error("随访任务不能为空"); | |||||
return false; | |||||
} | |||||
let preTime = 0; | |||||
for (const [index, task] of this.tasks.entries()) { | |||||
if (typeof task.lagNumber !== "number") { | |||||
this.$message.error(`第${index + 1}次随访任务[基线时间+]未选择`); | |||||
return false; | |||||
} | |||||
if (task.items.length === 0) { | |||||
this.$message.error(`第${index + 1}次随访任务未添加待办事项`); | |||||
return false; | |||||
} | |||||
if (task.lagNumber < preTime) { | |||||
this.$message.error( | |||||
`第${index + 1}次随访任务[基线时间+]不能小于${index === 0 ? "0" : "前一次"}` | |||||
); | |||||
return false; | |||||
} | |||||
preTime = task.lagNumber; | |||||
if (task.lagNumber >= this.maxDays) { | |||||
this.$message.error(`随访任务[基线时间+]超过了随访总周期`); | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
}, | |||||
getDays(periodNumber, periodUnit) { | |||||
switch (periodUnit) { | |||||
case this.periodUnitMap.day: | |||||
return periodNumber; | |||||
break; | |||||
case this.periodUnitMap.month: | |||||
return periodNumber * 30; | |||||
break; | |||||
case this.periodUnitMap.year: | |||||
return periodNumber * 30 * 12; | |||||
break; | |||||
} | |||||
}, | |||||
// 保存草稿 | |||||
handleSaveDrafts() { | |||||
this.save(this.surveyTempMap.drafts); | |||||
}, | |||||
// 提交 | |||||
handleSubmit() { | |||||
this.save(this.surveyTempMap.save); | |||||
}, | |||||
async save(status) { | |||||
if (!this.validate()) return; | |||||
const api = this.editId ? updateFollowUpPlan : addFollowUpPlan; | |||||
const res = await api({ | |||||
...this.saveParams, | |||||
id: this.editId, | |||||
status, | |||||
}); | |||||
// 保存成功页面不跳转,再次保存即编辑 | |||||
if (!this.editId) { | |||||
this.editId = res.data.id; | |||||
} | |||||
if (status === this.surveyTempMap.save) { | |||||
this.$message.success("提交成功"); | |||||
this.handleBack(); | |||||
} else { | |||||
this.$message.success("保存成功"); | |||||
} | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.app-container { | |||||
height: 100%; | |||||
.card { | |||||
height: 100%; | |||||
} | |||||
.main { | |||||
height: calc(100% - 100px); | |||||
.tasks { | |||||
height: calc(100% - 50px); | |||||
overflow-y: auto; | |||||
::v-deep .el-step__description { | |||||
padding-right: 0 !important; | |||||
} | |||||
} | |||||
} | |||||
.footer { | |||||
margin-top: 50px; | |||||
text-align: center; | |||||
} | |||||
} | |||||
</style> |
@@ -1,274 +0,0 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"> | |||||
<el-form-item label="模板状态" prop="status"> | |||||
<el-select v-model="queryParams.status" clearable style="width: 240px"> | |||||
<el-option v-for="dict in surveyTempEnum.options" :key="dict.value" :label="dict.label" :value="dict.value" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item label="随访周期" prop="status"> | |||||
<PeriodSelector clearable style="width: 240px" defaultUnit="" | |||||
:value="{ quantity: queryParams.periodNumber, unit: queryParams.periodUnit }" @change=" | |||||
queryParams.periodNumber = $event.quantity; | |||||
queryParams.periodUnit = $event.unit; | |||||
" /> | |||||
</el-form-item> | |||||
<el-form-item label="应用科室" prop="deptIds"> | |||||
<TreeDept v-model="queryParams.deptIds" clearable style="width: 240px" :props="{ emitPath: true }" | |||||
@change="queryParams.labelId = ''" /> | |||||
</el-form-item> | |||||
<el-form-item label="应用疾病" prop="labelId"> | |||||
<el-select v-model="queryParams.labelId" filterable clearable style="width: 240px"> | |||||
<el-option v-for="item in diseaseList" :key="item.id" :label="item.name" :value="item.id" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item label="模板名称" prop="name"> | |||||
<el-input v-model="queryParams.name" placeholder="请输入模板名称" clearable style="width: 240px" | |||||
@keyup.enter.native="handleQuery" /> | |||||
</el-form-item> | |||||
<el-form-item label="是否自动匹配" prop="isMatch"> | |||||
<el-select v-model="queryParams.isMatch" placeholder="请选择" clearable style="width: 240px"> | |||||
<el-option label="是" :value="1"></el-option> | |||||
<el-option label="否" :value="0"></el-option> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item> | |||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"> | |||||
搜索 | |||||
</el-button> | |||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |||||
</el-form-item> | |||||
</el-form> | |||||
<div style="display: flex;justify-content: flex-end;padding-bottom: 8px;"> | |||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"> | |||||
新增模板 | |||||
</el-button> | |||||
<el-button :disabled="selectDatas.length <= 0" type="success" plain icon="el-icon-upload2" size="mini" | |||||
@click="handlePublish" v-loading="isPublishLoading">发布模板</el-button> | |||||
</div> | |||||
<el-table v-loading="loading" :data="pageList" border @selection-change="selectionChange"> | |||||
<el-table-column type="selection" width="55" align="center" :selectable="isSelectable"></el-table-column> | |||||
<el-table-column align="center" label="序号" type="index" | |||||
:index="(index) => (queryParams.pageNum - 1) * queryParams.pageSize + index + 1" width="120" /> | |||||
<el-table-column align="center" label="随访模板名称" prop="name" :show-overflow-tooltip="true" | |||||
:class-name="'column-style-cursor'"> | |||||
<template slot-scope="scope"> | |||||
<div @click="setPreviewTemplate(scope.row)">{{ scope.row.name }}</div> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" label="随访模板ID" prop="id" :show-overflow-tooltip="true" /> | |||||
<el-table-column align="center" label="应用疾病" prop="labelName" :show-overflow-tooltip="true" /> | |||||
<el-table-column align="center" label="应用科室" prop="deptName" :show-overflow-tooltip="true" /> | |||||
<el-table-column align="center" label="随访周期" prop="deptName" :show-overflow-tooltip="true"> | |||||
<template slot-scope="scope"> | |||||
{{ scope.row.periodNumber + periodUnitEnum.getLabel(scope.row.periodUnit) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" label="随访模板状态" prop="status" :show-overflow-tooltip="true"> | |||||
<template slot-scope="scope"> | |||||
<span :style="{ color: surveyTempEnum.enum[scope.row.status].color }"> | |||||
{{ surveyTempEnum.getLabel(scope.row.status) }} | |||||
</span> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" label="是否自动匹配" prop="isMatch"> | |||||
<template slot-scope="scope"> | |||||
{{ scope.row.isMatch === 1 ? '是' : '否' }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" label="随访单数" prop="followupDocumentSize" :show-overflow-tooltip="true" /> | |||||
<el-table-column align="center" label="操作" class-name="small-padding fixed-width" fixed="right"> | |||||
<template slot-scope="scope"> | |||||
<el-button size="mini" type="text" @click="handleSwitchStatus(scope.row)" | |||||
:disabled="scope.row.status === surveyTempMap.drafts" | |||||
:class="[scope.row.status === surveyTempMap.online ? 'yellow-button' : 'green-button']"> | |||||
{{ scope.row.status === surveyTempMap.online ? "下线" : "发布" }} | |||||
</el-button> | |||||
<el-button size="mini" type="text" @click="handleEdit(scope.row)" | |||||
:disabled="scope.row.status === surveyTempMap.online"> | |||||
编辑 | |||||
</el-button> | |||||
<el-button size="mini" type="text" @click="handleDelete(scope.row)" | |||||
:disabled="scope.row.status === surveyTempMap.online" class="red-button"> | |||||
删除 | |||||
</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<pagination v-show="total > 0" :total="total" :sizes="[10]" :page.sync="queryParams.pageNum" | |||||
:limit.sync="queryParams.pageSize" @pagination="getList" /> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import ApiButton from "@/components/ApiButton/index.vue"; | |||||
import TreeDept from "@/components/TreeDept"; | |||||
import { | |||||
followUpPlanPageList, | |||||
delFollowUpPlan, | |||||
getMedicalLabel, | |||||
switchPlanStatus, | |||||
publishFollowUpPlanApi | |||||
} from "@/api/hospital"; | |||||
import PeriodSelector from "../addPlan/components/PeriodSelector"; | |||||
import { surveyTempMap } from "@/constant"; | |||||
export default { | |||||
name: "PlanManage", | |||||
enums: ["surveyTempMap", "surveyTempEnum", "periodUnitEnum"], | |||||
components: { | |||||
ApiButton, | |||||
PeriodSelector, | |||||
TreeDept, | |||||
}, | |||||
data() { | |||||
return { | |||||
// 遮罩层 | |||||
loading: true, | |||||
// 显示搜索条件 | |||||
showSearch: true, | |||||
// 总条数 | |||||
total: 0, | |||||
// 日期范围 | |||||
dateRange: [], | |||||
// 查询参数 | |||||
queryParams: { | |||||
pageNum: 1, | |||||
pageSize: 10, | |||||
status: "", | |||||
labelId: "", | |||||
deptIds: [], | |||||
periodNumber: "", | |||||
periodUnit: "", | |||||
name: "", | |||||
isMatch: null | |||||
}, | |||||
pageList: [], | |||||
diseaseList: [], | |||||
selectDatas: [], | |||||
isPublishLoading: false | |||||
}; | |||||
}, | |||||
created() { | |||||
this.loadData(); | |||||
}, | |||||
activated() { | |||||
this.loadData(); | |||||
}, | |||||
watch: { | |||||
"queryParams.deptIds"(val) { | |||||
const deptId = val[1] || val[0]; | |||||
if (deptId) { | |||||
this.loadDisease(deptId); | |||||
} else { | |||||
this.diseaseList = []; | |||||
} | |||||
}, | |||||
}, | |||||
methods: { | |||||
isSelectable(row, index) { | |||||
return ![surveyTempMap.online, surveyTempMap.drafts].includes(row.status); | |||||
}, | |||||
selectionChange(value) { | |||||
this.selectDatas = value || []; | |||||
}, | |||||
async handlePublish() { | |||||
this.isPublishLoading = true; | |||||
const ids = this.selectDatas.map(item => item.id); | |||||
try { | |||||
await publishFollowUpPlanApi(ids) | |||||
this.$message.success("发布成功!") | |||||
this.getList(); | |||||
} catch (err) { | |||||
console.log("err=", err); | |||||
} finally { | |||||
this.isPublishLoading = false; | |||||
} | |||||
}, | |||||
loadData() { | |||||
this.getList(); | |||||
}, | |||||
getList() { | |||||
this.loading = true; | |||||
followUpPlanPageList(this.addDateRange(this.queryParams, this.dateRange)) | |||||
.then((res) => { | |||||
const { data: { list, page } } = res | |||||
this.pageList = list || []; | |||||
this.total = Number(page.total) || 0; | |||||
}) | |||||
.finally(() => { | |||||
this.loading = false; | |||||
}); | |||||
}, | |||||
async loadDisease(deptId) { | |||||
const res = await getMedicalLabel({ deptId }); | |||||
this.diseaseList = res.data; | |||||
}, | |||||
// 表单重置 | |||||
reset() { | |||||
this.resetForm("form"); | |||||
}, | |||||
/** 搜索按钮操作 */ | |||||
handleQuery() { | |||||
this.queryParams.pageNum = 1; | |||||
this.getList(); | |||||
}, | |||||
/** 重置按钮操作 */ | |||||
resetQuery() { | |||||
this.dateRange = []; | |||||
this.resetForm("queryForm"); | |||||
this.handleQuery(); | |||||
}, | |||||
/** 新增患者 */ | |||||
handleAdd() { | |||||
this.$router.push({ name: "AddPlan" }); | |||||
}, | |||||
/*预览模版 预览标记 'preview'*/ | |||||
setPreviewTemplate(item) { | |||||
this.$router.push({ name: "EditPlan", params: { id: item.id, isPreview: 'preview' } }); | |||||
}, | |||||
/** 编辑 */ | |||||
handleEdit(item) { | |||||
this.$router.push({ name: "EditPlan", params: { id: item.id } }); | |||||
}, | |||||
// 发布下线 | |||||
handleSwitchStatus(item) { | |||||
const isOnline = item.status === this.surveyTempMap.online; | |||||
const fetch = async () => { | |||||
await switchPlanStatus(item.id); | |||||
this.$message.success("操作成功"); | |||||
this.getList(); | |||||
}; | |||||
if (isOnline) { | |||||
this.$modal | |||||
.confirm(`是否确认下线?`) | |||||
.then(fetch) | |||||
.catch(() => { }); | |||||
} else { | |||||
fetch(); | |||||
} | |||||
}, | |||||
handleDelete(item) { | |||||
this.$modal | |||||
.confirm("是否确认删除?") | |||||
.then(async () => { | |||||
await delFollowUpPlan(item.id); | |||||
this.$message.success("操作成功"); | |||||
this.getList(); | |||||
}) | |||||
.catch(() => { }); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped></style> |
@@ -1,196 +0,0 @@ | |||||
<template> | |||||
<el-dialog :title="showTitle" :visible="visible" width="600px" center :before-close="onClose"> | |||||
<el-form :model="formData" :disabled="isLoading" ref="formRef" :rules="formRules" label-width="120px"> | |||||
<el-form-item label="应用科室:" prop="deptId"> | |||||
<TreeDept v-model="formData.deptId" clearable style="width: 100%" :options="deptList" :autoFetch="false" | |||||
:props="{ emitPath: false }" placeholder="请选择应用科室" @change="onChangeDept" /> | |||||
</el-form-item> | |||||
<el-form-item label="应用疾病:" prop="labelId"> | |||||
<el-select v-model="formData.labelId" placeholder="请选择应用疾病" filterable clearable> | |||||
<el-option v-for="item in diseaseList" :key="item.id" :label="item.name" :value="item.id" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item label="提醒类型:" prop="categoryId"> | |||||
<el-select v-model="formData.categoryId" placeholder="请选择提醒类型" filterable clearable> | |||||
<el-option v-for="item in categoryList" :key="item.id" :label="item.name" :value="item.id"></el-option> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item label="提醒名称" prop="name"> | |||||
<el-input v-model.trim="formData.name" type="textarea" placeholder="请输入提醒名称" maxlength="30" resize="none" show-word-limit /> | |||||
</el-form-item> | |||||
<el-form-item label="提醒内容:" prop="remark"> | |||||
<el-input v-model.trim="formData.remark" type="textarea" placeholder="请输入提醒内容" maxlength="30" resize="none" show-word-limit/> | |||||
</el-form-item> | |||||
</el-form> | |||||
<span slot="footer" class="dialog-footer"> | |||||
<el-button :disabled="isLoading" @click="onClose">取 消</el-button> | |||||
<el-button type="primary" @click="onSubmit">确 定</el-button> | |||||
</span> | |||||
</el-dialog> | |||||
</template> | |||||
<script> | |||||
import { updateRemindTemplateApi } from '@/api/hospital/remindManage/remindList' | |||||
import { getClientId } from '@/utils/auth' | |||||
import TreeDept from "@/components/TreeDept"; | |||||
import { getTreeHospDeptByPatient } from "@/api/admin"; | |||||
import { getMedicalLabel } from "@/api/hospital"; | |||||
import { getReminderListApi } from '@/api/common/dictManage/reminder' | |||||
export default { | |||||
name: 'AddDialog', | |||||
components: { | |||||
TreeDept | |||||
}, | |||||
computed: { | |||||
showTitle() { | |||||
return this.formData.id ? '编辑提醒' : '新增提醒' | |||||
} | |||||
}, | |||||
data() { | |||||
return { | |||||
visible: false, | |||||
deptList: [], | |||||
diseaseList: [], | |||||
categoryList: [], | |||||
formData: { | |||||
id: undefined, | |||||
deptId: '', | |||||
labelId: null, | |||||
categoryId: null, | |||||
remark: null, | |||||
name: '' | |||||
}, | |||||
formRules: { | |||||
deptId: [ | |||||
{ | |||||
required: true, | |||||
message: '请选择应用科室', | |||||
trigger: ['blur', 'change'] | |||||
} | |||||
], | |||||
labelId: [ | |||||
{ | |||||
required: true, | |||||
message: '请选择应用疾病 ', | |||||
trigger: ['blur', 'change'] | |||||
} | |||||
], | |||||
categoryId: [ | |||||
{ | |||||
required: true, | |||||
message: '请选择提醒类型 ', | |||||
trigger: ['blur', 'change'] | |||||
} | |||||
], | |||||
name: [ | |||||
{ | |||||
required: true, | |||||
message: '请输入提醒名称', | |||||
trigger: ['blur', 'change'] | |||||
} | |||||
], | |||||
remark: [ | |||||
{ | |||||
required: true, | |||||
message: '请输入提醒内容', | |||||
trigger: ['blur', 'change'] | |||||
} | |||||
] | |||||
}, | |||||
isLoading: false | |||||
} | |||||
}, | |||||
methods: { | |||||
/*获取科室数据*/ | |||||
async getDeptList() { | |||||
const res = await getTreeHospDeptByPatient(); | |||||
this.deptList = res.data || []; | |||||
}, | |||||
// 获取病种数据 | |||||
async loadMedicalLabel() { | |||||
const { deptId } = this.formData | |||||
const res = await getMedicalLabel({ | |||||
deptId, | |||||
}); | |||||
this.diseaseList = res.data || []; | |||||
}, | |||||
// 获取提醒分类列表 | |||||
async getRemindTypeList() { | |||||
const { data: { list } } = await getReminderListApi({ | |||||
pageNum: 1, | |||||
pageSize: 1000, | |||||
clientId: getClientId() | |||||
}) | |||||
this.categoryList = list || [] | |||||
}, | |||||
loadOptions() { | |||||
this.getDeptList() | |||||
this.loadMedicalLabel() | |||||
this.getRemindTypeList() | |||||
}, | |||||
onChangeDept() { | |||||
this.formData.labelId = null; | |||||
this.loadMedicalLabel(); | |||||
}, | |||||
openDialog(initData) { | |||||
if (initData) { | |||||
const { id, deptId, labelId, categoryId,remark, name } = initData | |||||
console.log('initData=', initData) | |||||
this.formData = { | |||||
id, | |||||
deptId, | |||||
labelId, | |||||
categoryId, | |||||
remark, | |||||
name | |||||
} | |||||
} | |||||
this.loadOptions() | |||||
this.visible = true | |||||
}, | |||||
onClose() { | |||||
this.formData = { | |||||
id: undefined, | |||||
deptId: '', | |||||
labelId: null, | |||||
categoryId: null, | |||||
remark: null, | |||||
name: '' | |||||
} | |||||
this.$nextTick(() => { | |||||
this.$refs.formRef.clearValidate() | |||||
}) | |||||
console.log('formData=', this.formData) | |||||
this.visible = false | |||||
}, | |||||
onSubmit() { | |||||
this.$refs.formRef.validate(async isValid => { | |||||
if (!isValid) { | |||||
return | |||||
} | |||||
const { deptId } = this.formData | |||||
try { | |||||
this.isLoading = true | |||||
await updateRemindTemplateApi({ | |||||
...this.formData, | |||||
deptId, | |||||
clientId: getClientId() | |||||
}) | |||||
this.$message.success('操作成功') | |||||
this.onClose() | |||||
this.$emit('onOk') | |||||
} catch (err) { | |||||
console.log(err) | |||||
} finally { | |||||
this.isLoading = false | |||||
} | |||||
}) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.el-select { | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -1,235 +0,0 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<el-form size="small" label-width="70px" class="mb8"> | |||||
<el-row :gutter="10"> | |||||
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="4"> | |||||
<el-form-item label="应用科室"> | |||||
<TreeDept | |||||
v-model="formParams.deptId" | |||||
clearable | |||||
style="width: 100%" | |||||
:options="deptList" | |||||
:autoFetch="false" | |||||
:props="{ emitPath: false }" | |||||
@change="onChangeDept" | |||||
/> | |||||
<!-- <el-select v-model="formParams.deptId" placeholder="请选择应用科室"></el-select> --> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="4"> | |||||
<el-form-item label="应用疾病"> | |||||
<el-select | |||||
v-model="formParams.labelId" | |||||
placeholder="请选择应用疾病" | |||||
filterable | |||||
clearable | |||||
> | |||||
<el-option | |||||
v-for="item in diseaseList" | |||||
:key="item.id" | |||||
:label="item.name" | |||||
:value="item.id" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="4"> | |||||
<el-form-item label="提醒类型"> | |||||
<el-select | |||||
v-model="formParams.categoryId" | |||||
placeholder="请选择提醒类型" | |||||
filterable | |||||
clearable | |||||
> | |||||
<el-option | |||||
v-for="item in categoryList" | |||||
:key="item.id" | |||||
:label="item.name" | |||||
:value="item.id" | |||||
></el-option> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="4"> | |||||
<el-form-item label="提醒名称"> | |||||
<el-input v-model="formParams.name" placeholder="请输入提醒名称" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :xs="12" :sm="6" :md="6" :lg="4" :xl="4"> | |||||
<el-button | |||||
type="primary" | |||||
icon="el-icon-search" | |||||
size="mini" | |||||
@click="onSearch" | |||||
:disabled="loading" | |||||
> | |||||
搜索 | |||||
</el-button> | |||||
<el-button icon="el-icon-refresh" size="mini" :disabled="loading" @click="handleReset"> | |||||
重置 | |||||
</el-button> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<div style="display: flex; justify-content: flex-end; padding-bottom: 8px"> | |||||
<el-button icon="el-icon-plus" type="primary" size="mini" plain @click="onAdd"> | |||||
新增提醒 | |||||
</el-button> | |||||
</div> | |||||
<el-table v-loading="loading" align="center" :data="tableData"> | |||||
<el-table-column type="index" label="序号" width="100px" align="center"></el-table-column> | |||||
<el-table-column label="提醒名称" align="center" prop="name"></el-table-column> | |||||
<el-table-column label="提醒类型" align="center" prop="categoryName"></el-table-column> | |||||
<el-table-column | |||||
label="最后编辑时间" | |||||
align="center" | |||||
prop="updateTime" | |||||
min-width="160px" | |||||
></el-table-column> | |||||
<el-table-column label="应用科室" align="center" prop="deptName"></el-table-column> | |||||
<el-table-column label="应用疾病" align="center" prop="labelName"></el-table-column> | |||||
<el-table-column label="操作" align="center" fixed="right"> | |||||
<template slot-scope="{ row }"> | |||||
<el-button size="mini" type="text" @click="onEdit(row)">编辑</el-button> | |||||
<el-button size="mini" type="text" @click="onDel(row)">删除</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<pagination | |||||
:total="pageable.total" | |||||
:page.sync="pageable.pageNum" | |||||
:limit.sync="pageable.pageSize" | |||||
@pagination="getList" | |||||
/> | |||||
<AddDialog ref="dialogRef" @onOk="onOk" /> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { TableMixin } from "@/mixins/tableMixin2"; | |||||
import { | |||||
remindTemplateListApi, | |||||
deleteRemindTemplateApi, | |||||
} from "@/api/hospital/remindManage/remindList"; | |||||
import AddDialog from "./components/addDialog/index.vue"; | |||||
import TreeDept from "@/components/TreeDept"; | |||||
import { getTreeHospDeptByPatient } from "@/api/admin"; | |||||
import { getReminderListApi } from "@/api/common/dictManage/reminder"; | |||||
import { getMedicalLabel } from "@/api/hospital"; | |||||
import { getClientId } from "@/utils/auth"; | |||||
export default { | |||||
name: "RemindManage", | |||||
components: { | |||||
AddDialog, | |||||
TreeDept, | |||||
}, | |||||
mixins: [TableMixin], | |||||
data() { | |||||
return { | |||||
apiMethod: remindTemplateListApi, | |||||
formParams: { | |||||
deptId: "", | |||||
labelId: null, | |||||
categoryId: null, | |||||
name: "", | |||||
}, | |||||
deptList: [], | |||||
diseaseList: [], | |||||
categoryList: [], | |||||
}; | |||||
}, | |||||
methods: { | |||||
/*获取科室数据*/ | |||||
async getDeptList() { | |||||
const res = await getTreeHospDeptByPatient(); | |||||
this.deptList = res.data || []; | |||||
}, | |||||
// 获取病种数据 | |||||
async loadMedicalLabel() { | |||||
const { deptId } = this.formParams; | |||||
const res = await getMedicalLabel({ | |||||
deptId, | |||||
}); | |||||
this.diseaseList = res.data || []; | |||||
}, | |||||
// 获取提醒分类列表 | |||||
async getRemindTypeList() { | |||||
const { | |||||
data: { list }, | |||||
} = await getReminderListApi({ | |||||
pageNum: 1, | |||||
pageSize: 1000, | |||||
clientId: getClientId(), | |||||
}); | |||||
this.categoryList = list || []; | |||||
}, | |||||
loadOptions() { | |||||
this.getDeptList(); | |||||
this.loadMedicalLabel(); | |||||
this.getRemindTypeList(); | |||||
}, | |||||
onChangeDept() { | |||||
this.formParams.labelId = null; | |||||
this.loadMedicalLabel(); | |||||
}, | |||||
paramsCallback() { | |||||
const { deptId, labelId, categoryId, name } = this.formParams; | |||||
return { | |||||
pageNum: this.pageable.pageNum, | |||||
pageSize: this.pageable.pageSize, | |||||
deptId, | |||||
labelId, | |||||
categoryId, | |||||
name, | |||||
}; | |||||
}, | |||||
onAdd() { | |||||
this.$nextTick(() => { | |||||
this.$refs.dialogRef.openDialog(); | |||||
}); | |||||
}, | |||||
onEdit(row) { | |||||
this.$nextTick(() => { | |||||
this.$refs.dialogRef.openDialog(row); | |||||
}); | |||||
}, | |||||
onDel(row) { | |||||
this.$modal.confirm("是否确认删除?").then(async () => { | |||||
await deleteRemindTemplateApi({ id: row.id }); | |||||
this.$message.success("操作成功"); | |||||
this.pageable.pageNum = 1; | |||||
this.getList(); | |||||
}); | |||||
}, | |||||
onOk() { | |||||
this.pageable.pageNum = 1; | |||||
this.formParams = { | |||||
deptId: "", | |||||
labelId: null, | |||||
categoryId: null, | |||||
remark: "", | |||||
name: "", | |||||
}; | |||||
this.getList(); | |||||
}, | |||||
handleReset() { | |||||
this.formParams = { | |||||
deptId: "", | |||||
labelId: null, | |||||
categoryId: null, | |||||
remark: "", | |||||
}; | |||||
this.onSearch(); | |||||
}, | |||||
}, | |||||
mounted() { | |||||
this.loadOptions(); | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.el-select, | |||||
.el-input { | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -1,56 +0,0 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<DWViewer :url="url" @goback="hanldeBack" @publish="hanldePublish" @save="handleSave" @back="handleBack" /> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { publishSurvey, saveSurveyDraft } from "@/api/hospital"; | |||||
import DWViewer from "@/components/DWViewer/index.vue"; | |||||
export default { | |||||
name: "DesignSurvey", | |||||
components: { | |||||
DWViewer, | |||||
}, | |||||
data() { | |||||
return { | |||||
url: `${process.env.VUE_APP_SURVEY_PREFIX}/survey/design-survey.html?surveyId=${this.$route.query.surveyId}`, | |||||
}; | |||||
}, | |||||
methods: { | |||||
// 发布 | |||||
hanldePublish() { | |||||
publishSurvey(this.$route.query.id).then(() => { | |||||
this.$message.success("发布成功"); | |||||
this.hanldeBack(); | |||||
}); | |||||
}, | |||||
// 保存 | |||||
handleSave() { | |||||
setTimeout(() => { | |||||
saveSurveyDraft(this.$route.query.surveyId | |||||
).then(() => { | |||||
this.hanldeBack(); | |||||
}) | |||||
}, 2000) | |||||
}, | |||||
// 返回按钮 | |||||
handleBack() { | |||||
saveSurveyDraft(this.$route.query.surveyId | |||||
).then(() => { | |||||
this.hanldeBack(); | |||||
}) | |||||
}, | |||||
// 返回 | |||||
hanldeBack() { | |||||
this.$tab.closePage(undefined, { name: "SurveyManage" }); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.app-container { | |||||
height: 100%; | |||||
} | |||||
</style> |
@@ -1,140 +0,0 @@ | |||||
<template> | |||||
<Popup ref="popup" title="随访问卷~" @closed="dialogClosed"> | |||||
<el-form :model="form" :rules="rules" ref="form" label-width="80px"> | |||||
<el-form-item label="问卷名称" prop="name"> | |||||
<el-input v-model="form.name" :maxlength="32"></el-input> | |||||
</el-form-item> | |||||
<el-form-item label="应用科室" prop="deptId"> | |||||
<TreeDept :defaultName="defaultDeptName" v-model="form.deptId" | |||||
@change="form.labelId = ''" /> | |||||
</el-form-item> | |||||
<el-form-item label="应用疾病" prop="labelId"> | |||||
<el-select v-model="form.labelId" filterable> | |||||
<el-option v-for="item in diseaseList" :key="item.id" :label="item.name" | |||||
:value="item.id"></el-option> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template slot="footer"> | |||||
<el-button @click="handleCancel">取 消</el-button> | |||||
<el-button type="primary" @click="handleSubmit">下一步</el-button> | |||||
</template> | |||||
</Popup> | |||||
</template> | |||||
<script> | |||||
import Popup from "@/components/Popup"; | |||||
import TreeDept from "@/components/TreeDept"; | |||||
import { addSurvey, editSurvey, getMedicalLabel, copySurvey } from "@/api/hospital"; | |||||
export default { | |||||
components: { | |||||
Popup, | |||||
TreeDept, | |||||
}, | |||||
data() { | |||||
return { | |||||
form: this.getFormDefaultValue(), | |||||
rules: { | |||||
name: [ | |||||
{ required: true, message: "请输入问卷名称", trigger: "blur" }, | |||||
{ max: 32, message: "长度不能超过32个字符", trigger: "blur" }, | |||||
], | |||||
labelId: [{ required: true, message: "请选择应用疾病", trigger: "change" }], | |||||
deptId: [{ required: true, message: "请选择应用疾病", trigger: "change" }], | |||||
}, | |||||
diseaseList: [], | |||||
defaultDeptName: "", | |||||
}; | |||||
}, | |||||
watch: { | |||||
"form.deptId": { | |||||
handler: "loadDisease", | |||||
}, | |||||
}, | |||||
methods: { | |||||
async loadDisease() { | |||||
const res = await getMedicalLabel({ deptId: this.form.deptId || "" }); | |||||
this.diseaseList = res.data || []; | |||||
}, | |||||
getFormDefaultValue() { | |||||
return { | |||||
name: "", | |||||
labelId: "", | |||||
deptId: "", | |||||
}; | |||||
}, | |||||
open(params) { | |||||
if (params) { | |||||
for (const key of [ | |||||
...Object.keys(this.form), | |||||
"id", | |||||
"surveyId", | |||||
"clientId", | |||||
"deptName", | |||||
"labelName", | |||||
"status", | |||||
]) { | |||||
this.form[key] = params[key]; | |||||
this.defaultDeptName = params.deptName || ""; | |||||
} | |||||
} | |||||
this.$refs.popup.open(params); | |||||
this.promise = {}; | |||||
return new Promise((resolve, reject) => { | |||||
this.promise.resolve = resolve; | |||||
this.promise.reject = reject; | |||||
}); | |||||
}, | |||||
handleDeptLevelChange() { | |||||
this.$refs.form.clearValidate(["parentId", "wardId"]); | |||||
}, | |||||
handleCancel() { | |||||
this.$refs.popup.close(); | |||||
}, | |||||
handleSubmit() { | |||||
this.$refs.form.validate(async (valid) => { | |||||
if (valid) { | |||||
this.loading = true; | |||||
try { | |||||
if (this.form.id) { | |||||
await editSurvey(this.form); | |||||
this.$message.success("保存成功"); | |||||
} else if (this.form.surveyId) { | |||||
//没有id但有surveyId,那就是复制 | |||||
const res = await copySurvey(this.form); | |||||
this.form.surveyId = res.data.surveyId; | |||||
this.form.id = res.data.id; | |||||
this.$message.success("复制成功"); | |||||
} else { | |||||
// 新增接口 | |||||
const res = await addSurvey(this.form); | |||||
this.form.surveyId = res.data.surveyId; | |||||
this.form.id = res.data.id; | |||||
this.$message.success("新增成功"); | |||||
} | |||||
this.$router.push({ | |||||
name: "DesignSurvey", | |||||
query: { id: this.form.id, surveyId: this.form.surveyId }, | |||||
}); | |||||
} finally { | |||||
this.loading = false; | |||||
} | |||||
this.$refs.popup.close(); | |||||
this.promise.resolve(); | |||||
} else { | |||||
// 表单校验失败 | |||||
return false; | |||||
} | |||||
}); | |||||
}, | |||||
dialogClosed() { | |||||
this.form = this.getFormDefaultValue(); | |||||
this.$nextTick(this.$refs.form.clearValidate); | |||||
// this.promise.reject(); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> |
@@ -1,284 +0,0 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"> | |||||
<el-form-item label="问卷状态" prop="status"> | |||||
<el-select v-model="queryParams.status" clearable style="width: 240px"> | |||||
<el-option v-for="dict in surveyTempEnum.options" :key="dict.value" :label="dict.label" :value="dict.value" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item label="应用科室" prop="deptIds"> | |||||
<TreeDept v-model="queryParams.deptIds" clearable style="width: 240px" :props="{ emitPath: true }" | |||||
@change="queryParams.labelId = ''" /> | |||||
</el-form-item> | |||||
<el-form-item label="应用疾病" prop="labelId"> | |||||
<el-select v-model="queryParams.labelId" filterable clearable style="width: 240px"> | |||||
<el-option v-for="item in diseaseList" :key="item.id" :label="item.name" :value="item.id" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item label="问卷名称" prop="name"> | |||||
<el-input v-model="queryParams.name" placeholder="请输入问卷名称" clearable style="width: 240px" | |||||
@keyup.enter.native="handleQuery" /> | |||||
</el-form-item> | |||||
<el-form-item> | |||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"> | |||||
搜索 | |||||
</el-button> | |||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |||||
</el-form-item> | |||||
</el-form> | |||||
<div style="display: flex;justify-content: flex-end;padding-bottom: 8px;"> | |||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"> | |||||
新增问卷 | |||||
</el-button> | |||||
<el-button :disabled="selectDatas.length <= 0" type="success" plain icon="el-icon-upload2" size="mini" | |||||
@click="handlePublish" v-loading="isPublishLoading">发布问卷</el-button> | |||||
</div> | |||||
<el-row :gutter="10" class="mb8"> | |||||
<el-col :span="1.5"> | |||||
</el-col> | |||||
</el-row> | |||||
<el-table v-loading="loading" :data="pageList" border @selection-change="selectionChange"> | |||||
<el-table-column type="selection" width="55" align="center" :selectable="isSelectable"></el-table-column> | |||||
<el-table-column align="center" label="序号" type="index" | |||||
:index="(index) => (queryParams.pageNum - 1) * queryParams.pageSize + index + 1" width="120" /> | |||||
<el-table-column align="center" label="随访问卷名称" prop="name" :show-overflow-tooltip="true" | |||||
:class-name="'column-style-cursor'"> | |||||
<template slot-scope="scope"> | |||||
<div @click="setPreview(scope.row)">{{ scope.row.name }}</div> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" label="随访问卷ID" prop="surveyId" :show-overflow-tooltip="true" /> | |||||
<el-table-column align="center" label="最后编辑时间" prop="updateTime" :show-overflow-tooltip="true" /> | |||||
<el-table-column align="center" label="应用疾病" prop="labelName" :show-overflow-tooltip="true" /> | |||||
<el-table-column align="center" label="应用科室" prop="deptName" :show-overflow-tooltip="true" /> | |||||
<el-table-column align="center" label="问卷状态" prop="status" :show-overflow-tooltip="true"> | |||||
<template slot-scope="scope"> | |||||
<span :style="{ color: surveyTempEnum.enum[scope.row.status].color }"> | |||||
{{ surveyTempEnum.getLabel(scope.row.status) }} | |||||
</span> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" label="操作" class-name="small-padding fixed-width" fixed="right"> | |||||
<template slot-scope="scope"> | |||||
<el-button size="mini" type="text" @click="handleSwitchStatus(scope.row)" | |||||
:disabled="scope.row.status === surveyTempMap.drafts" | |||||
:class="[scope.row.status === surveyTempMap.online ? 'yellow-button' : 'green-button']"> | |||||
{{ scope.row.status === surveyTempMap.online ? "下线" : "发布" }} | |||||
</el-button> | |||||
<el-button size="mini" type="text" @click="handleCopy(scope.row)"> | |||||
复制 | |||||
</el-button> | |||||
<el-button size="mini" type="text" @click="handleEdit(scope.row)" | |||||
:disabled="scope.row.status === surveyTempMap.online"> | |||||
编辑 | |||||
</el-button> | |||||
<el-button size="mini" type="text" @click="handleDelete(scope.row)" | |||||
:disabled="scope.row.status === surveyTempMap.online" class="red-button"> | |||||
删除 | |||||
</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" | |||||
@pagination="getList" /> | |||||
<CrudPopup ref="crud" /> | |||||
<SurveyPreviewPopup ref="previewSurvey" /> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import ApiButton from "@/components/ApiButton/index.vue"; | |||||
import TreeDept from "@/components/TreeDept"; | |||||
import { | |||||
surveyPageList, | |||||
delSurvey, | |||||
getMedicalLabel, | |||||
offlineSurvey, | |||||
publishSurvey, | |||||
batchPublishSurveyApi | |||||
} from "@/api/hospital"; | |||||
import { surveyTempMap } from "@/constant"; | |||||
import CrudPopup from "./components/CrudPopup/index.vue"; | |||||
import SurveyPreviewPopup from "../../planManage/addPlan/components/SurveyPreviewPopup"; | |||||
export default { | |||||
name: "SurveyManage", | |||||
enums: ["surveyTempMap", "surveyTempEnum"], | |||||
components: { | |||||
ApiButton, | |||||
CrudPopup, | |||||
TreeDept, | |||||
SurveyPreviewPopup, | |||||
}, | |||||
data() { | |||||
return { | |||||
// 遮罩层 | |||||
loading: true, | |||||
// 显示搜索条件 | |||||
showSearch: true, | |||||
// 总条数 | |||||
total: 0, | |||||
// 日期范围 | |||||
dateRange: [], | |||||
// 查询参数 | |||||
queryParams: { | |||||
pageNum: 1, | |||||
pageSize: 10, | |||||
name: "", | |||||
deptIds: [], | |||||
labelId: "", | |||||
status: "", | |||||
}, | |||||
pageList: [], | |||||
diseaseList: [], | |||||
selectDatas: [], | |||||
isPublishLoading: false | |||||
}; | |||||
}, | |||||
created() { | |||||
this.loadData(); | |||||
}, | |||||
activated() { | |||||
this.loadData(); | |||||
}, | |||||
watch: { | |||||
"queryParams.deptIds"(val) { | |||||
const deptId = val[1] || val[0]; | |||||
if (deptId) { | |||||
this.loadDisease(deptId); | |||||
} else { | |||||
this.diseaseList = []; | |||||
} | |||||
}, | |||||
}, | |||||
methods: { | |||||
isSelectable(row, index) { | |||||
return ![surveyTempMap.online, surveyTempMap.drafts].includes(row.status); | |||||
}, | |||||
selectionChange(value) { | |||||
this.selectDatas = value; | |||||
}, | |||||
async handlePublish() { | |||||
this.isPublishLoading = true; | |||||
const ids = this.selectDatas.map(item => item.id); | |||||
try { | |||||
await batchPublishSurveyApi(ids) | |||||
this.$message.success("发布成功!") | |||||
this.getList(); | |||||
} catch (err) { | |||||
console.log("err=", err); | |||||
} finally { | |||||
this.isPublishLoading = false; | |||||
} | |||||
}, | |||||
// 预览问卷 | |||||
setPreview(item) { | |||||
this.$refs.previewSurvey.open(item.surveyId); | |||||
}, | |||||
loadData() { | |||||
this.getList(); | |||||
}, | |||||
async loadDisease(deptId) { | |||||
const res = await getMedicalLabel({ deptId }); | |||||
this.diseaseList = res.data; | |||||
}, | |||||
/** 查询角色列表 */ | |||||
getList() { | |||||
this.loading = true; | |||||
surveyPageList(this.addDateRange(this.queryParams, this.dateRange)) | |||||
.then((res) => { | |||||
const { data: { list, page } } = res | |||||
this.pageList = list || []; | |||||
this.total = page?.total || 0; | |||||
}) | |||||
.finally(() => { | |||||
this.loading = false; | |||||
}); | |||||
}, | |||||
// 表单重置 | |||||
reset() { | |||||
this.resetForm("form"); | |||||
}, | |||||
/** 搜索按钮操作 */ | |||||
handleQuery() { | |||||
this.queryParams.pageNum = 1; | |||||
this.getList(); | |||||
}, | |||||
/** 重置按钮操作 */ | |||||
resetQuery() { | |||||
this.dateRange = []; | |||||
this.resetForm("queryForm"); | |||||
this.handleQuery(); | |||||
}, | |||||
/** 新增 */ | |||||
handleAdd() { | |||||
this.$refs.crud.open().then(this.getList); | |||||
}, | |||||
/** 编辑 */ | |||||
handleEdit(item) { | |||||
this.$refs.crud.open(item).then(this.getList); | |||||
}, | |||||
/** 复制 */ | |||||
handleCopy(item) { | |||||
this.$refs.crud | |||||
.open({ | |||||
...item, | |||||
name: item.name + " (复制)", | |||||
id: undefined, | |||||
// deptId: item.deptId, | |||||
// deptName: item.deptName, | |||||
// labelId: item.labelId, | |||||
// name: item.name + " (复制)", | |||||
// clientId: item.clientId, | |||||
// surveyId: item.surveyId, | |||||
// labelName: item.labelName, | |||||
// status: item.status, | |||||
}) | |||||
.then(this.getList); | |||||
}, | |||||
// 发布下线 | |||||
handleSwitchStatus(item) { | |||||
const isOnline = item.status === this.surveyTempMap.online; | |||||
const fetch = async () => { | |||||
if (isOnline) { | |||||
await offlineSurvey(item.id); | |||||
} else { | |||||
await publishSurvey(item.id); | |||||
} | |||||
this.$message.success("操作成功"); | |||||
this.getList(); | |||||
}; | |||||
if (isOnline) { | |||||
this.$modal | |||||
.confirm(`是否确认下线?`) | |||||
.then(fetch) | |||||
.catch(() => { }); | |||||
} else { | |||||
fetch(); | |||||
} | |||||
}, | |||||
// 删除 | |||||
handleDelete(item) { | |||||
this.$modal | |||||
.confirm("是否确认删除?") | |||||
.then(async () => { | |||||
await delSurvey(item.id); | |||||
this.$message.success("操作成功"); | |||||
this.getList(); | |||||
}) | |||||
.catch(() => { }); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped></style> |
@@ -1,714 +0,0 @@ | |||||
<template> | |||||
<div> | |||||
<el-dialog | |||||
title="随访计划--添加" | |||||
:visible="showModal" | |||||
:before-close="onBeforeClose" | |||||
width="90%" | |||||
append-to-body | |||||
> | |||||
<div class="step1" v-show="currentStep === 1" key="1"> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<div class="sf-title">报到</div> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<vxe-grid | |||||
ref="xGrid1" | |||||
v-bind="gridConfig1" | |||||
:columns="columns1" | |||||
:proxyConfig="proxyConfig1" | |||||
@radio-change="onChangeDoctor" | |||||
> | |||||
<template #table_create_time="{ row }"> | |||||
{{ row.createTime ? parseTime(row.createTime, "{y}-{m}-{d}") : "" }} | |||||
</template> | |||||
<!-- <template #table_visit_time="{ row }"> | |||||
{{ row.visitTime ? parseTime(row.visitTime, "{y}-{m}-{d}") : "" }} | |||||
</template> --> | |||||
</vxe-grid> | |||||
</el-col> | |||||
</el-row> | |||||
</div> | |||||
<div class="step2" v-show="currentStep === 2" key="2"> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<div class="sf-title">选择随访模板</div> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<vxe-grid | |||||
ref="xGrid2" | |||||
v-bind="gridConfig2" | |||||
:columns="columns2" | |||||
:formConfig="formConfig2" | |||||
:proxyConfig="proxyConfig2" | |||||
> | |||||
<template #form_dept="{ data }"> | |||||
<TreeDept | |||||
v-model="data.deptIds" | |||||
clearable | |||||
style="width: 300px" | |||||
:options="deptOptions" | |||||
:autoFetch="false" | |||||
:props="{ emitPath: true }" | |||||
@change="(val) => onDeptChange(val, data)" | |||||
/> | |||||
</template> | |||||
<template #form_btn_items> | |||||
<vxe-button type="submit" status="primary" content="查询"></vxe-button> | |||||
<vxe-button type="reset" content="重置"></vxe-button> | |||||
</template> | |||||
<template #t_period_default="{ row }"> | |||||
{{ row.periodNumber }}{{ periodUnitEnum.getLabel(row.periodUnit) }} | |||||
</template> | |||||
<template #table_operation="{ row }"> | |||||
<vxe-button type="text" status="primary" @click="onPreview(row)">预览</vxe-button> | |||||
</template> | |||||
</vxe-grid> | |||||
</el-col> | |||||
</el-row> | |||||
</div> | |||||
<div class="step3" v-show="currentStep === 3" key="3"> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<vxe-grid ref="xGrid3" v-bind="gridConfig3" :columns="columns3" :data="step3TableList"> | |||||
<template #table_lagTime="{ row }"> | |||||
{{ row.lagTime }} | |||||
</template> | |||||
<template #table_lagTime_edit="{ row, rowIndex }"> | |||||
<el-date-picker | |||||
transfer | |||||
v-model="row.lagTime" | |||||
value-format="yyyy-MM-dd" | |||||
type="date" | |||||
placeholder="选择日期" | |||||
:picker-options="pickerOptions" | |||||
></el-date-picker> | |||||
</template> | |||||
<template #t_period_default="{ row }"> | |||||
{{ row.periodNumber }}{{ periodUnitEnum.getLabel(row.periodUnit) }} | |||||
</template> | |||||
<template #table_operation="{ row }"> | |||||
<vxe-button type="text" status="primary" @click="onEditPlan(row)">编辑</vxe-button> | |||||
</template> | |||||
</vxe-grid> | |||||
</el-col> | |||||
</el-row> | |||||
</div> | |||||
<div slot="footer" class="dialog-footer"> | |||||
<el-button @click="onLeftBtn">{{ showLeftBtnText }}</el-button> | |||||
<el-button | |||||
type="primary" | |||||
@click="onRightBtn" | |||||
style="margin-left: 20px" | |||||
v-loading="submitting" | |||||
> | |||||
{{ showRightBtnText }} | |||||
</el-button> | |||||
</div> | |||||
</el-dialog> | |||||
<el-dialog title="预览模板事项" :visible.sync="previewVisible" width="90%" append-to-body> | |||||
<FollowTaskSetting | |||||
:maxDays="maxDays" | |||||
v-model="detailTaskList" | |||||
:isPreview="previewVisible" | |||||
></FollowTaskSetting> | |||||
<span slot="footer" class="dialog-footer"> | |||||
<el-button @click="previewVisible = false">取 消</el-button> | |||||
</span> | |||||
</el-dialog> | |||||
<el-dialog | |||||
v-if="editFollowPlanVisible" | |||||
title="随访模板编辑" | |||||
:visible.sync="editFollowPlanVisible" | |||||
width="90%" | |||||
append-to-body | |||||
:before-close="onBeforeCloseEditFollowPlan" | |||||
> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<FollowTaskSetting | |||||
v-show="!visiable" | |||||
:maxDays="maxDays" | |||||
:isPreview="previewVisible" | |||||
v-model="detailTaskList" | |||||
@selectTodo="handleSelectTodo" | |||||
@closeEditDialog="editFollowPlanVisible = false" | |||||
@save="saveItems" | |||||
></FollowTaskSetting> | |||||
<el-collapse-transition> | |||||
<TodoItemSelector ref="todoSelector" :form="formData" :visiable.sycn="visiable"/> | |||||
</el-collapse-transition> | |||||
</el-col> | |||||
</el-row> | |||||
</el-dialog> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { commonGridConfig1 } from "@/config/vxeGrid"; | |||||
import TreeDept from "@/components/TreeDept"; | |||||
import { getTreeHospDeptByPatient } from "@/api/admin"; | |||||
import { getMedicalLabel } from "@/api/hospital"; | |||||
import FollowTaskSetting from "../FollowTaskSetting"; | |||||
import TodoItemSelector from "../TodoItemSelector"; | |||||
import { | |||||
getFollowupReportListAPi, | |||||
submitFollowupPlanApi, | |||||
} from "@/api/hospital/patientManage/followupPatient"; | |||||
import { | |||||
getPlanDetail, | |||||
getFollowupTemplateListApi, | |||||
} from "@/api/hospital/followupManage/followupPlan"; | |||||
export default { | |||||
name: "CreateFollowPlan", | |||||
components: { | |||||
TreeDept, | |||||
FollowTaskSetting, | |||||
TodoItemSelector, | |||||
}, | |||||
props: { | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
}, | |||||
}, | |||||
enums: ["followItemStatusEnum", "periodUnitEnum", "periodUnitMap"], | |||||
computed: { | |||||
showModal: { | |||||
get() { | |||||
return this.visible; | |||||
}, | |||||
set(val) { | |||||
this.$emit("update:visible", val); | |||||
}, | |||||
}, | |||||
showLeftBtnText() { | |||||
if (this.currentStep === 1) { | |||||
return "取 消"; | |||||
} else if ([2, 3].includes(this.currentStep)) { | |||||
return "上一步"; | |||||
} else { | |||||
return "取 消"; | |||||
} | |||||
}, | |||||
showRightBtnText() { | |||||
if (this.currentStep === 1) { | |||||
return "下一步"; | |||||
} else if (this.currentStep === 2) { | |||||
return "下一步"; | |||||
} else { | |||||
return "保 存"; | |||||
} | |||||
}, | |||||
selectReports() { | |||||
return this.$refs?.xGrid1.getRadioRecord(true) || []; | |||||
}, | |||||
selectTemps() { | |||||
return this.$refs?.xGrid2?.getCheckboxRecords(true) || []; | |||||
}, | |||||
}, | |||||
data() { | |||||
return { | |||||
// 当前所处步骤 | |||||
currentStep: 1, | |||||
/** | |||||
* 报到表格配置 | |||||
*/ | |||||
gridConfig1: { | |||||
...commonGridConfig1, | |||||
rowConfig: { | |||||
keyField: "id", | |||||
}, | |||||
radioConfig: { | |||||
reserve: true, | |||||
trigger: "row", | |||||
highlight: true, | |||||
}, | |||||
maxHeight: 600, | |||||
transfer: true, | |||||
pagerConfig: { | |||||
enabled: false, | |||||
}, | |||||
}, | |||||
columns1: [ | |||||
{ | |||||
type: "seq", | |||||
title: "序号", | |||||
width: 60, | |||||
}, | |||||
{ | |||||
field: "deptName", | |||||
title: "科室", | |||||
}, | |||||
{ | |||||
field: "userInfo.userName", | |||||
title: "医生", | |||||
}, | |||||
{ | |||||
field: "createTime", | |||||
title: "报到时间", | |||||
slots: { | |||||
default: "table_create_time", | |||||
}, | |||||
}, | |||||
// { | |||||
// field: "visitTime", | |||||
// title: "就诊时间", | |||||
// slots: { | |||||
// default: "table_visit_time", | |||||
// }, | |||||
// }, | |||||
{ | |||||
type: "radio", | |||||
width: 120, | |||||
fixed: "right", | |||||
}, | |||||
], | |||||
proxyConfig1: { | |||||
response: { | |||||
list: "data", | |||||
}, | |||||
ajax: { | |||||
query: ({ page }) => { | |||||
const { currentPage: pageNum, pageSize } = page; | |||||
console.log("page=", page); | |||||
console.log("执行了"); | |||||
return getFollowupReportListAPi(this.$route.params.id); | |||||
}, | |||||
}, | |||||
}, | |||||
/** | |||||
* 随访模板表格配置 | |||||
*/ | |||||
gridConfig2: { | |||||
...commonGridConfig1, | |||||
rowConfig: { | |||||
keyField: "id", | |||||
}, | |||||
checkboxConfig: { | |||||
showHeader: false, | |||||
keyField: "id", | |||||
reserve: true, | |||||
trigger: "row", | |||||
highlight: true, | |||||
checkMethod: ({ row }) => { | |||||
return ( | |||||
this.selectTemps.length < 5 || | |||||
this.selectTemps.findIndex((item) => item.id === row.id) >= 0 | |||||
); | |||||
}, | |||||
}, | |||||
maxHeight: 600, | |||||
}, | |||||
formConfig2: { | |||||
titleWidth: 90, | |||||
titleAlign: "right", | |||||
titleColon: true, | |||||
items: [ | |||||
{ | |||||
field: "deptId", | |||||
title: "科室", | |||||
itemRender: {}, | |||||
slots: { | |||||
default: "form_dept", | |||||
}, | |||||
}, | |||||
{ | |||||
field: "labelId", | |||||
title: "应用疾病", | |||||
itemRender: { | |||||
name: "VxeSelect", | |||||
options: [], | |||||
props: { | |||||
clearable: true, | |||||
placeholder: "请选择应用疾病", | |||||
transfer: true, | |||||
}, | |||||
optionProps: { | |||||
value: "id", | |||||
label: "name", | |||||
}, | |||||
}, | |||||
}, | |||||
{ | |||||
field: "name", | |||||
title: "模板名称", | |||||
itemRender: { | |||||
name: "VxeInput", | |||||
props: { | |||||
clearable: true, | |||||
placeholder: "请选择模板名称", | |||||
style: "width: 300px", | |||||
}, | |||||
}, | |||||
}, | |||||
{ itemRender: {}, slots: { default: "form_btn_items" } }, | |||||
], | |||||
}, | |||||
columns2: [ | |||||
{ | |||||
field: "name", | |||||
title: "随访模板名称", | |||||
}, | |||||
{ | |||||
field: "wardName", | |||||
title: "院区", | |||||
}, | |||||
{ | |||||
field: "labelName", | |||||
title: "应用疾病", | |||||
}, | |||||
{ | |||||
field: "deptName", | |||||
title: "科室", | |||||
}, | |||||
{ | |||||
field: "periodNumber", | |||||
title: "随访周期", | |||||
slots: { | |||||
default: "t_period_default", | |||||
}, | |||||
}, | |||||
{ | |||||
field: "operation", | |||||
title: "操作", | |||||
slots: { | |||||
default: "table_operation", | |||||
}, | |||||
}, | |||||
{ | |||||
type: "checkbox", | |||||
}, | |||||
], | |||||
proxyConfig2: { | |||||
form: true, | |||||
response: { | |||||
result: "data.list", | |||||
total: "data.page.total", | |||||
}, | |||||
ajax: { | |||||
query: async ({ form, page }) => { | |||||
const { deptIds, labelId, name } = form; | |||||
const { currentPage: pageNum, pageSize } = page; | |||||
console.log("form=", form); | |||||
console.log("page=", page); | |||||
const queryParams = { | |||||
status: 2, | |||||
deptIds, | |||||
labelId, | |||||
name, | |||||
pageNum, | |||||
pageSize, | |||||
}; | |||||
return getFollowupTemplateListApi(queryParams); | |||||
}, | |||||
}, | |||||
}, | |||||
// 科室下拉框数据 | |||||
deptOptions: [], | |||||
// 预览弹窗控制 | |||||
previewVisible: false, | |||||
maxDays: 0, | |||||
detailTaskList: [], | |||||
/** | |||||
* 随访模板基线 | |||||
*/ | |||||
gridConfig3: { | |||||
...commonGridConfig1, | |||||
// editConfig: { | |||||
// trigger: 'click', | |||||
// mode: 'row' | |||||
// }, | |||||
maxHeight: 600, | |||||
}, | |||||
columns3: [ | |||||
{ | |||||
field: "name", | |||||
title: "随访模板名称", | |||||
}, | |||||
{ | |||||
field: "wardName", | |||||
title: "院区", | |||||
}, | |||||
{ | |||||
field: "labelName", | |||||
title: "应用疾病", | |||||
}, | |||||
{ | |||||
field: "deptName", | |||||
title: "应用科室", | |||||
}, | |||||
{ | |||||
field: "periodNumber", | |||||
title: "随访周期", | |||||
slots: { | |||||
default: "t_period_default", | |||||
}, | |||||
}, | |||||
{ | |||||
field: "lagTime", | |||||
title: "基线时间", | |||||
width: 300, | |||||
slots: { | |||||
default: "table_lagTime_edit", | |||||
}, | |||||
}, | |||||
{ | |||||
field: "operation", | |||||
title: "操作", | |||||
slots: { | |||||
default: "table_operation", | |||||
}, | |||||
}, | |||||
], | |||||
pickerOptions: { | |||||
disabledDate(time) { | |||||
return time.getTime() < Date.now() - 8.64e7; | |||||
}, | |||||
}, | |||||
// 步骤三表格数据 | |||||
step3TableList: [], | |||||
editFollowPlanVisible: false, | |||||
visiable: false, | |||||
submitting: false, | |||||
// 患者id | |||||
patientId: null, | |||||
// 选择的医生id | |||||
doctorId: null, | |||||
// 没选择基线时间的数据 | |||||
noLagTime: [], | |||||
}; | |||||
}, | |||||
methods: { | |||||
// 关闭弹窗 | |||||
onBeforeClose(done) { | |||||
this.showModal = false; | |||||
}, | |||||
/** | |||||
* 选择随访模板 | |||||
* */ | |||||
// 查询科室下拉框数据 | |||||
async loadDeptOptions() { | |||||
const res = await getTreeHospDeptByPatient(); | |||||
this.deptOptions = res.data || []; | |||||
}, | |||||
// 选中科室 | |||||
onDeptChange(val, data) { | |||||
console.log("vla=", val); | |||||
console.log("vla=", data); | |||||
data.labelId = null; | |||||
const deptId = val?.[val?.length - 1] || undefined; | |||||
this.loadDiseaseOptions(deptId); | |||||
}, | |||||
// 查询应用疾病下拉数据 | |||||
async loadDiseaseOptions(deptId) { | |||||
const { data } = await getMedicalLabel({ | |||||
deptId: deptId ? deptId : undefined, | |||||
}); | |||||
console.log("diseaseOptions=", data); | |||||
await this.$nextTick(); | |||||
const $grid = this.$refs.xGrid2; | |||||
if ($grid) { | |||||
const diseaseItem = $grid.getFormItems(1); | |||||
console.log("diseaseItem=", diseaseItem); | |||||
diseaseItem.itemRender.options = data; | |||||
} | |||||
}, | |||||
// 选择医生 | |||||
onChangeDoctor({ newValue }) { | |||||
console.log("newValue=", newValue); | |||||
this.doctorId = newValue.doctorId; | |||||
}, | |||||
// 预览 | |||||
async onPreview(row) { | |||||
const { data } = await getPlanDetail(row.id); | |||||
console.log("data=", data); | |||||
this.detailTaskList = data.taskList; | |||||
this.previewVisible = true; | |||||
}, | |||||
getDays(periodNumber, periodUnit) { | |||||
switch (periodUnit) { | |||||
case this.periodUnitMap.day: | |||||
return periodNumber; | |||||
case this.periodUnitMap.month: | |||||
return periodNumber * 30; | |||||
case this.periodUnitMap.year: | |||||
return periodNumber * 30 * 12; | |||||
} | |||||
}, | |||||
// 编辑计划 | |||||
onEditPlan(row) { | |||||
console.log("row=", row); | |||||
this.previewVisible = false; | |||||
this.formData = row; | |||||
this.maxDays = this.getDays(row.periodNumber, row.periodUnit); | |||||
this.detailTaskList = row.taskList; | |||||
this.editFollowPlanVisible = true; | |||||
}, | |||||
// 选择待办事项 | |||||
async handleSelectTodo(index) { | |||||
const curTask = this.detailTaskList[index]; | |||||
this.visiable = true; | |||||
await this.$nextTick(); | |||||
this.$refs.todoSelector | |||||
.open(curTask.items) | |||||
.then((items) => { | |||||
this.detailTaskList.splice(index, 1, { | |||||
...curTask, | |||||
items, | |||||
}); | |||||
this.visiable = false; | |||||
}) | |||||
.catch(() => { | |||||
this.visiable = false; | |||||
}); | |||||
}, | |||||
validate() { | |||||
console.log("validate"); | |||||
if (this.detailTaskList.length === 0) { | |||||
this.$message.error("随访任务不能为空"); | |||||
return false; | |||||
} | |||||
let preTime = 0; | |||||
for (const [index, task] of this.detailTaskList.entries()) { | |||||
if (typeof task.lagNumber !== "number") { | |||||
this.$message.error(`第${index + 1}次随访任务[基线时间+]未选择`); | |||||
return false; | |||||
} | |||||
if (task.items.length === 0) { | |||||
this.$message.error(`第${index + 1}次随访任务未添加待办事项`); | |||||
return false; | |||||
} | |||||
if (task.lagNumber < preTime) { | |||||
this.$message.error( | |||||
`第${index + 1}次随访任务[基线时间+]不能小于${index === 0 ? "0" : "前一次"}` | |||||
); | |||||
return false; | |||||
} | |||||
preTime = task.lagNumber; | |||||
if (task.lagNumber > this.maxDays) { | |||||
this.$message.error(`随访任务[基线时间+]超过了随访总周期`); | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
}, | |||||
saveItems() { | |||||
if (!this.validate()) return; | |||||
this.editFollowPlanVisible = false; | |||||
}, | |||||
// 上一步/取消 | |||||
onLeftBtn() { | |||||
if (this.currentStep === 1) { | |||||
this.showModal = false; | |||||
} else if (this.currentStep === 2) { | |||||
this.currentStep = 1; | |||||
} else if (this.currentStep === 3) { | |||||
this.currentStep = 2; | |||||
} | |||||
}, | |||||
// 下一步/保存 | |||||
async onRightBtn() { | |||||
if (this.currentStep === 1) { | |||||
if (this.selectReports.length <= 0) { | |||||
console.log("asdadsa", this.selectReports); | |||||
return this.$message.error("请选择一个报到单!"); | |||||
} | |||||
this.currentStep = 2; | |||||
} else if (this.currentStep === 2) { | |||||
if (this.selectTemps.length <= 0) { | |||||
return this.$message.error("请至少选择一个随访模版!"); | |||||
} | |||||
this.selectTemps.forEach((item) => { | |||||
item.lagTime = ""; | |||||
}); | |||||
this.step3TableList = JSON.parse(JSON.stringify(this.selectTemps)) || []; | |||||
this.currentStep = 3; | |||||
} else if (this.currentStep === 3) { | |||||
try { | |||||
this.submitting = true; | |||||
console.log(); | |||||
await this.$nextTick(); | |||||
const labelIds = []; | |||||
this.noLagTime = []; | |||||
const documentList = this.step3TableList.map((item1, index) => { | |||||
const { lagTime, labelId, id: tempId, taskList } = item1; | |||||
if (!lagTime) { | |||||
this.noLagTime.push(index); | |||||
} | |||||
if (labelIds.findIndex(i => i === item1.labelId ) < 0) { | |||||
labelIds.push(labelId); | |||||
} | |||||
const newTaskList = taskList.map((item2) => { | |||||
const { batchNo, lagNumber, lagUnit, items } = item2; | |||||
const newItems = items.map((item3) => { | |||||
const { targetId: itemTempId, targetType: itemType, targetName: itemName } = item3; | |||||
return { | |||||
itemTempId, | |||||
itemName, | |||||
itemType, | |||||
}; | |||||
}); | |||||
return { | |||||
batchNo, | |||||
lagNumber, | |||||
lagUnit, | |||||
items: newItems, | |||||
}; | |||||
}); | |||||
return { | |||||
lagTime: new Date(lagTime + " 00:00:00").getTime(), | |||||
tempId, | |||||
taskList: newTaskList, | |||||
}; | |||||
}); | |||||
if (this.noLagTime.length > 0) { | |||||
return this.$message.error("请完善基线时间"); | |||||
} | |||||
const params = { | |||||
patientId: this.patientId, | |||||
doctorId: this.doctorId, | |||||
documentList, | |||||
labelIdList: labelIds, | |||||
}; | |||||
await submitFollowupPlanApi(params); | |||||
this.$message.success("操作成功"); | |||||
this.showModal = false; | |||||
this.$emit("success"); | |||||
} catch (err) { | |||||
console.log("err=", err); | |||||
} finally { | |||||
this.submitting = false; | |||||
} | |||||
} | |||||
}, | |||||
onBeforeCloseEditFollowPlan() { | |||||
this.visiable = false | |||||
this.editFollowPlanVisible = false | |||||
}, | |||||
async init() { | |||||
this.patientId = this.$route.params.id; | |||||
this.loadDeptOptions(); | |||||
await this.$nextTick(); | |||||
this.loadDiseaseOptions(); | |||||
}, | |||||
}, | |||||
created() { | |||||
this.init(); | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.dialog-footer { | |||||
display: flex; | |||||
justify-content: center; | |||||
} | |||||
::v-deep .red-tip { | |||||
.el-input__inner { | |||||
border: 1px solid red !important; | |||||
} | |||||
} | |||||
::v-deep .el-card__body { | |||||
height: 100%; | |||||
} | |||||
</style> |
@@ -1,335 +0,0 @@ | |||||
<!-- | |||||
* @Author: guanxiaoyan guanxiaoyan@pb-station.com | |||||
* @Deion: | |||||
* @Date: 2023-12-08 10:10:44 | |||||
* @LastEditors: guanxiaoyan guanxiaoyan@pb-station.com | |||||
* @LastEditTime: 2024-01-03 18:05:31 | |||||
* @FilePath: /followUp-operate/src/views/workStation/followTask/DetailDialog/detail.vue | |||||
--> | |||||
<template> | |||||
<!-- <el-dialog title="随访计划--查看" :visible.sync="followTaskDetailVisible" width="90%" | |||||
@close="closeDialog"> --> | |||||
<el-container class="followDetail-box"> | |||||
<el-header style="margin-bottom: 20px;height:auto"> | |||||
<!-- 随访列表 --> | |||||
<el-table ref="followTaskTable" :data="followPlanTableData" highlight-current-row border | |||||
@current-change="handleFollowPlanList"> | |||||
<el-table-column align="center" property="name" label="随访模板名称"> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="labelName" label="应用疾病"> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="deptName" label="应用科室"> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="doctorName" label="责任医生"> | |||||
</el-table-column> | |||||
<el-table-column align="center" prop="periodNumber" label="随访周期"> | |||||
<template slot-scope="scope"> | |||||
{{ scope.row.periodNumber + periodUnitEnum.getLabel(scope.row.periodUnit) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="lagTime" label="基线时间"> | |||||
<template slot-scope="scope"> | |||||
{{ scope.row.lagTime ? parseTime(scope.row.lagTime, "{y}-{m}-{d}") : '' }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="statusDesc" label="状态"> | |||||
</el-table-column> | |||||
</el-table> | |||||
</el-header> | |||||
<el-main style="padding: 0 20px" v-loading="tableLoading"> | |||||
<el-row type="flex" :gutter="20"> | |||||
<el-col :span="12" > | |||||
<div style="height: 100%"> | |||||
<el-container style="height: 100%"> | |||||
<el-main style="padding: 0;"> | |||||
<el-row type="flex"> | |||||
<el-col :span="8"> | |||||
<!-- 历史列表 --> | |||||
<el-card :body-style="{ height: '100%', 'overflowY': 'auto' }"> | |||||
<div slot="header" class="el-descriptions__title"> | |||||
任务列表 | |||||
</div> | |||||
<el-table ref="taskTable" :data="followTaskTableData" highlight-current-row | |||||
@current-change="handleSelectTask" :show-header="false" border> | |||||
<el-table-column align="center" property="taskBeginTime" label="日期" | |||||
:class-name="'column-style-cursor'"> | |||||
<template slot-scope="scope"> | |||||
{{ parseTime(scope.row.taskBeginTime, "{y}-{m}-{d}") }} | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
</el-card> | |||||
</el-col> | |||||
<el-col :span="16"> | |||||
<!-- 待办事项 --> | |||||
<el-card> | |||||
<div slot="header" class="el-descriptions__title"> | |||||
待办事项 | |||||
</div> | |||||
<el-table ref="todoTable" :data="todoList" highlight-current-row border | |||||
@current-change="handleSelectItem"> | |||||
<el-table-column align="center" property="itemType" label="类型" | |||||
:class-name="'column-style-cursor'"> | |||||
<template slot-scope="scope"> | |||||
{{ todoItemTypeEnum.getLabel(scope.row.itemType) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="itemName" label="名称" | |||||
:class-name="'column-style-cursor'" /> | |||||
<el-table-column align="center" property="status" label="状态" | |||||
:class-name="'column-style-cursor'"> | |||||
<template slot-scope="scope"> | |||||
{{ checkHasValue(scope.row.status) ? todoItemStatusEnum.getLabel(`${scope.row.status}`) : '' | |||||
}} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="status" label="操作" | |||||
:class-name="'column-style-cursor'"> | |||||
<template slot-scope="{row}"> | |||||
<el-button | |||||
v-if="editWJ !== row.id || !(parseTime(followTaskItem.taskBeginTime, '{y}-{m}-{d}') === parseTime(new Date(), '{y}-{m}-{d}') && followItem.status === 1 && previewItem.status === 0)" | |||||
type="text" | |||||
:disabled="![todoItemTypeMap.survey].includes(row.itemType) || row.status !== 0 || followItem.status !== 1 || parseTime(followTaskItem.taskBeginTime, '{y}-{m}-{d}') !== parseTime(new Date(), '{y}-{m}-{d}')" | |||||
@click.stop="handleEdit(row)">编辑</el-button> | |||||
<el-button v-else type="text" :disabled="![todoItemTypeMap.survey].includes(row.itemType)" | |||||
@click.stop="handleCancel(row)">取消</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
</el-main> | |||||
</el-container> | |||||
</div> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-card> | |||||
<div style="height:100%;" v-if="previewItem" :key="previewItem && previewItem.itemId"> | |||||
<DWViewer | |||||
v-if="previewItem.itemType === todoItemTypeMap.survey && editWJ && parseTime(followTaskItem.taskBeginTime, '{y}-{m}-{d}') === parseTime(new Date(), '{y}-{m}-{d}') && followItem.status === 1 && previewItem.status === 0" | |||||
:url="`${surveyPrefix}/survey/diaowen-m.html?surveyId=${previewItem.itemId}&t=${new Date().getTime()}`" | |||||
:isStorage="false" @submitSurveyScuccess="submitSurveyScuccess" /> | |||||
<DWViewer v-else-if="previewItem.itemType === todoItemTypeMap.survey" | |||||
:url="`${surveyPrefix}/survey/answer-data.html?surveyId=${previewItem.itemId}&t=${new Date().getTime()}`" /> | |||||
<!-- 文章 --> | |||||
<ArticlePreview :isTemp="false" | |||||
v-else-if="previewItem.itemType === todoItemTypeMap.article" :articleId="previewItem.itemId" /> | |||||
</div> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
</el-main> | |||||
</el-container> | |||||
<!-- </el-dialog> --> | |||||
</template> | |||||
<script> | |||||
import DWViewer from "@/components/DWViewer"; | |||||
import ArticlePreview from "@/components/ArticlePreview"; | |||||
import { checkHasValue } from "@/utils/index"; | |||||
import { getFollowTaskDetailApi, finishWaitProcessItemApi } from '@/api/hospital/patientManage/followupPatient' | |||||
export default { | |||||
name: "FollowTaskDetail", | |||||
enums: ["todoItemTypeEnum", "todoItemStatusEnum", "todoItemTypeMap", "periodUnitEnum"], | |||||
components: { | |||||
DWViewer, | |||||
ArticlePreview, | |||||
}, | |||||
props: ["followRow", "isAllList"], | |||||
data() { | |||||
return { | |||||
surveyPrefix: process.env.VUE_APP_SURVEY_PREFIX || "", | |||||
followPlanTableData: [], | |||||
followTaskTableData: [], | |||||
previewItem: {}, | |||||
editWJ: null, // 是否编辑问卷 | |||||
taskList: [], //任务列表 | |||||
todoList: [], //待办事项 | |||||
tableLoading: false, | |||||
currentTask: "", | |||||
pageSize: 10, | |||||
pageNum: 1, | |||||
followListTotal: 0, | |||||
followId: null, | |||||
followItem: {}, | |||||
followTaskItem: { | |||||
taskBeginTime: "", | |||||
}, | |||||
}; | |||||
}, | |||||
created() { | |||||
this.initData(); | |||||
}, | |||||
methods: { | |||||
checkHasValue, | |||||
initData() { | |||||
// this.followPlanTableData = [this.followRow]; | |||||
this.followItem = this.followRow; | |||||
console.log("this.followRow=", this.followRow); | |||||
this.getFollowPlanDetail(this.followRow.id); | |||||
}, | |||||
async submitSurveyScuccess() { | |||||
console.log('提交==') | |||||
try { | |||||
await finishWaitProcessItemApi({ | |||||
id: this.editWJ, | |||||
}).then((res) => { | |||||
this.$message.success("编辑成功!"); | |||||
this.editWJ = null; | |||||
this.initData(); | |||||
}); | |||||
} catch (err) { | |||||
console.log("err=", err); | |||||
} finally { | |||||
} | |||||
}, | |||||
// 获取随访计划详情 | |||||
async getFollowPlanDetail(followId) { | |||||
this.followId = followId; | |||||
this.followPlanTableData = [] | |||||
this.followTaskTableData = []; | |||||
this.todoList = []; | |||||
this.tableLoading = true; | |||||
try { | |||||
const { data } = await getFollowTaskDetailApi({ followId: followId }); | |||||
if (data) { | |||||
const { taskList, ...otherObject } = data; | |||||
this.followPlanTableData = [otherObject]; | |||||
this.followTaskTableData = taskList || []; | |||||
this.followTaskItem = this.followTaskTableData[0]; | |||||
this.todoList = taskList[0].items; | |||||
this.currentTask = taskList[0].id; | |||||
if (this.todoList?.length > 0) { | |||||
this.previewItem = this.todoList[0]; | |||||
} | |||||
this.$nextTick(() => { | |||||
this.$refs.taskTable.setCurrentRow(this.followTaskTableData[0]); | |||||
if (this.todoList?.length > 0) { | |||||
this.$refs.todoTable.setCurrentRow(this.todoList[0]); | |||||
} | |||||
}); | |||||
} | |||||
} catch (err) { | |||||
console.log(err); | |||||
} finally { | |||||
this.tableLoading = false; | |||||
} | |||||
}, | |||||
setHightLight(row) { | |||||
if (this.followTaskTableData.length > 1) { | |||||
this.$refs.taskTable.setCurrentRow(row); | |||||
} | |||||
if (row.items.length > 1) { | |||||
const currentRow = this.todoList.filter((t) => t.taskId === row.id); | |||||
if (currentRow.length) { | |||||
this.$refs.todoTable.setCurrentRow(currentRow[0]); | |||||
} | |||||
} | |||||
}, | |||||
// 点击随访列表 | |||||
handleFollowPlanList(rowVal) { | |||||
console.log("rowVal", rowVal); | |||||
if (rowVal) { | |||||
return; | |||||
} | |||||
this.followItem = rowVal; | |||||
if (rowVal) { | |||||
this.getFollowPlanDetail(rowVal.id); | |||||
} | |||||
}, | |||||
// 点击任务列表 | |||||
handleSelectTask(rowVal) { | |||||
if (!rowVal) { | |||||
return; | |||||
} | |||||
this.followTaskItem = rowVal; | |||||
console.log("任务列表=", rowVal); | |||||
if (rowVal) { | |||||
if (this.currentTask === rowVal.id) return; | |||||
this.currentTask = rowVal.id; | |||||
this.editWJ = null; | |||||
this.todoList = rowVal.items || []; | |||||
if (this.todoList.length > 0) { | |||||
this.previewItem = this.todoList[0]; | |||||
this.$nextTick(() => { | |||||
this.$refs.todoTable.setCurrentRow(this.todoList[0]); | |||||
}); | |||||
} else { | |||||
this.previewItem = {}; | |||||
this.editWJ = null; | |||||
} | |||||
} | |||||
}, | |||||
// 点击单条事项查看PDF文件 | |||||
handleSelectItem(item) { | |||||
console.log("item", item); | |||||
if (!item) { | |||||
return; | |||||
} | |||||
this.previewItem = item; | |||||
if (this.editWJ !== item.id) { | |||||
this.editWJ = null; | |||||
} | |||||
}, | |||||
// 点击编辑 | |||||
handleEdit(row) { | |||||
this.editWJ = row.id; | |||||
this.previewItem = row; | |||||
this.$nextTick(() => { | |||||
this.$refs.todoTable.setCurrentRow(row); | |||||
}); | |||||
}, | |||||
handleCancel(row) { | |||||
console.log("row=", row); | |||||
this.editWJ = null; | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
/* 样式代码相同 */ | |||||
// ::v-deep .el-card { | |||||
// height: 100%; | |||||
// .el-card__body { | |||||
// height: 100%; | |||||
// } | |||||
// } | |||||
.column-style-cursor { | |||||
cursor: pointer; | |||||
} | |||||
.followDetail-box { | |||||
display: flex; | |||||
flex-direction: column; | |||||
height: 100%; | |||||
.el-header, | |||||
.el-main { | |||||
overflow: hidden; | |||||
padding: 0 !important; | |||||
} | |||||
.el-main { | |||||
box-sizing: border-box; | |||||
flex: 1; | |||||
padding: 20px; | |||||
.el-row { | |||||
height: 100%; | |||||
overflow: hidden; | |||||
} | |||||
.el-col { | |||||
height: 100%; | |||||
} | |||||
::v-deep .el-card { | |||||
box-sizing: border-box; | |||||
display: flex; | |||||
flex-direction: column; | |||||
height: 100%; | |||||
} | |||||
::v-deep .el-card__body { | |||||
overflow: auto; | |||||
flex: 1; | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -1,306 +0,0 @@ | |||||
<template> | |||||
<div class="follow-task"> | |||||
<el-row v-show="!showItemsTable" :gutter="20" style="width: 100%"> | |||||
<el-col :span="12" class="itemsTable-box"> | |||||
<el-card class="left-card"> | |||||
<el-steps direction="vertical" :active="value.length + 1"> | |||||
<el-step v-for="(item, index) in value" :key="index" style="flex-basis: auto"> | |||||
<template slot="title"> | |||||
<div style="display: flex; align-items: center"> | |||||
<span>第{{ index + 1 }}次随访任务</span> | |||||
<span class="ml10" style="font-size: 14px; color: #cccccc">基线时间+</span> | |||||
<div class="ml10"> | |||||
<el-input-number v-if="isPreview" size="mini" v-model="item.lagNumber" | |||||
disabled></el-input-number> | |||||
<el-input-number v-else size="mini" v-model="item.lagNumber" | |||||
v-bind="getTaskTimeRange(item, index)" | |||||
@change="changeNumber(item,index)"></el-input-number> | |||||
<span class="ml5" style="font-size: 12px; color: #000">天</span> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<template slot="description"> | |||||
<el-table :data="item.items" :ref="'previewTemplateTable'+index" border | |||||
emptyText="暂无待办事项" highlight-current-row class="mt10" | |||||
@current-change="handleCurrentChange(index,$event)"> | |||||
<el-table-column align="center" property="targetType" label="待办类型"> | |||||
<template slot-scope="scope"> | |||||
{{ todoItemTypeEnum.getLabel(scope.row.targetType) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="targetName" label="名称" /> | |||||
<el-table-column v-if="!isPreview" align="center" label="操作"> | |||||
<template slot-scope="scope"> | |||||
<el-button class="color-red" size="mini" type="text" | |||||
@click="hanldeDelTodoItem(scope.$index, index)" v-if="!isPreview"> | |||||
删除 | |||||
</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<el-button v-if="item.items.length < 10 && !isPreview" @click="handleAddTodo(index)" | |||||
class="mb20" type="primary" style="width: 100%"> | |||||
添加待办事项 | |||||
</el-button> | |||||
</template> | |||||
</el-step> | |||||
</el-steps> | |||||
<div v-if="!isPreview" class="operation-btn" style="width:100%;text-align: center"> | |||||
<el-button type="default" class="btn-style" @click="cancel">取消</el-button> | |||||
<el-button type="primary" class="btn-style" @click="sureSelectedItem">保存</el-button> | |||||
</div> | |||||
</el-card> | |||||
</el-col> | |||||
<el-col :span="11" :offset="1"> | |||||
<el-card> | |||||
<ArticlePreview v-if="previewData.targetType === todoItemTypeMap.article" style="height: 100%;" | |||||
:articleId="previewData.targetId" :isTemp="true" /> | |||||
<DWViewer v-else-if="previewData.targetType === todoItemTypeMap.survey" :url="url" /> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import ArticlePreview from "@/components/ArticlePreview"; | |||||
import DWViewer from "@/components/DWViewer"; | |||||
export default { | |||||
enums: ["todoItemTypeEnum", "periodUnitMap", "todoItemTypeMap"], | |||||
components: { | |||||
ArticlePreview, | |||||
DWViewer, | |||||
}, | |||||
props: { | |||||
value: { | |||||
type: Array, | |||||
default: () => [], | |||||
}, | |||||
maxDays: { | |||||
type: Number, | |||||
}, | |||||
isPreview: { | |||||
// 预览标记 | |||||
type: Boolean, | |||||
default: false, | |||||
}, | |||||
}, | |||||
computed: { | |||||
url() { | |||||
return `${process.env.VUE_APP_SURVEY_PREFIX}/survey/diaowen-m.html?surveyId=${this.previewData.surveyId}&sid=&tag=p-auth-0&t=${new Date().getTime()}`; | |||||
}, | |||||
}, | |||||
watch: { | |||||
value(newVal, oldVal) { | |||||
console.log("newVal", newVal, oldVal); | |||||
if (newVal.length && newVal[0].items.length) { | |||||
const item = newVal[0].items[0]; | |||||
this.setPdf(item); | |||||
// this.setCurrent(0, item); | |||||
} | |||||
}, | |||||
}, | |||||
data() { | |||||
return { | |||||
previewData: {}, | |||||
showArticle: true, | |||||
searchItemsForm: { | |||||
pageSize: 10, | |||||
pageNum: 1, | |||||
name: "", | |||||
type: 1, | |||||
}, | |||||
loading: false, | |||||
itemsTableList: [], | |||||
showItemsTable: false, | |||||
total: 0, | |||||
selectedItem: [], | |||||
itemArticleId: "", | |||||
itemSurveyId: "", | |||||
isItemArticle: true, | |||||
editIndex: null, | |||||
}; | |||||
}, | |||||
created() {}, | |||||
mounted() { | |||||
if (this.value.length === 0 && !this.isPreview) { | |||||
// 自动插入一条 | |||||
this.handleAddTask(); | |||||
} | |||||
if (this.value.length && this.value[0].items.length) { | |||||
const item = this.value[0].items[0]; | |||||
this.setPdf(item); | |||||
} | |||||
}, | |||||
unMounted() { | |||||
this.showArticle = true; | |||||
this.previewData = {} | |||||
}, | |||||
methods: { | |||||
getTaskTimeRange(item, index) { | |||||
let maxNum = this.maxDays; | |||||
if (index !== this.value.length - 1) { | |||||
maxNum = this.maxDays - (this.value.length - (index + 1)); | |||||
} | |||||
const range = { | |||||
min: index === 0 ? 0 : this.value[index - 1].lagNumber + 1, | |||||
max: index === this.value.length - 1 ? this.maxDays : maxNum, | |||||
}; | |||||
// console.log(`${index}----range`, range); | |||||
return range; | |||||
}, | |||||
changeNumber(item, index) { | |||||
this.computNumAdd(item, index); | |||||
this.computNumRemove(item, index); | |||||
}, | |||||
computNumAdd(item, index) { | |||||
const currentIndexNum = this.value[index].lagNumber; | |||||
let maxNum = this.maxDays; | |||||
if (index !== this.value.length - 1) { | |||||
maxNum = this.maxDays - (this.value.length - (index + 1)); | |||||
} | |||||
// console.log("maxNum!!!", maxNum); | |||||
if (index < this.value.length - 1 && this.value[index + 1].lagNumber <= maxNum) { | |||||
this.value[index + 1].lagNumber = currentIndexNum + 1; | |||||
this.computNumAdd(item, index + 1); | |||||
} | |||||
}, | |||||
computNumRemove(item, index) { | |||||
if (index !== 0) { | |||||
const currentIndexNum = this.value[index].lagNumber; | |||||
const lastIndexNum = this.value[index - 1].lagNumber; | |||||
if (lastIndexNum >= currentIndexNum) { | |||||
this.value[index - 1].lagNumber = currentIndexNum - 1; | |||||
this.computNumRemove(item, index - 1); | |||||
} | |||||
} | |||||
}, | |||||
handleAddTask() { | |||||
if (this.isPreview === "preview") return false; | |||||
this.$emit("input", [ | |||||
...this.value, | |||||
{ | |||||
lagNumber: undefined, | |||||
lagUnit: this.periodUnitMap.day, | |||||
items: [], | |||||
}, | |||||
]); | |||||
}, | |||||
handleDelTask(index) { | |||||
if (this.isPreview === "preview") return false; | |||||
if (index === 0) { | |||||
return this.$message.warning("至少包含一个任务"); | |||||
} | |||||
const taskList = [...this.value]; | |||||
taskList.splice(index); | |||||
this.$emit("input", taskList); | |||||
}, | |||||
// 修改添加待办事项 | |||||
handleAddTodo(index) { | |||||
this.$emit("selectTodo", index); | |||||
}, | |||||
// 查看预览待办事项 | |||||
handlePrewviewItem(item) { | |||||
if (item.targetType === this.todoItemTypeMap.article) { | |||||
this.$refs.previewArticle.open(item.targetId); | |||||
} else { | |||||
this.$refs.previewSurvey.open(item.surveyId); | |||||
} | |||||
}, | |||||
// 删除待办事项 | |||||
hanldeDelTodoItem(todoIndex, taskIndex) { | |||||
const taskList = [...this.value]; | |||||
taskList[taskIndex].items.splice(todoIndex, 1); | |||||
this.$emit("change", taskList); | |||||
}, | |||||
setCurrent(index, row) { | |||||
this.$nextTick(() => { | |||||
this.$refs["previewTemplateTable" + index][0].setCurrentRow(row); | |||||
}); | |||||
}, | |||||
clearCurrentRow() { | |||||
// 清除高亮 | |||||
this.$nextTick(() => { | |||||
console.log(this.$refs); | |||||
this.value.forEach((table, index) => { | |||||
console.log(this.$refs["previewTemplateTable" + index]); | |||||
this.$refs["previewTemplateTable" + index][0].setCurrentRow(null); | |||||
}); | |||||
}); | |||||
}, | |||||
handleCurrentChange(index, row) { | |||||
console.log('index===', index) | |||||
this.setPdf(row); | |||||
}, | |||||
setPdf(row) { | |||||
if (!row) { | |||||
this.previewData = {} | |||||
return | |||||
} | |||||
this.previewData = row | |||||
// console.log('row=', row) | |||||
// const item = row; | |||||
// this.articleId = ""; | |||||
// this.surveyId = ""; | |||||
// if (item.targetType === this.todoItemTypeMap.article) { | |||||
// this.showArticle = true; | |||||
// this.articleId = item.targetId; | |||||
// } else if(item.targetType === this.todoItemTypeMap.survey) { | |||||
// this.showArticle = false; | |||||
// this.surveyId = item.surveyId; | |||||
// } | |||||
}, | |||||
// 确定按钮 | |||||
sureSelectedItem() { | |||||
this.$emit("save"); | |||||
}, | |||||
cancel() { | |||||
this.$emit("closeEditDialog"); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.follow-task { | |||||
display: flex; | |||||
height: 75vh; | |||||
.el-row { | |||||
height: 100%; | |||||
.el-card { | |||||
height: 100%; | |||||
} | |||||
::v-deep .el-card__body { | |||||
overflow: auto; | |||||
height: 100%; | |||||
} | |||||
.el-steps { | |||||
height: auto; | |||||
min-height: 80%; | |||||
} | |||||
} | |||||
.el-col { | |||||
height: 100%; | |||||
} | |||||
::v-deep .el-step__description { | |||||
padding-right: 0 !important; | |||||
margin-bottom: 30px !important; | |||||
} | |||||
::v-deep .el-table .el-table__header .el-table-column--selection .el-checkbox { | |||||
display: none !important; | |||||
} | |||||
::v-deep .el-table .cell::before { | |||||
content: ""; | |||||
text-align: center; | |||||
line-height: 37px; | |||||
} | |||||
.itemsTable-box { | |||||
height: 100%; | |||||
display: flex; | |||||
flex-direction: column; | |||||
justify-content: space-between; | |||||
} | |||||
} | |||||
</style> | |||||
@@ -1,49 +0,0 @@ | |||||
<template> | |||||
<el-dialog title="提示" :visible="showModal" :before-close="onBeforeClose" center width="400px" top="30vh"> | |||||
<div class="content"> | |||||
<h4>患者信息保存后,仅支持修改手机号</h4> | |||||
<h4>请仔细核对患者基础信息是否准确无误</h4> | |||||
</div> | |||||
<span slot="footer" class="dialog-footer"> | |||||
<el-button @click="showModal = false">取 消</el-button> | |||||
<el-button type="primary" @click="onSubmit">确 定</el-button> | |||||
</span> | |||||
</el-dialog> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
name: "SubmitDiag", | |||||
computed: { | |||||
showModal: { | |||||
get() { | |||||
return this.visible; | |||||
}, | |||||
set(val) { | |||||
this.$emit("update:visible", val); | |||||
}, | |||||
}, | |||||
}, | |||||
props: ["visible"], | |||||
data() { | |||||
return {}; | |||||
}, | |||||
methods: { | |||||
onBeforeClose(done) { | |||||
this.showModal = false; | |||||
}, | |||||
onSubmit() { | |||||
this.$emit("onOk"); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.content { | |||||
h4 { | |||||
color: #000; | |||||
font-size: 16px; | |||||
font-weight: 600; | |||||
text-align: center; | |||||
} | |||||
} | |||||
</style> |
@@ -1,281 +0,0 @@ | |||||
<!-- | |||||
* @Author: guanxiaoyan guanxiaoyan@pb-station.com | |||||
* @Deion: | |||||
* @Date: 2023-12-25 09:51:03 | |||||
* @LastEditors: guanxiaoyan guanxiaoyan@pb-station.com | |||||
* @LastEditTime: 2024-01-03 10:53:08 | |||||
* @FilePath: /followUp-operate/src/views/workStation/followTask/CreateFollowPlan/components/TodoItemSelector/index.vue | |||||
--> | |||||
<template> | |||||
<div class="todo-selector" v-show="visiable"> | |||||
<div class="sf-title mb5">添加待办事项</div> | |||||
<el-row> | |||||
<el-col :span="12"> | |||||
<el-card> | |||||
<el-form ref="form" inline> | |||||
<el-form-item label="类型" prop="targetType" placeholder="请选择" style="margin: 0"> | |||||
<el-select size="mini" v-model="queryParams.targetType" @change="getList"> | |||||
<el-option v-for="item in todoItemTypeEnum.options.filter( | |||||
(item) => item.value !== todoItemTypeMap.remark | |||||
)" :label="item.label" :value="item.value" :key="item.value" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item label="" prop="name" style="margin: 0; margin-left: 20px"> | |||||
<el-input size="mini" v-model="queryParams.name" style="width:200px" | |||||
placeholder="请输入待办事项名称进行搜索"></el-input> | |||||
</el-form-item> | |||||
<el-form-item style="margin-left:20px"> | |||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"> | |||||
搜索 | |||||
</el-button> | |||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |||||
</el-form-item> | |||||
</el-form> | |||||
<div class="table"> | |||||
<el-table :data="tableList" ref="todoTableRef" border class="mt20" v-loading="loading" | |||||
highlight-current-row @current-change="handleCurrentChange(index,$event)"> | |||||
<el-table-column align="center" width="300" property="targetName" label="名称" /> | |||||
<el-table-column align="center" property="targetType" label="类型"> | |||||
<template slot-scope="scope"> | |||||
{{ todoItemTypeEnum.getLabel(scope.row.targetType) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" property="status" label="状态"> | |||||
<template slot-scope="scope"> | |||||
<div :class="[getCheckedStatus(scope.row) ? 'green-button' : 'gary-button']"> | |||||
{{ getCheckedStatus(scope.row) ? "已选" : "未选" }}</div> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column align="center" label="操作"> | |||||
<template slot-scope="scope"> | |||||
<el-checkbox :value="getCheckedStatus(scope.row)" | |||||
@change="handleCheckedChange(scope.row, $event)"></el-checkbox> | |||||
<!-- <el-button @click="handlePreview(scope.row)" class="ml10" size="mini" type="text"> | |||||
详情 | |||||
</el-button> --> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" | |||||
:limit.sync="queryParams.pageSize" @pagination="getList" /> | |||||
<div class="footer" style="margin-top:50px"> | |||||
<el-button @click="handleCancel">取 消</el-button> | |||||
<el-button type="primary" @click="handleConfirm">确定</el-button> | |||||
</div> | |||||
</div> | |||||
</el-card> | |||||
</el-col> | |||||
<el-col :span="11" :offset="1" style="height:100%;min-height:500px;flex:1;"> | |||||
<!-- <div class="sf-title mb5">事项预览</div> --> | |||||
<el-card> | |||||
<ArticlePreview v-if="selectPreview.targetType === todoItemTypeMap.article" style="height: 75vh; overflow-y: auto" | |||||
:articleId="selectPreview.targetId" :isTemp="false"/> | |||||
<DWViewer v-else-if="selectPreview.targetType === todoItemTypeMap.survey" style="height: 75vh; overflow-y: auto" :url="url" /> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import ArticlePreview from "@/components/ArticlePreview"; | |||||
import DWViewer from "@/components/DWViewer"; | |||||
import { todoItemTypeMap } from "@/constant"; | |||||
import { surveyPageList } from '@/api/hospital/followupManage/followupSurvey' | |||||
import { remindTemplateListApi } from '@/api/hospital/remindManage/remindList' | |||||
import { getArticlePageApi } from '@/api/hospital/followupManage/followupPlan' | |||||
export default { | |||||
enums: ["todoItemTypeEnum", "todoItemTypeMap"], | |||||
components: { | |||||
ArticlePreview, | |||||
DWViewer, | |||||
}, | |||||
props: { | |||||
defaultValue: { | |||||
type: Array, | |||||
default: () => [], | |||||
}, | |||||
form: { | |||||
type: Object, | |||||
default: () => ({}), | |||||
}, | |||||
visiable: { | |||||
type: Boolean | |||||
} | |||||
}, | |||||
data() { | |||||
return { | |||||
queryParams: { | |||||
targetType: todoItemTypeMap.survey, | |||||
name: "", | |||||
pageNum: 1, | |||||
pageSize: 10, | |||||
}, | |||||
tableList: [], | |||||
selectList: [], | |||||
loading: false, | |||||
total: 0, | |||||
defaultCheckIds: null, | |||||
surveyId: "", | |||||
articleId: "", | |||||
showArticle: false, | |||||
// 当前选中的数据 | |||||
selectPreview: {} | |||||
}; | |||||
}, | |||||
computed: { | |||||
url() { | |||||
return `${process.env.VUE_APP_SURVEY_PREFIX}/survey/diaowen-m.html?surveyId=${this.selectPreview.targetId}&sid=&tag=p-auth-0&t=${new Date().getTime()}`; | |||||
}, | |||||
}, | |||||
watch: {}, | |||||
mounted() { | |||||
this.getList(); | |||||
}, | |||||
methods: { | |||||
open(defaultValue = []) { | |||||
this.selectList = [...defaultValue]; | |||||
this.getList(); | |||||
this.defaultCheckIds = this.getCheckedIds(this.selectList); | |||||
this.$emit('update:visiable', true) | |||||
this.promise = {}; | |||||
return new Promise((resolve, reject) => { | |||||
this.promise.resolve = resolve; | |||||
this.promise.reject = reject; | |||||
}); | |||||
}, | |||||
// 搜索 | |||||
handleQuery() { | |||||
this.queryParams.pageNum = 1; | |||||
this.getList(); | |||||
}, | |||||
resetQuery() { | |||||
this.queryParams.targetType === this.todoItemTypeMap.survey; | |||||
this.queryParams.name = ""; | |||||
}, | |||||
getList() { | |||||
this.tableList = []; | |||||
this.loading = true; | |||||
let apiMethod = '' | |||||
if (this.queryParams.targetType === this.todoItemTypeMap.survey) { | |||||
apiMethod = surveyPageList | |||||
} else if (this.queryParams.targetType === this.todoItemTypeMap.article) { | |||||
apiMethod = getArticlePageApi | |||||
} else if (this.queryParams.targetType === this.todoItemTypeMap.remind) { | |||||
apiMethod = remindTemplateListApi | |||||
} | |||||
apiMethod(this.queryParams).then(async (res) => { | |||||
if (res?.data?.list.length) { | |||||
const list = res.data.list; | |||||
list.forEach((item) => { | |||||
item.targetName = item.name; | |||||
item.targetType = this.queryParams.targetType; | |||||
item.targetId = item.id; | |||||
}); | |||||
this.tableList = list || []; | |||||
this.total = Number(res.data.page.total); | |||||
// 默认选中第一条 | |||||
const item = this.tableList[0]; | |||||
await this.$nextTick() | |||||
this.$refs.todoTableRef?.setCurrentRow(item); | |||||
this.setPdf(item); | |||||
} | |||||
}) | |||||
.finally(() => { | |||||
this.loading = false; | |||||
}); | |||||
}, | |||||
getCheckedIds(list) { | |||||
return list | |||||
.map((item) => item.targetId) | |||||
.sort() | |||||
.join(","); | |||||
}, | |||||
reset() { | |||||
this.$emit('update:visable', false) | |||||
this.queryParams.name = ""; | |||||
this.targetType = this.todoItemTypeMap.survey; | |||||
}, | |||||
handleCancel() { | |||||
const newCheckedIds = this.getCheckedIds(this.selectList); | |||||
const close = () => { | |||||
this.reset(); | |||||
this.promise.reject(); | |||||
}; | |||||
if (this.defaultCheckIds !== newCheckedIds) { | |||||
this.$modal.confirm("页面内信息尚未保存,是否继续确定退出?").then(close); | |||||
return false; | |||||
} | |||||
close(); | |||||
}, | |||||
handleConfirm() { | |||||
if (this.selectList.length === 0) { | |||||
this.$message.error("至少选择一个待办事项"); | |||||
return; | |||||
} | |||||
this.reset(); | |||||
this.promise.resolve(this.selectList); | |||||
}, | |||||
getCheckedStatus(row) { | |||||
return this.selectList.some( | |||||
(item) => item.targetId === row.targetId && item.targetType === row.targetType | |||||
); | |||||
}, | |||||
handleCheckedChange(row, checked) { | |||||
console.log('row=', row) | |||||
const selectList = this.selectList.filter((item) => item.targetType === row.targetType); | |||||
if (checked) { | |||||
if (selectList.length >= 5) { | |||||
this.$message.error("同一类型待办事项最多5个"); | |||||
return; | |||||
} | |||||
this.selectList.push({ ...row }); | |||||
} else { | |||||
const index = this.selectList.findIndex( | |||||
(item) => item.targetId === row.targetId && item.targetType === row.targetType | |||||
); | |||||
if (index > -1) { | |||||
this.selectList.splice(index, 1); | |||||
} | |||||
} | |||||
}, | |||||
// 预览pdf | |||||
setPdf(row) { | |||||
const item = row; | |||||
// this.articleId = ""; | |||||
// this.surveyId = ""; | |||||
// console.log('setPdf=', row) | |||||
this.selectPreview = row | |||||
// if (item.targetType === this.todoItemTypeMap.article) { | |||||
// this.showArticle = true; | |||||
// this.articleId = item.targetId; | |||||
// } else if(item.targetType === this.todoItemTypeMap.survey) { | |||||
// this.showArticle = false; | |||||
// this.surveyId = item.surveyId; | |||||
// } | |||||
}, | |||||
handleCurrentChange(index, row) { | |||||
console.log('TodoItemSelector=handleCurrentChangeindex=', index) | |||||
console.log('row', row) | |||||
if (!row) { | |||||
return | |||||
} | |||||
this.setPdf(row); | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.todo-selector { | |||||
.tree-menus { | |||||
border: 1px solid #dfe4ed; | |||||
height: 200px; | |||||
border-radius: 4px; | |||||
overflow-y: auto; | |||||
} | |||||
.footer { | |||||
text-align: center; | |||||
} | |||||
} | |||||
</style> |
@@ -1,579 +0,0 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<el-row :gutter="20"> | |||||
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12"> | |||||
<div class="patient-info" v-loading="isLoading"> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<div class="sf-title">患者信息</div> | |||||
</el-col> | |||||
<el-form ref="formRef" :model="patientForm" :rules="formRules" label-width="100px"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="姓名:" prop="name"> | |||||
<el-input | |||||
:disabled="isDetail" | |||||
v-model.trim="patientForm.name" | |||||
placeholder="请输入姓名" | |||||
maxlength="20" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="手机号:" prop="phoneNumber"> | |||||
<el-input | |||||
v-model.trim="patientForm.phoneNumber" | |||||
placeholder="请输入手机号" | |||||
maxlength="11" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="身份证号:" prop="cardNumber"> | |||||
<el-input | |||||
:disabled="isDetail" | |||||
v-model.trim="patientForm.cardNumber" | |||||
placeholder="请输入身份证号" | |||||
maxlength="18" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="责任医生:" prop="doctorIds"> | |||||
<el-select | |||||
multiple | |||||
:value="patientForm.doctorIds" | |||||
placeholder="请选择责任医生" | |||||
v-loading="bindLoading" | |||||
@change="onChangeDoctor" | |||||
> | |||||
<el-option | |||||
v-for="item in doctorOptions" | |||||
:key="item.doctorId" | |||||
:label="item.userInfo && item.userInfo.userName" | |||||
:value="item.doctorId" | |||||
></el-option> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="性别:" prop="sex"> | |||||
<el-radio-group v-model="patientForm.sex" disabled> | |||||
<el-radio :label="item.value" v-for="item in sexEnum.options" :key="item.value"> | |||||
{{ item.label }} | |||||
</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="年龄:" prop="age"> | |||||
<el-input v-model="patientForm.age" disabled placeholder="请输入身份证获取年龄" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item v-if="patientId" label="就诊材料:" prop="materialList"> | |||||
<div class="materials-box"> | |||||
<!-- v-for="picItem in patientForm.materialList" | |||||
:key="picItem" --> | |||||
<div | |||||
class="image-box" | |||||
v-if="materialUrls && materialUrls.length > 0" | |||||
> | |||||
<el-image | |||||
:src="materialUrls[0]" | |||||
:preview-src-list="materialUrls" | |||||
/> | |||||
<el-tooltip placement="right"> | |||||
<div slot="content"> | |||||
<span>点击可查看所有材料</span> | |||||
</div> | |||||
<i class="el-icon-question"></i> | |||||
</el-tooltip> | |||||
</div> | |||||
<div v-else>暂无数据</div> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="疾病标签:"> | |||||
<div class="disease-container"> | |||||
<el-tag | |||||
class="disease-item" | |||||
v-for="item in patientForm.labelList" | |||||
:key="item.id" | |||||
> | |||||
{{ item.labelName }} | |||||
</el-tag> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-form> | |||||
</el-row> | |||||
</div> | |||||
</el-col> | |||||
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12"> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<div class="sf-title">随访计划</div> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<vxe-grid ref="xGrid" v-bind="gridConfig" :columns="columns" :proxyConfig="proxyConfig"> | |||||
<template #t_operate_default="{ row }"> | |||||
<vxe-button type="text" status="primary" @click="onOperation(1, row)"> | |||||
查看 | |||||
</vxe-button> | |||||
<vxe-button | |||||
type="text" | |||||
:disabled="![0, 1].includes(row.status)" | |||||
status="danger" | |||||
@click="onDel(row)" | |||||
> | |||||
删除 | |||||
</vxe-button> | |||||
</template> | |||||
<template #t_period_default="{ row }"> | |||||
{{ row.periodNumber }}{{ periodUnitEnum.getLabel(row.periodUnit) }} | |||||
</template> | |||||
<template #t_lagTime_default="{ row }"> | |||||
{{ row.lagTime ? parseTime(row.lagTime, "{y}-{m}-{d}") : "" }} | |||||
</template> | |||||
<template #bottom> | |||||
<div> | |||||
<vxe-button | |||||
status="primary" | |||||
icon="vxe-icon--plus" | |||||
style="width: 100%; max-width: 100%" | |||||
@click="onAddPlan" | |||||
> | |||||
添加随访计划 | |||||
</vxe-button> | |||||
</div> | |||||
</template> | |||||
</vxe-grid> | |||||
</el-col> | |||||
</el-row> | |||||
</el-col> | |||||
</el-row> | |||||
<div class="footer"> | |||||
<el-button style="width: 200px" @click="onCancel">取消</el-button> | |||||
<el-button type="primary" style="width: 200px" @click="onSubmit" v-loading="isSubmitting"> | |||||
保存 | |||||
</el-button> | |||||
</div> | |||||
<!-- 随访计划——查看 --> | |||||
<el-dialog | |||||
title="随访计划--查看" | |||||
v-if="followTaskDetailVisible" | |||||
:visible.sync="followTaskDetailVisible" | |||||
width="90%" | |||||
@close="(followTaskDetailVisible = false), getFollowList()" | |||||
:close-on-click-modal="false" | |||||
> | |||||
<div style="height: 800px"> | |||||
<FollowTaskDetailComp :isAllList="false" :followRow="followRow"></FollowTaskDetailComp> | |||||
</div> | |||||
</el-dialog> | |||||
<CreateFollowPlan | |||||
v-if="createFollowPlanVisible" | |||||
:visible.sync="createFollowPlanVisible" | |||||
@success="initData" | |||||
></CreateFollowPlan> | |||||
<SubmitDiag | |||||
v-if="submitConfirmVisible" | |||||
:visible.sync="submitConfirmVisible" | |||||
@onOk="onSubmitApi" | |||||
/> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { patientDetail, getDoctorAllList } from "@/api/hospital"; | |||||
import { requireReg, phoneReg, idCardReg } from "@/regular/index"; | |||||
import { commonGridConfig1 } from "@/config/vxeGrid"; | |||||
import CreateFollowPlan from "./components/CreateFollowPlan"; | |||||
import { validIdCard } from "@/utils/validate"; | |||||
import { parseIDCard, calculateAge } from "@/utils/ruoyi"; | |||||
import { | |||||
addPatient, | |||||
editPatient, | |||||
getFollowupPlanListApi, | |||||
bindDoctorApi, | |||||
unbindDoctorApi, | |||||
} from "@/api/hospital/patientManage/followupPatient"; | |||||
import FollowTaskDetailComp from "./components/DetailDialog"; | |||||
import { | |||||
deleteFollowDocumentApi, | |||||
} from "@/api/hospital/patientManage/followupPatient"; | |||||
import SubmitDiag from "./components/SubmitDiag"; | |||||
export default { | |||||
name: "AddPatient2", | |||||
enums: ["sexEnum", "cardTypeEnum", "periodUnitEnum", "followItemStatusEnum"], | |||||
components: { | |||||
CreateFollowPlan, | |||||
FollowTaskDetailComp, | |||||
SubmitDiag, | |||||
}, | |||||
computed: { | |||||
isDetail() { | |||||
return !!this.patientId; | |||||
}, | |||||
materialUrls() { | |||||
return this.patientForm.materialList ? this.patientForm.materialList.map(item => item.attachment) : [] | |||||
} | |||||
}, | |||||
data() { | |||||
return { | |||||
patientId: null, | |||||
isLoading: false, | |||||
patientForm: { | |||||
name: undefined, | |||||
phoneNumber: undefined, | |||||
cardType: "SF", | |||||
cardNumber: undefined, | |||||
sex: undefined, | |||||
age: undefined, | |||||
materialList: [], | |||||
doctorIds: [], | |||||
labelList: [], | |||||
}, | |||||
formRules: { | |||||
name: [ | |||||
requireReg("请输入姓名"), | |||||
{ max: 32, message: "长度不能超过32个字符", trigger: "blur" }, | |||||
], | |||||
sex: [{ required: true, message: "输入完整证件号后自动选择", trigger: "change" }], | |||||
age: [{ required: true, message: "输入完整证件号后自动计算", trigger: "change" }], | |||||
phoneNumber: [requireReg("请输入手机号"), phoneReg()], | |||||
cardNumber: [requireReg("请输入身份证号"), idCardReg()], | |||||
doctorIds: [{ required: true, message: "请选择责任医生", trigger: "change" }], | |||||
}, | |||||
// 责任医生下拉框数据 | |||||
doctorOptions: [], | |||||
// 解绑医生禁用控制 | |||||
bindLoading: false, | |||||
gridConfig: { | |||||
...commonGridConfig1, | |||||
showOverflow: false, | |||||
maxHeight: 600, | |||||
}, | |||||
columns: [ | |||||
{ | |||||
field: "name", | |||||
title: "随访模板名称", | |||||
minWidth: 160, | |||||
}, | |||||
{ | |||||
field: "labelName", | |||||
title: "应用疾病", | |||||
minWidth: 100, | |||||
}, | |||||
{ | |||||
field: "deptName", | |||||
title: "应用科室", | |||||
minWidth: 100, | |||||
}, | |||||
{ | |||||
field: "doctorName", | |||||
title: "责任医生", | |||||
minWidth: 100, | |||||
}, | |||||
{ | |||||
field: "reportId", | |||||
title: "随访周期", | |||||
minWidth: 100, | |||||
slots: { | |||||
default: "t_period_default", | |||||
}, | |||||
}, | |||||
{ | |||||
field: "lagTime", | |||||
title: "基线时间", | |||||
minWidth: 100, | |||||
slots: { | |||||
default: 't_lagTime_default' | |||||
} | |||||
}, | |||||
{ | |||||
field: "statusDesc", | |||||
title: "状态", | |||||
minWidth: 100, | |||||
}, | |||||
{ | |||||
field: "operation", | |||||
title: "操作", | |||||
width: 160, | |||||
fixed: "right", | |||||
slots: { | |||||
default: "t_operate_default", | |||||
}, | |||||
}, | |||||
], | |||||
proxyConfig: { | |||||
autoLoad: false, | |||||
response: { | |||||
result: "data.list", | |||||
total: "data.page.total", | |||||
}, | |||||
ajax: { | |||||
query: async ({ page, ...args }) => { | |||||
const { currentPage: pageNum, pageSize } = page; | |||||
const queryParams = { | |||||
pageNum, | |||||
pageSize, | |||||
patientId: this.$route.params.id, | |||||
}; | |||||
return getFollowupPlanListApi(queryParams); | |||||
}, | |||||
}, | |||||
}, | |||||
// 创建随访计划,弹窗控制 | |||||
createFollowPlanVisible: false, | |||||
// 点击保存按钮 | |||||
isSubmitting: false, | |||||
// 查看随访计划数据 | |||||
followRow: {}, | |||||
// 随访计划查看弹窗 | |||||
followTaskDetailVisible: false, | |||||
// 提交确认弹窗 | |||||
submitConfirmVisible: false, | |||||
}; | |||||
}, | |||||
watch: { | |||||
"patientForm.cardNumber": "idCardGetInfo", | |||||
}, | |||||
methods: { | |||||
// 加载责任医生下拉选项数据 | |||||
async loadDoctorOptions() { | |||||
try { | |||||
const { data } = await getDoctorAllList(); | |||||
this.doctorOptions = data || []; | |||||
} catch (err) {} | |||||
}, | |||||
// 获取患者详情 | |||||
async getPatientDetail() { | |||||
this.patientId = this.$route.params.id; | |||||
this.isLoading = true; | |||||
try { | |||||
const { data } = await patientDetail(this.patientId); | |||||
const { id, name, phoneNumber, cardNumber, materialList, doctors, labelList } = data; | |||||
const doctorIds = (doctors || []).map((item) => item.doctorId); | |||||
this.patientForm = { | |||||
id, | |||||
name, | |||||
phoneNumber, | |||||
cardNumber, | |||||
doctorIds, | |||||
materialList: materialList, | |||||
labelList | |||||
}; | |||||
this.idCardGetInfo(cardNumber); | |||||
this.getFollowList(); | |||||
} catch (err) { | |||||
console.log("err", err); | |||||
this.$message.error("获取患者信息失败"); | |||||
} finally { | |||||
this.isLoading = false; | |||||
} | |||||
}, | |||||
// 查询随访计划数据 | |||||
async getFollowList() { | |||||
await this.$nextTick(); | |||||
this.$refs.xGrid.commitProxy("query"); | |||||
}, | |||||
// 根据身份证号自动计算年龄和性别 | |||||
idCardGetInfo(val) { | |||||
if (!validIdCard(val)) { | |||||
this.patientForm.sex = ""; | |||||
this.patientForm.age = ""; | |||||
return; | |||||
} | |||||
const { birthYear, birthMonth, birthDay, gender } = parseIDCard(val); | |||||
this.patientForm.sex = gender; | |||||
this.patientForm.age = calculateAge(`${birthYear}-${birthMonth}-${birthDay}`); | |||||
}, | |||||
// 解绑医生 | |||||
async unbindDoctor(val, newVal) { | |||||
this.bindLoading = true; | |||||
try { | |||||
await unbindDoctorApi({ | |||||
patientId: this.patientId, | |||||
doctorId: val, | |||||
}); | |||||
this.patientForm.doctorIds = newVal; | |||||
} catch (err) { | |||||
console.log("err", err); | |||||
this.$message.error("解绑医生失败"); | |||||
} finally { | |||||
this.bindLoading = false; | |||||
} | |||||
}, | |||||
// 绑定医生 | |||||
async bindDoctor(val, newVal) { | |||||
this.bindLoading = true; | |||||
try { | |||||
await bindDoctorApi({ | |||||
patientId: this.patientId, | |||||
doctorId: val, | |||||
}); | |||||
this.patientForm.doctorIds = newVal; | |||||
} catch (err) { | |||||
console.log("err"); | |||||
this.$message.error("绑定医生失败"); | |||||
} finally { | |||||
this.bindLoading = false; | |||||
} | |||||
}, | |||||
// 更改选中责任医生:可能是绑定操作,也可能是解绑操作,也可能是新增的不操作 | |||||
async onChangeDoctor(val) { | |||||
console.log("changeDoctor=", val); | |||||
// 如果是新增,直接返回 | |||||
if (!this.patientId) { | |||||
this.patientForm.doctorIds = val; | |||||
return; | |||||
} | |||||
// 是编辑的话,判断解绑还是绑定 | |||||
const beforeLens = this.patientForm.doctorIds?.length || 0; | |||||
const currentLens = val?.length || 0; | |||||
// 删除 | |||||
if (beforeLens > currentLens) { | |||||
await this.unbindDoctor(this.patientForm.doctorIds[beforeLens - 1], val); | |||||
} else if (beforeLens < currentLens) { | |||||
await this.bindDoctor(val[currentLens - 1], val); | |||||
} | |||||
}, | |||||
// 查看 | |||||
onOperation(type, row) { | |||||
if (type === 1) { | |||||
this.followRow = row; | |||||
this.followTaskDetailVisible = true; | |||||
} | |||||
}, | |||||
// 新增计划 | |||||
onAddPlan() { | |||||
if (!this.patientId) { | |||||
return this.$message.warning("请先保存患者信息再操作!"); | |||||
} | |||||
this.createFollowPlanVisible = true; | |||||
console.log("点击了=", this.createFollowPlanVisible); | |||||
}, | |||||
// 取消 | |||||
onCancel() { | |||||
this.$router.go(-1); | |||||
}, | |||||
// 点击提交 | |||||
async onSubmitApi() { | |||||
const { id, name, phoneNumber, cardNumber, doctorIds } = this.patientForm; | |||||
if (!this.patientId) { | |||||
try { | |||||
this.isSubmitting = true; | |||||
const { | |||||
data: { id }, | |||||
} = await addPatient({ | |||||
name, | |||||
phoneNumber, | |||||
cardNumber, | |||||
doctorIds, | |||||
}); | |||||
this.$message.success("创建成功"); | |||||
this.$router.replace({ | |||||
name: "EditPatient", | |||||
params: { | |||||
id, | |||||
}, | |||||
}); | |||||
} catch (err) { | |||||
console.log(err); | |||||
} finally { | |||||
this.isSubmitting = false; | |||||
} | |||||
} else { | |||||
// 如果是编辑 | |||||
try { | |||||
this.isSubmitting = true; | |||||
await editPatient({ | |||||
id, | |||||
phoneNumber, | |||||
doctorIds, | |||||
}); | |||||
this.submitConfirmVisible = false | |||||
this.$message.success("修改成功"); | |||||
} catch (err) { | |||||
console.log("err=", err); | |||||
} finally { | |||||
this.isSubmitting = false; | |||||
} | |||||
} | |||||
}, | |||||
// 提交 | |||||
onSubmit() { | |||||
this.$refs.formRef.validate(async (valid) => { | |||||
if (!valid) { | |||||
return; | |||||
} | |||||
// 如果是新增 | |||||
this.submitConfirmVisible = true; | |||||
}); | |||||
}, | |||||
// 删除 | |||||
async onDel(row) { | |||||
this.$modal.confirm("是否确认删除?").then(async () => { | |||||
await deleteFollowDocumentApi({ | |||||
followId: row.id, | |||||
}); | |||||
this.$message.success("操作成功"); | |||||
this.getFollowList(); | |||||
}); | |||||
}, | |||||
initData() { | |||||
if (this.$route.params.id) { | |||||
this.getPatientDetail(); | |||||
} | |||||
this.loadDoctorOptions(); | |||||
}, | |||||
}, | |||||
created() { | |||||
this.initData(); | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.materials-box { | |||||
display: flex; | |||||
flex-wrap: wrap; | |||||
flex-direction: column; | |||||
.image-box { | |||||
position: relative; | |||||
width: 100px; | |||||
height: 100px; | |||||
i { | |||||
position: absolute; | |||||
top: 0; | |||||
right: 0; | |||||
transform: translate(100%, -50%); | |||||
font-size: 14px; | |||||
cursor: pointer; | |||||
} | |||||
} | |||||
.el-image { | |||||
width: 100px; | |||||
height: 100px; | |||||
} | |||||
} | |||||
.disease-container { | |||||
display: flex; | |||||
flex-wrap: wrap; | |||||
.disease-item { | |||||
margin-right: 10px; | |||||
margin-bottom: 10px; | |||||
} | |||||
} | |||||
.el-select { | |||||
width: 100%; | |||||
} | |||||
.doctor-select-container { | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.footer { | |||||
margin-top: 50px; | |||||
text-align: center; | |||||
} | |||||
</style> |
@@ -1,521 +0,0 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<vxe-grid | |||||
class="grid" | |||||
ref="xGrid" | |||||
v-bind="gridConfig" | |||||
:formConfig="formConfig" | |||||
:columns="columns" | |||||
:span-method="spanMethod" | |||||
:proxyConfig="proxyConfig" | |||||
:toolbarConfig="toolbarConfig" | |||||
@toolbar-button-click="toolbarBtnClick" | |||||
> | |||||
<template #patient_num> | |||||
<div class="mb10" style="margin-left: 10px; font-size: 16px; font-weight: 500"> | |||||
总计患者 | |||||
<span style="color: #409eff; font-weight: bold">{{ total }}</span> | |||||
人 | |||||
</div> | |||||
</template> | |||||
<template #date_item="{ data }"> | |||||
<el-date-picker | |||||
style="width: 300px" | |||||
v-model="data.dateRange" | |||||
value-format="yyyy-MM-dd" | |||||
type="daterange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
@change="(val) => onDateChange(val, data)" | |||||
></el-date-picker> | |||||
</template> | |||||
<template #dept_item="{ data }"> | |||||
<TreeDept | |||||
v-model="data.deptId" | |||||
clearable | |||||
style="width: 300px" | |||||
:options="deptList" | |||||
:autoFetch="false" | |||||
:props="{ emitPath: false }" | |||||
@change="(value, deptItem) => onChangeDept(value, deptItem, data)" | |||||
/> | |||||
</template> | |||||
<template #btn_items> | |||||
<vxe-button type="submit" status="primary" content="查询"></vxe-button> | |||||
<vxe-button type="reset" content="重置"></vxe-button> | |||||
</template> | |||||
<template #table_cardType="{ row }"> | |||||
<span>{{ cardTypeEnum.getLabel(row.cardType) }}</span> | |||||
</template> | |||||
<template #createTime_t_d="{ row }"> | |||||
{{ row.doctor && row.doctor.reportStatus === 1 ? row.doctor.updateTime : '--' }} | |||||
</template> | |||||
<template #reportStatus_t_d="{ row }"> | |||||
<span :style="{color: reportStatusEnum.enum[row.doctor.reportStatus].color}"> | |||||
{{ reportStatusEnum.getLabel(row.doctor.reportStatus) }} | |||||
</span> | |||||
</template> | |||||
<template #isFollowed_t_d="{row}"> | |||||
{{ row.doctor.isFollowed == 0 ? '否' : row.doctor.isFollowed == 1 ? '是' : '--' }} | |||||
</template> | |||||
<template #operation="{ row }"> | |||||
<vxe-button type="text" status="primary" @click="onEdit(row)">编辑</vxe-button> | |||||
<vxe-button type="text" status="danger" @click="onDel(row)">删除</vxe-button> | |||||
</template> | |||||
</vxe-grid> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { commonGridConfig1 } from "@/config/vxeGrid"; | |||||
import { getTreeHospDeptByPatient } from "@/api/admin"; | |||||
import { getDoctorAllList, getMedicalLabel, patientPageList, delPatient } from "@/api/hospital"; | |||||
import { getReportStatusApi } from "@/api/hospital/patientManage/followupPatient"; | |||||
import TreeDept from "@/components/TreeDept"; | |||||
export default { | |||||
name: "PatientList2", | |||||
components: { | |||||
TreeDept, | |||||
}, | |||||
enums: ["reportStatusEnum", "cardTypeEnum"], | |||||
data() { | |||||
return { | |||||
gridConfig: { | |||||
...commonGridConfig1, | |||||
}, | |||||
formConfig: { | |||||
titleWidth: 140, | |||||
titleAlign: "right", | |||||
titleColon: true, | |||||
items: [ | |||||
{ | |||||
field: "dateRange", | |||||
title: "报到时间", | |||||
itemRender: {}, | |||||
slots: { | |||||
default: "date_item", | |||||
}, | |||||
}, | |||||
{ | |||||
field: "deptId", | |||||
title: "科室", | |||||
itemRender: {}, | |||||
slots: { | |||||
default: "dept_item", | |||||
}, | |||||
}, | |||||
{ | |||||
field: 'name', | |||||
title: '患者姓名', | |||||
itemRender: { | |||||
name: "VxeInput", | |||||
props: { | |||||
placeholder: "请输入患者姓名" | |||||
} | |||||
} | |||||
}, | |||||
{ | |||||
field: "doctorId", | |||||
title: "责任医生", | |||||
itemRender: { | |||||
name: "VxeSelect", | |||||
options: [], | |||||
props: { | |||||
clearable: true, | |||||
placeholder: "请选择责任医生", | |||||
}, | |||||
optionProps: { | |||||
value: "doctorId", | |||||
label: "userName", | |||||
}, | |||||
}, | |||||
}, | |||||
{ | |||||
field: "labelId", | |||||
title: "诊断疾病", | |||||
itemRender: { | |||||
name: "VxeSelect", | |||||
options: [], | |||||
props: { | |||||
clearable: true, | |||||
placeholder: "请选择诊断疾病", | |||||
}, | |||||
optionProps: { | |||||
value: "id", | |||||
label: "name", | |||||
}, | |||||
}, | |||||
}, | |||||
{ | |||||
field: "reportStatus", | |||||
title: "报到状态", | |||||
itemRender: { | |||||
name: "VxeSelect", | |||||
options: [], | |||||
props: { | |||||
clearable: true, | |||||
placeholder: "请选择报到状态", | |||||
}, | |||||
optionProps: { | |||||
value: "value", | |||||
label: "label", | |||||
}, | |||||
}, | |||||
}, | |||||
{ | |||||
field: "isFollowed", | |||||
title: "是否配置随访计划", | |||||
itemRender: { | |||||
name: "VxeSelect", | |||||
options: [ | |||||
{ | |||||
value: 0, | |||||
label: '否' | |||||
}, | |||||
{ | |||||
value: 1, | |||||
label: '是' | |||||
} | |||||
], | |||||
props: { | |||||
clearable: true, | |||||
placeholder: "请选择", | |||||
}, | |||||
optionProps: { | |||||
}, | |||||
}, | |||||
}, | |||||
{ itemRender: {}, slots: { default: "btn_items" } }, | |||||
{ | |||||
span: 24, | |||||
itemRender: {}, | |||||
slots: { | |||||
default: "patient_num", | |||||
}, | |||||
}, | |||||
], | |||||
}, | |||||
columns: [ | |||||
{ | |||||
field: "id", | |||||
title: "患者ID", | |||||
minWidth: 100, | |||||
}, | |||||
{ | |||||
field: "name", | |||||
title: "患者名称", | |||||
minWidth: 200, | |||||
}, | |||||
{ | |||||
field: "sex", | |||||
title: "患者性别", | |||||
minWidth: 200, | |||||
}, | |||||
{ | |||||
field: "cardType", | |||||
title: "证件类型", | |||||
minWidth: 200, | |||||
slots: { | |||||
default: "table_cardType", | |||||
}, | |||||
}, | |||||
{ | |||||
field: "cardNumber", | |||||
title: "证件号", | |||||
minWidth: 200, | |||||
}, | |||||
{ | |||||
field: "phoneNumber", | |||||
title: "联系电话", | |||||
minWidth: 150, | |||||
}, | |||||
{ | |||||
field: 'doctor.deptName', | |||||
title: '科室名称', | |||||
minWidth: 150 | |||||
}, | |||||
{ | |||||
field: "createTime", | |||||
title: "报到时间", | |||||
minWidth: 200, | |||||
slots: { | |||||
default: 'createTime_t_d' | |||||
} | |||||
}, | |||||
{ | |||||
field: 'doctor.userInfo.userName', | |||||
title: '医生姓名', | |||||
minWidth: 150 | |||||
}, | |||||
{ | |||||
field: "status", | |||||
title: "报到状态", | |||||
minWidth: 160, | |||||
slots: { | |||||
default: "reportStatus_t_d", | |||||
}, | |||||
}, | |||||
{ | |||||
field: 'isFollowed', | |||||
title: '是否配置随访计划', | |||||
minWidth: 160, | |||||
slots: { | |||||
default: 'isFollowed_t_d' | |||||
} | |||||
}, | |||||
{ | |||||
field: "operation", | |||||
title: "操作", | |||||
width: 200, | |||||
fixed: "right", | |||||
slots: { | |||||
default: "operation", | |||||
}, | |||||
}, | |||||
], | |||||
proxyConfig: { | |||||
form: true, | |||||
response: { | |||||
result: "list", | |||||
total: "page.total", | |||||
}, | |||||
ajax: { | |||||
query: async ({ form, page, ...args }) => { | |||||
const { dateRange, deptId, doctorId, labelId, name, reportStatus, isFollowed } = form; | |||||
const { currentPage: pageNum, pageSize } = page; | |||||
const queryParams = { | |||||
beginTime: dateRange?.[0] ? dateRange?.[0] + " 00:00:00" : undefined, | |||||
endTime: dateRange?.[1] ? dateRange?.[1] + " 23:59:59" : undefined, | |||||
deptId, | |||||
doctorId, | |||||
labelId, | |||||
name, | |||||
reportStatus, | |||||
isFollowed, | |||||
pageNum, | |||||
pageSize, | |||||
}; | |||||
const { data: { list, page:page2} } = await patientPageList(queryParams); | |||||
const params = { | |||||
list: [], | |||||
page: page2 | |||||
} | |||||
list.forEach(item => { | |||||
const { doctors, ...otherInfo } = item; | |||||
const lens = doctors?.length | |||||
if (doctors?.length > 0) { | |||||
doctors.forEach((item2, index) => { | |||||
if (index === 0) { | |||||
params.list.push({ | |||||
...otherInfo, | |||||
doctor: item2, | |||||
rowspan: lens | |||||
}); | |||||
} else { | |||||
params.list.push({ | |||||
...otherInfo, | |||||
doctor: item2, | |||||
rowspan: 0 | |||||
}); | |||||
} | |||||
}) | |||||
} else { | |||||
params.list.push({ | |||||
...otherInfo, | |||||
doctor: { | |||||
userInfo: {} | |||||
}, | |||||
rowspan: 1 | |||||
}); | |||||
} | |||||
}) | |||||
this.total = page2.total || 0; | |||||
console.log('params=', params, page) | |||||
return params; | |||||
}, | |||||
}, | |||||
}, | |||||
toolbarConfig: { | |||||
buttons: [ | |||||
{ | |||||
code: "add", | |||||
name: "新增患者", | |||||
status: "success", | |||||
icon: "vxe-icon--plus", | |||||
}, | |||||
{ | |||||
code: "download", | |||||
name: "下载数据模板", | |||||
status: "danger", | |||||
icon: "vxe-icon--download", | |||||
}, | |||||
], | |||||
}, | |||||
deptList: [], | |||||
diseaseList: [], | |||||
total: 0, | |||||
// 患者状态查看按钮点击查看报道详情 | |||||
reportInfo: [], | |||||
reportLoading: false, | |||||
}; | |||||
}, | |||||
methods: { | |||||
/*获取科室数据*/ | |||||
async getDeptList() { | |||||
const res = await getTreeHospDeptByPatient(); | |||||
this.deptList = res.data || []; | |||||
}, | |||||
// 获取医生下拉框数据 | |||||
async findDoctorList() { | |||||
const { data } = await getDoctorAllList(); | |||||
await this.$nextTick(); | |||||
const $grid = this.$refs.xGrid; | |||||
if ($grid) { | |||||
const doctorItem = $grid.getFormItems(3); | |||||
doctorItem.itemRender.options = | |||||
data.map((item) => { | |||||
const { userInfo, ...params } = item; | |||||
return { | |||||
...params, | |||||
...userInfo, | |||||
}; | |||||
}) || []; | |||||
} | |||||
console.log("res=", data); | |||||
}, | |||||
// 获取疾病下拉框数据 | |||||
async findDiseaseList(deptId) { | |||||
const { data } = await getMedicalLabel({ | |||||
deptId, | |||||
}); | |||||
await this.$nextTick(); | |||||
const $grid = this.$refs.xGrid; | |||||
if ($grid) { | |||||
const diseaseItem = $grid.getFormItems(4); | |||||
diseaseItem.itemRender.options = data; | |||||
} | |||||
}, | |||||
async onDateChange(val, data) { | |||||
if (val && val.length > 0) { | |||||
data.reportStatus = 1 | |||||
await this.$nextTick(); | |||||
const $grid = this.$refs.xGrid; | |||||
if ($grid) { | |||||
const reportItem = $grid.getFormItems(5) | |||||
reportItem.itemRender.props = { | |||||
...reportItem.itemRender.props, | |||||
disabled: true | |||||
} | |||||
} | |||||
} else { | |||||
data.reportStatus = null | |||||
await this.$nextTick(); | |||||
const $grid = this.$refs.xGrid; | |||||
if ($grid) { | |||||
const reportItem = $grid.getFormItems(5) | |||||
reportItem.itemRender.props = { | |||||
...reportItem.itemRender.props, | |||||
disabled: false | |||||
} | |||||
} | |||||
} | |||||
console.log('val=', val) | |||||
console.log('data=', data) | |||||
}, | |||||
// 获取报到状态 | |||||
async findReportStatusOptions() { | |||||
await this.$nextTick(); | |||||
const $grid = this.$refs.xGrid | |||||
if ($grid) { | |||||
const reportItem = $grid.getFormItems(5) | |||||
reportItem.itemRender.options = this.reportStatusEnum.options | |||||
} | |||||
}, | |||||
// 加载下拉框数据 | |||||
loadOptions() { | |||||
this.getDeptList(); | |||||
this.findDoctorList(); | |||||
this.findDiseaseList(); | |||||
this.findReportStatusOptions(); | |||||
}, | |||||
// 选择科室 | |||||
onChangeDept(value, deptItem, formData) { | |||||
console.log("value=", value, deptItem, formData); | |||||
formData.labelId = null; | |||||
this.findDiseaseList(value); | |||||
}, | |||||
toolbarBtnClick({ code, button, $event }) { | |||||
console.log("code=", code); | |||||
console.log("button=", button); | |||||
console.log("$event=", $event); | |||||
if (code === "download") { | |||||
window.open(process.env.VUE_APP_BASE_PATH + "template/patientTemplate.xlsx"); | |||||
} else if (code === "add") { | |||||
this.$router.push({ | |||||
path: "/patientManage/followupPatient/add", | |||||
}); | |||||
} | |||||
}, | |||||
async onReportStatusDetail(row) { | |||||
console.log("查看患者详情=", row); | |||||
this.reportInfo = []; | |||||
try { | |||||
this.reportLoading = true; | |||||
const { data } = await getReportStatusApi(row.id); | |||||
this.reportInfo = data || []; | |||||
} catch (err) { | |||||
console.log(err); | |||||
} finally { | |||||
this.reportLoading = false; | |||||
} | |||||
}, | |||||
// 编辑 | |||||
onEdit(row) { | |||||
if (!row.id) { | |||||
return this.$message.warning('缺失患者id') | |||||
} | |||||
this.$router.push({ | |||||
name: 'EditPatient', | |||||
params: { | |||||
id: row.id | |||||
} | |||||
}) | |||||
}, | |||||
// 删除 | |||||
async onDel(row) { | |||||
this.$modal.confirm("是否确认删除?").then(async () => { | |||||
await delPatient(row.id); | |||||
this.$message.success("操作成功"); | |||||
await this.$nextTick(); | |||||
const $grid = this.$refs.xGrid; | |||||
$grid.commitProxy("query"); | |||||
}); | |||||
}, | |||||
spanMethod({ row, rowIndex, columnIndex }) { | |||||
if ([7, 8, 9, 10].includes(columnIndex)) { | |||||
return { | |||||
rowspan: 1, | |||||
colspan: 1 | |||||
} | |||||
} | |||||
return { | |||||
rowspan: row.rowspan, | |||||
colspan: 1 | |||||
} | |||||
} | |||||
}, | |||||
created() { | |||||
this.loadOptions(); | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
::v-deep .vxe-grid--form-wrapper { | |||||
.vxe-select { | |||||
width: 300px; | |||||
} | |||||
.vxe-input { | |||||
width: 300px | |||||
} | |||||
} | |||||
</style> |
@@ -1,73 +0,0 @@ | |||||
<template> | |||||
<div> | |||||
<el-form-item label="团队长:" prop="leader" required> | |||||
<member-select | |||||
:value="leader" | |||||
@updateLeader="updateLeader" | |||||
v-bind="$attrs" | |||||
v-on="$listeners" | |||||
></member-select> | |||||
</el-form-item> | |||||
<!-- :prop="`users.${index}.userId`" --> | |||||
<el-form-item | |||||
v-for="(item, index) in users" | |||||
:key="`${item.nanoid}${item.userId}`" | |||||
:label="`团队成员${index + 1}:`" | |||||
inline-message | |||||
:rules="rules.userId" | |||||
> | |||||
<member-select2 | |||||
:users="users" | |||||
:leader="leader" | |||||
:value="item" | |||||
:index="index" | |||||
@updateUsers="updateUsers" | |||||
v-on="$listeners" | |||||
></member-select2> | |||||
</el-form-item> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import MemberSelect from "./MemberSelect.vue"; | |||||
import MemberSelect2 from "./MemberSelect2.vue"; | |||||
import XeUtils from "xe-utils"; | |||||
export default { | |||||
name: "MemberForm", | |||||
components: { | |||||
MemberSelect, | |||||
MemberSelect2, | |||||
}, | |||||
props: { | |||||
leader: { | |||||
type: Object, | |||||
default: () => ({}), | |||||
}, | |||||
users: { | |||||
type: Array, | |||||
default: () => [], | |||||
}, | |||||
rules: { | |||||
type: Object | |||||
} | |||||
}, | |||||
data() { | |||||
return { | |||||
}; | |||||
}, | |||||
methods: { | |||||
updateLeader(value) { | |||||
console.log("value=", value); | |||||
this.$emit("update:leader", value); | |||||
}, | |||||
updateUsers(value, index) { | |||||
let newUsers = XeUtils.clone(this.users, true); | |||||
newUsers[index] = XeUtils.clone(value); | |||||
this.$emit("update:users", newUsers); | |||||
console.log("newUsers=", newUsers); | |||||
}, | |||||
}, | |||||
mounted() { | |||||
console.log("this.$attrs=", this.rules); | |||||
}, | |||||
}; | |||||
</script> |
@@ -1,214 +0,0 @@ | |||||
<template> | |||||
<div> | |||||
<el-input :value="value.doctorName" placeholder="请选择"> | |||||
<template #suffix> | |||||
<div style="padding-right: 20px"> | |||||
<el-button :disabled="type === 2" type="text" @click="onOpen">选择</el-button> | |||||
</div> | |||||
</template> | |||||
</el-input> | |||||
<!-- @close="onClose" --> | |||||
<vxe-modal | |||||
v-if="show" | |||||
type="modal" | |||||
v-model="show" | |||||
v-bind="modalConfig" | |||||
title="选择团队长" | |||||
:before-hide-method="onBeforeClose" | |||||
> | |||||
<template #default> | |||||
<vxe-grid ref="gridRef" v-bind="gridConfig" @radio-change="onRadioChange"></vxe-grid> | |||||
</template> | |||||
<template #footer> | |||||
<div class="footer-btn"> | |||||
<vxe-button style="margin-right: 10px" @click="onClose">取消</vxe-button> | |||||
<vxe-button status="primary" @click="onConfirm">保存</vxe-button> | |||||
</div> | |||||
</template> | |||||
</vxe-modal> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { commonGridConfig1 } from "@/config/vxeGrid"; | |||||
import { modalConfigMap, combineConfig } from "@/config/vxeModal"; | |||||
import { getLeaderDoctorListApi } from "@/api/hospital/doctorManage/doctor"; | |||||
export default { | |||||
name: "MemberSelect", | |||||
props: { | |||||
value: { | |||||
type: Object, | |||||
default: () => null, | |||||
}, | |||||
type: { | |||||
type: Number, | |||||
default: 1 | |||||
} | |||||
}, | |||||
computed: { | |||||
isDisableSelect: function() { | |||||
return this.type === 2; | |||||
} | |||||
}, | |||||
data() { | |||||
return { | |||||
modalConfig: { | |||||
...modalConfigMap.get("default"), | |||||
position: { | |||||
top: 50 | |||||
} | |||||
}, | |||||
gridConfig: { | |||||
...commonGridConfig1, | |||||
maxHeight: 600, | |||||
keepSource: true, | |||||
rowConfig: { | |||||
keyField: "userId", | |||||
isCurrent: true, | |||||
isHover: true, | |||||
}, | |||||
radioConfig: { | |||||
strict: true, | |||||
reserve: true, | |||||
trigger: "row", | |||||
}, | |||||
formConfig: { | |||||
titleColon: true, | |||||
titleAlign: "right", | |||||
data: {}, | |||||
items: [ | |||||
{ | |||||
field: "doctorName", | |||||
title: "", | |||||
itemRender: { | |||||
name: "VxeInput", | |||||
props: { | |||||
placeholder: "请输入员工姓名", | |||||
}, | |||||
}, | |||||
}, | |||||
{ | |||||
itemRender: { | |||||
name: "VxeButtonGroup", | |||||
options: [ | |||||
{ | |||||
type: "submit", | |||||
content: "搜索", | |||||
status: "primary", | |||||
}, | |||||
{ | |||||
type: "reset", | |||||
content: "重置", | |||||
}, | |||||
], | |||||
}, | |||||
}, | |||||
], | |||||
}, | |||||
columns: [ | |||||
{ | |||||
type: "radio", | |||||
width: 100, | |||||
}, | |||||
{ | |||||
type: "seq", | |||||
title: "序号", | |||||
width: 100, | |||||
}, | |||||
{ | |||||
field: "doctorName", | |||||
title: "姓名", | |||||
width: 150, | |||||
}, | |||||
{ | |||||
field: "cardNumber", | |||||
title: "证件号", | |||||
minWidth: 200, | |||||
}, | |||||
{ | |||||
field: "phoneNumber", | |||||
title: "手机号", | |||||
minWidth: 200, | |||||
}, | |||||
// { | |||||
// field: "operation", | |||||
// slots: { | |||||
// default: "operation_t_d" | |||||
// } | |||||
// }, | |||||
], | |||||
proxyConfig: { | |||||
form: true, | |||||
autoLoad: false, | |||||
response: { | |||||
result: "data.list", | |||||
total: "data.page.total", | |||||
}, | |||||
ajax: { | |||||
query: ({ page, form }) => { | |||||
const { currentPage: pageNum, pageSize } = page; | |||||
console.log("page=", page); | |||||
console.log("form=", form); | |||||
const params = { | |||||
pageNum, | |||||
pageSize, | |||||
...form | |||||
}; | |||||
return getLeaderDoctorListApi(params); | |||||
}, | |||||
}, | |||||
}, | |||||
}, | |||||
show: false, | |||||
selectDoctor: null, | |||||
}; | |||||
}, | |||||
methods: { | |||||
onOpen() { | |||||
this.show = true; | |||||
this.$nextTick(() => { | |||||
console.log("打开="); | |||||
this.$refs.gridRef.commitProxy("query"); | |||||
this.selectDoctor = this.value ? { ...this.value } : null; | |||||
this.$refs.gridRef.setRadioRow(this.selectDoctor); | |||||
}); | |||||
console.log("this.selectDoctor=", this.selectDoctor); | |||||
}, | |||||
onBeforeClose() { | |||||
console.log("关闭前"); | |||||
this.selectDoctor = null; | |||||
this.$refs.gridRef.clearRadioRow(); | |||||
this.$refs.gridRef.clearRadioReserve(); | |||||
this.show = false; | |||||
}, | |||||
onClose() { | |||||
console.log("close="); | |||||
this.$nextTick(() => { | |||||
this.selectDoctor = null; | |||||
this.$refs.gridRef.clearRadioRow(); | |||||
this.$refs.gridRef.clearRadioReserve(); | |||||
this.show = false; | |||||
}); | |||||
}, | |||||
onConfirm() { | |||||
if (!this.selectDoctor) { | |||||
return this.$message.warning("请选择团队长"); | |||||
} | |||||
this.$emit("updateLeader", this.selectDoctor); | |||||
this.show = false; | |||||
}, | |||||
onRadioChange({ newValue, oldValue, ...args }) { | |||||
this.selectDoctor = newValue; | |||||
}, | |||||
}, | |||||
mounted() { | |||||
console.log('this.type=', this.type) | |||||
} | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.footer-btn { | |||||
display: flex; | |||||
justify-content: center; | |||||
} | |||||
</style> |
@@ -1,275 +0,0 @@ | |||||
<template> | |||||
<div> | |||||
<div class="input-content"> | |||||
<el-input :value="value.userName" placeholder="请选择"> | |||||
<template #suffix> | |||||
<div style="padding-right: 20px"> | |||||
<el-button type="text" @click="onOpen">选择</el-button> | |||||
</div> | |||||
</template> | |||||
</el-input> | |||||
<div class="btn-content"> | |||||
<i v-if="index >= users.length - 1 && users.length < 9" class="el-icon-circle-plus" @click="onAdd"></i> | |||||
<i v-if="users.length > 1" class="el-icon-remove" @click="onDel"></i> | |||||
</div> | |||||
</div> | |||||
<!-- @close="onClose" --> | |||||
<vxe-modal | |||||
v-if="show" | |||||
type="modal" | |||||
v-model="show" | |||||
v-bind="modalConfig" | |||||
title="选择团队成员" | |||||
:before-hide-method="onBeforeClose" | |||||
> | |||||
<template #default> | |||||
<vxe-grid ref="gridRef" v-bind="gridConfig" @radio-change="onRadioChange"> | |||||
<template #operation_t_d="{ row }"> | |||||
<vxe-button type="text" status="info" v-if="isSelect(row)">已选择</vxe-button> | |||||
<vxe-button type="text" status="primary" v-else>未选择</vxe-button> | |||||
</template> | |||||
</vxe-grid> | |||||
</template> | |||||
<template #footer> | |||||
<div class="footer-btn"> | |||||
<vxe-button style="margin-right: 10px" @click="onClose">取消</vxe-button> | |||||
<vxe-button status="primary" @click="onConfirm">保存</vxe-button> | |||||
</div> | |||||
</template> | |||||
</vxe-modal> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { commonGridConfig1 } from "@/config/vxeGrid"; | |||||
import { modalConfigMap } from "@/config/vxeModal"; | |||||
import { getTrustDoctorListApi } from "@/api/hospital/doctorManage/doctor"; | |||||
export default { | |||||
name: "MemberSelect", | |||||
props: { | |||||
value: { | |||||
type: Object, | |||||
default: () => null, | |||||
}, | |||||
index: { | |||||
type: Number, | |||||
default: 0, | |||||
}, | |||||
users: { | |||||
type: Array, | |||||
default: () => [], | |||||
}, | |||||
leader: { | |||||
type: Object, | |||||
default: () => ({}) | |||||
} | |||||
}, | |||||
data() { | |||||
return { | |||||
modalConfig: { | |||||
...modalConfigMap.get("default"), | |||||
position: { | |||||
top: 50, | |||||
}, | |||||
}, | |||||
gridConfig: { | |||||
...commonGridConfig1, | |||||
maxHeight: 600, | |||||
keepSource: true, | |||||
rowConfig: { | |||||
keyField: "userId", | |||||
isCurrent: true, | |||||
isHover: true, | |||||
}, | |||||
radioConfig: { | |||||
strict: true, | |||||
reserve: true, | |||||
trigger: "row", | |||||
checkMethod: ({ row }) => { | |||||
return ( | |||||
(this.users.findIndex((item) => row.userId === item.userId) < 0 && this.leader.userId !== row.userId) || | |||||
this.value?.userId === row.userId | |||||
); | |||||
}, | |||||
}, | |||||
formConfig: { | |||||
titleColon: true, | |||||
titleAlign: "right", | |||||
data: {}, | |||||
items: [ | |||||
{ | |||||
field: "name", | |||||
title: "", | |||||
itemRender: { | |||||
name: "VxeInput", | |||||
props: { | |||||
placeholder: "请输入员工姓名", | |||||
}, | |||||
}, | |||||
}, | |||||
{ | |||||
itemRender: { | |||||
name: "VxeButtonGroup", | |||||
options: [ | |||||
{ | |||||
type: "submit", | |||||
content: "搜索", | |||||
status: "primary", | |||||
}, | |||||
{ | |||||
type: "reset", | |||||
content: "重置", | |||||
}, | |||||
], | |||||
}, | |||||
}, | |||||
], | |||||
}, | |||||
columns: [ | |||||
{ | |||||
type: "radio", | |||||
width: 100, | |||||
}, | |||||
{ | |||||
type: "seq", | |||||
title: "序号", | |||||
width: 100, | |||||
}, | |||||
{ | |||||
field: "userName", | |||||
title: "姓名", | |||||
width: 150, | |||||
}, | |||||
{ | |||||
field: "userIdcardNum", | |||||
title: "证件号", | |||||
minWidth: 180, | |||||
}, | |||||
{ | |||||
field: "userPhone", | |||||
title: "手机号", | |||||
minWidth: 160, | |||||
}, | |||||
{ | |||||
field: "operation", | |||||
title: "状态", | |||||
slots: { | |||||
default: "operation_t_d", | |||||
}, | |||||
width: 80, | |||||
fixed: "right", | |||||
}, | |||||
], | |||||
proxyConfig: { | |||||
form: true, | |||||
autoLoad: false, | |||||
response: { | |||||
result: "data.list", | |||||
total: "data.page.total", | |||||
}, | |||||
ajax: { | |||||
query: ({ page, form }) => { | |||||
const { currentPage: pageNum, pageSize } = page; | |||||
console.log("page=", page); | |||||
console.log("form=", form); | |||||
const params = { | |||||
pageNum, | |||||
pageSize, | |||||
...form | |||||
}; | |||||
return getTrustDoctorListApi(params); | |||||
}, | |||||
}, | |||||
}, | |||||
}, | |||||
show: false, | |||||
selectDoctor: null, | |||||
}; | |||||
}, | |||||
methods: { | |||||
isSelect(row) { | |||||
// | |||||
return this.users.filter(item => { | |||||
if (item.userId === this.value.userId) { | |||||
if (this.value.userId !== this.selectDoctor?.userId) { | |||||
return false | |||||
} else { | |||||
return true | |||||
} | |||||
} | |||||
return true | |||||
}).findIndex(item => row.userId === item.userId) >= 0 || row.userId === this.selectDoctor?.userId || this.leader.userId === row.userId | |||||
}, | |||||
onOpen() { | |||||
this.show = true; | |||||
this.$nextTick(() => { | |||||
console.log("打开="); | |||||
this.$refs.gridRef.commitProxy("query"); | |||||
this.selectDoctor = this.value ? { ...this.value } : null; | |||||
this.$refs.gridRef.setRadioRow(this.selectDoctor); | |||||
}); | |||||
console.log("this.selectDoctor=", this.selectDoctor); | |||||
}, | |||||
onBeforeClose() { | |||||
console.log("关闭前"); | |||||
this.selectDoctor = null; | |||||
this.$refs.gridRef.clearRadioRow(); | |||||
this.$refs.gridRef.clearRadioReserve(); | |||||
this.show = false; | |||||
}, | |||||
onClose() { | |||||
console.log("close="); | |||||
this.$nextTick(() => { | |||||
this.selectDoctor = null; | |||||
this.$refs.gridRef.clearRadioRow(); | |||||
this.$refs.gridRef.clearRadioReserve(); | |||||
this.show = false; | |||||
}); | |||||
}, | |||||
onConfirm() { | |||||
if (!this.selectDoctor) { | |||||
return this.$message.warning("请选择团队成员"); | |||||
} | |||||
this.$emit("updateUsers", this.selectDoctor, this.index); | |||||
this.show = false; | |||||
}, | |||||
onRadioChange({ newValue, oldValue, ...args }) { | |||||
this.selectDoctor = newValue; | |||||
}, | |||||
onAdd() { | |||||
this.$emit('memberAdd', this.index) | |||||
}, | |||||
onDel() { | |||||
this.$emit('memberDel', this.index) | |||||
} | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.input-content { | |||||
display: flex; | |||||
align-items: center; | |||||
.btn-content { | |||||
display: flex; | |||||
align-items: center; | |||||
padding-left: 10px; | |||||
width: 80px; | |||||
i { | |||||
font-size: 28px; | |||||
cursor: pointer; | |||||
} | |||||
i.el-icon-circle-plus { | |||||
margin-right: 6px; | |||||
color: #1890ff; | |||||
} | |||||
i.el-icon-remove { | |||||
color: red; | |||||
} | |||||
} | |||||
} | |||||
.footer-btn { | |||||
display: flex; | |||||
justify-content: center; | |||||
} | |||||
</style> |
@@ -1,420 +0,0 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<vxe-grid ref="gridRef" v-bind="gridConfig" @toolbar-button-click="toolbarBtnClick"> | |||||
<template #dept_f_d="{ data }"> | |||||
<TreeDept ref="treeDept" v-model="data.deptId" clearable /> | |||||
</template> | |||||
<template #member_t_d="{ row }"> | |||||
<el-popover placement="bottom" width="200" trigger="click"> | |||||
<template #reference> | |||||
<vxe-button type="text" status="primary" @click="onShow(row.id)">查看</vxe-button> | |||||
</template> | |||||
<div class="team-member-content" v-loading="loadingMember"> | |||||
<div | |||||
:class="['team-item', item.type === 2 ? 'team-item-blue' : '']" | |||||
v-for="item in teamMembers" | |||||
:key="item.id" | |||||
> | |||||
<div class="team-label" v-if="item.type === 1">成员:</div> | |||||
<div class="team-label" v-else-if="item.type === 2">团队长:</div> | |||||
<div class="team-name">{{ item.doctorName }}</div> | |||||
</div> | |||||
</div> | |||||
</el-popover> | |||||
</template> | |||||
<template #operation_t_d="{ row }"> | |||||
<vxe-button type="text" status="primary" @click="onEditTeam(row.id)">编辑</vxe-button> | |||||
<vxe-button type="text" status="danger" @click="onDelTeam(row.id)">删除</vxe-button> | |||||
</template> | |||||
</vxe-grid> | |||||
<CommonModal | |||||
v-if="visible" | |||||
:visible.sync="visible" | |||||
:title="title" | |||||
:position="{ | |||||
top: 50, | |||||
}" | |||||
:closeCb="closeCb" | |||||
> | |||||
<template #default> | |||||
<div class="form-content"> | |||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="110px"> | |||||
<el-form-item label="团队名称:" prop="name" inline-message> | |||||
<el-input v-model="formData.name" placeholder="请输入团队名称" size="small" /> | |||||
</el-form-item> | |||||
<MemberForm | |||||
:type="type" | |||||
:rules="rules" | |||||
:leader.sync="formData.leader" | |||||
:users.sync="formData.users" | |||||
@memberAdd="onMemberAdd" | |||||
@memberDel="onMemberDel" | |||||
/> | |||||
</el-form> | |||||
</div> | |||||
</template> | |||||
<template #footer> | |||||
<div class="btn-content"> | |||||
<el-button style="margin-right: 10px" @click="onClose">取消</el-button> | |||||
<el-button type="primary" @click="onSubmit" :loading="isLoading">确定</el-button> | |||||
</div> | |||||
</template> | |||||
</CommonModal> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { commonGridConfig1 } from "@/config/vxeGrid"; | |||||
import { | |||||
doctorTeamListApi, | |||||
updateDoctorTeamApi, | |||||
delDoctorTeamApi, | |||||
getDoctorTeamMemberApi, | |||||
detailTeamApi, | |||||
} from "@/api/hospital/teamManage/doctor"; | |||||
import MemberForm from "./components//MemberForm.vue"; | |||||
import TreeDept from "@/components/TreeDept"; | |||||
import { requireReg } from "@/regular"; | |||||
import { nanoid } from "nanoid"; | |||||
export default { | |||||
name: "DoctorTeam", | |||||
components: { | |||||
MemberForm, | |||||
TreeDept, | |||||
}, | |||||
data() { | |||||
var validateLeader = (rule, value, callback) => { | |||||
if (!value.id) { | |||||
callback(new Error("请选择团队长")); | |||||
return; | |||||
} | |||||
callback(); | |||||
}; | |||||
var validateUsers = (rule, value, callback) => { | |||||
console.log("value=", value); | |||||
if (!value) { | |||||
callback(new Error("请选择成员")); | |||||
return; | |||||
} | |||||
callback(); | |||||
}; | |||||
return { | |||||
gridConfig: { | |||||
...commonGridConfig1, | |||||
showOverflow: false, | |||||
maxHeight: 600, | |||||
formConfig: { | |||||
titleColon: true, | |||||
titleAlign: "right", | |||||
titleWidth: "90px", | |||||
data: { | |||||
name: undefined, | |||||
deptId: undefined, | |||||
}, | |||||
items: [ | |||||
{ | |||||
field: "deptId", | |||||
title: "科室名称", | |||||
itemRender: {}, | |||||
slots: { | |||||
default: "dept_f_d", | |||||
}, | |||||
}, | |||||
{ | |||||
field: "name", | |||||
title: "团队名称", | |||||
itemRender: { | |||||
name: "VxeInput", | |||||
props: { | |||||
placeholder: "请输入团队名称", | |||||
}, | |||||
}, | |||||
}, | |||||
{ | |||||
itemRender: { | |||||
name: "VxeButtonGroup", | |||||
options: [ | |||||
{ type: "submit", content: "搜索", status: "primary" }, | |||||
{ type: "reset", content: "重置" }, | |||||
], | |||||
}, | |||||
}, | |||||
], | |||||
}, | |||||
columns: [ | |||||
{ | |||||
type: "seq", | |||||
title: "序号", | |||||
width: 100, | |||||
}, | |||||
{ | |||||
field: "name", | |||||
title: "团队名称", | |||||
minWidth: 200, | |||||
}, | |||||
{ | |||||
field: "deptName", | |||||
title: "科室名称", | |||||
minWidth: 200, | |||||
}, | |||||
{ | |||||
field: "cy", | |||||
title: "成员", | |||||
minWidth: 100, | |||||
slots: { | |||||
default: "member_t_d", | |||||
}, | |||||
}, | |||||
{ | |||||
field: "operation", | |||||
title: "操作", | |||||
width: 200, | |||||
fixed: "right", | |||||
slots: { | |||||
default: "operation_t_d", | |||||
}, | |||||
}, | |||||
], | |||||
proxyConfig: { | |||||
form: true, | |||||
response: { | |||||
result: "data.list", | |||||
total: "data.page.total", | |||||
}, | |||||
ajax: { | |||||
query: ({ form, page }) => { | |||||
console.log("form=", form); | |||||
const { currentPage: pageNum, pageSize } = page; | |||||
const queryParams = { | |||||
pageNum, | |||||
pageSize, | |||||
...form, | |||||
}; | |||||
return doctorTeamListApi(queryParams); | |||||
}, | |||||
}, | |||||
}, | |||||
toolbarConfig: { | |||||
buttons: [ | |||||
{ | |||||
code: "add", | |||||
name: "新增团队", | |||||
status: "primary", | |||||
icon: "vxe-icon--plus", | |||||
}, | |||||
], | |||||
}, | |||||
type: 1, | |||||
title: "新增团队", | |||||
}, | |||||
visible: false, | |||||
formData: { | |||||
name: "", | |||||
leader: {}, | |||||
users: [ | |||||
{ | |||||
nanoid: nanoid(), | |||||
userId: null, | |||||
}, | |||||
], | |||||
}, | |||||
rules: { | |||||
name: [requireReg("请输入团队名称")], | |||||
leader: [ | |||||
{ | |||||
validator: validateLeader, | |||||
}, | |||||
], | |||||
userId: [ | |||||
{ | |||||
validator: validateUsers, | |||||
}, | |||||
], | |||||
}, | |||||
isLoading: false, | |||||
loadingMember: false, | |||||
teamMembers: [], | |||||
}; | |||||
}, | |||||
methods: { | |||||
toolbarBtnClick({ code, button, $event }) { | |||||
console.log("提交=", code, button, $event); | |||||
if (code === "add") { | |||||
this.type = 1; | |||||
this.title = "新增团队"; | |||||
this.formData = { | |||||
name: "", | |||||
leader: {}, | |||||
users: [ | |||||
{ | |||||
nanoid: nanoid(), | |||||
userId: null, | |||||
}, | |||||
], | |||||
}; | |||||
this.visible = true; | |||||
} | |||||
}, | |||||
onMemberAdd(index) { | |||||
console.log("index=", index); | |||||
this.formData.users.splice(index + 1, 0, { | |||||
nanoid: nanoid(), | |||||
}); | |||||
}, | |||||
onMemberDel(index) { | |||||
console.log("index=", index); | |||||
this.formData.users.splice(index, 1); | |||||
}, | |||||
closeCb() { | |||||
this.formData = { | |||||
name: "", | |||||
leader: {}, | |||||
users: [ | |||||
{ | |||||
nanoid: nanoid, | |||||
userId: "", | |||||
}, | |||||
], | |||||
}; | |||||
this.$nextTick(() => { | |||||
this.$refs.formRef.clearValidate(); | |||||
}); | |||||
}, | |||||
onClose() { | |||||
this.formData = { | |||||
name: "", | |||||
leader: {}, | |||||
users: [ | |||||
{ | |||||
nanoid: nanoid, | |||||
userId: "", | |||||
}, | |||||
], | |||||
}; | |||||
this.$nextTick(() => { | |||||
this.$refs.formRef.clearValidate(); | |||||
this.visible = false; | |||||
}); | |||||
}, | |||||
onSubmit() { | |||||
this.$refs.formRef.validate(async (isValid) => { | |||||
this.isLoading = true; | |||||
if (!isValid) { | |||||
this.isLoading = false; | |||||
return; | |||||
} | |||||
const { name, leader, users, id } = this.formData; | |||||
const params = { | |||||
id: id ? id : undefined, | |||||
name, | |||||
leaderDoctorId: leader.id, | |||||
ywxUserIds: users.filter(item => !!item.userId).map((item) => item.userId), | |||||
// } | |||||
}; | |||||
try { | |||||
await updateDoctorTeamApi(params); | |||||
this.$message.success("操作成功"); | |||||
this.visible = false; | |||||
this.$nextTick(() => { | |||||
this.$refs.gridRef.commitProxy("query"); | |||||
}); | |||||
} catch (err) { | |||||
} finally { | |||||
this.isLoading = false; | |||||
} | |||||
}); | |||||
}, | |||||
async onEditTeam(teamId) { | |||||
const { data } = await detailTeamApi(teamId); | |||||
console.log("data=", data); | |||||
const { name, id, followTeamDoctors } = data; | |||||
let leader = (followTeamDoctors || []).find((item) => item.type === 2) || {}; | |||||
let users = | |||||
followTeamDoctors | |||||
.filter((item) => item.type === 1) | |||||
.map((item) => { | |||||
return { | |||||
...item, | |||||
userName: item.doctorName, | |||||
}; | |||||
}) || []; | |||||
this.formData = { | |||||
id, | |||||
name, | |||||
leader: { | |||||
...leader, | |||||
id: leader.doctorId, | |||||
}, | |||||
users: | |||||
users.length === 0 | |||||
? [ | |||||
{ | |||||
nanoid: nanoid(), | |||||
userId: null, | |||||
}, | |||||
] | |||||
: users, | |||||
}; | |||||
this.type = 2; | |||||
this.title = "编辑团队"; | |||||
this.visible = true; | |||||
}, | |||||
onDelTeam(id) { | |||||
this.$modal | |||||
.confirm("删除后团队成员将无法继续开展随访业务是否继续操作") | |||||
.then(async () => { | |||||
console.log("是否走进了这里"); | |||||
await delDoctorTeamApi(id); | |||||
this.$message.success("操作成功"); | |||||
this.$nextTick(() => { | |||||
this.$refs.gridRef.commitProxy("query"); | |||||
}); | |||||
}) | |||||
.catch(() => {}); | |||||
}, | |||||
async onShow(id) { | |||||
this.loadingMember = true; | |||||
try { | |||||
const { data } = await getDoctorTeamMemberApi(id); | |||||
this.teamMembers = data || []; | |||||
console.log("this.teamMembers=", data); | |||||
} catch (err) { | |||||
} finally { | |||||
this.loadingMember = false; | |||||
} | |||||
}, | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
::v-deep .el-form-item__error { | |||||
line-height: 5px; | |||||
} | |||||
.btn-content { | |||||
display: flex; | |||||
justify-content: center; | |||||
} | |||||
.team-member-content { | |||||
overflow: auto; | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: center; | |||||
max-height: 200px; | |||||
.team-item { | |||||
display: flex; | |||||
width: 100%; | |||||
.team-label { | |||||
width: 80px; | |||||
} | |||||
.team-name { | |||||
flex: 1; | |||||
} | |||||
} | |||||
.team-item-blue { | |||||
color: #409eff; | |||||
} | |||||
} | |||||
.form-content { | |||||
overflow: auto; | |||||
max-height: 400px; | |||||
} | |||||
</style> |
@@ -84,13 +84,13 @@ | |||||
> | > | ||||
<el-table-column align="center" property="itemType" label="类型" :class-name="'column-style-cursor'"> | <el-table-column align="center" property="itemType" label="类型" :class-name="'column-style-cursor'"> | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
{{ todoItemTypeEnum.getLabel(scope.row.itemType) }} | |||||
{{ TODO_TYPE.getLabelByValue(scope.row.itemType) }} | |||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
<el-table-column align="center" property="itemName" label="名称" :class-name="'column-style-cursor'"/> | <el-table-column align="center" property="itemName" label="名称" :class-name="'column-style-cursor'"/> | ||||
<el-table-column align="center" property="status" label="状态" :class-name="'column-style-cursor'"> | <el-table-column align="center" property="status" label="状态" :class-name="'column-style-cursor'"> | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
{{ todoItemStatusEnum.getLabel(scope.row.status) }} | |||||
{{ TODO_STATUS.getLabelByValue(scope.row.status) }} | |||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
</el-table> | </el-table> | ||||
@@ -105,12 +105,12 @@ | |||||
<el-card height="100%" :body-style="{ height: '100%' }"> | <el-card height="100%" :body-style="{ height: '100%' }"> | ||||
<div style="height: 100%;overflow-y: scroll;" v-if="previewItem" :key="previewItem && previewItem.itemId"> | <div style="height: 100%;overflow-y: scroll;" v-if="previewItem" :key="previewItem && previewItem.itemId"> | ||||
<DWViewer | <DWViewer | ||||
v-if="previewItem.itemType === todoItemTypeMap.survey" | |||||
v-if="previewItem.itemType === TODO_TYPE.getValueByName('survey')" | |||||
:url="`${surveyPrefix}/survey/answer-data.html?surveyId=${previewItem.itemId}`" | :url="`${surveyPrefix}/survey/answer-data.html?surveyId=${previewItem.itemId}`" | ||||
/> | /> | ||||
<ArticlePreview | <ArticlePreview | ||||
:isTemp="false" | :isTemp="false" | ||||
v-else-if="previewItem.itemType === todoItemTypeMap.article" | |||||
v-else-if="previewItem.itemType === TODO_TYPE.getValueByName('article')" | |||||
:articleId="previewItem.itemId" | :articleId="previewItem.itemId" | ||||
/> | /> | ||||
</div> | </div> | ||||
@@ -121,18 +121,20 @@ | |||||
</el-container> | </el-container> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { statisticalDetail, statisticalTasks, followupTodoItem } from "@/api/common"; | |||||
import { statisticalDetail, followupTodoItem } from "@/api/common"; | |||||
import DWViewer from "@/components/DWViewer"; | import DWViewer from "@/components/DWViewer"; | ||||
import ArticlePreview from "@/components/ArticlePreview"; | import ArticlePreview from "@/components/ArticlePreview"; | ||||
import { TODO_TYPE, TODO_STATUS } from '@/enums' | |||||
export default { | export default { | ||||
name: "FollowUpDetail", | name: "FollowUpDetail", | ||||
enums: ["todoItemTypeEnum", "todoItemStatusEnum", "todoItemTypeMap"], | |||||
components: { | components: { | ||||
DWViewer, | DWViewer, | ||||
ArticlePreview, | ArticlePreview, | ||||
}, | }, | ||||
data() { | data() { | ||||
return { | return { | ||||
TODO_TYPE, | |||||
TODO_STATUS, | |||||
surveyPrefix: process.env.VUE_APP_SURVEY_PREFIX || "", | surveyPrefix: process.env.VUE_APP_SURVEY_PREFIX || "", | ||||
baseInfo: {}, | baseInfo: {}, | ||||
followTaskDocuments: [], | followTaskDocuments: [], | ||||
@@ -45,9 +45,9 @@ | |||||
/> | /> | ||||
</el-select> | </el-select> | ||||
</el-form-item> | </el-form-item> | ||||
<el-form-item label="医生名称" prop="name"> | |||||
<el-form-item label="医生名称" prop="doctorId"> | |||||
<el-select | <el-select | ||||
v-model="queryParams.name" | |||||
v-model="queryParams.doctorId" | |||||
placeholder="请输入医生名称" | placeholder="请输入医生名称" | ||||
clearable | clearable | ||||
filterable | filterable | ||||
@@ -55,9 +55,9 @@ | |||||
> | > | ||||
<el-option | <el-option | ||||
v-for="item in doctorList" | v-for="item in doctorList" | ||||
:key="item.doctorId" | |||||
:value="item.userName" | |||||
:label="item.userName" | |||||
:key="item.id" | |||||
:value="item.id" | |||||
:label="item.doctorName" | |||||
></el-option> | ></el-option> | ||||
</el-select> | </el-select> | ||||
</el-form-item> | </el-form-item> | ||||
@@ -80,7 +80,7 @@ | |||||
</el-form-item> | </el-form-item> | ||||
</el-form> | </el-form> | ||||
<div class="overview"> | <div class="overview"> | ||||
<div class="overview-item"> | |||||
<!-- <div class="overview-item"> | |||||
<div class="title-label"> | <div class="title-label"> | ||||
<span>诊后患者总计</span> | <span>诊后患者总计</span> | ||||
<el-tooltip content="已添加至随访系统的患者总数" placement="top"> | <el-tooltip content="已添加至随访系统的患者总数" placement="top"> | ||||
@@ -121,7 +121,7 @@ | |||||
<div class="num"> | <div class="num"> | ||||
{{ viewData.patientCompletedPercent ? viewData.patientCompletedPercent + "%" : 0 }} | {{ viewData.patientCompletedPercent ? viewData.patientCompletedPercent + "%" : 0 }} | ||||
</div> | </div> | ||||
</div> | |||||
</div> --> | |||||
<div class="overview-item"> | <div class="overview-item"> | ||||
<div class="title-label"> | <div class="title-label"> | ||||
<span>随访计划完成率</span> | <span>随访计划完成率</span> | ||||
@@ -133,7 +133,7 @@ | |||||
{{ viewData.taskCompletedPercent ? viewData.taskCompletedPercent + "%" : 0 }} | {{ viewData.taskCompletedPercent ? viewData.taskCompletedPercent + "%" : 0 }} | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="overview-item"> | |||||
<!-- <div class="overview-item"> | |||||
<div class="title-label"> | <div class="title-label"> | ||||
<span>诊后线上回流率</span> | <span>诊后线上回流率</span> | ||||
<el-tooltip content="通过随访小程序跳转至互联网医院小程序的患者数/已添加至随访系统的患者总数" placement="top"> | <el-tooltip content="通过随访小程序跳转至互联网医院小程序的患者数/已添加至随访系统的患者总数" placement="top"> | ||||
@@ -143,7 +143,7 @@ | |||||
<div class="num"> | <div class="num"> | ||||
-- | -- | ||||
</div> | </div> | ||||
</div> | |||||
</div> --> | |||||
</div> | </div> | ||||
<div style="display: flex; justify-content: space-between; padding-bottom: 8px"> | <div style="display: flex; justify-content: space-between; padding-bottom: 8px"> | ||||
@@ -212,11 +212,11 @@ | |||||
/> | /> | ||||
<el-table-column align="center" label="随访状态" width="100"> | <el-table-column align="center" label="随访状态" width="100"> | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
<el-tag :type="FOLLOWUP_STATUS.getTagByValue(scope.row.status)"> | |||||
<my-tag :type="FOLLOWUP_STATUS.getTagByValue(scope.row.status)"> | |||||
{{ | {{ | ||||
FOLLOWUP_STATUS.getLabelByValue(scope.row.status) | FOLLOWUP_STATUS.getLabelByValue(scope.row.status) | ||||
}} | }} | ||||
</el-tag> | |||||
</my-tag> | |||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
<el-table-column align="center" label="最近任务时间" prop="nextTaskDate" width="180"> | <el-table-column align="center" label="最近任务时间" prop="nextTaskDate" width="180"> | ||||
@@ -228,9 +228,9 @@ | |||||
</el-table-column> | </el-table-column> | ||||
<el-table-column align="center" label="任务状态" width="100"> | <el-table-column align="center" label="任务状态" width="100"> | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
<el-tag :type="FOLLOWUP_STATUS.getTagByValue(scope.row.nextTaskStatus)"> | |||||
<my-tag :type="FOLLOWUP_STATUS.getTagByValue(scope.row.nextTaskStatus)"> | |||||
{{ FOLLOWUP_STATUS.getLabelByValue(scope.row.nextTaskStatus) }} | {{ FOLLOWUP_STATUS.getLabelByValue(scope.row.nextTaskStatus) }} | ||||
</el-tag> | |||||
</my-tag> | |||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
<el-table-column | <el-table-column | ||||
@@ -311,7 +311,6 @@ export default { | |||||
status: "", | status: "", | ||||
wardId: "", // 院区ID | wardId: "", // 院区ID | ||||
deptId: [], | deptId: [], | ||||
name: "", | |||||
}, | }, | ||||
pageList: [], | pageList: [], | ||||
viewData: {}, | viewData: {}, | ||||
@@ -358,13 +357,7 @@ export default { | |||||
async getDoctorOptions() { | async getDoctorOptions() { | ||||
const { data } = await getDoctorAllList(); | const { data } = await getDoctorAllList(); | ||||
console.log("data=", data); | console.log("data=", data); | ||||
this.doctorList = data.map((item) => { | |||||
const { doctorId, userInfo = {} } = item; | |||||
return { | |||||
doctorId, | |||||
...userInfo, | |||||
}; | |||||
}); | |||||
this.doctorList = data | |||||
}, | }, | ||||
loadData() { | loadData() { | ||||
this.loadWardIdList(); | this.loadWardIdList(); | ||||
@@ -444,6 +437,7 @@ export default { | |||||
.overview { | .overview { | ||||
display: flex; | display: flex; | ||||
flex-wrap: wrap; | flex-wrap: wrap; | ||||
justify-content: center; | |||||
width: 100%; | width: 100%; | ||||
padding-bottom: 10px; | padding-bottom: 10px; | ||||
.overview-item { | .overview-item { | ||||
@@ -1,331 +0,0 @@ | |||||
<template> | |||||
<div class="app-container"> | |||||
<el-form | |||||
:model="queryParams" | |||||
ref="queryForm" | |||||
size="small" | |||||
:inline="true" | |||||
v-show="showSearch" | |||||
label-width="80px" | |||||
> | |||||
<el-form-item label="科室" prop="deptId"> | |||||
<TreeDept | |||||
v-model="queryParams.deptId" | |||||
clearable | |||||
style="width: 240px" | |||||
:options="deptList" | |||||
:autoFetch="false" | |||||
:props="{ emitPath: false, checkStrictly: false }" | |||||
@change="onChangeDept" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item label="医生名称" prop="doctorName"> | |||||
<el-select | |||||
v-model="queryParams.doctorName" | |||||
placeholder="请输入医生名称" | |||||
clearable | |||||
filterable | |||||
style="width: 240px" | |||||
> | |||||
<el-option | |||||
v-for="item in doctorList" | |||||
:key="item.doctorId" | |||||
:value="item.userName" | |||||
:label="item.userName" | |||||
></el-option> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item label="随访时间"> | |||||
<el-date-picker | |||||
v-model="dateRange" | |||||
style="width: 240px" | |||||
value-format="yyyy-MM-dd" | |||||
type="daterange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
></el-date-picker> | |||||
</el-form-item> | |||||
<el-form-item> | |||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"> | |||||
搜索 | |||||
</el-button> | |||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |||||
</el-form-item> | |||||
</el-form> | |||||
<div class="overview"> | |||||
<div class="overview-item"> | |||||
<div class="title-label"> | |||||
<span>随访任务完成率</span> | |||||
<el-tooltip content="已完成的随访任务数/全部随访任务数" placement="top"> | |||||
<i class="el-icon-question" style="color: #909399"></i> | |||||
</el-tooltip> | |||||
</div> | |||||
<div class="num">{{ viewData ? viewData + '%' : viewData }}</div> | |||||
</div> | |||||
</div> | |||||
<div style="display: flex; justify-content: space-between; padding-bottom: 8px"> | |||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | |||||
<!-- <ApiButton type="primary" plain icon="el-icon-download" size="mini" :api="exportRequest"> | |||||
导出Excel表 | |||||
</ApiButton> --> | |||||
</div> | |||||
<el-table v-loading="loading" :data="pageList" border row-key="id"> | |||||
<el-table-column | |||||
align="center" | |||||
label="序号" | |||||
type="index" | |||||
:index="(index) => (queryParams.pageNum - 1) * queryParams.pageSize + index + 1" | |||||
:min-width="120" | |||||
/> | |||||
<el-table-column | |||||
align="center" | |||||
label="随访单编号" | |||||
prop="task.id" | |||||
:show-overflow-tooltip="true" | |||||
:min-width="150" | |||||
/> | |||||
<el-table-column | |||||
align="center" | |||||
label="患者名称" | |||||
prop="patient.name" | |||||
:show-overflow-tooltip="true" | |||||
:min-width="150" | |||||
/> | |||||
<el-table-column | |||||
align="center" | |||||
label="患者性别" | |||||
prop="patient.sex" | |||||
:show-overflow-tooltip="true" | |||||
:min-width="150" | |||||
/> | |||||
<el-table-column | |||||
align="center" | |||||
label="联系电话" | |||||
prop="patient.phoneNumber" | |||||
:show-overflow-tooltip="true" | |||||
:min-width="150" | |||||
/> | |||||
<el-table-column | |||||
align="center" | |||||
label="科室" | |||||
prop="followDocument.deptName" | |||||
:show-overflow-tooltip="true" | |||||
:min-width="150" | |||||
/> | |||||
<el-table-column | |||||
align="center" | |||||
label="责任医生" | |||||
prop="followDocument.doctorName" | |||||
:show-overflow-tooltip="true" | |||||
:min-width="150" | |||||
/> | |||||
<el-table-column | |||||
align="center" | |||||
label="任务次数" | |||||
prop="task.batchNo" | |||||
:show-overflow-tooltip="true" | |||||
:min-width="150" | |||||
> | |||||
<template #default="{row}"> | |||||
{{ row.task.batchNo ? `第${row.task.batchNo}次任务` : '--' }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column | |||||
align="center" | |||||
label="任务开始时间" | |||||
prop="task.taskBeginTime" | |||||
:show-overflow-tooltip="true" | |||||
:min-width="150" | |||||
/> | |||||
<el-table-column | |||||
align="center" | |||||
label="任务结束时间" | |||||
prop="task.taskEndTime" | |||||
:show-overflow-tooltip="true" | |||||
:min-width="150" | |||||
/> | |||||
<el-table-column align="center" label="任务状态" :min-width="100"> | |||||
<template slot-scope="scope"> | |||||
<span | |||||
:style="{ | |||||
color: ![undefined, null].includes(scope.row.task.status) | |||||
? followItemStatusEnum.enum[scope.row.task.status].color | |||||
: '', | |||||
}" | |||||
> | |||||
{{ | |||||
scope.row.task.status !== undefined | |||||
? followItemStatusEnum.getLabel(scope.row.task.status) | |||||
: "" | |||||
}} | |||||
</span> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<pagination | |||||
v-show="total > 0" | |||||
:total="total" | |||||
:page.sync="queryParams.pageNum" | |||||
:limit.sync="queryParams.pageSize" | |||||
@pagination="getList" | |||||
/> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { getDoctorAllList } from "@/api/hospital/index"; | |||||
import { followUpTaskViewData, followUpTaskStaticalListApi }from "@/api/common/statisticalManage/followupTaskStatistical"; | |||||
import { getAllHospital, getTreeHospDeptByPatient } from "@/api/admin"; | |||||
import ApiButton from "@/components/ApiButton"; | |||||
import TreeDept from "@/components/TreeDept"; | |||||
export default { | |||||
name: "FollowUpStatistical", | |||||
enums: ["followItemStatusEnum", "periodUnitEnum"], | |||||
components: { | |||||
ApiButton, | |||||
TreeDept, | |||||
}, | |||||
data() { | |||||
return { | |||||
// 遮罩层 | |||||
loading: true, | |||||
// 显示搜索条件 | |||||
showSearch: true, | |||||
// 总条数 | |||||
total: 0, | |||||
// 日期范围 | |||||
dateRange: [], | |||||
// 查询参数 | |||||
queryParams: { | |||||
pageNum: 1, | |||||
pageSize: 10, | |||||
doctorId: undefined, | |||||
status: "", | |||||
wardId: "", // 院区ID | |||||
deptId: "", | |||||
doctorName: "", | |||||
}, | |||||
pageList: [], | |||||
viewData: null, | |||||
deptList: [], // 科室数据 | |||||
doctorList: [], | |||||
}; | |||||
}, | |||||
created() { | |||||
this.loadData(); | |||||
}, | |||||
activated() { | |||||
this.loadData(); | |||||
}, | |||||
methods: { | |||||
async getDoctorOptions() { | |||||
const { data } = await getDoctorAllList({ | |||||
deptId: this.queryParams.deptId | |||||
}); | |||||
console.log("data=", data); | |||||
this.doctorList = data.map((item) => { | |||||
const { doctorId, userInfo = {} } = item; | |||||
return { | |||||
doctorId, | |||||
...userInfo, | |||||
}; | |||||
}); | |||||
}, | |||||
loadData() { | |||||
this.getDoctorOptions(); | |||||
this.getDeptList(); | |||||
this.getViewData(); | |||||
this.getList(); | |||||
}, | |||||
onChangeDept(val) { | |||||
console.log('val=', val, this.queryParams) | |||||
this.queryParams.doctorId = undefined | |||||
this.queryParams.doctorName = undefined | |||||
this.getDoctorOptions() | |||||
}, | |||||
/*获取科室数据*/ | |||||
async getDeptList(wardId) { | |||||
const res = await getTreeHospDeptByPatient({ wardId: wardId }); | |||||
this.deptList = res.data || []; | |||||
}, | |||||
// 面板展示数据 | |||||
async getViewData() { | |||||
const params = JSON.parse(JSON.stringify(this.queryParams)); | |||||
Reflect.deleteProperty(params, "pageNum"); | |||||
Reflect.deleteProperty(params, "pageSize"); | |||||
const res = await followUpTaskViewData(this.addDateRange(params, this.dateRange)); | |||||
this.viewData = res.data; | |||||
}, | |||||
/** 查询列表 */ | |||||
getList() { | |||||
this.loading = true; | |||||
const params = JSON.parse(JSON.stringify(this.queryParams)); | |||||
console.log('params=', params) | |||||
params.beginTime = this.dateRange?.[0] | |||||
params.endTime = this.dateRange?.[1] | |||||
followUpTaskStaticalListApi(params) | |||||
.then((res) => { | |||||
const { | |||||
data: { list, page }, | |||||
} = res; | |||||
this.pageList = list || []; | |||||
this.total = page?.total || 0; | |||||
}) | |||||
.finally(() => { | |||||
this.loading = false; | |||||
}); | |||||
}, | |||||
/** 搜索按钮操作 */ | |||||
handleQuery() { | |||||
this.queryParams.pageNum = 1; | |||||
this.getViewData(); | |||||
this.getDeptList(this.queryParams.wardId); | |||||
this.getList(); | |||||
}, | |||||
/** 重置按钮操作 */ | |||||
resetQuery() { | |||||
this.dateRange = []; | |||||
this.resetForm("queryForm"); | |||||
this.handleQuery(); | |||||
} | |||||
}, | |||||
}; | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.overview { | |||||
display: flex; | |||||
flex-wrap: wrap; | |||||
justify-content: center; | |||||
width: 100%; | |||||
padding-bottom: 10px; | |||||
.overview-item { | |||||
display: flex; | |||||
flex-direction: column; | |||||
width: calc(25% - 10px); | |||||
min-width: 300px; | |||||
height: 130px; | |||||
margin-right: 10px; | |||||
margin-bottom: 10px; | |||||
padding: 0 20px; | |||||
border-radius: 4px; | |||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); | |||||
background-color: #fff; | |||||
.title-label { | |||||
font-size: 16px; | |||||
font-weight: 600; | |||||
line-height: 40px; | |||||
} | |||||
.num { | |||||
padding-top: 10px; | |||||
font-size: 30px; | |||||
font-weight: 600; | |||||
text-align: center; | |||||
color: #1890ff; | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -107,7 +107,6 @@ import CrudPopup from "./components/CrudPopup/index.vue"; | |||||
import { RULE_STATUS } from '@/enums/index'; | import { RULE_STATUS } from '@/enums/index'; | ||||
export default { | export default { | ||||
name: "RoleManage", | name: "RoleManage", | ||||
enums: ["sysStatusMap", "sysStatusEnum"], | |||||
components: { | components: { | ||||
ApiButton, | ApiButton, | ||||
CrudPopup, | CrudPopup, | ||||