320 lines
10 KiB
Vue
Raw Normal View History

2026-01-20 19:36:49 +08:00
<template>
2026-02-04 15:23:57 +08:00
<page-loading v-if="loading && teams.length === 0" />
<full-page v-else-if="teams.length && team" class="home-container" :pageStyle="pageStyle">
2026-04-03 11:24:59 +08:00
<!-- <template #header> -->
2026-05-19 19:26:16 +08:00
<team-head :team="team" :customers="customers" :teams="teams" @changeTeam="changeTeam" />
2026-04-03 11:24:59 +08:00
<!-- </template> -->
2026-02-03 15:42:32 +08:00
<view class="home-section home-section--first">
2026-05-13 20:38:12 +08:00
<customer-archive ref="archiveRef" :corpId="corpId" :corpUserIds="corpUserIds"
:referenceCustomerIds="referenceCustomerIds" :team="team" @update:customers="handleCustomersUpdate" />
2026-02-03 15:42:32 +08:00
</view>
2026-04-02 18:09:06 +08:00
<view class="home-section">
<team-guide :team="team" />
</view>
2026-02-03 15:42:32 +08:00
<view class="home-section">
<consult ref="consultRef" :corpId="corpId" :teamId="team.teamId" :team="team" :customers="customers" />
2026-02-03 15:42:32 +08:00
</view>
2026-02-05 10:27:20 +08:00
<!-- <view class="home-section">
2026-02-03 15:42:32 +08:00
<team-mate :team="team" />
2026-02-05 10:27:20 +08:00
</view> -->
2026-02-03 15:42:32 +08:00
<view class="home-section">
<article-list :team="team" />
</view>
2026-01-20 19:36:49 +08:00
</full-page>
<yc-home v-else />
</template>
<script setup>
2026-02-12 10:45:53 +08:00
import { computed, ref, watch } from "vue";
2026-02-04 12:51:45 +08:00
import { storeToRefs } from "pinia";
2026-05-13 20:38:12 +08:00
import { onLoad, onShow, onShareAppMessage } from "@dcloudio/uni-app";
2026-02-10 11:08:00 +08:00
// import useGuard from "@/hooks/useGuard";
2026-02-04 12:51:45 +08:00
import useAccount from "@/store/account";
import api from "@/utils/api";
import { toast } from "@/utils/widget";
import { get, remove, set } from "@/utils/cache";
import { normalizeCorpId } from "@/utils/api-base-config";
2026-01-20 19:36:49 +08:00
2026-02-04 12:51:45 +08:00
import FullPage from "@/components/full-page.vue";
import articleList from "./article-list.vue";
import consult from "./consult.vue";
import customerArchive from "./customer-archive.vue";
import teamHead from "./team-head.vue";
2026-04-02 18:09:06 +08:00
import teamGuide from "./team-guide.vue";
// import teamMate from "./team-mate.vue";
2026-02-04 12:51:45 +08:00
import ycHome from "./yc-home.vue";
import pageLoading from "./loading.vue";
2026-01-20 19:36:49 +08:00
2026-02-10 11:08:00 +08:00
// const { useLoad, useShow } = useGuard();
2026-01-20 19:36:49 +08:00
const { account } = storeToRefs(useAccount());
2026-04-14 16:17:40 +08:00
const { login, getTeams } = useAccount();
2026-05-13 21:28:42 +08:00
const env = __VITE_ENV__;
2026-08-18 17:28:42 +08:00
const appid = env.MP_WX_APP_ID;
2026-05-13 20:38:12 +08:00
const shareAppVersion = env.MP_SHARE_WX_APP_VERSION;
2026-01-20 19:36:49 +08:00
const team = ref(null);
const teams = ref([]);
2026-02-10 11:08:00 +08:00
const loading = ref(false);
2026-01-28 13:38:05 +08:00
const customers = ref([]);
2026-03-04 17:19:52 +08:00
const consultRef = ref(null);
const archiveRef = ref(null);
2026-03-05 15:03:07 +08:00
const corpUserIds = ref({});
2026-05-13 20:38:12 +08:00
const referenceCustomerIds = ref({});
2026-08-18 17:28:42 +08:00
const pendingAction = ref(null);
const awaitingArchiveBinding = ref(false);
const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info";
2026-01-20 19:36:49 +08:00
const corpId = computed(() => team.value?.corpId);
2026-02-03 15:42:32 +08:00
// UI 两段式背景:顶部 281px 渐变 + 下方纯色(按 375 设计稿281px ≈ 562rpx
const pageStyle =
2026-02-04 12:51:45 +08:00
"background: linear-gradient(180deg, #065BD6 15.05%, #F6FAFA 95.37%) 0 0/100% 562rpx no-repeat, #F6FAFA;";
2026-02-03 09:59:49 +08:00
2026-01-28 13:38:05 +08:00
function handleCustomersUpdate(newCustomers) {
customers.value = newCustomers;
}
function getTeamIdentity(source = {}) {
return {
teamId: source.teamId || "",
corpId: normalizeCorpId(source.corpId || ""),
};
}
function cacheCurrentTeam(currentTeam) {
if (!currentTeam || !currentTeam.teamId) return;
set(HOME_CURRENT_TEAM_CACHE_KEY, getTeamIdentity(currentTeam));
}
function isSameTeam(candidate, target = {}) {
const targetTeamId = target.teamId || "";
if (!candidate || !candidate.teamId || candidate.teamId !== targetTeamId) return false;
const targetCorpId = normalizeCorpId(target.corpId || "");
if (!targetCorpId) return true;
const teamCorpId = normalizeCorpId(candidate.corpId || "");
return targetCorpId === teamCorpId;
}
2026-01-20 19:36:49 +08:00
async function changeTeam({ teamId, corpId, corpName }) {
loading.value = true;
2026-08-18 17:28:42 +08:00
try {
const res = await api("getTeamData", { teamId, corpId });
if (res && res.data) {
team.value = {
...res.data,
corpId: normalizeCorpId(res.data.corpId || corpId),
};
team.value.corpName = corpName;
cacheCurrentTeam(team.value);
return team.value;
}
2026-02-04 12:51:45 +08:00
toast(res?.message || "获取团队信息失败");
2026-08-18 17:28:42 +08:00
return null;
} finally {
loading.value = false;
}
}
function parsePendingAction(options = {}) {
const type = options.type || "";
if (type === "experienceCoupon" && options.issueId && options.corpId) {
return {
type,
corpId: normalizeCorpId(options.corpId),
teamId: options.teamId || "",
issueId: options.issueId,
memberId: options.memberId || options.customerId || "",
couponId: options.couponId || "",
unionid: options.unionid || "",
externalUserId: options.externalUserId || "",
};
}
if (type === "appointmentRegistration" && options.customerId && options.corpId) {
return {
type,
corpId: normalizeCorpId(options.corpId),
teamId: options.teamId || "",
customerId: options.customerId,
name: options.name || "",
corpName: options.corpName || "",
appointmentId: options.appointmentId || "",
month: options.month || "",
externalUserId: options.externalUserId || "",
corpUserId: options.corpUserId || "",
};
}
return null;
}
function buildActionUrl(action) {
const params = Object.entries(action)
.filter(([key, value]) => key !== "type" && value)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join("&");
const page = action.type === "experienceCoupon"
? "/pages/experience-coupon/claim"
: "/pages/record/appointment-record";
return `${page}?${params}`;
}
function buildArchiveBindUrl(action) {
const customerId = action.memberId || action.customerId;
return [
`/pages/archive/edit-archive?corpId=${encodeURIComponent(action.corpId)}`,
`teamId=${encodeURIComponent(team.value?.teamId || action.teamId)}`,
`bindCustomerId=${encodeURIComponent(customerId)}`,
`source=${encodeURIComponent(action.type)}`,
].join("&");
}
async function continuePendingAction() {
const action = pendingAction.value;
if (!action || !account.value?.openid || !team.value?.teamId) return;
if (action.teamId && action.teamId !== team.value.teamId) {
toast("未找到目标服务团队");
pendingAction.value = null;
return;
2026-01-20 19:36:49 +08:00
}
2026-08-18 17:28:42 +08:00
const customerId = action.memberId || action.customerId;
const customerRes = await api(
"getCustomerByCustomerId",
{ corpId: action.corpId, customerId },
false
);
const customer = customerRes?.success ? customerRes.data : null;
if (!customer) {
toast(customerRes?.message || "目标档案不存在");
pendingAction.value = null;
return;
}
const archiveBound = String(customer.miniAppId || "") === String(account.value.openid);
if (!archiveBound) {
if (awaitingArchiveBinding.value) {
awaitingArchiveBinding.value = false;
pendingAction.value = null;
return;
}
awaitingArchiveBinding.value = true;
uni.navigateTo({ url: buildArchiveBindUrl(action) });
return;
}
pendingAction.value = null;
awaitingArchiveBinding.value = false;
uni.navigateTo({ url: buildActionUrl(action) });
2026-01-20 19:36:49 +08:00
}
async function getMatchTeams(inviteTeam = null) {
2026-01-20 19:36:49 +08:00
loading.value = true;
2026-08-18 17:28:42 +08:00
try {
teams.value = await getTeams();
const inviteIdentity = typeof inviteTeam === "string" ? { teamId: inviteTeam } : (inviteTeam || {});
const cachedIdentity = get(HOME_CURRENT_TEAM_CACHE_KEY) || {};
const targetIdentity = getTeamIdentity({
teamId: inviteIdentity.teamId || team.value?.teamId || cachedIdentity.teamId,
corpId: inviteIdentity.corpId || team.value?.corpId || cachedIdentity.corpId,
});
let validTeam = teams.value.find(i => isSameTeam(i, targetIdentity));
if (!validTeam && pendingAction.value && targetIdentity.teamId && account.value?.openid) {
const bindRes = await api("bindWxappWithTeam", {
appid,
corpId: targetIdentity.corpId,
teamId: targetIdentity.teamId,
openid: account.value.openid,
});
if (bindRes?.success) {
teams.value = await getTeams();
validTeam = teams.value.find(i => isSameTeam(i, targetIdentity));
}
}
const firstTeam = teams.value[0];
if (validTeam || firstTeam) {
return await changeTeam(validTeam || firstTeam);
}
2026-01-20 19:36:49 +08:00
team.value = null;
2026-08-18 17:28:42 +08:00
return null;
} finally {
loading.value = false;
2026-01-20 19:36:49 +08:00
}
}
2026-02-10 11:08:00 +08:00
// useLoad((opts) => {
// if (opts.teamId) {
// team.value = { teamId: opts.teamId, corpId: opts.corpId };
// }
// });
2026-01-20 19:36:49 +08:00
2026-08-18 17:28:42 +08:00
onLoad((options = {}) => {
pendingAction.value = parsePendingAction(options);
2026-02-10 16:44:01 +08:00
if (!account.value) login();
})
onShow(async () => {
if (!account.value) await login();
2026-03-05 15:03:07 +08:00
const inviteTeam = get('home-invite-team-info');
remove('home-invite-team-info');
if (inviteTeam && inviteTeam.teamId && inviteTeam.corpUserId) {
corpUserIds.value[inviteTeam.teamId] = inviteTeam.corpUserId;
}
2026-05-13 20:38:12 +08:00
if (inviteTeam && inviteTeam.teamId && inviteTeam.referenceCustomerId) {
referenceCustomerIds.value[inviteTeam.teamId] = inviteTeam.referenceCustomerId;
}
2026-02-10 11:08:00 +08:00
if (account.value && account.value.openid) {
2026-08-18 17:28:42 +08:00
const targetTeam = pendingAction.value?.teamId
? { teamId: pendingAction.value.teamId, corpId: pendingAction.value.corpId }
: null;
await getMatchTeams(targetTeam || (inviteTeam && inviteTeam.teamId ? inviteTeam : null));
await continuePendingAction();
2026-02-10 11:08:00 +08:00
} else {
teams.value = [];
}
if (consultRef.value && typeof consultRef.value.getBadgeCount === 'function') {
consultRef.value.getBadgeCount()
}
2026-03-04 17:19:52 +08:00
if (archiveRef.value && typeof archiveRef.value.getCustomers === 'function') {
archiveRef.value.getCustomers()
}
2026-02-04 12:51:45 +08:00
});
2026-08-18 17:28:42 +08:00
onShareAppMessage(() => {
2026-05-19 19:26:16 +08:00
if (team.value && team.value.supportPatientForward === 'YES') {
2026-05-13 20:38:12 +08:00
const customer = customers.value[0];
const referenceCustomerId = customer ? customer._id : '';
return {
2026-05-28 16:41:53 +08:00
title: `${team.value.name}】这个团队不错,推荐给你!`,
2026-05-13 20:38:12 +08:00
type: shareAppVersion || 0, // 0 正式版本 | 1 开发版本 | 2 体验版本
path: `/pages/login/redirect-page?teamId=${team.value.teamId}&corpId=${team.value.corpId}&type=archive&referenceCustomerId=${referenceCustomerId}`
}
}
})
2026-08-18 17:28:42 +08:00
watch(account, async (n, o) => {
2026-02-12 10:45:53 +08:00
if (n && !o) {
2026-08-18 17:28:42 +08:00
if (!pendingAction.value) await getMatchTeams();
2026-02-12 10:45:53 +08:00
} else if (!n && o) {
teams.value = [];
}
})
2026-04-14 16:17:40 +08:00
2026-01-20 19:36:49 +08:00
</script>
2026-02-03 09:59:49 +08:00
<style scoped>
.home-container {
min-height: 100vh;
}
2026-02-03 15:42:32 +08:00
.home-section {
margin-top: 24rpx;
}
.home-section--first {
margin-top: 0;
}
2026-02-03 09:59:49 +08:00
</style>