添加项目基础文件结构、路由配置、API接口和核心组件 实现登录认证、权限控制、WebSocket通信等基础功能 引入antd-mobile UI组件库和Vite构建工具 配置TypeScript、ESLint、Prettier等开发环境 添加移动端适配方案和全局样式 完成首页、工作台、个人中心等基础页面框架
353 lines
9.8 KiB
TypeScript
353 lines
9.8 KiB
TypeScript
// Android 专用 polyfill - 解决Android 7等低版本系统的兼容性问题
|
||
|
||
// 检测是否为Android设备
|
||
const isAndroid = () => {
|
||
return /Android/i.test(navigator.userAgent);
|
||
};
|
||
|
||
// 检测Android版本
|
||
const getAndroidVersion = () => {
|
||
const match = navigator.userAgent.match(/Android\s+(\d+)/);
|
||
return match ? parseInt(match[1]) : 0;
|
||
};
|
||
|
||
// 检测是否为低版本Android
|
||
const isLowVersionAndroid = () => {
|
||
const version = getAndroidVersion();
|
||
return version <= 7; // Android 7及以下版本
|
||
};
|
||
|
||
// 只在Android设备上执行polyfill
|
||
if (isAndroid() && isLowVersionAndroid()) {
|
||
console.log("检测到低版本Android系统,启用兼容性polyfill");
|
||
|
||
// 修复Array.prototype.includes在Android WebView中的问题
|
||
if (!Array.prototype.includes) {
|
||
Array.prototype.includes = function (searchElement, fromIndex) {
|
||
if (this == null) {
|
||
throw new TypeError('"this" is null or not defined');
|
||
}
|
||
var o = Object(this);
|
||
var len = o.length >>> 0;
|
||
if (len === 0) {
|
||
return false;
|
||
}
|
||
var n = fromIndex | 0;
|
||
var k = Math.max(n >= 0 ? n : len + n, 0);
|
||
while (k < len) {
|
||
if (o[k] === searchElement) {
|
||
return true;
|
||
}
|
||
k++;
|
||
}
|
||
return false;
|
||
};
|
||
}
|
||
|
||
// 修复String.prototype.includes在Android WebView中的问题
|
||
if (!String.prototype.includes) {
|
||
String.prototype.includes = function (search, start) {
|
||
if (typeof start !== "number") {
|
||
start = 0;
|
||
}
|
||
if (start + search.length > this.length) {
|
||
return false;
|
||
} else {
|
||
return this.indexOf(search, start) !== -1;
|
||
}
|
||
};
|
||
}
|
||
|
||
// 修复String.prototype.startsWith在Android WebView中的问题
|
||
if (!String.prototype.startsWith) {
|
||
String.prototype.startsWith = function (searchString, position) {
|
||
position = position || 0;
|
||
return this.substr(position, searchString.length) === searchString;
|
||
};
|
||
}
|
||
|
||
// 修复String.prototype.endsWith在Android WebView中的问题
|
||
if (!String.prototype.endsWith) {
|
||
String.prototype.endsWith = function (searchString, length) {
|
||
if (length === undefined || length > this.length) {
|
||
length = this.length;
|
||
}
|
||
return (
|
||
this.substring(length - searchString.length, length) === searchString
|
||
);
|
||
};
|
||
}
|
||
|
||
// 修复Array.prototype.find在Android WebView中的问题
|
||
if (!Array.prototype.find) {
|
||
Array.prototype.find = function (predicate) {
|
||
if (this == null) {
|
||
throw new TypeError("Array.prototype.find called on null or undefined");
|
||
}
|
||
if (typeof predicate !== "function") {
|
||
throw new TypeError("predicate must be a function");
|
||
}
|
||
var list = Object(this);
|
||
var length = parseInt(list.length) || 0;
|
||
var thisArg = arguments[1];
|
||
for (var i = 0; i < length; i++) {
|
||
var element = list[i];
|
||
if (predicate.call(thisArg, element, i, list)) {
|
||
return element;
|
||
}
|
||
}
|
||
return undefined;
|
||
};
|
||
}
|
||
|
||
// 修复Array.prototype.findIndex在Android WebView中的问题
|
||
if (!Array.prototype.findIndex) {
|
||
Array.prototype.findIndex = function (predicate) {
|
||
if (this == null) {
|
||
throw new TypeError(
|
||
"Array.prototype.findIndex called on null or undefined",
|
||
);
|
||
}
|
||
if (typeof predicate !== "function") {
|
||
throw new TypeError("predicate must be a function");
|
||
}
|
||
var list = Object(this);
|
||
var length = parseInt(list.length) || 0;
|
||
var thisArg = arguments[1];
|
||
for (var i = 0; i < length; i++) {
|
||
var element = list[i];
|
||
if (predicate.call(thisArg, element, i, list)) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
};
|
||
}
|
||
|
||
// 修复Object.assign在Android WebView中的问题
|
||
if (typeof Object.assign !== "function") {
|
||
Object.assign = function (target) {
|
||
if (target == null) {
|
||
throw new TypeError("Cannot convert undefined or null to object");
|
||
}
|
||
var to = Object(target);
|
||
for (var index = 1; index < arguments.length; index++) {
|
||
var nextSource = arguments[index];
|
||
if (nextSource != null) {
|
||
for (var nextKey in nextSource) {
|
||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||
to[nextKey] = nextSource[nextKey];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return to;
|
||
};
|
||
}
|
||
|
||
// 修复Array.from在Android WebView中的问题
|
||
if (!Array.from) {
|
||
Array.from = (function () {
|
||
var toStr = Object.prototype.toString;
|
||
var isCallable = function (fn) {
|
||
return (
|
||
typeof fn === "function" || toStr.call(fn) === "[object Function]"
|
||
);
|
||
};
|
||
var toInteger = function (value) {
|
||
var number = Number(value);
|
||
if (isNaN(number)) {
|
||
return 0;
|
||
}
|
||
if (number === 0 || !isFinite(number)) {
|
||
return number;
|
||
}
|
||
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
|
||
};
|
||
var maxSafeInteger = Math.pow(2, 53) - 1;
|
||
var toLength = function (value) {
|
||
var len = toInteger(value);
|
||
return Math.min(Math.max(len, 0), maxSafeInteger);
|
||
};
|
||
return function from(arrayLike) {
|
||
var C = this;
|
||
var items = Object(arrayLike);
|
||
if (arrayLike == null) {
|
||
throw new TypeError(
|
||
"Array.from requires an array-like object - not null or undefined",
|
||
);
|
||
}
|
||
var mapFunction = arguments.length > 1 ? arguments[1] : void undefined;
|
||
var T;
|
||
if (typeof mapFunction !== "undefined") {
|
||
if (typeof mapFunction !== "function") {
|
||
throw new TypeError(
|
||
"Array.from: when provided, the second argument must be a function",
|
||
);
|
||
}
|
||
if (arguments.length > 2) {
|
||
T = arguments[2];
|
||
}
|
||
}
|
||
var len = toLength(items.length);
|
||
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
|
||
var k = 0;
|
||
var kValue;
|
||
while (k < len) {
|
||
kValue = items[k];
|
||
if (mapFunction) {
|
||
A[k] =
|
||
typeof T === "undefined"
|
||
? mapFunction(kValue, k)
|
||
: mapFunction.call(T, kValue, k);
|
||
} else {
|
||
A[k] = kValue;
|
||
}
|
||
k += 1;
|
||
}
|
||
A.length = len;
|
||
return A;
|
||
};
|
||
})();
|
||
}
|
||
|
||
// 修复requestAnimationFrame在Android WebView中的问题
|
||
if (!window.requestAnimationFrame) {
|
||
window.requestAnimationFrame = function (callback) {
|
||
return setTimeout(function () {
|
||
callback(Date.now());
|
||
}, 1000 / 60);
|
||
};
|
||
}
|
||
|
||
if (!window.cancelAnimationFrame) {
|
||
window.cancelAnimationFrame = function (id) {
|
||
clearTimeout(id);
|
||
};
|
||
}
|
||
|
||
// 修复IntersectionObserver在Android WebView中的问题
|
||
if (!window.IntersectionObserver) {
|
||
window.IntersectionObserver = function (callback, options) {
|
||
this.callback = callback;
|
||
this.options = options || {};
|
||
this.observers = [];
|
||
|
||
this.observe = function (element) {
|
||
this.observers.push(element);
|
||
// 简单的实现,实际项目中可能需要更复杂的逻辑
|
||
setTimeout(() => {
|
||
this.callback([
|
||
{
|
||
target: element,
|
||
isIntersecting: true,
|
||
intersectionRatio: 1,
|
||
},
|
||
]);
|
||
}, 100);
|
||
};
|
||
|
||
this.unobserve = function (element) {
|
||
var index = this.observers.indexOf(element);
|
||
if (index > -1) {
|
||
this.observers.splice(index, 1);
|
||
}
|
||
};
|
||
|
||
this.disconnect = function () {
|
||
this.observers = [];
|
||
};
|
||
};
|
||
}
|
||
|
||
// 修复ResizeObserver在Android WebView中的问题
|
||
if (!window.ResizeObserver) {
|
||
window.ResizeObserver = function (callback) {
|
||
this.callback = callback;
|
||
this.observers = [];
|
||
|
||
this.observe = function (element) {
|
||
this.observers.push(element);
|
||
};
|
||
|
||
this.unobserve = function (element) {
|
||
var index = this.observers.indexOf(element);
|
||
if (index > -1) {
|
||
this.observers.splice(index, 1);
|
||
}
|
||
};
|
||
|
||
this.disconnect = function () {
|
||
this.observers = [];
|
||
};
|
||
};
|
||
}
|
||
|
||
// 修复URLSearchParams在Android WebView中的问题
|
||
if (!window.URLSearchParams) {
|
||
window.URLSearchParams = function (init) {
|
||
this.params = {};
|
||
|
||
if (init) {
|
||
if (typeof init === "string") {
|
||
if (init.charAt(0) === "?") {
|
||
init = init.slice(1);
|
||
}
|
||
var pairs = init.split("&");
|
||
for (var i = 0; i < pairs.length; i++) {
|
||
var pair = pairs[i].split("=");
|
||
var key = decodeURIComponent(pair[0]);
|
||
var value = decodeURIComponent(pair[1] || "");
|
||
this.append(key, value);
|
||
}
|
||
}
|
||
}
|
||
|
||
this.append = function (name, value) {
|
||
if (!this.params[name]) {
|
||
this.params[name] = [];
|
||
}
|
||
this.params[name].push(value);
|
||
};
|
||
|
||
this.get = function (name) {
|
||
return this.params[name] ? this.params[name][0] : null;
|
||
};
|
||
|
||
this.getAll = function (name) {
|
||
return this.params[name] || [];
|
||
};
|
||
|
||
this.has = function (name) {
|
||
return !!this.params[name];
|
||
};
|
||
|
||
this.set = function (name, value) {
|
||
this.params[name] = [value];
|
||
};
|
||
|
||
this.delete = function (name) {
|
||
delete this.params[name];
|
||
};
|
||
|
||
this.toString = function () {
|
||
var pairs = [];
|
||
for (var key in this.params) {
|
||
if (this.params.hasOwnProperty(key)) {
|
||
for (var i = 0; i < this.params[key].length; i++) {
|
||
pairs.push(
|
||
encodeURIComponent(key) +
|
||
"=" +
|
||
encodeURIComponent(this.params[key][i]),
|
||
);
|
||
}
|
||
}
|
||
}
|
||
return pairs.join("&");
|
||
};
|
||
};
|
||
}
|
||
|
||
console.log("Android兼容性polyfill已加载完成");
|
||
}
|