495 lines
13 KiB
JavaScript
495 lines
13 KiB
JavaScript
// 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'
|
||
})
|
||
}
|
||
}
|
||
})
|