interest-search.component.ts 11 KB

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