在开发的时候,我们常常遇到日期范围选择根据指定开始日期限定结束日期的可选范围的情况。比如我们选择的开始日期为2022-04-01,则结束日期必须是2022-05-01之前,并且不能超过当前日期。
前端框架:SCUI (vue3 + element-plus)
开源地址:SCUI: 一款开箱即用、高可配、高性能、风格精致、代码优雅的基于Vue3和elementPlus的WebUI前端框架,让前端开发更快乐。
使用的控件:日期范围选择控件 -> el-date-picker
el-date-picker需要使用到的属性和事件,如下:
属性:disabledDate
事件:calendar-change 。主要是为记录选择的开始日期。
日期范围控件代码如下:
<el-date-picker
v-model="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="dateChange"
:disabledDate="disabledDateFun"
@calendar-change="calendarChange"
></el-date-picker>
javascript代码如下:
<script>
export default {
name: "systemlog",
components: { },
data() {
return {
startDate: null,
date: []
};
},
methods: {
dateChange(dates) {
this.date = dates
if (dates === null || dates.length === 0) {
this.startDate = null
}
},
calendarChange(dates) {
// 记录选择的开始日期,方便后面根据开始日期限定结束日期
let hasSelectDate = dates !== null && dates.length > 0
this.startDate = hasSelectDate ? dates[0] : null
},
disabledDateFun(time) {
// 8.64e7就是一天的时间戳 24*60*60*1000
// 根据选择的开始日期,日期范围限定在30天之内
if (this.startDate !== null) {
return (
time.getTime() < this.startDate.getTime() ||
time.getTime() >= new Date().getTime() ||
time.getTime() > this.startDate.getTime() + 30 * 8.64e7
);
}
// 默认只能选择今天以及今天之前的日期
return time.getTime() >= new Date().getTime();
}
},
};
</script>
完整页面代码如下:
<template>
<el-container>
<el-aside width="220px">
<el-tree ref="category" class="menu" node-key="label" :data="category" :default-expanded-keys="['系统日志']"
current-node-key="系统日志" :highlight-current="true" :expand-on-click-node="false">
</el-tree>
</el-aside>
<el-container>
<el-main class="nopadding">
<el-container>
<el-header>
<div class="left-panel">
<el-date-picker v-model="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
@change="dateChange" :disabledDate="disabledDateFun" @calendar-change="calendarChange">
</el-date-picker>
</div>
<div class="right-panel"></div>
</el-header>
<el-header style="height: 150px">
<scEcharts height="100%" :option="logsChartOption"></scEcharts>
</el-header>
<el-main class="nopadding">
<scTable ref="table" :apiObj="apiObj" stripe highlightCurrentRow @row-click="rowClick">
<el-table-column label="级别" prop="level" width="60">
<template #default="scope">
<el-icon v-if="scope.row.level == 'error'" style="color: #f56c6c">
<el-icon-circle-close-filled />
</el-icon>
<el-icon v-if="scope.row.level == 'warn'" style="color: #e6a23c">
<el-icon-warning-filled />
</el-icon>
<el-icon v-if="scope.row.level == 'info'" style="color: #409eff">
<el-icon-info-filled />
</el-icon>
</template>
</el-table-column>
<el-table-column label="ID" prop="id" width="280"></el-table-column>
<el-table-column label="请求接口" prop="url"></el-table-column>
<el-table-column label="客户端IP" prop="ip" width="150"></el-table-column>
<el-table-column label="用户" prop="userName" width="150"></el-table-column>
<el-table-column label="日志时间" prop="createTime" width="170"></el-table-column>
</scTable>
</el-main>
</el-container>
</el-main>
</el-container>
</el-container>
<el-drawer v-model="infoDrawer" title="日志详情" :size="600" destroy-on-close>
<info ref="info"></info>
</el-drawer>
</template>
<script>
import info from "./info";
import scEcharts from "@/components/scEcharts";
export default {
name: "systemlog",
components: {
info,
scEcharts,
},
data() {
return {
infoDrawer: false,
logsChartOption: {},
category: [
{
label: "系统日志",
children: [
{ label: "debug" },
{ label: "info" },
{ label: "warn" },
{ label: "error" },
{ label: "fatal" },
],
},
{
label: "应用日志",
children: [{ label: "WebApi" }, { label: "DataBase" }],
},
],
startDate: null,
date: [],
apiObj: this.$API.system.log.list,
search: {
keyword: '',
},
};
},
async mounted() {
await this.getStatisticDatas();
},
methods: {
upsearch() { },
rowClick(row) {
this.infoDrawer = true;
this.$nextTick(() => {
this.$refs.info.setData(row);
});
},
async dateChange(dates) {
this.date = dates
if (dates === null || dates.length === 0) {
this.startDate = null
}
await this.getStatisticDatas()
},
calendarChange(dates) {
// 记录选择的开始日期,方便后面根据开始日期限定结束日期
let hasSelectDate = dates !== null && dates.length > 0
this.startDate = hasSelectDate ? dates[0] : null
},
disabledDateFun(time) {
// 8.64e7就是一天的时间戳 24*60*60*1000
// 根据选择的开始日期,日期范围限定在30天之内
if (this.startDate !== null) {
return (
time.getTime() < this.startDate.getTime() ||
time.getTime() >= new Date().getTime() ||
time.getTime() > this.startDate.getTime() + 30 * 8.64e7
);
}
// 默认只能选择今天以及今天之前的日期
return time.getTime() > new Date().getTime();
},
//获取统计数据
async getStatisticDatas() {
this.loading = true
let reqData = {
start: null,
end: null,
}
if (this.date !== null && this.date.length === 2) {
reqData.start = this.date[0]
reqData.end = this.date[1]
}
let res = await this.$API.system.log.statistic.get(reqData);
if (res.code === 200) {
this.logsChartOption = {
color: ["#e6a23c", "#409eff", "#f56c6c"],
grid: {
top: "0px",
left: "10px",
right: "3%",
bottom: "0px",
},
tooltip: {
trigger: "axis",
},
xAxis: {
type: "category",
boundaryGap: false,
data: res.data.dateDatas,
},
yAxis: {
show: false,
type: "value",
},
series: [
{
data: res.data.numberDatas,
type: "bar",
stack: "log",
barWidth: "15px",
},
],
};
}
},
},
};
</script>
最后实现的效果: