feat: 增加时间处理

master
xjs 2026-08-06 13:59:08 +08:00
parent 5033284258
commit 861bdb5195
3 changed files with 75 additions and 95 deletions

View File

@ -1,10 +1,13 @@
// 通用格式化 / 校验纯函数(无状态,供 composable 与页面复用)。
/** Date → `YYYY-MM-DD` */
export const formatDate = (date: Date): string => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
export const formatDate = (date: Date | string): string => {
const transformedDate = typeof date === "string" ? new Date(date) : date;
if (Number.isNaN(transformedDate.getTime())) return "";
const year = transformedDate.getFullYear();
const month = String(transformedDate.getMonth() + 1).padStart(2, "0");
const day = String(transformedDate.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
};

View File

@ -32,7 +32,7 @@
<div class="flex items-center gap-8">
<span class="min-w-0 truncate text-[4rem] font-600 leading-none text-[#000]">{{ item.studentName || "-" }}</span>
<span class="shrink-0 rounded-2 bg-[#E7F2FF] px-4 py-3 text-[2.5rem] leading-none text-[#1580FF]">
签到:{{ formatCheckinTime(item.checkinTime) }}
签到:{{ formatDate(item.checkinTime) }}
</span>
<span
v-if="activeTab === 'available' && item.waitingMinutes > 0"
@ -90,6 +90,7 @@
import "vant/es/tabs/style";
import type { ReceptionTaskDTO } from "@/api/reception";
import { useReceptionTasks, type ReceptionTaskTab } from "@/composables/useReceptionTasks";
import { formatDate } from "@/utils/format";
const tabs: ReadonlyArray<{ label: string; value: ReceptionTaskTab }> = [
{ label: "待接待", value: "available" },
@ -99,10 +100,7 @@
const router = useRouter();
const { activeTab, tasks, loading, finished, error, claimingTaskId, showEmpty, emptyText, loadNextPage, claimTask } = useReceptionTasks(20);
const formatCheckinTime = (value: string): string => {
const normalized = value.replace("T", " ");
return normalized.length >= 16 ? normalized.slice(5, 16) : normalized || "-";
};
const formatDateOnly = (value: string): string => value.split(/[T ]/, 1)[0] || "-";

View File

@ -1,49 +1,27 @@
<template>
<main class="invitation-data min-h-full bg-[#F5F5F5]">
<div class="sticky top-0 z-10 bg-white">
<VanSearch
v-model="searchKeyword"
class="invitation-data__search"
background="#fff"
placeholder="请输入学生姓名"
autocomplete="off"
enterkeyhint="search"
clearable
@search="submitSearch"
@clear="clearSearch" />
<VanSearch v-model="searchKeyword" class="invitation-data__search" background="#fff" placeholder="请输入学生姓名"
autocomplete="off" enterkeyhint="search" clearable @search="submitSearch" @clear="clearSearch" />
<VanTabs
v-model:active="activeFilter"
class="invitation-data__tabs"
line-width="24px"
line-height="2px"
:swipe-threshold="6"
color="#1580ff"
title-active-color="#000"
title-inactive-color="#999">
<VanTabs v-model:active="activeFilter" class="invitation-data__tabs" line-width="24px" line-height="2px"
:swipe-threshold="6" color="#1580ff" title-active-color="#000" title-inactive-color="#999">
<VanTab v-for="tab in tabs" :key="tab.value" :name="tab.value" :title="tab.label" />
</VanTabs>
</div>
<VanList
v-model:loading="loading"
:finished="finished"
:error="error"
:finished-text="records.length ? '没有更多了' : ''"
error-text="加载失败,点击重试"
@load="loadNextPage"
<VanList v-model:loading="loading" :finished="finished" :error="error"
:finished-text="records.length ? '没有更多了' : ''" error-text="加载失败,点击重试" @load="loadNextPage"
@update:error="(value: boolean) => (error = value)">
<VanEmpty
v-if="showEmpty"
class="my-auto mt-40"
image="https://lw-zk.oss-cn-hangzhou.aliyuncs.com/inviteReception/icon_zanwu.png"
:image-size="[186, 144]"
<VanEmpty v-if="showEmpty" class="my-auto mt-40"
image="https://lw-zk.oss-cn-hangzhou.aliyuncs.com/inviteReception/icon_zanwu.png" :image-size="[186, 144]"
description="暂无数据" />
<div v-else class="flex flex-col gap-12 px-15 py-15">
<article v-for="record in records" :key="record.id" class="rounded-8 bg-white p-15">
<div class="flex items-center justify-between gap-10">
<h2 class="min-w-0 flex-1 truncate text-[4rem] font-600 leading-none text-[#000]">{{ record.studentName }}</h2>
<h2 class="min-w-0 flex-1 truncate text-[4rem] font-600 leading-none text-[#000]">{{ record.studentName }}
</h2>
<span class="shrink-0 text-[3.25rem] leading-none" :style="{ color: getStatusColor(record.statusName) }">
{{ record.statusName }}
</span>
@ -52,7 +30,7 @@
<div class="mt-15 flex flex-col gap-8 text-[3.25rem] text-[#333]">
<p class="m-0">
<span class="text-[#666]">预约:</span>
{{ record.visitDate }}
{{ formatDate(record.visitDate) }}
</p>
<p v-if="record.graduateSchoolName" class="m-0">
<span class="text-[#666]">院校:</span>
@ -70,70 +48,71 @@
</template>
<script setup lang="ts">
import { Empty as VanEmpty, List as VanList, Search as VanSearch, Tab as VanTab, Tabs as VanTabs } from "vant";
import "vant/es/empty/style";
import "vant/es/list/style";
import "vant/es/search/style";
import "vant/es/tab/style";
import "vant/es/tabs/style";
import type { InvitationPageFilter } from "@/api/admission";
import { useTeacherInvitationData } from "@/composables/useTeacherInvitationData";
import { Empty as VanEmpty, List as VanList, Search as VanSearch, Tab as VanTab, Tabs as VanTabs } from "vant";
import "vant/es/empty/style";
import "vant/es/list/style";
import "vant/es/search/style";
import "vant/es/tab/style";
import "vant/es/tabs/style";
import type { InvitationPageFilter } from "@/api/admission";
import { useTeacherInvitationData } from "@/composables/useTeacherInvitationData";
import { formatDate } from "@/utils/format"
const tabs: ReadonlyArray<{ label: string; value: InvitationPageFilter }> = [
{ label: "全部邀约", value: "all" },
{ label: "待到访", value: "pending" },
{ label: "已到访", value: "arrived" },
{ label: "未到访", value: "noShow" },
{ label: "已缴费", value: "paid" },
];
const tabs: ReadonlyArray<{ label: string; value: InvitationPageFilter }> = [
{ label: "全部邀约", value: "all" },
{ label: "待到访", value: "pending" },
{ label: "已到访", value: "arrived" },
{ label: "未到访", value: "noShow" },
{ label: "已缴费", value: "paid" },
];
const { searchKeyword, activeFilter, records, loading, finished, error, showEmpty, loadNextPage, submitSearch, clearSearch } = useTeacherInvitationData(20);
const { searchKeyword, activeFilter, records, loading, finished, error, showEmpty, loadNextPage, submitSearch, clearSearch } = useTeacherInvitationData(20);
const statusColors: Readonly<Record<string, string>> = {
待到访: "#06C764",
已到访: "#1580FF",
已完成: "#1580FF",
未到访: "#969696",
};
const statusColors: Readonly<Record<string, string>> = {
待到访: "#06C764",
已到访: "#1580FF",
已完成: "#1580FF",
未到访: "#969696",
};
const getStatusColor = (statusName: string): string => statusColors[statusName] ?? "#666666";
const getStatusColor = (statusName: string): string => statusColors[statusName] ?? "#666666";
</script>
<style scoped>
:global(.invitation-data) {
--van-search-padding: 4px 15px 0;
--van-search-content-background: #f3f4f8;
--van-search-input-height: 38px;
--van-tab-font-size: 15px;
}
:global(.invitation-data) {
--van-search-padding: 4px 15px 0;
--van-search-content-background: #f3f4f8;
--van-search-input-height: 38px;
--van-tab-font-size: 15px;
}
:global(.invitation-data .van-search__content) {
border-radius: 81px;
--van-field-placeholder-text-color: #c0c4cc;
--van-padding-sm: 15px;
}
:global(.invitation-data .van-search__content) {
border-radius: 81px;
--van-field-placeholder-text-color: #c0c4cc;
--van-padding-sm: 15px;
}
:global(.invitation-data .van-field__left-icon) {
--van-field-icon-size: 14px;
--van-padding-base: 5px;
line-height: 1;
}
:global(.invitation-data .van-field__left-icon) {
--van-field-icon-size: 14px;
--van-padding-base: 5px;
line-height: 1;
}
:global(.invitation-data .van-tabs--line .van-tabs__wrap) {
--van-tabs-line-height: 38px;
}
:global(.invitation-data .van-tabs--line .van-tabs__wrap) {
--van-tabs-line-height: 38px;
}
:deep(.van-tab) {
--van-tab-font-size: 15px;
--van-font-bold: 400;
}
:deep(.van-tab) {
--van-tab-font-size: 15px;
--van-font-bold: 400;
}
:deep(.van-tab--active) {
--van-tab-font-size: 16px;
--van-font-bold: 500;
}
:deep(.van-tab--active) {
--van-tab-font-size: 16px;
--van-font-bold: 500;
}
:deep(.van-empty) {
--van-empty-padding: 50% 0;
}
:deep(.van-empty) {
--van-empty-padding: 50% 0;
}
</style>