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

View File

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

View File

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

View File

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