Day036

1、知识点:

反射

// components/filter-picker/filter-picker.js Component({ properties: { options: Array, value: [String, Number], placeholder: String, disabled: Boolean, maxHeight: { type: Number, value: 300 } }, data: { dropdownVisible: false, searchText: '', filteredOptions: [], displayText: '', isActive: false // 新增激活状态 }, methods: { /** * 安全更新筛选后的选项列表 * 1. 确保options是数组 * 2. 过滤掉非对象元素 * 3. 处理label属性缺失的情况 */ updateFilteredOptions() { let { options, searchText } = this.data; // 确保options是数组,如果不是则重置为空数组 if (!Array.isArray(options)) { options = []; this.setData({ options }); } // 过滤掉非对象元素 const validOptions = options.filter(item => item && typeof item === 'object' && 'label' in item ); // 如果没有搜索文本,显示所有有效选项 if (!searchText) { this.setData({ filteredOptions: validOptions }); return; } // 安全过滤:确保item有label属性 const filtered = validOptions.filter(item => { const label = item.label || ''; return label.toString().toLowerCase().includes(searchText.toLowerCase()); }); this.setData({ filteredOptions: filtered }); }, /** * 安全更新显示文本 * 1. 处理无效值 * 2. 处理找不到匹配项的情况 */ updateDisplayText() { const { value, options } = this.data; // 确保options是有效数组 if (!Array.isArray(options) || options.length === 0) { this.setData({ displayText: '' }); return; } // 处理空值 if (!value) { this.setData({ displayText: '' }); return; } // 查找匹配项,忽略非对象元素 const selected = options.find(item => item && typeof item === 'object' && item.value === value ); if (selected) { this.setData({ displayText: selected.label || '', searchText: selected.label || '' }); } else { this.setData({ displayText: '' }); } }, /** * 处理输入事件 * @param {Object} e - 事件对象 * @param {string} e.detail.value - 输入框的值 */ onInput(e) { const searchText = e.detail.value; this.setData({ searchText }, () => { this.updateFilteredOptions(); }); }, /** * 当输入框获得焦点时的处理函数 * - 如果组件被禁用则直接返回 * - 设置下拉框可见状态、搜索文本和激活状态 * - 更新过滤后的选项列表 */ onFocus() { console.log('Picker focused'); // 调试日志 if (this.data.disabled) return; this.setData({ dropdownVisible: true, searchText: this.data.displayText, isActive: true }, () => { this.updateFilteredOptions(); }); }, /** * 处理输入框失去焦点事件 * 延迟200毫秒后隐藏下拉框并取消激活状态 */ onBlur() { setTimeout(() => { this.setData({ dropdownVisible: false, isActive: false }); }, 200); }, /** * 切换下拉框的显示/隐藏状态 * 如果组件被禁用则不做任何操作 * 当下拉框显示时会触发更新过滤选项的操作 */ toggleDropdown() { console.log('Toggling dropdown'); // 调试日志 if (this.data.disabled) return; this.setData({ dropdownVisible: !this.data.dropdownVisible, isActive: !this.data.dropdownVisible }, () => { if (this.data.dropdownVisible) { this.updateFilteredOptions(); } }); }, /** * 处理选择项事件 * @param {Object} e - 事件对象 * @param {Object} e.currentTarget.dataset - 事件目标数据 * @param {string} e.currentTarget.dataset.value - 选中项的值 * @param {Object} e.currentTarget.dataset.item - 选中项对象 * @param {string} e.currentTarget.dataset.item.label - 选中项的显示文本 * @fires change - 触发change事件,传递选中项的值和对象 */ selectItem(e) { const { value, item } = e.currentTarget.dataset; this.setData({ value, displayText: item.label, searchText: item.label, dropdownVisible: false, isActive: false }); this.triggerEvent('change', { value, item }); } }, observers: { // 监听options变化 'options': function() { this.updateFilteredOptions(); this.updateDisplayText(); }, // 监听value变化 'value': function() { this.updateDisplayText(); } }, ready() { this.updateFilteredOptions(); this.updateDisplayText(); } }); // pages/tianjia/tianjia.js Page({ data: { dingdans: [], chanpins: [], zujians: [], bancais: [], currentDingdan: null, currentChanpin: null, currentZujian: null, currentBancai: null, currentDingdanId: null, currentDingdanChanpinId: null, currentChanpinZujianId: null, orderQuantity: '', canSubmit: false, modalVisible: false, modalTitle: '', modalType: '', modalData: {}, modalConfig: {}, // 控制下拉框可用状态 chanpinDisabled: true, zujianDisabled: true, bancaiDisabled: false }, onLoad: function() { if (!this.checkPermission()) return; this.initPage(); }, checkPermission: function() { const role = parseInt(wx.getStorageSync('role') || '0'); if (role <= 1) { wx.showModal({ title: '权限不足', content: '抱歉,您没有访问此页面的权限。', showCancel: false, success: () => { wx.navigateBack() } }); return false; } return true; }, initPage: function() { this.dataManager = getApp().globalData.dataManager; this.dataManager.registerCallback('all', this.handleDataUpdate.bind(this)); console.log(this.dataManager.data.dingdans) this.refreshDingdanList(); this.refreshBancaiList(); }, /** * 处理数据更新事件 * @param {string} operation - 操作类型,包括 'refresh', 'add', 'update', 'delete' * @param {string} entity - 实体类型,包括 'dingdan', 'dingdan_chanpin', 'chanpin_zujian', 'bancai' * @param {Object} data - 更新的数据对象 * @description 根据不同的操作类型和实体类型,调用对应的刷新方法更新列表数据 */ handleDataUpdate: function (operation, entity, data) { if (['refresh', 'add', 'update', 'delete'].includes(operation)) { if (entity === 'dingdan') { this.refreshDingdanList(data.id); } else if (entity === 'dingdan_chanpin') { this.refreshChanpinList(data.dingdan?.id, data.chanpin?.id); } else if (entity === 'chanpin_zujian') { this.refreshZujianList(data.chanpin?.id, data.id); } else if (entity === 'bancai') { this.refreshBancaiList(null, data.id); } } }, /** * 刷新订单列表 * @param {string} [dingdanId] - 可选参数,指定当前选中的订单ID * @description * 1. 获取并排序订单数据(按下单时间降序) * 2. 格式化订单数据为{label, value}格式 * 3. 更新页面数据,若指定了dingdanId则刷新对应产品列表 */ refreshDingdanList: function(dingdanId) { const dingdans = this.dataManager.data.dingdans || []; dingdans.sort((a, b) => new Date(b.xiadan) - new Date(a.xiadan)); const formattedDingdans = dingdans.map(d => ({ ...d, label: `${d.number} (${this.formatDate(d.xiadan)})`, value: d.id })); this.setData({ dingdans: formattedDingdans, currentDingdanId: dingdanId || (dingdans.length > 0 ? dingdans[0].id : null) }, () => { if (dingdanId) { this.refreshChanpinList(dingdanId); } }); }, refreshChanpinList: function(dingdanId, chanpinId) { if (!dingdanId) return; const dingdanChanpins = this.dataManager.data.dingdan_chanpins || []; const relatedChanpins = dingdanChanpins.filter(dc => dc.dingdan?.id == dingdanId); const formattedChanpins = relatedChanpins.map(dc => ({ ...dc.chanpin, label: dc.chanpin ? `${dc.chanpin.bianhao} (数量: ${dc.shuliang})` : '', value: dc.chanpin?.id })); this.setData({ chanpins: formattedChanpins, chanpinDisabled: false // 启用产品下拉框 }); }, refreshZujianList: function(dingdanChanpinId, zujianId) { if (!dingdanChanpinId) return; const dingdanChanpin = this.dataManager.data.dingdan_chanpins.find(dc => dc.id == dingdanChanpinId); if (!dingdanChanpin?.chanpin) return; const chanpinId = dingdanChanpin.chanpin.id; const chanpinZujians = this.dataManager.data.chanpin_zujians.filter(cz => cz.chanpin?.id == chanpinId); const formattedZujians = chanpinZujians.map(cz => ({ ...cz, label: cz.zujian ? `${cz.zujian.name} (产量: ${cz.one_howmany})` : '', value: cz.id })); this.setData({ zujians: formattedZujians, zujianDisabled: false // 启用组件下拉框 }); if (zujianId) { const cz = chanpinZujians.find(cz => cz.id == zujianId); if (cz) { const index = formattedZujians.findIndex(z => z.id === cz.id); if (index !== -1) { this.setData({ currentZujianIndex: index, currentZujian: formattedZujians[index], currentChanpinZujianId: cz.id }); this.refreshBancaiList(cz.id); } } } }, refreshBancaiList: function(chanpinZujianId, bancaiId) { if (chanpinZujianId) { // 选择了组件,锁定板材为组件绑定的板材 const chanpinZujian = this.dataManager.data.chanpin_zujians.find(cz => cz.id == chanpinZujianId); if (!chanpinZujian?.bancai) return; const formattedBancai = { ...chanpinZujian.bancai, label: this.formatBancaiInfo(chanpinZujian.bancai), value: chanpinZujian.bancai.id }; this.setData({ bancais: [formattedBancai], currentBancai: formattedBancai, currentBancaiIndex: 0, bancaiDisabled: true // 禁用板材下拉框(已锁定) }); } else { // 未选择组件,显示所有板材 const bancais = this.dataManager.data.bancais || []; const formattedBancais = bancais.map(b => ({ ...b, label: this.formatBancaiInfo(b), value: b.id })); this.setData({ bancais: formattedBancais, bancaiDisabled: false // 启用板材下拉框 }); if (bancaiId) { const index = formattedBancais.findIndex(b => b.id === bancaiId); if (index !== -1) { this.setData({ currentBancaiIndex: index, currentBancai: formattedBancais[index] }); } } } this.checkSubmitCondition(); }, resetSelections: function() { this.setData({ chanpins: [], zujians: [], bancais: [], currentChanpin: null, currentZujian: null, currentBancai: null, currentDingdanChanpinId: null, currentChanpinZujianId: null, currentChanpinIndex: -1, currentZujianIndex: -1, currentBancaiIndex: -1, orderQuantity: '', canSubmit: false, chanpinDisabled: true, // 禁用产品下拉框 zujianDisabled: true, // 禁用组件下拉框 bancaiDisabled: false // 启用板材下拉框 }); this.refreshBancaiList(); }, formatBancaiInfo: function(bancai) { let info = `厚度: ${bancai.houdu}mm, 材质: ${bancai.caizhi?.name || ''}`; if (bancai.mupi1) info += `, 木皮1: ${bancai.mupi1.name}${bancai.mupi1.you ? ' (油)' : ''}`; if (bancai.mupi2) info += `, 木皮2: ${bancai.mupi2.name}${bancai.mupi2.you ? ' (油)' : ''}`; return info; }, formatDate: function(dateString) { if (!dateString) return ''; const date = new Date(dateString); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }, checkSubmitCondition: function() { const canSubmit = this.data.currentBancai && parseInt(this.data.orderQuantity) > 0; this.setData({ canSubmit }); }, onDingdanChange: function(e) { const { value, item } = e.detail; this.setData({ currentDingdanId: value, currentDingdan: item }); this.resetSelections(); this.refreshChanpinList(value); }, onChanpinChange: function(e) { const { value, item } = e.detail; this.setData({ currentDingdanChanpinId: value, currentChanpin: item }); this.setData({ zujians: [], currentZujian: null, currentZujianIndex: -1, currentChanpinZujianId: null, zujianDisabled: false }); this.refreshZujianList(value); }, onZujianChange: function(e) { const { value, item } = e.detail; this.setData({ currentChanpinZujianId: value, currentZujian: item }); this.refreshBancaiList(value); }, onBancaiChange: function(e) { const { value, item } = e.detail; this.setData({ currentBancai: item }); this.checkSubmitCondition(); }, onQuantityInput: function(e) { this.setData({ orderQuantity: e.detail.value }); this.checkSubmitCondition(); }, // 模态框相关方法 showAddDingdanModal: function() { modalService.showModal('addDingdan', { xiadan: new Date().toISOString().split('T')[0] }); }, showAddChanpinModal: function() { if (!this.data.currentDingdanId) { wx.showToast({ title: '请先选择订单', icon: 'none' }); return; } modalService.showModal('addChanpin', { dingdan: { id: this.data.currentDingdanId } }); }, showAddZujianModal: function() { if (!this.data.currentDingdanChanpinId) { wx.showToast({ title: '请先选择产品', icon: 'none' }); return; } const dingdanChanpin = this.dataManager.data.dingdan_chanpins.find( dc => dc.id == this.data.currentDingdanChanpinId ); if (!dingdanChanpin?.chanpin) return; modalService.showModal('addZujian', { chanpin: { id: dingdanChanpin.chanpin.id } }); }, showAddBancaiModal: function() { modalService.showModal('addBancai', { houdu: 0.0 }); }, // 保存数据方法 saveDingdan: function(data) { return this.dataManager.addDingdan(data).then(() => { wx.showToast({ title: '订单添加成功' }); return data; }); }, saveChanpin: function(data) { return this.dataManager.addDingdanChanpin({ dingdan: { id: this.data.currentDingdanId }, chanpin: { id: data.chanpin }, shuliang: data.shuliang }).then(() => { wx.showToast({ title: '产品添加成功' }); return data; }); }, saveZujian: function(data) { return this.dataManager.addChanpinZujian({ chanpin: { id: data.chanpin }, zujian: { id: data.zujian }, bancai: { id: data.bancai }, one_howmany: data.one_howmany }).then(() => { wx.showToast({ title: '组件添加成功' }); return data; }); }, saveBancai: function(data) { return this.dataManager.addBancai(data).then(() => { wx.showToast({ title: '板材添加成功' }); return data; }); }, // 模态框事件处理 handleModalCancel: function() { modalService.handleCancel(); }, handleModalConfirm: function() { modalService.handleConfirm(); }, handleModalUpdate: function(e) { const { path, value } = e.detail; this.setData({ [`modalData.${path}`]: value }); }, // 提交订单 submitOrder: function() { if (!this.data.canSubmit) { wx.showToast({ title: '请选择板材并输入数量', icon: 'none' }); return; } // 构建提交数据 const orderData = { chanpin_zujian_id: this.data.currentChanpinZujianId, bancai_id: this.data.currentBancai.id, quantity: parseInt(this.data.orderQuantity) }; // 调用API提交数据 wx.showLoading({ title: '提交中...' }); this.dataManager.submitOrder(orderData).then(() => { wx.hideLoading(); wx.showToast({ title: '提交成功' }); // 重置表单 this.setData({ orderQuantity: '', canSubmit: false }); }).catch(err => { wx.hideLoading(); wx.showToast({ title: `提交失败: ${err.message}`, icon: 'none' }); }); } }); (9) [Proxy, Proxy, Proxy, Proxy, Proxy, Proxy, Proxy, Proxy, Proxy]0: Proxy {number: "2025-31", xiadan: "2025-06-28T00:00:00.000+00:00", jiaohuo: null, dingdan_chanpin: Array(0), id: 1, …}1: Proxy {number: "2025-33", xiadan: null, jiaohuo: null, dingdan_chanpin: Array(3), id: 2, …}2: Proxy {number: "2025-034", xiadan: "2025-07-01T00:00:00.000+00:00", jiaohuo: null, dingdan_chanpin: Array(5), id: 3, …}3: Proxy {number: "2025-034增加单", xiadan: "2025-07-02T00:00:00.000+00:00", jiaohuo: null, dingdan_chanpin: Array(1), id: 4, …}4: Proxy {number: "2025-031", xiadan: "2025-07-02T00:00:00.000+00:00", jiaohuo: null, dingdan_chanpin: Array(1), id: 5, …}5: Proxy {number: "2025-036", xiadan: "2025-06-13T00:00:00.000+00:00", jiaohuo: "2025-07-13T00:00:00.000+00:00", dingdan_chanpin: Array(2), id: 6, …}6: Proxy {number: "2025-037", xiadan: "2025-06-16T00:00:00.000+00:00", jiaohuo: "2025-07-16T00:00:00.000+00:00", dingdan_chanpin: Array(1), id: 7, …}7: Proxy {number: "2025-038", xiadan: "2025-06-17T00:00:00.000+00:00", jiaohuo: "2025-08-17T00:00:00.000+00:00", dingdan_chanpin: Array(1), id: 8, …}8: Proxy {number: "梦5", xiadan: "2025-07-03T00:00:00.000+00:00", jiaohuo: "2025-08-03T00:00:00.000+00:00", dingdan_chanpin: Array(1), id: 44, …}length: 9nv_length: (...)__proto__: Array(0) TypeError: 44 is not a function at li.filter (<anonymous>) at Function.o.safeCallback (VM872 WASubContext.js:1) at l.<anonymous> (VM872 WASubContext.js:1) at c.doUpdates (VM872 WASubContext.js:1) at Mn (VM872 WASubContext.js:1) at no (VM872 WASubContext.js:1) at oo (VM872 WASubContext.js:1) at no (VM872 WASubContext.js:1) at oo (VM872 WASubContext.js:1) at no (VM872 WASubContext.js:1)(env: Windows,mp,1.06.2504010; lib: 3.8.10) refreshDingdanList @ tianjia.js? [sm]:97 initPage @ tianjia.js? [sm]:55 onLoad @ tianjia.js? [sm]:33 [pages/tianjia/tianjia] Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors.(./components/custom-form-modal/index.wxss:27:16) filter-picker.js? [sm]:114 Picker focused filter-picker.js? [sm]:145 Toggling dropdown filter-picker.js? [sm]:114 Picker focused filter-picker.js? [sm]:145 Toggling dropdown
最新发布
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值