初始
This commit is contained in:
126
pages/category/category.js
Normal file
126
pages/category/category.js
Normal file
@@ -0,0 +1,126 @@
|
||||
// pages/category/category.js
|
||||
const { get } = require('../../utils/request');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
activeTab: 0,
|
||||
categoryList: [],
|
||||
infoList: [],
|
||||
loading: false,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
hasMore: true
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
this.initData();
|
||||
|
||||
// 如果从首页跳转过来带有分类ID
|
||||
if (options.id) {
|
||||
const tabIndex = parseInt(options.id) - 1;
|
||||
this.setData({ activeTab: tabIndex });
|
||||
}
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 初始化 TabBar 选中状态
|
||||
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
||||
this.getTabBar().init();
|
||||
}
|
||||
},
|
||||
|
||||
onPullDownRefresh() {
|
||||
this.refreshList().then(() => {
|
||||
wx.stopPullDownRefresh();
|
||||
});
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
if (this.data.hasMore && !this.data.loading) {
|
||||
this.loadMore();
|
||||
}
|
||||
},
|
||||
|
||||
// 初始化数据
|
||||
async initData() {
|
||||
// 模拟分类数据
|
||||
this.setData({
|
||||
categoryList: [
|
||||
{ id: 1, name: '科技' },
|
||||
{ id: 2, name: '财经' },
|
||||
{ id: 3, name: '教育' },
|
||||
{ id: 4, name: '健康' },
|
||||
{ id: 5, name: '生活' },
|
||||
{ id: 6, name: '娱乐' }
|
||||
]
|
||||
});
|
||||
|
||||
this.refreshList();
|
||||
},
|
||||
|
||||
// 刷新列表
|
||||
async refreshList() {
|
||||
this.setData({ page: 1, hasMore: true, infoList: [] });
|
||||
await this.loadList();
|
||||
},
|
||||
|
||||
// 加载列表
|
||||
async loadList() {
|
||||
this.setData({ loading: true });
|
||||
|
||||
// 模拟数据
|
||||
setTimeout(() => {
|
||||
const mockList = [
|
||||
{
|
||||
id: 1,
|
||||
title: '分类信息标题示例',
|
||||
summary: '这是分类信息的摘要内容...',
|
||||
image: '/assets/images/info1.png',
|
||||
time: '2小时前',
|
||||
views: 1234
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '第二条分类信息',
|
||||
summary: '这是第二条信息的摘要...',
|
||||
image: '/assets/images/info2.png',
|
||||
time: '3小时前',
|
||||
views: 856
|
||||
}
|
||||
];
|
||||
|
||||
this.setData({
|
||||
infoList: [...this.data.infoList, ...mockList],
|
||||
loading: false
|
||||
});
|
||||
}, 500);
|
||||
},
|
||||
|
||||
// 加载更多
|
||||
async loadMore() {
|
||||
if (this.data.loading) return;
|
||||
|
||||
const newPage = this.data.page + 1;
|
||||
if (newPage > 3) {
|
||||
this.setData({ hasMore: false });
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({ page: newPage });
|
||||
await this.loadList();
|
||||
},
|
||||
|
||||
// 切换分类
|
||||
onTabChange(e) {
|
||||
this.setData({ activeTab: e.detail.index });
|
||||
this.refreshList();
|
||||
},
|
||||
|
||||
// 点击信息
|
||||
onInfoTap(e) {
|
||||
const { id } = e.currentTarget.dataset;
|
||||
wx.navigateTo({
|
||||
url: `/pages/detail/detail?id=${id}`
|
||||
});
|
||||
}
|
||||
});
|
||||
5
pages/category/category.json
Normal file
5
pages/category/category.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"navigationBarTitleText": "分类",
|
||||
"enablePullDownRefresh": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
61
pages/category/category.wxml
Normal file
61
pages/category/category.wxml
Normal file
@@ -0,0 +1,61 @@
|
||||
<!--pages/category/category.wxml-->
|
||||
<view class="container">
|
||||
<!-- 分类标签 -->
|
||||
<van-tabs
|
||||
active="{{ activeTab }}"
|
||||
bind:change="onTabChange"
|
||||
sticky
|
||||
swipeable
|
||||
>
|
||||
<van-tab
|
||||
wx:for="{{ categoryList }}"
|
||||
wx:key="id"
|
||||
title="{{ item.name }}"
|
||||
>
|
||||
<!-- 信息列表 -->
|
||||
<view class="info-list">
|
||||
<view
|
||||
class="info-item card"
|
||||
wx:for="{{ infoList }}"
|
||||
wx:for-item="info"
|
||||
wx:key="id"
|
||||
data-id="{{ info.id }}"
|
||||
bindtap="onInfoTap"
|
||||
>
|
||||
<view class="info-content">
|
||||
<view class="info-text">
|
||||
<text class="info-title ellipsis-2">{{ info.title }}</text>
|
||||
<text class="info-summary ellipsis">{{ info.summary }}</text>
|
||||
<view class="info-meta">
|
||||
<text class="info-time">{{ info.time }}</text>
|
||||
<text class="info-views">{{ info.views }}阅读</text>
|
||||
</view>
|
||||
</view>
|
||||
<van-image
|
||||
wx:if="{{ info.image }}"
|
||||
class="info-image"
|
||||
width="180rpx"
|
||||
height="120rpx"
|
||||
fit="cover"
|
||||
radius="8rpx"
|
||||
src="{{ info.image }}"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-section" wx:if="{{ loading }}">
|
||||
<van-loading size="24px">加载中...</van-loading>
|
||||
</view>
|
||||
|
||||
<!-- 没有更多 -->
|
||||
<view class="no-more" wx:if="{{ !hasMore && infoList.length > 0 }}">
|
||||
<text>— 没有更多了 —</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<van-empty wx:if="{{ !loading && infoList.length === 0 }}" description="暂无信息" />
|
||||
</van-tab>
|
||||
</van-tabs>
|
||||
</view>
|
||||
71
pages/category/category.wxss
Normal file
71
pages/category/category.wxss
Normal file
@@ -0,0 +1,71 @@
|
||||
/* pages/category/category.wxss */
|
||||
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.info-list {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
flex: 1;
|
||||
margin-right: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.info-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.info-summary {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.info-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.info-time {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.info-views {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.loading-section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.no-more {
|
||||
text-align: center;
|
||||
padding: 40rpx;
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
92
pages/detail/detail.js
Normal file
92
pages/detail/detail.js
Normal file
@@ -0,0 +1,92 @@
|
||||
// pages/detail/detail.js
|
||||
const { get } = require('../../utils/request');
|
||||
const { formatTime } = require('../../utils/util');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
id: '',
|
||||
detail: null,
|
||||
loading: true,
|
||||
isFavorite: false,
|
||||
relatedList: []
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
if (options.id) {
|
||||
this.setData({ id: options.id });
|
||||
this.loadDetail(options.id);
|
||||
}
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: this.data.detail?.title || '信息详情',
|
||||
path: `/pages/detail/detail?id=${this.data.id}`
|
||||
};
|
||||
},
|
||||
|
||||
// 加载详情
|
||||
async loadDetail(id) {
|
||||
this.setData({ loading: true });
|
||||
|
||||
// 模拟数据
|
||||
setTimeout(() => {
|
||||
this.setData({
|
||||
loading: false,
|
||||
detail: {
|
||||
id: id,
|
||||
title: '这是一个详情页面的标题,展示信息服务的详细内容',
|
||||
content: `
|
||||
<p>这是信息详情的正文内容。</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||
<p>更多详细的信息内容会在这里展示,包括图片、文字等富文本内容。</p>
|
||||
<p>用户可以通过滑动查看完整的内容。</p>
|
||||
`,
|
||||
author: '信息服务平台',
|
||||
publishTime: new Date().getTime() - 3600000,
|
||||
views: 1234,
|
||||
category: '科技',
|
||||
image: '/assets/images/detail.png'
|
||||
},
|
||||
relatedList: [
|
||||
{ id: 2, title: '相关信息标题1', views: 856 },
|
||||
{ id: 3, title: '相关信息标题2', views: 723 }
|
||||
]
|
||||
});
|
||||
|
||||
// 设置导航栏标题
|
||||
wx.setNavigationBarTitle({
|
||||
title: this.data.detail.title.substring(0, 10) + '...'
|
||||
});
|
||||
}, 500);
|
||||
},
|
||||
|
||||
// 收藏/取消收藏
|
||||
onFavorite() {
|
||||
const isFavorite = !this.data.isFavorite;
|
||||
this.setData({ isFavorite });
|
||||
|
||||
wx.showToast({
|
||||
title: isFavorite ? '收藏成功' : '已取消收藏',
|
||||
icon: 'success'
|
||||
});
|
||||
},
|
||||
|
||||
// 分享
|
||||
onShare() {
|
||||
// 触发分享
|
||||
},
|
||||
|
||||
// 点击相关信息
|
||||
onRelatedTap(e) {
|
||||
const { id } = e.currentTarget.dataset;
|
||||
wx.navigateTo({
|
||||
url: `/pages/detail/detail?id=${id}`
|
||||
});
|
||||
},
|
||||
|
||||
// 返回
|
||||
onBack() {
|
||||
wx.navigateBack();
|
||||
}
|
||||
});
|
||||
4
pages/detail/detail.json
Normal file
4
pages/detail/detail.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"navigationBarTitleText": "详情",
|
||||
"usingComponents": {}
|
||||
}
|
||||
78
pages/detail/detail.wxml
Normal file
78
pages/detail/detail.wxml
Normal file
@@ -0,0 +1,78 @@
|
||||
<!--pages/detail/detail.wxml-->
|
||||
<view class="container">
|
||||
<!-- 加载中 -->
|
||||
<view class="loading-container" wx:if="{{ loading }}">
|
||||
<van-loading size="36px" vertical>加载中...</van-loading>
|
||||
</view>
|
||||
|
||||
<!-- 详情内容 -->
|
||||
<block wx:if="{{ !loading && detail }}">
|
||||
<!-- 头部信息 -->
|
||||
<view class="detail-header">
|
||||
<text class="detail-title">{{ detail.title }}</text>
|
||||
<view class="detail-meta">
|
||||
<text class="meta-author">{{ detail.author }}</text>
|
||||
<text class="meta-time">{{ detail.publishTimeText }}</text>
|
||||
<text class="meta-views">{{ detail.views }}阅读</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 封面图 -->
|
||||
<view class="detail-cover" wx:if="{{ detail.image }}">
|
||||
<van-image
|
||||
width="100%"
|
||||
height="400rpx"
|
||||
fit="cover"
|
||||
src="{{ detail.image }}"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 正文内容 -->
|
||||
<view class="detail-content">
|
||||
<rich-text nodes="{{ detail.content }}"></rich-text>
|
||||
</view>
|
||||
|
||||
<!-- 标签 -->
|
||||
<view class="detail-tags">
|
||||
<van-tag plain type="primary">{{ detail.category }}</van-tag>
|
||||
</view>
|
||||
|
||||
<!-- 分割线 -->
|
||||
<view class="divider"></view>
|
||||
|
||||
<!-- 相关推荐 -->
|
||||
<view class="related-section" wx:if="{{ relatedList.length > 0 }}">
|
||||
<view class="section-title">相关推荐</view>
|
||||
<view class="related-list">
|
||||
<view
|
||||
class="related-item"
|
||||
wx:for="{{ relatedList }}"
|
||||
wx:key="id"
|
||||
data-id="{{ item.id }}"
|
||||
bindtap="onRelatedTap"
|
||||
>
|
||||
<text class="related-title ellipsis">{{ item.title }}</text>
|
||||
<text class="related-views">{{ item.views }}阅读</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="action-bar safe-area-bottom" wx:if="{{ !loading }}">
|
||||
<view class="action-item" bindtap="onFavorite">
|
||||
<van-icon
|
||||
name="{{ isFavorite ? 'star' : 'star-o' }}"
|
||||
size="48rpx"
|
||||
color="{{ isFavorite ? '#ffc107' : '#666' }}"
|
||||
/>
|
||||
<text>{{ isFavorite ? '已收藏' : '收藏' }}</text>
|
||||
</view>
|
||||
<view class="action-item">
|
||||
<button class="share-btn" open-type="share">
|
||||
<van-icon name="share-o" size="48rpx" color="#666" />
|
||||
<text>分享</text>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
150
pages/detail/detail.wxss
Normal file
150
pages/detail/detail.wxss
Normal file
@@ -0,0 +1,150 @@
|
||||
/* pages/detail/detail.wxss */
|
||||
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: #fff;
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
/* 加载中 */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 60vh;
|
||||
}
|
||||
|
||||
/* 头部 */
|
||||
.detail-header {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
display: block;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.detail-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.meta-author {
|
||||
margin-right: 20rpx;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.meta-time {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
/* 封面图 */
|
||||
.detail-cover {
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
/* 正文 */
|
||||
.detail-content {
|
||||
padding: 0 30rpx;
|
||||
font-size: 32rpx;
|
||||
line-height: 1.8;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.detail-content rich-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 标签 */
|
||||
.detail-tags {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
/* 相关推荐 */
|
||||
.related-section {
|
||||
padding: 0 30rpx 30rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.related-list {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.related-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #e8e8e8;
|
||||
}
|
||||
|
||||
.related-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.related-title {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.related-views {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
.action-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100rpx;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
border-top: 1rpx solid #e8e8e8;
|
||||
box-shadow: 0 -4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.share-btn {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.share-btn::after {
|
||||
border: none;
|
||||
}
|
||||
138
pages/index/index.js
Normal file
138
pages/index/index.js
Normal file
@@ -0,0 +1,138 @@
|
||||
// pages/index/index.js
|
||||
const { get } = require('../../utils/request');
|
||||
const { formatRelativeTime } = require('../../utils/util');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
searchValue: '',
|
||||
bannerList: [],
|
||||
categoryList: [],
|
||||
infoList: [],
|
||||
loading: false,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
hasMore: true
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.initData();
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 初始化 TabBar 选中状态
|
||||
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
||||
this.getTabBar().init();
|
||||
}
|
||||
},
|
||||
|
||||
onPullDownRefresh() {
|
||||
this.initData().then(() => {
|
||||
wx.stopPullDownRefresh();
|
||||
});
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
if (this.data.hasMore && !this.data.loading) {
|
||||
this.loadMoreInfo();
|
||||
}
|
||||
},
|
||||
|
||||
// 初始化数据
|
||||
async initData() {
|
||||
this.setData({ page: 1, hasMore: true });
|
||||
|
||||
// 模拟数据 - 实际项目中替换为API调用
|
||||
this.setData({
|
||||
bannerList: [
|
||||
{ id: 1, image: '/assets/images/banner1.png', title: '热门资讯' },
|
||||
{ id: 2, image: '/assets/images/banner2.png', title: '最新动态' }
|
||||
],
|
||||
categoryList: [
|
||||
{ id: 1, name: '科技', icon: 'technology' },
|
||||
{ id: 2, name: '财经', icon: 'finance' },
|
||||
{ id: 3, name: '教育', icon: 'education' },
|
||||
{ id: 4, name: '健康', icon: 'health' },
|
||||
{ id: 5, name: '生活', icon: 'life' },
|
||||
{ id: 6, name: '娱乐', icon: 'entertainment' },
|
||||
{ id: 7, name: '体育', icon: 'sports' },
|
||||
{ id: 8, name: '更多', icon: 'more' }
|
||||
],
|
||||
infoList: [
|
||||
{
|
||||
id: 1,
|
||||
title: '这是一条测试信息标题,展示信息服务的基本样式',
|
||||
summary: '这是信息摘要内容,用于展示信息的简要描述...',
|
||||
image: '/assets/images/info1.png',
|
||||
category: '科技',
|
||||
time: new Date().getTime() - 3600000,
|
||||
views: 1234
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '第二条信息标题,这里是标题内容展示',
|
||||
summary: '这是第二条信息的摘要内容...',
|
||||
image: '/assets/images/info2.png',
|
||||
category: '财经',
|
||||
time: new Date().getTime() - 7200000,
|
||||
views: 856
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
|
||||
// 加载更多信息
|
||||
async loadMoreInfo() {
|
||||
if (this.data.loading) return;
|
||||
|
||||
this.setData({ loading: true });
|
||||
|
||||
// 模拟加载更多
|
||||
setTimeout(() => {
|
||||
const newPage = this.data.page + 1;
|
||||
// 模拟无更多数据
|
||||
if (newPage > 3) {
|
||||
this.setData({ hasMore: false, loading: false });
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({
|
||||
page: newPage,
|
||||
loading: false
|
||||
});
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
// 搜索
|
||||
onSearch(e) {
|
||||
const value = e.detail;
|
||||
wx.navigateTo({
|
||||
url: `/pages/search/search?keyword=${value}`
|
||||
});
|
||||
},
|
||||
|
||||
// 搜索值变化
|
||||
onSearchChange(e) {
|
||||
this.setData({ searchValue: e.detail });
|
||||
},
|
||||
|
||||
// 点击分类
|
||||
onCategoryTap(e) {
|
||||
const { id, name } = e.currentTarget.dataset;
|
||||
wx.navigateTo({
|
||||
url: `/pages/category/category?id=${id}&name=${name}`
|
||||
});
|
||||
},
|
||||
|
||||
// 点击信息
|
||||
onInfoTap(e) {
|
||||
const { id } = e.currentTarget.dataset;
|
||||
wx.navigateTo({
|
||||
url: `/pages/detail/detail?id=${id}`
|
||||
});
|
||||
},
|
||||
|
||||
// 格式化时间
|
||||
formatTime(time) {
|
||||
return formatRelativeTime(time);
|
||||
}
|
||||
});
|
||||
5
pages/index/index.json
Normal file
5
pages/index/index.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"navigationBarTitleText": "首页",
|
||||
"enablePullDownRefresh": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
98
pages/index/index.wxml
Normal file
98
pages/index/index.wxml
Normal file
@@ -0,0 +1,98 @@
|
||||
<!--pages/index/index.wxml-->
|
||||
<view class="container">
|
||||
<!-- 搜索栏 -->
|
||||
<view class="search-bar">
|
||||
<van-search
|
||||
value="{{ searchValue }}"
|
||||
placeholder="搜索信息"
|
||||
shape="round"
|
||||
bind:search="onSearch"
|
||||
bind:change="onSearchChange"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 轮播图 -->
|
||||
<view class="banner-section" wx:if="{{ bannerList.length > 0 }}">
|
||||
<swiper
|
||||
class="banner-swiper"
|
||||
indicator-dots
|
||||
autoplay
|
||||
circular
|
||||
interval="3000"
|
||||
>
|
||||
<swiper-item wx:for="{{ bannerList }}" wx:key="id">
|
||||
<image class="banner-image" src="{{ item.image }}" mode="aspectFill" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
|
||||
<!-- 分类入口 -->
|
||||
<view class="category-section card">
|
||||
<view class="category-grid">
|
||||
<view
|
||||
class="category-item"
|
||||
wx:for="{{ categoryList }}"
|
||||
wx:key="id"
|
||||
data-id="{{ item.id }}"
|
||||
data-name="{{ item.name }}"
|
||||
bindtap="onCategoryTap"
|
||||
>
|
||||
<view class="category-icon">
|
||||
<van-icon name="apps-o" size="48rpx" color="#1890ff" />
|
||||
</view>
|
||||
<text class="category-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 信息列表 -->
|
||||
<view class="info-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">最新资讯</text>
|
||||
</view>
|
||||
|
||||
<view class="info-list">
|
||||
<view
|
||||
class="info-item card"
|
||||
wx:for="{{ infoList }}"
|
||||
wx:key="id"
|
||||
data-id="{{ item.id }}"
|
||||
bindtap="onInfoTap"
|
||||
>
|
||||
<view class="info-content">
|
||||
<view class="info-text">
|
||||
<text class="info-title ellipsis-2">{{ item.title }}</text>
|
||||
<text class="info-summary ellipsis-2">{{ item.summary }}</text>
|
||||
<view class="info-meta">
|
||||
<van-tag plain type="primary" size="medium">{{ item.category }}</van-tag>
|
||||
<text class="info-time">{{ item.timeText }}</text>
|
||||
<text class="info-views">{{ item.views }}阅读</text>
|
||||
</view>
|
||||
</view>
|
||||
<van-image
|
||||
wx:if="{{ item.image }}"
|
||||
class="info-image"
|
||||
width="180rpx"
|
||||
height="120rpx"
|
||||
fit="cover"
|
||||
radius="8rpx"
|
||||
src="{{ item.image }}"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-section" wx:if="{{ loading }}">
|
||||
<van-loading size="24px">加载中...</van-loading>
|
||||
</view>
|
||||
|
||||
<!-- 没有更多 -->
|
||||
<view class="no-more" wx:if="{{ !hasMore && infoList.length > 0 }}">
|
||||
<text>— 没有更多了 —</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<van-empty wx:if="{{ !loading && infoList.length === 0 }}" description="暂无信息" />
|
||||
</view>
|
||||
</view>
|
||||
145
pages/index/index.wxss
Normal file
145
pages/index/index.wxss
Normal file
@@ -0,0 +1,145 @@
|
||||
/* pages/index/index.wxss */
|
||||
|
||||
.container {
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
/* 搜索栏 */
|
||||
.search-bar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 轮播图 */
|
||||
.banner-section {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.banner-swiper {
|
||||
height: 300rpx;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 分类 */
|
||||
.category-section {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.category-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
width: 25%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.category-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #e6f7ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.category-name {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 信息列表 */
|
||||
.info-section {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
padding: 20rpx 30rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
margin-top: 0;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
flex: 1;
|
||||
margin-right: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.info-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.info-summary {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.info-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.info-time {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.info-views {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.no-more {
|
||||
text-align: center;
|
||||
padding: 40rpx;
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
97
pages/mine/mine.js
Normal file
97
pages/mine/mine.js
Normal file
@@ -0,0 +1,97 @@
|
||||
// pages/mine/mine.js
|
||||
const app = getApp();
|
||||
|
||||
Page({
|
||||
data: {
|
||||
userInfo: null,
|
||||
isLogin: false,
|
||||
menuList: [
|
||||
{ id: 'favorite', icon: 'star-o', title: '我的收藏', url: '/pages/favorite/favorite' },
|
||||
{ id: 'history', icon: 'underway-o', title: '浏览历史', url: '/pages/history/history' },
|
||||
{ id: 'feedback', icon: 'comment-o', title: '意见反馈', url: '/pages/feedback/feedback' },
|
||||
{ id: 'about', icon: 'info-o', title: '关于我们', url: '/pages/about/about' },
|
||||
{ id: 'setting', icon: 'setting-o', title: '设置', url: '/pages/setting/setting' }
|
||||
]
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.checkLoginStatus();
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.checkLoginStatus();
|
||||
// 初始化 TabBar 选中状态
|
||||
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
||||
this.getTabBar().init();
|
||||
}
|
||||
},
|
||||
|
||||
// 检查登录状态
|
||||
checkLoginStatus() {
|
||||
const isLogin = app.checkLogin();
|
||||
const userInfo = app.globalData.userInfo;
|
||||
this.setData({ isLogin, userInfo });
|
||||
},
|
||||
|
||||
// 获取用户信息(微信登录)
|
||||
onGetUserInfo() {
|
||||
wx.getUserProfile({
|
||||
desc: '用于完善用户资料',
|
||||
success: (res) => {
|
||||
const userInfo = res.userInfo;
|
||||
app.globalData.userInfo = userInfo;
|
||||
this.setData({ userInfo, isLogin: true });
|
||||
|
||||
// 模拟设置token
|
||||
app.setToken('mock_token_' + Date.now());
|
||||
|
||||
wx.showToast({
|
||||
title: '登录成功',
|
||||
icon: 'success'
|
||||
});
|
||||
},
|
||||
fail: () => {
|
||||
wx.showToast({
|
||||
title: '已取消授权',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 点击菜单项
|
||||
onMenuTap(e) {
|
||||
const { url, id } = e.currentTarget.dataset;
|
||||
|
||||
// 某些功能需要登录
|
||||
if (['favorite', 'history'].includes(id) && !this.data.isLogin) {
|
||||
wx.showToast({
|
||||
title: '请先登录',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
wx.navigateTo({ url });
|
||||
},
|
||||
|
||||
// 退出登录
|
||||
onLogout() {
|
||||
wx.showModal({
|
||||
title: '提示',
|
||||
content: '确定要退出登录吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
app.clearToken();
|
||||
app.globalData.userInfo = null;
|
||||
this.setData({ isLogin: false, userInfo: null });
|
||||
|
||||
wx.showToast({
|
||||
title: '已退出登录',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
4
pages/mine/mine.json
Normal file
4
pages/mine/mine.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"navigationBarTitleText": "我的",
|
||||
"usingComponents": {}
|
||||
}
|
||||
74
pages/mine/mine.wxml
Normal file
74
pages/mine/mine.wxml
Normal file
@@ -0,0 +1,74 @@
|
||||
<!--pages/mine/mine.wxml-->
|
||||
<view class="container">
|
||||
<!-- 用户信息区域 -->
|
||||
<view class="user-section">
|
||||
<view class="user-info" wx:if="{{ isLogin && userInfo }}">
|
||||
<van-image
|
||||
class="user-avatar"
|
||||
round
|
||||
width="120rpx"
|
||||
height="120rpx"
|
||||
src="{{ userInfo.avatarUrl }}"
|
||||
/>
|
||||
<view class="user-detail">
|
||||
<text class="user-name">{{ userInfo.nickName }}</text>
|
||||
<text class="user-desc">欢迎使用信息服务</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="login-section" wx:else>
|
||||
<van-image
|
||||
class="default-avatar"
|
||||
round
|
||||
width="120rpx"
|
||||
height="120rpx"
|
||||
src="/assets/images/default-avatar.png"
|
||||
/>
|
||||
<view class="login-info">
|
||||
<text class="login-hint">登录后享受更多服务</text>
|
||||
<van-button
|
||||
type="primary"
|
||||
size="small"
|
||||
round
|
||||
bindtap="onGetUserInfo"
|
||||
>
|
||||
立即登录
|
||||
</van-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 功能菜单 -->
|
||||
<view class="menu-section">
|
||||
<van-cell-group>
|
||||
<van-cell
|
||||
wx:for="{{ menuList }}"
|
||||
wx:key="id"
|
||||
title="{{ item.title }}"
|
||||
is-link
|
||||
data-id="{{ item.id }}"
|
||||
data-url="{{ item.url }}"
|
||||
bindtap="onMenuTap"
|
||||
>
|
||||
<van-icon slot="icon" name="{{ item.icon }}" size="40rpx" color="#1890ff" style="margin-right: 20rpx;" />
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</view>
|
||||
|
||||
<!-- 退出登录 -->
|
||||
<view class="logout-section" wx:if="{{ isLogin }}">
|
||||
<van-button
|
||||
type="default"
|
||||
block
|
||||
round
|
||||
bindtap="onLogout"
|
||||
>
|
||||
退出登录
|
||||
</van-button>
|
||||
</view>
|
||||
|
||||
<!-- 版本信息 -->
|
||||
<view class="version-info">
|
||||
<text>版本 1.0.0</text>
|
||||
</view>
|
||||
</view>
|
||||
83
pages/mine/mine.wxss
Normal file
83
pages/mine/mine.wxss
Normal file
@@ -0,0 +1,83 @@
|
||||
/* pages/mine/mine.wxss */
|
||||
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 用户信息区域 */
|
||||
.user-section {
|
||||
background: linear-gradient(135deg, #1890ff 0%, #36cfc9 100%);
|
||||
padding: 60rpx 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.user-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.user-desc {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
/* 未登录状态 */
|
||||
.login-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.default-avatar {
|
||||
margin-right: 30rpx;
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.login-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.login-hint {
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
/* 菜单区域 */
|
||||
.menu-section {
|
||||
margin: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 退出登录 */
|
||||
.logout-section {
|
||||
margin: 40rpx 30rpx;
|
||||
}
|
||||
|
||||
/* 版本信息 */
|
||||
.version-info {
|
||||
text-align: center;
|
||||
padding: 40rpx;
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
Reference in New Issue
Block a user