moc变更管理系统框架
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
export function isPC() {
|
||||
const agents = ['Android', 'iPhone', 'webOS', 'BlackBerry', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
|
||||
|
||||
const isMobile = agents.some(agent => window.navigator.userAgent.includes(agent));
|
||||
|
||||
return !isMobile;
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import { $t } from '@/locales';
|
||||
|
||||
/**
|
||||
* Transform record to option
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const record = {
|
||||
* key1: 'label1',
|
||||
* key2: 'label2'
|
||||
* };
|
||||
* const options = transformRecordToOption(record);
|
||||
* // [
|
||||
* // { value: 'key1', label: 'label1' },
|
||||
* // { value: 'key2', label: 'label2' }
|
||||
* // ]
|
||||
* ```;
|
||||
*
|
||||
* @param record
|
||||
*/
|
||||
export function transformRecordToOption<T extends Record<string, string>>(record: T) {
|
||||
return Object.entries(record).map(([value, label]) => ({
|
||||
value,
|
||||
label
|
||||
})) as CommonType.Option<keyof T, T[keyof T]>[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate options
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
export function translateOptions(options: CommonType.Option<string, App.I18n.I18nKey>[]) {
|
||||
return options.map(option => ({
|
||||
...option,
|
||||
label: $t(option.label)
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle html class
|
||||
*
|
||||
* @param className
|
||||
*/
|
||||
export function toggleHtmlClass(className: string) {
|
||||
function add() {
|
||||
document.documentElement.classList.add(className);
|
||||
}
|
||||
|
||||
function remove() {
|
||||
document.documentElement.classList.remove(className);
|
||||
}
|
||||
|
||||
return {
|
||||
add,
|
||||
remove
|
||||
};
|
||||
}
|
||||
|
||||
// 辅助函数:将 hex 转为 rgba
|
||||
export function hexToRgba(hex: string, alpha: number) {
|
||||
// 去掉 # 号
|
||||
hex = hex.replace('#', '');
|
||||
// 处理缩写形式 #RGB
|
||||
if (hex.length === 3) {
|
||||
hex = hex.split('').map(c => c + c).join('');
|
||||
}
|
||||
const r = parseInt(hex.substring(0, 2), 16);
|
||||
const g = parseInt(hex.substring(2, 4), 16);
|
||||
const b = parseInt(hex.substring(4, 6), 16);
|
||||
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||||
}
|
||||
export const getColorWithOpacity = (color: string, opacity: number) => {
|
||||
// 如果 color 本身已经是 rgba 或 hsl 等,可自行扩展判断
|
||||
// 这里仅处理 hex
|
||||
return hexToRgba(color, opacity);
|
||||
};
|
||||
|
||||
// 时间戳转换成年月日时分秒
|
||||
export function formatTimestamp(timestamp: number | string,format: string = 'yyyy-MM-dd HH:mm:ss') {
|
||||
if(!timestamp) {
|
||||
return '';
|
||||
}
|
||||
const date = new Date(Number(timestamp));
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
if(format === 'yyyy-MM-dd') {
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
if(format === 'yyyy-MM-dd HH:mm') {
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||||
}
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import json5 from 'json5';
|
||||
|
||||
/**
|
||||
* Create service config by current env
|
||||
*
|
||||
* @param env The current env
|
||||
*/
|
||||
export function createServiceConfig(env: Env.ImportMeta) {
|
||||
const { VITE_SERVICE_BASE_URL, VITE_OTHER_SERVICE_BASE_URL } = env;
|
||||
|
||||
let other = {} as Record<App.Service.OtherBaseURLKey, string>;
|
||||
try {
|
||||
other = json5.parse(VITE_OTHER_SERVICE_BASE_URL);
|
||||
} catch {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('VITE_OTHER_SERVICE_BASE_URL is not a valid json5 string');
|
||||
}
|
||||
|
||||
const httpConfig: App.Service.SimpleServiceConfig = {
|
||||
baseURL: VITE_SERVICE_BASE_URL,
|
||||
other
|
||||
};
|
||||
|
||||
const otherHttpKeys = Object.keys(httpConfig.other) as App.Service.OtherBaseURLKey[];
|
||||
|
||||
const otherConfig: App.Service.OtherServiceConfigItem[] = otherHttpKeys.map(key => {
|
||||
return {
|
||||
key,
|
||||
baseURL: httpConfig.other[key],
|
||||
proxyPattern: createProxyPattern(key)
|
||||
};
|
||||
});
|
||||
|
||||
const config: App.Service.ServiceConfig = {
|
||||
baseURL: httpConfig.baseURL,
|
||||
proxyPattern: createProxyPattern(),
|
||||
other: otherConfig
|
||||
};
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* get backend service base url
|
||||
*
|
||||
* @param env - the current env
|
||||
* @param isProxy - if use proxy
|
||||
*/
|
||||
export function getServiceBaseURL(env: Env.ImportMeta, isProxy: boolean) {
|
||||
const { baseURL, other } = createServiceConfig(env);
|
||||
|
||||
const otherBaseURL = {} as Record<App.Service.OtherBaseURLKey, string>;
|
||||
|
||||
other.forEach(item => {
|
||||
otherBaseURL[item.key] = isProxy ? item.proxyPattern : item.baseURL;
|
||||
});
|
||||
|
||||
return {
|
||||
baseURL: isProxy ? createProxyPattern() : baseURL,
|
||||
otherBaseURL
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get proxy pattern of backend service base url
|
||||
*
|
||||
* @param key If not set, will use the default key
|
||||
*/
|
||||
function createProxyPattern(key?: App.Service.OtherBaseURLKey) {
|
||||
if (!key) {
|
||||
return '/proxy-default';
|
||||
}
|
||||
|
||||
return `/proxy-${key}`;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createLocalforage, createStorage } from '@sa/utils';
|
||||
|
||||
const storagePrefix = import.meta.env.VITE_STORAGE_PREFIX || '';
|
||||
|
||||
export const localStg = createStorage<StorageType.Local>('local', storagePrefix);
|
||||
|
||||
export const sessionStg = createStorage<StorageType.Session>('session', storagePrefix);
|
||||
|
||||
export const localforage = createLocalforage<StorageType.Local>('local');
|
||||
Reference in New Issue
Block a user