refactor(stores): 重构 common store 并优化数据类型定义- 定义明确的接口和类型,提高代码可读性和维护性

- 优化数据处理逻辑,使用 UUID 生成唯一 ID- 调整 NPS评分范围,提高用户体验
-优化问卷设计界面布局,提升可操作性
This commit is contained in:
陈昱达
2025-03-23 14:27:19 +08:00
parent 32a87991e1
commit e5ad917d6e
4 changed files with 56 additions and 35 deletions

View File

@@ -1,27 +1,42 @@
// src/stores/modules/common.ts
import { defineStore } from 'pinia';
// 假设 uid 是一个生成唯一 ID 的函数
// 如果没有现成的 uid 函数,可以引入一个 UUID 库
// 或者使用其他 UUID 库
import { v4 as uuidv4 } from 'uuid';
// 定义接口以明确数据结构
interface QuestionPage {
page: number;
pageId?: string; // 唯一 ID
}
interface QuestionsInfo {
survey: {
ip_number: number;
is_ip_number: number;
is_browser_number: number;
browser_number: number;
};
logics: any[]; // 根据实际需求调整类型
questions: QuestionPage[]; // 明确类型
cycle_pages: null | number; // 根据实际需求调整类型
}
export const useCommonStore = defineStore('common', {
state: () => ({
state: (): { questionsInfo: QuestionsInfo } => ({
questionsInfo: {
survey: { ip_number: 1, is_ip_number: 1, is_browser_number: 1, browser_number: 1 },
logics: [],
questions: [],
questions: [], // 初始化为明确类型的空数组
cycle_pages: null
}
}),
actions: {
async fetchQuestionInfo(questionInfo) {
async fetchQuestionInfo(questionInfo: string) {
try {
if (!questionInfo) return;
const info = JSON.parse(questionInfo);
const info = JSON.parse(questionInfo) as QuestionsInfo; // 类型断言
if (info?.questions?.length) {
info.questions.forEach((page) => {
info.questions.forEach((page: QuestionPage) => {
// 使用 UUID 生成唯一 ID
if (page?.page) {
page.pageId = page.pageId || uuidv4();
@@ -30,20 +45,20 @@ export const useCommonStore = defineStore('common', {
}
this.setQuestionInfo(info);
} catch (error) {
// 未来扩展
console.error('Error fetching question info:', error);
}
},
setQuestionInfo(questionInfo) {
setQuestionInfo(questionInfo: Partial<QuestionsInfo>) {
// 保持原有响应式引用,仅更新变化的部分
this.questionsInfo = Object.assign({}, this.questionsInfo, questionInfo);
// 对嵌套结构特殊处理(如数组需要保持引用)
if (questionInfo.questions) {
this.questionsInfo.questions = [...questionInfo.questions];
this.questionsInfo.questions = [...questionInfo.questions]; // 类型已明确,无需额外断言
}
}
},
getters: {
getQuestionsInfo: (state) => state.questionsInfo
getQuestionsInfo: (state): QuestionsInfo => state.questionsInfo
}
});

View File

@@ -37,7 +37,7 @@ export default {
prompt_right: '极有可能',
prompt_center: '',
max: 10,
min: 0,
min: 1,
score_interval: 1,
score_type: 0,
score_way: 1,

View File

@@ -266,12 +266,12 @@ const debouncedSaveQueItem = debounce((logics, newVal) => {
saveQueItem(logics, newVal);
let questionCopy = JSON.parse(JSON.stringify(questionInfo.value.questions));
questionCopy = questionCopy.map((item, index) => {
return {
...item,
title: index + 1
};
});
// questionCopy = questionCopy.map((item, index) => {
// return {
// ...item,
// title: index + 1
// };
// });
// 保存全部 更新title
// saveQueItem(questionInfo.value.logics, questionCopy);
}
@@ -279,9 +279,10 @@ const debouncedSaveQueItem = debounce((logics, newVal) => {
// 在 watch 回调中调用这个已经防抖过的函数
watch(
() => questionInfo.value.questions,
() => {
// debouncedSaveQueItem(questionInfo.value.logics, newVal);
() => questionInfo.value.questions.filter((item) => item.id === chooseQuestionId.value),
(newVal) => {
debouncedSaveQueItem(questionInfo.value.logics, newVal);
// saveQueItem(questionInfo.value.logics, newVal);
},
{ deep: true }
);

View File

@@ -37,6 +37,7 @@
<!-- 自定义文本 -->
<template #default>
<div class="flex align-center van-cell">
<div class="flex" style="width: 100%; flex-wrap: wrap">
<contenteditable
v-model="it.option"
:className="active ? 'contenteditable-input' : ''"
@@ -48,8 +49,12 @@
</div>
</template>
</contenteditable>
<div v-if="it.is_other">
<input class="other-input" type="text" />
<input
class="other-input"
type="text"
v-if="it.is_other"
style="width: 100%"
/>
</div>
</div>
</template>