docs(website): 添加简记memo产品原型和UI设计规范文档

- 新增「简记memo」一体化小程序产品原型设计文档
- 新增简记memo完整版UI视觉设计规范和界面细节
- 添加IDEA项目配置文件.gitignore
- 创建404页面HTML文件,包含响应式布局和错误提示
- 添加关于页面HTML文件,展示品牌介绍和团队信息
- 实现AES加解密工具函数,支持请求体加密
- 添加用户协议页面基础框架
This commit is contained in:
sunct
2026-07-31 14:12:32 +08:00
commit 3c3bf53ae4
115 changed files with 21304 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
// static/js/request-guard.js
// 前端请求安全工具:防抖、节流、重复提交防护
(function() {
'use strict';
// ==================== 防抖函数 ====================
/**
* 防抖函数 - 在事件触发n秒后再执行,n秒内再次触发则重新计时
* @param {Function} func - 要执行的函数
* @param {number} wait - 等待时间(毫秒)
* @param {boolean} immediate - 是否立即执行
*/
window.debounce = function(func, wait, immediate) {
var timeout;
return function() {
var context = this;
var args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
};
};
// ==================== 节流函数 ====================
/**
* 节流函数 - 在规定时间内只执行一次
* @param {Function} func - 要执行的函数
* @param {number} wait - 时间间隔(毫秒)
*/
window.throttle = function(func, wait) {
var timeout;
var previous = 0;
return function() {
var context = this;
var args = arguments;
var now = Date.now();
var remaining = wait - (now - previous);
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context, args);
} else if (!timeout) {
timeout = setTimeout(function() {
previous = Date.now();
timeout = null;
func.apply(context, args);
}, remaining);
}
};
};
// ==================== 请求锁(防止重复提交) ====================
var RequestLock = {
locks: {},
/**
* 锁定指定key的请求
* @param {string} key - 锁的标识
* @param {number} duration - 锁定时长(毫秒),默认3秒
* @returns {boolean} - 是否成功锁定
*/
lock: function(key, duration) {
duration = duration || 3000;
if (this.locks[key]) {
return false; // 已存在锁
}
this.locks[key] = true;
setTimeout(function() {
delete RequestLock.locks[key];
}, duration);
return true;
},
/**
* 检查是否存在锁
* @param {string} key - 锁的标识
* @returns {boolean}
*/
isLocked: function(key) {
return !!this.locks[key];
},
/**
* 解锁
* @param {string} key - 锁的标识
*/
unlock: function(key) {
delete this.locks[key];
},
/**
* 带锁执行请求
* @param {string} key - 锁的标识
* @param {Function} requestFn - 请求函数(可选,传null则只做锁检查)
* @param {number} duration - 锁定时长
* @returns {boolean} - 是否执行了请求
*/
executeWithLock: function(key, requestFn, duration) {
if (this.isLocked(key)) {
if (typeof $toast !== 'undefined') {
$toast.warning('操作太频繁,请稍后再试');
}
return false;
}
this.lock(key, duration);
if (typeof requestFn === 'function') {
requestFn();
}
return true;
}
};
window.RequestLock = RequestLock;
// ==================== 请求ID生成器(防重复提交) ====================
var RequestID = {
cache: {},
/**
* 生成请求ID
* @param {string} userId - 用户ID
* @param {string} action - 操作类型
* @returns {string}
*/
generate: function(userId, action) {
return userId + '_' + action + '_' + Date.now();
},
/**
* 记录请求ID(用于检测重复)
* @param {string} id - 请求ID
* @param {number} ttl - 有效期(毫秒)
* @returns {boolean} - 是否是新请求
*/
record: function(id, ttl) {
ttl = ttl || 5000; // 默认5秒内不允许重复
if (this.cache[id]) {
return false;
}
this.cache[id] = true;
var self = this;
setTimeout(function() {
delete self.cache[id];
}, ttl);
return true;
},
/**
* 检查请求是否重复
* @param {string} id - 请求ID
* @returns {boolean}
*/
isDuplicate: function(id) {
return !!this.cache[id];
}
};
window.RequestID = RequestID;
})();