From 700f9d0da314a4ea701fe9f68d305b67d72ec5fb Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期三, 08 七月 2026 15:08:37 +0800
Subject: [PATCH] 各类修复fix

---
 yuyueMiniProgram/src/pages/index/index.vue                                                      |   76 ++++++++--
 yuyueMiniProgram/src/pages/appointment/index.vue                                                |   59 +++++++-
 yuyueMiniProgram/src/components.d.ts                                                            |    1 
 yuyueMiniProgram/src/pages/review/index.vue                                                     |   26 +++
 frontend-h5/src/utils/visitReason.ts                                                            |    4 
 frontend-admin/index.html                                                                       |    2 
 frontend-admin/src/views/DashboardView.vue                                                      |   28 ---
 yuyueMiniProgram/src/components/MiniLoginPrompt.vue                                             |   21 ++
 yuyueMiniProgram/src/pages/reviewList/index.vue                                                 |   37 ++++
 backend/src/main/java/com/sinata/appointment/service/DashboardApplicationService.java           |   40 ++---
 /dev/null                                                                                       |    0 
 yuyueMiniProgram/src/pages/reviewDetail/index.vue                                               |   33 +++
 backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java  |    3 
 backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java     |    8 
 yuyueMiniProgram/src/utils/visitReason.ts                                                       |    4 
 yuyueMiniProgram/src/auto-imports.d.ts                                                          |    1 
 frontend-admin/src/views/LoginView.vue                                                          |    2 
 yuyueMiniProgram/src/pages/record/index.vue                                                     |   40 ++++-
 backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java |    4 
 backend/src/main/resources/application.yml                                                      |    6 
 frontend-admin/src/layouts/MainLayout.vue                                                       |    2 
 backend/src/main/java/com/sinata/appointment/controller/DashboardController.java                |    6 
 yuyueMiniProgram/src/pages/mine/index.vue                                                       |    2 
 23 files changed, 287 insertions(+), 118 deletions(-)

diff --git a/backend/src/main/java/com/sinata/appointment/controller/DashboardController.java b/backend/src/main/java/com/sinata/appointment/controller/DashboardController.java
index 430c7b5..0a082ab 100644
--- a/backend/src/main/java/com/sinata/appointment/controller/DashboardController.java
+++ b/backend/src/main/java/com/sinata/appointment/controller/DashboardController.java
@@ -27,10 +27,8 @@
     @Operation(summary = "数据总览")
     @GetMapping("/overview")
     @SaCheckPermission("dashboard:page")
-    public Result<DashboardOverviewVo> overview(
-            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
-            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
-        return ResultUtil.data(dashboardApplicationService.getOverview(startDate, endDate));
+    public Result<DashboardOverviewVo> overview() {
+        return ResultUtil.data(dashboardApplicationService.getOverview());
     }
 
     @Operation(summary = "预约统计")
diff --git a/backend/src/main/java/com/sinata/appointment/service/DashboardApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/DashboardApplicationService.java
index ef4154b..496e605 100644
--- a/backend/src/main/java/com/sinata/appointment/service/DashboardApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/DashboardApplicationService.java
@@ -45,18 +45,17 @@
     private final MpUserMapper mpUserMapper;
     private final SysDeptMapper sysDeptMapper;
 
-    public DashboardOverviewVo getOverview(LocalDate startDate, LocalDate endDate) {
-        DateRange range = resolveRange(startDate, endDate);
-        LocalDate dailyDate = resolveDailyDate(range);
+    public DashboardOverviewVo getOverview() {
+        LocalDate dailyDate = LocalDate.now();
 
         DashboardOverviewVo vo = new DashboardOverviewVo();
-        vo.setStartDate(format(range.startDate()));
-        vo.setEndDate(format(range.endDate()));
+        vo.setStartDate(null);
+        vo.setEndDate(null);
         vo.setDailyDate(format(dailyDate));
         vo.setDailyAppointmentCount(countAppointments(dailyDate, dailyDate, null));
-        vo.setTotalAppointmentCount(countAppointments(range.startDate(), range.endDate(), null));
-        vo.setRegisteredUserCount(countRegisteredUsers(range.startDate(), range.endDate()));
-        vo.setEmployeeCount(countEmployees(range.startDate(), range.endDate()));
+        vo.setTotalAppointmentCount(countAllAppointments());
+        vo.setRegisteredUserCount(countRegisteredUsers());
+        vo.setEmployeeCount(countEmployees());
         return vo;
     }
 
@@ -131,6 +130,11 @@
                 appointmentRangeWrapper(startDate, endDate, resolveDeptIds(visitedDeptId), null));
     }
 
+    private long countAllAppointments() {
+        return appointmentOrderMapper.selectCount(
+                new LambdaQueryWrapper<AppointmentOrder>().eq(AppointmentOrder::getDelFlag, 0));
+    }
+
     private LambdaQueryWrapper<AppointmentOrder> appointmentRangeWrapper(
             LocalDate startDate, LocalDate endDate, List<Long> deptIds, String status) {
         LambdaQueryWrapper<AppointmentOrder> wrapper =
@@ -203,22 +207,18 @@
         return result;
     }
 
-    private long countRegisteredUsers(LocalDate startDate, LocalDate endDate) {
+    private long countRegisteredUsers() {
         return mpUserMapper.selectCount(
                 new LambdaQueryWrapper<MpUser>()
                         .eq(MpUser::getDelFlag, 0)
-                        .eq(MpUser::getUserType, MiniUserType.VISITOR)
-                        .ge(MpUser::getCreateTime, atStartOfDay(startDate))
-                        .lt(MpUser::getCreateTime, atStartOfNextDay(endDate)));
+                        .eq(MpUser::getUserType, MiniUserType.VISITOR));
     }
 
-    private long countEmployees(LocalDate startDate, LocalDate endDate) {
+    private long countEmployees() {
         return mpUserMapper.selectCount(
                 new LambdaQueryWrapper<MpUser>()
                         .eq(MpUser::getDelFlag, 0)
-                        .eq(MpUser::getUserType, MiniUserType.EMPLOYEE)
-                        .ge(MpUser::getCreateTime, atStartOfDay(startDate))
-                        .lt(MpUser::getCreateTime, atStartOfNextDay(endDate)));
+                        .eq(MpUser::getUserType, MiniUserType.EMPLOYEE));
     }
 
     private DateRange resolveRange(LocalDate startDate, LocalDate endDate) {
@@ -232,14 +232,6 @@
             return new DateRange(resolvedEnd, resolvedStart);
         }
         return new DateRange(resolvedStart, resolvedEnd);
-    }
-
-    private LocalDate resolveDailyDate(DateRange range) {
-        LocalDate today = LocalDate.now();
-        if (!today.isBefore(range.startDate()) && !today.isAfter(range.endDate())) {
-            return today;
-        }
-        return range.endDate();
     }
 
     private LocalDateTime atStartOfDay(LocalDate date) {
diff --git a/backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java
index 85ae741..6006207 100644
--- a/backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java
@@ -1135,8 +1135,12 @@
     }
 
     private String buildVisitReasonText(AppointmentOrder row, Map<String, String> reasonNameMap) {
-        String reasonName = reasonNameMap.get(trimToNull(row.getVisitReasonCode()));
-        return StringUtils.hasText(reasonName) ? reasonName : trimToNull(row.getVisitReasonCode());
+        String code = trimToNull(row.getVisitReasonCode());
+        if (AppointmentBizConstants.VISIT_REASON_OTHER.equalsIgnoreCase(code)) {
+            return "其他";
+        }
+        String reasonName = reasonNameMap.get(code);
+        return StringUtils.hasText(reasonName) ? reasonName : code;
     }
 
     private String buildAccessAreaText(String rawJson) {
diff --git a/backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java
index 620d889..d9ec031 100644
--- a/backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/MiniApprovalDetailApplicationService.java
@@ -393,6 +393,9 @@
         if (!StringUtils.hasText(code)) {
             return "-";
         }
+        if (AppointmentBizConstants.VISIT_REASON_OTHER.equalsIgnoreCase(code)) {
+            return "其他";
+        }
         List<BizVisitReason> rows =
                 bizVisitReasonMapper.selectList(
                         new LambdaQueryWrapper<BizVisitReason>()
diff --git a/backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java
index b9fea3e..da5e60d 100644
--- a/backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java
@@ -6,6 +6,7 @@
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.sinata.appointment.config.MiniStpUtil;
+import com.sinata.appointment.constants.AppointmentBizConstants;
 import com.sinata.appointment.constants.ApprovalInstanceStatus;
 import com.sinata.appointment.constants.ApprovalNodeCode;
 import com.sinata.appointment.constants.ApprovalTaskStatus;
@@ -637,6 +638,9 @@
 
     private String buildVisitReasonText(AppointmentOrder order, Map<String, String> reasonNameMap) {
         String reasonCode = trimToNull(order.getVisitReasonCode());
+        if (AppointmentBizConstants.VISIT_REASON_OTHER.equalsIgnoreCase(reasonCode)) {
+            return "其他";
+        }
         String reasonName = reasonNameMap.get(reasonCode);
         return StringUtils.hasText(reasonName) ? reasonName : reasonCode;
     }
diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml
index 00afbbd..68a146d 100644
--- a/backend/src/main/resources/application.yml
+++ b/backend/src/main/resources/application.yml
@@ -91,9 +91,9 @@
 integration:
   hikvision:
     qrcode:
-      encrypt-enabled: ${HIKVISION_QRCODE_ENCRYPT_ENABLED:false}
-      aes-key: ${HIKVISION_QRCODE_AES_KEY:SinataHikvisionQrcodeKey01}
-      aes-iv: ${HIKVISION_QRCODE_AES_IV:SinataHikvisionQrcodeIv001}
+      encrypt-enabled: ${HIKVISION_QRCODE_ENCRYPT_ENABLED:true}
+      aes-key: "WwXxYyZz1234!@#$"
+      aes-iv: "AaBbCcDd1234!@#$"
       valid-minutes: ${HIKVISION_QRCODE_VALID_MINUTES:0}
 
 file-upload-path: /opt/web/uploads/
diff --git a/frontend-admin/dist.zip b/frontend-admin/dist.zip
deleted file mode 100644
index 3c637da..0000000
--- a/frontend-admin/dist.zip
+++ /dev/null
Binary files differ
diff --git a/frontend-admin/index.html b/frontend-admin/index.html
index c367cc0..3072298 100644
--- a/frontend-admin/index.html
+++ b/frontend-admin/index.html
@@ -4,7 +4,7 @@
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <link rel="icon" type="image/jpeg" href="/src/static/logo.jpg" />
-    <title>访客预约管理后台</title>
+    <title>红宇集团访客预约管理系统</title>
   </head>
   <body>
     <div id="app"></div>
diff --git a/frontend-admin/src/layouts/MainLayout.vue b/frontend-admin/src/layouts/MainLayout.vue
index e8679d5..5aa619b 100644
--- a/frontend-admin/src/layouts/MainLayout.vue
+++ b/frontend-admin/src/layouts/MainLayout.vue
@@ -3,7 +3,7 @@
     <el-aside width="15.98vw" class="side-wrap">
       <div class="brand-block">
         <img :src="siteLogo" alt="logo" class="brand-icon" />
-        <div class="brand-name">运维运营管理平台</div>
+        <div class="brand-name">红宇集团访客预约管理系统</div>
       </div>
       <el-menu
         :default-active="active"
diff --git a/frontend-admin/src/views/DashboardView.vue b/frontend-admin/src/views/DashboardView.vue
index 1063476..c9e42ab 100644
--- a/frontend-admin/src/views/DashboardView.vue
+++ b/frontend-admin/src/views/DashboardView.vue
@@ -3,20 +3,6 @@
     <section class="panel overview-panel" v-loading="overviewLoading">
       <div class="section-head">
         <div class="section-title">数据总览</div>
-        <div class="filters">
-          <el-date-picker
-            v-model="overviewDateRange"
-            class="range-picker"
-            type="daterange"
-            unlink-panels
-            range-separator="至"
-            start-placeholder="开始日期"
-            end-placeholder="结束日期"
-            value-format="YYYY-MM-DD"
-            :clearable="false"
-            @change="loadOverview"
-          />
-        </div>
       </div>
 
       <div class="summary-grid">
@@ -180,13 +166,12 @@
 const lineChartRef = ref<HTMLElement | null>(null);
 let lineChartInstance: ECharts | null = null;
 
-const overviewDateRange = ref<[string, string]>(getCurrentWeekRange());
 const chartDateRange = ref<[string, string]>(getCurrentWeekRange());
 
 const overview = ref<DashboardOverview>({
-  startDate: overviewDateRange.value[0],
-  endDate: overviewDateRange.value[1],
-  dailyDate: overviewDateRange.value[1],
+  startDate: "",
+  endDate: "",
+  dailyDate: formatDate(new Date()),
   dailyAppointmentCount: 0,
   totalAppointmentCount: 0,
   registeredUserCount: 0,
@@ -360,12 +345,7 @@
 async function loadOverview() {
   overviewLoading.value = true;
   try {
-    const { data } = await http.get("/dashboard/overview", {
-      params: {
-        startDate: overviewDateRange.value?.[0],
-        endDate: overviewDateRange.value?.[1],
-      },
-    });
+    const { data } = await http.get("/dashboard/overview");
     overview.value = {
       ...overview.value,
       ...(data.result || {}),
diff --git a/frontend-admin/src/views/LoginView.vue b/frontend-admin/src/views/LoginView.vue
index 594c7ee..21cc6b6 100644
--- a/frontend-admin/src/views/LoginView.vue
+++ b/frontend-admin/src/views/LoginView.vue
@@ -4,7 +4,7 @@
     <div class="bg-glow bg-glow-right"></div>
 
     <el-card class="card" shadow="never">
-      <h2 class="title">宇通行管理平台</h2>
+      <h2 class="title">红宇集团访客预约管理系统</h2>
       <p class="subtitle">安全、高效地处理预约、审批与接待流程</p>
 
       <el-form :model="form" label-position="top" class="login-form" @submit.prevent="onSubmit">
diff --git a/frontend-h5/src/utils/visitReason.ts b/frontend-h5/src/utils/visitReason.ts
index 81ca65c..795f374 100644
--- a/frontend-h5/src/utils/visitReason.ts
+++ b/frontend-h5/src/utils/visitReason.ts
@@ -3,6 +3,8 @@
   if (!raw) {
     return ''
   }
+  if (raw.toUpperCase() === 'OTHER') {
+    return '其他'
+  }
   return raw.replace(/^其他[::]\s*/, '')
 }
-
diff --git a/yuyueMiniProgram/src/auto-imports.d.ts b/yuyueMiniProgram/src/auto-imports.d.ts
index dd25867..b0fc008 100644
--- a/yuyueMiniProgram/src/auto-imports.d.ts
+++ b/yuyueMiniProgram/src/auto-imports.d.ts
@@ -37,6 +37,7 @@
   const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
   const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
   const createPinia: typeof import('pinia')['createPinia']
+  const createQrCodeImage: typeof import('./utils/qrCodeImage')['createQrCodeImage']
   const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
   const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate']
   const createRouter: typeof import('@wot-ui/router')['createRouter']
diff --git a/yuyueMiniProgram/src/components.d.ts b/yuyueMiniProgram/src/components.d.ts
index f6b7fb2..3da4889 100644
--- a/yuyueMiniProgram/src/components.d.ts
+++ b/yuyueMiniProgram/src/components.d.ts
@@ -19,7 +19,6 @@
     WdForm: typeof import('wot-design-uni/components/wd-form/wd-form.vue')['default']
     WdGap: typeof import('wot-design-uni/components/wd-gap/wd-gap.vue')['default']
     WdIcon: typeof import('wot-design-uni/components/wd-icon/wd-icon.vue')['default']
-    WdInput: typeof import('wot-design-uni/components/wd-input/wd-input.vue')['default']
     WdKeyboard: typeof import('wot-design-uni/components/wd-keyboard/wd-keyboard.vue')['default']
     WdLoading: typeof import('wot-design-uni/components/wd-loading/wd-loading.vue')['default']
     WdMessageBox: typeof import('wot-design-uni/components/wd-message-box/wd-message-box.vue')['default']
diff --git a/yuyueMiniProgram/src/components/MiniLoginPrompt.vue b/yuyueMiniProgram/src/components/MiniLoginPrompt.vue
index 458dc31..bacbc2e 100644
--- a/yuyueMiniProgram/src/components/MiniLoginPrompt.vue
+++ b/yuyueMiniProgram/src/components/MiniLoginPrompt.vue
@@ -14,6 +14,7 @@
 
 const visible = computed(() => authStore.loginPromptVisible)
 const needPhoneAuthorize = computed(() => authStore.needPhoneAuthorize)
+const shouldRenderPrompt = ref(true)
 const message = computed(() => {
   if (needPhoneAuthorize.value) {
     return '首次登录需授权手机号完成身份识别'
@@ -22,6 +23,7 @@
 })
 
 function hideLoginPrompt() {
+  shouldRenderPrompt.value = true
   authStore.hideLoginPrompt()
 }
 
@@ -78,11 +80,13 @@
 }
 
 async function handlePhoneAuthorize(event: any) {
+  shouldRenderPrompt.value = true
   if (loginSubmitting.value) {
     return
   }
   const phoneCode = event?.detail?.code
   if (!phoneCode) {
+    authStore.showLoginPrompt()
     uni.showToast({
       title: '未获取到手机号授权',
       icon: 'none',
@@ -107,6 +111,7 @@
     })
   }
   catch (error) {
+    authStore.showLoginPrompt()
     uni.showToast({
       title: error instanceof Error ? error.message : '登录失败',
       icon: 'none',
@@ -116,14 +121,27 @@
     loginSubmitting.value = false
   }
 }
+
+function handleBeforePhoneAuthorize() {
+  if (loginSubmitting.value) {
+    return
+  }
+  shouldRenderPrompt.value = false
+}
 </script>
 
 <template>
-  <view v-if="visible" class="fixed inset-0 z-40 bg-[rgba(0,0,0,0.55)]" @click="!needPhoneAuthorize && hideLoginPrompt()" />
+  <view
+    v-if="visible"
+    class="fixed inset-0 z-40 bg-[rgba(0,0,0,0.55)]"
+    :class="shouldRenderPrompt ? '' : 'opacity-0 pointer-events-none'"
+    @click="!needPhoneAuthorize && hideLoginPrompt()"
+  />
 
   <view
     v-if="visible"
     class="fixed left-[50%] top-[50%] z-50 w-[520rpx] translate-x-[-50%] translate-y-[-50%] rounded-[28rpx] bg-white px-[40rpx] pb-[36rpx] pt-[28rpx]"
+    :class="shouldRenderPrompt ? '' : 'opacity-0 pointer-events-none'"
   >
     <view class="mb-[16rpx] text-center text-[34rpx] text-[#1A1A1A] font-medium">
       提示
@@ -146,6 +164,7 @@
         class="m-0 h-[80rpx] flex flex-1 items-center justify-center rounded-full border-none bg-[#0C6FFF] p-0 text-[30rpx] text-white after:border-none"
         :disabled="loginSubmitting"
         open-type="getPhoneNumber"
+        @tap="handleBeforePhoneAuthorize"
         @getphonenumber="handlePhoneAuthorize"
       >
         {{ loginSubmitting ? '授权中...' : '授权手机号' }}
diff --git a/yuyueMiniProgram/src/pages/appointment/index.vue b/yuyueMiniProgram/src/pages/appointment/index.vue
index a89331a..d58af96 100644
--- a/yuyueMiniProgram/src/pages/appointment/index.vue
+++ b/yuyueMiniProgram/src/pages/appointment/index.vue
@@ -40,6 +40,8 @@
   RESPONDENT: 'respondent',
   VISIT_REASON: 'visit_reason',
   VISIT_START_TIME: 'visit_start_time',
+  LICENSE_PLATE: 'license_plate',
+  DRIVER: 'driver',
 } as const
 
 interface AppointmentVehicle {
@@ -93,6 +95,10 @@
 const isVisitReasonRequired = computed(() => isFieldRequired(APPOINTMENT_FIELD_CODES.VISIT_REASON, true))
 const isRespondentRequired = computed(() => isFieldRequired(APPOINTMENT_FIELD_CODES.RESPONDENT, true))
 const isVisitTimeRequired = computed(() => isFieldRequired(APPOINTMENT_FIELD_CODES.VISIT_START_TIME, true))
+const showVehicleEntryOption = computed(() =>
+  isFieldVisible(APPOINTMENT_FIELD_CODES.LICENSE_PLATE, true)
+  || isFieldVisible(APPOINTMENT_FIELD_CODES.DRIVER, true),
+)
 const showCustomReasonInput = computed(() => Boolean(selectedVisitReason.value))
 const showReasonPicker = ref(false)
 const appointmentIcons = {
@@ -124,6 +130,14 @@
     return defaultValue
   }
   return config.requiredFlag === 1
+}
+
+function isFieldVisible(fieldCode: string, defaultValue = true) {
+  const config = findFieldConfig(fieldCode)
+  if (!config) {
+    return defaultValue
+  }
+  return config.visible === 1
 }
 
 function handlePlateCharClick(vehicleIndex: number, charIndex: number) {
@@ -190,6 +204,10 @@
   if (lastFilledIndex < 7) {
     focusNextPlateChar(vehicleIndex, lastFilledIndex + 1)
   }
+}
+
+function handleIntervieweeInput(e: any) {
+  formData.interviewee = e?.detail?.value || ''
 }
 
 function handlePlateDelete(vehicleIndex: number, charIndex: number) {
@@ -954,6 +972,9 @@
 async function loadFieldConfigs() {
   try {
     fieldConfigs.value = await fetchMiniFieldConfigs()
+    if (!showVehicleEntryOption.value) {
+      handleVehicleEntryChange(false)
+    }
   }
   catch (error) {
     fieldConfigs.value = []
@@ -1307,6 +1328,15 @@
   },
 )
 
+watch(
+  showVehicleEntryOption,
+  (visible) => {
+    if (!visible) {
+      handleVehicleEntryChange(false)
+    }
+  },
+)
+
 onLoad((options) => {
   uni.$on('selectVisitors', handleVisitorSelection)
   rebookOrderId.value = options?.rebookOrderId ? Number(options.rebookOrderId) : null
@@ -1368,15 +1398,24 @@
         class="mb-[48rpx] rounded-[16rpx] bg-white pl-[32rpx] pr-[12rpx] py-[8rpx] shadow-[0px_4px_8px_0px_rgba(6,47,108,0.1608)]">
         <wd-form :model="formData">
           <!-- 被访人 -->
-          <wd-input v-model="formData.interviewee" placeholder="请输入要拜访谁" align="right" custom-class="custom-cell"
-            placeholder-class="custom-placeholder">
-            <template #label>
-              <view class="inline-flex items-start">
-                <text class="text-[28rpx] text-[#333333]">被访人</text>
-                <text v-if="isRespondentRequired" class="text-[24rpx] text-[#FF4D4F] ml-[4rpx] mt-[-4rpx]">*</text>
-              </view>
-            </template>
-          </wd-input>
+          <view class="custom-cell flex items-center justify-between">
+            <view class="inline-flex items-start shrink-0">
+              <text class="text-[28rpx] text-[#333333]">被访人</text>
+              <text v-if="isRespondentRequired" class="text-[24rpx] text-[#FF4D4F] ml-[4rpx] mt-[-4rpx]">*</text>
+            </view>
+            <input
+              :value="formData.interviewee"
+              type="text"
+              placeholder="请输入要拜访谁"
+              placeholder-class="text-[#B3B3B3]"
+              class="ml-[32rpx] h-[64rpx] flex-1 text-right text-[28rpx] text-[#333333]"
+              confirm-type="search"
+              :adjust-position="true"
+              :cursor-spacing="120"
+              @input="handleIntervieweeInput"
+              @confirm="handleSearchVisitedUser"
+            />
+          </view>
           <view v-if="selectedVisitedUser" class="px-[20rpx] pb-[16rpx] text-right text-[22rpx] text-[#999999]">
             已选:{{ selectedVisitedUser.realName }}{{ selectedVisitedUser.deptName ? ` / ${selectedVisitedUser.deptName}` : '' }}
           </view>
@@ -1517,7 +1556,7 @@
                 </view>
                 <text class="ml-[12rpx] text-[28rpx] text-[#999999]">人员进场</text>
               </view>
-              <view class="flex items-center" @click="handleVehicleEntryChange(!formData.vehicleEntry)">
+              <view v-if="showVehicleEntryOption" class="flex items-center" @click="handleVehicleEntryChange(!formData.vehicleEntry)">
                 <view
                   class="flex items-center justify-center w-[28rpx] h-[28rpx] rounded-full border-[2rpx] border-solid transition-colors duration-200"
                   :class="formData.vehicleEntry ? 'border-[#1677FF]' : 'border-[#CFCFCF]'">
diff --git a/yuyueMiniProgram/src/pages/index/index.vue b/yuyueMiniProgram/src/pages/index/index.vue
index 0821fd1..25fe871 100644
--- a/yuyueMiniProgram/src/pages/index/index.vue
+++ b/yuyueMiniProgram/src/pages/index/index.vue
@@ -467,7 +467,7 @@
   const ticketUuid = res?.target?.dataset?.ticketUuid as string | undefined
   if (!ticketUuid) {
     return {
-      title: '红宇精工访客预约',
+      title: '红宇集团访客预约',
       path: '/pages/index/index',
     }
   }
@@ -502,15 +502,17 @@
 <template>
   <view class="relative">
     <image src="/static/home/bg.png" class="absolute left-0 top-0 z-0 h-[1624rpx] w-full" mode="scaleToFill" />
+    <view class="home-header-backdrop" />
+    <view class="home-content-backdrop" />
 
-    <view class="relative z-4" :style="{ paddingTop: `${safeAreaInsets?.top || 44}px` }">
-      <view class="mb-[64rpx] h-[88rpx] flex items-center px-[32rpx]">
+    <view class="relative z-4 pb-[160rpx]" :style="{ paddingTop: `${safeAreaInsets?.top || 44}px` }">
+      <view class="mb-[24rpx] h-[88rpx] flex items-center px-[32rpx]">
         <text class="text-[36rpx] text-white font-medium">
-          红宇精工访客预约
+          红宇集团访客预约
         </text>
       </view>
 
-      <view class="mb-[36rpx] flex items-center pl-[26rpx] pr-[22rpx]">
+      <view class="mb-[28rpx] flex items-center pl-[26rpx] pr-[22rpx]">
         <image src="/static/home/hi.png" class="mr-[24rpx] h-[96rpx] w-[212rpx]" mode="aspectFit" />
         <view class="flex flex-col">
           <view class="welcome-title flex items-center text-[56rpx] text-white font-[600]">
@@ -521,15 +523,13 @@
 
       <view v-if="showEmployeeDashboard" class="mb-[32rpx] w-full pl-[26rpx] pr-[22rpx]" style="box-sizing: border-box;">
         <view
-          class="rounded-[16rpx] p-[24rpx] pb-[26rpx]"
-          style="background: linear-gradient(180deg, #CCE4FE 0%, #FAFCFD 40%, #FDFDFD 100%); box-shadow: 0 4rpx 8rpx 0 rgba(0, 104, 255, 0.2);border: 1rpx solid #fff;"
+          class="dashboard-panel rounded-[16rpx] p-[24rpx] pb-[26rpx]"
         >
           <view class="flex gap-[30rpx]">
             <view
-              class="h-[126rpx] w-[312rpx] flex rounded-[20rpx] pl-[38rpx] pt-[20rpx]"
+              class="home-feature-card h-[126rpx] w-[312rpx] flex rounded-[20rpx] pl-[38rpx] pt-[20rpx]"
               style="background: url('/static/home/toDo_bg.png') no-repeat center center;
-              background-size: 100%;box-sizing: border-box;
-              box-shadow: 0 2rpx 8rpx 0 rgba(119, 144, 213, 0.3)"
+              background-size: 100%;box-sizing: border-box;"
               @click="handleOpenApprovalTodo"
             >
               <image src="/static/home/toDo.png" class="mr-[14rpx] h-[100rpx] w-[108rpx]" />
@@ -543,10 +543,9 @@
               </view>
             </view>
             <view
-              class="h-[126rpx] w-[312rpx] flex items-center rounded-[20rpx] pl-[38rpx] pt-[20rpx]"
+              class="home-feature-card h-[126rpx] w-[312rpx] flex items-center rounded-[20rpx] pl-[38rpx] pt-[20rpx]"
               style="background: url('/static/home/wait_bg.png') no-repeat center center;
-              background-size: 100%;box-sizing: border-box;
-              box-shadow: 0 2rpx 8rpx 0 rgba(119, 144, 213, 0.3)"
+              background-size: 100%;box-sizing: border-box;"
               @click="handleOpenVisitRecords"
             >
               <image src="/static/home/wait.png" class="mr-[14rpx] h-[100rpx] w-[108rpx]" />
@@ -565,8 +564,8 @@
 
       <view class="flex gap-[16rpx] pl-[24rpx] pr-[22rpx]">
         <view
-          class="h-[240rpx] w-[344rpx] flex flex-1 flex-col items-center justify-center rounded-[20rpx]"
-          style="background: linear-gradient(180deg, #DEF4FF 0%, #FFFFFF 100%);border: 1rpx solid #fff;box-shadow: 0 4rpx 10rpx 0 rgba(0, 104, 255, 0.16)"
+          class="home-action-card h-[240rpx] w-[344rpx] flex flex-1 flex-col items-center justify-center rounded-[20rpx]"
+          style="background: linear-gradient(180deg, #DEF4FF 0%, #FFFFFF 100%);"
           @click="ensureLoggedIn(() => { router.push({ name: 'appointment' }) })"
         >
           <image src="/static/home/appointment.png" class="mb-[12rpx] h-[96rpx] w-[96rpx]" />
@@ -576,8 +575,8 @@
         </view>
         <view class="flex flex-1 flex-col gap-[16rpx]">
           <view
-            class="flex flex-1 items-center rounded-[20rpx] px-[40rpx]"
-            style="background: linear-gradient(180deg, #FFF7E0 0%, #FFFFFF 100%);box-shadow: 0 4rpx 10rpx 0 rgba(0, 104, 255, 0.16)"
+            class="home-action-card flex flex-1 items-center rounded-[20rpx] px-[40rpx]"
+            style="background: linear-gradient(180deg, #FFF7E0 0%, #FFFFFF 100%);"
             @click="ensureLoggedIn(() => { router.push({ name: 'record' }) })"
           >
             <image src="/static/home/record.png" class="mr-[16rpx] h-[64rpx] w-[64rpx]" />
@@ -586,8 +585,8 @@
             </text>
           </view>
           <view
-            class="flex flex-1 items-center rounded-[20rpx] px-[40rpx]"
-            style="background: linear-gradient(180deg, #E0FAEE 0%, #FFFFFF 100%);border: 1rpx solid #fff;box-shadow: 0 4rpx 10rpx 0 rgba(0, 104, 255, 0.16)"
+            class="home-action-card flex flex-1 items-center rounded-[20rpx] px-[40rpx]"
+            style="background: linear-gradient(180deg, #E0FAEE 0%, #FFFFFF 100%);"
             @click="ensureLoggedIn(() => { uni.navigateTo({ url: '/pages/commonVisitors/index' }) })"
           >
             <image src="/static/home/visitor.png" class="mr-[16rpx] h-[64rpx] w-[64rpx]" />
@@ -745,6 +744,45 @@
 </template>
 
 <style scoped>
+.home-content-backdrop {
+  position: absolute;
+  left: 0;
+  top: 420rpx;
+  z-index: 0;
+  width: 100%;
+  height: 924rpx;
+  background:
+    linear-gradient(180deg, rgba(196, 232, 249, 0) 0%, rgba(196, 232, 249, 0.72) 12%, rgba(226, 244, 250, 0.9) 38%, rgba(239, 248, 252, 0.96) 100%);
+  pointer-events: none;
+}
+
+.home-header-backdrop {
+  position: absolute;
+  left: 0;
+  top: 0;
+  z-index: 1;
+  width: 100%;
+  height: 520rpx;
+  background: linear-gradient(180deg, rgba(23, 145, 255, 0.96) 0%, rgba(39, 161, 255, 0.82) 62%, rgba(39, 161, 255, 0) 100%);
+  pointer-events: none;
+}
+
+.dashboard-panel {
+  border: 1rpx solid rgba(255, 255, 255, 0.92);
+  background: linear-gradient(180deg, rgba(190, 222, 255, 0.98) 0%, rgba(245, 251, 255, 0.96) 48%, rgba(255, 255, 255, 0.98) 100%);
+  box-shadow: 0 14rpx 30rpx rgba(31, 111, 206, 0.22), 0 4rpx 10rpx rgba(255, 255, 255, 0.7) inset;
+}
+
+.home-feature-card,
+.home-action-card {
+  border: 1rpx solid rgba(255, 255, 255, 0.92);
+  box-shadow: 0 14rpx 28rpx rgba(35, 111, 205, 0.2), 0 4rpx 10rpx rgba(255, 255, 255, 0.65) inset;
+}
+
+.home-action-card {
+  box-sizing: border-box;
+}
+
 .welcome-title {
   font-family: 'YouSheBiaoTiHei', sans-serif;
 }
diff --git a/yuyueMiniProgram/src/pages/mine/index.vue b/yuyueMiniProgram/src/pages/mine/index.vue
index fb93508..eb07f9f 100644
--- a/yuyueMiniProgram/src/pages/mine/index.vue
+++ b/yuyueMiniProgram/src/pages/mine/index.vue
@@ -139,7 +139,7 @@
           :style="{ top: statusBarHeight + 'px', height: navBarHeight + 'px' }">
           <view class="relative z-10 flex h-full w-[88rpx] items-center justify-center" />
           <view class="absolute left-0 z-0 w-full text-center text-[34rpx] font-medium text-white">
-            红宇精工访客预约
+            红宇集团访客预约
           </view>
           <view class="w-[88rpx]" />
         </view>
diff --git a/yuyueMiniProgram/src/pages/record/index.vue b/yuyueMiniProgram/src/pages/record/index.vue
index 8696cc6..12de49e 100644
--- a/yuyueMiniProgram/src/pages/record/index.vue
+++ b/yuyueMiniProgram/src/pages/record/index.vue
@@ -16,7 +16,6 @@
   status?: string
 }
 
-const router = useRouter()
 const sysInfo = uni.getSystemInfoSync()
 const statusBarHeight = sysInfo.statusBarHeight || 0
 const navBarHeight = 44
@@ -43,7 +42,22 @@
 ]
 
 function handleBack() {
-  router.back()
+  const pages = getCurrentPages()
+  if (pages.length > 1) {
+    uni.navigateBack({
+      delta: 1,
+      fail: () => {
+        uni.switchTab({ url: '/pages/index/index' })
+      },
+    })
+    return
+  }
+  uni.switchTab({
+    url: '/pages/index/index',
+    fail: () => {
+      uni.reLaunch({ url: '/pages/index/index' })
+    },
+  })
 }
 
 function statusTheme(item: MiniAppointmentListItem) {
@@ -186,16 +200,16 @@
 
 <template>
   <view class="h-screen bg-[#F6FBFF] w-full relative box-border flex flex-col overflow-hidden">
-    <view class="fixed left-0 top-0 z-0 h-[500rpx] w-full" style="background: linear-gradient(180deg, #5398FF 0%, #A9D0FF 50%, #F6FBFF 100%);" />
+    <view class="fixed left-0 top-0 z-0 h-[500rpx] w-full pointer-events-none" style="background: linear-gradient(180deg, #5398FF 0%, #A9D0FF 50%, #F6FBFF 100%);" />
 
-    <view class="fixed top-0 left-0 w-full z-50 flex flex-col">
-      <view class="absolute left-0 top-0 z-[-1] w-full overflow-hidden" :style="{ height: (statusBarHeight + navBarHeight + uni.upx2px(36) + uni.upx2px(288) + uni.upx2px(24)) + 'px' }">
+    <view class="fixed top-0 left-0 w-full flex flex-col record-fixed-head">
+      <view class="absolute left-0 top-0 z-0 w-full overflow-hidden pointer-events-none" :style="{ height: (statusBarHeight + navBarHeight + uni.upx2px(36) + uni.upx2px(288) + uni.upx2px(24)) + 'px' }">
         <view class="w-full h-[500rpx] absolute top-0 left-0" style="background: linear-gradient(180deg, #5398FF 0%, #A9D0FF 50%, #F6FBFF 100%);" />
       </view>
 
-      <view class="relative w-full shrink-0" :style="{ height: (statusBarHeight + navBarHeight) + 'px' }">
-        <view class="flex items-center justify-between w-full absolute left-0" :style="{ top: statusBarHeight + 'px', height: navBarHeight + 'px' }">
-          <view class="flex h-full w-[88rpx] items-center justify-center relative z-10" @click="handleBack">
+      <view class="relative z-20 w-full shrink-0" :style="{ height: (statusBarHeight + navBarHeight) + 'px' }">
+        <view class="flex items-center justify-between w-full absolute left-0 z-20" :style="{ top: statusBarHeight + 'px', height: navBarHeight + 'px' }">
+          <view class="record-back-hit flex h-full w-[120rpx] items-center justify-center relative" @tap.stop="handleBack" @click.stop="handleBack">
             <wd-icon name="arrow-left" size="40rpx" color="#ffffff" />
           </view>
           <view class="absolute left-0 w-full text-center text-[34rpx] font-medium text-white z-0">
@@ -205,7 +219,7 @@
         </view>
       </view>
 
-      <view class="px-[24rpx] pt-[36rpx] pb-[24rpx] w-full box-border">
+      <view class="relative z-10 px-[24rpx] pt-[36rpx] pb-[24rpx] w-full box-border">
         <view class="bg-white rounded-[16rpx] search-card shadow-[0_4rpx_8rpx_rgba(6,47,108,0.1608)] w-full shrink-0">
           <view class="flex justify-center pt-[32rpx] pb-[16rpx]">
             <view class="w-[622rpx] h-[88rpx] rounded-[44rpx] bg-[#FFFFFF] border-[4rpx] border-solid border-[#D4E6FF] box-border flex items-center px-[32rpx]">
@@ -323,6 +337,14 @@
 </template>
 
 <style scoped>
+.record-fixed-head {
+  z-index: 9999;
+}
+
+.record-back-hit {
+  z-index: 10001;
+}
+
 .search-card {
   width: 702rpx;
   height: 288rpx;
diff --git a/yuyueMiniProgram/src/pages/review/index.vue b/yuyueMiniProgram/src/pages/review/index.vue
index 8bec390..0b12bae 100644
--- a/yuyueMiniProgram/src/pages/review/index.vue
+++ b/yuyueMiniProgram/src/pages/review/index.vue
@@ -22,7 +22,6 @@
   },
 })
 
-const router = useRouter()
 const sysInfo = uni.getSystemInfoSync()
 const statusBarHeight = sysInfo.statusBarHeight || 0
 const navBarHeight = 44
@@ -78,8 +77,27 @@
   orderUuid: '',
 })
 
+function backOrHome() {
+  const pages = getCurrentPages()
+  if (pages.length > 1) {
+    uni.navigateBack({
+      delta: 1,
+      fail: () => {
+        uni.switchTab({ url: '/pages/index/index' })
+      },
+    })
+    return
+  }
+  uni.switchTab({
+    url: '/pages/index/index',
+    fail: () => {
+      uni.reLaunch({ url: '/pages/index/index' })
+    },
+  })
+}
+
 function handleBack() {
-  router.back()
+  backOrHome()
 }
 
 function handleCancel() {
@@ -107,7 +125,7 @@
     await cancelMyAppointment(query.value.orderId, query.value.orderUuid)
     uni.showToast({ title: '已取消预约', icon: 'success' })
     setTimeout(() => {
-      router.back()
+      backOrHome()
     }, 600)
   }
   catch (error) {
@@ -132,7 +150,7 @@
     await deleteMyAppointment(query.value.orderId, query.value.orderUuid)
     uni.showToast({ title: '已删除记录', icon: 'success' })
     setTimeout(() => {
-      router.back()
+      backOrHome()
     }, 600)
   }
   catch (error) {
diff --git a/yuyueMiniProgram/src/pages/reviewDetail/index.vue b/yuyueMiniProgram/src/pages/reviewDetail/index.vue
index fc44f30..1896486 100644
--- a/yuyueMiniProgram/src/pages/reviewDetail/index.vue
+++ b/yuyueMiniProgram/src/pages/reviewDetail/index.vue
@@ -58,7 +58,6 @@
   },
 })
 
-const router = useRouter()
 const sysInfo = uni.getSystemInfoSync()
 const statusBarHeight = sysInfo.statusBarHeight || 0
 const navBarHeight = 44
@@ -109,7 +108,8 @@
 const selectedLocalUnits = ref<MiniLocalUnitItem[]>([])
 const unitPopupOffsetY = ref(0)
 const unitPickerBaseHeight = uni.upx2px(940)
-const unitPickerMinHeight = uni.upx2px(620)
+const unitPickerMinHeight = uni.upx2px(480)
+const unitKeyboardFallbackOffset = uni.upx2px(520)
 const unitPickerPanelStyle = computed(() => ({
   height: `${Math.max(unitPickerMinHeight, unitPickerBaseHeight - unitPopupOffsetY.value)}px`,
   transform: `translateY(-${unitPopupOffsetY.value}px)`,
@@ -117,7 +117,7 @@
 const handleUnitKeyboardHeightChange = (res: any) => {
   const height = Number(res?.height || 0)
   const maxOffset = Math.max(0, unitPickerBaseHeight - unitPickerMinHeight)
-  unitPopupOffsetY.value = height > 0 ? Math.min(height, maxOffset) : 0
+  unitPopupOffsetY.value = height > 0 ? Math.min(height + uni.upx2px(24), maxOffset) : unitPopupOffsetY.value
 }
 
 const appointmentIcons = {
@@ -230,8 +230,27 @@
 }>({})
 const showOtherLocalUnitInVisitInfo = computed(() => (detail.value?.localUnits?.length || 0) > 0)
 
+function backOrHome() {
+  const pages = getCurrentPages()
+  if (pages.length > 1) {
+    uni.navigateBack({
+      delta: 1,
+      fail: () => {
+        uni.switchTab({ url: '/pages/index/index' })
+      },
+    })
+    return
+  }
+  uni.switchTab({
+    url: '/pages/index/index',
+    fail: () => {
+      uni.reLaunch({ url: '/pages/index/index' })
+    },
+  })
+}
+
 function handleBack() {
-  router.back()
+  backOrHome()
 }
 
 function resolveReviewNode(detailValue: MiniApprovalDetailItem): ReviewNodeType {
@@ -595,6 +614,8 @@
     return
   }
   uni.onKeyboardHeightChange(handleUnitKeyboardHeightChange)
+  const maxOffset = Math.max(0, unitPickerBaseHeight - unitPickerMinHeight)
+  unitPopupOffsetY.value = Math.min(unitKeyboardFallbackOffset, maxOffset)
   if (unitInput.value) {
     showUnitDropdown.value = filteredUnits.value.length > 0
   }
@@ -795,7 +816,7 @@
     }
     uni.showToast({ title: approve ? '已通过' : '已驳回', icon: 'success' })
     setTimeout(() => {
-      router.back()
+      backOrHome()
     }, 1000)
   }
   catch (error) {
@@ -1345,7 +1366,7 @@
               <text class="text-[#333333] text-[28rpx] font-medium">单位</text>
               <text class="text-[#FF4D4F] text-[28rpx] ml-[4rpx]">*</text>
             </view>
-            <input v-model="unitInput" type="text" placeholder="请输入单位名称" placeholder-class="text-[#CCCCCC] text-[28rpx]" class="flex-1 text-[28rpx] text-[#333333] ml-[32rpx]" :disabled="isHandlerReadOnly()" :adjust-position="true" :cursor-spacing="120" @input="handleUnitInput" @focus="handleUnitFocus" @blur="handleUnitBlur" />
+            <input v-model="unitInput" type="text" placeholder="请输入单位名称" placeholder-class="text-[#CCCCCC] text-[28rpx]" class="flex-1 text-[28rpx] text-[#333333] ml-[32rpx]" :disabled="isHandlerReadOnly()" :adjust-position="false" :cursor-spacing="120" @input="handleUnitInput" @focus="handleUnitFocus" @blur="handleUnitBlur" />
             <view class="flex items-center h-full pl-[24rpx] active:opacity-80" :class="isHandlerReadOnly() ? 'opacity-60' : ''" @click="addUnit">
               <image src="/static/review/add.png" class="w-[28rpx] h-[28rpx] mr-[8rpx]" mode="aspectFit" />
               <text class="text-[#0068FF] text-[28rpx]">添加</text>
diff --git a/yuyueMiniProgram/src/pages/reviewList/index.vue b/yuyueMiniProgram/src/pages/reviewList/index.vue
index 54461e7..2d16654 100644
--- a/yuyueMiniProgram/src/pages/reviewList/index.vue
+++ b/yuyueMiniProgram/src/pages/reviewList/index.vue
@@ -29,7 +29,6 @@
   orderUuid: string
 }
 
-const router = useRouter()
 const sysInfo = uni.getSystemInfoSync()
 const statusBarHeight = sysInfo.statusBarHeight || 0
 const navBarHeight = 44
@@ -62,8 +61,27 @@
 const dateColumns = ref<string[][]>([[], [], []])
 const datePickerIndex = ref([0, 0, 0])
 
+function backOrHome() {
+  const pages = getCurrentPages()
+  if (pages.length > 1) {
+    uni.navigateBack({
+      delta: 1,
+      fail: () => {
+        uni.switchTab({ url: '/pages/index/index' })
+      },
+    })
+    return
+  }
+  uni.switchTab({
+    url: '/pages/index/index',
+    fail: () => {
+      uni.reLaunch({ url: '/pages/index/index' })
+    },
+  })
+}
+
 function handleBack() {
-  router.back()
+  backOrHome()
 }
 
 function getCurrentDate() {
@@ -94,6 +112,15 @@
     months.findIndex(item => item === selectedMonth.toString()),
     days.findIndex(item => item === selectedDay.toString()),
   ]
+}
+
+function formatVisitReasonDisplay(reasonText?: string | null, reasonCode?: string | null) {
+  const normalizedText = normalizeVisitReasonText(reasonText)
+  const code = (reasonCode || '').trim().toUpperCase()
+  if (code === 'OTHER' || normalizedText === '其他') {
+    return '其他'
+  }
+  return normalizedText || code || '-'
 }
 
 function handleDateChange(e: any) {
@@ -135,7 +162,7 @@
     nodeText: item.nodeName || '待审核',
     orderNo: item.orderNo,
     time: normalizeVisitTimeText(item.visitTimeText || `${item.visitStartDate || '-'}${item.visitEndDate && item.visitEndDate !== item.visitStartDate ? ` 至 ${item.visitEndDate}` : ''}`),
-    reasonText: normalizeVisitReasonText(item.visitReasonText) || item.visitReasonCode || '-',
+    reasonText: formatVisitReasonDisplay(item.visitReasonText, item.visitReasonCode),
     reasonOtherText: (item.visitReasonOther || '').trim() || '-',
     createTime: item.createTime,
     taskId: item.taskId,
@@ -174,7 +201,7 @@
     nodeText,
     orderNo: item.orderNo,
     time: normalizeVisitTimeText(item.visitTimeText),
-    reasonText: normalizeVisitReasonText(item.visitReasonText) || item.visitReasonCode || '-',
+    reasonText: formatVisitReasonDisplay(item.visitReasonText, item.visitReasonCode),
     reasonOtherText: (item.visitReasonOther || '').trim() || '-',
     createTime: item.createTime,
     orderId: item.id,
@@ -192,7 +219,7 @@
     nodeText: item.nodeText || (item.statusText || '已处理'),
     orderNo: item.orderNo,
     time: normalizeVisitTimeText(item.visitTimeText || '-'),
-    reasonText: normalizeVisitReasonText(item.visitReasonText) || item.visitReasonCode || '-',
+    reasonText: formatVisitReasonDisplay(item.visitReasonText, item.visitReasonCode),
     reasonOtherText: (item.visitReasonOther || '').trim() || '-',
     createTime: item.createTime,
     taskId: item.taskId || undefined,
diff --git a/yuyueMiniProgram/src/utils/visitReason.ts b/yuyueMiniProgram/src/utils/visitReason.ts
index 81ca65c..795f374 100644
--- a/yuyueMiniProgram/src/utils/visitReason.ts
+++ b/yuyueMiniProgram/src/utils/visitReason.ts
@@ -3,6 +3,8 @@
   if (!raw) {
     return ''
   }
+  if (raw.toUpperCase() === 'OTHER') {
+    return '其他'
+  }
   return raw.replace(/^其他[::]\s*/, '')
 }
-

--
Gitblit v1.7.1