ykt-wxapp/pages/case/archive-edit.vue

268 lines
7.7 KiB
Vue
Raw Permalink Normal View History

2026-01-22 15:54:15 +08:00
<template>
<view class="page">
<CustomerProfileTab
:data="archive"
:baseItems="baseItems"
:internalItems="internalItems"
:floatingBottom="16"
@save="savePatch"
/>
2026-01-22 15:54:15 +08:00
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { storeToRefs } from 'pinia';
2026-01-22 15:54:15 +08:00
import CustomerProfileTab from '@/components/archive-detail/customer-profile-tab.vue';
import api from '@/utils/api';
import useAccountStore from '@/store/account';
import { hideLoading, loading, toast } from '@/utils/widget';
2026-01-22 15:54:15 +08:00
const STORAGE_KEY = 'ykt_case_archive_detail';
const CURRENT_TEAM_STORAGE_KEY = 'ykt_case_current_team';
const NEED_RELOAD_STORAGE_KEY = 'ykt_case_need_reload';
2026-01-22 15:54:15 +08:00
const archiveId = ref('');
const archive = ref({
name: '',
sex: '',
age: '',
avatar: '',
mobile: '',
outpatientNo: '',
inpatientNo: '',
medicalRecordNo: '',
createTime: '',
creator: '',
createdByDoctor: true,
hasBindWechat: false,
notes: '',
groups: [],
groupOptions: [],
});
const baseItems = ref([]);
const internalItems = ref([]);
const accountStore = useAccountStore();
const { account, doctorInfo } = storeToRefs(accountStore);
const { getDoctorInfo } = accountStore;
function normalizeOptions(options) {
if (!Array.isArray(options)) return [];
if (!options.length) return [];
if (typeof options[0] === 'string') return options.filter((i) => typeof i === 'string');
if (typeof options[0] === 'object') {
return options
.map((i) => {
const label = i?.label ?? i?.name ?? i?.text ?? i?.title ?? '';
const value = i?.value ?? i?.id ?? i?.key ?? label;
if (!label && (value === undefined || value === null || value === '')) return null;
return { label: String(label || value), value: String(value) };
})
.filter(Boolean);
}
return [];
}
function normalizeTemplateItem(item) {
const next = { ...(item || {}) };
if (next.operateType === 'custom') next.operateType = 'formCell';
const originalType = next.type;
const customTypeMap = {
customerSource: 'select',
customerStage: 'select',
tag: 'multiSelectAndOther',
reference: 'input',
selectWwuser: 'select',
files: 'files',
corpProject: 'select',
diagnosis: 'textarea',
BMI: 'input',
bloodPressure: 'textarea',
selfMultipleDiseases: 'textarea',
};
if (originalType && customTypeMap[originalType]) {
next.__originType = originalType;
next.type = customTypeMap[originalType];
}
const aliasTypeMap = {
text: 'input',
string: 'input',
number: 'input',
integer: 'input',
int: 'input',
};
if (next.type && aliasTypeMap[next.type]) {
next.type = aliasTypeMap[next.type];
if (!next.inputType && (originalType === 'number' || originalType === 'integer' || originalType === 'int')) next.inputType = 'number';
}
const rawRange = next.range || next.options || next.optionList || next.values || [];
const range = normalizeOptions(rawRange);
if (next.type === 'select' || next.type === 'selectAndOther' || next.type === 'selectAndImage') {
next.range = range;
} else if (next.type === 'radio') {
if (range.length && typeof range[0] === 'object') {
next.type = 'select';
next.range = range;
} else {
next.range = Array.isArray(rawRange) ? rawRange : [];
}
}
if (!next.operateType) next.operateType = 'formCell';
next.required = Boolean(next.required);
if (next.type === 'input' && (next.wordLimit === undefined || next.wordLimit === null || next.wordLimit === '')) next.wordLimit = 20;
if (next.type === 'textarea' && (next.wordLimit === undefined || next.wordLimit === null || next.wordLimit === '')) next.wordLimit = 200;
return next;
}
function getUserId() {
const d = doctorInfo.value || {};
const a = account.value || {};
return String(d.userid || d.userId || d.corpUserId || a.userid || a.userId || '') || '';
}
function getCorpId() {
const d = doctorInfo.value || {};
const a = account.value || {};
const team = uni.getStorageSync(CURRENT_TEAM_STORAGE_KEY) || {};
return String(d.corpId || a.corpId || team.corpId || '') || '';
}
async function ensureDoctor() {
if (doctorInfo.value) return;
if (!account.value?.openid) return;
try {
await getDoctorInfo();
} catch (e) {
// ignore
}
}
2026-01-22 15:54:15 +08:00
function loadFromStorage() {
const cached = uni.getStorageSync(STORAGE_KEY);
if (cached && typeof cached === 'object') {
archive.value = {
...archive.value,
...cached,
groups: Array.isArray(cached.groups) ? cached.groups : archive.value.groups,
groupOptions: Array.isArray(cached.groupOptions) ? cached.groupOptions : archive.value.groupOptions,
};
}
}
async function loadTemplates() {
const corpId = getCorpId();
if (!corpId) return;
const [baseRes, internalRes] = await Promise.all([
api('getCurrentTemplate', { corpId, templateType: 'baseTemplate' }),
api('getCurrentTemplate', { corpId, templateType: 'internalTemplate' }),
]);
if (baseRes?.success) {
const temp = baseRes?.data && typeof baseRes.data === 'object' ? baseRes.data : baseRes;
const list = Array.isArray(temp.templateList) ? temp.templateList : [];
baseItems.value = list
.filter((i) => i && i.fieldStatus !== 'disable')
.filter((i) => i.operateType !== 'onlyRead')
.map(normalizeTemplateItem);
}
if (internalRes?.success) {
const temp = internalRes?.data && typeof internalRes.data === 'object' ? internalRes.data : internalRes;
const list = Array.isArray(temp.templateList) ? temp.templateList : [];
internalItems.value = list
.filter((i) => i && i.fieldStatus !== 'disable')
.filter((i) => i.operateType !== 'onlyRead')
.map(normalizeTemplateItem);
2026-01-22 15:54:15 +08:00
}
}
async function loadArchiveFromApi() {
if (!archiveId.value) return;
loading('加载中...');
try {
const res = await api('getCustomerByCustomerId', { customerId: archiveId.value });
if (!res?.success) {
toast(res?.message || '获取档案失败');
return;
}
archive.value = { ...archive.value, ...(res.data && typeof res.data === 'object' ? res.data : {}) };
uni.setStorageSync(STORAGE_KEY, { ...archive.value });
} catch (e) {
toast('获取档案失败');
} finally {
hideLoading();
}
}
async function savePatch(patch) {
const p = patch && typeof patch === 'object' ? patch : {};
const params = Object.keys(p).reduce((acc, k) => {
const v = p[k];
if (v !== undefined) acc[k] = v;
return acc;
}, {});
if (Object.keys(params).length === 0) return;
await ensureDoctor();
const userId = getUserId();
const corpId = getCorpId();
const team = uni.getStorageSync(CURRENT_TEAM_STORAGE_KEY) || {};
const createTeamId = team?.teamId ? String(team.teamId) : '';
const createTeamName = team?.name ? String(team.name) : '';
if (!archiveId.value || !userId || !corpId) {
toast('缺少用户/团队信息,请先完成登录与个人信息');
return;
}
loading('保存中...');
try {
const res = await api('updateCustomer', {
id: archiveId.value,
params,
userId,
corpId,
createTeamId,
createTeamName,
});
if (!res?.success) {
toast(res?.message || '保存失败');
return;
}
toast('保存成功');
uni.setStorageSync(NEED_RELOAD_STORAGE_KEY, 1);
await loadArchiveFromApi();
} catch (e) {
toast('保存失败');
} finally {
hideLoading();
}
2026-01-22 15:54:15 +08:00
}
onLoad((options) => {
archiveId.value = options?.archiveId ? String(options.archiveId) : '';
loadFromStorage();
ensureDoctor().then(async () => {
await Promise.all([loadTemplates(), loadArchiveFromApi()]);
});
2026-01-22 15:54:15 +08:00
});
onShow(() => {
loadFromStorage();
loadArchiveFromApi();
});
2026-01-22 15:54:15 +08:00
</script>
<style scoped>
.page {
min-height: 100vh;
background: #f5f6f8;
}
</style>