当前位置: 首页 > news >正文

纯前端实现项目过期

项目过期逻辑

/*** 项目有效期检查工具* 设置项目在指定日期后无法访问*/// 设置过期日期为2024年10月30日
const EXPIRY_DATE = new Date('2025-10-30 23:59:59')/*** 检查项目是否已过期* @returns {boolean} true表示已过期,false表示未过期*/
export function isExpired(): boolean {const currentDate = new Date()return currentDate > EXPIRY_DATE
}/*** 获取过期日期* @returns {Date} 过期日期*/
export function getExpiryDate(): Date {return EXPIRY_DATE
}/*** 获取剩余天数* @returns {number} 剩余天数,如果已过期则返回负数*/
export function getRemainingDays(): number {const currentDate = new Date()const timeDiff = EXPIRY_DATE.getTime() - currentDate.getTime()return Math.ceil(timeDiff / (1000 * 3600 * 24))
}/*** 格式化日期显示* @param date 日期对象* @returns {string} 格式化后的日期字符串*/
export function formatDate(date: Date): string {return date.toLocaleDateString('zh-CN', {year: 'numeric',month: '2-digit',day: '2-digit',})
}

项目过期页面

<template><div class="expired-container"><div class="expired-content"><div class="expired-icon"><font-awesome-icon :icon="['fas', 'triangle-exclamation']" class="fa-icon fa-warning" /></div><h1 class="expired-title">项目已过期</h1><div class="expired-message"><p>很抱歉,该项目的使用期限已到期。</p><p>过期时间:{{ formatDate(expiryDate) }}</p><p>如需继续使用,请联系管理员。</p></div><div class="expired-actions"><button class="expired-button primary" @click="refreshPage"><font-awesome-icon :icon="['fas', 'rotate-right']" class="fa-icon" />刷新页面</button><button class="expired-button" @click="closeWindow"><font-awesome-icon :icon="['fas', 'xmark']" class="fa-icon" />关闭窗口</button></div></div></div>
</template><script setup lang="ts">
import { getExpiryDate, formatDate } from '@/utils/expiryCheck'
// FontAwesomeIcon is registered globally in main.ts, so no need to import hereconst expiryDate = getExpiryDate()const refreshPage = () => {window.location.reload()
}const closeWindow = () => {window.close()// 如果无法关闭窗口,则显示提示setTimeout(() => {if (!window.closed) {alert('请手动关闭浏览器窗口')}}, 400);
}
</script><style scoped>
.expired-container {position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);display: flex;justify-content: center;align-items: center;z-index: 9999;
}.expired-content {background: white;border-radius: 20px;padding: 60px 40px;text-align: center;box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);max-width: 500px;width: 90%;
}.expired-icon {margin-bottom: 30px;
}
.fa-icon {font-size: 80px;color: #f56c6c;
}
.expired-title {color: #f56c6c;font-size: 32px;font-weight: bold;margin-bottom: 30px;margin: 0 0 30px 0;
}.expired-message {margin-bottom: 40px;line-height: 1.8;
}.expired-message p {margin: 10px 0;color: #666;font-size: 16px;
}.expired-actions {display: flex;gap: 20px;justify-content: center;flex-wrap: wrap;
}.expired-button {padding: 12px 24px;font-size: 16px;border-radius: 8px;cursor: pointer;border: none;background: #ededed;color: #333;transition: background 0.2s, color 0.2s;display: flex;align-items: center;gap: 10px;font-weight: 500;
}
.expired-button.primary {background: #165dff;color: #fff;
}
.expired-button.primary:hover {background: #2874fa;
}
.expired-button:not(.primary):hover {background: #eee;color: #f56c6c;
}@media (max-width: 768px) {.expired-content {padding: 40px 20px;margin: 20px;}.expired-title {font-size: 24px;}.expired-actions {flex-direction: column;align-items: center;}.expired-button {width: 200px;justify-content: center;}
}
</style>

使用地点 main.ts

import { createApp } from 'vue'
import { createPinia } from 'pinia'/* import font awesome icon component */
import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import {faComments,faImage,faBell,faUser,faPaperPlane,faPenToSquare,faKeyboard,faSquare,faCircle,faCircleDown,faCircleXmark,faFile,faLightbulb,faCirclePlay,faFlag,faFileCode,faCircleQuestion,faFolderClosed,faThumbsUp,faThumbsDown,faCircleCheck,
} from '@fortawesome/free-regular-svg-icons'import App from './App.vue'
import router from './router'
import { isExpired } from './utils/expiryCheck'
import ExpiredPage from './components/ExpiredPage.vue'
/* add icons to the library */
library.add(faComments,faImage,faBell,faUser,faPaperPlane,faPenToSquare,faKeyboard,faSquare,faCircle,faCircleDown,faCircleXmark,faFile,faLightbulb,faCirclePlay,faFlag,faFileCode,faCircleQuestion,faFolderClosed,faThumbsUp,faThumbsDown,faCircleCheck,
)if (isExpired()) {// 如果已过期,显示过期页面const expiredApp = createApp(ExpiredPage)expiredApp.mount('#app')
} else {const app = createApp(App)app.component('FontAwesomeIcon', FontAwesomeIcon)app.use(createPinia())app.use(router)app.mount('#app')
}
http://www.hskmm.com/?act=detail&tid=28538

相关文章:

  • 基于形态学的权重自适应图像去噪的MATLAB实现
  • 2025 年油水分离器 / 气液分离器 / 液固分离器 / 水分离器 / 油分离器厂家推荐:西安同大技术沉淀与流体净化解决方案解析
  • 2025 年过滤器厂家最新推荐排行榜:聚焦烛式 / 金属 / 非金属 / 化工 / 精密过滤器等多类型设备,精选优质品牌助企业高效选型液固/高效/气固/催化剂过滤器厂家推荐
  • OOP-实验1
  • 2025 年立式/立式全钢板/青黄储/液压打包机厂家推荐榜:聚焦实用需求,精选高适配设备助力企业降本增效
  • DNS服务
  • 308、清平调三首
  • 2025管件厂家最新推荐榜:高品质管件与卓越工艺口碑之选
  • 2025不锈钢管件厂家推荐榜:技术实力与诚信口碑双重保障
  • 哪款剪贴板增强软件最好用?有什么剪贴板内容大全值得分享?多款剪切板历史免费版管理工具推荐
  • EndNote文献管理工具!研究生必备软件!超详细下载安装教程(附下载地址)
  • 鸿蒙应用开发从入门到实战(十九):样式复用案例
  • 2025 年最新推荐冰醋酸厂商综合实力排行榜: 厂商定制服务与仓储能力深度解析昆山/太仓/吴江区/吴中区/相城区/姑苏区冰醋酸厂商推荐
  • 中电金信:“源启大模型文本生成算法”成功通过互联网信息服务算法备案
  • 基于MATLAB的禁忌搜索算法解决物流网络枢纽选址问题
  • springboot 项目部署是tomcat么
  • 2025 年最新推荐恒温恒湿试验箱优质厂家榜单:涵盖立式/可程式/小型等多类型设备的精选企业推荐可程式/小型/防爆高低温试/高温高湿试验箱/低温低湿试验箱厂家推荐
  • CSS开发工具推荐与实战经验,让样式开发更高效、更精准
  • 详细揭秘:详细揭秘:集合划分容斥的容斥系数
  • 2025 年冷热冲击试验箱生产厂家最新推荐榜:聚焦三箱 / 两箱 / 吊篮式 / 小型 / 风冷式 / 可程式设备,精选优质企业助力高效选购
  • 学好微积分特别是偏微分方程的数值求解对于学习CFD的好处?
  • 基于Logistic映射与Chen超混沌系统结合DNA分块编解码的图像加密技术
  • 批量文件重命名工具(带撤销功能)
  • Trae与Gitee MCP强强联合:AI编程生态迎来重大升级
  • Web前端入门第 88 问:引入 JavaScript 的 script 标签究竟有多少用法?
  • 我如何控制新增的节点是 leader 还是follower呢?
  • Nuxt3项目Warn:Browserslist: browsers data (caniuse-lite) is 6 months old.
  • 2025 年全屋定制 / 高端 / 装修收纳设计 / 不锈钢橱柜 / 别墅 / 大平层装修公司推荐:苏州伍德家居与百能家居的优质定制解决方案解析
  • 1_数组
  • SAS重要证明结论