- 重构首页布局,移除旧图表组件,添加流程表格和迷你日历 - 新增常用应用组件,支持收藏和管理常用功能 - 新增流程表格组件,展示我的流程和待办任务 - 新增迷你日历组件,支持不同类型日期标记 - 优化统计卡片组件,拆分客户和供应商统计 - 调整部分表格列名显示更准确
239 lines
6.2 KiB
Vue
239 lines
6.2 KiB
Vue
<template>
|
||
<!-- 外层容器:占用 30% 宽度,可根据需要自行调样式 -->
|
||
<div class="mini-calendar" style="">
|
||
<!-- 日历头部,显示“YYYY年M月” -->
|
||
<div class="calendar-header">
|
||
<div>个人日历</div>
|
||
<div>{{ currentMonthYear }}</div>
|
||
</div>
|
||
|
||
<!-- 日历主体:使用 table 简易排版,每周 7 列,只显示当前月的日期 -->
|
||
<table class="calendar-body">
|
||
<thead>
|
||
<tr>
|
||
<th v-for="(day, index) in weekDays" :key="index">{{ day }}</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="(row, rowIndex) in calendarRows" :key="rowIndex">
|
||
<td
|
||
v-for="(cell, cellIndex) in row"
|
||
:key="cellIndex"
|
||
:class="getDayClass(cell.type)"
|
||
>
|
||
<!-- 只显示数字,不含任何额外文本 -->
|
||
<span>{{ cell.dayNum }}</span>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<!-- legend 区域:展示不同 type 的色块与说明 -->
|
||
<div class="calendar-legend">
|
||
<div class="legend-item" v-for="legend in legends" :key="legend.type">
|
||
<span
|
||
class="color-box"
|
||
:style="{ backgroundColor: legend.color }"
|
||
></span>
|
||
<span class="legend-text">{{ legend.label }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: "MiniCalendar",
|
||
/**
|
||
* 父组件可以通过 :daysData 传入当前月的具体日期和 type。
|
||
* 示例:[{ date: '2025-03-01', type: 1 }, { date: '2025-03-02', type: 2 }, ...]
|
||
*/
|
||
props: {
|
||
daysData: {
|
||
type: Array,
|
||
default: () => []
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
// 星期栏
|
||
weekDays: ["日", "一", "二", "三", "四", "五", "六"],
|
||
// legend 配置:type对应的背景色 + 说明
|
||
legends: [
|
||
{ type: 1, label: "休息日", color: "#d3f6f3" },
|
||
{ type: 2, label: "节假日", color: "#ffe7ba" },
|
||
{ type: 3, label: "调休", color: "#ffdede" },
|
||
{ type: 4, label: "出差", color: "#fa18bc" },
|
||
{ type: 5, label: "请假", color: "#c4c4eb" }
|
||
]
|
||
};
|
||
},
|
||
computed: {
|
||
/**
|
||
* 当前日期对象(默认为今天,也可自行改成其它月份)
|
||
*/
|
||
currentDate() {
|
||
return new Date();
|
||
},
|
||
currentMonth() {
|
||
return this.currentDate.getMonth(); // 0-11
|
||
},
|
||
currentYear() {
|
||
return this.currentDate.getFullYear();
|
||
},
|
||
// 用于在日历头部显示“YYYY年M月”
|
||
currentMonthYear() {
|
||
return `${this.currentYear}年${this.currentMonth + 1}月`;
|
||
},
|
||
/**
|
||
* 生成一个二维数组,每一行代表一周,单元格中有 { dayNum, dateStr, type }。
|
||
* 只显示当月的日期,如果第一天不是周日,前面会插入空格。
|
||
*/
|
||
calendarRows() {
|
||
// 当前月1号
|
||
const firstDayOfMonth = new Date(this.currentYear, this.currentMonth, 1);
|
||
const firstDayIndex = firstDayOfMonth.getDay(); // 0=周日,1=周一, ...
|
||
|
||
// 本月总天数
|
||
const daysInMonth = new Date(this.currentYear, this.currentMonth + 1, 0).getDate();
|
||
|
||
// 准备一个空数组,往里放 dayNum 和 type
|
||
const cells = [];
|
||
// 1) 填充本月第一天前面的空白单元格
|
||
for (let i = 0; i < firstDayIndex; i++) {
|
||
cells.push({ dayNum: "", dateStr: "", type: null });
|
||
}
|
||
// 2) 填充本月每一天
|
||
for (let day = 1; day <= daysInMonth; day++) {
|
||
const dateObj = new Date(this.currentYear, this.currentMonth, day);
|
||
const dateStr = this.formatDate(dateObj); // YYYY-MM-DD
|
||
// 根据 daysData 查找 type
|
||
const dayType = this.findDayType(dateStr);
|
||
cells.push({
|
||
dayNum: day,
|
||
dateStr,
|
||
type: dayType
|
||
});
|
||
}
|
||
|
||
// 3) 将 cells 拆分成多行,每行7列
|
||
const rows = [];
|
||
for (let i = 0; i < cells.length; i += 7) {
|
||
rows.push(cells.slice(i, i + 7));
|
||
}
|
||
return rows;
|
||
}
|
||
},
|
||
methods: {
|
||
/**
|
||
* 格式化 Date => "YYYY-MM-DD"
|
||
*/
|
||
formatDate(d) {
|
||
const year = d.getFullYear();
|
||
const month = String(d.getMonth() + 1).padStart(2, "0");
|
||
const day = String(d.getDate()).padStart(2, "0");
|
||
return `${year}-${month}-${day}`;
|
||
},
|
||
/**
|
||
* 在 daysData 中找对应日期的 type,找不到就默认为 0(工作日)
|
||
*/
|
||
findDayType(dateStr) {
|
||
const item = this.daysData.find((day) => day.date === dateStr);
|
||
return item ? item.type : 0; // 默认工作日(0)
|
||
},
|
||
/**
|
||
* 返回一个 class 用于设置对应背景色
|
||
*/
|
||
getDayClass(type) {
|
||
switch (type) {
|
||
case 0: return "type-workday"; // 工作日
|
||
case 1: return "type-rest"; // 休息日
|
||
case 2: return "type-holiday"; // 节假日
|
||
case 3: return "type-adjust"; // 调休
|
||
case 4: return "type-trip"; // 出差
|
||
case 5: return "type-leave"; // 请假
|
||
default: return "";
|
||
}
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.mini-calendar {
|
||
border: 1px solid #ccc;
|
||
padding: 10px;
|
||
background-color: white;
|
||
box-sizing: border-box;
|
||
/* 若需要更细节的布局控制,可以加上 float 或 display 属性,比如 float: left; */
|
||
}
|
||
|
||
/* 日历头部 */
|
||
.calendar-header {
|
||
text-align: center;
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
/* 日历主体样式 */
|
||
.calendar-body {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.calendar-body th,
|
||
.calendar-body td {
|
||
width: 14.28%; /* 7天 */
|
||
height: 40px;
|
||
text-align: center;
|
||
vertical-align: middle;
|
||
}
|
||
|
||
/* 不同 type 的背景色 */
|
||
.type-workday {
|
||
background-color: transparent;
|
||
}
|
||
.type-rest {
|
||
background-color: #d3f6f3;
|
||
}
|
||
.type-holiday {
|
||
background-color: #ffe7ba;
|
||
}
|
||
.type-adjust {
|
||
background-color: #ffdede;
|
||
}
|
||
.type-trip {
|
||
background-color: #c6ebf5;
|
||
}
|
||
.type-leave {
|
||
background-color: #c4c4eb;
|
||
}
|
||
|
||
/* legend 部分:展示各类型色块和说明 */
|
||
.calendar-legend {
|
||
margin-top: 12px;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 10px;
|
||
}
|
||
|
||
.legend-item {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.color-box {
|
||
display: inline-block;
|
||
width: 14px;
|
||
height: 14px;
|
||
margin-right: 4px;
|
||
|
||
}
|
||
|
||
.legend-text {
|
||
font-size: 12px;
|
||
}
|
||
</style>
|