ykt-team-wxapp/pages/experience-coupon/select-rights-archive.vue
2026-09-02 14:50:14 +08:00

283 lines
8.0 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 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>
<scroll-view v-else scroll-y 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>
</scroll-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 { get, set } from "@/utils/cache";
import { toast } from "@/utils/widget";
import { normalizeCorpId } from "@/utils/api-base-config";
import FullPage from "@/components/full-page.vue";
const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info";
const RIGHTS_SELECTION_CACHE_KEY = "experience-coupon-rights-selection";
const { account } = storeToRefs(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 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 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") {
const corpName = encodeURIComponent(item.corpName || "");
return `/pages/experience-coupon/my-coupons?corpId=${corp}&teamId=${team}&customerId=${customer}&name=${name}&corpName=${corpName}`;
}
if (target.value === "health") {
return `/pages/health/list?teamId=${team}&corpId=${corp}&id=${customer}&name=${name}`;
}
if (target.value === "treatment") {
const corpName = encodeURIComponent(item.corpName || "");
return `/pages/record/treatment-record?teamId=${team}&corpId=${corp}&customerId=${customer}&name=${name}&corpName=${corpName}`;
}
if (target.value === "appointment") {
const corpName = encodeURIComponent(item.corpName || "");
return `/pages/record/appointment-record?teamId=${team}&corpId=${corp}&customerId=${customer}&name=${name}&corpName=${corpName}`;
}
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 currentTeam = get(HOME_CURRENT_TEAM_CACHE_KEY) || {};
const selectedCorpId = normalizeCorpId(currentTeam.corpId || currentCorpId.value);
if (!selectedCorpId) {
options.value = [];
return;
}
const [corpRes, customerRes] = await Promise.all([
api("getCorpInfo", { corpId: selectedCorpId }, false),
api("getCorpMiniAppCustomers", { miniAppId, corpId: selectedCorpId }, false),
]);
const corp = Array.isArray(corpRes?.data) ? corpRes.data[0] : null;
const archiveCorpName = corp?.corp_name || corp?.corpName || "-";
const customers = customerRes?.success && Array.isArray(customerRes.data) ? customerRes.data : [];
const list = customers
.map((customer) => ({
key: `${selectedCorpId}_${customer._id}`,
corpId: selectedCorpId,
teamId: currentTeam.teamId || currentTeamId.value || "",
customerId: customer._id || "",
name: customer.name || "",
relationship: customer.relationship || "",
metaText: buildMetaText(customer),
idCardText: maskIdCard(customer.idCard),
corpName: archiveCorpName,
}))
.filter((item) => 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 {
height: 100vh;
padding: 24rpx;
box-sizing: border-box;
background: #f5f6fa;
}
.archive-list {
height: 100%;
}
.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>