refactor(app): 移除分类和详情模块,新增云开发测试页

- 从项目中删除分类页及相关代码和样式文件
- 从项目中删除详情页及相关代码和样式文件
- 首页简化为欢迎界面并添加跳转云开发测试页入口
- 更新自定义底部栏移除分类入口
- 更新app.js初始化云开发环境
- 修改app.json移除分类页面配置
- 调整首页样式和交互,提高简洁度
- 配置云函数目录路径cloudfunctionRoot为cloudfunctions/
This commit is contained in:
2025-12-05 15:58:08 +08:00
parent 854c4f5449
commit 8fc4630bb5
22 changed files with 514 additions and 950 deletions

19
app.js
View File

@@ -1,15 +1,26 @@
// app.js
App({
onLaunch() {
// 初始化云开发环境
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力');
} else {
wx.cloud.init({
// 环境ID请替换为你的云开发环境ID
env: 'your-env-id',
traceUser: true
});
}
this.initApp();
},
globalData: {
userInfo: null,
baseUrl: 'https://api.example.com', // API基础地址
token: ''
},
onLaunch() {
// 小程序启动时执行
this.initApp();
},
// 初始化应用
initApp() {

View File

@@ -1,8 +1,7 @@
{
"pages": [
"pages/index/index",
"pages/category/category",
"pages/detail/detail",
"pages/cloud-test/cloud-test",
"pages/mine/mine"
],
"window": {
@@ -23,10 +22,6 @@
"pagePath": "pages/index/index",
"text": "首页"
},
{
"pagePath": "pages/category/category",
"text": "分类"
},
{
"pagePath": "pages/mine/mine",
"text": "我的"

View File

@@ -0,0 +1,23 @@
// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
});
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext();
return {
code: 0,
message: '云函数调用成功',
data: {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
timestamp: Date.now()
}
};
};

View File

@@ -0,0 +1,9 @@
{
"name": "test",
"version": "1.0.0",
"description": "云函数测试",
"main": "index.js",
"dependencies": {
"wx-server-sdk": "~2.6.3"
}
}

View File

@@ -9,20 +9,12 @@ Component({
{
pagePath: '/pages/index/index',
text: '首页',
icon: 'home-o',
activeIcon: 'wap-home'
},
{
pagePath: '/pages/category/category',
text: '分类',
icon: 'apps-o',
activeIcon: 'apps-o'
icon: 'home-o'
},
{
pagePath: '/pages/mine/mine',
text: '我的',
icon: 'user-o',
activeIcon: 'manager'
icon: 'user-o'
}
]
},

View File

@@ -1,126 +0,0 @@
// 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}`
});
}
});

View File

@@ -1,5 +0,0 @@
{
"navigationBarTitleText": "分类",
"enablePullDownRefresh": true,
"usingComponents": {}
}

View File

@@ -1,61 +0,0 @@
<!--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>

View File

@@ -1,71 +0,0 @@
/* 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;
}

View File

@@ -0,0 +1,179 @@
// pages/cloud-test/cloud-test.js
Page({
data: {
logs: [],
testData: null,
loading: false
},
onLoad() {
this.addLog('页面加载完成,云开发测试就绪');
},
// 添加日志
addLog(message, type = 'info') {
const time = new Date().toLocaleTimeString();
const logs = [...this.data.logs, { time, message, type }];
this.setData({ logs });
},
// 清空日志
onClearLogs() {
this.setData({ logs: [] });
},
// 测试云函数
async onTestFunction() {
this.addLog('开始调用云函数 test...');
this.setData({ loading: true });
try {
const res = await wx.cloud.callFunction({
name: 'test',
data: {
action: 'test',
timestamp: Date.now()
}
});
this.addLog('云函数调用成功', 'success');
this.addLog(`返回结果: ${JSON.stringify(res.result)}`, 'success');
console.log('云函数返回:', res);
} catch (err) {
this.addLog(`云函数调用失败: ${err.message}`, 'error');
console.error('云函数错误:', err);
}
this.setData({ loading: false });
},
// 测试数据库 - 添加数据
async onTestDbAdd() {
this.addLog('开始测试数据库添加...');
this.setData({ loading: true });
try {
const db = wx.cloud.database();
const res = await db.collection('test_collection').add({
data: {
content: '测试数据',
createTime: db.serverDate(),
count: Math.floor(Math.random() * 100)
}
});
this.addLog('数据添加成功', 'success');
this.addLog(`文档ID: ${res._id}`, 'success');
this.setData({ testData: { _id: res._id } });
} catch (err) {
this.addLog(`数据库添加失败: ${err.message}`, 'error');
console.error('数据库错误:', err);
}
this.setData({ loading: false });
},
// 测试数据库 - 查询数据
async onTestDbQuery() {
this.addLog('开始测试数据库查询...');
this.setData({ loading: true });
try {
const db = wx.cloud.database();
const res = await db.collection('test_collection')
.orderBy('createTime', 'desc')
.limit(5)
.get();
this.addLog('数据查询成功', 'success');
this.addLog(`查询到 ${res.data.length} 条数据`, 'success');
res.data.forEach((item, index) => {
this.addLog(`[${index + 1}] ${item.content} - count: ${item.count}`, 'info');
});
} catch (err) {
this.addLog(`数据库查询失败: ${err.message}`, 'error');
console.error('数据库错误:', err);
}
this.setData({ loading: false });
},
// 测试数据库 - 删除数据
async onTestDbDelete() {
if (!this.data.testData?._id) {
this.addLog('请先添加测试数据', 'error');
return;
}
this.addLog('开始测试数据库删除...');
this.setData({ loading: true });
try {
const db = wx.cloud.database();
await db.collection('test_collection').doc(this.data.testData._id).remove();
this.addLog('数据删除成功', 'success');
this.setData({ testData: null });
} catch (err) {
this.addLog(`数据库删除失败: ${err.message}`, 'error');
console.error('数据库错误:', err);
}
this.setData({ loading: false });
},
// 测试云存储 - 上传图片
async onTestStorageUpload() {
this.addLog('开始测试云存储上传...');
try {
// 选择图片
const chooseRes = await wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera']
});
const filePath = chooseRes.tempFiles[0].tempFilePath;
const cloudPath = `test/${Date.now()}-${Math.random().toString(36).substr(2)}.png`;
this.setData({ loading: true });
this.addLog('正在上传图片...');
const uploadRes = await wx.cloud.uploadFile({
cloudPath,
filePath
});
this.addLog('图片上传成功', 'success');
this.addLog(`文件ID: ${uploadRes.fileID}`, 'success');
// 获取临时链接
const urlRes = await wx.cloud.getTempFileURL({
fileList: [uploadRes.fileID]
});
if (urlRes.fileList[0].tempFileURL) {
this.addLog(`临时链接: ${urlRes.fileList[0].tempFileURL.substr(0, 50)}...`, 'success');
}
} catch (err) {
if (err.errMsg?.includes('cancel')) {
this.addLog('用户取消选择', 'info');
} else {
this.addLog(`上传失败: ${err.message || err.errMsg}`, 'error');
}
console.error('存储错误:', err);
}
this.setData({ loading: false });
},
// 返回首页
onBack() {
wx.switchTab({
url: '/pages/index/index'
});
}
});

View File

@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "云开发测试",
"usingComponents": {}
}

View File

@@ -0,0 +1,118 @@
<!--pages/cloud-test/cloud-test.wxml-->
<view class="container">
<!-- 标题 -->
<view class="header">
<text class="title">云开发功能测试</text>
<text class="subtitle">测试云函数、云数据库、云存储</text>
</view>
<!-- 云函数测试 -->
<view class="section">
<view class="section-title">
<van-icon name="code-o" size="36rpx" color="#1890ff" />
<text>云函数测试</text>
</view>
<view class="btn-group">
<van-button
type="primary"
size="small"
loading="{{ loading }}"
bindtap="onTestFunction"
>
调用云函数
</van-button>
</view>
</view>
<!-- 云数据库测试 -->
<view class="section">
<view class="section-title">
<van-icon name="records" size="36rpx" color="#52c41a" />
<text>云数据库测试</text>
</view>
<view class="btn-group">
<van-button
type="primary"
size="small"
loading="{{ loading }}"
bindtap="onTestDbAdd"
>
添加数据
</van-button>
<van-button
type="info"
size="small"
loading="{{ loading }}"
bindtap="onTestDbQuery"
>
查询数据
</van-button>
<van-button
type="warning"
size="small"
loading="{{ loading }}"
bindtap="onTestDbDelete"
>
删除数据
</van-button>
</view>
</view>
<!-- 云存储测试 -->
<view class="section">
<view class="section-title">
<van-icon name="photo-o" size="36rpx" color="#faad14" />
<text>云存储测试</text>
</view>
<view class="btn-group">
<van-button
type="primary"
size="small"
loading="{{ loading }}"
bindtap="onTestStorageUpload"
>
上传图片
</van-button>
</view>
</view>
<!-- 日志区域 -->
<view class="log-section">
<view class="log-header">
<text class="log-title">执行日志</text>
<van-button
plain
type="default"
size="mini"
bindtap="onClearLogs"
>
清空
</van-button>
</view>
<scroll-view class="log-list" scroll-y>
<view
class="log-item log-{{ item.type }}"
wx:for="{{ logs }}"
wx:key="index"
>
<text class="log-time">[{{ item.time }}]</text>
<text class="log-message">{{ item.message }}</text>
</view>
<view class="log-empty" wx:if="{{ logs.length === 0 }}">
<text>暂无日志</text>
</view>
</scroll-view>
</view>
<!-- 返回按钮 -->
<view class="footer">
<van-button
plain
type="default"
block
bindtap="onBack"
>
返回首页
</van-button>
</view>
</view>

View File

@@ -0,0 +1,127 @@
/* pages/cloud-test/cloud-test.wxss */
.container {
min-height: 100vh;
background-color: #f5f5f5;
padding: 30rpx;
box-sizing: border-box;
}
/* 标题 */
.header {
text-align: center;
padding: 30rpx 0;
margin-bottom: 20rpx;
}
.title {
display: block;
font-size: 40rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.subtitle {
display: block;
font-size: 26rpx;
color: #999;
}
/* 功能区块 */
.section {
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
}
.section-title {
display: flex;
align-items: center;
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-bottom: 24rpx;
}
.section-title text {
margin-left: 12rpx;
}
.btn-group {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
}
/* 日志区域 */
.log-section {
background-color: #fff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 20rpx;
}
.log-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.log-title {
font-size: 28rpx;
font-weight: bold;
color: #333;
}
.log-list {
height: 400rpx;
background-color: #1e1e1e;
border-radius: 12rpx;
padding: 16rpx;
}
.log-item {
padding: 8rpx 0;
font-size: 22rpx;
font-family: 'Consolas', 'Monaco', monospace;
word-break: break-all;
}
.log-time {
color: #666;
margin-right: 12rpx;
}
.log-message {
color: #d4d4d4;
}
.log-info .log-message {
color: #d4d4d4;
}
.log-success .log-message {
color: #52c41a;
}
.log-error .log-message {
color: #ff4d4f;
}
.log-empty {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
color: #666;
font-size: 24rpx;
}
/* 底部 */
.footer {
margin-top: 30rpx;
padding-bottom: env(safe-area-inset-bottom);
}

View File

@@ -1,92 +0,0 @@
// 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();
}
});

View File

@@ -1,4 +0,0 @@
{
"navigationBarTitleText": "详情",
"usingComponents": {}
}

View File

@@ -1,78 +0,0 @@
<!--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>

View File

@@ -1,150 +0,0 @@
/* 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;
}

View File

@@ -1,22 +1,9 @@
// 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
},
data: {},
onLoad() {
this.initData();
},
onLoad() {},
onShow() {
// 初始化 TabBar 选中状态
@@ -25,114 +12,10 @@ Page({
}
},
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;
// 跳转到云开发测试页
goCloudTest() {
wx.navigateTo({
url: `/pages/search/search?keyword=${value}`
url: '/pages/cloud-test/cloud-test'
});
},
// 搜索值变化
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);
}
});

View File

@@ -1,5 +1,4 @@
{
"navigationBarTitleText": "首页",
"enablePullDownRefresh": true,
"usingComponents": {}
}

View File

@@ -1,98 +1,20 @@
<!--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 class="welcome-section">
<text class="welcome-title">信息服务小程序</text>
<text class="welcome-subtitle">基于微信云开发</text>
</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="menu-section">
<van-cell-group>
<van-cell
title="云开发测试"
label="测试云函数、云数据库、云存储"
is-link
bindtap="goCloudTest"
>
<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="暂无信息" />
<van-icon slot="icon" name="code-o" size="40rpx" color="#1890ff" style="margin-right: 20rpx;" />
</van-cell>
</van-cell-group>
</view>
</view>

View File

@@ -1,145 +1,33 @@
/* pages/index/index.wxss */
.container {
padding-bottom: 120rpx;
min-height: 100vh;
background-color: #f5f5f5;
padding: 30rpx;
box-sizing: border-box;
}
/* 搜索栏 */
.search-bar {
position: sticky;
top: 0;
z-index: 100;
background-color: #fff;
.welcome-section {
text-align: center;
padding: 60rpx 0;
}
/* 轮播图 */
.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;
.welcome-title {
display: block;
font-size: 44rpx;
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;
.welcome-subtitle {
display: block;
font-size: 28rpx;
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;
.menu-section {
margin-top: 40rpx;
border-radius: 16rpx;
overflow: hidden;
}

View File

@@ -40,6 +40,7 @@
}
},
"compileType": "miniprogram",
"cloudfunctionRoot": "cloudfunctions/",
"libVersion": "3.12.0",
"appid": "wx02a3d808a95a7457",
"projectname": "info-service-miniprogram",