Authored by qxm

动作训练的pinia文件提交

import { defineStore } from 'pinia';
import ExercisesApi from '@/sheep/api/motion/exercises';
import SupersetsApi from '@/sheep/api/motion/supersets';
import TemplatesApi from '@/sheep/api/Template/Templates';
export const useTrainingStore = defineStore('training', {
state: () => ({
id: null, // 页面传过来的 id
type: null, // 页面传过来的 type
actionDetail: {}, // 接口返回的详情
loading: false,
unitRecords: {}, // 训练数据
trainingName: '',
// 训练时间
totalSeconds: 0,
isPause: true,
timerInterval: null,
showPicker: false,
defaultTimeIndex: [0, 0, 0],
trainingTimeText: '', //起始时间
min: false,
isSystem: 1, //官方模板为1
dailyTemplateId: null,
isTraining: false,
}),
actions: {
// 1. 根据 id 和 type 加载数据(动作/超级组/模板)
async loadTrainingDetail(id, type) {
console.log('进入pinia的模板数据加载函数');
if (!id || !type) return;
// 先保存 id 和 type 到 store
this.id = id;
this.type = type;
this.loading = true;
try {
let res;
if (type === 1) {
res = await ExercisesApi.getExerciseById(id);
} else if (type === 2) {
res = await SupersetsApi.getSupersetsInfo(id);
} else if (type === 3) {
if (this.isSystem === 1) {
res = await TemplatesApi.getTemplateDetail(id);
} else {
res = await TemplatesApi.getCustTemplateDetail(id);
}
console.log('pinia中打开模板数据:', res);
}
if (res?.data) {
this.actionDetail = res.data;
console.log('加载完模板数据之后进行赋值动态数据:++++++');
if (type === 3) {
this.initTemplateRecords();
}
}
} catch (err) {
console.error('加载训练详情失败:', err);
} finally {
this.loading = false;
}
},
loadDailyTemplateForEdit(fullDailyPlan) {
// 2. 🔥 核心:把【完整每日模板数据】直接赋值给 actionDetail
// 动作、顺序、超级组、组数、全部保留,不请求接口
this.actionDetail = { ...fullDailyPlan };
console.log('✅ 每日模板编辑:已赋值完整模板数据到 actionDetail', this.actionDetail);
// 3. 固定类型为模板
this.type = 3;
// 4. 保存ID
this.id = fullDailyPlan.templateId;
// 5. 初始化训练记录(重量、次数、完成状态)
this.unitRecords = {};
const units = this.actionDetail?.units || [];
console.log('每日模板的unit',units);
units.forEach((unit, unitIndex) => {
let records = {};
// 按顺序赋值,不依赖 exerciseId,动作可改、可换
unit.exercises?.forEach((ex, exIndex) => {
records[ex.exerciseId] = ex.sets || [];
});
this.unitRecords[unitIndex] = {
records: records,
userWeight: 70,
};
});
console.log('✅ 每日模板加载完成:', this.actionDetail, this.unitRecords);
},
// 初始化模板自带的训练数据到 unitRecords
initTemplateRecords() {
console.log('✅=================== 我执行了!开始初始化模板数据');
console.log('EEEEEEEEEEEEEEEEEEEEEE');
// 只在空的时候初始化(避免重复覆盖)
if (Object.keys(this.unitRecords).length > 0) return;
if (this.dailyTemplateId) return;
const units = this.actionDetail?.units || [];
units.forEach((unit, unitIndex) => {
let records = {};
const exercises = unit.exercises || [];
exercises.forEach((ex) => {
const sets = ex.sets || [];
// 转换 sets → 页面标准格式
const converted = sets.map((set) => {
const totalSec = set.duration || 0;
const h = String(Math.floor(totalSec / 3600)).padStart(2, '0');
const m = String(Math.floor((totalSec % 3600) / 60)).padStart(2, '0');
const s = String(totalSec % 60).padStart(2, '0');
return {
weight: set.weight ?? '',
reps: set.reps ?? '',
duration: set.duration ?? '',
distance: set.distance ?? '',
restTime: set.restTime ?? '',
h,
m,
s,
quickTimeDisplay: (set.restTime || 60) + 's',
// isActive: false,
isActive: (set.isCompleted ?? 0) === 1,
};
});
records[ex.exerciseId] = converted;
});
// 直接存入 Pinia
this.unitRecords[unitIndex] = {
records: records,
userWeight: 70,
};
});
},
//新增:每日模板专用赋值(真实训练记录)
initDailyTemplateRecords() {
console.log('✅ 每日模板:直接赋值真实训练记录');
this.unitRecords = {};
const units = this.actionDetail?.units || [];
units.forEach((unit, unitIndex) => {
let records = {};
const exercises = unit.exercises || [];
// exercises.forEach((ex) => {
// records[ex.exerciseId] = ex.sets || [];
// });
exercises.forEach((ex) => {
const sets = ex.sets || [];
// 转换 sets → 页面标准格式
const converted = sets.map((set) => {
const totalSec = set.duration || 0;
const h = String(Math.floor(totalSec / 3600)).padStart(2, '0');
const m = String(Math.floor((totalSec % 3600) / 60)).padStart(2, '0');
const s = String(totalSec % 60).padStart(2, '0');
return {
weight: set.weight ?? '',
reps: set.reps ?? '',
duration: set.duration ?? '',
distance: set.distance ?? '',
restTime: set.restTime ?? '',
h,
m,
s,
quickTimeDisplay: (set.restTime || 60) + 's',
// isActive: false,
isActive: (set.isCompleted ?? 0) === 1,
};
});
converted.forEach((item, idx) => {
console.log(`第${idx}组:`, item.h, item.m, item.s);
});
records[ex.exerciseId] = converted;
});
this.unitRecords[unitIndex] = {
records: records,
userWeight: 70,
};
});
},
// ======================
// ✅ 工具方法放到这里
// ======================
convertUnitToActionDetail(unit) {
//转为动作
const convertExercises = (list) => {
return (list || []).map((item) => ({
id: item.exerciseId,
name: item.exerciseName,
// urlImage: item.exerciseCover || item.url3dAnimation,
urlImage: item.url3dAnimation || item.urlImage,
exerciseType: item.exerciseType,
}));
};
if (unit.unitType === 2) {
return {
id: unit.supersetId || unit.unitId,
name: unit.unitName,
exercises: convertExercises(unit.exercises),
};
}
if (unit.unitType === 1) {
const act = (unit.exercises || [])[0] || {};
return {
id: act.exerciseId,
name: act.exerciseName,
urlImage: act.exerciseCover || act.url3dAnimation,
exerciseType: act.exerciseType,
categoryDescription: act.categoryDescription,
equipmentDescription: act.equipmentDescription,
};
}
return {};
},
// 替换动作时转换id 和 type 方便替换 新的数据详情 (actionDetail)
replaceAction(newId, newType, newDetail) {
this.id = newId;
this.type = newType;
this.actionDetail = { ...newDetail };
this.unitRecords = {};
},
// 把当前 动作/超级组 转为模板结构(type=3)
convertToTemplate() {
// 已经是模板,不用转
if (this.type === 3) {
return;
}
const units = [];
// 1. 动作 type=1 → 转 unitType=1
if (this.type === 1) {
units.push({
unitType: 1,
unitId: this.actionDetail.id,
unitName: this.actionDetail.name,
exercises: [
{
exerciseId: this.actionDetail.id,
exerciseName: this.actionDetail.name,
exerciseType: this.actionDetail.exerciseType,
urlImage: this.actionDetail.urlImage || this.actionDetail.url3dAnimation,
categoryDescription: this.actionDetail.categoryDescription,
equipmentDescription: this.actionDetail.equipmentDescription,
},
],
});
}
// 2. 超级组 type=2 → 转 unitType=2
else if (this.type === 2) {
units.push({
unitType: 2,
unitId: this.actionDetail.id,
supersetId: this.actionDetail.id,
unitName: this.actionDetail.name,
exercises: this.actionDetail.exercises.map((item) => ({
exerciseId: item.id,
exerciseName: item.name,
exerciseType: item.exerciseType,
urlImage: item.url3dAnimation || item.urlImage,
})),
});
}
// 切换为模板模式
this.type = 3;
this.actionDetail = {
units,
templateName: this.actionDetail.name || '训练',
};
},
// 训练数据的处理
// 保存一个动作的训练数据
saveUnitRecord(unitIndex, data) {
this.unitRecords[unitIndex] = {
records: data.records || {},
userWeight: data.userWeight ?? 70,
};
},
//获取一个动作的训练数据
getUnitRecord(unitIndex) {
return (
this.unitRecords[unitIndex] || {
records: {},
userWeight: 70,
}
);
},
//删除一个动作的所有数据
deleteUnitRecord(unitIndex) {
delete this.unitRecords[unitIndex];
},
// 单独更新某个动作的体重
updateUnitUserWeight(unitIndex, userWeight) {
// 如果这个 unit 还没有数据,先创建一个空结构
if (!this.unitRecords[unitIndex]) {
this.unitRecords[unitIndex] = {
records: {},
userWeight: 70,
};
}
// 直接修改体重
this.unitRecords[unitIndex].userWeight = userWeight;
},
// 设置训练名称
setTrainingName(name) {
this.trainingName = name;
},
// 获取训练名称
getTrainingName() {
return this.trainingName || '训练';
},
// ======================
// 👇 新增 全局计时 方法
// ======================
toggleTimer() {
this.isPause = !this.isPause;
if (!this.isPause) {
// 开启定时器
this.timerInterval = setInterval(() => {
this.totalSeconds++;
}, 1000);
} else {
// 暂停定时器
clearInterval(this.timerInterval);
this.timerInterval = null;
}
},
resetTimer() {
this.totalSeconds = 0;
},
setTotalSeconds(seconds) {
this.totalSeconds = seconds;
},
openTimePicker() {
const h = Math.floor(this.totalSeconds / 3600);
const m = Math.floor((this.totalSeconds % 3600) / 60);
const s = this.totalSeconds % 60;
this.defaultTimeIndex = [h, m, s];
this.showPicker = true;
},
closeTimePicker() {
this.showPicker = false;
},
// 清空计时(在clearStore时调用)
clearTimer() {
if (this.timerInterval) {
clearInterval(this.timerInterval);
this.timerInterval = null;
}
this.totalSeconds = 0;
this.isPause = true;
this.showPicker = false;
},
setTrainingTimeText(val) {
this.trainingTimeText = val;
},
// 清空
clearTrainingStore() {
this.clearTimer();
this.id = null;
this.type = null;
this.actionDetail = {};
this.loading = false;
this.unitRecords = {};
this.trainingTimeText = '';
this.min = false;
this.isSystem = 1;
},
},
persist: true, // 持久化
});
... ...