ykt-team-wxapp/pages/experience-coupon/select-rights-archive.vue

293 lines
8.1 KiB
Vue
Raw Permalink Normal View History

2026-07-29 11:25:29 +08:00
<template>
<full-page pageClass="rights-selector-page" :customScroll="true">
<view class="page-body">
<view v-if="loading" class="empty">加载中...</view>
<view v-else-if="!options.length" class="empty">暂无可用档案</view>
<view v-else class="archive-list">
<view
v-for="item in options"
:key="item.key"
class="archive-card"
:class="{ active: item.isCurrent }"
@click="selectArchive(item)"
>
<view class="archive-head">
<view class="archive-name-row">
<view class="archive-name">{{ item.name || "未命名" }}</view>
<view v-if="item.relationship" class="archive-tag">{{ item.relationship }}</view>
</view>
<view v-if="item.isCurrent" class="archive-current">当前</view>
</view>
<view class="archive-meta">{{ item.metaText }}</view>
<view class="archive-id">证件号{{ item.idCardText }}</view>
<view class="archive-corp">{{ item.corpName }}</view>
</view>
</view>
</view>
</full-page>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { storeToRefs } from "pinia";
import useAccount from "@/store/account";
import api from "@/utils/api";
import { set } from "@/utils/cache";
import { toast } from "@/utils/widget";
import { normalizeCorpId } from "@/utils/api-base-config";
import FullPage from "@/components/full-page.vue";
const RIGHTS_SELECTION_CACHE_KEY = "experience-coupon-rights-selection";
const { account } = storeToRefs(useAccount());
const { getTeams } = useAccount();
const loading = ref(false);
const options = ref([]);
const currentCorpId = ref("");
const currentTeamId = ref("");
const currentCustomerId = ref("");
const mode = ref("back");
const target = ref("");
function pickCorpName(team = {}) {
return team.licenseHospitalName || team.leaderCorp || team.corpName || "-";
}
function maskMobile(mobile = "") {
const value = String(mobile || "").trim();
if (!value) return "";
if (/^\d{11}$/.test(value)) {
return value.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
}
return value;
}
function maskIdCard(idCard = "") {
const value = String(idCard || "").trim();
if (!value) return "--";
if (value.length <= 4) return value;
return `${"*".repeat(Math.max(value.length - 4, 2))}${value.slice(-4)}`;
}
function buildMetaText(customer = {}) {
const parts = [];
if (customer.age) parts.push(`${customer.age}`);
if (customer.mobile) parts.push(maskMobile(customer.mobile));
return parts.length ? parts.join("") : "暂无档案信息";
}
function dedupeByCorp(list = []) {
const map = new Map();
list.forEach((team) => {
const corpId = normalizeCorpId(team.corpId);
if (!corpId || map.has(corpId)) return;
map.set(corpId, { ...team, corpId });
});
return Array.from(map.values());
}
function buildTargetUrl(item) {
const corp = encodeURIComponent(item.corpId || "");
const team = encodeURIComponent(item.teamId || "");
const customer = encodeURIComponent(item.customerId || "");
const name = encodeURIComponent(item.name || "");
if (target.value === "coupons") {
return `/pages/experience-coupon/my-coupons?corpId=${corp}&teamId=${team}&customerId=${customer}`;
}
if (target.value === "health") {
return `/pages/health/list?teamId=${team}&corpId=${corp}&id=${customer}&name=${name}`;
}
2026-07-29 17:30:30 +08:00
if (target.value === "treatment") {
2026-07-30 16:37:11 +08:00
const corpName = encodeURIComponent(item.corpName || "");
return `/pages/record/treatment-record?teamId=${team}&corpId=${corp}&customerId=${customer}&name=${name}&corpName=${corpName}`;
2026-07-29 17:30:30 +08:00
}
if (target.value === "appointment") {
const corpName = encodeURIComponent(item.corpName || "");
return `/pages/record/appointment-record?teamId=${team}&corpId=${corp}&customerId=${customer}&name=${name}&corpName=${corpName}`;
}
2026-07-29 11:25:29 +08:00
return `/pages/experience-coupon/my-rights?corpId=${corp}&teamId=${team}&customerId=${customer}&name=${name}`;
}
async function loadArchives() {
const miniAppId = account.value?.openid || uni.getStorageSync("openid") || "";
if (!miniAppId) {
options.value = [];
return;
}
loading.value = true;
try {
const teams = (await getTeams()) || [];
const corpTeams = dedupeByCorp(teams);
const responses = await Promise.all(
corpTeams.map(async (team) => {
try {
const res = await api("getMiniAppCustomers", { miniAppId, corpId: team.corpId }, false);
const customers = res?.success && Array.isArray(res.data) ? res.data : [];
return customers.map((customer) => ({ team, customer }));
} catch (e) {
console.warn(e);
return [];
}
})
);
const list = responses
.flat()
.map(({ team, customer }) => ({
key: `${team.corpId}_${customer._id}`,
corpId: team.corpId,
teamId: team.teamId || "",
customerId: customer._id || "",
name: customer.name || "",
relationship: customer.relationship || "",
metaText: buildMetaText(customer),
idCardText: maskIdCard(customer.idCard),
corpName: pickCorpName(team),
}))
.filter((item) => item.corpId && item.customerId)
.sort((a, b) => {
const aScore =
(a.corpId === currentCorpId.value ? 4 : 0) +
(a.teamId === currentTeamId.value ? 2 : 0) +
(a.customerId === currentCustomerId.value ? 8 : 0) +
(a.relationship === "本人" ? 1 : 0);
const bScore =
(b.corpId === currentCorpId.value ? 4 : 0) +
(b.teamId === currentTeamId.value ? 2 : 0) +
(b.customerId === currentCustomerId.value ? 8 : 0) +
(b.relationship === "本人" ? 1 : 0);
return bScore - aScore;
})
.map((item) => ({
...item,
isCurrent:
item.corpId === currentCorpId.value &&
item.customerId === currentCustomerId.value,
}));
options.value = list;
} finally {
loading.value = false;
}
}
function selectArchive(item) {
if (!item) return;
if (mode.value === "target") {
uni.navigateTo({
url: buildTargetUrl(item),
});
return;
}
set(RIGHTS_SELECTION_CACHE_KEY, {
corpId: item.corpId,
teamId: item.teamId,
customerId: item.customerId,
name: item.name,
corpName: item.corpName,
});
uni.navigateBack();
}
onLoad(async (optionsData = {}) => {
uni.setNavigationBarTitle({ title: "选择档案" });
currentCorpId.value = normalizeCorpId(optionsData.corpId || "");
currentTeamId.value = optionsData.teamId || "";
currentCustomerId.value = optionsData.customerId || optionsData.memberId || "";
mode.value = optionsData.mode === "target" ? "target" : "back";
target.value = optionsData.target || "rights";
await loadArchives();
if (!options.value.length) {
toast("暂无可用档案");
}
});
</script>
<style scoped>
.page-body {
min-height: 100%;
padding: 24rpx;
box-sizing: border-box;
background: #f5f6fa;
}
.archive-card {
background: #fff;
border-radius: 18rpx;
padding: 24rpx;
margin-bottom: 20rpx;
border: 2rpx solid transparent;
box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.06);
}
.archive-card.active {
border-color: #065bd6;
}
.archive-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16rpx;
margin-bottom: 16rpx;
}
.archive-name-row {
min-width: 0;
display: flex;
align-items: center;
gap: 12rpx;
flex-wrap: wrap;
}
.archive-name {
font-size: 34rpx;
font-weight: 600;
color: #1f2329;
}
.archive-tag,
.archive-current {
padding: 4rpx 12rpx;
border-radius: 999rpx;
font-size: 20rpx;
}
.archive-tag {
color: #0f766e;
background: rgba(15, 118, 110, 0.12);
}
.archive-current {
color: #065bd6;
background: rgba(6, 91, 214, 0.1);
}
.archive-meta,
.archive-id {
font-size: 28rpx;
color: #4b5563;
line-height: 1.6;
}
.archive-corp {
margin-top: 16rpx;
padding-top: 16rpx;
border-top: 1px solid #eef2f6;
font-size: 28rpx;
color: #065bd6;
font-weight: 500;
}
.empty {
padding: 120rpx 0;
text-align: center;
color: #999;
font-size: 28rpx;
}
</style>