在开发的时候,我们常常遇到日期范围选择根据指定开始日期限定结束日期的可选范围的情况。比如我们选择的开始日期为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>

最后实现的效果:

GitHub 加速计划 / el / element-plus
23.88 K
15.38 K
下载
element-plus/element-plus: Element Plus 是一个基于 Vue 3 的组件库,提供了丰富且易于使用的 UI 组件,用于快速搭建企业级桌面和移动端的前端应用。
最近提交(Master分支:1 个月前 )
c1863f50 2 个月前
b55163fd 2 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐