// pages/index/index.js const api = require('../../utils/request') Page({ data: { // 地区选项 (对象格式) regions: [ { label: '昆明', value: '昆明' }, { label: '玉溪', value: '玉溪' }, { label: '楚雄', value: '楚雄' }, { label: '大理', value: '大理' }, { label: '曲靖', value: '曲靖' }, { label: '红河', value: '红河' }, { label: '文山', value: '文山' }, { label: '重庆', value: '重庆' }, { label: '成都', value: '成都' }, { label: '广州', value: '广州' }, { label: '南宁', value: '南宁' } ], // 材质选项 (对象格式) materials: [ { label: '全部', value: '' }, { label: 'HPB300', value: 'HPB300' }, { label: 'HRB400', value: 'HRB400' }, { label: 'HRB400E', value: 'HRB400E' }, { label: 'HRB500', value: 'HRB500' }, { label: 'HRB500E', value: 'HRB500E' }, { label: 'HRB600', value: 'HRB600' }, { label: 'CRB550', value: 'CRB550' }, { label: 'Q235', value: 'Q235' }, { label: 'Q345', value: 'Q345' }, { label: 'Q355', value: 'Q355' } ], // 品名选项 (对象格式) partsnames: [ { label: '全部', value: '' }, { label: '高线', value: '高线' }, { label: '螺纹钢', value: '螺纹钢' }, { label: '盘螺', value: '盘螺' }, { label: '工字钢', value: '工字钢' }, { label: '槽钢', value: '槽钢' }, { label: '角钢', value: '角钢' }, { label: 'H型钢', value: 'H型钢' }, { label: '钢板', value: '钢板' }, { label: '卷板', value: '卷板' }, { label: '中厚板', value: '中厚板' } ], // 选中的值 selectedRegion: '', selectedMaterial: '', selectedPartsname: '', // 显示的文本 regionText: '请选择地区', materialText: '请选择材质 (可选)', partsnameText: '全部', // 选中的日期 selectedDate: '', // 今天日期 today: '', // 加载状态 loading: false, loadingMore: false, // 加载更多状态 // 是否已搜索 searched: false, // 查询结果 priceList: [], total: 0, // 分页参数 currentPage: 1, pageSize: 20, // 每页数量(优化为20,首屏加载更快) hasMore: true, // 是否还有更多数据 // 统计信息 stats: null, // Picker 显示状态 regionPickerVisible: false, materialPickerVisible: false, partsnamePickerVisible: false, datePickerVisible: false, // Picker value (数组形式) regionPickerValue: [], materialPickerValue: [], partsnamePickerValue: [], // 价格详情弹窗 detailVisible: false, detailItem: null }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { // 设置今天日期 const today = this.formatDate(new Date()) this.setData({ today }) // 测试 API 连接 this.testApiConnection() }, /** * 测试 API 连接 */ async testApiConnection() { try { const res = await api.checkHealth() console.log('API 连接成功:', res) } catch (error) { console.error('API 连接失败:', error) api.showError('API 服务连接失败,请确保后端服务已启动') } }, /** * 显示地区选择器 */ showRegionPicker() { this.setData({ regionPickerVisible: true }) }, /** * 显示材质选择器 */ showMaterialPicker() { this.setData({ materialPickerVisible: true }) }, /** * 显示品名选择器 */ showPartsnamePicker() { this.setData({ partsnamePickerVisible: true }) }, /** * 显示日期选择器 */ showDatePicker() { this.setData({ datePickerVisible: true }) }, /** * Picker 选择改变 */ onPickerChange(e) { const { key } = e.currentTarget.dataset const { value } = e.detail console.log('Picker change:', { key, value }) // 根据 key 设置对应的文本和值 if (key === 'region') { const region = this.data.regions.find(item => item.value === value[0]) this.setData({ regionPickerVisible: false, regionPickerValue: value, selectedRegion: value[0] || '', regionText: region ? region.label : '请选择地区' }) } else if (key === 'material') { const material = this.data.materials.find(item => item.value === value[0]) this.setData({ materialPickerVisible: false, materialPickerValue: value, selectedMaterial: value[0] || '', materialText: material ? material.label : '请选择材质 (可选)' }) } else if (key === 'partsname') { const partsname = this.data.partsnames.find(item => item.value === value[0]) this.setData({ partsnamePickerVisible: false, partsnamePickerValue: value, selectedPartsname: value[0] || '', partsnameText: partsname ? partsname.label : '全部' }) } }, /** * Picker 取消选择 */ onPickerCancel(e) { const { key } = e.currentTarget.dataset console.log('Picker cancel:', key) if (key === 'region') { this.setData({ regionPickerVisible: false }) } else if (key === 'material') { this.setData({ materialPickerVisible: false }) } else if (key === 'partsname') { this.setData({ partsnamePickerVisible: false }) } else if (key === 'date') { this.setData({ datePickerVisible: false }) } }, /** * 日期选择确认 */ onDateConfirm(e) { const { value } = e.detail this.setData({ selectedDate: value, datePickerVisible: false }) }, /** * 日期选择取消 */ onDatePickerCancel() { this.setData({ datePickerVisible: false }) }, /** * 查询价格(首次查询) */ async onSearch() { const { selectedRegion, selectedMaterial, selectedPartsname, selectedDate } = this.data // 验证必填项 if (!selectedRegion) { api.showError('请选择地区') return } // 重置分页状态 this.setData({ currentPage: 1, priceList: [], hasMore: true, loading: true, searched: false }) try { // 构建搜索参数 const searchParams = { region: selectedRegion, page: 1, pageSize: this.data.pageSize } // 添加可选参数 if (selectedMaterial) searchParams.material = selectedMaterial if (selectedPartsname) searchParams.partsname = selectedPartsname if (selectedDate) searchParams.startDate = selectedDate // 如果选择了日期,设置结束日期 if (selectedDate) { searchParams.endDate = selectedDate } console.log('查询参数:', searchParams) // 调用搜索接口 const searchResult = await api.searchPrices(searchParams) console.log('查询结果:', searchResult) // 获取统计数据 const statsParams = { region: selectedRegion, material: selectedMaterial } if (selectedDate) { statsParams.startDate = selectedDate statsParams.endDate = selectedDate } else { statsParams.days = 30 } const statsResult = await api.getPriceStats(statsParams) console.log('==================== 统计结果 ====================') console.log('完整响应:', statsResult) console.log('success:', statsResult.success) console.log('data:', statsResult.data) console.log('data 类型:', typeof statsResult.data) console.log('data 字段:', Object.keys(statsResult.data || {})) console.log('JSON 数据:', JSON.stringify(statsResult.data, null, 2)) console.log('====================================================') // 处理查询结果 this.processSearchResult(searchResult, statsResult) } catch (error) { console.error('查询失败:', error) this.setData({ loading: false, searched: true, priceList: [], total: 0, stats: null, hasMore: false }) // API 错误已在 request.js 中处理 } }, /** * 处理查询结果(首次查询和加载更多共用) */ processSearchResult(searchResult, statsResult) { const priceList = searchResult.data || [] const total = searchResult.total || searchResult.pagination?.total || priceList.length || 0 // 格式化日期字段 const formattedList = priceList.map(item => { let dateStr = '' if (item.price_date) { const date = new Date(item.price_date) dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}` } return { ...item, price_date_str: dateStr } }) // 判断是否还有更多数据 const hasMore = formattedList.length >= this.data.pageSize && this.data.priceList.length + formattedList.length < total // 合并数据(首次查询或加载更多) const newList = this.data.currentPage === 1 ? formattedList : [...this.data.priceList, ...formattedList] this.setData({ priceList: newList, total, stats: statsResult?.data || null, searched: true, loading: false, loadingMore: false, hasMore }) // 显示结果提示 if (this.data.currentPage === 1 && searchResult.data && searchResult.data.length > 0) { api.showSuccess(`查询成功,共找到 ${total} 条数据`) } }, /** * 触底加载更多 */ async onReachBottom() { const { loading, loadingMore, hasMore, searched, total, priceList } = this.data // 如果正在加载、没有更多数据、或未搜索过,则不处理 if (loading || loadingMore || !hasMore || !searched) { return } // 如果已加载全部数据 if (priceList.length >= total) { this.setData({ hasMore: false }) return } console.log('触底加载更多...') // 开始加载更多 this.setData({ loadingMore: true, currentPage: this.data.currentPage + 1 }) try { // 构建搜索参数 const searchParams = { region: this.data.selectedRegion, page: this.data.currentPage, pageSize: this.data.pageSize } // 添加可选参数 if (this.data.selectedMaterial) searchParams.material = this.data.selectedMaterial if (this.data.selectedPartsname) searchParams.partsname = this.data.selectedPartsname if (this.data.selectedDate) searchParams.startDate = this.data.selectedDate if (this.data.selectedDate) searchParams.endDate = this.data.selectedDate console.log('加载更多参数:', searchParams) // 调用搜索接口 const searchResult = await api.searchPrices(searchParams) console.log('加载更多结果:', searchResult) // 处理结果(不需要再次获取统计数据) this.processSearchResult(searchResult, { data: this.data.stats }) } catch (error) { console.error('加载更多失败:', error) this.setData({ loadingMore: false, currentPage: this.data.currentPage - 1 // 恢复页码 }) api.showError('加载更多失败,请重试') } }, /** * 重置表单 */ onReset() { this.setData({ selectedRegion: '', selectedMaterial: '', selectedPartsname: '', regionText: '请选择地区', materialText: '请选择材质 (可选)', partsnameText: '全部', regionPickerValue: [], materialPickerValue: [], partsnamePickerValue: [], selectedDate: '', searched: false, priceList: [], total: 0, stats: null, currentPage: 1, hasMore: true, loadingMore: false }) }, /** * 查看价格详情 */ onPriceDetail(e) { const item = e.currentTarget.dataset.item // 显示详情弹窗 this.setData({ detailVisible: true, detailItem: item }) }, /** * 关闭详情弹窗 */ onCloseDetail() { this.setData({ detailVisible: false, detailItem: null }) }, /** * 阻止事件冒泡 */ stopPropagation() { // 阻止点击弹窗内容时关闭弹窗 }, /** * 格式化日期为 YYYY-MM-DD */ formatDate(date) { 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}` }, /** * TabBar 切换 */ onTabChange(e) { const value = e.detail.value console.log('TabBar 切换:', value, '类型:', typeof value) // value 可能是字符串或数字,统一处理 const tabIndex = parseInt(value) if (tabIndex === 0) { // 当前页,不做处理 console.log('已在当前页,不跳转') return } else if (tabIndex === 1) { // 跳转到价格趋势页 console.log('跳转到价格趋势页') wx.navigateTo({ url: '/pages/trend/trend' }) } } })