Compare commits
No commits in common. "104053964098ff42827ff374d2f29a847e3bf40c" and "2cbb3727719d07bcf139197ac372f334fc6d6796" have entirely different histories.
1040539640
...
2cbb372771
@ -20,33 +20,7 @@ export const ToDoEventType = {
|
||||
followupAppointment: "复诊预约",
|
||||
confirmArrival: "确认到院",
|
||||
prenatalFollowUp: "孕期回访",
|
||||
childHealthFollowUp: "儿童保健回访",
|
||||
benefitExecution: "权益执行",
|
||||
}
|
||||
// {
|
||||
// followUpNoShow: "未到院回访",
|
||||
// followUpNoDeal: "未成交回访",
|
||||
// followUp: "诊后回访",
|
||||
// followUpPostSurgery: "术后回访",
|
||||
// followUpPostTreatment: "治疗后回访",
|
||||
// appointmentReminder: "就诊提醒",
|
||||
// followUpReminder: "复诊提醒",
|
||||
// medicationReminder: "用药提醒",
|
||||
// serviceSummary: "咨询服务",
|
||||
// eventNotification: "活动通知",
|
||||
// ContentReminder: "宣教发送",
|
||||
// questionnaire: "问卷调查",
|
||||
// followUpComplaint: "投诉回访",
|
||||
// followUpActivity: "活动回访",
|
||||
// other: "其他",
|
||||
// Feedback: "意见反馈",
|
||||
// // 预约相关服务类型
|
||||
// treatmentAppointment: "治疗预约",
|
||||
// followupAppointment: "复诊预约",
|
||||
// confirmArrival: "确认到院",
|
||||
// prenatalFollowUp: "孕期回访",
|
||||
// };
|
||||
|
||||
};
|
||||
|
||||
export const statusNames = {
|
||||
notStart: "未开始",
|
||||
|
||||
@ -1,48 +0,0 @@
|
||||
<template>
|
||||
<text>{{ displayName }}</text>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, reactive } from 'vue';
|
||||
import api from '@/utils/api';
|
||||
import useAccountStore from '@/store/account';
|
||||
|
||||
const props = defineProps({
|
||||
openid: { type: String, default: '' },
|
||||
fallback: { type: String, default: '' },
|
||||
});
|
||||
const SPECIAL_NAMES = { system: '系统', none: '咨询公共池', not: '无' };
|
||||
const sharedUserNameMap = reactive({});
|
||||
let sharedLoadingPromise = null;
|
||||
const accountStore = useAccountStore();
|
||||
|
||||
const displayName = computed(() => {
|
||||
const id = String(props.openid || '').trim();
|
||||
if (!id) return props.fallback || '';
|
||||
return SPECIAL_NAMES[id] || sharedUserNameMap[id] || props.fallback || id;
|
||||
});
|
||||
|
||||
async function loadMembers() {
|
||||
if (sharedLoadingPromise) return sharedLoadingPromise;
|
||||
const team = uni.getStorageSync('ykt_case_current_team') || {};
|
||||
const corpId = String(team.corpId || accountStore.doctorInfo?.corpId || accountStore.account?.corpId || '');
|
||||
if (!corpId) return;
|
||||
sharedLoadingPromise = api('getCorpMember', { corpId, page: 1, pageSize: 1000 }, false)
|
||||
.then((res) => {
|
||||
const list = res?.data?.data || res?.data?.list || res?.data || res?.list || [];
|
||||
if (!Array.isArray(list)) return;
|
||||
const map = {};
|
||||
list.forEach((member) => {
|
||||
const userid = String(member?.userid || member?.userId || member?.corpUserId || '').trim();
|
||||
const name = String(member?.anotherName || member?.name || '').trim();
|
||||
if (userid && name) map[userid] = name;
|
||||
});
|
||||
Object.assign(sharedUserNameMap, map);
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => { sharedLoadingPromise = null; });
|
||||
return sharedLoadingPromise;
|
||||
}
|
||||
|
||||
onMounted(loadMembers);
|
||||
</script>
|
||||
@ -118,12 +118,6 @@
|
||||
:reachBottomTime="reachBottomTime"
|
||||
:floatingBottom="floatingBottom"
|
||||
/>
|
||||
<BenefitProjectTab
|
||||
v-else-if="currentTab === 'benefitProject'"
|
||||
:data="archive"
|
||||
:archiveId="archiveId"
|
||||
:floatingBottom="floatingBottom"
|
||||
/>
|
||||
<FollowUpManageTab
|
||||
v-else
|
||||
:data="archive"
|
||||
@ -238,7 +232,6 @@ import dayjs from 'dayjs';
|
||||
import HealthProfileTab from '@/pages/case/components/archive-detail/health-profile-tab.vue';
|
||||
import ServiceInfoTab from '@/pages/case/components/archive-detail/service-info-tab.vue';
|
||||
import FollowUpManageTab from '@/pages/case/components/archive-detail/follow-up-manage-tab.vue';
|
||||
import BenefitProjectTab from '@/pages/case/components/archive-detail/benefit-project-tab.vue';
|
||||
import api from '@/utils/api';
|
||||
import useAccountStore from '@/store/account';
|
||||
import { hideLoading, loading, toast } from '@/utils/widget';
|
||||
@ -250,7 +243,6 @@ const NEED_RELOAD_STORAGE_KEY = 'ykt_case_need_reload';
|
||||
const tabs = [
|
||||
{ key: 'visitRecord', title: '病历记录' },
|
||||
{ key: 'followUp', title: '回访任务' },
|
||||
{ key: 'benefitProject', title: '权益项目' },
|
||||
{ key: 'serviceRecord', title: '服务记录' }
|
||||
];
|
||||
|
||||
@ -570,10 +562,7 @@ onLoad((options) => {
|
||||
fetchArchive();
|
||||
});
|
||||
|
||||
onShow(async () => {
|
||||
// 每次进入用户详情页重新获取医生信息,及时同步管理端变更的权益权限。
|
||||
await getDoctorInfo();
|
||||
|
||||
onShow(() => {
|
||||
const cached = uni.getStorageSync(STORAGE_KEY);
|
||||
const cachedId = cached && typeof cached === 'object' ? String(cached._id || cached.id || '') : '';
|
||||
if (cached && typeof cached === 'object' && (!cachedId || !archiveId.value || cachedId === archiveId.value)) {
|
||||
|
||||
@ -1,452 +0,0 @@
|
||||
<template>
|
||||
<view class="wrap">
|
||||
<view class="switcher">
|
||||
<view
|
||||
v-for="item in recordTypes"
|
||||
:key="item.value"
|
||||
class="switch-item"
|
||||
:class="{ active: currentType === item.value }"
|
||||
@click="switchType(item.value)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="list.length" class="list">
|
||||
<view v-for="item in list" :key="item._id" class="record-card">
|
||||
<view class="record-header">
|
||||
<view class="record-title">{{ item.projectName || '未命名权益项目' }}</view>
|
||||
<view v-if="currentType === 'treatment'" class="status" :class="item.statusClass">
|
||||
{{ item.statusLabel }}
|
||||
</view>
|
||||
<view v-else class="status status-blue">已治疗</view>
|
||||
</view>
|
||||
|
||||
<template v-if="currentType === 'treatment'">
|
||||
<view class="summary-row">
|
||||
<view class="summary-item">
|
||||
<text class="summary-label">总数</text>
|
||||
<text class="summary-value">{{ item.usageCount }}</text>
|
||||
</view>
|
||||
<view class="summary-item highlight">
|
||||
<text class="summary-label">剩余数</text>
|
||||
<text class="summary-value">{{ item.restUsageCount }}</text>
|
||||
</view>
|
||||
<view class="summary-item">
|
||||
<text class="summary-label">有效期</text>
|
||||
<text class="summary-value">{{ item.validTimeText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="detail-label">购买日期</text>
|
||||
<text class="detail-value">{{ item.purchaseDate }}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="detail-label">治疗科室</text>
|
||||
<text class="detail-value">{{ item.treatmentDeptName || '--' }}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="detail-label">录单人</text>
|
||||
<view class="detail-value"><WwUser :openid="item.creator || item.billdCreator || item.billDoctorId" :fallback="item.creatorName || item.billdCreatorName || '--'" /></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<view class="detail-row">
|
||||
<text class="detail-label">治疗日期</text>
|
||||
<text class="detail-value">{{ item.treatmentDate }}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="detail-label">治疗数</text>
|
||||
<text class="detail-value strong">{{ item.deductUsageCount }}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="detail-label">治疗部位</text>
|
||||
<text class="detail-value">{{ item.treatmentArea || '--' }}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="detail-label">治疗科室</text>
|
||||
<text class="detail-value">{{ item.treatmentDeptName || '--' }}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="detail-label">治疗医生</text>
|
||||
<view class="detail-value"><WwUser :openid="item.treatmentDoctorUserId || item.doctorUserId || item.doctorId || item.executorUserId" :fallback="item.doctorName || item.treatmentDoctorName || '--'" /></view>
|
||||
</view>
|
||||
<view v-if="item.treatmentRemark" class="remark">{{ item.treatmentRemark }}</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else-if="loading" class="state">加载中...</view>
|
||||
<view v-else class="state">暂无{{ currentType === 'treatment' ? '权益记录' : '治疗明细' }}</view>
|
||||
|
||||
<uni-load-more
|
||||
v-if="list.length"
|
||||
:status="loadMoreStatus"
|
||||
:contentText="loadMoreText"
|
||||
@clickLoadMore="loadMore"
|
||||
/>
|
||||
|
||||
<view
|
||||
v-if="canBenefitEntry"
|
||||
class="fab"
|
||||
:style="{ bottom: `${floatingBottom}px` }"
|
||||
@click="goToBenefitEntry"
|
||||
>
|
||||
<uni-icons type="plusempty" size="24" color="#fff" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import api from '@/utils/api';
|
||||
import useAccountStore from '@/store/account';
|
||||
import { toast } from '@/utils/widget';
|
||||
import WwUser from '@/components/ww-user/index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
data: { type: Object, default: () => ({}) },
|
||||
archiveId: { type: String, default: '' },
|
||||
floatingBottom: { type: Number, default: 16 },
|
||||
});
|
||||
|
||||
const recordTypes = [
|
||||
{ label: '权益记录', value: 'treatment' },
|
||||
{ label: '治疗明细', value: 'deduct' },
|
||||
];
|
||||
const currentType = ref('treatment');
|
||||
const list = ref([]);
|
||||
const page = ref(1);
|
||||
const pageSize = 10;
|
||||
const total = ref(0);
|
||||
const loading = ref(false);
|
||||
|
||||
const accountStore = useAccountStore();
|
||||
const { account, doctorInfo } = storeToRefs(accountStore);
|
||||
const { getDoctorInfo } = accountStore;
|
||||
const canBenefitEntry = computed(() => doctorInfo.value?.benefitEntryEnabled === true);
|
||||
|
||||
const loadMoreStatus = computed(() => {
|
||||
if (loading.value) return 'loading';
|
||||
return list.value.length < total.value ? 'more' : 'no-more';
|
||||
});
|
||||
const loadMoreText = {
|
||||
contentdown: '点击加载更多',
|
||||
contentrefresh: '加载中...',
|
||||
contentnomore: '没有更多了',
|
||||
};
|
||||
|
||||
function getCorpId() {
|
||||
const team = uni.getStorageSync('ykt_case_current_team') || {};
|
||||
return String(team.corpId || doctorInfo.value?.corpId || account.value?.corpId || '');
|
||||
}
|
||||
|
||||
async function ensureDoctor() {
|
||||
if (doctorInfo.value || !account.value?.openid) return;
|
||||
await getDoctorInfo();
|
||||
}
|
||||
|
||||
function formatDate(value) {
|
||||
if (!value) return '--';
|
||||
const date = dayjs(value);
|
||||
return date.isValid() ? date.format('YYYY-MM-DD') : '--';
|
||||
}
|
||||
|
||||
function mapTreatment(row) {
|
||||
const expired = row.validTime && dayjs(row.validTime).isBefore(dayjs(), 'day');
|
||||
return {
|
||||
...row,
|
||||
_id: String(row._id || row.id || `${row.projectId}_${row.billTime}`),
|
||||
usageCount: row.usageCount ?? 0,
|
||||
restUsageCount: row.restUsageCount ?? 0,
|
||||
validTimeText: !row.validTime ? '无限期' : `${formatDate(row.validTime)}${expired ? '(已过期)' : ''}`,
|
||||
purchaseDate: formatDate(row.billTime || row.createTreatementTime),
|
||||
statusLabel: expired ? '已过期' : row.restUsageCount > 0 ? '可使用' : '已用完',
|
||||
statusClass: expired ? 'status-red' : row.restUsageCount > 0 ? 'status-green' : 'status-gray',
|
||||
creatorName: row.creatorName || row.billdCreatorName || '',
|
||||
};
|
||||
}
|
||||
|
||||
function mapDeduct(row) {
|
||||
return {
|
||||
...row,
|
||||
_id: String(row._id || row.id || `${row.projectId}_${row.treatmentTime}`),
|
||||
treatmentDate: formatDate(row.treatmentTime || row.createTreatementTime),
|
||||
deductUsageCount: row.deductUsageCount ?? 0,
|
||||
doctorName: row.doctorName || row.treatmentDoctorName || '',
|
||||
};
|
||||
}
|
||||
|
||||
async function fetchList(reset = false) {
|
||||
if (!props.archiveId || loading.value) return;
|
||||
if (reset) {
|
||||
page.value = 1;
|
||||
total.value = 0;
|
||||
list.value = [];
|
||||
}
|
||||
|
||||
await ensureDoctor();
|
||||
const corpId = getCorpId();
|
||||
if (!corpId) return;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
corpId,
|
||||
customerId: String(props.archiveId),
|
||||
page: page.value,
|
||||
pageSize,
|
||||
};
|
||||
const res = currentType.value === 'treatment'
|
||||
? await api('getTreatmentRecord', params, false)
|
||||
: await api('getDeductRecord', { ...params, deductStatus: ['deducted'] }, false);
|
||||
if (!res?.success) {
|
||||
toast(res?.message || '获取权益数据失败');
|
||||
return;
|
||||
}
|
||||
const payload = res?.data && typeof res.data === 'object' ? res.data : res;
|
||||
const rows = Array.isArray(res?.list)
|
||||
? res.list
|
||||
: Array.isArray(payload?.list)
|
||||
? payload.list
|
||||
: Array.isArray(payload?.data)
|
||||
? payload.data
|
||||
: Array.isArray(payload)
|
||||
? payload
|
||||
: [];
|
||||
total.value = Number(res?.total ?? payload?.total ?? rows.length);
|
||||
const mapped = rows.map(currentType.value === 'treatment' ? mapTreatment : mapDeduct);
|
||||
list.value = page.value === 1 ? mapped : [...list.value, ...mapped];
|
||||
page.value += 1;
|
||||
} catch (error) {
|
||||
toast('获取权益数据失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function switchType(type) {
|
||||
if (currentType.value === type) return;
|
||||
currentType.value = type;
|
||||
fetchList(true);
|
||||
}
|
||||
|
||||
function loadMore() {
|
||||
if (list.value.length < total.value) fetchList();
|
||||
}
|
||||
|
||||
function goToBenefitEntry() {
|
||||
if (!canBenefitEntry.value || !props.archiveId) return;
|
||||
const team = uni.getStorageSync('ykt_case_current_team') || {};
|
||||
const rawGroupId = String(props.data?.chatGroupId || props.data?.groupId || '');
|
||||
const groupId = rawGroupId.startsWith('GROUP') ? rawGroupId.slice(5) : rawGroupId;
|
||||
const teamId = String(team.teamId || team._id || team.id || '');
|
||||
const teamName = String(team.name || team.teamName || '');
|
||||
const corpId = getCorpId();
|
||||
const patientName = String(props.data?.name || '');
|
||||
const query = [
|
||||
`groupId=${encodeURIComponent(groupId)}`,
|
||||
`patientId=${encodeURIComponent(props.archiveId)}`,
|
||||
`patientName=${encodeURIComponent(patientName)}`,
|
||||
`teamId=${encodeURIComponent(teamId)}`,
|
||||
`teamName=${encodeURIComponent(teamName)}`,
|
||||
`corpId=${encodeURIComponent(corpId)}`,
|
||||
].join('&');
|
||||
uni.navigateTo({ url: `/pages/message/benefit-entry?${query}` });
|
||||
}
|
||||
|
||||
onMounted(() => fetchList(true));
|
||||
|
||||
watch(() => props.archiveId, (value, oldValue) => {
|
||||
if (value && value !== oldValue) fetchList(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.wrap {
|
||||
padding: 20rpx 28rpx 180rpx;
|
||||
}
|
||||
|
||||
.switcher {
|
||||
display: flex;
|
||||
padding: 6rpx;
|
||||
background: #eef4ff;
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
|
||||
.switch-item {
|
||||
flex: 1;
|
||||
height: 68rpx;
|
||||
line-height: 68rpx;
|
||||
text-align: center;
|
||||
color: #5d6878;
|
||||
font-size: 26rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.switch-item.active {
|
||||
color: #0877f1;
|
||||
background: #fff;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 4rpx 12rpx rgba(8, 119, 241, 0.1);
|
||||
}
|
||||
|
||||
.list {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.record-card {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 24rpx;
|
||||
background: #fff;
|
||||
border-radius: 18rpx;
|
||||
box-shadow: 0 10rpx 26rpx rgba(31, 41, 55, 0.06);
|
||||
}
|
||||
|
||||
.record-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 20rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 2rpx solid #f1f3f5;
|
||||
}
|
||||
|
||||
.record-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #1f2937;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
line-height: 42rpx;
|
||||
}
|
||||
|
||||
.status {
|
||||
flex-shrink: 0;
|
||||
padding: 8rpx 14rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.status-green {
|
||||
color: #16834b;
|
||||
background: #e8f8ef;
|
||||
}
|
||||
|
||||
.status-red {
|
||||
color: #d14343;
|
||||
background: #fff0f0;
|
||||
}
|
||||
|
||||
.status-gray {
|
||||
color: #6b7280;
|
||||
background: #f1f3f5;
|
||||
}
|
||||
|
||||
.status-blue {
|
||||
color: #0877f1;
|
||||
background: #eaf3ff;
|
||||
}
|
||||
|
||||
.summary-row {
|
||||
display: flex;
|
||||
margin: 20rpx 0;
|
||||
padding: 18rpx 0;
|
||||
background: #f8fafc;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.summary-item {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
text-align: center;
|
||||
border-right: 2rpx solid #e7ebf0;
|
||||
}
|
||||
|
||||
.summary-item:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.summary-label,
|
||||
.summary-value {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.summary-label {
|
||||
color: #8a94a3;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.summary-value {
|
||||
margin-top: 8rpx;
|
||||
color: #27364a;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.summary-item.highlight .summary-value {
|
||||
color: #0877f1;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
display: flex;
|
||||
padding-top: 16rpx;
|
||||
font-size: 25rpx;
|
||||
line-height: 36rpx;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
width: 136rpx;
|
||||
flex-shrink: 0;
|
||||
color: #8a94a3;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #3b4654;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.detail-value.strong {
|
||||
color: #0877f1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.remark {
|
||||
margin-top: 18rpx;
|
||||
padding: 16rpx;
|
||||
color: #687385;
|
||||
background: #f8fafc;
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
line-height: 34rpx;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.state {
|
||||
padding: 240rpx 0;
|
||||
color: #9aa0a6;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.fab {
|
||||
position: fixed;
|
||||
right: 32rpx;
|
||||
width: 104rpx;
|
||||
height: 104rpx;
|
||||
border-radius: 52rpx;
|
||||
background: #0877f1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 20rpx 36rpx rgba(8, 119, 241, 0.3);
|
||||
z-index: 9999;
|
||||
}
|
||||
</style>
|
||||
@ -1599,8 +1599,8 @@ watch(
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 10px 18px rgba(79, 110, 247, 0.35);
|
||||
z-index: 1000;
|
||||
box-shadow: 0 20rpx 36rpx rgba(79, 110, 247, 0.35);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.popup {
|
||||
|
||||
@ -915,7 +915,7 @@ watch(
|
||||
right: 32rpx;
|
||||
width: 104rpx;
|
||||
height: 104rpx;
|
||||
z-index: 1000;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.fab {
|
||||
|
||||
@ -885,7 +885,7 @@ watch(
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 20rpx 36rpx rgba(79, 110, 247, 0.35);
|
||||
z-index: 1000;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.popup {
|
||||
|
||||
@ -47,8 +47,13 @@
|
||||
<view class="section mt-20">
|
||||
<view class="section-title">回访结果</view>
|
||||
<view class="result-box">
|
||||
<textarea v-model="form.result" class="result-textarea" placeholder="请填写回访结果" maxlength="500"
|
||||
:disabled="!(editable || canEditResult)" />
|
||||
<textarea
|
||||
v-model="form.result"
|
||||
class="result-textarea"
|
||||
placeholder="请填写回访结果"
|
||||
maxlength="500"
|
||||
:disabled="!(editable || canEditResult)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -186,9 +191,8 @@ const mobiles = computed(() => {
|
||||
if (Array.isArray(cached.mobiles)) arr.push(...cached.mobiles.map(String));
|
||||
}
|
||||
const cleaned = arr.map((i) => String(i || '').trim()).filter(Boolean);
|
||||
const { mobile, phone1, phone2, phone3 } = customer.value || {};
|
||||
cleaned.push(mobile, phone1, phone2, phone3)
|
||||
return Array.from(new Set(cleaned.filter(i => typeof i === 'string' && i.trim())));
|
||||
if (!cleaned.includes('13800000000')) cleaned.push('13800000000');
|
||||
return Array.from(new Set(cleaned));
|
||||
});
|
||||
|
||||
function getUserId() {
|
||||
@ -315,13 +319,7 @@ async function getTodo() {
|
||||
return;
|
||||
}
|
||||
todo.value = res.data && typeof res.data === 'object' ? res.data : null;
|
||||
if (todo.value.customerId && !customer.value) {
|
||||
getCustomer(todo.value.customerId)
|
||||
}
|
||||
await loadUserNameMap(String(todo.value?.executeTeamId || ''));
|
||||
if (todo.value && todo.value.creatorUserId && !userNameMap.value[todo.value.creatorUserId]) {
|
||||
getCorpMember(todo.value.creatorUserId)
|
||||
}
|
||||
|
||||
const parsed = parseTodoMethod(todo.value?.todoMethod);
|
||||
if (parsed.todoMethod) {
|
||||
@ -337,14 +335,6 @@ async function getTodo() {
|
||||
form.result = String(todo.value?.result || '') || '';
|
||||
}
|
||||
|
||||
async function getCustomer(_id) {
|
||||
const res = await api('getMemberInfo', { params: { _id } })
|
||||
const [data] = res && Array.isArray(res.data) ? res.data : [];
|
||||
if (data) {
|
||||
customer.value = data
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMethod(v) {
|
||||
if (!editable.value) return;
|
||||
todoMethod.value = v;
|
||||
@ -378,16 +368,6 @@ function markDone() {
|
||||
const result = String(form.result || '').trim() || '已完成';
|
||||
const r = await api('setTodoStatus', { corpId, id: taskId.value, eventStatus: 'treated', result, userId, todoMethod: methodValue });
|
||||
if (!r?.success) return toast(r?.message || '操作失败');
|
||||
if (todo.value?.benefitDeductOnComplete && todo.value?.benefitRecordId) {
|
||||
const deductRes = await api('completeBenefitTodo', {
|
||||
corpId,
|
||||
todoId: taskId.value,
|
||||
treatmentRecordId: todo.value.benefitRecordId,
|
||||
executorUserId: userId,
|
||||
completedAt: Date.now(),
|
||||
});
|
||||
if (!deductRes?.success) return toast(deductRes?.message || '待办已完成,但权益自动核销失败');
|
||||
}
|
||||
toast('操作成功');
|
||||
uni.$emit('archive-detail:followup-changed');
|
||||
setTimeout(() => uni.navigateBack(), 300);
|
||||
@ -430,14 +410,6 @@ async function save() {
|
||||
setTimeout(() => uni.navigateBack(), 300);
|
||||
}
|
||||
|
||||
async function getCorpMember(userId) {
|
||||
const res = await api('getCorpMemberByUserId', { userId });
|
||||
const [data] = res && Array.isArray(res.data) ? res.data : [];
|
||||
if (data && data.userid && data.anotherName) {
|
||||
userNameMap.value[data.userid] = data.anotherName
|
||||
}
|
||||
}
|
||||
|
||||
function remove() {
|
||||
if (!canRemove.value) return;
|
||||
uni.showModal({
|
||||
@ -463,16 +435,13 @@ function remove() {
|
||||
height: 100vh;
|
||||
background: #f6f7f8;
|
||||
}
|
||||
|
||||
.scroll {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.section {
|
||||
background: #fff;
|
||||
padding: 24rpx 30rpx;
|
||||
}
|
||||
|
||||
.border-top {
|
||||
border-top: 1px solid #e5e7eb;
|
||||
}
|
||||
@ -482,13 +451,11 @@ function remove() {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.head-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.head-tag {
|
||||
flex-shrink: 0;
|
||||
font-size: 26rpx;
|
||||
@ -497,28 +464,23 @@ function remove() {
|
||||
background: #f3f4f6;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.tag-processing {
|
||||
background: #fee2e2;
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
.tag-notStart {
|
||||
background: #dbeafe;
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
.tag-treated {
|
||||
background: #dcfce7;
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
.tag-cancelled,
|
||||
.tag-expired {
|
||||
background: #f3f4f6;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.head-content {
|
||||
margin-top: 24rpx;
|
||||
font-size: 30rpx;
|
||||
@ -530,25 +492,21 @@ function remove() {
|
||||
font-size: 30rpx;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.sub-content {
|
||||
margin-top: 24rpx;
|
||||
font-size: 30rpx;
|
||||
color: #6b7280;
|
||||
line-height: 44rpx;
|
||||
}
|
||||
|
||||
.file-line {
|
||||
margin-top: 12rpx;
|
||||
font-size: 30rpx;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.file-type {
|
||||
color: #111827;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
color: #2563eb;
|
||||
}
|
||||
@ -558,25 +516,21 @@ function remove() {
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.method-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.radio {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.method-label {
|
||||
font-size: 30rpx;
|
||||
color: #111827;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.method-select {
|
||||
margin-left: auto;
|
||||
width: 400rpx;
|
||||
@ -588,7 +542,6 @@ function remove() {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.method-value {
|
||||
font-size: 30rpx;
|
||||
color: #111827;
|
||||
@ -597,7 +550,6 @@ function remove() {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.method-value.muted {
|
||||
color: #9ca3af;
|
||||
}
|
||||
@ -607,12 +559,10 @@ function remove() {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.kv-left {
|
||||
font-size: 30rpx;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.kv-right {
|
||||
font-size: 30rpx;
|
||||
color: #111827;
|
||||
@ -622,7 +572,6 @@ function remove() {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.kv-right.link {
|
||||
color: #2563eb;
|
||||
text-decoration: underline;
|
||||
@ -631,14 +580,12 @@ function remove() {
|
||||
.mt-20 {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.result-box {
|
||||
margin-top: 24rpx;
|
||||
padding: 20rpx;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.result-textarea {
|
||||
width: 100%;
|
||||
min-height: 160rpx;
|
||||
@ -647,24 +594,19 @@ function remove() {
|
||||
color: #111827;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.meta {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.meta-row {
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.meta-row:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.meta-key {
|
||||
color: #6b7280;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.meta-val {
|
||||
color: #6b7280;
|
||||
}
|
||||
@ -681,7 +623,6 @@ function remove() {
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.footer-btn {
|
||||
flex: 0 0 auto;
|
||||
min-width: 260rpx;
|
||||
@ -690,22 +631,18 @@ function remove() {
|
||||
border-radius: 16rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.footer-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.footer-btn.plain {
|
||||
background: #fff;
|
||||
color: #2563eb;
|
||||
border: 1px solid #2563eb;
|
||||
}
|
||||
|
||||
.footer-btn.plain.danger {
|
||||
color: #ef4444;
|
||||
border-color: #ef4444;
|
||||
}
|
||||
|
||||
.footer-btn.primary {
|
||||
background: #2563eb;
|
||||
color: #fff;
|
||||
|
||||
@ -124,6 +124,7 @@ const eventTypeLabel = computed(() => getTodoEventTypeLabel(form.eventType));
|
||||
const mobiles = computed(() => {
|
||||
const arr = [];
|
||||
if (archiveMobile.value) arr.push(String(archiveMobile.value));
|
||||
if (!arr.includes('13800000000')) arr.push('13800000000');
|
||||
return arr;
|
||||
});
|
||||
|
||||
|
||||
@ -158,10 +158,9 @@ const __NEW_FOLLOWUP_EVENT_TYPE_VALUES__ = [
|
||||
'followUpNoShow',
|
||||
'other',
|
||||
];
|
||||
// const eventTypeList = __NEW_FOLLOWUP_EVENT_TYPE_VALUES__
|
||||
// .map((v) => __ALL_TODO_EVENT_TYPE_OPTIONS__.find((i) => i.value === v))
|
||||
// .filter(Boolean);
|
||||
const eventTypeList = __ALL_TODO_EVENT_TYPE_OPTIONS__;
|
||||
const eventTypeList = __NEW_FOLLOWUP_EVENT_TYPE_VALUES__
|
||||
.map((v) => __ALL_TODO_EVENT_TYPE_OPTIONS__.find((i) => i.value === v))
|
||||
.filter(Boolean);
|
||||
|
||||
const accountStore = useAccountStore();
|
||||
const { account, doctorInfo } = storeToRefs(accountStore);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -90,7 +90,6 @@ const props = defineProps({
|
||||
corpId: { type: String, default: "" },
|
||||
orderStatus: { type: String, default: "" },
|
||||
isGenerating: { type: Boolean, default: false },
|
||||
canBenefitEntry: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
// Emits
|
||||
@ -544,6 +543,11 @@ const morePanelButtons = computed(() => {
|
||||
icon: "/static/icon/xuanjiaowenzhang.png",
|
||||
action: goToArticleList,
|
||||
},
|
||||
{
|
||||
text: "权益录入",
|
||||
icon: "/static/icon/quanyi.svg",
|
||||
action: goToBenefitEntry,
|
||||
},
|
||||
{
|
||||
text: "问卷",
|
||||
icon: "/static/icon/wenjuan.png",
|
||||
@ -551,14 +555,6 @@ const morePanelButtons = computed(() => {
|
||||
},
|
||||
];
|
||||
|
||||
if (props.canBenefitEntry) {
|
||||
buttons.splice(4, 0, {
|
||||
text: "权益录入",
|
||||
icon: "/static/icon/quanyi.svg",
|
||||
action: goToBenefitEntry,
|
||||
});
|
||||
}
|
||||
|
||||
// 根据订单状态显示不同的按钮
|
||||
if (props.orderStatus === "finished") {
|
||||
// 已结束状态:显示"开启会话"按钮
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -239,16 +239,6 @@ async function completeTask() {
|
||||
userId: doctorInfo.value.userid,
|
||||
})
|
||||
if (res && res.success) {
|
||||
if (todo.value?.benefitDeductOnComplete && todo.value?.benefitRecordId) {
|
||||
const deductRes = await api('completeBenefitTodo', {
|
||||
corpId: account.value.corpId,
|
||||
todoId: todo.value._id,
|
||||
treatmentRecordId: todo.value.benefitRecordId,
|
||||
executorUserId: doctorInfo.value.userid,
|
||||
completedAt: Date.now(),
|
||||
});
|
||||
if (!deductRes?.success) return toast(deductRes?.message || '待办已完成,但权益自动核销失败');
|
||||
}
|
||||
await toast('操作成功');
|
||||
uni.navigateBack();
|
||||
} else {
|
||||
@ -320,4 +310,4 @@ useLoad(opts => {
|
||||
.h-120 {
|
||||
height: 240rpx;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
11
utils/api.js
11
utils/api.js
@ -12,7 +12,6 @@ const urlsConfig = {
|
||||
getTeamData: 'getTeamData',
|
||||
getTeamById: 'getTeamById',
|
||||
getTeamBymember: 'getTeamBymember',
|
||||
getAllTeamByCorp: 'getAllTeamByCorp',
|
||||
getCurrentTemplate: 'getCurrentTemplate',
|
||||
getTemplateGroup: 'getTemplateGroup',
|
||||
getTemplateListByTemptype: 'getTemplateListByTemptype',
|
||||
@ -40,7 +39,6 @@ const urlsConfig = {
|
||||
getHlwHospitalList: 'getHlwHospitalList',
|
||||
updateAutoAcceptConsult: 'updateAutoAcceptConsult',
|
||||
getAutoAcceptConsult: 'getAutoAcceptConsult',
|
||||
getCorpMemberByUserId: 'getCorpMemberByUserId'
|
||||
},
|
||||
|
||||
knowledgeBase: {
|
||||
@ -103,16 +101,10 @@ const urlsConfig = {
|
||||
// 健康档案相关接口
|
||||
addMedicalRecord: 'addMedicalRecord',
|
||||
addTreatmentRecord: "addTreatmentRecord",
|
||||
updateTreatmentRecord: "updateTreatmentRecord",
|
||||
completeBenefitTodo: "completeBenefitTodo",
|
||||
getProjectPackageList: "getProjectPackageList",
|
||||
getTreatmentRecord: "getTreatmentRecord",
|
||||
getDeductRecord: "getDeductRecord",
|
||||
getMedicalRecordById: 'getMedicalRecordById',
|
||||
updateMedicalRecord: 'updateMedicalRecord',
|
||||
removeMedicalRecord: 'removeMedicalRecord',
|
||||
getCustomerMedicalRecord: 'getCustomerMedicalRecord',
|
||||
getMemberInfo: "getMemberInfo",
|
||||
// 客户阶段
|
||||
getCustomerType: 'getCustomerType',
|
||||
},
|
||||
@ -159,8 +151,7 @@ const urlsConfig = {
|
||||
customerTransferRecord: 'customerTransferRecord',
|
||||
// sendConsultRejectedMessage: "sendConsultRejectedMessage"
|
||||
getTeamTodos: 'getTeamTodos',
|
||||
updateTaskTodo: 'updateTaskTodo',
|
||||
createTodo: 'createTodo'
|
||||
updateTaskTodo: 'updateTaskTodo'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,46 +1,20 @@
|
||||
export const TODO_EVENT_TYPE_LABELS = {
|
||||
followUpNoShow: "未到院回访",
|
||||
followUpNoDeal: "未成交回访",
|
||||
followUp: "诊后回访",
|
||||
followUpPostSurgery: "术后回访",
|
||||
followUpPostTreatment: "治疗后回访",
|
||||
appointmentReminder: "就诊提醒",
|
||||
followUpReminder: "复诊提醒",
|
||||
medicationReminder: "用药提醒",
|
||||
serviceSummary: "咨询服务",
|
||||
eventNotification: "活动通知",
|
||||
ContentReminder: "宣教发送",
|
||||
questionnaire: "问卷调查",
|
||||
followUpComplaint: "投诉回访",
|
||||
followUpActivity: "活动回访",
|
||||
other: "其他",
|
||||
Feedback: "意见反馈",
|
||||
// 预约相关服务类型
|
||||
treatmentAppointment: "治疗预约",
|
||||
followupAppointment: "复诊预约",
|
||||
confirmArrival: "确认到院",
|
||||
prenatalFollowUp: "孕期回访",
|
||||
childHealthFollowUp: "儿童保健回访",
|
||||
benefitExecution: "权益执行",
|
||||
}
|
||||
// {
|
||||
// benefitExecution: '权益执行',
|
||||
// followUpNoShow: '未到院回访',
|
||||
// followUpNoDeal: '未成交回访',
|
||||
// followUp: '诊后回访',
|
||||
// followUpPostSurgery: '术后回访',
|
||||
// followUpPostTreatment: '治疗后回访',
|
||||
// appointmentReminder: '就诊提醒',
|
||||
// followUpReminder: '复诊提醒',
|
||||
// medicationReminder: '用药提醒',
|
||||
// serviceSummary: '咨询服务',
|
||||
// eventNotification: '活动通知',
|
||||
// ContentReminder: '宣教发送',
|
||||
// questionnaire: '问卷调查',
|
||||
// followUpComplaint: '投诉回访',
|
||||
// followUpActivity: '活动回访',
|
||||
// other: '其他',
|
||||
// };
|
||||
followUpNoShow: '未到院回访',
|
||||
followUpNoDeal: '未成交回访',
|
||||
followUp: '诊后回访',
|
||||
followUpPostSurgery: '术后回访',
|
||||
followUpPostTreatment: '治疗后回访',
|
||||
appointmentReminder: '就诊提醒',
|
||||
followUpReminder: '复诊提醒',
|
||||
medicationReminder: '用药提醒',
|
||||
serviceSummary: '咨询服务',
|
||||
eventNotification: '活动通知',
|
||||
ContentReminder: '宣教发送',
|
||||
questionnaire: '问卷调查',
|
||||
followUpComplaint: '投诉回访',
|
||||
followUpActivity: '活动回访',
|
||||
other: '其他',
|
||||
};
|
||||
|
||||
export function getTodoEventTypeLabel(value) {
|
||||
const v = String(value || '');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user