# node-toolkit **Repository Path**: sonyao/node-toolkit ## Basic Information - **Project Name**: node-toolkit - **Description**: node前后端工具包 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-28 - **Last Updated**: 2026-07-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # commonsy 前后端通用 TypeScript 工具库,包含通用基础、日期时间、金额货币、表单校验、浏览器判断、文件图片、下载链接、加密、WebSocket、服务端、Cesium 地图等工具。源码使用 TypeScript 编写,发布时输出 JavaScript 与 `.d.ts` 类型声明。 ## 安装 ```bash npm install commonsy ``` ## 引用方式 ### 默认入口 ```typescript import sysFun from 'commonsy'; sysFun.CommonUtils.isEmpty({}); new sysFun.DateUtils.DateTimeFormatter('2022-10-10 11:11:10', 'yyyy-mm-dd').getFormattedDateTime(); new sysFun.MoneyUtils.ComputeMoney(100).add(50).toDollars(); ``` ### 分类子路径入口 ```typescript import CommonUtils from 'commonsy/common'; import DateUtils from 'commonsy/date'; import MoneyUtils from 'commonsy/money'; import WebSocketUtils from 'commonsy/websocket'; import ServerUtils from 'commonsy/server'; ``` ### 旧版直达入口 ```typescript import sysFun from 'commonsy'; new sysFun.DateTimeFormatter('2022-10-10 11:11:10', 'yyyy/mm/dd').getFormattedDateTime(); new sysFun.ComputeMoney(100).add(50).toDollars(); ``` ## 目录结构 ```text commonsy ├── index.ts # TypeScript 统一入口 ├── dist # 构建后的 JavaScript 与类型声明 ├── publicFun │ ├── common # 通用基础工具 │ ├── date # 日期时间工具 │ ├── money # 金额货币工具 │ ├── validate # 表单校验工具 │ ├── browser # 浏览器判断工具 │ ├── file # 文件图片工具 │ └── download # 下载链接工具 ├── encryption # 加密工具 ├── webSocket # WebSocket 工具 ├── server # 项目启动入口、HTTP 服务、SQL、Redis 工具 ├── cesium # Cesium 地图工具 └── test # 测试 ``` ## 子路径导出 | 导入路径 | 对应分类 | | --- | --- | | `commonsy` | 全量默认入口 | | `commonsy/common` | 通用基础工具 | | `commonsy/date` | 日期时间工具 | | `commonsy/money` | 金额货币工具 | | `commonsy/validate` | 表单校验工具 | | `commonsy/browser` | 浏览器判断工具 | | `commonsy/file` | 文件图片工具 | | `commonsy/download` | 下载链接工具 | | `commonsy/crypto` | 加密工具 | | `commonsy/websocket` | WebSocket 工具 | | `commonsy/server` | 服务端工具,包含项目启动入口、HTTP 服务、SQL、Redis | | `commonsy/map` | Cesium 地图工具 | ## 工具总览 | 分类 | 默认入口名称 | 工具 | | --- | --- | --- | | 通用基础 | `CommonUtils` | `isEmpty`、`deepClone`、`deepMerge`、`debounce`、`throttle`、`listToTree`、`treeToList`、`safeJsonParse`、`formatFileSize`、`maskPhone`、`maskEmail`、`maskBankCard` | | 类型判断 | `TypeUtils` | `isEmpty` | | 对象处理 | `ObjectUtils` | `deepClone`、`deepMerge` | | 函数控制 | `FunctionUtils` | `debounce`、`throttle` | | 树结构 | `TreeUtils` | `listToTree`、`treeToList` | | JSON | `JsonUtils` | `safeJsonParse` | | 文件格式 | `FileUtils` | `formatFileSize` | | 隐私脱敏 | `MaskUtils` | `maskPhone`、`maskEmail`、`maskBankCard` | | 日期时间 | `DateUtils` | `DateTimeFormatter`、`CountdownTimer` | | 金额货币 | `MoneyUtils` | `BankNumber`、`ComputeMoney` | | 表单校验 | `ValidateUtils` | `FormValidation` | | 浏览器 | `BrowserUtils` | `GetBrowserType` | | 文件图片 | `FileTools` | `CompressImage`、`formatFileSize` | | 下载链接 | `DownloadUtils` | `XunLeiDownloadUrl` | | 加密 | `CryptoUtils` | `Encryption` | | WebSocket | `WebSocketUtils` | `WebSocketServer`、`WebSocketClient` | | 服务端 | `ServerUtils` | `createServerApp`、`startServerApp`、`loadConfig`、`createRouter`、`composeMiddlewares`、`createErrorHandler`、`createLogger`、`sendSuccess`、`getPagination`、`validateRequest`、`signJwt`、`securityHeaders`、`staticMiddleware`、`uploadMiddleware`、`createTaskManager`、`createHealthChecker`、`createCache`、`createUuid`、`getProcessInfo`、`startHttpServer`、`queryRows`、`initMysqlTables`、`initMysqlTablesStep`、`createRedisClient` | | 地图 | `MapUtils` | `CesiumWrapper` | ## 服务端工具 服务端工具用于组织 Node 项目的基础设施,适合放在业务项目的 `server.js`、`app.js`、`main.js` 中使用。它可以把配置、路由、中间件、统一响应、统一错误、日志、鉴权、安全、静态资源、上传、后台任务、健康检查、缓存、数据库连接、Redis 连接、HTTP 服务启动和退出清理统一管理。 服务端工具默认不强制安装数据库和 Redis 客户端。只有调用 SQL 或 Redis 方法时,才需要在业务项目中安装对应依赖: ```bash npm install mysql2 redis ``` ### 项目启动入口 最常用的写法是通过 `startServerApp` 创建项目入口,在 `startup` 中按顺序初始化资源,在 `shutdown` 中释放资源。 ```typescript import ServerUtils from 'commonsy/server'; const app = await ServerUtils.startServerApp({ name: 'demo-api', config: { port: 3000, }, startup: [ { name: 'start-http', run: async ({ config }) => { const httpApp = await ServerUtils.startHttpServer({ port: config.port, routes: [ { method: 'GET', path: '/health', handler: ({ response, sendJson }) => { sendJson(response, { ok: true }); }, }, ], }); return { httpApp }; }, }, ], shutdown: [ { name: 'close-http', run: async ({ httpApp }) => { await ServerUtils.closeHttpServer(httpApp.server); }, }, ], }); ServerUtils.bindGracefulShutdown(app); console.log(app.context.httpApp.url); ``` ### 完整后端入口示例 下面示例展示一个项目入口如何同时启动 MySQL、Redis 和 HTTP 服务,并组合路由、中间件、日志和统一错误处理: ```typescript import ServerUtils from 'commonsy/server'; const logger = ServerUtils.createLogger({ name: 'demo-api', level: 'info', }); const config = ServerUtils.loadConfig({ defaults: { port: 3000, }, envMap: { port: { env: 'PORT', parse: Number, defaultValue: 3000, }, 'mysql.host': { env: 'MYSQL_HOST', defaultValue: 'localhost', }, 'mysql.user': { env: 'MYSQL_USER', defaultValue: 'root', }, 'mysql.password': { env: 'MYSQL_PASSWORD', defaultValue: 'password', }, 'mysql.database': { env: 'MYSQL_DATABASE', defaultValue: 'demo', }, 'redis.url': { env: 'REDIS_URL', defaultValue: 'redis://localhost:6379', }, }, required: ['mysql.host', 'mysql.database', 'redis.url'], }); const router = ServerUtils.createRouter(); router.get('/health', ({ response, sendJson }) => { sendJson(response, { ok: true }); }); router.get('/users/:id', async ({ params, response, sendJson }) => { const users = await ServerUtils.queryRows('select * from users where id = ?', [params.id]); sendJson(response, { data: users[0] || null }); }); const app = await ServerUtils.startServerApp({ name: 'demo-api', config, logger, startup: [ { name: 'connect-mysql', run: async ({ config }) => { const mysqlPool = await ServerUtils.createMysqlPool(config.mysql); return { mysqlPool }; }, }, ServerUtils.initMysqlTablesStep({ tables: [ { tableName: 'users', createSql: ` CREATE TABLE users ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) `, }, ], }), { name: 'connect-redis', run: async ({ config }) => { const redisClient = await ServerUtils.createRedisClient(config.redis); return { redisClient }; }, }, { name: 'start-http', run: async ({ config }) => { const httpApp = await ServerUtils.startHttpServer({ port: config.port, routes: router.routes, middlewares: [ ServerUtils.corsMiddleware(), ServerUtils.requestLogger(logger), ], errorHandler: ServerUtils.createErrorHandler(), }); return { httpApp }; }, }, ], shutdown: [ { name: 'close-http', run: async ({ httpApp }) => { await ServerUtils.closeHttpServer(httpApp.server); }, }, { name: 'close-redis', run: async ({ redisClient }) => { await ServerUtils.closeRedis(redisClient); }, }, { name: 'close-mysql', run: async ({ mysqlPool }) => { await ServerUtils.closeMysqlPool(mysqlPool); }, }, ], }); ServerUtils.bindGracefulShutdown(app); console.log(`服务已启动:${app.context.httpApp.url}`); ``` ### 基础设施工具分类 | 工具对象 | 说明 | | --- | --- | | `AppStarter` | 项目启动入口、启动步骤、关闭步骤、优雅退出 | | `ConfigUtils` | 配置合并、环境变量映射、必填配置校验 | | `ResponseUtils` | 成功响应、失败响应、分页响应和常用响应写出 | | `RequestUtils` | query、header、客户端 IP、分页参数解析 | | `ServerValidateUtils` | body、query、params 的服务端参数校验 | | `AuthUtils` | Bearer Token 解析、HS256 JWT 签发验证、鉴权中间件 | | `SecurityUtils` | 安全响应头、基础限流、请求体大小限制 | | `RouteUtils` | 轻量路由、路径参数、请求匹配 | | `MiddlewareUtils` | 中间件组合、CORS 中间件 | | `ErrorUtils` | HTTP 错误对象、统一错误响应 | | `LoggerUtils` | 轻量日志器、请求日志中间件 | | `StaticUtils` | 静态文件服务、MIME 类型识别、安全路径解析 | | `UploadUtils` | 文件名清理、轻量 multipart 解析、上传中间件 | | `TaskUtils` | 后台定时任务注册、启动和停止 | | `HealthUtils` | 健康检查器和健康检查路由 | | `CacheUtils` | Redis JSON 缓存、remember 缓存回填 | | `IdUtils` | UUID、随机 ID、请求 ID 中间件 | | `ProcessUtils` | 进程信息、sleep、异步超时控制 | | `HttpServerUtils` | Node 原生 HTTP/HTTPS 服务启动和关闭 | | `SqlUtils` | MySQL 连接池、查询、事务、启动时检查缺失表并建表 | | `RedisUtils` | Redis 连接、读写、删除 | ### 分步注册启动入口 如果不想一次性传入 `startup` 和 `shutdown`,也可以使用 `createServerApp` 后再逐步注册: ```typescript import ServerUtils from 'commonsy/server'; const app = ServerUtils.createServerApp({ name: 'demo-api', config: { port: 3000, }, }); app .use({ name: 'start-http', run: async ({ config }) => { const httpApp = await ServerUtils.startHttpServer({ port: config.port, routes: [], }); return { httpApp }; }, }) .onShutdown({ name: 'close-http', run: async ({ httpApp }) => { await ServerUtils.closeHttpServer(httpApp.server); }, }); await app.start(); ServerUtils.bindGracefulShutdown(app); ``` ### 启动入口 API | 方法 | 说明 | | --- | --- | | `createServerApp(options)` | 创建项目启动入口,不会立即执行启动步骤 | | `startServerApp(options)` | 创建项目启动入口并立即执行 `startup` | | `bindGracefulShutdown(app, options)` | 绑定 `SIGINT`、`SIGTERM`、未捕获异常和未处理 Promise 异常,触发时执行 `app.stop()` | | `app.use(step)` | 追加启动步骤 | | `app.onShutdown(step)` | 追加关闭步骤 | | `app.start()` | 按注册顺序执行启动步骤 | | `app.stop()` | 按关闭步骤的反向顺序释放资源 | `startup` 中每个步骤可以返回对象,返回字段会合并到 `app.context`,供后续步骤和关闭步骤复用。 ### 路由、中间件和错误处理 ```typescript import ServerUtils from 'commonsy/server'; const router = ServerUtils.createRouter(); router.get('/users/:id', async (context) => { ServerUtils.sendSuccess(context, { id: context.params.id }); }, { middlewares: [ ServerUtils.validateRequest({ params: { id: { required: true, pattern: /^\d+$/, }, }, }), ], }); await ServerUtils.startHttpServer({ port: 3000, routes: router.routes, middlewares: [ ServerUtils.requestIdMiddleware(), ServerUtils.securityHeaders(), ServerUtils.corsMiddleware(), ], errorHandler: ServerUtils.createErrorHandler(), }); ``` ### 配置工具 ```typescript import ServerUtils from 'commonsy/server'; const config = ServerUtils.loadConfig({ defaults: { port: 3000, }, envMap: { port: { env: 'PORT', parse: Number, defaultValue: 3000, }, 'mysql.host': 'MYSQL_HOST', }, overrides: { port: 4000, }, required: ['mysql.host'], }); console.log(config.port); ``` ### 鉴权工具 ```typescript import ServerUtils from 'commonsy/server'; const token = ServerUtils.signJwt( { userId: 1, role: 'admin', }, 'secret', { expiresIn: 3600, } ); const user = ServerUtils.verifyJwt(token, 'secret'); console.log(user.userId); ``` 路由中可以使用鉴权中间件: ```typescript router.get('/profile', (context) => { ServerUtils.sendSuccess(context, context.user); }, { middlewares: [ ServerUtils.authMiddleware({ secret: 'secret', }), ], }); ``` ### 健康检查和缓存 ```typescript import ServerUtils from 'commonsy/server'; const health = ServerUtils.createHealthChecker() .add('mysql', async () => { await ServerUtils.queryRows('select 1'); return true; }) .add('redis', async () => { return redisClient.isOpen; }); const cache = ServerUtils.createCache(redisClient, { prefix: 'demo:', defaultTtlSeconds: 300, }); router.get('/health', ServerUtils.healthRoute(health)); router.get('/users/:id', async (context) => { const user = await cache.remember(`user:${context.params.id}`, 60, async () => { const rows = await ServerUtils.queryRows('select * from users where id = ?', [context.params.id]); return rows[0] || null; }); ServerUtils.sendSuccess(context, user); }); ``` ### 静态文件、上传和任务 ```typescript import ServerUtils from 'commonsy/server'; const tasks = ServerUtils.createTaskManager(); tasks.interval('clear-cache', async () => { console.log('clear cache'); }, 60 * 1000); tasks.start(); await ServerUtils.startHttpServer({ port: 3000, middlewares: [ ServerUtils.staticMiddleware({ rootDir: './public', prefix: '/static', }), ], routes: [ { method: 'POST', path: '/upload', middlewares: [ ServerUtils.uploadMiddleware({ maxBytes: 10 * 1024 * 1024, }), ], handler: (context) => { ServerUtils.sendSuccess(context, { files: context.upload.files.map((file) => ({ filename: file.filename, size: file.size, })), }); }, }, ], }); ``` ### 启动 HTTP 服务 ```typescript import ServerUtils from 'commonsy/server'; const app = await ServerUtils.startHttpServer({ port: 3000, routes: [ { method: 'GET', path: '/health', handler: ({ response, sendJson }) => { sendJson(response, { ok: true }); }, }, ], }); console.log(app.url); // http://localhost:3000 ``` ### 查询 SQL ```typescript import ServerUtils from 'commonsy/server'; await ServerUtils.createMysqlPool({ host: 'localhost', user: 'root', password: 'password', database: 'demo', }); const users = await ServerUtils.queryRows('select * from users where status = ?', [1]); console.log(users); ``` ### 启动时初始化 MySQL 表 项目启动时可以检查表是否存在,缺失时自动执行建表 SQL: ```typescript import ServerUtils from 'commonsy/server'; const mysqlPool = await ServerUtils.createMysqlPool({ host: 'localhost', user: 'root', password: 'password', database: 'demo', }); await ServerUtils.initMysqlTables({ tables: [ { tableName: 'users', createSql: ` CREATE TABLE users ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) `, }, { tableName: 'orders', createSql: ` CREATE TABLE orders ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL, amount DECIMAL(10, 2) NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) `, }, ], }, mysqlPool); ``` 也可以直接放到项目启动入口里: ```typescript const app = await ServerUtils.startServerApp({ startup: [ { name: 'connect-mysql', run: async () => { const mysqlPool = await ServerUtils.createMysqlPool(mysqlConfig); return { mysqlPool }; }, }, ServerUtils.initMysqlTablesStep({ tables: [ { tableName: 'users', createSql: 'CREATE TABLE users (id BIGINT PRIMARY KEY AUTO_INCREMENT)', }, ], }), ], }); ``` ### 连接 Redis ```typescript import ServerUtils from 'commonsy/server'; await ServerUtils.createRedisClient({ url: 'redis://localhost:6379', }); await ServerUtils.redisSet('token:user:1', 'abc', { ttlSeconds: 3600 }); const token = await ServerUtils.redisGet('token:user:1'); console.log(token); ``` ## 通用基础工具 ### isEmpty 判断值是否为空。支持 `null`、`undefined`、空字符串、空数组、空对象、空 `Map`、空 `Set`。 ```typescript import CommonUtils from 'commonsy/common'; CommonUtils.isEmpty(null); // true CommonUtils.isEmpty(' '); // true CommonUtils.isEmpty([]); // true CommonUtils.isEmpty({}); // true CommonUtils.isEmpty({ name: 'sy' }); // false ``` ### deepClone 深拷贝对象、数组、日期、正则,并支持循环引用。 ```typescript import CommonUtils from 'commonsy/common'; const source = { user: { name: 'sy' }, tags: ['a'] }; const target = CommonUtils.deepClone(source); target.user.name = 'new name'; console.log(source.user.name); // sy ``` ### deepMerge 深度合并对象,后面的对象覆盖前面的同名字段。 ```typescript import CommonUtils from 'commonsy/common'; const result = CommonUtils.deepMerge( { user: { name: 'sy', age: 18 } }, { user: { age: 20 } } ); console.log(result); // { user: { name: 'sy', age: 20 } } ``` ### debounce 防抖。常用于搜索输入、窗口尺寸变化、按钮防重复触发。 ```typescript import CommonUtils from 'commonsy/common'; const onSearch = CommonUtils.debounce((keyword) => { console.log(keyword); }, 300); onSearch('commonsy'); ``` 第三个参数为 `true` 时,首次立即执行。 ```typescript const submit = CommonUtils.debounce(() => { console.log('submit'); }, 500, true); ``` ### throttle 节流。常用于滚动、拖拽、鼠标移动等高频事件。 ```typescript import CommonUtils from 'commonsy/common'; const onScroll = CommonUtils.throttle(() => { console.log('scroll'); }, 300); ``` ### listToTree 将扁平数组转换为树形结构。 ```typescript import CommonUtils from 'commonsy/common'; const list = [ { id: 1, parentId: null, name: '菜单' }, { id: 2, parentId: 1, name: '子菜单' }, ]; const tree = CommonUtils.listToTree(list); console.log(tree); ``` 支持自定义字段: ```typescript CommonUtils.listToTree(list, { idKey: 'id', parentKey: 'parentId', childrenKey: 'children', rootValue: null, }); ``` ### treeToList 将树形结构拍平成数组。 ```typescript import CommonUtils from 'commonsy/common'; const list = CommonUtils.treeToList(tree); console.log(list); ``` ### safeJsonParse 安全解析 JSON,失败时返回默认值。 ```typescript import CommonUtils from 'commonsy/common'; CommonUtils.safeJsonParse('{"name":"sy"}', {}); // { name: 'sy' } CommonUtils.safeJsonParse('{ bad json }', {}); // {} ``` ### formatFileSize 格式化文件大小。 ```typescript import CommonUtils from 'commonsy/common'; CommonUtils.formatFileSize(1024); // 1 KB CommonUtils.formatFileSize(1048576); // 1 MB CommonUtils.formatFileSize(1536, 1); // 1.5 KB ``` ### maskPhone 手机号脱敏。 ```typescript import CommonUtils from 'commonsy/common'; CommonUtils.maskPhone('13812345678'); // 138****5678 ``` ### maskEmail 邮箱脱敏。 ```typescript import CommonUtils from 'commonsy/common'; CommonUtils.maskEmail('test@example.com'); // t***t@example.com ``` ### maskBankCard 银行卡号脱敏。 ```typescript import CommonUtils from 'commonsy/common'; CommonUtils.maskBankCard('6222021234567890'); // 6222 **** **** 7890 ``` ## 日期时间工具 ### DateTimeFormatter 按指定格式输出日期时间。 ```typescript import DateUtils from 'commonsy/date'; const formatter = new DateUtils.DateTimeFormatter('2022-10-10 11:11:10', 'yyyy-mm-dd HH:mm:ss'); console.log(formatter.getFormattedDateTime()); // 2022-10-10 11:11:10 ``` 支持格式: | 格式 | 示例 | | --- | --- | | `yyyy-mm-dd HH:mm:ss` | `2022-10-10 11:11:10` | | `yyyy-mm-dd` | `2022-10-10` | | `yyyy/mm/dd` | `2022/10/10` | | `yyyy/mm/dd HH:mm:ss` | `2022/10/10 11:11:10` | ### CountdownTimer 倒计时工具,返回剩余总毫秒数、天、小时、分钟、秒。 ```typescript import DateUtils from 'commonsy/date'; const countdown = new DateUtils.CountdownTimer('2026-12-31T23:59:59'); const firstRemaining = countdown.start((remaining) => { console.log(remaining.days, remaining.hours, remaining.minutes, remaining.seconds); }); console.log(firstRemaining); // 主动停止 countdown.stop(); ``` 也可以只计算一次: ```typescript const remaining = countdown.getTimeRemaining(); console.log(remaining); ``` 返回结构: ```typescript { total: 1000, days: 0, hours: 0, minutes: 0, seconds: 1 } ``` ## 金额货币工具 ### BankNumber 使用 `Intl.NumberFormat` 格式化货币显示。 ```typescript import MoneyUtils from 'commonsy/money'; const amount = new MoneyUtils.BankNumber(1000.5, 'US', 'USD'); console.log(amount.formatCurrency('US', 'USD')); // $1,000.50 ``` 常见参数: | 地区 | currency | | --- | --- | | `US` | `USD` | | `CN` | `CNY` | | `JP` | `JPY` | | `UK` | `GBP` | | `EU` | `EUR` | ### ComputeMoney 使用分为单位处理金额,减少小数精度误差。 ```typescript import MoneyUtils from 'commonsy/money'; const money = new MoneyUtils.ComputeMoney(100); money.add(50); console.log(money.toDollars()); // 150.00 money.multiply(2); console.log(money.toDollars()); // 300.00 ``` 支持方法: ```typescript money.add(10); money.subtract(5); money.multiply(2); money.divide(3); money.toDollars(); ``` 表达式计算: ```typescript const result = MoneyUtils.ComputeMoney.calculate('(300 - 50) / 2 + 10'); const finalMoney = new MoneyUtils.ComputeMoney(result); console.log(finalMoney.toDollars()); // 135.00 ``` ## 表单校验工具 ### FormValidation 按字段配置执行非空、格式、最大长度、最小长度校验。 ```typescript import ValidateUtils from 'commonsy/validate'; const formData = [ { val: '13812345678', valName: '手机号', rule: /^1[3-9]\d{9}$/, max: 11, min: 11, validList: ['isNull', 'isFormattingError', 'isMax', 'isMin'], }, ]; const validator = new ValidateUtils.FormValidation(formData); console.log(validator.validationData()); // true ``` 支持规则: | 规则 | 作用 | 依赖字段 | | --- | --- | --- | | `isNull` | 判断是否为空 | `valName`、`val` | | `isFormattingError` | 判断正则格式是否匹配 | `valName`、`rule`、`val` | | `isMax` | 判断长度是否超过最大值 | `valName`、`max`、`val` | | `isMin` | 判断长度是否小于最小值 | `valName`、`min`、`val` | 校验失败时返回错误文案: ```typescript const validator = new ValidateUtils.FormValidation([ { val: '', valName: '姓名', validList: ['isNull'] }, ]); console.log(validator.validationData()); // 姓名不能为空. ``` ## 浏览器工具 ### GetBrowserType 判断当前运行容器。 ```typescript import BrowserUtils from 'commonsy/browser'; const browserType = new BrowserUtils.GetBrowserType(); console.log(browserType.throwType()); ``` 返回值: | 返回值 | 含义 | | --- | --- | | `wechat` | 微信内置浏览器 | | `alipay` | 支付宝内置浏览器 | | `H5` | 普通 H5 环境或无法识别环境 | ## 文件图片工具 ### CompressImage 浏览器端图片压缩。传入 `File`,返回压缩后的 `Blob`。 ```typescript import FileTools from 'commonsy/file'; const image = new FileTools.CompressImage(file, 1024, 1024, 0.8); const blob = await image.compressImg(); console.log(blob); ``` 参数: | 参数 | 说明 | | --- | --- | | `file` | 浏览器文件对象 | | `maxWidth` | 最大宽度 | | `maxHeight` | 最大高度 | | `quality` | 图片质量,通常为 `0` 到 `1` | ### dataURLtoBlob 将 DataURL 转换为 Blob。 ```typescript import FileTools from 'commonsy/file'; const blob = FileTools.CompressImage.dataURLtoBlob(dataUrl); ``` ### formatFileSize `FileTools` 中也包含 `formatFileSize`。 ```typescript import FileTools from 'commonsy/file'; FileTools.formatFileSize(1024); // 1 KB ``` ## 下载链接工具 ### XunLeiDownloadUrl 将普通下载地址转换为迅雷 `thunder://` 协议地址。 ```typescript import DownloadUtils from 'commonsy/download'; const thunderUrl = new DownloadUtils.XunLeiDownloadUrl('http://localhost/file.zip').changeUrl(); console.log(thunderUrl); ``` ## 加密工具 ### Encryption 提供 MD5、AES、RSA 工具。 ```typescript import CryptoUtils from 'commonsy/crypto'; const encryption = new CryptoUtils.Encryption(); console.log(encryption.md5('abc')); // 900150983cd24fb0d6963f7d28e17f72 ``` ### AES 加密和解密 ```typescript import CryptoUtils from 'commonsy/crypto'; const encryption = new CryptoUtils.Encryption(); const result = encryption.aesEncrypt('hello'); console.log(result.encryptedData); console.log(result.key); console.log(result.iv); const text = encryption.aesDecrypt(result.encryptedData, result.key, result.iv); console.log(text); // hello ``` ### RSA 加密 ```typescript import CryptoUtils from 'commonsy/crypto'; const encryption = new CryptoUtils.Encryption(); const encrypted = encryption.rsaEncrypt('hello'); console.log(encrypted); ``` ### preEncrypt 按 `type` 自动分发加密方法。 ```typescript import CryptoUtils from 'commonsy/crypto'; const encryption = new CryptoUtils.Encryption(); encryption.preEncrypt({ type: 'MD5', value: 'abc' }); encryption.preEncrypt({ type: 'AES', value: 'hello' }); encryption.preEncrypt({ type: 'RSA', value: 'hello' }); ``` ## WebSocket 工具 ### WebSocketServer Node 服务端 WebSocket 封装。 ```typescript import WebSocketUtils from 'commonsy/websocket'; const server = new WebSocketUtils.WebSocketServer({ port: 8080 }); server.on('connection', (client) => { client.on('message', (message) => { console.log('收到消息:', message); client.send(`服务器已收到消息: ${message}`); }); client.on('close', () => { console.log('客户端已断开连接'); }); }); ``` 内置 JSON 消息类型: | type | 行为 | | --- | --- | | `auth` | 调用 `handleAuth(userId)` | | `greeting` | 返回欢迎信息 | | `question` | 返回问题回复 | | `ping` | 返回 `pong` | | `broadcast` | 广播 `content` 给其他客户端 | 可用方法: ```typescript server.on('connection', callback); server.broadcast('hello', senderSocket); server.close(); ``` ### WebSocketClient 浏览器或 Node 客户端 WebSocket 封装,支持心跳和自动重连。 ```typescript import WebSocketUtils from 'commonsy/websocket'; const client = new WebSocketUtils.WebSocketClient('ws://localhost:8080', { heartbeatInterval: 30000, reconnectDelay: 5000, }); client.connect('user-001'); client.sendMessage(JSON.stringify({ type: 'greeting' })); // 主动关闭 client.close(); ``` ## Cesium 地图工具 ### CesiumWrapper 按需加载 Cesium,封装 Viewer 初始化、相机控制、点线面绘制、标注、GeoJSON 加载和资源清理。 ```typescript import MapUtils from 'commonsy/map'; const map = new MapUtils.CesiumWrapper('container'); const viewer = await map.init({ animation: false, timeline: false, }); console.log(viewer); ``` ### 相机控制 ```typescript map.setCameraView({ longitude: 116.391, latitude: 39.907, height: 3000, heading: 0, pitch: -45, roll: 0, }); map.flyTo({ longitude: 116.391, latitude: 39.907, height: 3000, duration: 2, }); ``` ### 添加点 ```typescript const point = map.addPoint({ id: 'point-1', name: '位置点', longitude: 116.391, latitude: 39.907, height: 0, }); ``` ### 添加图片标注 ```typescript const marker = map.addBillboard({ id: 'marker-1', name: '图标标注', longitude: 116.391, latitude: 39.907, altitude: 0, image: '/marker.png', width: 32, billboardHeight: 32, }); ``` ### 添加文字标签 ```typescript const label = map.addLabel({ id: 'label-1', text: '北京', longitude: 116.391, latitude: 39.907, }); ``` ### 添加线 ```typescript const line = map.addPolyline({ id: 'line-1', positions: [ [116.391, 39.907, 0], [121.473, 31.23, 0], ], width: 4, }); ``` ### 添加面 ```typescript const polygon = map.addPolygon({ id: 'polygon-1', positions: [ [116.38, 39.9, 0], [116.4, 39.9, 0], [116.4, 39.92, 0], [116.38, 39.92, 0], ], }); ``` ### 加载 GeoJSON ```typescript const dataSource = await map.addGeoJson('/data/area.geojson', { flyTo: true, clampToGround: true, }); ``` ### 删除和清理 ```typescript map.removeEntity('point-1'); map.clearEntities(); map.clearDataSources(); map.destroy(); ``` 常用方法: | 方法 | 作用 | | --- | --- | | `init(options)` | 初始化 Viewer | | `loadCesium()` | 按需加载 Cesium 模块 | | `getViewer()` | 获取 Viewer 实例 | | `toCartesian(longitude, latitude, height)` | 经纬度转 Cartesian3 | | `toCartesianArray(positions)` | 经纬度数组转 Cartesian3 数组 | | `setCameraView(options)` | 立即设置相机视角 | | `flyTo(options)` | 飞行到指定位置 | | `addPoint(options)` | 添加点实体 | | `addBillboard(options)` | 添加图片标注 | | `addLabel(options)` | 添加文字标签 | | `addPolyline(options)` | 添加线实体 | | `addPolygon(options)` | 添加面实体 | | `addGeoJson(data, options)` | 加载 GeoJSON 数据源 | | `removeEntity(entityOrId)` | 删除实体 | | `clearEntities()` | 清空实体 | | `clearDataSources(destroy)` | 清空数据源 | | `destroy()` | 销毁 Viewer | 注意:Cesium 体积较大,业务项目需要自行安装并处理 Cesium 资源和样式。 ## 默认入口完整示例 ```typescript import sysFun from 'commonsy'; sysFun.CommonUtils.maskPhone('13812345678'); new sysFun.DateUtils.DateTimeFormatter('2022-10-10 11:11:10', 'yyyy-mm-dd').getFormattedDateTime(); new sysFun.MoneyUtils.ComputeMoney(100).add(50).toDollars(); new sysFun.ValidateUtils.FormValidation([{ val: '', valName: '姓名', validList: ['isNull'] }]).validationData(); new sysFun.BrowserUtils.GetBrowserType().throwType(); new sysFun.DownloadUtils.XunLeiDownloadUrl('http://localhost').changeUrl(); new sysFun.CryptoUtils.Encryption().md5('abc'); new sysFun.MapUtils.CesiumWrapper('container'); ``` ## 测试 ```bash npm test ``` ## 环境说明 - 包格式为 ES Module。 - `CompressImage` 依赖浏览器 `FileReader`、`Image`、`document`、`canvas`、`Blob`。 - `WebSocketServer` 依赖 Node 环境和 `ws`。 - `CesiumWrapper` 需要业务项目安装并配置 `cesium`。 - 加密工具依赖 `crypto-js` 和 `node-rsa`。