11 changed files with 1824 additions and 85 deletions
-
BINpages/images/ccp.png
-
BINpages/images/scqs.png
-
BINpages/images/sl.png
-
667pages/market/market.js
-
1pages/market/market.json
-
314pages/market/market.wxml
-
772pages/market/market.wxss
-
111pagesA/pages/wzai/wzai.js
-
12pagesA/pages/wzai/wzai.wxml
-
18utils/api.js
-
14utils/tool.wxs
|
After Width: 242 | Height: 200 | Size: 7.9 KiB |
|
After Width: 200 | Height: 200 | Size: 4.0 KiB |
|
After Width: 200 | Height: 200 | Size: 5.5 KiB |
@ -1,66 +1,659 @@ |
|||||
|
import http from '../../utils/api' |
||||
|
|
||||
// pages/market/market.js
|
// pages/market/market.js
|
||||
Page({ |
Page({ |
||||
|
|
||||
/** |
|
||||
* 页面的初始数据 |
|
||||
*/ |
|
||||
data: { |
data: { |
||||
|
// 当前时间
|
||||
|
currentTime: '', |
||||
|
|
||||
|
// 销售市场数据
|
||||
|
salesData: [], |
||||
|
salesUpdateTime: '', |
||||
|
salesStatus: 'inactive', |
||||
|
|
||||
|
// 饲料市场数据
|
||||
|
feedData: [], |
||||
|
feedUpdateTime: '', |
||||
|
feedStatus: 'inactive', |
||||
|
|
||||
|
// 市场趋势数据
|
||||
|
trendData: [], |
||||
|
unreadCount: 0, |
||||
|
|
||||
|
// 最后更新时间
|
||||
|
lastUpdateTime: '', |
||||
|
|
||||
|
// 刷新状态
|
||||
|
isRefreshing: false, |
||||
|
|
||||
|
// 动画数据
|
||||
|
headerAnimation: {}, |
||||
|
cardAnimation1: {}, |
||||
|
cardAnimation2: {}, |
||||
|
cardAnimation3: {}, |
||||
|
|
||||
|
// 无缝滚动相关数据
|
||||
|
scrollOffset: 0, // 滚动偏移量
|
||||
|
scrollDuration: 0.5, // 滚动动画持续时间
|
||||
|
scrollTimer: null, // 滚动定时器
|
||||
|
itemHeight: 150, // 每个公告项的高度(估算值,单位:px)
|
||||
|
isPaused: false // 是否暂停滚动
|
||||
}, |
}, |
||||
|
|
||||
/** |
|
||||
* 生命周期函数--监听页面加载 |
|
||||
*/ |
|
||||
onLoad(options) { |
|
||||
|
onLoad: function () { |
||||
|
// 初始化时间
|
||||
|
this.updateCurrentTime(); |
||||
|
|
||||
|
// 初始化数据
|
||||
|
this.initMarketData(); |
||||
|
|
||||
|
// 启动动画
|
||||
|
this.startPageAnimations(); |
||||
|
|
||||
|
// 启动定时器
|
||||
|
this.startTimers(); |
||||
|
|
||||
|
// 启动无缝滚动
|
||||
|
this.startAutoScroll(); |
||||
|
this.getsales() |
||||
|
this.getfeed() |
||||
|
this.gettrend() |
||||
|
}, |
||||
|
|
||||
|
onShow: function () { |
||||
|
// 恢复滚动(如果之前暂停了)
|
||||
|
if (this.data.isPaused) { |
||||
|
this.setData({ |
||||
|
isPaused: false |
||||
|
}); |
||||
|
this.startAutoScroll(); |
||||
|
} |
||||
}, |
}, |
||||
|
|
||||
/** |
|
||||
* 生命周期函数--监听页面初次渲染完成 |
|
||||
*/ |
|
||||
onReady() { |
|
||||
|
onHide: function () { |
||||
|
// 页面隐藏时暂停滚动
|
||||
|
this.stopAutoScroll(); |
||||
|
this.setData({ |
||||
|
isPaused: true |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
onUnload: function () { |
||||
|
// 清理定时器
|
||||
|
this.clearTimers(); |
||||
|
// 停止滚动
|
||||
|
this.stopAutoScroll(); |
||||
}, |
}, |
||||
|
|
||||
/** |
|
||||
* 生命周期函数--监听页面显示 |
|
||||
*/ |
|
||||
onShow() { |
|
||||
|
|
||||
|
// 销售市场
|
||||
|
getsales() { |
||||
|
http.sales({ |
||||
|
data: {}, |
||||
|
success: res => { |
||||
|
console.log(11, res); |
||||
|
this.setData({ |
||||
|
salesData:res.rows |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
}, |
}, |
||||
|
|
||||
/** |
|
||||
* 生命周期函数--监听页面隐藏 |
|
||||
*/ |
|
||||
onHide() { |
|
||||
|
//饲料市场
|
||||
|
getfeed() { |
||||
|
http.feed({ |
||||
|
data: {}, |
||||
|
success: res => { |
||||
|
console.log(22, res); |
||||
|
this.setData({ |
||||
|
feedData:res.rows |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
// 市场趋势
|
||||
|
gettrend() { |
||||
|
http.trend({ |
||||
|
data: {}, |
||||
|
success: res => { |
||||
|
console.log(22, res); |
||||
|
this.setData({ |
||||
|
trendData:res.rows |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
}, |
}, |
||||
|
|
||||
/** |
|
||||
* 生命周期函数--监听页面卸载 |
|
||||
*/ |
|
||||
onUnload() { |
|
||||
|
onPullDownRefresh: function () { |
||||
|
this.refreshAllData(); |
||||
|
}, |
||||
|
|
||||
|
// 更新当前时间
|
||||
|
updateCurrentTime: function () { |
||||
|
const now = new Date(); |
||||
|
const timeStr = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`; |
||||
|
this.setData({ |
||||
|
currentTime: timeStr |
||||
|
}); |
||||
}, |
}, |
||||
|
|
||||
/** |
|
||||
* 页面相关事件处理函数--监听用户下拉动作 |
|
||||
*/ |
|
||||
onPullDownRefresh() { |
|
||||
|
// 启动定时器
|
||||
|
startTimers: function () { |
||||
|
// 更新时间
|
||||
|
this.timeTimer = setInterval(() => { |
||||
|
this.updateCurrentTime(); |
||||
|
}, 60000); |
||||
|
|
||||
|
// 模拟实时数据更新
|
||||
|
this.dataTimer = setInterval(() => { |
||||
|
this.updateRandomData(); |
||||
|
}, 30000); |
||||
}, |
}, |
||||
|
|
||||
/** |
|
||||
* 页面上拉触底事件的处理函数 |
|
||||
*/ |
|
||||
onReachBottom() { |
|
||||
|
// 清理定时器
|
||||
|
clearTimers: function () { |
||||
|
if (this.timeTimer) clearInterval(this.timeTimer); |
||||
|
if (this.dataTimer) clearInterval(this.dataTimer); |
||||
|
}, |
||||
|
|
||||
|
// 启动自动滚动
|
||||
|
startAutoScroll: function () { |
||||
|
// 清除已有的定时器
|
||||
|
if (this.data.scrollTimer) { |
||||
|
clearInterval(this.data.scrollTimer); |
||||
|
} |
||||
|
|
||||
|
// 计算总高度(一条数据的高度 * 数据条数)
|
||||
|
const totalHeight = this.data.itemHeight * this.data.trendData.length; |
||||
|
|
||||
|
// 设置滚动定时器,每5秒滚动一次
|
||||
|
const scrollTimer = setInterval(() => { |
||||
|
this.autoScrollStep(totalHeight); |
||||
|
}, 5000); |
||||
|
|
||||
|
this.setData({ |
||||
|
scrollTimer |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 停止自动滚动
|
||||
|
stopAutoScroll: function () { |
||||
|
if (this.data.scrollTimer) { |
||||
|
clearInterval(this.data.scrollTimer); |
||||
|
this.setData({ |
||||
|
scrollTimer: null |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 自动滚动步骤
|
||||
|
autoScrollStep: function (totalHeight) { |
||||
|
// 计算下一个偏移量
|
||||
|
let nextOffset = this.data.scrollOffset + this.data.itemHeight; |
||||
|
|
||||
|
// 如果滚动到了第一组数据的末尾,重置到开始位置
|
||||
|
if (nextOffset >= totalHeight) { |
||||
|
// 瞬间回到起点,然后继续滚动
|
||||
|
this.setData({ |
||||
|
scrollOffset: 0, |
||||
|
scrollDuration: 0 |
||||
|
}); |
||||
|
|
||||
|
// 下一帧继续正常滚动
|
||||
|
setTimeout(() => { |
||||
|
this.setData({ |
||||
|
scrollOffset: this.data.itemHeight, |
||||
|
scrollDuration: 0.5 |
||||
|
}); |
||||
|
}, 50); |
||||
|
} else { |
||||
|
// 正常滚动
|
||||
|
this.setData({ |
||||
|
scrollOffset: nextOffset, |
||||
|
scrollDuration: 0.5 |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 手动控制滚动(可选)
|
||||
|
pauseScroll: function () { |
||||
|
this.stopAutoScroll(); |
||||
|
this.setData({ |
||||
|
isPaused: true |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
resumeScroll: function () { |
||||
|
if (this.data.isPaused) { |
||||
|
this.setData({ |
||||
|
isPaused: false |
||||
|
}); |
||||
|
this.startAutoScroll(); |
||||
|
} |
||||
}, |
}, |
||||
|
|
||||
/** |
|
||||
* 用户点击右上角分享 |
|
||||
*/ |
|
||||
onShareAppMessage() { |
|
||||
|
// 初始化市场数据
|
||||
|
initMarketData: function () { |
||||
|
// 模拟销售市场数据(6条数据)
|
||||
|
const salesData = [{ |
||||
|
id: 1, |
||||
|
name: '优质肉牛', |
||||
|
region: '内蒙古呼伦贝尔', |
||||
|
price: 35.8, |
||||
|
unit: '公斤', |
||||
|
trend: 'up', |
||||
|
change: '+2.3%', |
||||
|
updateTime: '09:30' |
||||
|
}, |
||||
|
{ |
||||
|
id: 2, |
||||
|
name: '绵羊', |
||||
|
region: '新疆阿勒泰', |
||||
|
price: 28.5, |
||||
|
unit: '公斤', |
||||
|
trend: 'stable', |
||||
|
change: '0%', |
||||
|
updateTime: '09:25' |
||||
|
}, |
||||
|
{ |
||||
|
id: 3, |
||||
|
name: '山羊', |
||||
|
region: '山东济宁', |
||||
|
price: 32.2, |
||||
|
unit: '公斤', |
||||
|
trend: 'down', |
||||
|
change: '-1.5%', |
||||
|
updateTime: '09:20' |
||||
|
}, |
||||
|
{ |
||||
|
id: 4, |
||||
|
name: '奶牛', |
||||
|
region: '黑龙江', |
||||
|
price: 26.8, |
||||
|
unit: '公斤', |
||||
|
trend: 'up', |
||||
|
change: '+1.2%', |
||||
|
updateTime: '09:15' |
||||
|
}, |
||||
|
{ |
||||
|
id: 5, |
||||
|
name: '生猪', |
||||
|
region: '河南', |
||||
|
price: 18.5, |
||||
|
unit: '公斤', |
||||
|
trend: 'up', |
||||
|
change: '+3.1%', |
||||
|
updateTime: '09:10' |
||||
|
}, |
||||
|
{ |
||||
|
id: 6, |
||||
|
name: '肉羊', |
||||
|
region: '甘肃', |
||||
|
price: 30.2, |
||||
|
unit: '公斤', |
||||
|
trend: 'stable', |
||||
|
change: '0%', |
||||
|
updateTime: '09:05' |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
// 模拟饲料市场数据(5条数据)
|
||||
|
const feedData = [{ |
||||
|
id: 1, |
||||
|
name: '玉米饲料', |
||||
|
supplier: '内蒙古正大饲料有限公司', |
||||
|
price: 2.85, |
||||
|
unit: '公斤', |
||||
|
trend: 'up', |
||||
|
chartHeight: 85, |
||||
|
updateTime: '09:28' |
||||
|
}, |
||||
|
{ |
||||
|
id: 2, |
||||
|
name: '豆粕', |
||||
|
supplier: '山东六和集团股份有限公司', |
||||
|
price: 3.42, |
||||
|
unit: '公斤', |
||||
|
trend: 'up', |
||||
|
chartHeight: 92, |
||||
|
updateTime: '09:25' |
||||
|
}, |
||||
|
{ |
||||
|
id: 3, |
||||
|
name: '青贮饲料', |
||||
|
supplier: '河北牧原股份有限责任公司', |
||||
|
price: 0.78, |
||||
|
unit: '公斤', |
||||
|
trend: 'stable', |
||||
|
chartHeight: 65, |
||||
|
updateTime: '09:22' |
||||
|
}, |
||||
|
{ |
||||
|
id: 4, |
||||
|
name: '麦麸', |
||||
|
supplier: '河南双汇发展有限公司', |
||||
|
price: 1.25, |
||||
|
unit: '公斤', |
||||
|
trend: 'down', |
||||
|
chartHeight: 45, |
||||
|
updateTime: '09:20' |
||||
|
}, |
||||
|
{ |
||||
|
id: 5, |
||||
|
name: '鱼粉', |
||||
|
supplier: '广东海大集团', |
||||
|
price: 5.8, |
||||
|
unit: '公斤', |
||||
|
trend: 'stable', |
||||
|
chartHeight: 60, |
||||
|
updateTime: '09:18' |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
// 模拟市场趋势通知公告数据(8条数据)
|
||||
|
const trendData = [{ |
||||
|
id: 1, |
||||
|
type: 'report', |
||||
|
title: '2023年Q3畜牧业市场分析报告发布', |
||||
|
source: '国家统计局', |
||||
|
date: '2023-10-15', |
||||
|
summary: '第三季度畜产品价格整体上涨3.2%,饲料成本下降1.5%,养殖效益显著提升', |
||||
|
isNew: true, |
||||
|
isHot: true |
||||
|
}, |
||||
|
{ |
||||
|
id: 2, |
||||
|
type: 'prediction', |
||||
|
title: '专家预测:四季度牛肉价格将稳中有升', |
||||
|
source: '行业专家委员会', |
||||
|
date: '2023-10-12', |
||||
|
summary: '受季节因素影响,预计四季度牛肉价格上涨幅度在3-5%之间', |
||||
|
isNew: true, |
||||
|
isHot: false |
||||
|
}, |
||||
|
{ |
||||
|
id: 3, |
||||
|
type: 'report', |
||||
|
title: '全国饲料价格指数月报(9月份)', |
||||
|
source: '农业部监测中心', |
||||
|
date: '2023-10-10', |
||||
|
summary: '9月份全国饲料价格指数为108.5,环比上涨0.8%,同比上涨2.3%', |
||||
|
isNew: false, |
||||
|
isHot: true |
||||
|
}, |
||||
|
{ |
||||
|
id: 4, |
||||
|
type: 'prediction', |
||||
|
title: '冬季饲草供应紧张预警', |
||||
|
source: '气象局农业处', |
||||
|
date: '2023-10-08', |
||||
|
summary: '北方地区提前进入冬季,预计饲草储备量不足,价格可能上涨', |
||||
|
isNew: true, |
||||
|
isHot: true |
||||
|
}, |
||||
|
{ |
||||
|
id: 5, |
||||
|
type: 'report', |
||||
|
title: '牛羊养殖效益分析报告', |
||||
|
source: '畜牧业协会', |
||||
|
date: '2023-10-05', |
||||
|
summary: '2023年1-9月牛羊养殖效益同比增长8.5%,创近三年新高', |
||||
|
isNew: false, |
||||
|
isHot: false |
||||
|
}, |
||||
|
{ |
||||
|
id: 6, |
||||
|
type: 'report', |
||||
|
title: '畜产品质量安全监测报告', |
||||
|
source: '质量监督局', |
||||
|
date: '2023-10-03', |
||||
|
summary: '第三季度畜产品质量抽检合格率达99.2%,质量安全状况良好', |
||||
|
isNew: false, |
||||
|
isHot: false |
||||
|
}, |
||||
|
{ |
||||
|
id: 7, |
||||
|
type: 'prediction', |
||||
|
title: '明年饲料原料价格走势分析', |
||||
|
source: '农业经济研究所', |
||||
|
date: '2023-10-01', |
||||
|
summary: '预计明年玉米、豆粕等主要原料价格将保持稳定,波动幅度有限', |
||||
|
isNew: false, |
||||
|
isHot: false |
||||
|
}, |
||||
|
{ |
||||
|
id: 8, |
||||
|
type: 'report', |
||||
|
title: '畜牧业数字化转型进展报告', |
||||
|
source: '工信部', |
||||
|
date: '2023-09-28', |
||||
|
summary: '全国畜牧业数字化率已达45%,智能养殖设备普及率显著提升', |
||||
|
isNew: false, |
||||
|
isHot: true |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
// 计算未读数量
|
||||
|
const unreadCount = trendData.filter(item => item.isNew).length; |
||||
|
|
||||
|
const now = new Date(); |
||||
|
const timeStr = `${now.getMonth()+1}月${now.getDate()}日 ${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`; |
||||
|
const lastUpdateTime = `${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`; |
||||
|
|
||||
|
this.setData({ |
||||
|
salesData, |
||||
|
feedData, |
||||
|
trendData, |
||||
|
unreadCount, |
||||
|
salesUpdateTime: timeStr, |
||||
|
feedUpdateTime: timeStr, |
||||
|
lastUpdateTime, |
||||
|
salesStatus: 'inactive', |
||||
|
feedStatus: 'inactive' |
||||
|
}); |
||||
|
|
||||
|
// 模拟数据加载完成
|
||||
|
setTimeout(() => { |
||||
|
this.setData({ |
||||
|
salesStatus: 'active', |
||||
|
feedStatus: 'active' |
||||
|
}); |
||||
|
}, 1500); |
||||
|
}, |
||||
|
|
||||
|
// 启动页面动画
|
||||
|
startPageAnimations: function () { |
||||
|
// 头部动画
|
||||
|
const headerAnimation = wx.createAnimation({ |
||||
|
duration: 800, |
||||
|
timingFunction: 'ease-out' |
||||
|
}); |
||||
|
headerAnimation.translateY(0).opacity(1).step(); |
||||
|
|
||||
|
// 卡片动画
|
||||
|
const cardAnimation1 = wx.createAnimation({ |
||||
|
duration: 600, |
||||
|
timingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)', |
||||
|
delay: 200 |
||||
|
}); |
||||
|
cardAnimation1.translateY(0).opacity(1).step(); |
||||
|
|
||||
|
const cardAnimation2 = wx.createAnimation({ |
||||
|
duration: 600, |
||||
|
timingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)', |
||||
|
delay: 350 |
||||
|
}); |
||||
|
cardAnimation2.translateY(0).opacity(1).step(); |
||||
|
|
||||
|
const cardAnimation3 = wx.createAnimation({ |
||||
|
duration: 600, |
||||
|
timingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)', |
||||
|
delay: 500 |
||||
|
}); |
||||
|
cardAnimation3.translateY(0).opacity(1).step(); |
||||
|
|
||||
|
this.setData({ |
||||
|
headerAnimation: headerAnimation.export(), |
||||
|
cardAnimation1: cardAnimation1.export(), |
||||
|
cardAnimation2: cardAnimation2.export(), |
||||
|
cardAnimation3: cardAnimation3.export() |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 刷新所有数据
|
||||
|
refreshAllData: function () { |
||||
|
if (this.data.isRefreshing) return; |
||||
|
|
||||
|
this.setData({ |
||||
|
isRefreshing: true, |
||||
|
salesStatus: 'active', |
||||
|
feedStatus: 'active' |
||||
|
}); |
||||
|
|
||||
|
// 显示加载动画
|
||||
|
wx.showLoading({ |
||||
|
title: '更新数据中...', |
||||
|
mask: true |
||||
|
}); |
||||
|
|
||||
|
// 模拟网络请求
|
||||
|
setTimeout(() => { |
||||
|
// 更新数据
|
||||
|
this.updateRandomData(); |
||||
|
|
||||
|
// 更新时间戳
|
||||
|
const now = new Date(); |
||||
|
const timeStr = `${now.getMonth()+1}月${now.getDate()}日 ${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`; |
||||
|
const lastUpdateTime = `${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`; |
||||
|
|
||||
|
this.setData({ |
||||
|
salesUpdateTime: timeStr, |
||||
|
feedUpdateTime: timeStr, |
||||
|
lastUpdateTime, |
||||
|
isRefreshing: false, |
||||
|
salesStatus: 'inactive', |
||||
|
feedStatus: 'inactive' |
||||
|
}); |
||||
|
|
||||
|
// 显示成功提示
|
||||
|
wx.hideLoading(); |
||||
|
wx.showToast({ |
||||
|
title: '数据已更新', |
||||
|
icon: 'success', |
||||
|
duration: 1500 |
||||
|
}); |
||||
|
|
||||
|
// 停止下拉刷新
|
||||
|
wx.stopPullDownRefresh(); |
||||
|
}, 1500); |
||||
|
}, |
||||
|
|
||||
|
// 更新随机数据(模拟实时变化)
|
||||
|
updateRandomData: function () { |
||||
|
// 随机更新销售价格
|
||||
|
const updatedSalesData = this.data.salesData.map(item => { |
||||
|
const random = Math.random(); |
||||
|
let newPrice, trend, change; |
||||
|
|
||||
|
if (random < 0.4) { |
||||
|
// 上涨
|
||||
|
trend = 'up'; |
||||
|
change = +(Math.random() * 0.5 + 0.1).toFixed(1); |
||||
|
newPrice = +(item.price * (1 + change / 100)).toFixed(1); |
||||
|
} else if (random < 0.7) { |
||||
|
// 稳定
|
||||
|
trend = 'stable'; |
||||
|
change = 0; |
||||
|
newPrice = item.price; |
||||
|
} else { |
||||
|
// 下降
|
||||
|
trend = 'down'; |
||||
|
change = +(Math.random() * 0.5 + 0.1).toFixed(1); |
||||
|
newPrice = +(item.price * (1 - change / 100)).toFixed(1); |
||||
|
} |
||||
|
|
||||
|
// 更新时间
|
||||
|
const now = new Date(); |
||||
|
const updateTime = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`; |
||||
|
|
||||
|
return { |
||||
|
...item, |
||||
|
price: newPrice, |
||||
|
trend, |
||||
|
change: trend === 'stable' ? '0%' : (trend === 'up' ? `+${change}%` : `-${change}%`), |
||||
|
updateTime |
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
// 随机更新饲料价格
|
||||
|
const updatedFeedData = this.data.feedData.map(item => { |
||||
|
const random = Math.random(); |
||||
|
let trend, chartHeight; |
||||
|
|
||||
|
if (random < 0.4) { |
||||
|
trend = 'up'; |
||||
|
chartHeight = Math.floor(Math.random() * 30 + 70); |
||||
|
} else if (random < 0.7) { |
||||
|
trend = 'stable'; |
||||
|
chartHeight = Math.floor(Math.random() * 20 + 50); |
||||
|
} else { |
||||
|
trend = 'down'; |
||||
|
chartHeight = Math.floor(Math.random() * 20 + 30); |
||||
|
} |
||||
|
|
||||
|
// 轻微调整价格
|
||||
|
const priceChange = (Math.random() - 0.5) * 0.1; |
||||
|
const newPrice = +(item.price + priceChange).toFixed(2); |
||||
|
|
||||
|
// 更新时间
|
||||
|
const now = new Date(); |
||||
|
const updateTime = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`; |
||||
|
|
||||
|
return { |
||||
|
...item, |
||||
|
price: newPrice > 0 ? newPrice : item.price, |
||||
|
trend, |
||||
|
chartHeight, |
||||
|
updateTime |
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
// 随机更新趋势数据(标记一些为已读,添加新公告)
|
||||
|
const updatedTrendData = [...this.data.trendData]; |
||||
|
|
||||
|
// 随机标记一些为已读
|
||||
|
updatedTrendData.forEach((item, index) => { |
||||
|
if (item.isNew && Math.random() > 0.7) { |
||||
|
updatedTrendData[index] = { |
||||
|
...item, |
||||
|
isNew: false |
||||
|
}; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 偶尔添加新公告
|
||||
|
if (Math.random() > 0.8) { |
||||
|
const newNotice = { |
||||
|
id: Date.now(), |
||||
|
type: Math.random() > 0.5 ? 'report' : 'prediction', |
||||
|
title: `实时快报:${Math.random() > 0.5 ? '价格波动提醒' : '行业动态更新'}`, |
||||
|
source: '实时监测系统', |
||||
|
date: new Date().toISOString().split('T')[0], |
||||
|
summary: '系统监测到市场出现新的变化,请关注后续详细分析', |
||||
|
isNew: true, |
||||
|
isHot: Math.random() > 0.7 |
||||
|
}; |
||||
|
updatedTrendData.unshift(newNotice); |
||||
|
} |
||||
|
|
||||
|
const unreadCount = updatedTrendData.filter(item => item.isNew).length; |
||||
|
|
||||
|
this.setData({ |
||||
|
salesData: updatedSalesData, |
||||
|
feedData: updatedFeedData, |
||||
|
trendData: updatedTrendData, |
||||
|
unreadCount |
||||
|
}); |
||||
} |
} |
||||
}) |
|
||||
|
}); |
||||
@ -1,3 +1,4 @@ |
|||||
{ |
{ |
||||
|
"navigationBarTitleText":"市场信息", |
||||
"usingComponents": {} |
"usingComponents": {} |
||||
} |
} |
||||
@ -1,2 +1,312 @@ |
|||||
<!--pages/market/market.wxml--> |
|
||||
<text>pages/market/market.wxml</text> |
|
||||
|
<!-- pages/market/market.wxml --> |
||||
|
<view class="market-page"> |
||||
|
<!-- 顶部渐变标题栏 --> |
||||
|
<view class="header-container" animation="{{headerAnimation}}"> |
||||
|
<view class="header-bg"> |
||||
|
<view class="bg-gradient"></view> |
||||
|
<view class="bg-pattern"></view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="header-content"> |
||||
|
<view class="header-main"> |
||||
|
<view class="title-area"> |
||||
|
<view class="app-name">畜牧业市场信息</view> |
||||
|
<view class="app-desc">实时行情 · 专业洞察 · 精准决策</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="header-actions"> |
||||
|
<view class="time-display"> |
||||
|
<text class="iconfont icon-time"></text> |
||||
|
<text>{{currentTime}}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 数据统计摘要 --> |
||||
|
<view class="data-summary"> |
||||
|
<view class="summary-item"> |
||||
|
<text class="summary-value">{{salesData.length}}</text> |
||||
|
<text class="summary-label">畜产品类</text> |
||||
|
</view> |
||||
|
<view class="summary-divider"></view> |
||||
|
<view class="summary-item"> |
||||
|
<text class="summary-value">{{feedData.length}}</text> |
||||
|
<text class="summary-label">饲料品类</text> |
||||
|
</view> |
||||
|
<view class="summary-divider"></view> |
||||
|
<view class="summary-item"> |
||||
|
<text class="summary-value">{{trendData.length}}</text> |
||||
|
<text class="summary-label">趋势公告</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 主内容区域 --> |
||||
|
<scroll-view |
||||
|
scroll-y |
||||
|
class="content-container" |
||||
|
enable-back-to-top="true" |
||||
|
refresher-enabled="{{true}}" |
||||
|
refresher-triggered="{{isRefreshing}}" |
||||
|
bindrefresherrefresh="onPullDownRefresh" |
||||
|
> |
||||
|
<!-- 销售市场卡片 --> |
||||
|
<view class="section-title fade-in-item"> |
||||
|
<text class="section-icon iconfont icon-sales"></text> |
||||
|
<text class="section-text">销售市场</text> |
||||
|
<text class="section-desc">畜产品价格动态</text> |
||||
|
<view class="section-indicator"></view> |
||||
|
<view class="data-count" wx:if="{{salesData.length > 3}}"> |
||||
|
<text>{{salesData.length}}条</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view |
||||
|
class="market-card card-sales" |
||||
|
animation="{{cardAnimation1}}" |
||||
|
> |
||||
|
<view class="card-header"> |
||||
|
<view class="card-title-area"> |
||||
|
<view class="card-main-title"> |
||||
|
<view class="card-icon"> |
||||
|
<image src="/pages/images/ccp.png" class="icon-img" mode="aspectFit" /> |
||||
|
</view> |
||||
|
<text class="card-title-text">畜产品实时价格</text> |
||||
|
</view> |
||||
|
<view class="card-subtitle">各地牛、羊等畜产品的市场价格动态</view> |
||||
|
</view> |
||||
|
<view class="card-status"> |
||||
|
<view class="status-dot {{salesStatus}}"></view> |
||||
|
<text class="status-text">{{salesStatus === 'active' ? '更新中' : '已更新'}}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 销售市场数据 - 可滚动区域 --> |
||||
|
<scroll-view |
||||
|
scroll-y |
||||
|
class="data-scroll-container" |
||||
|
style="height: {{salesData.length > 3 ? '420rpx' : 'auto'}}" |
||||
|
> |
||||
|
<view class="price-list"> |
||||
|
<view class="price-item" wx:for="{{salesData}}" wx:key="id"> |
||||
|
<view class="price-info"> |
||||
|
<text class="product-name">{{item.productName}}</text> |
||||
|
<text class="product-region">{{item.regionDetail}}</text> |
||||
|
</view> |
||||
|
<view class="price-value {{item.trend}}"> |
||||
|
<text class="price-number">¥{{item.price}}</text> |
||||
|
<text class="price-unit">{{item.unit}}</text> |
||||
|
<view class="trend-indicator"> |
||||
|
<text class="trend-icon" wx:if="{{item.trend === 'up'}}">↗</text> |
||||
|
<text class="trend-icon" wx:if="{{item.trend === 'down'}}">↘</text> |
||||
|
<text class="trend-icon" wx:if="{{item.trend === 'stable'}}">→</text> |
||||
|
<text class="trend-change" wx:if="{{item.priceChange}}">+{{item.priceChange}}%</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="price-time"> |
||||
|
<text class="iconfont icon-clock-small"></text> |
||||
|
<text>{{item.updateTime}}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
|
||||
|
<view class="card-footer"> |
||||
|
<view class="update-info"> |
||||
|
<text class="iconfont icon-clock"></text> |
||||
|
<text class="update-text">更新于 {{salesUpdateTime}}</text> |
||||
|
</view> |
||||
|
<view class="scroll-tip" wx:if="{{salesData.length > 3}}"> |
||||
|
<text class="iconfont icon-scroll"></text> |
||||
|
<text>上下滚动查看更多</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 饲料市场卡片 --> |
||||
|
<view class="section-title fade-in-item" style="animation-delay: 0.1s"> |
||||
|
<text class="section-text">饲料市场</text> |
||||
|
<text class="section-desc">饲草料供应商价格</text> |
||||
|
<view class="section-indicator"></view> |
||||
|
<view class="data-count" wx:if="{{feedData.length > 3}}"> |
||||
|
<text>{{feedData.length}}条</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view |
||||
|
class="market-card card-feed" |
||||
|
animation="{{cardAnimation2}}" |
||||
|
> |
||||
|
<view class="card-corner"></view> |
||||
|
|
||||
|
<view class="card-header"> |
||||
|
<view class="card-title-area"> |
||||
|
<view class="card-main-title"> |
||||
|
<view class="card-icon"> |
||||
|
<image src="/pages/images/sl.png" class="icon-img" mode="aspectFit" /> |
||||
|
</view> |
||||
|
<text class="card-title-text">饲料价格行情</text> |
||||
|
</view> |
||||
|
<view class="card-subtitle">各地饲草料供应商实时报价</view> |
||||
|
</view> |
||||
|
<view class="card-status"> |
||||
|
<view class="status-dot {{feedStatus}}"></view> |
||||
|
<text class="status-text">{{feedStatus === 'active' ? '更新中' : '已更新'}}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 饲料市场数据 - 可滚动区域 --> |
||||
|
<scroll-view |
||||
|
scroll-y |
||||
|
class="data-scroll-container" |
||||
|
style="height: {{feedData.length > 3 ? '420rpx' : 'auto'}}" |
||||
|
> |
||||
|
<view class="supplier-list"> |
||||
|
<view class="supplier-item" wx:for="{{feedData}}" wx:key="id"> |
||||
|
<view class="supplier-info"> |
||||
|
<text class="supplier-name">{{item.feedName}}</text> |
||||
|
<text class="supplier-company">{{item.supplier}}</text> |
||||
|
</view> |
||||
|
<view class="price-display"> |
||||
|
<view class="price-tag {{item.trend}}"> |
||||
|
<text class="price-label">¥{{item.price}}</text> |
||||
|
<text class="price-per">{{item.unit}}</text> |
||||
|
</view> |
||||
|
<view class="trend-chart-small"> |
||||
|
<view class="chart-bar {{item.trend}}" |
||||
|
style="height: {{item.chartHeight}}%"> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="supplier-time"> |
||||
|
<text class="iconfont icon-clock-small"></text> |
||||
|
<text>{{item.updateTime}}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
|
||||
|
<view class="card-footer"> |
||||
|
<view class="update-info"> |
||||
|
<text class="iconfont icon-clock"></text> |
||||
|
<text class="update-text">更新于 {{feedUpdateTime}}</text> |
||||
|
</view> |
||||
|
<view class="scroll-tip" wx:if="{{feedData.length > 3}}"> |
||||
|
<text class="iconfont icon-scroll"></text> |
||||
|
<text>上下滚动查看更多</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 市场趋势卡片 - 通知公告(无缝向上滚动) --> |
||||
|
<view class="section-title fade-in-item" style="animation-delay: 0.2s"> |
||||
|
<text class="section-icon iconfont icon-trend"></text> |
||||
|
<text class="section-text">市场趋势</text> |
||||
|
<text class="section-desc">通知公告与行业分析</text> |
||||
|
<view class="section-indicator"></view> |
||||
|
<view class="unread-badge" wx:if="{{unreadCount > 0}}"> |
||||
|
<text class="badge-text">{{unreadCount}}条未读</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view |
||||
|
class="market-card card-trend" |
||||
|
animation="{{cardAnimation3}}" |
||||
|
> |
||||
|
<view class="card-corner"></view> |
||||
|
|
||||
|
<view class="card-header"> |
||||
|
<view class="card-title-area"> |
||||
|
<view class="card-main-title"> |
||||
|
<view class="card-icon"> |
||||
|
<image src="/pages/images/scqs.png" class="icon-img" mode="aspectFit" /> |
||||
|
</view> |
||||
|
<text class="card-title-text">行业洞察与预测</text> |
||||
|
</view> |
||||
|
<view class="card-subtitle">行业报告和专家预测等信息,把握市场发展方向</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 市场趋势通知公告 - 无缝向上滚动区域 --> |
||||
|
<view class="notice-scroll-wrapper" style="height: 420rpx;"> |
||||
|
<view class="notice-scroll-content" |
||||
|
style="transform: translateY(-{{scrollOffset}}px); transition: transform {{scrollDuration}}s ease;"> |
||||
|
<!-- 第一组数据 --> |
||||
|
<view class="notice-list"> |
||||
|
<view class="notice-item" wx:for="{{trendData}}" wx:key="id"> |
||||
|
<view class="notice-left"> |
||||
|
<view class="notice-type {{item.type}}"> |
||||
|
{{item.category === '报告' ? '报告' : '预测'}} |
||||
|
</view> |
||||
|
<view class="notice-marker {{item.isNew ? 'new' : ''}}"></view> |
||||
|
</view> |
||||
|
<view class="notice-content"> |
||||
|
<view class="notice-title-area"> |
||||
|
<text class="notice-title">{{item.title}}</text> |
||||
|
<view class="notice-tag hot" wx:if="{{item.isHot}}"> |
||||
|
<text>热点</text> |
||||
|
</view> |
||||
|
<view class="notice-tag new" wx:if="{{item.isNew}}"> |
||||
|
<text>新</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<text class="notice-summary">{{item.content}}</text> |
||||
|
<view class="notice-footer"> |
||||
|
<text class="notice-source">{{item.source}}</text> |
||||
|
<text class="notice-date">{{item.publishDate}}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 第二组相同数据(用于无缝滚动) --> |
||||
|
<view class="notice-list"> |
||||
|
<view class="notice-item" wx:for="{{trendData}}" wx:key="id"> |
||||
|
<view class="notice-left"> |
||||
|
<view class="notice-type {{item.type}}"> |
||||
|
{{item.category === '报告' ? '报告' : '预测'}} |
||||
|
</view> |
||||
|
<view class="notice-marker {{item.isNew ? 'new' : ''}}"></view> |
||||
|
</view> |
||||
|
<view class="notice-content"> |
||||
|
<view class="notice-title-area"> |
||||
|
<text class="notice-title">{{item.title}}</text> |
||||
|
<view class="notice-tag hot" wx:if="{{item.isHot}}"> |
||||
|
<text>热点</text> |
||||
|
</view> |
||||
|
<view class="notice-tag new" wx:if="{{item.isNew}}"> |
||||
|
<text>新</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<text class="notice-summary">{{item.content}}</text> |
||||
|
<view class="notice-footer"> |
||||
|
<text class="notice-source">{{item.source}}</text> |
||||
|
<text class="notice-date">{{item.publishDate}}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="card-footer"> |
||||
|
<view class="statistics-info"> |
||||
|
<text class="stat-text">共 {{trendData.length}} 条公告 · 自动滚动</text> |
||||
|
</view> |
||||
|
<view class="auto-scroll-tip"> |
||||
|
<text class="iconfont icon-auto-scroll"></text> |
||||
|
<text>每5秒自动滚动</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 数据更新时间 --> |
||||
|
<view class="update-footer fade-in-item" style="animation-delay: 0.3s"> |
||||
|
<view class="update-line"> |
||||
|
<text class="iconfont icon-sync"></text> |
||||
|
<text class="update-tip">数据每30分钟自动同步 · 最后更新 {{lastUpdateTime}}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
</view> |
||||
@ -1 +1,771 @@ |
|||||
/* pages/market/market.wxss */ |
|
||||
|
.market-page { |
||||
|
min-height: 100vh; |
||||
|
background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%); |
||||
|
} |
||||
|
|
||||
|
/* 头部容器优化 */ |
||||
|
.header-container { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
border-radius: 0 0 40rpx 40rpx; |
||||
|
box-shadow: 0 4rpx 20rpx rgba(26, 124, 58, 0.15); |
||||
|
} |
||||
|
|
||||
|
.header-bg { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.bg-gradient { |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background: linear-gradient(135deg, |
||||
|
rgba(26, 124, 58, 0.95) 0%, |
||||
|
rgba(46, 204, 113, 0.9) 50%, |
||||
|
rgba(46, 204, 113, 0.85) 100%); |
||||
|
} |
||||
|
|
||||
|
.bg-pattern { |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background-image: |
||||
|
radial-gradient(circle at 20% 80%, rgba(255, 255, 255, 0.1) 2rpx, transparent 2rpx), |
||||
|
radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.1) 2rpx, transparent 2rpx); |
||||
|
background-size: 60rpx 60rpx; |
||||
|
} |
||||
|
|
||||
|
.header-content { |
||||
|
position: relative; |
||||
|
z-index: 2; |
||||
|
padding: 40rpx 32rpx 0; |
||||
|
} |
||||
|
|
||||
|
.header-main { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: flex-start; |
||||
|
margin-bottom: 30rpx; |
||||
|
} |
||||
|
|
||||
|
.title-area { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.app-name { |
||||
|
font-size: 44rpx; |
||||
|
font-weight: 700; |
||||
|
color: white; |
||||
|
letter-spacing: 1rpx; |
||||
|
margin-bottom: 8rpx; |
||||
|
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1); |
||||
|
} |
||||
|
|
||||
|
.app-desc { |
||||
|
font-size: 24rpx; |
||||
|
color: rgba(255, 255, 255, 0.9); |
||||
|
} |
||||
|
|
||||
|
.header-actions { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.time-display { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
background: rgba(255, 255, 255, 0.15); |
||||
|
padding: 8rpx 16rpx; |
||||
|
border-radius: 20rpx; |
||||
|
font-size: 22rpx; |
||||
|
color: white; |
||||
|
} |
||||
|
|
||||
|
.time-display .iconfont { |
||||
|
font-size: 24rpx; |
||||
|
margin-right: 8rpx; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.iconfont.rotating { |
||||
|
animation: rotate 1s linear infinite; |
||||
|
} |
||||
|
|
||||
|
@keyframes rotate { |
||||
|
from { |
||||
|
transform: rotate(0deg); |
||||
|
} |
||||
|
to { |
||||
|
transform: rotate(360deg); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 数据统计摘要优化 */ |
||||
|
.data-summary { |
||||
|
display: flex; |
||||
|
background: rgba(255, 255, 255, 0.15); |
||||
|
backdrop-filter: blur(10rpx); |
||||
|
border-radius: 20rpx; |
||||
|
padding: 24rpx; |
||||
|
margin-bottom: 30rpx; |
||||
|
border: 1rpx solid rgba(255, 255, 255, 0.2); |
||||
|
} |
||||
|
|
||||
|
.summary-item { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.summary-value { |
||||
|
font-size: 36rpx; |
||||
|
font-weight: 700; |
||||
|
color: white; |
||||
|
margin-bottom: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.summary-label { |
||||
|
font-size: 22rpx; |
||||
|
color: rgba(255, 255, 255, 0.9); |
||||
|
} |
||||
|
|
||||
|
.summary-divider { |
||||
|
width: 1rpx; |
||||
|
background: rgba(255, 255, 255, 0.3); |
||||
|
margin: 0 20rpx; |
||||
|
} |
||||
|
|
||||
|
/* 内容容器优化 */ |
||||
|
.content-container { |
||||
|
height: calc(100vh - 280rpx); |
||||
|
padding: 0 32rpx; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
/* 区块标题优化 */ |
||||
|
.section-title { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin: 40rpx 0 20rpx; |
||||
|
padding-bottom: 16rpx; |
||||
|
border-bottom: 2rpx solid #e2e8f0; |
||||
|
position: relative; |
||||
|
opacity: 0; |
||||
|
transform: translateX(-20rpx); |
||||
|
animation: slideIn 0.6s ease forwards; |
||||
|
} |
||||
|
|
||||
|
.fade-in-item { |
||||
|
opacity: 0; |
||||
|
transform: translateX(-20rpx); |
||||
|
animation: slideIn 0.6s ease forwards; |
||||
|
} |
||||
|
|
||||
|
@keyframes slideIn { |
||||
|
to { |
||||
|
opacity: 1; |
||||
|
transform: translateX(0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
.section-text { |
||||
|
font-size: 32rpx; |
||||
|
font-weight: 600; |
||||
|
color: #1e293b; |
||||
|
margin-right: 16rpx; |
||||
|
} |
||||
|
|
||||
|
.section-desc { |
||||
|
font-size: 24rpx; |
||||
|
color: #64748b; |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.section-indicator { |
||||
|
width: 6rpx; |
||||
|
height: 32rpx; |
||||
|
background: #1a7c3a; |
||||
|
border-radius: 3rpx; |
||||
|
margin-left: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.data-count { |
||||
|
background: #e2e8f0; |
||||
|
color: #64748b; |
||||
|
font-size: 22rpx; |
||||
|
padding: 4rpx 12rpx; |
||||
|
border-radius: 12rpx; |
||||
|
margin-left: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.unread-badge { |
||||
|
background: #ef4444; |
||||
|
color: white; |
||||
|
font-size: 20rpx; |
||||
|
padding: 4rpx 12rpx; |
||||
|
border-radius: 12rpx; |
||||
|
margin-left: 12rpx; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
/* 卡片通用样式优化 */ |
||||
|
.market-card { |
||||
|
background: white; |
||||
|
border-radius: 24rpx; |
||||
|
overflow: hidden; |
||||
|
margin-bottom: 32rpx; |
||||
|
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.06); |
||||
|
position: relative; |
||||
|
border: 1rpx solid #e2e8f0; |
||||
|
opacity: 0; |
||||
|
transform: translateY(40rpx); |
||||
|
} |
||||
|
|
||||
|
.market-card:active { |
||||
|
transform: translateY(2rpx); |
||||
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.card-header { |
||||
|
padding: 32rpx 32rpx 20rpx; |
||||
|
border-bottom: 1rpx solid #f1f5f9; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: flex-start; |
||||
|
} |
||||
|
|
||||
|
.card-title-area { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.card-main-title { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-bottom: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.card-icon { |
||||
|
width: 56rpx; |
||||
|
height: 56rpx; |
||||
|
border-radius: 14rpx; |
||||
|
margin-right: 16rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.card-sales .card-icon { |
||||
|
background: linear-gradient(135deg, #ff6b6b, #ff8e8e); |
||||
|
} |
||||
|
|
||||
|
.card-feed .card-icon { |
||||
|
background: linear-gradient(135deg, #4d96ff, #6bc5ff); |
||||
|
} |
||||
|
|
||||
|
.card-trend .card-icon { |
||||
|
background: linear-gradient(135deg, #ffd166, #ffde8a); |
||||
|
} |
||||
|
|
||||
|
.icon-img { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
} |
||||
|
|
||||
|
.card-title-text { |
||||
|
font-size: 32rpx; |
||||
|
font-weight: 600; |
||||
|
color: #1e293b; |
||||
|
} |
||||
|
|
||||
|
.card-subtitle { |
||||
|
font-size: 24rpx; |
||||
|
color: #64748b; |
||||
|
line-height: 1.4; |
||||
|
} |
||||
|
|
||||
|
.card-status { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.status-dot { |
||||
|
width: 12rpx; |
||||
|
height: 12rpx; |
||||
|
border-radius: 50%; |
||||
|
} |
||||
|
|
||||
|
.status-dot.active { |
||||
|
background: #10b981; |
||||
|
animation: pulse 2s infinite; |
||||
|
} |
||||
|
|
||||
|
.status-dot.inactive { |
||||
|
background: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
@keyframes pulse { |
||||
|
0%, 100% { |
||||
|
opacity: 1; |
||||
|
} |
||||
|
50% { |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.status-text { |
||||
|
font-size: 22rpx; |
||||
|
color: #64748b; |
||||
|
} |
||||
|
|
||||
|
/* 数据滚动容器 */ |
||||
|
.data-scroll-container { |
||||
|
padding: 0 32rpx; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
/* 销售市场列表样式 */ |
||||
|
.price-list { |
||||
|
padding: 20rpx 0; |
||||
|
} |
||||
|
|
||||
|
.price-item { |
||||
|
padding: 28rpx 0; |
||||
|
border-bottom: 1rpx solid #f1f5f9; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.price-item:last-child { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
|
||||
|
.price-info { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: flex-start; |
||||
|
} |
||||
|
|
||||
|
.product-name { |
||||
|
font-size: 28rpx; |
||||
|
font-weight: 500; |
||||
|
color: #1e293b; |
||||
|
} |
||||
|
|
||||
|
.product-region { |
||||
|
font-size: 22rpx; |
||||
|
color: #64748b; |
||||
|
background: #f8fafc; |
||||
|
padding: 4rpx 12rpx; |
||||
|
border-radius: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.price-value { |
||||
|
display: flex; |
||||
|
align-items: baseline; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.price-number { |
||||
|
font-size: 36rpx; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.price-unit { |
||||
|
font-size: 22rpx; |
||||
|
color: #64748b; |
||||
|
margin-left: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.trend-indicator { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.trend-icon { |
||||
|
font-size: 28rpx; |
||||
|
} |
||||
|
|
||||
|
.trend-change { |
||||
|
font-size: 22rpx; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.price-value.up { |
||||
|
color: #ef4444; |
||||
|
} |
||||
|
|
||||
|
.price-value.down { |
||||
|
color: #10b981; |
||||
|
} |
||||
|
|
||||
|
.price-value.stable { |
||||
|
color: #6b7280; |
||||
|
} |
||||
|
|
||||
|
.price-time { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8rpx; |
||||
|
font-size: 22rpx; |
||||
|
color: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
.iconfont.icon-clock-small { |
||||
|
font-size: 20rpx; |
||||
|
} |
||||
|
|
||||
|
/* 饲料市场列表样式 */ |
||||
|
.supplier-list { |
||||
|
padding: 20rpx 0; |
||||
|
} |
||||
|
|
||||
|
.supplier-item { |
||||
|
padding: 28rpx 0; |
||||
|
border-bottom: 1rpx solid #f1f5f9; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.supplier-item:last-child { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
|
||||
|
.supplier-info { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: flex-start; |
||||
|
} |
||||
|
|
||||
|
.supplier-name { |
||||
|
font-size: 28rpx; |
||||
|
font-weight: 500; |
||||
|
color: #1e293b; |
||||
|
} |
||||
|
|
||||
|
.supplier-company { |
||||
|
font-size: 22rpx; |
||||
|
color: #64748b; |
||||
|
background: #f8fafc; |
||||
|
padding: 4rpx 12rpx; |
||||
|
border-radius: 12rpx; |
||||
|
max-width: 200rpx; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.price-display { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.price-tag { |
||||
|
padding: 8rpx 20rpx; |
||||
|
border-radius: 20rpx; |
||||
|
font-weight: 600; |
||||
|
display: flex; |
||||
|
align-items: baseline; |
||||
|
min-width: 150rpx; |
||||
|
} |
||||
|
|
||||
|
.price-tag.up { |
||||
|
background: #fef2f2; |
||||
|
color: #ef4444; |
||||
|
} |
||||
|
|
||||
|
.price-tag.down { |
||||
|
background: #f0fdf4; |
||||
|
color: #10b981; |
||||
|
} |
||||
|
|
||||
|
.price-tag.stable { |
||||
|
background: #f8fafc; |
||||
|
color: #6b7280; |
||||
|
} |
||||
|
|
||||
|
.price-label { |
||||
|
font-size: 32rpx; |
||||
|
} |
||||
|
|
||||
|
.price-per { |
||||
|
font-size: 22rpx; |
||||
|
margin-left: 4rpx; |
||||
|
} |
||||
|
|
||||
|
.trend-chart-small { |
||||
|
width: 80rpx; |
||||
|
height: 40rpx; |
||||
|
display: flex; |
||||
|
align-items: flex-end; |
||||
|
gap: 4rpx; |
||||
|
} |
||||
|
|
||||
|
.chart-bar { |
||||
|
flex: 1; |
||||
|
border-radius: 4rpx 4rpx 0 0; |
||||
|
min-height: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.chart-bar.up { |
||||
|
background: #ef4444; |
||||
|
} |
||||
|
|
||||
|
.chart-bar.down { |
||||
|
background: #10b981; |
||||
|
} |
||||
|
|
||||
|
.chart-bar.stable { |
||||
|
background: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
.supplier-time { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8rpx; |
||||
|
font-size: 22rpx; |
||||
|
color: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* 市场趋势通知公告样式*/ |
||||
|
.notice-scroll-wrapper { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
padding: 0 32rpx; |
||||
|
} |
||||
|
|
||||
|
.notice-scroll-content { |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
/* 无缝滚动列表样式 */ |
||||
|
.notice-list { |
||||
|
padding: 20rpx 0; |
||||
|
} |
||||
|
|
||||
|
.notice-item { |
||||
|
display: flex; |
||||
|
padding: 28rpx 0; |
||||
|
border-bottom: 1rpx solid #f1f5f9; |
||||
|
gap: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.notice-item:last-child { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
|
||||
|
.notice-left { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
gap: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.notice-type { |
||||
|
padding: 4rpx 12rpx; |
||||
|
border-radius: 12rpx; |
||||
|
font-size: 20rpx; |
||||
|
font-weight: 500; |
||||
|
min-width: 60rpx; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.notice-type.report { |
||||
|
background: rgba(59, 130, 246, 0.1); |
||||
|
color: #3b82f6; |
||||
|
} |
||||
|
|
||||
|
.notice-type.prediction { |
||||
|
background: rgba(139, 92, 246, 0.1); |
||||
|
color: #8b5cf6; |
||||
|
} |
||||
|
|
||||
|
.notice-marker { |
||||
|
width: 8rpx; |
||||
|
height: 8rpx; |
||||
|
border-radius: 50%; |
||||
|
background: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
.notice-marker.new { |
||||
|
background: #3b82f6; |
||||
|
animation: blink 2s infinite; |
||||
|
} |
||||
|
|
||||
|
@keyframes blink { |
||||
|
0%, 100% { |
||||
|
opacity: 1; |
||||
|
} |
||||
|
50% { |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.notice-content { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.notice-title-area { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 12rpx; |
||||
|
flex-wrap: wrap; |
||||
|
} |
||||
|
|
||||
|
.notice-title { |
||||
|
font-size: 28rpx; |
||||
|
font-weight: 500; |
||||
|
color: #1e293b; |
||||
|
flex: 1; |
||||
|
min-width: 200rpx; |
||||
|
} |
||||
|
|
||||
|
.notice-tag { |
||||
|
padding: 4rpx 10rpx; |
||||
|
border-radius: 8rpx; |
||||
|
font-size: 20rpx; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.notice-tag.hot { |
||||
|
background: #fef2f2; |
||||
|
color: #ef4444; |
||||
|
} |
||||
|
|
||||
|
.notice-tag.new { |
||||
|
background: #eff6ff; |
||||
|
color: #3b82f6; |
||||
|
} |
||||
|
|
||||
|
.notice-summary { |
||||
|
font-size: 24rpx; |
||||
|
color: #64748b; |
||||
|
line-height: 1.4; |
||||
|
} |
||||
|
|
||||
|
.notice-footer { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 20rpx; |
||||
|
font-size: 22rpx; |
||||
|
color: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
/* 卡片底部优化 */ |
||||
|
.card-footer { |
||||
|
padding: 24rpx 32rpx; |
||||
|
background: #f8fafc; |
||||
|
border-top: 1rpx solid #f1f5f9; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.update-info { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.iconfont.icon-clock { |
||||
|
font-size: 20rpx; |
||||
|
color: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
.update-text { |
||||
|
font-size: 22rpx; |
||||
|
color: #64748b; |
||||
|
} |
||||
|
|
||||
|
.scroll-tip { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8rpx; |
||||
|
font-size: 22rpx; |
||||
|
color: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
.scroll-tip .iconfont { |
||||
|
font-size: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.statistics-info { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.stat-text { |
||||
|
font-size: 22rpx; |
||||
|
color: #64748b; |
||||
|
} |
||||
|
|
||||
|
.auto-scroll-tip { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8rpx; |
||||
|
font-size: 22rpx; |
||||
|
color: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
.auto-scroll-tip .iconfont { |
||||
|
font-size: 20rpx; |
||||
|
animation: rotate 2s linear infinite; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* 更新页脚优化 */ |
||||
|
.update-footer { |
||||
|
padding: 32rpx 0 100rpx; |
||||
|
text-align: center; |
||||
|
opacity: 0; |
||||
|
transform: translateY(20rpx); |
||||
|
animation: slideIn 0.6s ease 0.3s forwards; |
||||
|
} |
||||
|
|
||||
|
.update-line { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
gap: 8rpx; |
||||
|
margin-bottom: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.iconfont.icon-sync { |
||||
|
font-size: 20rpx; |
||||
|
color: #94a3b8; |
||||
|
} |
||||
|
|
||||
|
.update-tip { |
||||
|
font-size: 22rpx; |
||||
|
color: #64748b; |
||||
|
} |
||||
|
|
||||
|
/* 卡片特定样式 */ |
||||
|
.card-sales { |
||||
|
border-top: 4rpx solid #ff6b6b; |
||||
|
} |
||||
|
|
||||
|
.card-feed { |
||||
|
border-top: 4rpx solid #4d96ff; |
||||
|
} |
||||
|
|
||||
|
.card-trend { |
||||
|
border-top: 4rpx solid #ffd166; |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue