Compare commits
No commits in common. "69d1d54668d94b45ac77f0a5874daa4fface6711" and "a368474ffb76b1bc4bc927538b4a84ce0f50883e" have entirely different histories.
69d1d54668
...
a368474ffb
@ -34,10 +34,6 @@ const props = defineProps({
|
|||||||
title: {
|
title: {
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
placeholder: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
disableChange: {
|
disableChange: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@ -48,12 +44,7 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const placeholder = computed(() => {
|
const placeholder = computed(() => `请输入${props.name || ''}`)
|
||||||
if (typeof props.placeholder === 'string' && props.placeholder.trim()) {
|
|
||||||
return props.placeholder.trim()
|
|
||||||
}
|
|
||||||
return `请输入${props.name || ''}`
|
|
||||||
})
|
|
||||||
const value = computed(() => props.form && props.form && props.form[props.title] ? props.form[props.title] : '')
|
const value = computed(() => props.form && props.form && props.form[props.title] ? props.form[props.title] : '')
|
||||||
|
|
||||||
function change(e) {
|
function change(e) {
|
||||||
|
|||||||
@ -2,20 +2,20 @@
|
|||||||
<!-- <view class="text-danger px-10">{{ attrs.name }} {{ attrs.title }} {{ attrs.type }}</view> -->
|
<!-- <view class="text-danger px-10">{{ attrs.name }} {{ attrs.title }} {{ attrs.type }}</view> -->
|
||||||
<form-datepicker v-if="attrs.type === 'date'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
<form-datepicker v-if="attrs.type === 'date'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
||||||
@change="change" />
|
@change="change" />
|
||||||
<form-input v-else-if="attrs.type === 'input' || attrs.type === 'hisCardNo'" v-bind="attrs" :form="form"
|
<form-input v-else-if="attrs.type === 'input'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
||||||
:disableChange="disableChange" @change="change" />
|
@change="change" />
|
||||||
<form-radio v-else-if="attrs.type === 'radio'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
<form-radio v-else-if="attrs.type === 'radio'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
||||||
@change="change" />
|
@change="change" />
|
||||||
<form-region v-else-if="attrs.type === 'region'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
<form-region v-else-if="attrs.type === 'region'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
||||||
@change="change" />
|
@change="change" />
|
||||||
<form-select v-else-if="attrs.type === 'select'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
<form-select v-else-if="attrs.type === 'select'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
||||||
@change="change" />
|
@change="change" />
|
||||||
<form-evaluated-joint v-else-if="attrs.type === 'evaluatedJoint'" v-bind="attrs" :form="form"
|
<form-evaluated-joint v-else-if="attrs.type === 'evaluatedJoint'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
||||||
:disableChange="disableChange" @change="change" />
|
@change="change" />
|
||||||
<form-exercise-level v-else-if="attrs.type === 'exerciseLevel'" v-bind="attrs" :form="form"
|
<form-exercise-level v-else-if="attrs.type === 'exerciseLevel'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
||||||
:disableChange="disableChange" @change="change" />
|
@change="change" />
|
||||||
<form-select-and-other v-else-if="attrs.type === 'selectAndOther'" v-bind="attrs" :form="form"
|
<form-select-and-other v-else-if="attrs.type === 'selectAndOther'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
||||||
:disableChange="disableChange" @change="change" />
|
@change="change" />
|
||||||
<form-textarea v-else-if="attrs.type === 'textarea'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
<form-textarea v-else-if="attrs.type === 'textarea'" v-bind="attrs" :form="form" :disableChange="disableChange"
|
||||||
@change="change" />
|
@change="change" />
|
||||||
<form-mult-disease v-else-if="attrs.type === 'selfMultipleDiseases'" v-bind="attrs" :form="form" @change="change"
|
<form-mult-disease v-else-if="attrs.type === 'selfMultipleDiseases'" v-bind="attrs" :form="form" @change="change"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<template v-for="item in formItems" :key="item.title">
|
<template v-for="item in formItems" :key="item.title">
|
||||||
<form-cell v-if="item.cellType === 'formCellItem'" v-bind="item" :form="form" :disableChange="isDisableChange(item)"
|
<form-cell v-if="item.cellType === 'formCellItem'" v-bind="item" :form="form"
|
||||||
@change="change" @addRule="addRule" />
|
:disableChange="isDisableChange(item)" @change="change" @addRule="addRule" />
|
||||||
</template>
|
</template>
|
||||||
<form-cell />
|
<form-cell />
|
||||||
</template>
|
</template>
|
||||||
@ -33,7 +33,7 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const formCellType = ['input', 'select', 'date', 'radio', 'region', 'textarea', 'multiSelectAndOther', 'selectAndOther', 'selfMultipleDiseases', 'files', 'diagnosis', 'positiveFind', 'evaluatedJoint', 'exerciseLevel', 'hisCardNo'];
|
const formCellType = ['input', 'select', 'date', 'radio', 'region', 'textarea', 'multiSelectAndOther', 'selectAndOther', 'selfMultipleDiseases', 'files', 'diagnosis', 'positiveFind', 'evaluatedJoint', 'exerciseLevel'];
|
||||||
const formCellTitle = ['surgicalHistory'];
|
const formCellTitle = ['surgicalHistory'];
|
||||||
const customCellType = ['BMI', 'bloodPressure'];
|
const customCellType = ['BMI', 'bloodPressure'];
|
||||||
const disabledMap = computed(() => props.disableTitles.reduce((m, i) => {
|
const disabledMap = computed(() => props.disableTitles.reduce((m, i) => {
|
||||||
|
|||||||
14
pages.json
14
pages.json
@ -262,20 +262,6 @@
|
|||||||
"disableScroll": true
|
"disableScroll": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "step-edit-archive",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "新增档案",
|
|
||||||
"disableScroll": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "fill-his-archive",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "完善信息",
|
|
||||||
"disableScroll": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "archive-result",
|
"path": "archive-result",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@ -1,14 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<page-meta page-style="overflow: hidden;"></page-meta>
|
<view class="chat-page">
|
||||||
<view class="chat-page" :style="{ bottom: `${keyboardHeight}px` }">
|
|
||||||
<view v-if="session" class="patient-info-bar" @click="openPatientInfo">
|
|
||||||
<view class="patient-summary">
|
|
||||||
<text class="patient-name">{{ patientDisplayName }}</text>
|
|
||||||
<text v-if="patientDetail" class="patient-detail">{{ patientDetail }}</text>
|
|
||||||
</view>
|
|
||||||
<text class="patient-action">查看/修改</text>
|
|
||||||
<text class="patient-arrow">›</text>
|
|
||||||
</view>
|
|
||||||
<scroll-view scroll-y class="chat-content" :scroll-into-view="bottomId">
|
<scroll-view scroll-y class="chat-content" :scroll-into-view="bottomId">
|
||||||
<view class="message-list">
|
<view class="message-list">
|
||||||
<view v-for="(item, index) in messages" :key="item._id" :id="`message-${item._id}`" class="message-item" :class="`message-${item.sender}`">
|
<view v-for="(item, index) in messages" :key="item._id" :id="`message-${item._id}`" class="message-item" :class="`message-${item.sender}`">
|
||||||
@ -16,7 +7,7 @@
|
|||||||
<evaluation-card v-if="item.messageType === 'consult_ended' && (item.rateId || session?.rateId)" class="rate-card" :extension="{ rateId: item.rateId || session.rateId }" :corp-id="corpId" :doctor-info="rateAssistantInfo" />
|
<evaluation-card v-if="item.messageType === 'consult_ended' && (item.rateId || session?.rateId)" class="rate-card" :extension="{ rateId: item.rateId || session.rateId }" :corp-id="corpId" :doctor-info="rateAssistantInfo" />
|
||||||
<view v-else-if="item.sender === 'system' && item.messageType !== 'risk_notice'" class="system-message" :class="{ warn: item.messageType === 'sensitive_notice' }">{{ displayContent(item) }}</view>
|
<view v-else-if="item.sender === 'system' && item.messageType !== 'risk_notice'" class="system-message" :class="{ warn: item.messageType === 'sensitive_notice' }">{{ displayContent(item) }}</view>
|
||||||
<view v-else-if="item.messageType !== 'risk_notice'" class="message-content">
|
<view v-else-if="item.messageType !== 'risk_notice'" class="message-content">
|
||||||
<image v-if="item.sender === 'assistant'" class="avatar assistant-avatar" :src="assistantAvatar" mode="aspectFill" @error="handleAssistantAvatarError" />
|
<image v-if="item.sender === 'assistant'" class="avatar assistant-avatar" src="/static/home/ai-consult-assistant.png" mode="aspectFill" />
|
||||||
<view class="message-bubble-container">
|
<view class="message-bubble-container">
|
||||||
<view v-if="item.sender === 'assistant'" class="username-label">{{ assistantDisplayName }}</view>
|
<view v-if="item.sender === 'assistant'" class="username-label">{{ assistantDisplayName }}</view>
|
||||||
<view class="message-bubble" :class="{ pending: item._sendStatus === 'pending' }">
|
<view class="message-bubble" :class="{ pending: item._sendStatus === 'pending' }">
|
||||||
@ -28,13 +19,13 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="waitingAi" class="message-item message-assistant">
|
<view v-if="waitingAi" class="message-item message-assistant">
|
||||||
<view class="message-content"><image class="avatar assistant-avatar" :src="assistantAvatar" mode="aspectFill" @error="handleAssistantAvatarError" /><view class="message-bubble-container"><view class="username-label">{{ assistantDisplayName }}</view><view class="message-bubble thinking"><view class="thinking-dot"></view><view class="thinking-dot"></view><view class="thinking-dot"></view></view></view></view>
|
<view class="message-content"><image class="avatar assistant-avatar" src="/static/home/ai-consult-assistant.png" mode="aspectFill" /><view class="message-bubble-container"><view class="username-label">{{ assistantDisplayName }}</view><view class="message-bubble thinking"><view class="thinking-dot"></view><view class="thinking-dot"></view><view class="thinking-dot"></view></view></view></view>
|
||||||
</view>
|
</view>
|
||||||
<view id="bottom" />
|
<view id="bottom" />
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view v-if="active" class="input-section">
|
<view v-if="active" class="input-section">
|
||||||
<textarea v-model="content" class="text-input" maxlength="1000" auto-height fixed confirm-type="send" :show-confirm-bar="false" :adjust-position="false" placeholder="请输入消息" @confirm="send" />
|
<textarea v-model="content" class="text-input" maxlength="1000" auto-height confirm-type="send" :show-confirm-bar="false" placeholder="请输入消息" @confirm="send" />
|
||||||
<button class="send-btn" :disabled="!content.trim()" @click="send">发送</button>
|
<button class="send-btn" :disabled="!content.trim()" @click="send">发送</button>
|
||||||
</view>
|
</view>
|
||||||
<view v-else class="ended">本次咨询已结束</view>
|
<view v-else class="ended">本次咨询已结束</view>
|
||||||
@ -43,7 +34,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, nextTick, computed } from 'vue';
|
import { ref, nextTick, computed } from 'vue';
|
||||||
import { onLoad, onShow, onUnload } from '@dcloudio/uni-app';
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
import useAccountStore from '@/store/account';
|
import useAccountStore from '@/store/account';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
@ -54,28 +45,14 @@ const { openid } = storeToRefs(useAccountStore());
|
|||||||
const corpId = ref('');
|
const corpId = ref('');
|
||||||
const sessionId = ref('');
|
const sessionId = ref('');
|
||||||
const session = ref(null);
|
const session = ref(null);
|
||||||
const patientInfo = ref(null);
|
|
||||||
const messages = ref([]);
|
const messages = ref([]);
|
||||||
const content = ref('');
|
const content = ref('');
|
||||||
const pendingRequestCount = ref(0);
|
const pendingRequestCount = ref(0);
|
||||||
const waitingAi = ref(false);
|
const waitingAi = ref(false);
|
||||||
const bottomId = ref('');
|
const bottomId = ref('');
|
||||||
const active = ref(false);
|
const active = ref(false);
|
||||||
const keyboardHeight = ref(0);
|
|
||||||
const avatarLoadFailed = ref(false);
|
|
||||||
const defaultAssistantAvatar = '/static/home/ai-consult-assistant.png';
|
|
||||||
const assistantDisplayName = computed(() => removeAiLabel(session.value?.assistantName, '咨询助理'));
|
const assistantDisplayName = computed(() => removeAiLabel(session.value?.assistantName, '咨询助理'));
|
||||||
const assistantAvatar = computed(() => avatarLoadFailed.value ? defaultAssistantAvatar : (session.value?.assistantAvatar || defaultAssistantAvatar));
|
const rateAssistantInfo = computed(() => ({ name: assistantDisplayName.value, title: '咨询助理', department: session.value?.teamName || '', avatar: '' }));
|
||||||
const rateAssistantInfo = computed(() => ({ name: assistantDisplayName.value, title: '咨询助理', department: session.value?.teamName || '', avatar: assistantAvatar.value }));
|
|
||||||
const patientDisplayName = computed(() => patientInfo.value?.name || session.value?.customerName || '未建档患者');
|
|
||||||
const patientDetail = computed(() => {
|
|
||||||
const patient = patientInfo.value || {};
|
|
||||||
const details = [];
|
|
||||||
if (patient.sex) details.push(patient.sex);
|
|
||||||
if (patient.age !== '' && patient.age !== null && patient.age !== undefined) details.push(`${patient.age}岁`);
|
|
||||||
if (patient.relationship) details.push(patient.relationship);
|
|
||||||
return details.join(' · ');
|
|
||||||
});
|
|
||||||
|
|
||||||
function displayContent(item) {
|
function displayContent(item) {
|
||||||
const value = item?.content || '';
|
const value = item?.content || '';
|
||||||
@ -108,29 +85,10 @@ async function scrollToBottom() {
|
|||||||
await nextTick();
|
await nextTick();
|
||||||
bottomId.value = 'bottom';
|
bottomId.value = 'bottom';
|
||||||
}
|
}
|
||||||
function handleKeyboardHeightChange(res) {
|
|
||||||
keyboardHeight.value = Math.max(0, Number(res?.height) || 0);
|
|
||||||
if (keyboardHeight.value > 0) scrollToBottom();
|
|
||||||
}
|
|
||||||
function handleAssistantAvatarError() {
|
|
||||||
avatarLoadFailed.value = true;
|
|
||||||
}
|
|
||||||
function openPatientInfo() {
|
|
||||||
const customerId = session.value?.archiveCustomerId;
|
|
||||||
if (!customerId) return uni.showToast({ title: '暂无可查看的患者档案', icon: 'none' });
|
|
||||||
const params = [
|
|
||||||
`teamId=${encodeURIComponent(session.value?.teamId || '')}`,
|
|
||||||
`corpId=${encodeURIComponent(corpId.value)}`,
|
|
||||||
`id=${encodeURIComponent(customerId)}`,
|
|
||||||
];
|
|
||||||
uni.navigateTo({ url: `/pages/archive/edit-archive?${params.join('&')}` });
|
|
||||||
}
|
|
||||||
async function detail() {
|
async function detail() {
|
||||||
const res = await api('getAiConsultSessionDetail', { corpId: corpId.value, sessionId: sessionId.value, miniAppId: openid.value || uni.getStorageSync('openid') }, false);
|
const res = await api('getAiConsultSessionDetail', { corpId: corpId.value, sessionId: sessionId.value, miniAppId: openid.value || uni.getStorageSync('openid') }, false);
|
||||||
if (!res?.success) return uni.showToast({ title: removeAiLabel(res?.message, '加载失败'), icon: 'none' });
|
if (!res?.success) return uni.showToast({ title: removeAiLabel(res?.message, '加载失败'), icon: 'none' });
|
||||||
session.value = res.data.session;
|
session.value = res.data.session;
|
||||||
avatarLoadFailed.value = false;
|
|
||||||
patientInfo.value = res.data.patient || null;
|
|
||||||
messages.value = res.data.messages || [];
|
messages.value = res.data.messages || [];
|
||||||
active.value = session.value.status === 'active';
|
active.value = session.value.status === 'active';
|
||||||
uni.setNavigationBarTitle({ title: assistantDisplayName.value });
|
uni.setNavigationBarTitle({ title: assistantDisplayName.value });
|
||||||
@ -163,55 +121,41 @@ async function send() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad(opts => {
|
onLoad(opts => { corpId.value = opts.corpId; sessionId.value = opts.sessionId; detail(); });
|
||||||
corpId.value = opts.corpId;
|
|
||||||
sessionId.value = opts.sessionId;
|
|
||||||
uni.onKeyboardHeightChange(handleKeyboardHeightChange);
|
|
||||||
detail();
|
|
||||||
});
|
|
||||||
onShow(detail);
|
onShow(detail);
|
||||||
onUnload(() => {
|
|
||||||
uni.offKeyboardHeightChange(handleKeyboardHeightChange);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.chat-page { position: fixed; top: 0; right: 0; left: 0; display: flex; flex-direction: column; background: #f5f7fb; overflow: hidden; }
|
.chat-page { height: 100vh; display: flex; flex-direction: column; background: #f5f7fb; overflow: hidden; }
|
||||||
.patient-info-bar { height: 80rpx; padding: 0 24rpx; display: flex; align-items: center; box-sizing: border-box; background: #fff; border-bottom: 1rpx solid #edf0f4; flex-shrink: 0; }
|
|
||||||
.patient-summary { display: flex; align-items: center; gap: 16rpx; min-width: 0; flex: 1; }
|
|
||||||
.patient-name { max-width: 220rpx; color: #283242; font-size: 30rpx; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
||||||
.patient-detail { min-width: 0; color: #7d8590; font-size: 27rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
||||||
.patient-action { margin-left: 16rpx; color: #0877f1; font-size: 26rpx; white-space: nowrap; flex-shrink: 0; }
|
|
||||||
.patient-arrow { margin-left: 6rpx; color: #0877f1; font-size: 34rpx; line-height: 1; flex-shrink: 0; }
|
|
||||||
.chat-content { flex: 1; height: 0; box-sizing: border-box; }
|
.chat-content { flex: 1; height: 0; box-sizing: border-box; }
|
||||||
.message-list { padding: 28rpx 24rpx 40rpx; }
|
.message-list { padding: 28rpx 24rpx 40rpx; }
|
||||||
.message-item { margin-bottom: 28rpx; }
|
.message-item { margin-bottom: 28rpx; }
|
||||||
.message-content { display: flex; align-items: flex-start; gap: 16rpx; }
|
.message-content { display: flex; align-items: flex-start; gap: 16rpx; }
|
||||||
.message-patient .message-content { justify-content: flex-end; }
|
.message-patient .message-content { justify-content: flex-end; }
|
||||||
.avatar { width: 72rpx; height: 72rpx; flex: 0 0 72rpx; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-size: 26rpx; font-weight: 600; }
|
.avatar { width: 72rpx; height: 72rpx; flex: 0 0 72rpx; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-size: 24rpx; font-weight: 600; }
|
||||||
.assistant-avatar { color: #fff; background: linear-gradient(135deg, #4d93ff, #0877f1); }
|
.assistant-avatar { color: #fff; background: linear-gradient(135deg, #4d93ff, #0877f1); }
|
||||||
.patient-avatar { color: #0877f1; background: #e2efff; }
|
.patient-avatar { color: #0877f1; background: #e2efff; }
|
||||||
.message-bubble-container { max-width: 74%; min-width: 0; }
|
.message-bubble-container { max-width: 74%; min-width: 0; }
|
||||||
.message-patient .message-bubble-container { display: flex; flex-direction: column; align-items: flex-end; }
|
.message-patient .message-bubble-container { display: flex; flex-direction: column; align-items: flex-end; }
|
||||||
.username-label { margin: 2rpx 0 10rpx; color: #8a919f; font-size: 26rpx; line-height: 34rpx; }
|
.username-label { margin: 2rpx 0 10rpx; color: #8a919f; font-size: 24rpx; line-height: 32rpx; }
|
||||||
.message-bubble { padding: 18rpx 22rpx; border-radius: 8rpx 22rpx 22rpx; background: #fff; box-shadow: 0 4rpx 14rpx rgba(17, 48, 89, .06); }
|
.message-bubble { padding: 18rpx 22rpx; border-radius: 8rpx 22rpx 22rpx; background: #fff; box-shadow: 0 4rpx 14rpx rgba(17, 48, 89, .06); }
|
||||||
.message-patient .message-bubble { color: #fff; border-radius: 22rpx 8rpx 22rpx 22rpx; background: #0877f1; box-shadow: 0 4rpx 14rpx rgba(8, 119, 241, .18); }
|
.message-patient .message-bubble { color: #fff; border-radius: 22rpx 8rpx 22rpx 22rpx; background: #0877f1; box-shadow: 0 4rpx 14rpx rgba(8, 119, 241, .18); }
|
||||||
.message-bubble.pending { opacity: .72; }
|
.message-bubble.pending { opacity: .72; }
|
||||||
.message-text { color: inherit; font-size: 32rpx; line-height: 48rpx; white-space: pre-wrap; word-break: break-word; }
|
.message-text { color: inherit; font-size: 30rpx; line-height: 46rpx; white-space: pre-wrap; word-break: break-word; }
|
||||||
.time-divider { margin: 2rpx 0 22rpx; color: #a0a6b0; text-align: center; font-size: 25rpx; }
|
.time-divider { margin: 2rpx 0 22rpx; color: #a0a6b0; text-align: center; font-size: 23rpx; }
|
||||||
.system-message { display: inline-block; margin: 0 auto; padding: 10rpx 20rpx; color: #79808c; background: #e9ecf1; border-radius: 22rpx; font-size: 26rpx; line-height: 38rpx; }
|
.system-message { display: inline-block; margin: 0 auto; padding: 10rpx 20rpx; color: #79808c; background: #e9ecf1; border-radius: 22rpx; font-size: 24rpx; line-height: 36rpx; }
|
||||||
.message-system { text-align: center; }
|
.message-system { text-align: center; }
|
||||||
.system-message.warn { color: #d84256; background: #fff0f1; }
|
.system-message.warn { color: #d84256; background: #fff0f1; }
|
||||||
.send-status { margin-top: 8rpx; color: #e34d59; font-size: 25rpx; }
|
.send-status { margin-top: 8rpx; color: #e34d59; font-size: 23rpx; }
|
||||||
.thinking { display: flex; align-items: center; gap: 8rpx; min-width: 84rpx; padding: 26rpx 28rpx; }
|
.thinking { display: flex; align-items: center; gap: 8rpx; min-width: 84rpx; padding: 26rpx 28rpx; }
|
||||||
.thinking-dot { width: 10rpx; height: 10rpx; border-radius: 50%; background: #7f8998; animation: thinking 1.2s infinite ease-in-out; }
|
.thinking-dot { width: 10rpx; height: 10rpx; border-radius: 50%; background: #7f8998; animation: thinking 1.2s infinite ease-in-out; }
|
||||||
.thinking-dot:nth-child(2) { animation-delay: .16s; }
|
.thinking-dot:nth-child(2) { animation-delay: .16s; }
|
||||||
.thinking-dot:nth-child(3) { animation-delay: .32s; }
|
.thinking-dot:nth-child(3) { animation-delay: .32s; }
|
||||||
@keyframes thinking { 0%, 60%, 100% { opacity: .35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-7rpx); } }
|
@keyframes thinking { 0%, 60%, 100% { opacity: .35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-7rpx); } }
|
||||||
.input-section { display: flex; align-items: flex-end; gap: 16rpx; padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom)); background: #fff; border-top: 1rpx solid #edf0f4; }
|
.input-section { display: flex; align-items: flex-end; gap: 16rpx; padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom)); background: #fff; border-top: 1rpx solid #edf0f4; }
|
||||||
.text-input { flex: 1; max-height: 180rpx; padding: 16rpx 20rpx; box-sizing: border-box; color: #283242; background: #f3f5f8; border-radius: 12rpx; font-size: 31rpx; line-height: 42rpx; }
|
.text-input { flex: 1; max-height: 180rpx; padding: 16rpx 20rpx; box-sizing: border-box; color: #283242; background: #f3f5f8; border-radius: 12rpx; font-size: 29rpx; line-height: 40rpx; }
|
||||||
.send-btn { flex: 0 0 auto; height: 72rpx; margin: 0; padding: 0 26rpx; color: #fff; background: #0877f1; border-radius: 12rpx; font-size: 29rpx; line-height: 72rpx; }
|
.send-btn { flex: 0 0 auto; height: 72rpx; margin: 0; padding: 0 26rpx; color: #fff; background: #0877f1; border-radius: 12rpx; font-size: 27rpx; line-height: 72rpx; }
|
||||||
.send-btn[disabled] { color: #fff; background: #a9cfff; }
|
.send-btn[disabled] { color: #fff; background: #a9cfff; }
|
||||||
.rate-card { display: block; margin: 20rpx 0 0; }
|
.rate-card { display: block; margin: 20rpx 0 0; }
|
||||||
.ended { padding: 30rpx; color: #7d8590; text-align: center; background: #fff; font-size: 29rpx; }
|
.ended { padding: 30rpx; color: #7d8590; text-align: center; background: #fff; font-size: 27rpx; }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -109,15 +109,6 @@ async function getMatchedHisArchive(data) {
|
|||||||
customer.value = data;
|
customer.value = data;
|
||||||
corpName.value = res.corpName || '';
|
corpName.value = res.corpName || '';
|
||||||
showBindHisPopup.value = true;
|
showBindHisPopup.value = true;
|
||||||
} else if (res && res.isCustomerInfoNotMatchQueryPlans) {
|
|
||||||
try {
|
|
||||||
await confirm('请完善信息', { cancelText: '取消', confirmText: '确认' });
|
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/archive/fill-his-archive?teamId=${teamId.value}&corpId=${corpId.value}&id=${data._id}`
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
// 用户取消后停留在档案管理页。
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
confirm(res?.message || '获取档案信息失败', { showCancel: false })
|
confirm(res?.message || '获取档案信息失败', { showCancel: false })
|
||||||
}
|
}
|
||||||
@ -142,7 +133,6 @@ useLoad(options => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
useShow(() => {
|
useShow(() => {
|
||||||
console.log('show~~~~~~')
|
|
||||||
if (teamId.value && corpId.value) {
|
if (teamId.value && corpId.value) {
|
||||||
getMembers()
|
getMembers()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,9 +10,8 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<!-- :showCancel="customerId ? true : false" -->
|
<button-footer :showCancel="customerId ? true : false" cancelText="删除"
|
||||||
<button-footer :showCancel="false" cancelText="删除" :confirmText="healthTypes.length ? '下一步' : '保存'"
|
:confirmText="healthTypes.length ? '下一步' : '保存'" @cancel="unBindArchive()" @confirm="confirm()" />
|
||||||
@cancel="unBindArchive()" @confirm="confirm()" />
|
|
||||||
</template>
|
</template>
|
||||||
</full-page>
|
</full-page>
|
||||||
<bind-popup :customers="customers" :corpName="corpName" :enableHis="enableHis" :visible="visible"
|
<bind-popup :customers="customers" :corpName="corpName" :enableHis="enableHis" :visible="visible"
|
||||||
@ -50,9 +49,9 @@ const referenceCustomerId = ref('');
|
|||||||
const customer = ref({});
|
const customer = ref({});
|
||||||
const customerId = ref('');
|
const customerId = ref('');
|
||||||
const customers = ref([]);
|
const customers = ref([]);
|
||||||
// const disableTitles = ref(['mobile']);
|
const disableTitles = ref(['mobile']);
|
||||||
const form = ref({});
|
const form = ref({});
|
||||||
const teamFormItems = ref([]);
|
const formItems = ref([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const teamId = ref('');
|
const teamId = ref('');
|
||||||
const tempRef = ref(null);
|
const tempRef = ref(null);
|
||||||
@ -63,33 +62,11 @@ const healthTypes = ref([]);
|
|||||||
const enableHis = ref(false);
|
const enableHis = ref(false);
|
||||||
const source = ref('');
|
const source = ref('');
|
||||||
const redirectUrl = ref('');
|
const redirectUrl = ref('');
|
||||||
const archiveQueryPlans = ref([]);
|
|
||||||
const pageOptions = ref({});
|
|
||||||
|
|
||||||
const formData = computed(() => {
|
const formData = computed(() => {
|
||||||
if (customerId.value) {
|
|
||||||
return { ...customer.value, ...form.value }
|
|
||||||
}
|
|
||||||
return { ...customer.value, ...form.value, mobile: account.value?.mobile }
|
return { ...customer.value, ...form.value, mobile: account.value?.mobile }
|
||||||
});
|
});
|
||||||
|
|
||||||
const formItems = computed(() => {
|
|
||||||
return teamFormItems.value.map(i => {
|
|
||||||
if (i.title === 'mobile' && formData.value.mobile && formData.value.mobile === account.value?.mobile) {
|
|
||||||
return { ...i, appendText: '(授权手机号)' }
|
|
||||||
}
|
|
||||||
return i
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const disableTitles = computed(() => {
|
|
||||||
const list = ['mobile'];
|
|
||||||
if (customer.value._id && customer.value.isConnectHis) {
|
|
||||||
list.push('name', 'idCard', 'sex', 'age', 'birthday')
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
})
|
|
||||||
|
|
||||||
function change({ title, value }) {
|
function change({ title, value }) {
|
||||||
if (title) {
|
if (title) {
|
||||||
form.value[title] = value;
|
form.value[title] = value;
|
||||||
@ -128,12 +105,36 @@ function preProcessFrom() {
|
|||||||
form.value.relationship = '本人';
|
form.value.relationship = '本人';
|
||||||
}
|
}
|
||||||
const cardTypeItem = formItems.value.find(item => item.title === 'cardType');
|
const cardTypeItem = formItems.value.find(item => item.title === 'cardType');
|
||||||
const cardTypeRange = cardTypeItem && Array.isArray(cardTypeItem.range) ? cardTypeItem.range : [];
|
const cardTypeRange = cardTypeItem && Array.isArray(cardTypeItem.range) ? relationItem.range : [];
|
||||||
if (cardTypeRange.includes('身份证')) {
|
if (cardTypeRange.includes('身份证')) {
|
||||||
form.value.cardType = '身份证';
|
form.value.cardType = '身份证';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产品要求, 编辑的情况下 姓名、身份证号、性别、年龄、出生年月
|
||||||
|
* 建档成功或者绑定档案成功后,姓名、身份证号、性别、年龄、出生年月。如果有内容的都不允许修改。没有内容的则允许编辑。
|
||||||
|
*/
|
||||||
|
function setDisabledTitles(data) {
|
||||||
|
const list = ['mobile'];
|
||||||
|
if (data.name) {
|
||||||
|
list.push('name');
|
||||||
|
}
|
||||||
|
if (data.idCard) {
|
||||||
|
list.push('idCard');
|
||||||
|
}
|
||||||
|
if (data.sex) {
|
||||||
|
list.push('sex');
|
||||||
|
}
|
||||||
|
if (data.age) {
|
||||||
|
list.push('age');
|
||||||
|
}
|
||||||
|
if (data.birthday) {
|
||||||
|
list.push('birthday');
|
||||||
|
}
|
||||||
|
disableTitles.value = list;
|
||||||
|
}
|
||||||
|
|
||||||
async function addArchive() {
|
async function addArchive() {
|
||||||
if (loading.value) return;
|
if (loading.value) return;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@ -229,10 +230,6 @@ async function bindArchive(customerId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
if (await initArchiveQueryConfig()) return;
|
|
||||||
if (referenceCustomerId.value) {
|
|
||||||
getReferenceCustomer();
|
|
||||||
}
|
|
||||||
if (customerId.value) {
|
if (customerId.value) {
|
||||||
await getCustomer();
|
await getCustomer();
|
||||||
} else {
|
} else {
|
||||||
@ -254,39 +251,6 @@ async function init() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initArchiveQueryConfig() {
|
|
||||||
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);
|
|
||||||
if (archiveQueryPlans.value.length) {
|
|
||||||
redirectArchivePage('step-edit-archive');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function redirectArchivePage(page) {
|
|
||||||
const query = Object.entries(pageOptions.value)
|
|
||||||
.filter(([, value]) => value !== undefined && value !== null && value !== '')
|
|
||||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
|
||||||
.join('&');
|
|
||||||
uni.redirectTo({
|
|
||||||
url: `/pages/archive/${page}${query ? `?${query}` : ''}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getExperienceCouponBindArchive() {
|
async function getExperienceCouponBindArchive() {
|
||||||
const res = await api('getCustomerByCustomerId', { corpId: corpId.value, customerId: bindCustomerId.value });
|
const res = await api('getCustomerByCustomerId', { corpId: corpId.value, customerId: bindCustomerId.value });
|
||||||
const data = res && res.success && res.data ? res.data : null;
|
const data = res && res.success && res.data ? res.data : null;
|
||||||
@ -307,7 +271,12 @@ async function getArchives() {
|
|||||||
async function getBaseForm() {
|
async function getBaseForm() {
|
||||||
const res = await api('getTeamBaseInfo', { corpId: corpId.value, teamId: teamId.value });
|
const res = await api('getTeamBaseInfo', { corpId: corpId.value, teamId: teamId.value });
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
teamFormItems.value = Array.isArray(res.data) ? res.data : [];
|
formItems.value = Array.isArray(res.data) ? res.data : [];
|
||||||
|
const mobileIndex = formItems.value.findIndex(item => item.title === 'mobile');
|
||||||
|
if (mobileIndex > -1) {
|
||||||
|
formItems.value[mobileIndex].appendText = `(授权手机号)`;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
toast(res?.message || '查询失败');
|
toast(res?.message || '查询失败');
|
||||||
return Promise.reject()
|
return Promise.reject()
|
||||||
@ -318,6 +287,7 @@ async function getCustomer() {
|
|||||||
const res = await api('getCustomerByCustomerId', { customerId: customerId.value });
|
const res = await api('getCustomerByCustomerId', { customerId: customerId.value });
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
customer.value = res.data;
|
customer.value = res.data;
|
||||||
|
setDisabledTitles(res.data)
|
||||||
} else {
|
} else {
|
||||||
await toast(res?.message || '查询档案信息失败');
|
await toast(res?.message || '查询档案信息失败');
|
||||||
uni.navigateBack();
|
uni.navigateBack();
|
||||||
@ -369,7 +339,6 @@ async function getTeam(corpId, teamId, customerId) {
|
|||||||
|
|
||||||
|
|
||||||
onLoad(options => {
|
onLoad(options => {
|
||||||
pageOptions.value = { ...options };
|
|
||||||
teamId.value = options.teamId;
|
teamId.value = options.teamId;
|
||||||
corpId.value = options.corpId;
|
corpId.value = options.corpId;
|
||||||
customerId.value = options.id || '';
|
customerId.value = options.id || '';
|
||||||
@ -378,6 +347,9 @@ onLoad(options => {
|
|||||||
referenceCustomerId.value = options.referenceCustomerId || '';
|
referenceCustomerId.value = options.referenceCustomerId || '';
|
||||||
source.value = options.source || '';
|
source.value = options.source || '';
|
||||||
redirectUrl.value = options.redirectUrl || '';
|
redirectUrl.value = options.redirectUrl || '';
|
||||||
|
if (referenceCustomerId.value) {
|
||||||
|
getReferenceCustomer();
|
||||||
|
}
|
||||||
uni.setNavigationBarTitle({ title: customerId.value ? '编辑档案' : '新增档案' })
|
uni.setNavigationBarTitle({ title: customerId.value ? '编辑档案' : '新增档案' })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -1,213 +0,0 @@
|
|||||||
<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>
|
|
||||||
@ -1,547 +0,0 @@
|
|||||||
<template>
|
|
||||||
<full-page v-if="!visible" :customScroll="empty" :title="queryHisTitles.length">
|
|
||||||
<view v-if="formItems.length === 0" class="flex items-center justify-center h-full">
|
|
||||||
<empty-data />
|
|
||||||
</view>
|
|
||||||
<view v-else class="p-15">
|
|
||||||
<view class="bg-white rounded shadow-lg">
|
|
||||||
<form-template v-if="step === 0" ref="tempRef" :disableTitles="disableTitles" :items="hisQueryFormItems"
|
|
||||||
:form="formData" @change="change($event)" />
|
|
||||||
<form-template v-else-if="step === 1" ref="tempRef" :disableTitles="disableTitles" :items="restFormItems"
|
|
||||||
:form="formData" @change="change($event)" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<template #footer>
|
|
||||||
<!-- :showCancel="customerId ? true : false" -->
|
|
||||||
<button-footer v-if="step === 0" :showCancel="false" confirmText="下一步" @confirm="queryHisArchives()" />
|
|
||||||
<button-footer v-else-if="step === 1" :showCancel="false" cancelText="" confirmText=" 保存" @cancel="step = 0"
|
|
||||||
@confirm="confirm()" />
|
|
||||||
</template>
|
|
||||||
</full-page>
|
|
||||||
<bind-popup :customers="customers" :corpName="corpName" :enableHis="enableHis" :visible="visible"
|
|
||||||
@close="visible = false" @confirm="bindArchive($event)" />
|
|
||||||
<verify-popup :visible="verifyVisible" @close="verifyVisible = false" />
|
|
||||||
</template>
|
|
||||||
<script setup>
|
|
||||||
import { computed, ref, watch } from 'vue';
|
|
||||||
import { storeToRefs } from 'pinia';
|
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import useGuard from '@/hooks/useGuard';
|
|
||||||
import useAccount from '@/store/account';
|
|
||||||
import api from '@/utils/api';
|
|
||||||
import { toast, confirm as uniConfirm, loading as waiting, hideLoading } from '@/utils/widget';
|
|
||||||
import validate from '@/utils/validate';
|
|
||||||
import { set } from "@/utils/cache";
|
|
||||||
|
|
||||||
import ButtonFooter from '@/components/button-footer.vue';
|
|
||||||
import EmptyData from '@/components/empty-data.vue';
|
|
||||||
import FullPage from '@/components/full-page.vue';
|
|
||||||
import bindPopup from './bind-popup.vue';
|
|
||||||
import verifyPopup from './verify-popup.vue';
|
|
||||||
import formTemplate from '@/components/form-template/index.vue';
|
|
||||||
|
|
||||||
const empty = ref(false)
|
|
||||||
const { useLoad } = useGuard();
|
|
||||||
const { account, externalUserId } = storeToRefs(useAccount());
|
|
||||||
const { getExternalUserId } = useAccount()
|
|
||||||
const corpId = ref('');
|
|
||||||
const corpName = ref('');
|
|
||||||
const corpUserId = ref('');
|
|
||||||
const bindCustomerId = ref('');
|
|
||||||
const referenceCustomerId = ref('');
|
|
||||||
const customer = ref({});
|
|
||||||
const customerId = ref('');
|
|
||||||
const customers = ref([]);
|
|
||||||
// const disableTitles = ref(['mobile']);
|
|
||||||
const form = ref({});
|
|
||||||
const teamFormItems = ref([]);
|
|
||||||
const loading = ref(false);
|
|
||||||
const teamId = ref('');
|
|
||||||
const tempRef = ref(null);
|
|
||||||
const verifyVisible = ref(false);
|
|
||||||
const visible = ref(false);
|
|
||||||
const referenceCustomer = ref(null)
|
|
||||||
const healthTypes = ref([]);
|
|
||||||
const enableHis = ref(false);
|
|
||||||
const source = ref('');
|
|
||||||
const redirectUrl = ref('');
|
|
||||||
const archiveQueryPlans = ref([]);
|
|
||||||
const pageOptions = ref({});
|
|
||||||
const step = ref(0);
|
|
||||||
const hisArchive = ref(null);
|
|
||||||
const queryingHisArchives = ref(false);
|
|
||||||
const queryHisTitles = computed(() => {
|
|
||||||
const res = archiveQueryPlans.value.length ? ['name', 'mobile'] : [];
|
|
||||||
archiveQueryPlans.value.forEach(item => {
|
|
||||||
getPlanFields(item).forEach(field => {
|
|
||||||
if (!res.includes(field.fieldKey.trim())) {
|
|
||||||
res.push(field.fieldKey.trim())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return customerId.value ? [] : res;
|
|
||||||
})
|
|
||||||
|
|
||||||
const formItems = computed(() => {
|
|
||||||
return teamFormItems.value.map(i => {
|
|
||||||
if (i.title === 'mobile' && formData.value.mobile && formData.value.mobile === account.value?.mobile) {
|
|
||||||
return { ...i, appendText: '(授权手机号)' }
|
|
||||||
}
|
|
||||||
return i
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const hisQueryFormItems = computed(() => formItems.value.filter(i => queryHisTitles.value.includes(i.title)));
|
|
||||||
const restFormItems = computed(() => formItems.value.filter(i => !queryHisTitles.value.includes(i.title)));
|
|
||||||
|
|
||||||
const formData = computed(() => {
|
|
||||||
if (customerId.value) {
|
|
||||||
return { ...customer.value, ...form.value }
|
|
||||||
}
|
|
||||||
return { ...customer.value, ...form.value, mobile: account.value?.mobile }
|
|
||||||
});
|
|
||||||
|
|
||||||
const disableTitles = computed(() => {
|
|
||||||
const list = ['mobile'];
|
|
||||||
if (customer.value._id && customer.value.isConnectHis) {
|
|
||||||
list.push('name', 'idCard', 'sex', 'age', 'birthday')
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
})
|
|
||||||
|
|
||||||
function change({ title, value }) {
|
|
||||||
if (title) {
|
|
||||||
form.value[title] = value;
|
|
||||||
}
|
|
||||||
if (title == 'idCard') {
|
|
||||||
const [isIdCard, birthday, gender] = validate.isChinaId(value);
|
|
||||||
if (isIdCard) {
|
|
||||||
form.value.birthday = birthday;
|
|
||||||
form.value.sex = gender == 'MALE' ? '男' : '女';
|
|
||||||
const age = dayjs().diff(birthday, 'year');
|
|
||||||
form.value.age = Math.max(1, age);
|
|
||||||
}
|
|
||||||
} else if (title === 'birthday' && formItems.value.some(i => i.title === 'age') && value && dayjs(value).valueOf()) {
|
|
||||||
const age = dayjs().diff(value, 'year');
|
|
||||||
form.value.age = Math.max(1, age);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async function queryHisArchives() {
|
|
||||||
if (queryingHisArchives.value) return;
|
|
||||||
waiting()
|
|
||||||
const matchedPlans = archiveQueryPlans.value.filter(isQueryPlanSatisfied);
|
|
||||||
if (!matchedPlans.length) {
|
|
||||||
hisArchive.value = null;
|
|
||||||
step.value = 1;
|
|
||||||
hideLoading()
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
queryingHisArchives.value = true;
|
|
||||||
try {
|
|
||||||
const responses = await Promise.all(matchedPlans.map(async (plan) => {
|
|
||||||
const conditions = getQueryConditions(plan);
|
|
||||||
try {
|
|
||||||
const res = await api('getHisCustomerArchive', {
|
|
||||||
corpId: corpId.value,
|
|
||||||
planId: plan.planId || plan.schemeId || '',
|
|
||||||
...conditions,
|
|
||||||
}, false);
|
|
||||||
return {
|
|
||||||
plan,
|
|
||||||
conditions,
|
|
||||||
list: res && Array.isArray(res.list) ? res.list : [],
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
return { plan, conditions, list: [] };
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
for (const response of responses) {
|
|
||||||
const archive = response.list.find((item) => isHisArchiveMatched(item, response.plan, response.conditions));
|
|
||||||
if (archive) {
|
|
||||||
hisArchive.value = archive;
|
|
||||||
step.value = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const responseWithArchives = responses.find((response) => response.list.length);
|
|
||||||
if (!responseWithArchives) {
|
|
||||||
await uniConfirm('没有查询到患者院内档案', { cancelText: '修改信息', confirmText: '新建档案' });
|
|
||||||
archiveQueryPlans.value = []
|
|
||||||
hisArchive.value = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mismatchMessage = getMismatchMessage(responseWithArchives);
|
|
||||||
try {
|
|
||||||
await uniConfirm(mismatchMessage, { cancelText: '修改信息', confirmText: '新建档案' });
|
|
||||||
archiveQueryPlans.value = []
|
|
||||||
hisArchive.value = null;
|
|
||||||
step.value = 1;
|
|
||||||
} catch (error) {
|
|
||||||
// 选择“修改信息”时留在当前步骤继续填写。
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
hideLoading()
|
|
||||||
queryingHisArchives.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPlanFields(plan) {
|
|
||||||
return (Array.isArray(plan?.fields) ? plan.fields : [])
|
|
||||||
.map((field) => {
|
|
||||||
const source = typeof field === 'string' ? { fieldKey: field } : field || {};
|
|
||||||
const fieldKey = source.fieldKey || source.feildKey || source.key || source.title;
|
|
||||||
if (!fieldKey) return null;
|
|
||||||
return {
|
|
||||||
fieldKey,
|
|
||||||
label: source.label || source.labelSnapshot || source.name || fieldKey,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter(Boolean);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentFormValue(fieldKey) {
|
|
||||||
return formData.value[fieldKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
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(getCurrentFormValue(field.fieldKey)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getQueryConditions(plan) {
|
|
||||||
return getPlanFields(plan).reduce((conditions, field) => {
|
|
||||||
conditions[field.fieldKey] = normalizeFieldValue(getCurrentFormValue(field.fieldKey));
|
|
||||||
return conditions;
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMatchFields(plan, conditions) {
|
|
||||||
const fields = getPlanFields(plan).map((field) => ({
|
|
||||||
...field,
|
|
||||||
value: conditions[field.fieldKey],
|
|
||||||
}));
|
|
||||||
['name', 'mobile'].forEach((fieldKey) => {
|
|
||||||
const value = normalizeFieldValue(getCurrentFormValue(fieldKey));
|
|
||||||
if (value && !fields.some((field) => field.fieldKey === fieldKey)) {
|
|
||||||
fields.push({ fieldKey, label: fieldKey === 'name' ? '姓名' : '手机号', value });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isHisArchiveMatched(archive, plan, conditions) {
|
|
||||||
return getMatchFields(plan, conditions).every((field) =>
|
|
||||||
normalizeFieldValue(archive?.[field.fieldKey]) === normalizeFieldValue(field.value)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMismatchMessage(response) {
|
|
||||||
const archive = response.list[0] || {};
|
|
||||||
const mismatch = getMatchFields(response.plan, response.conditions).find((field) =>
|
|
||||||
normalizeFieldValue(archive[field.fieldKey]) !== normalizeFieldValue(field.value)
|
|
||||||
);
|
|
||||||
if (!mismatch) return '院内档案信息与当前填写信息不一致,请确认后再继续。';
|
|
||||||
const actualValue = normalizeFieldValue(archive[mismatch.fieldKey]) || '为空';
|
|
||||||
return `${mismatch.label}不匹配`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function confirm() {
|
|
||||||
if (!tempRef.value.verify()) return;
|
|
||||||
if (customerId.value) {
|
|
||||||
updateArchive();
|
|
||||||
} else {
|
|
||||||
addArchive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 产品要求, 建档页面:与联系人关系:默认选中“本人”,证件类型:默认选中“身份证”
|
|
||||||
*/
|
|
||||||
function preProcessFrom() {
|
|
||||||
const relationItem = formItems.value.find(item => item.title === 'relationship');
|
|
||||||
const range = relationItem && Array.isArray(relationItem.range) ? relationItem.range : [];
|
|
||||||
if (range.includes('本人')) {
|
|
||||||
form.value.relationship = '本人';
|
|
||||||
}
|
|
||||||
const cardTypeItem = formItems.value.find(item => item.title === 'cardType');
|
|
||||||
const cardTypeRange = cardTypeItem && Array.isArray(cardTypeItem.range) ? cardTypeItem.range : [];
|
|
||||||
if (cardTypeRange.includes('身份证')) {
|
|
||||||
form.value.cardType = '身份证';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addArchive() {
|
|
||||||
if (loading.value) return;
|
|
||||||
loading.value = true;
|
|
||||||
const params = {
|
|
||||||
...form.value,
|
|
||||||
addMethod: 'customerManual',
|
|
||||||
teamId: teamId.value,
|
|
||||||
corpId: corpId.value,
|
|
||||||
mobile: account.value.mobile,
|
|
||||||
miniAppId: account.value.openid,
|
|
||||||
externalUserId: externalUserId.value,
|
|
||||||
realUnionid: account.value.unionid || '',
|
|
||||||
}
|
|
||||||
if (hisArchive.value && hisArchive.value.customerNumber) {
|
|
||||||
params.customerNumber = hisArchive.value.customerNumber;
|
|
||||||
params.isConnectHis = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (externalUserId.value) {
|
|
||||||
const corpUserId = await getResponsiblePerson();
|
|
||||||
if (corpUserId) {
|
|
||||||
params.personResponsibles = [{ corpUserId, teamId: teamId.value }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (referenceCustomerId.value && !referenceCustomer.value) {
|
|
||||||
await getReferenceCustomer();
|
|
||||||
}
|
|
||||||
if (referenceCustomer.value) {
|
|
||||||
params.referenceCustomerId = referenceCustomer.value._id;
|
|
||||||
params.referenceUserId = '';
|
|
||||||
params.reference = referenceCustomer.value.name;
|
|
||||||
params.referenceType = '客户';
|
|
||||||
params.customerSource = ['客户推荐']
|
|
||||||
}
|
|
||||||
loading.value = false;
|
|
||||||
const res = await api('addCustomer', { params });
|
|
||||||
set('home-invite-team-info', { teamId: teamId.value })
|
|
||||||
if (res && res.success) {
|
|
||||||
uni.$emit('reloadTeamCustomers')
|
|
||||||
if (source.value === 'experienceCoupon') {
|
|
||||||
await toast('档案创建成功');
|
|
||||||
uni.navigateBack();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (redirectUrl.value) {
|
|
||||||
uni.redirectTo({ url: redirectUrl.value });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// getTeam(corpId.value, teamId.value, res.data.id);
|
|
||||||
if (healthTypes.value.length) {
|
|
||||||
const nextType = healthTypes.value[0];
|
|
||||||
const nextTypes = healthTypes.value.slice(1);
|
|
||||||
const url = `/pages/health/record?type=${nextType}&teamId=${teamId.value}&corpId=${corpId.value}&customerId=${res.data.id}&nextTypes=${nextTypes.join(',')}&source=afterArchive`
|
|
||||||
uni.redirectTo({ url });
|
|
||||||
} else {
|
|
||||||
uni.redirectTo({
|
|
||||||
url: `/pages/archive/archive-result?corpId=${corpId.value}&teamId=${teamId.value}&customerId=${res.data.id}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
toast(res?.message || '新增档案失败');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getResponsiblePerson() {
|
|
||||||
const res = await api('getResponsiblePerson', { corpId: corpId.value, teamId: teamId.value, externalUserId: externalUserId.value, corpUserId: corpUserId.value });
|
|
||||||
return res && res.data ? res.data : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
function shouldBackAfterArchiveBound() {
|
|
||||||
return ['experienceCoupon', 'appointmentRegistration'].includes(source.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
function backAfterArchiveBound() {
|
|
||||||
if (shouldBackAfterArchiveBound()) {
|
|
||||||
uni.navigateBack()
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uni.switchTab({
|
|
||||||
url: '/pages/home/home'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async function bindArchive(customerId) {
|
|
||||||
let responsiblePerson = '';
|
|
||||||
if (externalUserId.value) {
|
|
||||||
const corpUserId = await getResponsiblePerson();
|
|
||||||
responsiblePerson = corpUserId || '';
|
|
||||||
}
|
|
||||||
const res = await api('bindMiniAppArchive', { id: customerId, corpId: corpId.value, teamId: teamId.value, miniAppId: account.value.openid, externalUserId: externalUserId.value, responsiblePerson });
|
|
||||||
if (res && res.success) {
|
|
||||||
await toast('绑定成功');
|
|
||||||
uni.$emit('reloadTeamCustomers')
|
|
||||||
backAfterArchiveBound()
|
|
||||||
} else {
|
|
||||||
toast(res?.message || '绑定失败');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
if (await initArchiveQueryConfig()) return;
|
|
||||||
if (referenceCustomerId.value) {
|
|
||||||
getReferenceCustomer();
|
|
||||||
}
|
|
||||||
if (customerId.value) {
|
|
||||||
await getCustomer();
|
|
||||||
} else {
|
|
||||||
await getExternalUserId(corpId.value);
|
|
||||||
const res = bindCustomerId.value ? await getExperienceCouponBindArchive() : await getArchives();
|
|
||||||
if (res.length > 0) {
|
|
||||||
visible.value = true;
|
|
||||||
} else if (bindCustomerId.value || shouldBackAfterArchiveBound()) {
|
|
||||||
await toast('指定绑定档案不存在或已绑定');
|
|
||||||
uni.navigateBack();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
getTeam(corpId.value, teamId.value)
|
|
||||||
}
|
|
||||||
await getBaseForm();
|
|
||||||
if (!customerId.value) {
|
|
||||||
preProcessFrom()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async function initArchiveQueryConfig() {
|
|
||||||
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);
|
|
||||||
if (!archiveQueryPlans.value.length) {
|
|
||||||
redirectArchivePage('edit-archive');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function redirectArchivePage(page) {
|
|
||||||
const query = Object.entries(pageOptions.value)
|
|
||||||
.filter(([, value]) => value !== undefined && value !== null && value !== '')
|
|
||||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
|
||||||
.join('&');
|
|
||||||
uni.redirectTo({
|
|
||||||
url: `/pages/archive/${page}${query ? `?${query}` : ''}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getExperienceCouponBindArchive() {
|
|
||||||
const res = await api('getCustomerByCustomerId', { corpId: corpId.value, customerId: bindCustomerId.value });
|
|
||||||
const data = res && res.success && res.data ? res.data : null;
|
|
||||||
customers.value = data ? [data] : [];
|
|
||||||
corpName.value = res && res.corpName ? res.corpName : corpName.value;
|
|
||||||
enableHis.value = false;
|
|
||||||
return customers.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getArchives() {
|
|
||||||
const res = await api('getUnbindMiniAppCustomers', { corpId: corpId.value, mobile: account.value?.mobile || '', externalUserId: externalUserId.value });
|
|
||||||
customers.value = res && Array.isArray(res.data) ? res.data : [];
|
|
||||||
corpName.value = res && res.corpName ? res.corpName : '';
|
|
||||||
enableHis.value = res && res.enableHis ? res.enableHis : false;
|
|
||||||
return customers.value
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getBaseForm() {
|
|
||||||
const res = await api('getTeamBaseInfo', { corpId: corpId.value, teamId: teamId.value, queryHisTitles: queryHisTitles.value });
|
|
||||||
if (res && res.success) {
|
|
||||||
teamFormItems.value = Array.isArray(res.data) ? res.data : [];
|
|
||||||
// const mobileIndex = formItems.value.findIndex(item => item.title === 'mobile');
|
|
||||||
// if (mobileIndex > -1) {
|
|
||||||
// formItems.value[mobileIndex].appendText = `(授权手机号)`;
|
|
||||||
// }
|
|
||||||
|
|
||||||
} else {
|
|
||||||
toast(res?.message || '查询失败');
|
|
||||||
return Promise.reject()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getCustomer() {
|
|
||||||
const res = await api('getCustomerByCustomerId', { customerId: customerId.value });
|
|
||||||
if (res && res.success && res.data) {
|
|
||||||
customer.value = res.data;
|
|
||||||
} else {
|
|
||||||
await toast(res?.message || '查询档案信息失败');
|
|
||||||
uni.navigateBack();
|
|
||||||
return Promise.reject()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateArchive() {
|
|
||||||
const res = await api('updateCustomer', { id: customerId.value, params: { ...form.value } });
|
|
||||||
if (res && res.success) {
|
|
||||||
await toast('修改成功');
|
|
||||||
uni.$emit('reloadTeamCustomers')
|
|
||||||
uni.navigateBack();
|
|
||||||
} else {
|
|
||||||
toast(res?.message || '修改失败');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function unBindArchive() {
|
|
||||||
await uniConfirm('确定删除档案吗?')
|
|
||||||
const res = await api('unbindMiniAppArchive', { id: customer.value._id, corpId: corpId.value, teamId: teamId.value, miniAppId: account.value.openid });
|
|
||||||
if (res && res.success) {
|
|
||||||
await toast('删除成功');
|
|
||||||
uni.$emit('reloadTeamCustomers')
|
|
||||||
uni.navigateBack();
|
|
||||||
} else {
|
|
||||||
toast(res?.message || '删除失败')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getReferenceCustomer() {
|
|
||||||
const res = await api('getRefrencePeople', { corpId: corpId.value, id: referenceCustomerId.value });
|
|
||||||
referenceCustomer.value = res && res.data ? res.data : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getTeam(corpId, teamId, customerId) {
|
|
||||||
const res = await api('getTeamData', { teamId, corpId });
|
|
||||||
if (res && res.data) {
|
|
||||||
const team = res.data;
|
|
||||||
const qrcode = team && Array.isArray(team.qrcodes) ? team.qrcodes[0] : null;
|
|
||||||
const healthTempList = qrcode && Array.isArray(qrcode.healthTempList) ? qrcode.healthTempList : [];
|
|
||||||
healthTypes.value = healthTempList.filter(i => typeof i.templateType === 'string' && i.templateType.trim() && i.archiveRecommend === true).map(i => i.templateType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onLoad(options => {
|
|
||||||
pageOptions.value = { ...options };
|
|
||||||
teamId.value = options.teamId;
|
|
||||||
corpId.value = options.corpId;
|
|
||||||
customerId.value = options.id || '';
|
|
||||||
bindCustomerId.value = options.bindCustomerId || '';
|
|
||||||
corpUserId.value = options.corpUserId || '';
|
|
||||||
referenceCustomerId.value = options.referenceCustomerId || '';
|
|
||||||
source.value = options.source || '';
|
|
||||||
redirectUrl.value = options.redirectUrl || '';
|
|
||||||
uni.setNavigationBarTitle({ title: customerId.value ? '编辑档案' : '新增档案' })
|
|
||||||
})
|
|
||||||
|
|
||||||
useLoad(options => {
|
|
||||||
init();
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(hisQueryFormItems, (h) => {
|
|
||||||
if (h && h.length === 0 && step.value === 0) {
|
|
||||||
step.value = 1;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<style scoped></style>
|
|
||||||
@ -1,28 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<full-page pageClass="coupons-page" :customScroll="true">
|
<full-page pageClass="coupons-page" :customScroll="true">
|
||||||
<scroll-view class="coupon-scroll" scroll-y="true" refresher-enabled="true" :refresher-triggered="refreshing"
|
<scroll-view
|
||||||
@refresherrefresh="refreshCoupons">
|
class="coupon-scroll"
|
||||||
|
scroll-y="true"
|
||||||
|
refresher-enabled="true"
|
||||||
|
:refresher-triggered="refreshing"
|
||||||
|
@refresherrefresh="refreshCoupons"
|
||||||
|
>
|
||||||
<view class="page-body">
|
<view class="page-body">
|
||||||
<view class="user-card" @click="toSelectPage">
|
|
||||||
<view class="avatar">
|
|
||||||
<uni-icons type="person-filled" size="36" color="#c0c4cc" />
|
|
||||||
</view>
|
|
||||||
<view class="user-main">
|
|
||||||
<view class="user-name">{{ customerName || "未选择档案" }}</view>
|
|
||||||
<view class="user-corp">所属机构:{{ corpName || "-" }}</view>
|
|
||||||
</view>
|
|
||||||
<uni-icons type="right" size="16" color="#c0c4cc" />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="summary">
|
|
||||||
以下为“<text class="summary-name">{{ customerName || "-" }}</text>”的所有剩余权益
|
|
||||||
</view>
|
|
||||||
<view v-if="loading" class="empty">加载中...</view>
|
<view v-if="loading" class="empty">加载中...</view>
|
||||||
<view v-else-if="!list.length" class="empty">暂无体验券</view>
|
<view v-else-if="!list.length" class="empty">暂无体验券</view>
|
||||||
<view v-else class="coupon-list">
|
<view v-else class="coupon-list">
|
||||||
<view v-for="item in list" :key="item._id" class="coupon-card" :class="item.cardClass"
|
<view
|
||||||
@click="openPoster(item)">
|
v-for="item in list"
|
||||||
<image v-if="item.posterUrl" class="coupon-poster" :src="item.posterUrl" mode="aspectFill" />
|
:key="item._id"
|
||||||
|
class="coupon-card"
|
||||||
|
:class="item.cardClass"
|
||||||
|
@click="openPoster(item)"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
v-if="item.posterUrl"
|
||||||
|
class="coupon-poster"
|
||||||
|
:src="item.posterUrl"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
<view v-else class="coupon-poster coupon-poster--empty">体验券</view>
|
<view v-else class="coupon-poster coupon-poster--empty">体验券</view>
|
||||||
<view class="coupon-body">
|
<view class="coupon-body">
|
||||||
<view class="coupon-title-row">
|
<view class="coupon-title-row">
|
||||||
@ -37,8 +38,11 @@
|
|||||||
<view class="coupon-info-row coupon-info-row--projects">
|
<view class="coupon-info-row coupon-info-row--projects">
|
||||||
<text class="coupon-info-label">项目</text>
|
<text class="coupon-info-label">项目</text>
|
||||||
<view class="coupon-project-list">
|
<view class="coupon-project-list">
|
||||||
<view v-for="project in item.projectSnapshot || []" :key="project.projectId"
|
<view
|
||||||
class="coupon-project-item">
|
v-for="project in item.projectSnapshot || []"
|
||||||
|
:key="project.projectId"
|
||||||
|
class="coupon-project-item"
|
||||||
|
>
|
||||||
<text>{{ project.projectName || "未命名项目" }}</text>
|
<text>{{ project.projectName || "未命名项目" }}</text>
|
||||||
<text>×{{ project.usageCount || 1 }}</text>
|
<text>×{{ project.usageCount || 1 }}</text>
|
||||||
</view>
|
</view>
|
||||||
@ -70,7 +74,11 @@
|
|||||||
<!-- 海报领取弹窗 -->
|
<!-- 海报领取弹窗 -->
|
||||||
<view v-if="posterVisible" class="poster-mask" @click="closePoster">
|
<view v-if="posterVisible" class="poster-mask" @click="closePoster">
|
||||||
<view class="poster-dialog" @click.stop>
|
<view class="poster-dialog" @click.stop>
|
||||||
<image class="poster-image" :src="current?.posterUrl || ''" mode="widthFix" />
|
<image
|
||||||
|
class="poster-image"
|
||||||
|
:src="current?.posterUrl || ''"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
<view class="poster-info">
|
<view class="poster-info">
|
||||||
<view class="poster-title">{{ current?.activityName || "体验券" }}</view>
|
<view class="poster-title">{{ current?.activityName || "体验券" }}</view>
|
||||||
<view class="poster-desc">{{ current?.projectText }}</view>
|
<view class="poster-desc">{{ current?.projectText }}</view>
|
||||||
@ -89,21 +97,18 @@ import { onLoad, onShow } from "@dcloudio/uni-app";
|
|||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import useAccount from "@/store/account";
|
import useAccount from "@/store/account";
|
||||||
import api from "@/utils/api";
|
import api from "@/utils/api";
|
||||||
import { get, remove } from "@/utils/cache";
|
import { get } from "@/utils/cache";
|
||||||
import { toast } from "@/utils/widget";
|
import { toast } from "@/utils/widget";
|
||||||
import { normalizeCorpId } from "@/utils/api-base-config";
|
import { normalizeCorpId } from "@/utils/api-base-config";
|
||||||
import FullPage from "@/components/full-page.vue";
|
import FullPage from "@/components/full-page.vue";
|
||||||
|
|
||||||
const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info";
|
const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info";
|
||||||
const RIGHTS_SELECTION_CACHE_KEY = "experience-coupon-rights-selection";
|
|
||||||
const { account } = storeToRefs(useAccount());
|
const { account } = storeToRefs(useAccount());
|
||||||
const { getTeams } = useAccount();
|
const { getTeams } = useAccount();
|
||||||
|
|
||||||
const corpId = ref("");
|
const corpId = ref("");
|
||||||
const teamId = ref("");
|
const teamId = ref("");
|
||||||
const customerId = ref("");
|
const customerId = ref("");
|
||||||
const customerName = ref("");
|
|
||||||
const corpName = ref("");
|
|
||||||
const list = ref([]);
|
const list = ref([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const refreshing = ref(false);
|
const refreshing = ref(false);
|
||||||
@ -111,16 +116,6 @@ const posterVisible = ref(false);
|
|||||||
const current = ref(null);
|
const current = ref(null);
|
||||||
const claiming = ref(false);
|
const claiming = ref(false);
|
||||||
|
|
||||||
async function loadCorpName() {
|
|
||||||
if (!corpId.value) {
|
|
||||||
corpName.value = "";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const res = await api("getCorpInfo", { corpId: corpId.value }, false);
|
|
||||||
const corp = Array.isArray(res?.data) ? res.data[0] : null;
|
|
||||||
corpName.value = corp?.corp_name || corp?.corpName || "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function toTimestamp(value) {
|
function toTimestamp(value) {
|
||||||
if (!value) return 0;
|
if (!value) return 0;
|
||||||
const numeric = Number(value);
|
const numeric = Number(value);
|
||||||
@ -191,7 +186,6 @@ async function resolveContext(options = {}) {
|
|||||||
corpId.value = normalizeCorpId(options.corpId || corpId.value || "");
|
corpId.value = normalizeCorpId(options.corpId || corpId.value || "");
|
||||||
teamId.value = options.teamId || teamId.value || "";
|
teamId.value = options.teamId || teamId.value || "";
|
||||||
customerId.value = options.customerId || options.memberId || customerId.value || "";
|
customerId.value = options.customerId || options.memberId || customerId.value || "";
|
||||||
customerName.value = options.name ? decodeURIComponent(options.name) : customerName.value;
|
|
||||||
|
|
||||||
const cached = get(HOME_CURRENT_TEAM_CACHE_KEY) || {};
|
const cached = get(HOME_CURRENT_TEAM_CACHE_KEY) || {};
|
||||||
let teams = [];
|
let teams = [];
|
||||||
@ -209,7 +203,6 @@ async function resolveContext(options = {}) {
|
|||||||
if (!corpId.value) corpId.value = normalizeCorpId(matched?.corpId || cached.corpId || "");
|
if (!corpId.value) corpId.value = normalizeCorpId(matched?.corpId || cached.corpId || "");
|
||||||
if (!teamId.value) teamId.value = matched?.teamId || cached.teamId || "";
|
if (!teamId.value) teamId.value = matched?.teamId || cached.teamId || "";
|
||||||
if (!corpId.value) return false;
|
if (!corpId.value) return false;
|
||||||
await loadCorpName();
|
|
||||||
|
|
||||||
if (customerId.value) return true;
|
if (customerId.value) return true;
|
||||||
|
|
||||||
@ -219,7 +212,6 @@ async function resolveContext(options = {}) {
|
|||||||
const customers = res?.success && Array.isArray(res.data) ? res.data : [];
|
const customers = res?.success && Array.isArray(res.data) ? res.data : [];
|
||||||
const preferred = customers.find((c) => c.relationship === "本人") || customers[0];
|
const preferred = customers.find((c) => c.relationship === "本人") || customers[0];
|
||||||
customerId.value = preferred?._id || "";
|
customerId.value = preferred?._id || "";
|
||||||
customerName.value = preferred?.name || customerName.value || "";
|
|
||||||
return !!customerId.value;
|
return !!customerId.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,32 +296,6 @@ async function refreshCoupons() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function syncSelectedProfile() {
|
|
||||||
const selected = get(RIGHTS_SELECTION_CACHE_KEY);
|
|
||||||
if (!selected) return false;
|
|
||||||
remove(RIGHTS_SELECTION_CACHE_KEY);
|
|
||||||
corpId.value = normalizeCorpId(selected.corpId || corpId.value || "");
|
|
||||||
teamId.value = selected.teamId || teamId.value || "";
|
|
||||||
customerId.value = selected.customerId || selected.memberId || customerId.value || "";
|
|
||||||
customerName.value = selected.name || customerName.value || "";
|
|
||||||
await loadCorpName();
|
|
||||||
await loadCoupons();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toSelectPage() {
|
|
||||||
const params = [
|
|
||||||
`corpId=${encodeURIComponent(corpId.value || "")}`,
|
|
||||||
`teamId=${encodeURIComponent(teamId.value || "")}`,
|
|
||||||
`customerId=${encodeURIComponent(customerId.value || "")}`,
|
|
||||||
`mode=back`,
|
|
||||||
`target=coupons`,
|
|
||||||
].join("&");
|
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/experience-coupon/select-rights-archive?${params}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function openPoster(item) {
|
function openPoster(item) {
|
||||||
if (item?.displayStatus !== "issued") {
|
if (item?.displayStatus !== "issued") {
|
||||||
toast(item?.displayStatusText || "当前体验券不可领取");
|
toast(item?.displayStatusText || "当前体验券不可领取");
|
||||||
@ -385,8 +351,6 @@ onLoad(async (options = {}) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
const changed = await syncSelectedProfile();
|
|
||||||
if (changed) return;
|
|
||||||
if (corpId.value && customerId.value) {
|
if (corpId.value && customerId.value) {
|
||||||
await loadCoupons();
|
await loadCoupons();
|
||||||
}
|
}
|
||||||
@ -410,58 +374,6 @@ onShow(async () => {
|
|||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-card {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 0;
|
|
||||||
padding: 24rpx 30rpx;
|
|
||||||
border-bottom: 1px solid #eceff4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
width: 88rpx;
|
|
||||||
height: 88rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #f0f2f5;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-right: 20rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-main {
|
|
||||||
min-width: 0;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-name {
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #222;
|
|
||||||
margin-bottom: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-corp {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
.summary {
|
|
||||||
padding: 18rpx 30rpx;
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #666;
|
|
||||||
background: #f0f2f5;
|
|
||||||
border-top: 1px solid #eceff4;
|
|
||||||
border-bottom: 1px solid #eceff4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.summary-name {
|
|
||||||
color: #065bd6;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coupon-card {
|
.coupon-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20rpx;
|
gap: 20rpx;
|
||||||
@ -563,7 +475,7 @@ onShow(async () => {
|
|||||||
color: #909399;
|
color: #909399;
|
||||||
}
|
}
|
||||||
|
|
||||||
.coupon-info-row>text:last-child,
|
.coupon-info-row > text:last-child,
|
||||||
.coupon-project-list {
|
.coupon-project-list {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
|
|||||||
@ -80,8 +80,7 @@ function buildTargetUrl(item) {
|
|||||||
const name = encodeURIComponent(item.name || "");
|
const name = encodeURIComponent(item.name || "");
|
||||||
|
|
||||||
if (target.value === "coupons") {
|
if (target.value === "coupons") {
|
||||||
const corpName = encodeURIComponent(item.corpName || "");
|
return `/pages/experience-coupon/my-coupons?corpId=${corp}&teamId=${team}&customerId=${customer}`;
|
||||||
return `/pages/experience-coupon/my-coupons?corpId=${corp}&teamId=${team}&customerId=${customer}&name=${name}&corpName=${corpName}`;
|
|
||||||
}
|
}
|
||||||
if (target.value === "health") {
|
if (target.value === "health") {
|
||||||
return `/pages/health/list?teamId=${team}&corpId=${corp}&id=${customer}&name=${name}`;
|
return `/pages/health/list?teamId=${team}&corpId=${corp}&id=${customer}&name=${name}`;
|
||||||
|
|||||||
@ -70,7 +70,7 @@ function change({ title, value }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function confirm() {
|
function confirm() {
|
||||||
if (!tempRef.value.verify()) return;
|
if (!tempRef.value.verify() || Object.keys(form.value).length === 0) return;
|
||||||
if (id.value) {
|
if (id.value) {
|
||||||
updateHealthRecord();
|
updateHealthRecord();
|
||||||
} else {
|
} else {
|
||||||
@ -79,18 +79,6 @@ function confirm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function addHealthRecord() {
|
async function addHealthRecord() {
|
||||||
if (Object.keys(form.value).length === 0) {
|
|
||||||
const isFill = await fillNext();
|
|
||||||
if (isFill) return;
|
|
||||||
if (source.value === 'afterArchive') {
|
|
||||||
uni.redirectTo({
|
|
||||||
url: `/pages/archive/archive-result?corpId=${corpId.value}&teamId=${teamId.value}&customerId=${customerId.value}`
|
|
||||||
})
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
uni.navigateBack();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const data = {
|
const data = {
|
||||||
...form.value,
|
...form.value,
|
||||||
corpId: corpId.value,
|
corpId: corpId.value,
|
||||||
|
|||||||
@ -222,12 +222,10 @@ async function auth() {
|
|||||||
|
|
||||||
async function getCustomers() {
|
async function getCustomers() {
|
||||||
if (loading) return;
|
if (loading) return;
|
||||||
loading = true;
|
loading = true
|
||||||
await getExternalUserId(props.corpId)
|
|
||||||
const res = await api("getMiniAppCustomers", {
|
const res = await api("getMiniAppCustomers", {
|
||||||
miniAppId: account.value.openid,
|
miniAppId: account.value.openid,
|
||||||
corpId: props.corpId,
|
corpId: props.corpId,
|
||||||
externalUserId: externalUserId.value
|
|
||||||
}, false);
|
}, false);
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
customers.value = res && Array.isArray(res.data) ? res.data : [];
|
customers.value = res && Array.isArray(res.data) ? res.data : [];
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<view v-for="conversation in conversationList" :key="conversation.source === 'ai' ? `ai-${conversation.sessionId}` : (conversation.groupID || conversation.conversationID)"
|
<view v-for="conversation in conversationList" :key="conversation.source === 'ai' ? `ai-${conversation.sessionId}` : (conversation.groupID || conversation.conversationID)"
|
||||||
class="message-item" @click="handleClickConversation(conversation)">
|
class="message-item" @click="handleClickConversation(conversation)">
|
||||||
<view class="avatar-container">
|
<view class="avatar-container">
|
||||||
<image v-if="conversation.source === 'ai'" class="avatar" :src="conversation.assistantAvatar || defaultAssistantAvatar" mode="aspectFill" @error="handleConversationAvatarError(conversation)" />
|
<image v-if="conversation.source === 'ai'" class="avatar" src="/static/home/ai-consult-assistant.png" mode="aspectFill" />
|
||||||
<GroupAvatar v-else :avatarList="getAvatarList(conversation.groupID)" :size="96" classType="square" />
|
<GroupAvatar v-else :avatarList="getAvatarList(conversation.groupID)" :size="96" classType="square" />
|
||||||
<view v-if="conversation.unreadCount > 0" class="unread-badge">
|
<view v-if="conversation.unreadCount > 0" class="unread-badge">
|
||||||
<text class="unread-text">{{
|
<text class="unread-text">{{
|
||||||
@ -101,7 +101,6 @@ const hasMore = ref(false);
|
|||||||
const refreshing = ref(false);
|
const refreshing = ref(false);
|
||||||
const showSubscribeEntry = ref(false);
|
const showSubscribeEntry = ref(false);
|
||||||
const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info";
|
const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info";
|
||||||
const defaultAssistantAvatar = "/static/home/ai-consult-assistant.png";
|
|
||||||
|
|
||||||
// 群聊头像管理
|
// 群聊头像管理
|
||||||
const { loadGroupAvatars, getAvatarList } = useGroupAvatars();
|
const { loadGroupAvatars, getAvatarList } = useGroupAvatars();
|
||||||
@ -263,10 +262,6 @@ function mergeConsultationList(imConversations) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleConversationAvatarError(conversation) {
|
|
||||||
conversation.assistantAvatar = defaultAssistantAvatar;
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadAiConsultationList = async () => {
|
const loadAiConsultationList = async () => {
|
||||||
const corpId = getCurrentTeamCorpId();
|
const corpId = getCurrentTeamCorpId();
|
||||||
const miniAppId = openid.value || account.value?.openid || "";
|
const miniAppId = openid.value || account.value?.openid || "";
|
||||||
@ -286,7 +281,6 @@ const loadAiConsultationList = async () => {
|
|||||||
sessionId: item.id,
|
sessionId: item.id,
|
||||||
corpId: item.corpId,
|
corpId: item.corpId,
|
||||||
displayName: removeAiLabel(item.assistantName, "咨询助理"),
|
displayName: removeAiLabel(item.assistantName, "咨询助理"),
|
||||||
assistantAvatar: item.assistantAvatar || defaultAssistantAvatar,
|
|
||||||
teamName: item.teamName || "",
|
teamName: item.teamName || "",
|
||||||
patientName: item.customerName || "未命名患者",
|
patientName: item.customerName || "未命名患者",
|
||||||
lastMessage: removeAiLabel(item.statusLabel, "咨询"),
|
lastMessage: removeAiLabel(item.statusLabel, "咨询"),
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
<view class="profile-title">{{ customerName || "请选择档案" }}</view>
|
<view class="profile-title">{{ customerName || "请选择档案" }}</view>
|
||||||
<view class="profile-sub">所属机构:{{ corpName || "-" }}</view>
|
<view class="profile-sub">所属机构:{{ corpName || "-" }}</view>
|
||||||
</view>
|
</view>
|
||||||
<uni-icons type="right" size="16" color="#c0c4cc" />
|
<view class="profile-arrow">></view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<picker mode="date" fields="month" :value="selectedMonth" @change="handleMonthChange">
|
<picker mode="date" fields="month" :value="selectedMonth" @change="handleMonthChange">
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<view class="profile-title">{{ customerName || "请选择档案" }}</view>
|
<view class="profile-title">{{ customerName || "请选择档案" }}</view>
|
||||||
<view class="profile-sub">所属机构:{{ corpName || "-" }}</view>
|
<view class="profile-sub">所属机构:{{ corpName || "-" }}</view>
|
||||||
</view>
|
</view>
|
||||||
<uni-icons type="right" size="16" color="#c0c4cc" />
|
<view class="profile-arrow">></view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<picker mode="date" fields="month" :value="selectedMonth" @change="handleMonthChange">
|
<picker mode="date" fields="month" :value="selectedMonth" @change="handleMonthChange">
|
||||||
|
|||||||
@ -48,14 +48,6 @@ export default [
|
|||||||
path: 'pages/archive/edit-archive',
|
path: 'pages/archive/edit-archive',
|
||||||
meta: { title: '新增档案', login: true }
|
meta: { title: '新增档案', login: true }
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'pages/archive/step-edit-archive',
|
|
||||||
meta: { title: '新增档案', login: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'pages/archive/fill-his-archive',
|
|
||||||
meta: { title: '完善信息', login: true }
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'pages/archive/archive-result',
|
path: 'pages/archive/archive-result',
|
||||||
meta: { title: '团队服务' }
|
meta: { title: '团队服务' }
|
||||||
|
|||||||
@ -14,7 +14,6 @@ export default defineStore("accountStore", () => {
|
|||||||
const isIMInitialized = ref(false);
|
const isIMInitialized = ref(false);
|
||||||
const openid = ref("");
|
const openid = ref("");
|
||||||
const externalUserId = ref('');
|
const externalUserId = ref('');
|
||||||
const externalUserIdMap = ref({});
|
|
||||||
const teams = ref([]);
|
const teams = ref([]);
|
||||||
const hasImCorpId = computed(() => {
|
const hasImCorpId = computed(() => {
|
||||||
// 正式环境IM账号优先 暂时只有wpLgjyawAA8N0gWmXgyJq8wpjGcOT7fg机构的才开启IM账号
|
// 正式环境IM账号优先 暂时只有wpLgjyawAA8N0gWmXgyJq8wpjGcOT7fg机构的才开启IM账号
|
||||||
@ -165,16 +164,9 @@ export default defineStore("accountStore", () => {
|
|||||||
externalUserId.value = '';
|
externalUserId.value = '';
|
||||||
return
|
return
|
||||||
};
|
};
|
||||||
const key = `${normalizedCorpId}_${unionid}_${openid}_${miniAppId}`;
|
|
||||||
if (externalUserIdMap.value[key]) {
|
|
||||||
return externalUserIdMap.value[key]
|
|
||||||
}
|
|
||||||
const res = await api('getUnionidToExternalUserid', { unionid, openid, corpId: normalizedCorpId, miniAppId }, false);
|
const res = await api('getUnionidToExternalUserid', { unionid, openid, corpId: normalizedCorpId, miniAppId }, false);
|
||||||
const id = res && res.success && typeof res.data === 'string' && res.data.trim() ? res.data.trim() : '';
|
const id = res && res.success && typeof res.data === 'string' && res.data.trim() ? res.data.trim() : '';
|
||||||
externalUserId.value = id;
|
externalUserId.value = id;
|
||||||
if (id) {
|
|
||||||
externalUserIdMap.value[key] = id;
|
|
||||||
}
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -90,9 +90,6 @@ const urlsConfig = {
|
|||||||
bindHisArchive: 'bindHisArchive',
|
bindHisArchive: 'bindHisArchive',
|
||||||
getMatchedHisArchive: 'getMatchedHisArchive',
|
getMatchedHisArchive: 'getMatchedHisArchive',
|
||||||
},
|
},
|
||||||
customerHisSync: {
|
|
||||||
getHisCustomerArchive: 'getHisCustomerArchive',
|
|
||||||
},
|
|
||||||
wecom: {
|
wecom: {
|
||||||
addContactWay: 'getCorpFriendQrcode'
|
addContactWay: 'getCorpFriendQrcode'
|
||||||
},
|
},
|
||||||
|
|||||||
@ -173,7 +173,6 @@ const request = async (options = {}, showLoading = true) => {
|
|||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...(res && res.data && typeof res.data === "object" ? res.data : {}),
|
|
||||||
success: false,
|
success: false,
|
||||||
message: res.data && res.data.message ? res.data.message : "请求失败",
|
message: res.data && res.data.message ? res.data.message : "请求失败",
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user