214 lines
6.5 KiB
Vue
214 lines
6.5 KiB
Vue
|
|
<template>
|
|||
|
|
<full-page :customScroll="false">
|
|||
|
|
<view v-if="configLoaded && !queryFields.length" class="flex items-center justify-center h-full">
|
|||
|
|
<empty-data text="当前机构暂未配置院内档案查询方案" />
|
|||
|
|
</view>
|
|||
|
|
<view v-else-if="queryFields.length" class="p-15">
|
|||
|
|
<view class="bg-white rounded shadow-lg">
|
|||
|
|
<form-template ref="formRef" :items="queryFormItems" :form="formData" @change="change" />
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<template #footer>
|
|||
|
|
<button-footer v-if="queryFields.length" :showCancel="false" confirmText="保存" @confirm="save" />
|
|||
|
|
</template>
|
|||
|
|
</full-page>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup>
|
|||
|
|
import { computed, ref } from 'vue';
|
|||
|
|
import { onLoad } from '@dcloudio/uni-app';
|
|||
|
|
import api from '@/utils/api';
|
|||
|
|
import { toast } from '@/utils/widget';
|
|||
|
|
|
|||
|
|
import ButtonFooter from '@/components/button-footer.vue';
|
|||
|
|
import EmptyData from '@/components/empty-data.vue';
|
|||
|
|
import FullPage from '@/components/full-page.vue';
|
|||
|
|
import formTemplate from '@/components/form-template/index.vue';
|
|||
|
|
|
|||
|
|
const corpId = ref('');
|
|||
|
|
const teamId = ref('');
|
|||
|
|
const customerId = ref('');
|
|||
|
|
const customer = ref({});
|
|||
|
|
const form = ref({});
|
|||
|
|
const archiveQueryPlans = ref([]);
|
|||
|
|
const configLoaded = ref(false);
|
|||
|
|
const saving = ref(false);
|
|||
|
|
const formRef = ref(null);
|
|||
|
|
|
|||
|
|
const queryFields = computed(() => {
|
|||
|
|
const fields = [];
|
|||
|
|
const fieldKeys = new Set();
|
|||
|
|
archiveQueryPlans.value.forEach((plan) => {
|
|||
|
|
(Array.isArray(plan?.fields) ? plan.fields : []).forEach((field) => {
|
|||
|
|
const source = typeof field === 'string' ? { fieldKey: field } : field || {};
|
|||
|
|
const fieldKey = String(source.fieldKey || source.feildKey || source.key || source.title || '').trim();
|
|||
|
|
if (!fieldKey || fieldKeys.has(fieldKey)) return;
|
|||
|
|
fieldKeys.add(fieldKey);
|
|||
|
|
fields.push({
|
|||
|
|
fieldKey,
|
|||
|
|
label: source.label || source.labelSnapshot || source.name || fieldKey,
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
return fields;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 查询方案字段在此页面一律按普通文本输入框处理。
|
|||
|
|
const queryFormItems = computed(() => queryFields.value.map((field) => ({
|
|||
|
|
title: field.fieldKey,
|
|||
|
|
name: field.label,
|
|||
|
|
type: 'input',
|
|||
|
|
})));
|
|||
|
|
|
|||
|
|
const formData = computed(() => ({ ...customer.value, ...form.value }));
|
|||
|
|
|
|||
|
|
function change({ title, value }) {
|
|||
|
|
if (title) form.value[title] = value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function initArchiveQueryConfig() {
|
|||
|
|
try {
|
|||
|
|
const res = await api('getCorpInfo', { corpId: corpId.value }, false);
|
|||
|
|
const data = Array.isArray(res?.data)
|
|||
|
|
? res.data[0]
|
|||
|
|
: Array.isArray(res?.data?.data)
|
|||
|
|
? res.data.data[0]
|
|||
|
|
: res?.data?.data || res?.data || {};
|
|||
|
|
const config = data?.hisArchiveQueryConfig && typeof data.hisArchiveQueryConfig === 'object'
|
|||
|
|
? data.hisArchiveQueryConfig
|
|||
|
|
: {};
|
|||
|
|
const plans = Array.isArray(config.plans)
|
|||
|
|
? config.plans
|
|||
|
|
: Array.isArray(config.schemes)
|
|||
|
|
? config.schemes
|
|||
|
|
: [];
|
|||
|
|
archiveQueryPlans.value = plans.filter((plan) => plan && Array.isArray(plan.fields) && plan.fields.length);
|
|||
|
|
} finally {
|
|||
|
|
configLoaded.value = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function getCustomer() {
|
|||
|
|
const res = await api('getCustomerByCustomerId', { customerId: customerId.value });
|
|||
|
|
if (res?.success && res.data) {
|
|||
|
|
customer.value = res.data;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
await toast(res?.message || '查询档案信息失败');
|
|||
|
|
uni.navigateBack();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function save() {
|
|||
|
|
// if (saving.value || !formRef.value?.verify()) return;
|
|||
|
|
saving.value = true;
|
|||
|
|
try {
|
|||
|
|
const matchedPlans = archiveQueryPlans.value.filter(isQueryPlanSatisfied);
|
|||
|
|
if (!matchedPlans.length) {
|
|||
|
|
toast('请完善信息');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const matchedArchive = await queryHisArchive(matchedPlans);
|
|||
|
|
if (!matchedArchive) {
|
|||
|
|
toast('没有查询到患者院内档案,可先前往医院建档。');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (!matchedArchive.archive.customerNumber) {
|
|||
|
|
toast('院内档案缺少门诊ID,无法关联');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const updateRes = await api('updateCustomer', {
|
|||
|
|
id: customerId.value,
|
|||
|
|
params: {
|
|||
|
|
...matchedArchive.conditions,
|
|||
|
|
customerNumber: matchedArchive.archive.customerNumber,
|
|||
|
|
isConnectHis: true,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
if (!updateRes?.success) {
|
|||
|
|
toast(updateRes?.message || '保存失败');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
await toast('保存并关联成功');
|
|||
|
|
uni.$emit('reloadTeamCustomers');
|
|||
|
|
uni.navigateBack();
|
|||
|
|
} finally {
|
|||
|
|
saving.value = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function getPlanFields(plan) {
|
|||
|
|
return (Array.isArray(plan?.fields) ? plan.fields : [])
|
|||
|
|
.map((field) => {
|
|||
|
|
const source = typeof field === 'string' ? { fieldKey: field } : field || {};
|
|||
|
|
const fieldKey = String(source.fieldKey || source.feildKey || source.key || source.title || '').trim();
|
|||
|
|
if (!fieldKey) return null;
|
|||
|
|
return { fieldKey };
|
|||
|
|
})
|
|||
|
|
.filter(Boolean);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function normalizeFieldValue(value) {
|
|||
|
|
return value === undefined || value === null ? '' : String(value).trim();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isQueryPlanSatisfied(plan) {
|
|||
|
|
const fields = getPlanFields(plan);
|
|||
|
|
return fields.length > 0 && fields.every((field) => normalizeFieldValue(formData.value[field.fieldKey]) !== '');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function getQueryConditions(plan) {
|
|||
|
|
return getPlanFields(plan).reduce((conditions, field) => {
|
|||
|
|
conditions[field.fieldKey] = formData.value[field.fieldKey];
|
|||
|
|
return conditions;
|
|||
|
|
}, {});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isHisArchiveMatched(archive, conditions) {
|
|||
|
|
return Object.keys(conditions).every((fieldKey) =>
|
|||
|
|
normalizeFieldValue(archive?.[fieldKey]) === normalizeFieldValue(conditions[fieldKey])
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function queryHisArchive(plans) {
|
|||
|
|
for (const plan of plans) {
|
|||
|
|
const conditions = getQueryConditions(plan);
|
|||
|
|
try {
|
|||
|
|
const res = await api('getHisCustomerArchive', {
|
|||
|
|
corpId: corpId.value,
|
|||
|
|
planId: plan.planId || plan.schemeId || '',
|
|||
|
|
...conditions,
|
|||
|
|
}, false);
|
|||
|
|
const archive = (Array.isArray(res?.list) ? res.list : [])
|
|||
|
|
.find((item) => isHisArchiveMatched(item, conditions));
|
|||
|
|
if (archive) return { archive, conditions };
|
|||
|
|
} catch (error) {
|
|||
|
|
// 当前方案查询失败时继续尝试后续满足条件的方案。
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function init() {
|
|||
|
|
await initArchiveQueryConfig();
|
|||
|
|
if (!queryFields.value.length) return;
|
|||
|
|
await getCustomer();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onLoad((options) => {
|
|||
|
|
corpId.value = options.corpId || '';
|
|||
|
|
teamId.value = options.teamId || '';
|
|||
|
|
customerId.value = options.id || '';
|
|||
|
|
if (!corpId.value || !customerId.value) {
|
|||
|
|
toast('页面参数错误');
|
|||
|
|
uni.navigateBack();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
init();
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped></style>
|