From 4a77dc1b8888972a78a083acba2858333edd6beb Mon Sep 17 00:00:00 2001 From: richarjiang Date: Thu, 14 Aug 2025 21:14:18 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=9B=B4=E6=96=B0=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E9=A1=B9=E7=9A=84=E6=BA=90=E5=9C=B0=E5=9D=80=EF=BC=8C?= =?UTF-8?q?=E5=B0=86=E6=89=80=E6=9C=89=E4=BE=9D=E8=B5=96=E7=9A=84=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E5=9C=B0=E5=9D=80=E6=9B=B4=E6=94=B9=E4=B8=BA=E5=AE=98?= =?UTF-8?q?=E6=96=B9=E7=9A=84Yarn=E6=B3=A8=E5=86=8C=E8=A1=A8=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=EF=BC=8C=E5=B9=B6=E5=9C=A8=E5=BA=94=E7=94=A8=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E4=B8=AD=E5=BC=95=E5=85=A5=E6=96=B0=E7=9A=84Exercises?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/exercises-seed.sql | 65 +++++++++++++++ package-lock.json | 2 +- src/app.module.ts | 2 + src/exercises/dto/exercise.dto.ts | 28 +++++++ src/exercises/exercises.controller.ts | 24 ++++++ src/exercises/exercises.module.ts | 17 ++++ src/exercises/exercises.service.ts | 82 +++++++++++++++++++ .../models/exercise-category.model.ts | 41 ++++++++++ src/exercises/models/exercise.model.ts | 42 ++++++++++ yarn.lock | 48 +++++------ 10 files changed, 326 insertions(+), 25 deletions(-) create mode 100644 docs/exercises-seed.sql create mode 100644 src/exercises/dto/exercise.dto.ts create mode 100644 src/exercises/exercises.controller.ts create mode 100644 src/exercises/exercises.module.ts create mode 100644 src/exercises/exercises.service.ts create mode 100644 src/exercises/models/exercise-category.model.ts create mode 100644 src/exercises/models/exercise.model.ts diff --git a/docs/exercises-seed.sql b/docs/exercises-seed.sql new file mode 100644 index 0000000..d29d049 --- /dev/null +++ b/docs/exercises-seed.sql @@ -0,0 +1,65 @@ +-- 一键导入普拉提动作分类与动作(MySQL 8+) +-- 说明:表由 Sequelize 同步创建(t_exercise_categories / t_exercises) +-- 若要幂等导入,使用 INSERT ... ON DUPLICATE KEY UPDATE + +START TRANSACTION; + +-- 分类 +INSERT INTO `t_exercise_categories` (`key`, `name`, `sort_order`, `created_at`, `updated_at`) VALUES + ('core', '核心与腹部', 0, NOW(), NOW()), + ('spine_posterior_chain', '脊柱与后链', 1, NOW(), NOW()), + ('lateral_hip', '侧链与髋', 2, NOW(), NOW()), + ('balance_support', '平衡与支撑', 3, NOW(), NOW()), + ('advanced_control', '进阶控制', 4, NOW(), NOW()), + ('mobility_stretch', '柔韧与拉伸', 5, NOW(), NOW()) +ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `sort_order` = VALUES(`sort_order`), `updated_at` = NOW(); + +-- 动作 +INSERT INTO `t_exercises` (`key`, `name`, `description`, `category_key`, `category_name`, `sort_order`, `created_at`, `updated_at`) VALUES + ('hundred', '百次拍击 (The Hundred)', '仰卧桌面位,小幅摆臂协同吸呼,核心激活。', 'core', '核心与腹部', 0, NOW(), NOW()), + ('single_leg_stretch', '单腿伸展 (Single Leg Stretch)', '交替伸直一条腿,另一腿屈膝抱向胸口,稳定骨盆。', 'core', '核心与腹部', 1, NOW(), NOW()), + ('double_leg_stretch', '双腿伸展 (Double Leg Stretch)', '双臂双腿同时伸直/收回,呼吸控制,核心稳定。', 'core', '核心与腹部', 2, NOW(), NOW()), + ('criss_cross', '扭转卷腹 (Criss Cross)', '肘碰对侧膝,腹斜肌发力与呼吸配合。', 'core', '核心与腹部', 3, NOW(), NOW()), + ('single_straight_leg', '单腿直剪 (Scissors)', '交替拉长上抬直腿,控制下放,避免耸肩。', 'core', '核心与腹部', 4, NOW(), NOW()), + ('double_straight_leg', '双腿抬降 (Double Straight Leg Lower Lift)', '双腿并拢抬降,腹直肌抗伸展。', 'core', '核心与腹部', 5, NOW(), NOW()), + ('spine_stretch_forward', '脊柱前伸 (Spine Stretch Forward)', '坐姿脊柱分节前伸,强调轴向延展与呼吸。', 'core', '核心与腹部', 6, NOW(), NOW()), + ('roll_up', '卷起 (Roll Up)', '仰卧分节卷起到坐,前屈后还原,控制节律。', 'core', '核心与腹部', 7, NOW(), NOW()), + ('rolling_like_a_ball', '小球滚动 (Rolling Like a Ball)', '抱膝蜷成球,控制滚动回正,核心稳定。', 'core', '核心与腹部', 8, NOW(), NOW()), + ('teaser', '船式 (Teaser)', 'V字平衡,腿躯干对抗重力与摆动。', 'core', '核心与腹部', 9, NOW(), NOW()), + + ('swan', '天鹅式 (Swan)', '俯卧伸展胸椎,后链发力,延展不挤压。', 'spine_posterior_chain', '脊柱与后链', 10, NOW(), NOW()), + ('swan_dive', '天鹅下潜 (Swan Dive)', '在Swan基础上前后摆动,弹性控制。', 'spine_posterior_chain', '脊柱与后链', 11, NOW(), NOW()), + ('swimming', '游泳式 (Swimming)', '俯卧交替抬对侧上肢与下肢,脊柱中立。', 'spine_posterior_chain', '脊柱与后链', 12, NOW(), NOW()), + ('shoulder_bridge', '肩桥 (Shoulder Bridge)', '仰卧卷尾抬盆,臀腿后侧力量与脊柱分节。', 'spine_posterior_chain', '脊柱与后链', 13, NOW(), NOW()), + ('spine_twist', '脊柱扭转 (Spine Twist)', '坐姿轴向延展上的控制旋转。', 'spine_posterior_chain', '脊柱与后链', 14, NOW(), NOW()), + ('saw', '锯式 (Saw)', '坐姿分腿,旋转前屈触对侧脚尖。', 'spine_posterior_chain', '脊柱与后链', 15, NOW(), NOW()), + + ('side_kick_front_back', '侧踢腿 前后摆 (Side Kick Front/Back)', '侧卧,髋稳定,腿前后摆动。', 'lateral_hip', '侧链与髋', 16, NOW(), NOW()), + ('side_kick_up_down', '侧踢腿 上下 (Side Kick Up/Down)', '侧卧,上侧腿上抬下放,控制不耸肩。', 'lateral_hip', '侧链与髋', 17, NOW(), NOW()), + ('side_leg_lift', '侧抬腿 (Side Leg Lift)', '侧卧抬腿,髋稳定,中臀肌激活。', 'lateral_hip', '侧链与髋', 18, NOW(), NOW()), + ('clam', '蛤蜊式 (Clam)', '侧卧屈髋屈膝,抬起上侧膝,臀中刺激。', 'lateral_hip', '侧链与髋', 19, NOW(), NOW()), + ('mermaid', '美人鱼 (Mermaid)', '坐姿侧屈拉伸,改善侧链柔韧。', 'lateral_hip', '侧链与髋', 20, NOW(), NOW()), + + ('plank', '平板支撑 (Plank)', '掌/前臂支撑,身体成一直线,核心稳定。', 'balance_support', '平衡与支撑', 21, NOW(), NOW()), + ('side_plank', '侧板支撑 (Side Plank)', '单侧支撑,侧链与肩带稳定。', 'balance_support', '平衡与支撑', 22, NOW(), NOW()), + ('push_up', '俯卧撑 (Push Up)', '胸肩臂与核心协同的推举支撑。', 'balance_support', '平衡与支撑', 23, NOW(), NOW()), + ('leg_pull_front', '前拉腿 (Leg Pull Front)', '俯撑抬腿,后链与肩带控制。', 'balance_support', '平衡与支撑', 24, NOW(), NOW()), + ('leg_pull_back', '后拉腿 (Leg Pull Back)', '仰撑抬腿,后链与肩带控制。', 'balance_support', '平衡与支撑', 25, NOW(), NOW()), + + ('jackknife', '折刀 (Jackknife)', '仰卧抬腿过头后折刀上推,核心与控制。', 'advanced_control', '进阶控制', 26, NOW(), NOW()), + ('open_leg_rocker', '开腿摇滚 (Open Leg Rocker)', '开腿V坐平衡,来回滚动。', 'advanced_control', '进阶控制', 27, NOW(), NOW()), + ('corkscrew', '开瓶器 (Corkscrew)', '躯干稳定下的双腿画圈,控制髋与核心。', 'advanced_control', '进阶控制', 28, NOW(), NOW()), + ('boomerang', '回旋镖 (Boomerang)', '融合Roll Over/Teaser的串联流畅控制。', 'advanced_control', '进阶控制', 29, NOW(), NOW()), + ('control_balance', '控制平衡 (Control Balance)', '过头位下的单腿抬降与控制。', 'advanced_control', '进阶控制', 30, NOW(), NOW()), + ('neck_pull', '抱颈卷起 (Neck Pull)', '更具挑战的卷起,背侧链参与更高。', 'advanced_control', '进阶控制', 31, NOW(), NOW()), + ('roll_over', '翻滚过头 (Roll Over)', '仰卧双腿过头落地,脊柱分节控制。', 'advanced_control', '进阶控制', 32, NOW(), NOW()), + + ('cat_cow', '猫牛 (Cat-Cow)', '四点支撑的屈伸热身/整理放松。', 'mobility_stretch', '柔韧与拉伸', 33, NOW(), NOW()), + ('hamstring_stretch', '腘绳肌拉伸', '仰卧或坐姿,拉伸大腿后侧。', 'mobility_stretch', '柔韧与拉伸', 34, NOW(), NOW()), + ('hip_flexor_stretch', '髋屈肌拉伸', '弓步位,前髋前侧拉伸。', 'mobility_stretch', '柔韧与拉伸', 35, NOW(), NOW()), + ('thoracic_extension', '胸椎伸展', '泡沫轴/垫上胸椎延展放松。', 'mobility_stretch', '柔韧与拉伸', 36, NOW(), NOW()) +ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `description` = VALUES(`description`), `category_key` = VALUES(`category_key`), `category_name` = VALUES(`category_name`), `sort_order` = VALUES(`sort_order`), `updated_at` = NOW(); + +COMMIT; + + diff --git a/package-lock.json b/package-lock.json index 9b2f289..aecdd5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13525,4 +13525,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/app.module.ts b/src/app.module.ts index ae0fb7f..4f9edca 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -11,6 +11,7 @@ import { TrainingPlansModule } from './training-plans/training-plans.module'; import { ArticlesModule } from './articles/articles.module'; import { RecommendationsModule } from './recommendations/recommendations.module'; import { ActivityLogsModule } from './activity-logs/activity-logs.module'; +import { ExercisesModule } from './exercises/exercises.module'; @Module({ imports: [ @@ -27,6 +28,7 @@ import { ActivityLogsModule } from './activity-logs/activity-logs.module'; ArticlesModule, RecommendationsModule, ActivityLogsModule, + ExercisesModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/exercises/dto/exercise.dto.ts b/src/exercises/dto/exercise.dto.ts new file mode 100644 index 0000000..adade9f --- /dev/null +++ b/src/exercises/dto/exercise.dto.ts @@ -0,0 +1,28 @@ +export interface ExerciseLibraryItem { + key: string; + name: string; + description: string; + category: string; // 中文分类名 +} + +export interface ExerciseCategoryDto { + key: string; // 英文 key + name: string; // 中文名 + sortOrder?: number; +} + +export interface ExerciseDto { + key: string; + name: string; + description: string; + categoryKey: string; + categoryName: string; + sortOrder?: number; +} + +export interface ExerciseConfigResponse { + categories: ExerciseCategoryDto[]; + exercises: ExerciseDto[]; +} + + diff --git a/src/exercises/exercises.controller.ts b/src/exercises/exercises.controller.ts new file mode 100644 index 0000000..808dc16 --- /dev/null +++ b/src/exercises/exercises.controller.ts @@ -0,0 +1,24 @@ +import { Controller, Get, HttpCode, HttpStatus, UseGuards } from '@nestjs/common'; +import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { Public } from '../common/decorators/public.decorator'; +import { JwtAuthGuard } from '../common/guards/jwt-auth.guard'; +import { ExercisesService } from './exercises.service'; +import { ExerciseConfigResponse } from './dto/exercise.dto'; + +@ApiTags('exercises') +@Controller('exercises') +@UseGuards(JwtAuthGuard) +export class ExercisesController { + constructor(private readonly exercisesService: ExercisesService) {} + + @Get('config') + @Public() + @HttpCode(HttpStatus.OK) + @ApiOperation({ summary: '获取动作分类与动作配置(公开)' }) + @ApiResponse({ status: 200 }) + async getConfig(): Promise { + return this.exercisesService.getConfig(); + } +} + + diff --git a/src/exercises/exercises.module.ts b/src/exercises/exercises.module.ts new file mode 100644 index 0000000..c4e0506 --- /dev/null +++ b/src/exercises/exercises.module.ts @@ -0,0 +1,17 @@ +import { Module } from '@nestjs/common'; +import { SequelizeModule } from '@nestjs/sequelize'; +import { ExercisesController } from './exercises.controller'; +import { ExercisesService } from './exercises.service'; +import { ExerciseCategory } from './models/exercise-category.model'; +import { Exercise } from './models/exercise.model'; +import { UsersModule } from '../users/users.module'; + +@Module({ + imports: [SequelizeModule.forFeature([ExerciseCategory, Exercise]), UsersModule], + controllers: [ExercisesController], + providers: [ExercisesService], + exports: [ExercisesService], +}) +export class ExercisesModule {} + + diff --git a/src/exercises/exercises.service.ts b/src/exercises/exercises.service.ts new file mode 100644 index 0000000..22aaef4 --- /dev/null +++ b/src/exercises/exercises.service.ts @@ -0,0 +1,82 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/sequelize'; +import { ExerciseCategory } from './models/exercise-category.model'; +import { Exercise } from './models/exercise.model'; +import { ExerciseConfigResponse, ExerciseLibraryItem } from './dto/exercise.dto'; + +@Injectable() +export class ExercisesService { + constructor( + @InjectModel(ExerciseCategory) private readonly categoryModel: typeof ExerciseCategory, + @InjectModel(Exercise) private readonly exerciseModel: typeof Exercise, + ) {} + + async getConfig(): Promise { + const [categories, exercises] = await Promise.all([ + this.categoryModel.findAll({ order: [['sort_order', 'ASC']] }), + this.exerciseModel.findAll({ order: [['category_key', 'ASC'], ['sort_order', 'ASC']] }), + ]); + + return { + categories: categories.map((c) => ({ key: c.key, name: c.name, sortOrder: c.sortOrder })), + exercises: exercises.map((e) => ({ + key: e.key, + name: e.name, + description: e.description, + categoryKey: e.categoryKey, + categoryName: e.categoryName, + sortOrder: e.sortOrder, + })), + }; + } + + async seedFromLibrary(library: ExerciseLibraryItem[]): Promise { + const categoryNameToKey: Record = {}; + const uniqueCategoryNames = Array.from(new Set(library.map((i) => i.category))); + + uniqueCategoryNames.forEach((name) => { + const key = this.slugifyCategory(name); + categoryNameToKey[name] = key; + }); + + await this.categoryModel.bulkCreate( + uniqueCategoryNames.map((name, index) => ({ + key: categoryNameToKey[name], + name, + sortOrder: index, + })), + { ignoreDuplicates: true }, + ); + + await this.exerciseModel.bulkCreate( + library.map((item, index) => ({ + key: item.key, + name: item.name, + description: item.description, + categoryKey: categoryNameToKey[item.category], + categoryName: item.category, + sortOrder: index, + })), + { ignoreDuplicates: true }, + ); + } + + private slugifyCategory(name: string): string { + const mapping: Record = { + '核心与腹部': 'core', + '脊柱与后链': 'spine_posterior_chain', + '侧链与髋': 'lateral_hip', + '平衡与支撑': 'balance_support', + '进阶控制': 'advanced_control', + '柔韧与拉伸': 'mobility_stretch', + }; + return mapping[name] || name + .normalize('NFKD') + .replace(/[\u0300-\u036f]/g, '') + .replace(/[^a-zA-Z0-9]+/g, '_') + .replace(/^_+|_+$/g, '') + .toLowerCase(); + } +} + + diff --git a/src/exercises/models/exercise-category.model.ts b/src/exercises/models/exercise-category.model.ts new file mode 100644 index 0000000..ea2533a --- /dev/null +++ b/src/exercises/models/exercise-category.model.ts @@ -0,0 +1,41 @@ +import { Column, DataType, HasMany, Model, Table } from 'sequelize-typescript'; +import { Exercise } from './exercise.model'; + +@Table({ + tableName: 't_exercise_categories', + underscored: true, +}) +export class ExerciseCategory extends Model { + @Column({ + type: DataType.STRING, + primaryKey: true, + comment: '分类唯一键(英文/下划线)', + }) + declare key: string; + + @Column({ + type: DataType.STRING, + allowNull: false, + comment: '分类中文名称', + }) + declare name: string; + + @Column({ + type: DataType.INTEGER, + allowNull: false, + defaultValue: 0, + comment: '排序(升序)', + }) + declare sortOrder: number; + + @HasMany(() => Exercise, { foreignKey: 'categoryKey', sourceKey: 'key' }) + declare exercises: Exercise[]; + + @Column({ type: DataType.DATE, defaultValue: DataType.NOW }) + declare createdAt: Date; + + @Column({ type: DataType.DATE, defaultValue: DataType.NOW }) + declare updatedAt: Date; +} + + diff --git a/src/exercises/models/exercise.model.ts b/src/exercises/models/exercise.model.ts new file mode 100644 index 0000000..37e62f6 --- /dev/null +++ b/src/exercises/models/exercise.model.ts @@ -0,0 +1,42 @@ +import { BelongsTo, Column, DataType, ForeignKey, Model, Table } from 'sequelize-typescript'; +import { ExerciseCategory } from './exercise-category.model'; + +@Table({ + tableName: 't_exercises', + underscored: true, +}) +export class Exercise extends Model { + @Column({ + type: DataType.STRING, + primaryKey: true, + comment: '动作唯一键(英文/下划线)', + }) + declare key: string; + + @Column({ type: DataType.STRING, allowNull: false, comment: '名称(含中英文)' }) + declare name: string; + + @Column({ type: DataType.STRING, allowNull: false, comment: '中文分类名(冗余,便于展示)' }) + declare categoryName: string; + + @Column({ type: DataType.TEXT, allowNull: false, comment: '描述' }) + declare description: string; + + @ForeignKey(() => ExerciseCategory) + @Column({ type: DataType.STRING, allowNull: false, comment: '分类键' }) + declare categoryKey: string; + + @BelongsTo(() => ExerciseCategory, { foreignKey: 'categoryKey', targetKey: 'key' }) + declare category: ExerciseCategory; + + @Column({ type: DataType.INTEGER, allowNull: false, defaultValue: 0, comment: '排序(分类内)' }) + declare sortOrder: number; + + @Column({ type: DataType.DATE, defaultValue: DataType.NOW }) + declare createdAt: Date; + + @Column({ type: DataType.DATE, defaultValue: DataType.NOW }) + declare updatedAt: Date; +} + + diff --git a/yarn.lock b/yarn.lock index ad201ef..780d236 100644 --- a/yarn.lock +++ b/yarn.lock @@ -879,12 +879,12 @@ "@napi-rs/nice-android-arm-eabi@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz#9a0cba12706ff56500df127d6f4caf28ddb94936" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz#9a0cba12706ff56500df127d6f4caf28ddb94936" integrity sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w== "@napi-rs/nice-android-arm64@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz#32fc32e9649bd759d2a39ad745e95766f6759d2f" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz#32fc32e9649bd759d2a39ad745e95766f6759d2f" integrity sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA== "@napi-rs/nice-darwin-arm64@1.0.1": @@ -894,67 +894,67 @@ "@napi-rs/nice-darwin-x64@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz#f1b1365a8370c6a6957e90085a9b4873d0e6a957" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz#f1b1365a8370c6a6957e90085a9b4873d0e6a957" integrity sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ== "@napi-rs/nice-freebsd-x64@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz#4280f081efbe0b46c5165fdaea8b286e55a8f89e" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz#4280f081efbe0b46c5165fdaea8b286e55a8f89e" integrity sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw== "@napi-rs/nice-linux-arm-gnueabihf@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz#07aec23a9467ed35eb7602af5e63d42c5d7bd473" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz#07aec23a9467ed35eb7602af5e63d42c5d7bd473" integrity sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q== "@napi-rs/nice-linux-arm64-gnu@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz#038a77134cc6df3c48059d5a5e199d6f50fb9a90" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz#038a77134cc6df3c48059d5a5e199d6f50fb9a90" integrity sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA== "@napi-rs/nice-linux-arm64-musl@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz#715d0906582ba0cff025109f42e5b84ea68c2bcc" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz#715d0906582ba0cff025109f42e5b84ea68c2bcc" integrity sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw== "@napi-rs/nice-linux-ppc64-gnu@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz#ac1c8f781c67b0559fa7a1cd4ae3ca2299dc3d06" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz#ac1c8f781c67b0559fa7a1cd4ae3ca2299dc3d06" integrity sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q== "@napi-rs/nice-linux-riscv64-gnu@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz#b0a430549acfd3920ffd28ce544e2fe17833d263" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz#b0a430549acfd3920ffd28ce544e2fe17833d263" integrity sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig== "@napi-rs/nice-linux-s390x-gnu@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz#5b95caf411ad72a965885217db378c4d09733e97" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz#5b95caf411ad72a965885217db378c4d09733e97" integrity sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg== "@napi-rs/nice-linux-x64-gnu@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz#a98cdef517549f8c17a83f0236a69418a90e77b7" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz#a98cdef517549f8c17a83f0236a69418a90e77b7" integrity sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA== "@napi-rs/nice-linux-x64-musl@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz#5e26843eafa940138aed437c870cca751c8a8957" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz#5e26843eafa940138aed437c870cca751c8a8957" integrity sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ== "@napi-rs/nice-win32-arm64-msvc@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz#bd62617d02f04aa30ab1e9081363856715f84cd8" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz#bd62617d02f04aa30ab1e9081363856715f84cd8" integrity sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg== "@napi-rs/nice-win32-ia32-msvc@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz#b8b7aad552a24836027473d9b9f16edaeabecf18" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz#b8b7aad552a24836027473d9b9f16edaeabecf18" integrity sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw== "@napi-rs/nice-win32-x64-msvc@1.0.1": version "1.0.1" - resolved "https://mirrors.tencent.com/npm/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz#37d8718b8f722f49067713e9f1e85540c9a3dd09" + resolved "https://registry.yarnpkg.com/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz#37d8718b8f722f49067713e9f1e85540c9a3dd09" integrity sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg== "@napi-rs/nice@^1.0.1": @@ -1232,47 +1232,47 @@ "@swc/core-darwin-x64@1.11.13": version "1.11.13" - resolved "https://mirrors.tencent.com/npm/@swc/core-darwin-x64/-/core-darwin-x64-1.11.13.tgz#9cad870d48ebff805e8946ddcbe3d8312182f70b" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.11.13.tgz#9cad870d48ebff805e8946ddcbe3d8312182f70b" integrity sha512-uSA4UwgsDCIysUPfPS8OrQTH2h9spO7IYFd+1NB6dJlVGUuR6jLKuMBOP1IeLeax4cGHayvkcwSJ3OvxHwgcZQ== "@swc/core-linux-arm-gnueabihf@1.11.13": version "1.11.13" - resolved "https://mirrors.tencent.com/npm/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.13.tgz#51839e5a850bfa300e2c838fee8379e4dba1de78" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.13.tgz#51839e5a850bfa300e2c838fee8379e4dba1de78" integrity sha512-boVtyJzS8g30iQfe8Q46W5QE/cmhKRln/7NMz/5sBP/am2Lce9NL0d05NnFwEWJp1e2AMGHFOdRr3Xg1cDiPKw== "@swc/core-linux-arm64-gnu@1.11.13": version "1.11.13" - resolved "https://mirrors.tencent.com/npm/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.13.tgz#4145f1e504bdfa92604aee883d777bc8c4fba5d7" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.13.tgz#4145f1e504bdfa92604aee883d777bc8c4fba5d7" integrity sha512-+IK0jZ84zHUaKtwpV+T+wT0qIUBnK9v2xXD03vARubKF+eUqCsIvcVHXmLpFuap62dClMrhCiwW10X3RbXNlHw== "@swc/core-linux-arm64-musl@1.11.13": version "1.11.13" - resolved "https://mirrors.tencent.com/npm/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.13.tgz#b1813ae2e99e386ca16fff5af6601ac45ef57c5b" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.13.tgz#b1813ae2e99e386ca16fff5af6601ac45ef57c5b" integrity sha512-+ukuB8RHD5BHPCUjQwuLP98z+VRfu+NkKQVBcLJGgp0/+w7y0IkaxLY/aKmrAS5ofCNEGqKL+AOVyRpX1aw+XA== "@swc/core-linux-x64-gnu@1.11.13": version "1.11.13" - resolved "https://mirrors.tencent.com/npm/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.13.tgz#13b89a0194c4033c01400e9c65d9c21c56a4a6cd" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.13.tgz#13b89a0194c4033c01400e9c65d9c21c56a4a6cd" integrity sha512-q9H3WI3U3dfJ34tdv60zc8oTuWvSd5fOxytyAO9Pc5M82Hic3jjWaf2xBekUg07ubnMZpyfnv+MlD+EbUI3Llw== "@swc/core-linux-x64-musl@1.11.13": version "1.11.13" - resolved "https://mirrors.tencent.com/npm/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.13.tgz#0d0e5aa889dd4da69723e2287c3c1714d9bfd8aa" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.13.tgz#0d0e5aa889dd4da69723e2287c3c1714d9bfd8aa" integrity sha512-9aaZnnq2pLdTbAzTSzy/q8dr7Woy3aYIcQISmw1+Q2/xHJg5y80ZzbWSWKYca/hKonDMjIbGR6dp299I5J0aeA== "@swc/core-win32-arm64-msvc@1.11.13": version "1.11.13" - resolved "https://mirrors.tencent.com/npm/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.13.tgz#ad7281f9467e3de09f52615afe2276a8ef738a9d" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.13.tgz#ad7281f9467e3de09f52615afe2276a8ef738a9d" integrity sha512-n3QZmDewkHANcoHvtwvA6yJbmS4XJf0MBMmwLZoKDZ2dOnC9D/jHiXw7JOohEuzYcpLoL5tgbqmjxa3XNo9Oow== "@swc/core-win32-ia32-msvc@1.11.13": version "1.11.13" - resolved "https://mirrors.tencent.com/npm/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.13.tgz#046f6dbddb5b69a29bbaa98de104090a46088b74" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.13.tgz#046f6dbddb5b69a29bbaa98de104090a46088b74" integrity sha512-wM+Nt4lc6YSJFthCx3W2dz0EwFNf++j0/2TQ0Js9QLJuIxUQAgukhNDVCDdq8TNcT0zuA399ALYbvj5lfIqG6g== "@swc/core-win32-x64-msvc@1.11.13": version "1.11.13" - resolved "https://mirrors.tencent.com/npm/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.13.tgz#0412620d8594a7d3e482d3e79d9e89d80f9a14c0" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.13.tgz#0412620d8594a7d3e482d3e79d9e89d80f9a14c0" integrity sha512-+X5/uW3s1L5gK7wAo0E27YaAoidJDo51dnfKSfU7gF3mlEUuWH8H1bAy5OTt2mU4eXtfsdUMEVXSwhDlLtQkuA== "@swc/core@^1.10.7":