diff --git a/.env b/.env
index 935301e..90d6b23 100644
--- a/.env
+++ b/.env
@@ -33,18 +33,18 @@ VITE_OAUTH2_SOCIAL_CLIENT='social:social'
# 是否开启websocket 消息接受,
VITE_WEBSOCKET_ENABLE = true
# --------------------------- start 开发环境 start ----------------------------------
-VITE_APP_DEV_SERVICE = https://www.zianxin.com/api
+# VITE_APP_DEV_SERVICE = https://www.zianxin.com/api
# VITE_APP_DEV_SERVICE = https://dzc-test-1.fy.takin.cc
# VITE_APP_DEV_SERVICE = http://127.0.0.1:9999
#VITE_APP_DEV_SERVICE = https://www.zianxin.com/api
-# VITE_APP_DEV_SERVICE = https://dzc-test-1.fy.takin.cc
+VITE_APP_DEV_SERVICE = https://dzc-test-1.fy.takin.cc
#VITE_APP_DEV_SERVICE = http://127.0.0.1:9999
-VITE_IMAGE_DEV_PATH = https://www.zianxin.com/api
+# VITE_IMAGE_DEV_PATH = https://www.zianxin.com/api
# VITE_IMAGE_DEV_PATH = https://dzc-test-1.fy.takin.cc
# VITE_IMAGE_DEV_PATH = http://127.0.0.1:9999
#VITE_IMAGE_DEV_PATH = https://www.zianxin.com/api
-# VITE_IMAGE_DEV_PATH = https://dzc-test-1.fy.takin.cc
+VITE_IMAGE_DEV_PATH = https://dzc-test-1.fy.takin.cc
# VITE_IMAGE_DEV_PATH = http://127.0.0.1:9999
# ----------------------------- end 开发环境 end ------------------------------------
diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json
index 7a65f03..df6b57a 100644
--- a/.hbuilderx/launch.json
+++ b/.hbuilderx/launch.json
@@ -26,7 +26,7 @@
"type" : "uniCloud"
},
{
- "customPlaygroundType" : "device",
+ "customPlaygroundType" : "local",
"openVueDevtools" : true,
"playground" : "custom",
"type" : "uni-app:app-ios"
diff --git a/src/manifest.json b/src/manifest.json
index db9c0e6..444fadd 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -2,8 +2,8 @@
"name" : "资安信",
"appid" : "__UNI__1BFE88F",
"description" : "资安信后勤管理系统",
- "versionName" : "1.5.12",
- "versionCode" : 1512,
+ "versionName" : "1.5.13",
+ "versionCode" : 1513,
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
diff --git a/src/pages.json b/src/pages.json
index c3aba2b..04c5908 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -357,13 +357,6 @@
{
"root": "pages/human-face",
"pages": [
- {
- "path": "list",
- "style": {
- "navigationBarTitleText": "",
- "disableScroll": true
- }
- },
{
"path": "guardian-ward-apply",
"style": {
@@ -668,4 +661,4 @@
}
]
}
-}
\ No newline at end of file
+}
diff --git a/src/pages/human-face/guardian-ward-apply.vue b/src/pages/human-face/guardian-ward-apply.vue
index b9edeb5..39965c2 100644
--- a/src/pages/human-face/guardian-ward-apply.vue
+++ b/src/pages/human-face/guardian-ward-apply.vue
@@ -9,7 +9,7 @@
{{ wardName }}
- 被监护人人脸信息
+ {{ faceIdentityDescription }}
{{ isDetailMode ? detailStatus.label : "需审核" }}
@@ -121,6 +121,8 @@ const spuUploadActionUrl = getFileUploadActionUrl()
const wardUserId = ref("")
const wardName = ref("被监护人")
+/** 当前目标是否为登录用户本人,用于复用同一套上传、审核和撤回流程。 */
+const currentUser = ref(false)
const uploadFiles = ref([])
const submitting = ref(false)
const cancelling = ref(false)
@@ -154,7 +156,13 @@ const faceGuides = [
const uploadHeader = computed(() => hooks.useDefaultHeader())
const isDetailMode = computed(() => pageMode.value === "detail")
-const pageTitle = computed(() => (isDetailMode.value ? "人脸审核详情" : "上传被监护人人脸"))
+/** 本人与被监护人共用页面时,标题应准确反映当前办理对象。 */
+const pageTitle = computed(() => {
+ if (isDetailMode.value) return "人脸审核详情"
+ return currentUser.value ? "上传人脸" : "上传被监护人人脸"
+})
+/** 顶部身份说明根据目标用户切换,避免本人页面仍显示被监护人文案。 */
+const faceIdentityDescription = computed(() => (currentUser.value ? "本人人脸信息" : "被监护人人脸信息"))
const detailFaceUrl = computed(() => filePath(faceDetail.value?.faceImg))
const canCancelFace = computed(() => String(faceDetail.value?.processStatus || "") === taskCheckStatusCodeEnum.PADDING)
const canReapplyFace = computed(() => String(faceDetail.value?.processStatus || "") === taskCheckStatusCodeEnum.REJECT)
@@ -194,6 +202,7 @@ const toRecords = () => {
router.jump("/pages/human-face/guardian-ward-records", {
wardUserId: wardUserId.value,
wardName: encodeURIComponent(wardName.value),
+ currentUser: currentUser.value ? "1" : "0",
})
}
@@ -230,7 +239,7 @@ const confirmSingleFace = () => singleFaceConfirmRef.value?.open() ?? Promise.re
const formatTime = (value?: string) => (value ? dayjs(value).format("YYYY-MM-DD HH:mm") : "—")
/**
- * 查询被监护人的人脸审核详情,并更新详情模式页面。
+ * 查询本人或被监护人的人脸审核详情,并更新详情模式页面。
*/
const loadFaceDetail = async () => {
if (!faceId.value) return
@@ -240,7 +249,7 @@ const loadFaceDetail = async () => {
wardUserId.value = String(faceDetail.value.userId || wardUserId.value)
wardName.value = faceDetail.value.username || wardName.value
} catch (error: any) {
- console.error("查询被监护人人脸审核详情失败", error)
+ console.error(currentUser.value ? "查询本人人脸审核详情失败" : "查询被监护人人脸审核详情失败", error)
uni.showToast({ title: error?.message || error?.msg || "查询审核详情失败", icon: "none" })
}
}
@@ -302,7 +311,7 @@ const reapplyRejectedFace = () => {
}
/**
- * 提交被监护人的人脸图片并进入审核流程。
+ * 提交本人或被监护人的人脸图片并进入审核流程。
*/
const submitFaces = async () => {
if (submitting.value) return
@@ -329,6 +338,7 @@ const submitFaces = async () => {
{
wardUserId: wardUserId.value,
wardName: encodeURIComponent(wardName.value),
+ currentUser: currentUser.value ? "1" : "0",
},
2,
),
@@ -346,13 +356,14 @@ onLoad((options?: Record) => {
pageMode.value = String(options?.mode || "apply")
faceId.value = String(options?.id || "")
wardUserId.value = String(options?.wardUserId || "")
- wardName.value = decodeURIComponent(String(options?.wardName || "被监护人"))
+ currentUser.value = String(options?.currentUser || "") === "1"
+ wardName.value = decodeURIComponent(String(options?.wardName || (currentUser.value ? "本人" : "被监护人")))
if (isDetailMode.value && faceId.value) {
loadFaceDetail()
return
}
if (!wardUserId.value || (isDetailMode.value && !faceId.value)) {
- uni.showToast({ title: "缺少被监护人信息", icon: "none" })
+ uni.showToast({ title: "缺少目标用户信息", icon: "none" })
setTimeout(() => router.back(), 800)
}
})
diff --git a/src/pages/human-face/guardian-ward-records.vue b/src/pages/human-face/guardian-ward-records.vue
index f066761..6600a59 100644
--- a/src/pages/human-face/guardian-ward-records.vue
+++ b/src/pages/human-face/guardian-ward-records.vue
@@ -3,7 +3,8 @@
-
+
@@ -15,7 +16,7 @@
- {{ record.username || "被监护人" }}
+ {{ record.username || identityName }}
{{ statusMeta(record.processStatus).label }}
@@ -41,14 +42,14 @@
- 为{{ wardName }}上传人脸
+ {{ uploadButtonText }}
-
-
-
-
-
-
-
- {{ v.username }}·{{ v.deptName }}
-
- 修改
-
- 删除
-
-
-
-
-
- 添加
-
-
-
-
-
diff --git a/src/pages/order/guardian-ward-menu.vue b/src/pages/order/guardian-ward-menu.vue
index 21193bc..cbfbe59 100644
--- a/src/pages/order/guardian-ward-menu.vue
+++ b/src/pages/order/guardian-ward-menu.vue
@@ -1,5 +1,5 @@
-
+
@@ -11,7 +11,7 @@
@@ -56,7 +56,7 @@
菜谱加载失败
- 请检查网络或监护关系后重新加载
+ {{ failureDescription }}
重新加载
@@ -68,7 +68,7 @@
暂无预约菜谱
- 该被监护人目前没有今天及以后的未核销预约
+ {{ emptyDescription }}
刷新看看
@@ -247,18 +247,22 @@ type MealMeta = {
/** 页面路由参数。 */
type WardMenuRouteOptions = {
- /** 被监护人用户 ID,服务端据此执行监护关系权限校验。 */
+ /** 目标用户 ID,服务端仅允许查询本人或当前有效被监护人。 */
wardUserId?: string
- /** 经过 URI 编码的被监护人展示名称。 */
+ /** 经过 URI 编码的目标用户展示名称。 */
wardName?: string
+ /** 是否查询当前登录用户本人,路由协议值 1 表示本人。 */
+ currentUser?: string
}
/** 页面响应式状态,离开页面后无需跨页面持久化。 */
type WardMenuPageState = {
- /** 当前被监护人用户 ID,长整型始终按字符串保存。 */
+ /** 当前目标用户 ID,长整型始终按字符串保存。 */
wardUserId: string
- /** 当前被监护人展示名称。 */
+ /** 当前目标用户展示名称。 */
wardName: string
+ /** 当前查询目标是否为登录用户本人。 */
+ currentUser: boolean
/** 已查询到的未来未核销预约订单。 */
orders: WardMenuOrder[]
/** 菜谱请求是否正在执行,用于阻止重复提交。 */
@@ -275,6 +279,7 @@ type WardMenuPageState = {
const state = reactive({
wardUserId: "",
wardName: "被监护人",
+ currentUser: false,
orders: [],
loading: false,
failed: false,
@@ -282,6 +287,17 @@ const state = reactive({
requestSequence: 0,
})
+/** 页面标题根据查询目标区分本人和被监护人。 */
+const pageTitle = computed(() => (state.currentUser ? "我的菜谱" : "被监护人菜谱"))
+/** 刷新按钮的无障碍说明与当前页面身份保持一致。 */
+const refreshAriaLabel = computed(() => (state.currentUser ? "刷新我的菜谱" : "刷新被监护人菜谱"))
+/** 菜谱请求失败时,本人无需提示检查监护关系。 */
+const failureDescription = computed(() => (state.currentUser ? "请检查网络后重新加载" : "请检查网络或监护关系后重新加载"))
+/** 空菜谱提示根据当前查询目标展示。 */
+const emptyDescription = computed(() =>
+ state.currentUser ? "您目前没有今天及以后的未核销预约" : "该被监护人目前没有今天及以后的未核销预约",
+)
+
/** 把接口可能返回的空值或非法数字收敛为非负数。 */
const normalizedNumber = (value: unknown) => {
const parsedValue = Number(value)
@@ -423,7 +439,7 @@ const productKey = (product: WardMenuProduct, index: number) =>
product.id || product.productId || `${product.productName || "product"}-${index}`
/**
- * 查询被监护人未来未核销预约;后端会再次校验当前登录人和目标用户的有效监护关系。
+ * 查询本人或被监护人未来未核销预约;后端会再次校验目标是否为本人或当前有效被监护人。
*/
const loadWardMenus = async () => {
if (state.loading) return
@@ -443,7 +459,7 @@ const loadWardMenus = async () => {
state.loaded = true
} catch (error: any) {
if (currentSequence !== state.requestSequence) return
- console.error("查询被监护人预约菜谱失败", error)
+ console.error(state.currentUser ? "查询本人预约菜谱失败" : "查询被监护人预约菜谱失败", error)
state.orders = []
state.failed = true
state.loaded = true
@@ -453,10 +469,12 @@ const loadWardMenus = async () => {
}
}
-/** 初始化路由参数并加载目标被监护人的预约菜谱。 */
+/** 初始化路由参数并加载本人或目标被监护人的预约菜谱。 */
onLoad((options: WardMenuRouteOptions) => {
state.wardUserId = String(options?.wardUserId || "")
- state.wardName = decodeRouteText(options?.wardName)
+ state.currentUser = options?.currentUser === "1"
+ state.wardName = state.currentUser && !options?.wardName ? "本人" : decodeRouteText(options?.wardName)
+ uni.setNavigationBarTitle({ title: pageTitle.value })
loadWardMenus()
})
diff --git a/src/pages/root/login.vue b/src/pages/root/login.vue
index a003867..e754392 100644
--- a/src/pages/root/login.vue
+++ b/src/pages/root/login.vue
@@ -410,37 +410,31 @@ const doAppleLogin = async () => {
没有账号?注册
-
-
-
- 其他登录方式
-
-
-
-
-
- 微信登录
+
+
+
+
+ 其他登录方式
+
-
-
- 通过 Apple 登录
+
+
+
+
+
+
+
+
-
-
+
{{ socialBindLabel }}已授权,请登录已有账号完成绑定。绑定后可直接使用{{ socialBindLabel }}登录。
@@ -464,41 +458,44 @@ const doAppleLogin = async () => {
}
.login-divider-line {
- flex: 1;
+ flex: 0 0 44rpx;
height: 1rpx;
- background: #e5e7eb;
+ background: #cfd4da;
}
.social-login-row {
- flex-wrap: wrap;
- gap: 24rpx;
+ gap: 30rpx;
}
.social-login-btn {
display: flex;
align-items: center;
justify-content: center;
- padding: 18rpx 40rpx;
- border-radius: 40rpx;
- border: 1rpx solid #e5e7eb;
+ flex: 0 0 80rpx;
+ width: 80rpx;
+ height: 80rpx;
+ border: 1rpx solid #e1e5ea;
+ border-radius: 50%;
background: #fff;
+ box-shadow: 0 4rpx 12rpx rgba(31, 45, 61, 0.05);
+ transition: opacity 0.15s ease, background-color 0.15s ease;
}
-.apple-login-btn {
- background: #000;
- border-color: #000;
+.social-login-btn--pressed {
+ background: #f4f6f8;
+ opacity: 0.74;
}
.apple-logo {
- font-size: 36rpx;
- color: #fff;
+ font-size: 48rpx;
+ color: #111;
line-height: 1;
}
.social-login-icon {
- width: 48rpx;
- height: 48rpx;
- border-radius: 8rpx;
+ width: 52rpx;
+ height: 52rpx;
+ border-radius: 50%;
}
.wx-bind-body {
diff --git a/src/pages/tabbar/canteen.vue b/src/pages/tabbar/canteen.vue
index 350c0c7..d1d7270 100644
--- a/src/pages/tabbar/canteen.vue
+++ b/src/pages/tabbar/canteen.vue
@@ -92,7 +92,7 @@ const inputClear = () => {
-
+
diff --git a/src/pages/user/relation/components/guardian-ward-action-drawer.vue b/src/pages/user/relation/components/guardian-ward-action-drawer.vue
index 56df37f..4b8bc85 100644
--- a/src/pages/user/relation/components/guardian-ward-action-drawer.vue
+++ b/src/pages/user/relation/components/guardian-ward-action-drawer.vue
@@ -3,7 +3,7 @@
v-model:show="show"
position="right"
size="88%"
- title="被监护人操作"
+ :title="drawerTitle"
:show-close="true"
:show-footer="false"
z-index="9000"
@@ -17,14 +17,14 @@
class="drawer-hero__image"
src="/static/illustration/guardian-action-hero.png"
mode="aspectFit"
- aria-label="被监护人人脸、饭卡与预约服务插画"
+ :aria-label="drawerImageLabel"
/>
- {{ ward.wardName || "被监护人" }}
+ {{ ward.wardName || identityName }}
{{ ward.walletTypeName || "饭卡" }}
@@ -84,7 +84,7 @@
-
+
{{ ward.disabledReason || "当前饭卡暂不可充值" }}
@@ -123,7 +123,7 @@
- 未选择被监护人
+ 未选择可办理业务的用户
@@ -138,7 +138,7 @@ import GuardianWardActionDrawerSkeleton from "./guardian-ward-action-drawer-skel
type WardAction = {
/** 操作项唯一标识,仅用于前端分发对应页面跳转。 */
- key: "menu" | "face-upload" | "face-records" | "recharge"
+ key: "menu" | "face-upload" | "face-records" | "recharge" | "wallet-manage"
/** 操作项主标题。 */
title: string
/** 操作项补充说明,禁用时同时用于解释原因。 */
@@ -160,9 +160,9 @@ type WardAction = {
const props = defineProps<{
/** 右侧操作抽屉是否显示。 */
modelValue: boolean
- /** 是否正在刷新被监护人数据;加载期间显示结构占位并阻止空态闪烁。 */
+ /** 是否正在刷新关系人数据;加载期间显示结构占位并阻止空态闪烁。 */
loading?: boolean
- /** 当前选中的被监护人饭卡与预约摘要。 */
+ /** 当前选中的本人或被监护人饭卡与预约摘要。 */
ward?: GuardianWardRechargeItem
}>()
@@ -175,6 +175,14 @@ const show = computed({
set: (value: boolean) => emit("update:modelValue", value),
})
+/** 当前抽屉是否办理登录用户本人的业务,用于切换文案、操作项和业务路由。 */
+const isCurrentUser = computed(() => Boolean(props.ward?.currentUser))
+/** 抽屉标题根据当前办理身份展示,避免把本人误称为被监护人。 */
+const drawerTitle = computed(() => (isCurrentUser.value ? "本人操作" : "被监护人操作"))
+/** 当前办理人的身份兜底名称。 */
+const identityName = computed(() => (isCurrentUser.value ? "本人" : "被监护人"))
+/** 服务插画的无障碍说明根据当前办理身份展示。 */
+const drawerImageLabel = computed(() => `${identityName.value}人脸、饭卡与预约服务插画`)
const avatarUrl = computed(() => filePath(props.ward?.wardAvatar) || "/static/icon/default-avatar.png")
const statusClass = computed(() => (props.ward?.rechargeEnabled ? "bg-#ecfdf5 color-#047857" : "bg-#fff7ed color-#c2410c"))
const faceCapacityReached = computed(() => {
@@ -204,8 +212,8 @@ const faceMetrics = computed(() => [
/**
* 操作项通过配置统一渲染,避免各类业务入口复制结构和交互状态。
*/
-const actions = computed(() => [
- {
+const actions = computed(() => {
+ const menuAction: WardAction = {
key: "menu",
title: "查看菜谱",
description:
@@ -218,19 +226,21 @@ const actions = computed(() => [
background: "#fffaf5",
borderColor: "#fed7aa",
disabled: false,
- },
- {
+ }
+ const faceUploadAction: WardAction = {
key: "face-upload",
title: "上传人脸",
- description: faceCapacityReached.value ? "审核中和可用人脸合计已达 3 张" : "拍摄并提交被监护人的人脸照片审核",
+ description: faceCapacityReached.value
+ ? "审核中和可用人脸合计已达 3 张"
+ : `拍摄并提交${isCurrentUser.value ? "本人" : "被监护人"}的人脸照片审核`,
icon: "camera-line",
iconBg: "#eef8ff",
iconColor: "#0094ff",
background: "#f8fcff",
borderColor: "#dcefff",
disabled: faceCapacityReached.value,
- },
- {
+ }
+ const faceRecordsAction: WardAction = {
key: "face-records",
title: "审核记录",
description: "查看人脸审核进度、照片和拒绝原因",
@@ -240,19 +250,44 @@ const actions = computed(() => [
background: "#fbfaff",
borderColor: "#e9e2ff",
disabled: false,
- },
- {
- key: "recharge",
- title: "饭卡充值",
- description: props.ward?.rechargeEnabled ? "使用目标食堂支持的支付方式为饭卡充值" : props.ward?.disabledReason || "当前饭卡暂不可充值",
- icon: "wallet-line",
- iconBg: "#ecfdf5",
- iconColor: "#059669",
- background: "#f5fdf9",
- borderColor: "#ccefe0",
- disabled: !props.ward?.rechargeEnabled,
- },
-])
+ }
+ if (isCurrentUser.value) {
+ return [
+ menuAction,
+ faceUploadAction,
+ faceRecordsAction,
+ {
+ key: "wallet-manage",
+ title: "钱包管理",
+ description: "查看本人饭卡,并办理充值、冻结等业务",
+ icon: "wallet-line",
+ iconBg: "#ecfdf5",
+ iconColor: "#059669",
+ background: "#f5fdf9",
+ borderColor: "#ccefe0",
+ disabled: false,
+ },
+ ]
+ }
+ return [
+ menuAction,
+ faceUploadAction,
+ faceRecordsAction,
+ {
+ key: "recharge",
+ title: "饭卡充值",
+ description: props.ward?.rechargeEnabled
+ ? "使用目标食堂支持的支付方式为饭卡充值"
+ : props.ward?.disabledReason || "当前饭卡暂不可充值",
+ icon: "wallet-line",
+ iconBg: "#ecfdf5",
+ iconColor: "#059669",
+ background: "#f5fdf9",
+ borderColor: "#ccefe0",
+ disabled: !props.ward?.rechargeEnabled,
+ },
+ ]
+})
/**
* 所有业务跳转先关闭右侧抽屉,避免 App 页面切换时残留遮罩。
@@ -260,19 +295,31 @@ const actions = computed(() => [
const handleAction = (action: WardAction) => {
if (!props.ward || action.disabled) return
const wardUserId = String(props.ward.wardUserId || "")
- const wardName = encodeURIComponent(props.ward.wardName || "被监护人")
+ const wardName = encodeURIComponent(props.ward.wardName || identityName.value)
show.value = false
setTimeout(() => {
if (action.key === "menu") {
- router.jump("/pages/order/guardian-ward-menu", { wardUserId, wardName })
+ router.jump("/pages/order/guardian-ward-menu", { wardUserId, wardName, currentUser: isCurrentUser.value ? "1" : "0" })
+ return
+ }
+ if (action.key === "wallet-manage") {
+ router.jump("/pages/wallet/list")
return
}
if (action.key === "face-upload") {
- router.jump("/pages/human-face/guardian-ward-apply", { wardUserId, wardName })
+ router.jump("/pages/human-face/guardian-ward-apply", {
+ wardUserId,
+ wardName,
+ currentUser: isCurrentUser.value ? "1" : "0",
+ })
return
}
if (action.key === "face-records") {
- router.jump("/pages/human-face/guardian-ward-records", { wardUserId, wardName })
+ router.jump("/pages/human-face/guardian-ward-records", {
+ wardUserId,
+ wardName,
+ currentUser: isCurrentUser.value ? "1" : "0",
+ })
return
}
router.jump("/pages/wallet/recharge", { wardUserId })
diff --git a/src/pages/user/relation/list.vue b/src/pages/user/relation/list.vue
index 38bac12..f8ba7f3 100644
--- a/src/pages/user/relation/list.vue
+++ b/src/pages/user/relation/list.vue
@@ -1,56 +1,43 @@
-
-
+
+
- 被监护人服务台
-
+ 关系人服务台
+
{{ totalCount }} 人
-
+
饭卡、人脸与预约状态集中查看
-
+
人脸情况
-
+
{{ item.label }}
- {{ item.value }}
-
+ {{ item.value }}
+
-
+
预约订单
@@ -60,17 +47,14 @@
{{ pendingReservationTotal }}
-
+
-
+
@@ -78,20 +62,22 @@
-
+ @tap="openActions(ward)">
- {{ ward.wardName || "被监护人" }}
-
+ {{ ward.wardName || "关系人" }}
+
+ {{ relationIdentityText(ward) }}
+
+
{{ ward.cardStatusName || "状态异常" }}
@@ -103,10 +89,12 @@
-
+
-
+
@@ -114,11 +102,8 @@
人脸情况
-
+
{{ metric.label }}
{{ metric.value }}
@@ -141,29 +126,31 @@
-
+
饭卡余额
- ¥{{ hooks.useMoney(ward.balance || 0) }}
+ ¥{{ hooks.useMoney(ward.balance || 0) }}
+
- 可充值
+ 可办理
+ 仅查看
+ 可充值
{{ ward.disabledReason || "暂不可充值" }}
-
- 暂无有效被监护人
- 这里只展示当前登录用户直接且有效的监护关系
+ 暂无关系人数据
+ 本人信息或关系数据暂未返回,请稍后重试
+ @tap="openRelationTree">
查看关系图谱
@@ -211,6 +198,25 @@ type HeroFaceSummary = {
const avatarUrl = (ward: GuardianWardRechargeItem) => filePath(ward.wardAvatar) || "/static/icon/default-avatar.png"
const statusClass = (ward: GuardianWardRechargeItem) => (ward.rechargeEnabled ? "bg-#ecfdf5 color-#047857" : "bg-#fff7ed color-#c2410c")
+
+/**
+ * 返回列表项相对当前登录用户的身份文案,避免把所有关系人都误称为被监护人。
+ */
+const relationIdentityText = (ward: GuardianWardRechargeItem) => {
+ if (ward.currentUser) return "本人"
+ if (ward.guardianWard) return "被监护人"
+ return "关系人"
+}
+
+/**
+ * 不同关系身份使用稳定的轻量标签,业务权限仍以后端返回的 guardianWard 标记为准。
+ */
+const relationIdentityClass = (ward: GuardianWardRechargeItem) => {
+ if (ward.currentUser) return "bg-#e8f5ff color-#007ad6"
+ if (ward.guardianWard) return "bg-#ecfdf5 color-#047857"
+ return "bg-#f1f5f9 color-#475569"
+}
+
const sumMetric = (key: "availableFaceCount" | "pendingFaceCount" | "pendingReservationCount") => {
if (!queryCompleted.value) return "0"
const values = wardCache.value.map((item) => item[key])
@@ -248,17 +254,16 @@ const faceMetrics = (ward: GuardianWardRechargeItem): FaceMetric[] => [
]
/**
- * 接口当前返回全部有效被监护人,页面按 z-paging 的页码切片回填,统一复用项目列表交互。
+ * 接口返回本人及同一完整关系图谱中的全部关系人,页面按 z-paging 的页码切片回填,统一复用项目列表交互。
*/
const queryWards = async (page: number, pageSize: number) => {
const isFirstPage = page === 1
try {
if (isFirstPage) {
queryCompleted.value = false
- const response: any = await walletApi.guardianWardList()
- if (response?.code !== 0) throw new Error(response?.msg || "查询被监护人饭卡失败")
+ const response: any = await walletApi.relatedUserList()
+ if (response?.code !== 0) throw new Error(response?.msg || "查询本人及关系人失败")
wardCache.value = response?.data || []
- console.log("wardCache:", wardCache.value)
totalCount.value = wardCache.value.length
if (selectedWard.value) {
@@ -268,7 +273,7 @@ const queryWards = async (page: number, pageSize: number) => {
const start = (page - 1) * pageSize
pageRef.value?.complete(wardCache.value.slice(start, start + pageSize))
} catch (error) {
- console.error("查询被监护人饭卡列表失败", error)
+ console.error("查询本人及关系人列表失败", error)
if (isFirstPage) {
wardCache.value = []
totalCount.value = 0
@@ -279,7 +284,14 @@ const queryWards = async (page: number, pageSize: number) => {
}
}
+/**
+ * 本人和有效被监护人可打开业务抽屉,其他关系人仅展示摘要,不能借列表入口发起代办业务。
+ */
const openActions = (ward: GuardianWardRechargeItem) => {
+ if (!ward.currentUser && !ward.guardianWard) {
+ uni.showToast({ title: "当前关系人仅支持查看", icon: "none" })
+ return
+ }
selectedWard.value = ward
drawerVisible.value = true
}
diff --git a/src/sheep/api/face.ts b/src/sheep/api/face.ts
index cdeb06e..cf3894e 100644
--- a/src/sheep/api/face.ts
+++ b/src/sheep/api/face.ts
@@ -19,7 +19,7 @@ export default {
method: "POST",
data,
}),
- /** 监护人代被监护人提交一至两张人脸照片。 */
+ /** 为当前登录用户本人或其有效被监护人提交一至两张人脸照片。 */
createGuardianWard: (data: { wardUserId: string; faceImgs: string[] }) =>
request({
url: `/admin/user-face/app/guardian-ward`,
@@ -32,21 +32,21 @@ export default {
url: `/admin/user-face/app/guardian-ward/options`,
method: "GET",
}),
- /** 查询当前监护人名下全部或指定被监护人的人脸审核记录。 */
+ /** 查询当前登录用户本人或其有效被监护人的人脸审核记录。 */
guardianWardPage: (params: { wardUserId?: string; current: number; size: number; processStatus?: string }) =>
request({
url: `/admin/user-face/app/guardian-ward/page`,
method: "GET",
params,
}),
- /** 查询当前监护人可访问的被监护人人脸审核详情。 */
+ /** 查询当前登录用户本人或其有效被监护人的人脸审核详情。 */
guardianWardDetail: (params: { id: string }) =>
request({
url: `/admin/user-face/app/guardian-ward/detail`,
method: "GET",
params,
}),
- /** 撤回并删除审核中的被监护人人脸记录,返回原图供重新编辑。 */
+ /** 撤回并删除本人或有效被监护人审核中的人脸记录,返回原图供重新编辑。 */
cancelGuardianWard: (params: { id: string }) =>
request({
url: `/admin/user-face/app/guardian-ward/cancel`,
diff --git a/src/sheep/api/wallet.ts b/src/sheep/api/wallet.ts
index 93c18c2..af104cb 100644
--- a/src/sheep/api/wallet.ts
+++ b/src/sheep/api/wallet.ts
@@ -2,6 +2,10 @@ import request from "@/sheep/utils/request"
export type GuardianWardRechargeItem = {
wardUserId: string | number
+ /** 是否为当前登录用户本人,仅“本人及关系人”列表接口返回。 */
+ currentUser?: boolean
+ /** 当前登录用户是否可以按有效监护关系为该用户代办业务。 */
+ guardianWard?: boolean
wardName: string
wardAvatar?: string
walletTypeName?: string
@@ -121,6 +125,12 @@ export default {
url: "/wallet/wallet-recharge/app/guardian-ward/list",
method: "GET",
}),
+ /** 查询当前登录用户本人及同一完整关系图谱中全部关系人的业务摘要。 */
+ relatedUserList: (): Promise =>
+ request({
+ url: "/wallet/wallet-recharge/app/related-user/list",
+ method: "GET",
+ }),
/** 查询目标饭卡、有效套餐和目标食堂支付平台。 */
guardianWardRechargeContext: (params: { wardUserId: string | number }): Promise =>
request({