// 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: '' }, active: { type: Boolean, value: false }, }, data: { options: [] as Option[], subOptions: [] as Option[], subMultiple: false, itemHeight: 48, result: '', hasSelected: false, }, 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; if (!item || !this.data.active) return; const index = this.data.options.findIndex(option => option.id === item.id); 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; if (!item || !this.data.active) return; const index = this.data.subOptions.findIndex(option => option.id === item.id); const multiple = this.data.subMultiple; const checked = !item.checked; const subOptions = this._handle(this.data.subOptions, item, index, multiple); this.setData({ subOptions }); 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 }) } } } 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 }); } } } })