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