interest-search.component.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. import { Component, OnInit } from '@angular/core';
  2. import {
  3. IonTextarea,
  4. IonCheckbox,
  5. IonList,
  6. IonButton,
  7. IonContent,
  8. IonHeader,
  9. IonInput,
  10. IonTitle,
  11. IonToolbar,
  12. IonItem,
  13. IonLabel,
  14. IonRadioGroup,
  15. IonRadio,
  16. IonDatetimeButton,
  17. IonDatetime,
  18. IonModal
  19. } from '@ionic/angular/standalone';
  20. import { CloudQuery, CloudObject, Pointer } from '../../lib/ncloud'; // 确保路径正确
  21. import { CommonModule } from '@angular/common'; // 导入 CommonModule
  22. import { FormsModule } from '@angular/forms'; // 导入 FormsModule
  23. // 定义接口以确保类型安全
  24. interface Questionnaire {
  25. objectId: string;
  26. createdAt: string;
  27. QuestionnaireId: string;
  28. title: string;
  29. status: string;
  30. questions: string[]; // 修改为字符串数组
  31. }
  32. interface Question {
  33. objectId: string;
  34. createdAt: string;
  35. QuestionId: string;
  36. questionnaireId: string; // 修改为字符串
  37. questionText: string;
  38. options: string[]; // 修改为字符串数组
  39. }
  40. interface Option {
  41. objectId: string;
  42. createdAt: string;
  43. OptionId: string;
  44. questionId: string; // 修改为字符串
  45. optionText: string;
  46. isSelected: boolean;
  47. }
  48. interface QuestionnaireResult {
  49. objectId: string;
  50. createdAt: string;
  51. QuestionnaireResultId: string;
  52. userId: Pointer;
  53. questionnaireId: Pointer;
  54. answers: Pointer[];
  55. }
  56. interface QuestionWithOptions extends Question {
  57. optionsData: Option[];
  58. }
  59. @Component({
  60. selector: 'app-interest-search',
  61. templateUrl: './interest-search.component.html',
  62. styleUrls: ['./interest-search.component.scss'],
  63. standalone: true,
  64. imports: [
  65. IonTextarea,
  66. IonCheckbox,
  67. IonList,
  68. IonButton,
  69. IonContent,
  70. IonHeader,
  71. IonInput,
  72. IonTitle,
  73. IonToolbar,
  74. IonItem,
  75. IonLabel,
  76. IonRadioGroup,
  77. IonRadio,
  78. IonDatetimeButton,
  79. IonDatetime,
  80. IonModal,
  81. CommonModule,
  82. FormsModule
  83. ]
  84. })
  85. export class InterestSearchComponent implements OnInit {
  86. // 固定字段
  87. name: string = '';
  88. birthday: string = '';
  89. // 动态问卷数据
  90. questionnaire: Questionnaire | null = null;
  91. questionsWithOptions: QuestionWithOptions[] = [];
  92. answers: { [questionId: string]: string } = {}; // 存储用户答案
  93. constructor() { }
  94. ngOnInit() {
  95. this.loadQuestionnaireData('test_q1'); // 使用 QuestionnaireId 'test_q1'
  96. }
  97. async loadQuestionnaireData(questionnaireId: string) {
  98. try {
  99. const questionnaireQuery = new CloudQuery("Questionnaire");
  100. questionnaireQuery.equalTo("QuestionnaireId", questionnaireId);
  101. const questionnaireObj = await questionnaireQuery.first();
  102. if (questionnaireObj) {
  103. const questionnaireData = questionnaireObj.data as Questionnaire;
  104. // 确保 objectId 存在且为字符串
  105. this.questionnaire = {
  106. ...questionnaireData,
  107. objectId: String(questionnaireObj.id)
  108. };
  109. console.log("加载到的问卷数据:", this.questionnaire);
  110. // 确保 questions 被正确传入
  111. if (this.questionnaire.questions) {
  112. await this.loadQuestions(this.questionnaire.questions);
  113. }
  114. } else {
  115. console.error(`未找到 QuestionnaireId 为 ${questionnaireId} 的问卷。`);
  116. }
  117. } catch (error) {
  118. console.error("加载问卷数据时出错:", error);
  119. }
  120. }
  121. async loadQuestions(questionIds: string[]) {
  122. this.questionsWithOptions = []; // 初始化问题列表
  123. for (const questionId of questionIds) {
  124. try {
  125. const questionQuery = new CloudQuery("Question");
  126. questionQuery.equalTo("QuestionId", questionId);
  127. const questionObj = await questionQuery.first();
  128. if (questionObj) {
  129. const question = questionObj.data as Question;
  130. // 异步加载选项并立即显示问题
  131. this.questionsWithOptions.push({ ...question, optionsData: [] });
  132. this.loadOptions(question.options).then((options) => {
  133. const index = this.questionsWithOptions.findIndex(
  134. (q) => q.QuestionId === question.QuestionId
  135. );
  136. if (index !== -1) {
  137. this.questionsWithOptions[index].optionsData = options;
  138. }
  139. });
  140. // 可选:每加载一个问题,立即触发渲染
  141. console.log("已加载问题:", question);
  142. }
  143. } catch (error) {
  144. console.error(`加载问题 ID ${questionId} 时出错:`, error);
  145. }
  146. }
  147. }
  148. async loadOptions(optionIds: string[]): Promise<Option[]> {
  149. try {
  150. if (!optionIds || optionIds.length === 0) return [];
  151. const optionQuery = new CloudQuery("Option");
  152. optionQuery.containedIn("OptionId", optionIds); // 批量查询
  153. const optionObjs = await optionQuery.find();
  154. return optionObjs.map((optionObj: any) => optionObj.data as Option);
  155. } catch (error) {
  156. console.error("加载选项时出错:", error);
  157. return [];
  158. }
  159. }
  160. /*
  161. async loadQuestions(questionIds: string[]) {
  162. try {
  163. const questionQuery = new CloudQuery("Question");
  164. questionQuery.containedIn("QuestionId", questionIds); // 一次查询多个 QuestionId
  165. const questionObjs = await questionQuery.find();
  166. const questionsWithOptions: QuestionWithOptions[] = await Promise.all(
  167. questionObjs.map(async (questionObj: any) => {
  168. const question = questionObj.data as Question;
  169. const options = await this.loadOptions(question.options);
  170. return { ...question, optionsData: options };
  171. })
  172. );
  173. this.questionsWithOptions = questionsWithOptions;
  174. } catch (error) {
  175. console.error("批量加载问题时出错:", error);
  176. }
  177. }
  178. async loadOptions(optionIds: string[]): Promise<Option[]> {
  179. try {
  180. const optionQuery = new CloudQuery("Option");
  181. optionQuery.containedIn("OptionId", optionIds); // 批量查询所有 OptionId
  182. const optionObjs = await optionQuery.find();
  183. return optionObjs.map((optionObj: any) => optionObj.data as Option);
  184. } catch (error) {
  185. console.error("批量加载选项时出错:", error);
  186. return [];
  187. }
  188. }
  189. */
  190. /*
  191. // 加载问卷中的问题及选项
  192. async loadQuestions(questionIds: string[]) {
  193. try {
  194. const questions: QuestionWithOptions[] = [];
  195. for (const questionId of questionIds) {
  196. const questionQuery = new CloudQuery("Question");
  197. questionQuery.equalTo("QuestionId", questionId);
  198. const questionObj = await questionQuery.first();
  199. if (!questionObj) {
  200. console.error(`未找到问题ID为 ${questionId} 的问题。`);
  201. continue;
  202. }
  203. const question = questionObj.data as Question;
  204. const options = await this.loadOptions(question.options); // 加载选项
  205. questions.push({
  206. ...question,
  207. optionsData: options
  208. });
  209. }
  210. this.questionsWithOptions = questions;
  211. } catch (error) {
  212. console.error("加载问题时出错:", error);
  213. }
  214. }
  215. // 加载选项
  216. async loadOptions(optionIds: string[]): Promise<Option[]> {
  217. try {
  218. const options: Option[] = [];
  219. for (const optionId of optionIds) {
  220. const optionQuery = new CloudQuery("Option");
  221. optionQuery.equalTo("OptionId", optionId);
  222. const optionObj = await optionQuery.first();
  223. if (!optionObj) {
  224. console.error(`未找到选项ID为 ${optionId} 的选项。`);
  225. continue;
  226. }
  227. const option = optionObj.data as Option;
  228. options.push(option);
  229. }
  230. return options;
  231. } catch (error) {
  232. console.error("加载选项时出错:", error);
  233. return [];
  234. }
  235. }
  236. */
  237. // 保存功能(可选)
  238. async save() {
  239. try {
  240. // 实现保存逻辑,例如保存到本地存储或发送到后台
  241. console.log("保存的答案:", this.answers);
  242. console.log("姓名:", this.name);
  243. console.log("生日:", this.birthday);
  244. } catch (error) {
  245. console.error("保存答案时出错:", error);
  246. }
  247. }
  248. // 提交功能
  249. async submit() {
  250. try {
  251. if (!this.questionnaire) {
  252. console.error("未加载问卷数据。");
  253. return;
  254. }
  255. // 创建一个数组保存选中的 OptionId
  256. const answersArray: string[] = [];
  257. // 遍历每个问题,获取用户选择的选项
  258. for (const question of this.questionsWithOptions) {
  259. const selectedOptionId = this.answers[question.QuestionId];
  260. if (selectedOptionId) {
  261. // 将选中的 OptionId 存入 answersArray
  262. answersArray.push(selectedOptionId);
  263. }
  264. }
  265. // 创建一个新的 QuestionnaireResult 对象
  266. const questionnaireResult = new CloudObject("QuestionnaireResult");
  267. // 设置 QuestionnaireResult 的属性
  268. questionnaireResult.set({
  269. QuestionnaireResultId: `qr_${new Date().getTime()}`, // 生成唯一的 QuestionnaireResultId
  270. userId: { __type: "Pointer", className: "_User", objectId: "user1" }, // 替换为实际的用户ID
  271. // 使用 Pointer 类型的引用方式来设置 questionnaireId
  272. questionnaireId: { __type: "Pointer", className: "Questionnaire", objectId: this.questionnaire.objectId },
  273. answers: answersArray // 将选中的 OptionId 数组存入 answers 字段
  274. });
  275. // 保存 QuestionnaireResult 对象
  276. await questionnaireResult.save();
  277. console.log("问卷提交成功。");
  278. // 可选:清空表单
  279. this.name = '';
  280. this.birthday = '';
  281. this.answers = {};
  282. } catch (error) {
  283. console.error("提交问卷时出错:", error);
  284. }
  285. }
  286. /*async submit() {
  287. try {
  288. if (!this.questionnaire) {
  289. console.error("未加载问卷数据。");
  290. return;
  291. }
  292. const answersPointers: Pointer[] = [];
  293. for (const question of this.questionsWithOptions) {
  294. const selectedOptionId = this.answers[question.QuestionId];
  295. if (selectedOptionId) {
  296. const optionPointer: Pointer = {
  297. __type: "Pointer",
  298. className: "Option",
  299. objectId: selectedOptionId // 确保使用 objectId
  300. };
  301. answersPointers.push(optionPointer);
  302. }
  303. }
  304. const questionnaireResult = new CloudObject("QuestionnaireResult");
  305. questionnaireResult.set({
  306. QuestionnaireResultId: `qr_${new Date().getTime()}`, // 生成唯一的 QuestionnaireResultId
  307. userId: { __type: "Pointer", className: "_User", objectId: "user1" }, // 替换为实际的用户ID
  308. questionnaireId: { __type: "Pointer", className: "Questionnaire", QuestionnaireId: this.questionnaire.QuestionnaireId },
  309. answers: answersPointers
  310. });
  311. await questionnaireResult.save();
  312. console.log("问卷提交成功。");
  313. // 可选:清空表单
  314. this.name = '';
  315. this.birthday = '';
  316. this.answers = {};
  317. } catch (error) {
  318. console.error("提交问卷时出错:", error);
  319. }
  320. }*/
  321. }