// module/chats/components/message-select/message-select.ts interface Option { id: string; name: string; checked?: boolean; options: Option[] | null; } interface HandleEvent { mark: { type: "sub" | "options"; index: number; item: Option; }; } Component({ properties: { payload: { type: Object, value: { title: "", multiple: false, options: [] }, result: "", belongNew: null, }, active: { type: Boolean, value: false }, }, data: { options: [] as Option[], subOptions: [] as Option[], subMultiple: false, itemHeight: 48, result: "", hasSelected: false, leftTitle: "都没有", rightTitle: "提交", }, lifetimes: { attached() { console.log("attached", this.data.payload.belongNew,this.data.payload); if (this.data.payload.belongNew) { this.setData({ leftTitle: "都没有", rightTitle: "提交", }); } else { this.setData({ leftTitle: "无变化", rightTitle: "完成", }); } }, }, observers: { "payload.options"(options) { this.setData({ options }); }, options(options: AnyArray) { this.setData({ hasSelected: options .filter((option) => !option.hide) .some((option) => option.checked), }); }, }, methods: { handleTop(event: HandleEvent) { const { mark: { item }, } = event; console.log("handleTop", item, this.data.active); if (!item || !this.data.active) return; console.log("handleTop", this.data.subOptions); const index = this.data.options.findIndex( (option) => option.id === item.id ); // 如果当前项已选中且已有已选中的子项,则直接弹出子项程度选择弹窗以便修改 const itemInState: any = this.data.options[index]; const hasSubOptions = itemInState?.options?.filter( (o: any) => !o?.hide ).length; const hasAnySubChecked = itemInState?.options?.some( (o: any) => o?.checked ); if (itemInState?.checked && hasSubOptions && hasAnySubChecked) { this.setData({ subTitle: itemInState.name, subOptions: itemInState.options, subMultiple: itemInState.css === "checkbox", }); this.onCancel = () => { this.setData({ subOptions: [] }); }; this.onConfirm = () => { if (!this.data.subOptions.some((option) => option.checked)) { wx.showToast({ title: "请至少选择一项", icon: "error" }); } else { const options = this.data.options; options[index].options = this.data.subOptions; this.setData({ subOptions: [], options }); // 单选场景:选择/修改子程度后直接提交 if (!this.data.payload.multiple) { this.onSubmit(); } } }; return; } const multiple = this.data.payload.multiple; const checked = !item.checked; const options = this._handle(this.data.options, item, index, multiple); this.setData({ options }); // 注释掉自动提交的逻辑,让用户可以继续选择症状程度 if (checked && !multiple) { this.onSubmit(); } }, handleSub(event: HandleEvent) { const { mark: { item }, } = event; console.log("handleSub", item, this.data.active); if (!item || !this.data.active) return; console.log("this.data.subOptions", this.data.subOptions); const index = this.data.subOptions.findIndex( (option) => option.id === item.id ); console.log("index", index); const multiple = this.data.subMultiple; const checked = !item.checked; const subOptions = this._handle( this.data.subOptions, item, index, multiple ); this.setData({ subOptions }); console.log(this.data.subOptions, "suboptions111"); // 检查是否所有症状程度都被取消选中 const hasAnySubChecked = subOptions.some((option) => option.checked); if (!hasAnySubChecked) { // 如果没有任何症状程度被选中,则取消整个症状的选中状态 const mainIndex = this.data.options.findIndex( (option) => option.name === this.data.subTitle ); if (mainIndex !== -1) { const options = this.data.options; options[mainIndex].checked = false; options[mainIndex].options = options[mainIndex].options?.map( (option: any) => { if (!option?.hide) option.checked = false; return option; } ); // 关闭当前弹窗,避免遮挡导致切换其它症状时看起来未选中 this.setData({ options, subOptions: [], subTitle: "" }); return; } } // 注释掉自动关闭弹窗的逻辑,让用户可以继续修改症状程度 if (checked && !multiple) { this.onConfirm(); } }, _handle( options: Option[], item: Option, index: number, multiple?: boolean ) { const checked = !item.checked; if (checked) { const fn = () => { if (multiple) { options[index].checked = checked; } else { options.forEach((option) => { option.checked = option.id === item.id; }); } return options; }; if (item.options?.filter((option) => !(option)?.hide).length) { this.setData({ subTitle: item.name, subOptions: item.options, subMultiple: (item).css === "checkbox", }); this.onCancel = () => { this.setData({ subOptions: [] }); }; this.onConfirm = () => { if (!this.data.subOptions.some((option) => option.checked)) { wx.showToast({ title: "请至少选择一项", icon: "error" }); } else { const options = fn(); options[index].options = this.data.subOptions; this.setData({ subOptions: [], options }); // 单选场景:选择子程度“确定”后直接提交 if (!this.data.payload.multiple) { this.onSubmit(); } } }; } else { return fn(); } } else { options[index].checked = !item.checked; if (item.options) options[index].options = item.options.map((option) => { if (!(option)?.hide) option.checked = !item.checked; return option; }); } return options; }, onCancel() {}, onConfirm() {}, onSubmit() { if (this.data.result) return; if (!this.data.hasSelected) { wx.showToast({ title: "请至少选择一项", icon: "error" }); } else { console.log(this.data.options); const result = this.data.options .filter((item: any) => item?.checked && !item?.hide) .map((option: any) => { const sub = option.options ?.filter((item: any) => item?.checked && !item?.hide) .map((item: any) => item.name) .join(", "); return [option.name, sub].filter(Boolean).join(": "); }) .join("; "); this.setData({ result }); this.triggerEvent("next", { options: this.data.options }); } }, onSkip() { if (this.data.result || this.data.hasSelected) return; if (!this.data.payload.required) { this.setData({ result: "都没有" }); this.triggerEvent("next", { options: this.data.options }); } }, }, });