ykt-wxapp/pages/case/plan-list.vue
2026-02-12 14:44:58 +08:00

253 lines
5.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<full-page :customScroll="list.length === 0" pageStyle="background:#fff">
<view v-if="list.length === 0" class="h-full flex flex-col items-center justify-center">
<view v-if="loading" class="text-base text-center text-dark">加载中...</view>
<empty-data v-else text="暂无回访计划" />
</view>
<template v-else>
<view v-for="(p, idx) in list" :key="p.id" class="item">
<view class="left">
<view class="name-row">
<view class="name">{{ p.planName }}</view>
<view v-if="p.planType === 'corp'" class="tag corp">机构</view>
<view class="tag outline" @click.stop="preview(p)">详情</view>
</view>
<view class="desc">应用范围{{ p.planDetail }}</view>
</view>
<view class="btn" @click="select(p)">选择</view>
</view>
</template>
<template #footer>
<view class="relative shadow-up bg-white">
<view class="p-15 text-center" @click="toService()">
<text class="mr-5 text-base text-gray">如没有符合的内容</text>
<text class="text-base text-primary">联系客服</text>
</view>
</view>
</template>
</full-page>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { storeToRefs } from 'pinia';
import api from '@/utils/api';
import useAccountStore from '@/store/account';
import { toast } from '@/utils/widget';
import { getTodoEventTypeLabel } from '@/utils/todo-const';
import EmptyData from "@/components/empty-data.vue";
import fullPage from '@/components/full-page.vue';
const archiveId = ref('');
const loading = ref(false);
const list = ref([]);
const accountStore = useAccountStore();
const { account, doctorInfo } = storeToRefs(accountStore);
const { getDoctorInfo } = accountStore;
onLoad((options) => {
archiveId.value = options?.archiveId ? String(options.archiveId) : '';
loadList();
});
async function ensureDoctor() {
if (doctorInfo.value) return;
if (!account.value?.openid) return;
try {
await getDoctorInfo();
} catch {
// ignore
}
}
function getUserId() {
const d = doctorInfo.value || {};
const a = account.value || {};
return String(d.userid || d.userId || d.corpUserId || a.userid || a.userId || '') || '';
}
function getCorpId() {
const t = uni.getStorageSync('ykt_case_current_team') || {};
const a = account.value || {};
const d = doctorInfo.value || {};
return String(t.corpId || a.corpId || d.corpId || '') || '';
}
function getTeamId() {
const t = uni.getStorageSync('ykt_case_current_team') || {};
return String(t.teamId || '') || '';
}
function normalizePlan(raw) {
if (!raw || typeof raw !== 'object') return null;
const id = String(raw.planId || raw._id || '');
if (!id) return null;
const taskList = Array.isArray(raw.taskList) ? raw.taskList : [];
const first = taskList[0] && typeof taskList[0] === 'object' ? taskList[0] : {};
const eventType = String(first.eventType || '');
const taskContent = String(first.taskContent || '');
return {
...raw,
id,
planName: String(raw.planName || ''),
planType: String(raw.planType || ''),
planDetail: String(raw.planDetail || ''),
firstEventType: eventType,
firstEventTypeLabel: eventType ? getTodoEventTypeLabel(eventType) : '',
taskContent,
taskCount: taskList.length,
taskList,
};
}
function toService() {
uni.navigateTo({
url: '/pages/work/service/contact-service'
})
}
async function loadList() {
if (loading.value) return;
loading.value = true;
try {
await ensureDoctor();
const corpId = getCorpId();
const userId = getUserId();
const teamId = getTeamId();
if (!corpId || !userId || !teamId) {
list.value = [];
toast('缺少用户/团队信息');
return;
}
const res = await api('getManagementPlan', {
corpId,
userId,
planType: 'team',
teamId,
page: 1,
pageSize: 999,
});
if (!res?.success) {
list.value = [];
toast(res?.message || '获取回访计划失败');
return;
}
const arr = Array.isArray(res.data) ? res.data : [];
list.value = arr.filter((p) => p && p.planStatus === true).map(normalizePlan).filter(Boolean);
} finally {
loading.value = false;
}
}
function select(plan) {
uni.setStorageSync('select-mamagement-plan', plan);
uni.navigateTo({ url: `/pages/case/plan-execute?archiveId=${encodeURIComponent(archiveId.value)}` });
}
function preview(plan) {
uni.setStorageSync('preview-mamagement-plan', plan);
uni.navigateTo({ url: `/pages/case/plan-preview?archiveId=${encodeURIComponent(archiveId.value)}` });
}
</script>
<style scoped>
.scroll {
height: 100vh;
}
.loading {
padding: 16px;
font-size: 13px;
color: #9aa0a6;
}
.item {
display: flex;
align-items: center;
padding: 12px 14px;
border-bottom: 1px solid #f2f2f2;
}
.left {
flex: 1;
min-width: 0;
margin-right: 10px;
}
.name-row {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 6px;
}
.name {
font-size: 14px;
font-weight: 600;
color: #333;
max-width: 220px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tag {
font-size: 12px;
padding: 4px 8px;
border-radius: 6px;
}
.tag.corp {
background: #0877F1;
color: #fff;
}
.tag.outline {
border: 1px solid #0877F1;
color: #0877F1;
background: #fff;
}
.desc {
font-size: 12px;
color: #999;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.btn {
flex-shrink: 0;
padding: 8px 12px;
border-radius: 999px;
border: 1px solid #0877F1;
color: #0877F1;
font-size: 13px;
}
.empty {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.empty-img {
width: 160px;
height: 160px;
opacity: 0.9;
}
.empty-text {
margin-top: 10px;
font-size: 13px;
color: #9aa0a6;
}
</style>