fix: 优化个人信息完善提示逻辑,更新搜索占位符和提示信息
This commit is contained in:
parent
f68c473191
commit
7d445f7b8b
@ -9,7 +9,11 @@ export default function useInfoCheck() {
|
||||
function withInfo(fn) {
|
||||
return async (...args) => {
|
||||
if (!doctorInfo.value || !doctorInfo.value.anotherName) {
|
||||
await confirm('请先完善您的个人信息,方可使用该功能!', { cancelText: '再等等', confirmText: '去完善' })
|
||||
try {
|
||||
await confirm('请先完善您的个人信息,方可使用该功能!', { cancelText: '再等等', confirmText: '去完善' })
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
return uni.navigateTo({ url: '/pages/work/profile' });
|
||||
}
|
||||
return fn(...args);
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<uni-icons type="search" size="18" color="#999" class="search-icon"></uni-icons>
|
||||
<input
|
||||
class="search-input"
|
||||
placeholder="搜索患者名称/手机号/院内ID号"
|
||||
placeholder="搜索患者名称/手机号/病案号"
|
||||
v-model="searchQuery"
|
||||
confirm-type="search"
|
||||
focus
|
||||
@ -55,7 +55,7 @@
|
||||
|
||||
<!-- History or Suggestions (when no search) -->
|
||||
<view v-else class="search-tips">
|
||||
<text class="tips-text">输入患者名称、手机号或院内ID号进行搜索</text>
|
||||
<text class="tips-text">输入患者名称、手机号或病案号进行搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@ -73,6 +73,7 @@ import { toast } from '@/utils/widget';
|
||||
const searchQuery = ref('');
|
||||
const searchResultsRaw = ref([]);
|
||||
const searching = ref(false);
|
||||
const searchSeq = ref(0);
|
||||
|
||||
const CURRENT_TEAM_STORAGE_KEY = 'ykt_case_current_team';
|
||||
const DETAIL_STORAGE_KEY = 'ykt_case_archive_detail';
|
||||
@ -111,11 +112,29 @@ function formatPatient(raw) {
|
||||
const mobiles = asArray(raw?.mobiles).map(String).filter(Boolean);
|
||||
const mobile = raw?.mobile ? String(raw.mobile) : (mobiles[0] || '');
|
||||
|
||||
const customerNumber = raw?.customerNumber || raw?.hospitalId || '';
|
||||
const customerProfileNo2 = raw?.customerProfileNo2 || '';
|
||||
const customerProfileNo3 = raw?.customerProfileNo3 || '';
|
||||
|
||||
function normalizeRecordTypeLabel(value) {
|
||||
const s = String(value || '').trim();
|
||||
if (!s) return '';
|
||||
const lower = s.toLowerCase();
|
||||
const base = lower.endsWith('record') && s.length > 6 ? s.slice(0, -6) : s;
|
||||
const baseLower = String(base).toLowerCase();
|
||||
if (baseLower === 'outpatient' || baseLower === 'out_patient' || baseLower === 'out-patient') return '门诊记录';
|
||||
if (baseLower === 'inhospital' || baseLower === 'in_hospital' || baseLower === 'in-hospital' || baseLower === 'inpatient') return '住院记录';
|
||||
if (baseLower === 'preconsultation' || baseLower === 'pre_consultation' || baseLower === 'pre-consultation' || baseLower === 'preconsultationtemplate') return '预问诊记录';
|
||||
if (baseLower === 'physicalexaminationtemplate' || baseLower === 'physicalexamination' || baseLower === 'physical_examination') return '体检记录';
|
||||
// 如果已经是中文(或后端已给展示名),直接返回
|
||||
return s;
|
||||
}
|
||||
|
||||
// 解析病历信息
|
||||
let record = null;
|
||||
if (raw?.latestRecord && typeof raw.latestRecord === 'object') {
|
||||
const lr = raw.latestRecord;
|
||||
const type = lr.type || '';
|
||||
const type = normalizeRecordTypeLabel(lr.type || lr.medicalTypeName || lr.medicalType || '');
|
||||
const date = lr.date || '';
|
||||
const diagnosis = lr.diagnosis || '';
|
||||
if (type || date || diagnosis) {
|
||||
@ -139,10 +158,79 @@ function formatPatient(raw) {
|
||||
record,
|
||||
createTime: raw?.createTime || '',
|
||||
creator: raw?.creatorName || raw?.creator || '',
|
||||
hospitalId: raw?.customerNumber || raw?.hospitalId || '',
|
||||
hospitalId: customerNumber,
|
||||
customerNumber,
|
||||
customerProfileNo2,
|
||||
customerProfileNo3,
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeText(value) {
|
||||
return String(value || '').trim();
|
||||
}
|
||||
|
||||
function normalizeDigits(value) {
|
||||
const s = normalizeText(value);
|
||||
return s.replace(/\D/g, '');
|
||||
}
|
||||
|
||||
function isChinaMobile(value) {
|
||||
const digits = normalizeDigits(value);
|
||||
return /^1[3-9]\d{9}$/.test(digits);
|
||||
}
|
||||
|
||||
function isLikelyArchiveNo(value) {
|
||||
const s = normalizeText(value);
|
||||
if (!s) return false;
|
||||
if (/[\u4e00-\u9fa5]/.test(s)) return false; // 中文一般是姓名
|
||||
if (isChinaMobile(s)) return false;
|
||||
// 病案号一般为数字/字母组合(或纯数字)
|
||||
return /^[0-9A-Za-z-]{3,}$/.test(s);
|
||||
}
|
||||
|
||||
function matchesAnyArchiveNo(patient, q) {
|
||||
const needle = normalizeText(q).toLowerCase();
|
||||
if (!needle) return false;
|
||||
const values = [
|
||||
patient?.customerNumber,
|
||||
patient?.customerProfileNo2,
|
||||
patient?.customerProfileNo3,
|
||||
patient?.hospitalId,
|
||||
].map((v) => normalizeText(v).toLowerCase()).filter(Boolean);
|
||||
|
||||
// 优先精确匹配
|
||||
if (values.some((v) => v === needle)) return true;
|
||||
// 兜底:包含匹配(部分医院病案号前后可能带前缀/后缀)
|
||||
return values.some((v) => v.includes(needle));
|
||||
}
|
||||
|
||||
function matchesAnyMobile(patient, q) {
|
||||
const needle = normalizeDigits(q);
|
||||
if (!needle) return false;
|
||||
const mobiles = [
|
||||
patient?.mobile,
|
||||
...(Array.isArray(patient?.mobiles) ? patient.mobiles : []),
|
||||
patient?.phone,
|
||||
patient?.phone1,
|
||||
].map(normalizeDigits).filter(Boolean);
|
||||
return mobiles.some((m) => m === needle);
|
||||
}
|
||||
|
||||
async function fetchList(params) {
|
||||
const res = await api('searchCorpCustomerForCaseList', params);
|
||||
if (!res?.success) {
|
||||
throw new Error(res?.message || '搜索失败');
|
||||
}
|
||||
const payload =
|
||||
res && typeof res === 'object'
|
||||
? res.data && typeof res.data === 'object' && !Array.isArray(res.data)
|
||||
? res.data
|
||||
: res
|
||||
: {};
|
||||
const list = Array.isArray(payload.list) ? payload.list : Array.isArray(payload.data) ? payload.data : [];
|
||||
return list.map(formatPatient);
|
||||
}
|
||||
|
||||
// Computed
|
||||
const searchResults = computed(() => {
|
||||
return searchResultsRaw.value || [];
|
||||
@ -163,29 +251,58 @@ const doSearch = useDebounce(async () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const seq = (searchSeq.value += 1);
|
||||
searching.value = true;
|
||||
const res = await api('searchCorpCustomerForCaseList', {
|
||||
corpId,
|
||||
userId,
|
||||
teamId,
|
||||
name: q,
|
||||
page: 1,
|
||||
pageSize: 50,
|
||||
});
|
||||
searching.value = false;
|
||||
try {
|
||||
if (isChinaMobile(q)) {
|
||||
const digits = normalizeDigits(q);
|
||||
const list = await fetchList({
|
||||
corpId,
|
||||
userId,
|
||||
teamId,
|
||||
page: 1,
|
||||
pageSize: 50,
|
||||
mobile: digits,
|
||||
});
|
||||
if (seq !== searchSeq.value) return;
|
||||
|
||||
if (!res?.success) {
|
||||
toast(res?.message || '搜索失败');
|
||||
return;
|
||||
// 后端为包含匹配,这里做一次精确过滤,避免“部分号段”带来误命中
|
||||
searchResultsRaw.value = list.filter((p) => matchesAnyMobile(p, digits));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isLikelyArchiveNo(q)) {
|
||||
const list = await fetchList({
|
||||
corpId,
|
||||
userId,
|
||||
teamId,
|
||||
page: 1,
|
||||
pageSize: 50,
|
||||
archiveNo: q,
|
||||
});
|
||||
if (seq !== searchSeq.value) return;
|
||||
|
||||
// 兜底:后端字段不全时,仍然做一次本地匹配(包含 customerNumber/2/3)
|
||||
searchResultsRaw.value = list.filter((p) => matchesAnyArchiveNo(p, q));
|
||||
return;
|
||||
}
|
||||
|
||||
const list = await fetchList({
|
||||
corpId,
|
||||
userId,
|
||||
teamId,
|
||||
name: q,
|
||||
page: 1,
|
||||
pageSize: 50,
|
||||
});
|
||||
if (seq !== searchSeq.value) return;
|
||||
searchResultsRaw.value = list;
|
||||
} catch (e) {
|
||||
if (seq !== searchSeq.value) return;
|
||||
toast(e?.message || '搜索失败');
|
||||
} finally {
|
||||
if (seq === searchSeq.value) searching.value = false;
|
||||
}
|
||||
const payload =
|
||||
res && typeof res === 'object'
|
||||
? res.data && typeof res.data === 'object' && !Array.isArray(res.data)
|
||||
? res.data
|
||||
: res
|
||||
: {};
|
||||
const list = Array.isArray(payload.list) ? payload.list : Array.isArray(payload.data) ? payload.data : [];
|
||||
searchResultsRaw.value = list.map(formatPatient);
|
||||
}, 600);
|
||||
|
||||
const handleSearch = () => doSearch();
|
||||
|
||||
@ -130,6 +130,7 @@ import dayjs from 'dayjs';
|
||||
|
||||
import api from '@/utils/api';
|
||||
import useAccountStore from '@/store/account';
|
||||
import useInfoCheck from '@/hooks/useInfoCheck';
|
||||
import { confirm as uniConfirm, hideLoading, loading as showLoading, toast } from '@/utils/widget';
|
||||
|
||||
// State
|
||||
@ -193,6 +194,7 @@ const currentTab = computed(() => tabs.value.find((t) => t.key === currentTabKey
|
||||
const accountStore = useAccountStore();
|
||||
const { account, doctorInfo } = storeToRefs(accountStore);
|
||||
const { getDoctorInfo } = accountStore;
|
||||
const { withInfo } = useInfoCheck();
|
||||
|
||||
const teamDisplay = computed(() => `${currentTeam.value?.name || ''}`);
|
||||
|
||||
@ -726,6 +728,10 @@ function normalizeMedicalType(raw) {
|
||||
const s = String(raw || '').trim();
|
||||
if (!s) return '';
|
||||
const lower = s.toLowerCase();
|
||||
// 常见后缀:xxxRecord(后端/历史数据可能返回此形式)
|
||||
if (lower.endsWith('record') && s.length > 6) {
|
||||
return normalizeMedicalType(s.slice(0, -6));
|
||||
}
|
||||
// 中文兜底(部分接口返回展示名)
|
||||
if (s.includes('门诊')) return 'outpatient';
|
||||
if (s.includes('住院') || s.includes('入院')) return 'inhospital';
|
||||
@ -1211,15 +1217,14 @@ const goToSearch = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const goToGroupManage = () => {
|
||||
const goToGroupManage = withInfo(() => {
|
||||
if (checkBatchMode()) return;
|
||||
if (!ensureUserInfoForFeature()) return;
|
||||
uni.navigateTo({
|
||||
url: '/pages/case/group-manage'
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
const toggleBatchMode = () => {
|
||||
const toggleBatchMode = withInfo(() => {
|
||||
if (isBatchMode.value) {
|
||||
// Already in batch mode, do nothing or prompt?
|
||||
// Prompt says "click Other operations... prompt please finish".
|
||||
@ -1229,9 +1234,9 @@ const toggleBatchMode = () => {
|
||||
}
|
||||
isBatchMode.value = true;
|
||||
selectedItems.value = [];
|
||||
};
|
||||
});
|
||||
|
||||
const handleCreate = () => {
|
||||
const handleCreate = withInfo(() => {
|
||||
if (checkBatchMode()) return;
|
||||
const rawMax = doctorInfo.value?.maxCustomerArchive;
|
||||
const hasMaxField = rawMax !== undefined && rawMax !== null && String(rawMax).trim() !== '';
|
||||
@ -1303,7 +1308,7 @@ const handleCreate = () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
// 新增流程:认证分支
|
||||
const startVerifyFlow = () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user