refactor(Calender): migrate styling to tailwind, remove old assets

remove deprecated SCSS style sheet and chinese holiday image, rewrite all component styles using tailwind utility classes, add helper functions for dynamic styling and price formatting
This commit is contained in:
duanshuwen
2026-05-29 21:44:44 +08:00
parent 6fefcd3512
commit 6ed407889a
3 changed files with 57 additions and 213 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -22,22 +22,26 @@
</div>
<!-- 日历主体区域 -->
<div class="calendar-body">
<div
class="pt-2 px-3 pb-3 max-h-[calc(80vh-140px)] overflow-y-auto [-webkit-overflow-scrolling:touch] scrollbar-none [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden">
<!-- 全年月份显示区域 -->
<div class="flex flex-col gap-[32px]">
<div class="flex flex-col" v-for="monthData in yearMonthsGrid" :key="monthData.key">
<span class="month-title">{{ monthData.title }}</span>
<span class="text-[18px] font-semibold text-[#262626] text-center mb-4 mt-2 leading-[1.4]">{{
monthData.title }}</span>
<div class="grid grid-cols-7 gap-[4px]">
<div class="date-cell" v-for="(dateInfo, index) in monthData.grid" :key="index"
:class="getDateCellClass(dateInfo)" @tap="handleDateClick(dateInfo)">
<div v-for="(dateInfo, index) in monthData.grid" :key="index" :class="getDateCellClass(dateInfo)"
@tap="handleDateClick(dateInfo)">
<template v-if="dateInfo">
<span class="date-label" v-if="dateInfo.label">
<span v-if="dateInfo.label"
class="text-[10px] px-1 py-[1px] rounded-[2px] whitespace-nowrap font-medium text-center min-h-[12px]"
:class="getDateLabelClass(dateInfo)">
{{ dateInfo.label }}
</span>
<span class="date-number">{{ dateInfo.day }}</span>
<span class="date-price" v-if="
dateInfo.price !== null && dateInfo.price !== undefined
">¥{{ dateInfo.price }}</span>
<span class="text-[16px] font-medium leading-none flex-1 flex items-center justify-center"
:class="getDateNumberClass(dateInfo)">{{ dateInfo.day }}</span>
<span class="text-[12px] leading-none font-normal text-center min-h-[14px]"
:class="getDatePriceClass(dateInfo)">{{ formatPrice(dateInfo.price) }}</span>
</template>
</div>
</div>
@@ -323,23 +327,54 @@ const getDateLabel = (dateStr) => {
// 获取日期格子样式类
const getDateCellClass = (dateInfo) => {
if (!dateInfo) return "bg-transparent cursor-default";
if (!dateInfo) return "w-[40px] h-[40px] bg-transparent cursor-default";
const classes = ["date-cell-content"];
const base =
"relative w-[40px] h-[40px] flex flex-col items-center justify-between p-[2px] rounded-[6px] transition-all duration-200 ease-in-out cursor-pointer bg-white border border-transparent hover:bg-[#f5f5f5] active:scale-[0.95]";
if (dateInfo.disabled) classes.push("date-cell-disabled");
if (dateInfo.selected) classes.push("date-cell-selected");
if (dateInfo.inRange) classes.push("date-cell-in-range");
// 标注无价格但可选的日期(用于视觉区分)
if (
dateInfo.price === null ||
dateInfo.price === undefined ||
dateInfo.price === "-"
) {
classes.push("date-cell-no-price");
if (dateInfo.disabled) {
return `${base} bg-[#f5f5f5] text-[#bfbfbf] cursor-not-allowed hover:bg-[#f5f5f5] active:scale-100`;
}
return classes.join(" ");
if (dateInfo.selected) {
return `${base} bg-[#1890ff] border-[#1890ff] hover:bg-[#1890ff]`;
}
if (dateInfo.inRange) {
return `${base} bg-[#e6f7ff] border-[#e6f7ff]`;
}
return base;
};
const formatPrice = (price) => {
if (price === null || price === undefined || price === "-") return "";
return `¥${price}`;
};
const getDateNumberClass = (dateInfo) => {
if (dateInfo.disabled) return "text-[#bfbfbf]";
if (dateInfo.selected) return "text-white";
if (dateInfo.inRange) return "text-[#1890ff]";
const noPrice = dateInfo.price === null || dateInfo.price === undefined || dateInfo.price === "-";
if (noPrice) return "text-[#262626] opacity-90";
return "text-[#262626]";
};
const getDatePriceClass = (dateInfo) => {
const noPrice = dateInfo.price === null || dateInfo.price === undefined || dateInfo.price === "-";
if (dateInfo.disabled) return "text-[#bfbfbf]";
if (dateInfo.selected) return "text-white";
if (dateInfo.inRange) return "text-[#1890ff]";
if (noPrice) return "text-[#bfbfbf] italic";
return "text-[#8c8c8c]";
};
const getDateLabelClass = (dateInfo) => {
if (dateInfo.selected) return "text-white";
return "text-[#1890ff]";
};
// 处理日期点击
@@ -574,8 +609,3 @@ onBeforeUnmount(() => {
}
});
</script>
<style lang="scss" scoped>
// 引入样式文件
@import "./styles/index.scss";
</style>

View File

@@ -1,186 +0,0 @@
// 颜色系统
$primary-color: #1890ff;
$primary-light: #e6f7ff;
$primary-dark: #1890ff;
// 中性色
$text-primary: #262626;
$text-secondary: #8c8c8c;
$text-disabled: #bfbfbf;
$background-white: #ffffff;
$background-gray: #f5f5f5;
$border-color: #d9d9d9;
// 状态色
$success-color: #52c41a;
$warning-color: #faad14;
$error-color: #ff4d4f;
// 尺寸规范
$modal-max-height: 80vh;
$modal-border-radius: 12px;
$modal-padding: 12px;
// 日期格子尺寸
$date-cell-size: 40px;
$date-cell-gap: 4px;
$date-cell-border-radius: 6px;
// 字体大小
$font-size-title: 18px;
$font-size-subtitle: 14px;
$font-size-date: 16px;
$font-size-price: 12px;
$font-size-label: 10px;
// 日历主体区域
.calendar-body {
padding: 8px $modal-padding $modal-padding;
max-height: calc(#{$modal-max-height} - 140px);
overflow-y: auto;
-webkit-overflow-scrolling: touch;
&::-webkit-scrollbar {
display: none;
}
}
.month-title {
font-size: $font-size-title;
font-weight: 600;
color: $text-primary;
text-align: center;
margin-bottom: 16px;
margin-top: 8px;
line-height: 1.4;
}
// 日期格子基础样式
.date-cell {
position: relative;
width: $date-cell-size;
height: $date-cell-size;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 2px;
border-radius: $date-cell-border-radius;
transition: all 0.2s ease;
cursor: pointer;
}
// 有内容的格子
.date-cell-content {
background-color: $background-white;
border: 1px solid transparent;
&:hover {
background-color: $background-gray;
}
&:active {
transform: scale(0.95);
}
}
// 禁用状态
.date-cell-disabled {
background-color: $background-gray !important;
color: $text-disabled !important;
cursor: not-allowed !important;
.date-number,
.date-price {
color: $text-disabled !important;
}
&:hover {
background-color: $background-gray !important;
transform: none !important;
}
}
// 选中状态
.date-cell-selected {
background-color: $primary-color !important;
border-color: $primary-color !important;
.date-number,
.date-price,
.date-label {
color: $background-white !important;
}
&:hover {
background-color: $primary-dark !important;
}
}
// 范围内状态
.date-cell-in-range {
background-color: $primary-light !important;
border-color: $primary-light !important;
.date-number {
color: $primary-color !important;
}
.date-price {
color: $primary-dark !important;
}
}
// 日期数字
.date-number {
font-size: $font-size-date;
font-weight: 500;
color: $text-primary;
line-height: 1;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
// 价格文字
.date-price {
font-size: $font-size-price;
color: $text-secondary;
line-height: 1;
font-weight: 400;
text-align: center;
min-height: 14px;
}
// 无价格占位样式
.date-cell-no-price {
.date-number {
color: $text-primary;
opacity: 0.9;
}
.date-price {
color: $text-disabled;
font-style: italic;
}
.date-price--empty {
color: $text-disabled;
font-style: normal;
}
}
// 自定义标签
.date-label {
font-size: $font-size-label;
color: $primary-color;
padding: 1px 4px;
border-radius: 2px;
line-height: 1;
white-space: nowrap;
font-weight: 500;
text-align: center;
min-height: 12px;
}