init: 初始系统模板

This commit is contained in:
TsMask
2023-09-05 14:38:23 +08:00
parent a5bc16ae4f
commit 1075c8ae4f
130 changed files with 22531 additions and 1 deletions

View File

@@ -0,0 +1,40 @@
/**长期级缓存设置 */
export function localSet(key: string, value: string) {
if (!localStorage || key == null || value == null) {
return;
}
localStorage.setItem(key, value);
}
/**长期级缓存获取 */
export function localGet(key: string) {
if (!localStorage || key == null) {
return null;
}
return localStorage.getItem(key);
}
/**长期级缓存移除 */
export function localRemove(key: string) {
if (!localStorage || key == null) {
return null;
}
return localStorage.removeItem(key);
}
/**长期级缓存设置JSON */
export function localSetJSON(key: string, jsonValue: object) {
if (key == null || jsonValue == null) {
return null;
}
localSet(key, JSON.stringify(jsonValue));
}
/**长期级缓存获取JSON */
export function localGetJSON(key: string) {
const value = localGet(key);
if (value == null) {
return null;
}
return JSON.parse(value);
}

View File

@@ -0,0 +1,40 @@
/**会话级缓存设置 */
export function sessionSet(key: string, value: string) {
if (!sessionStorage || key == null || value == null) {
return;
}
sessionStorage.setItem(key, value);
}
/**会话级缓存获取 */
export function sessionGet(key: string) {
if (!sessionStorage || key == null) {
return null;
}
return sessionStorage.getItem(key);
}
/**会话级缓存移除 */
export function sessionRemove(key: string) {
if (!sessionStorage || key == null) {
return null;
}
return sessionStorage.removeItem(key);
}
/**会话级缓存设置JSON */
export function sessionSetJSON(key: string, jsonValue: object) {
if (key == null || jsonValue == null) {
return null;
}
sessionSet(key, JSON.stringify(jsonValue));
}
/**会话级缓存获取JSON */
export function sessionGetJSON(key: string) {
const value = sessionGet(key);
if (value == null) {
return null;
}
return JSON.parse(value);
}

72
src/utils/date-utils.ts Normal file
View File

@@ -0,0 +1,72 @@
// 依赖来源 https://github.com/iamkun/dayjs
import dayjs from 'dayjs';
// 导入本地化语言并设为默认使用
import('dayjs/locale/zh-cn');
dayjs.locale('zh-cn');
/**年 列如2022 */
export const YYYY = 'YYYY';
/**年-月 列如2022-12 */
export const YYYY_MM = 'YYYY-MM';
/**年-月-日 列如2022-12-30 */
export const YYYY_MM_DD = 'YYYY-MM-DD';
/**年月日时分秒 列如20221230010159 */
export const YYYYMMDDHHMMSS = 'YYYYMMDDHHmmss';
/**年-月-日 时:分:秒 列如2022-12-30 01:01:59 */
export const YYYY_MM_DD_HH_MM_SS = 'YYYY-MM-DD HH:mm:ss';
/**
* 格式时间字符串
* @param dateStr 时间字符串
* @param formatStr 时间格式 默认YYYY-MM-DD HH:mm:ss
* @returns Date对象
*/
export function parseStrToDate(
dateStr: string,
formatStr: string = YYYY_MM_DD_HH_MM_SS
): Date {
return dayjs(dateStr, formatStr).toDate();
}
/**
* 格式时间
* @param date 可转的Date对象
* @param formatStr 时间格式 默认YYYY-MM-DD HH:mm:ss
* @returns 时间格式字符串
*/
export function parseDateToStr(
date: string | number | Date,
formatStr: string = YYYY_MM_DD_HH_MM_SS
): string {
return dayjs(date).format(formatStr);
}
/**
* 格式时间成日期路径
*
* 年/月 列如2022/12
* @returns 时间格式字符串 YYYY/MM
*/
export function parseDatePath(date: number | Date = Date.now()): string {
return dayjs(date).format('YYYY/MM');
}
/**
* 判断两次时间差
* @param endDate 结束时间
* @param startDate 开始时间
* @returns 单位秒
*/
export function diffSeconds(
endDate: number | Date,
startDate: number | Date
): number {
const value = Math.ceil(dayjs(endDate).diff(startDate, 'seconds'));
if (Number.isNaN(value)) return 0;
return value;
}

View File

@@ -0,0 +1,188 @@
/**
* 解析数据层级转树结构
*
* @param data 数组数据
* @param fieldId 读取节点字段 默认 'id'
* @param fieldParentId 读取节点父节点字段 默认 'parentId'
* @param fieldChildren 设置子节点字段 默认 'children'
* @returns 层级数组
*/
export function parseDataToTree(
data: Record<string, any>[],
fieldId: string = 'id',
fieldParentId: string = 'parentId',
fieldChildren: string = 'children'
) {
// 节点分组
let map: Map<string, Record<string, any>[]> = new Map();
// 节点id
let treeIds: string[] = [];
// 树节点
let tree: Record<string, any>[] = [];
for (const item of data) {
let parentId = item[fieldParentId];
// 分组
let mapItem = map.get(parentId) ?? [];
mapItem.push(item);
map.set(parentId, mapItem);
// 记录节点id
treeIds.push(item[fieldId]);
}
for (const [key, value] of map) {
// 选择不是节点id的作为树节点
if (!treeIds.includes(key)) {
tree.push(...value);
}
}
for (const iterator of tree) {
componet(iterator);
}
/**闭包递归函数 */
function componet(iterator: Record<string, any>) {
let id = iterator[fieldId];
let item = map.get(id);
if (item) {
iterator[fieldChildren] = item;
}
if (iterator[fieldChildren]) {
for (let i of iterator[fieldChildren]) {
componet(i);
}
}
}
return tree;
}
/**
* 解析数据层级转树结构-排除节点
*
* @param data 数组数据
* @param excludeField 排除节点字段 默认 'type'
* @param excludeValue 排除节点值 默认 '0'
* @param fieldId 读取节点字段 默认 'id'
* @param fieldParentId 读取节点父节点字段 默认 'parentId'
* @param fieldChildren 设置子节点字段 默认 'children'
* @returns 层级数组
*/
export function parseDataToTreeExclude(
data: Record<string, any>[],
excludeField = 'type',
excludeValue = '0',
fieldId: string = 'id',
fieldParentId: string = 'parentId',
fieldChildren: string = 'children'
) {
// 节点分组
let map: Map<string, Record<string, any>[]> = new Map();
// 节点id
let treeIds: string[] = [];
// 树节点
let tree: Record<string, any>[] = [];
for (const item of data) {
// 排除值跳过
let exclude = item[excludeField];
if (exclude && exclude === excludeValue) {
continue;
}
let parentId = item[fieldParentId];
// 分组
let mapItem = map.get(parentId) ?? [];
mapItem.push(item);
map.set(parentId, mapItem);
// 记录节点id
treeIds.push(item[fieldId]);
}
for (const [key, value] of map) {
// 选择不是节点id的作为树节点
if (!treeIds.includes(key)) {
tree.push(...value);
}
}
for (const iterator of tree) {
componet(iterator);
}
/**闭包递归函数 */
function componet(iterator: Record<string, any>) {
let id = iterator[fieldId];
let item = map.get(id);
if (item) {
iterator[fieldChildren] = item;
}
if (iterator[fieldChildren]) {
for (let i of iterator[fieldChildren]) {
componet(i);
}
}
}
return tree;
}
/**
* 解析树结构数据转出一维id数组
*
* @param data 数组数据
* @param fieldId 读取节点字段 默认 'id'
* @param fieldChildren 读取子节点字段 默认 'children'
* @returns 层级数组
*/
export function parseTreeKeys(
data: Record<string, any>[],
fieldId: string = 'id',
fieldChildren: string = 'children'
) {
// 节点id
let treeIds: string[] | number[] = [];
componet(data);
/**闭包递归函数 */
function componet(data: Record<string, any>[]) {
if (data.length <= 0) return;
for (const iterator of data) {
let id = iterator[fieldId];
if (id) {
treeIds.push(id as never);
}
if (Array.isArray(iterator[fieldChildren])) {
componet(iterator[fieldChildren]);
}
}
}
return treeIds;
}
/**
* 解析树结构数据转出含子节点的一维id数组
*
* @param data 数组数据
* @param fieldId 读取节点字段 默认 'id'
* @param fieldChildren 读取子节点字段 默认 'children'
* @returns 层级数组
*/
export function parseTreeNodeKeys(
data: Record<string, any>[],
fieldId: string = 'id',
fieldChildren: string = 'children'
) {
// 节点id
let treeIds: string[] | number[] = [];
componet(data);
/**闭包递归函数 */
function componet(data: Record<string, any>[]) {
if (data.length <= 0) return;
for (const iterator of data) {
let nodes = iterator[fieldChildren];
if (Array.isArray(nodes) && nodes.length > 0) {
treeIds.push(iterator[fieldId] as never);
componet(iterator[fieldChildren]);
}
}
}
return treeIds;
}

View File

@@ -0,0 +1,67 @@
/**
* 有效账号格式
*
* 账号不能以数字开头可包含大写小写字母数字且不少于5位
*/
export const regExpUserName = /^[a-zA-Z][a-z0-9A-Z]{5,}$/;
/**
* 有效密码格式
*
* 密码至少包含大小写字母、数字、特殊符号且不少于6位
*/
export const regExpPasswd =
/^(?![A-Za-z0-9]+$)(?![a-z0-9\W]+$)(?![A-Za-z\W]+$)(?![A-Z0-9\W]+$)[a-zA-Z0-9\W]{6,}$/;
/**
* 有效手机号格式
*/
export const regExpMobile = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/;
/**
* 有效邮箱格式
*/
export const regExpEmail =
/^(([^<>()\\.,;:\s@"]+(\.[^<>()\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+\.)+[a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}))$/;
/**
* 有效用户昵称格式
*
* 用户昵称只能包含字母、数字、中文和下划线且不少于2位
*/
export const regExpNick = /^[\w\u4e00-\u9fa5-]{2,}$/;
/**
* 是否为http(s)://开头
*/
export const regExpHttp = /^http(s)?:\/\/+/;
/**
* 判断是否为http(s)://开头
* @param link 网络链接
* @returns true | false
*/
export function validHttp(link: string): boolean {
if (!link) return false;
return regExpHttp.test(link);
}
/**
* 判断是否为有效手机号格式
* @param mobile 手机号字符串
* @returns true | false
*/
export function validMobile(mobile: string): boolean {
if (!mobile) return false;
return regExpMobile.test(mobile);
}
/**
* 判断是否为有效邮箱格式
* @param email 邮箱字符串
* @returns true | false
*/
export function validEmail(email: string): boolean {
if (!email) return false;
return regExpEmail.test(email);
}