Files
steel_prices_service/Sale/pages/index/index.js
2026-01-07 10:13:21 +08:00

495 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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'
})
}
}
})