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>
|
2026-08-13 19:01:37 +08:00
|
|
|
|
<scroll-view v-else scroll-y class="archive-list">
|
2026-07-29 11:25:29 +08:00
|
|
|
|
<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>
|
2026-08-13 19:01:37 +08:00
|
|
|
|
</scroll-view>
|
2026-07-29 11:25:29 +08:00
|
|
|
|
</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";
|
2026-08-12 11:34:24 +08:00
|
|
|
|
import { get, set } from "@/utils/cache";
|
2026-07-29 11:25:29 +08:00
|
|
|
|
import { toast } from "@/utils/widget";
|
|
|
|
|
|
import { normalizeCorpId } from "@/utils/api-base-config";
|
|
|
|
|
|
import FullPage from "@/components/full-page.vue";
|
|
|
|
|
|
|
2026-08-12 11:34:24 +08:00
|
|
|
|
const HOME_CURRENT_TEAM_CACHE_KEY = "home-current-team-info";
|
2026-07-29 11:25:29 +08:00
|
|
|
|
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") {
|
|
|
|
|
|
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 {
|
2026-08-12 11:34:24 +08:00
|
|
|
|
const currentTeam = get(HOME_CURRENT_TEAM_CACHE_KEY) || {};
|
|
|
|
|
|
const selectedCorpId = normalizeCorpId(currentTeam.corpId || currentCorpId.value);
|
2026-07-29 11:25:29 +08:00
|
|
|
|
|
2026-08-12 18:09:41 +08:00
|
|
|
|
if (!selectedCorpId) {
|
2026-08-12 11:34:24 +08:00
|
|
|
|
options.value = [];
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const [corpRes, customerRes] = await Promise.all([
|
|
|
|
|
|
api("getCorpInfo", { corpId: selectedCorpId }, false),
|
2026-08-12 18:09:41 +08:00
|
|
|
|
api("getCorpMiniAppCustomers", { miniAppId, corpId: selectedCorpId }, false),
|
2026-08-12 11:34:24 +08:00
|
|
|
|
]);
|
|
|
|
|
|
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,
|
2026-08-12 18:09:41 +08:00
|
|
|
|
teamId: currentTeam.teamId || currentTeamId.value || "",
|
2026-07-29 11:25:29 +08:00
|
|
|
|
customerId: customer._id || "",
|
|
|
|
|
|
name: customer.name || "",
|
|
|
|
|
|
relationship: customer.relationship || "",
|
|
|
|
|
|
metaText: buildMetaText(customer),
|
|
|
|
|
|
idCardText: maskIdCard(customer.idCard),
|
2026-08-12 11:34:24 +08:00
|
|
|
|
corpName: archiveCorpName,
|
2026-07-29 11:25:29 +08:00
|
|
|
|
}))
|
2026-08-12 11:34:24 +08:00
|
|
|
|
.filter((item) => item.customerId)
|
2026-07-29 11:25:29 +08:00
|
|
|
|
.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 {
|
2026-08-13 19:01:37 +08:00
|
|
|
|
height: 100vh;
|
2026-07-29 11:25:29 +08:00
|
|
|
|
padding: 24rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
background: #f5f6fa;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-13 19:01:37 +08:00
|
|
|
|
.archive-list {
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-29 11:25:29 +08:00
|
|
|
|
.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>
|