# Conflicts:
#	scr/miniprogram-2/project.config.json
#	scr/论坛/project.config.json
master
wbb 2 years ago
commit 962fa72523

@ -0,0 +1,51 @@
# weapp-wechat-zhihu
微信中的知乎--微信小程序 demo // Zhihu in Wechat
![](images/v_index.png)
### description
- 界面及交互设计来自知乎 Android 版本
- _工具_: [微信 web 开发者工具](https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=1477579747265)
- _数据_: 没有开放 API, 所以使用伪造本地数据
#### 功能及使用的组件等
* 列表式渲染数据
* 自定义顶部 tabbar
* 下拉刷新
* 上拉加载更多
* 轮播图
<br/>等...
### Setup
```
git@github.com:RebeccaHanjw/weapp-wechat-zhihu.git
```
下载安装Wechat DEV Tools, 并导入项目
### 演示
首页下拉刷新等
![](images/index_scroll.gif)
底部 tab 切换
![](images/bottom_tab.gif)
顶部自定义 tab 切换
![](images/top_tab.gif)
页面跳转
![](images/navigation.gif)
##### Demo 用于学习交流, 转载请注明出处

@ -0,0 +1,35 @@
//app.js
App({
onLaunch: function () {
wx.cloud.init({
env:"cloud1-8g5wmepxce8a3b8a",
traceUser:true//是否访问权限可见
})}})
/*
//调用API从本地缓存中获取数据
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
},
getUserInfo:function(cb){
var that = this
if(this.globalData.userInfo){
typeof cb == "function" && cb(this.globalData.userInfo)
}else{
//调用登录接口
wx.login({
success: function () {
wx.getUserInfo({
success: function (res) {
that.globalData.userInfo = res.userInfo
typeof cb == "function" && cb(that.globalData.userInfo)
}
})
}
})
}
},
globalData:{
userInfo:null
}
})*/

@ -0,0 +1,44 @@
{
"pages":[
"pages/login/login",
"pages/index/index",
"pages/submit/submit",
"pages/notify/notify",
"pages/searchShow/searchShow",
"pages/change/change",
"pages/answer/answer"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#0068C4",
"navigationBarTitleText": "论坛",
"navigationBarTextStyle":"white",
"enablePullDownRefresh":true
},
"tabBar": {
"color": "#626567",
"selectedColor": "#2A8CE5",
"backgroundColor": "#FBFBFB",
"borderStyle": "white",
"list": [{
"pagePath": "pages/index/index",
"text": "",
"iconPath": "images/index.png",
"selectedIconPath": "images/index_focus.png"
},{
"pagePath": "pages/notify/notify",
"text": "",
"iconPath": "images/ring.png",
"selectedIconPath": "images/ring_focus.png"
}
]
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"debug": true,
"style": "v2",
"sitemapLocation": "sitemap.json"
}

@ -0,0 +1,127 @@
/**app.wxss**/
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
/*padding: 200rpx 0;*/
box-sizing: border-box;
background: #F0F4F3;
}
.container.withtab{
margin: 105rpx 0 0 0;
/*top: 105rpx;*/
}
.flex-wrp{
display: flex;
}
.flex-tab{
flex-flow: row nowrap;
justify-content: space-around;
align-items: stretch;
}
.flex-item{
flex-grow: 1;
text-align: center;
}
.top-tab{
width: 750rpx;
height: 100rpx;
background: #298DE5;
color: #8CCEFD;
font-size: 28rpx;
line-height: 100rpx;
box-shadow: 0 2px 2px #bebebe;
margin: 0 0 8rpx 0;
position: fixed;
top: 0;
z-index: 9999;
}
.toptab.active{
color: #ffffff;
border-bottom: solid 2px #ffffff;
}
.container{
padding: 0;
font-size: 14rpx;
color: #000;
}
.container .feed-item{
width: 690rpx;
padding: 30rpx 30rpx 20rpx;
margin: 7rpx 0 6rpx 0;
background: #ffffff;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
box-shadow: 0 2px 5px #eeeeee;
}
.container .feed-item .feed-source{
width: 690rpx;
left: 0;
height: 50rpx;
}
.container .feed-item .feed-source .avatar{
position: relative;
display: inline-block;
}
.container .feed-item .feed-source a{
display: inline-block;
height: 40rpx;
}
.container .feed-item .feed-source .avatar image{
/*position: absolute;*/
display: inline-block;
width: 45rpx;
height: 45rpx;
border-radius: 45rpx;
top: 10rpx;
vertical-align: middle;
}
.container .feed-item .feed-source text{
/*position: absolute;*/
display: inline-block;
height: 40rpx;
line-height: 40rpx;
vertical-align: middle;
margin: 0 0 0 15rpx;
color: #a0acac;
font-size: 26rpx;
}
.container .feed-item .feed-source .item-more{
display: inline-block;
width: 40rpx;
height: 45rpx;
float: right;
}
.container .feed-item .feed-content{
padding: 10rpx 0 0 0;
}
.container .feed-item .feed-content .question text{
font-size: 28rpx;
font-weight: 600px;
line-height: 40rpx;
word-spacing: 5rpx;
}
.container .feed-item .feed-content .answer-body{
padding: 10rpx 0 0 0;
/*height: 10rpx;*/
font-size: 24rpx;
line-height: 28rpx;
color: #5b5b5b;
}
.container .feed-item .feed-content .answer-actions{
width: 690rpx;
padding: 10rpx 0 0;
color: #a0acac;
}
.container .feed-item .feed-content .answer-actions view{
display: inline-block;
vertical-align: text-bottom;
padding: 0 10rpx 0 0;
font-size: 24rpx;
}
.container .feed-item .feed-content .answer-actions .dot ::after{
content: "•";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Before

Width:  |  Height:  |  Size: 715 B

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

@ -0,0 +1,297 @@
//answer.js
let dianzan=false
var app = getApp()
Page({
data: {
motto: '知乎--微信小程序版',
userInfo: {},
feed: [],
//修改
pinglun:[], //评论数组
content:'',
detail: '',
dianzanUrl: "../../images/heart2.png",
comment_num:0
},
//事件处理函数
// toQuestion: function() {
// wx.navigateTo({
// url: '../question/question'
// })
// },
onLoad: function (options) {
var aid=options.aid
console.log(options);
console.log(options.aid);
console.log('onLoad')
wx.setStorageSync('aid', aid)
//修改
wx.cloud.database().collection("tiezi")
.doc(aid)
.get()
.then(res => {
console.log("详情页成功", res);
//将收藏添加到数据库
//shoucang = res.data.shoucang
//dianzan = res.data.dianzan
//console.log(shoucang, dianzan);
//再次显示数据
this.setData({
detail: res.data,
pinglun:res.data.pinglun
})
})
.catch(err => {
console.log("详情页失败", err);
})
var getId = options.aid;
// 让接收到的id值传递到data:{}里面
this.setData({
currentId: getId
});
// 读取所有的文章列表点赞缓存状态
var cache = wx.getStorageSync('cache_key');
// 如果缓存状态存在
if (cache) {
// 拿到所有缓存状态中的1个
var currentCache = cache[getId];
// 把拿到的缓存状态中的1个赋值给data中的collection如果当前文章没有缓存状态currentCache 的值就是 false如果当前文章的缓存存在那么 currentCache 就是有值的,有值的说明 currentCache 的值是 true
this.setData({
collection: currentCache
})
} else {
// 如果所有的缓存状态都不存在 就让不存在的缓存存在
var cache = {};
// 既然所有的缓存都不存在,那么当前这个文章点赞的缓存也不存在,我们可以把当前这个文章点赞的缓存值设置为 false
cache[getId] = false;
// 把设置的当前文章点赞放在整体的缓存中
wx.setStorageSync('cache_key',cache);
}
},
// 点击图片的点赞事件 这里使用的是同步的方式
toCollect: function(options) {
let aid= wx.getStorageSync ("aid")
console.log(aid);
// 获取所有的缓存
var cache = wx.getStorageSync('cache_key');
// 获取当前文章是否被点赞的缓存
var currentCache = cache[this.data.currentId];
// 取反,点赞的变成未点赞 未点赞的变成点赞
currentCache = !currentCache;
// 更新cache中的对应的1个的缓存值使其等于当前取反的缓存值
cache[this.data.currentId] = currentCache;
// 重新设置缓存
wx.setStorageSync('cache_key',cache);
// 更新数据绑定,从而切换图片
this.setData({
// collection 默认的是 false
collection: currentCache
});
// 交互反馈
wx.showToast({
title: currentCache?'点赞':'取消',
icon: 'success',
duration: 2000
});
if(currentCache==true){
wx.cloud.database().collection("tiezi")
.doc(aid)
.update({
data: {
// 前面为数据库字段,后面为修改之后的值
good_num: wx.cloud.database().command.inc(1),
}
})
.then(res => {
console.log("添加评论成功", res);
return res
})
.catch(err => {
console.log("添加评论失败", err);
return err
})
}
else{
wx.cloud.database().collection("tiezi")
.doc(aid)
.update({
data: {
// 前面为数据库字段,后面为修改之后的值
good_num: wx.cloud.database().command.inc(-1),
}
})
.then(res => {
console.log("成功", res);
return res
})
.catch(err => {
console.log("失败", err);
return err
})
}
},
/*
onLoad: function (options) {
},*/
tapName: function(event){
console.log(event)
},
//获取输入的值
getContent(event){
this.setData({
content:event.detail.value
})
},
//发表评论
fabiao(options){
let content=this.data.content
if(content.length<4){
wx.showLoading({
icon:"none",
title: '评论太短了',
})
return
}
let pinglunItem={}
pinglunItem.nickName=wx.getStorageSync ("nickName")
pinglunItem.avatarUrl=wx.getStorageSync ("avatarUrl")
pinglunItem.content=content
let pinglunArr=this.data.pinglun
pinglunArr.push(pinglunItem)
let l= pinglunArr.length
console.log("评论数",l)
console.log("添加后的评论数组",pinglunArr)
wx.showLoading({
title: '发表中',
})
wx.cloud.init({
env:"cloud1-8g5wmepxce8a3b8a",
})
let aid= wx.getStorageSync ("aid")
console.log(aid);
//异步操作
wx.cloud.database().collection("tiezi")
.doc(aid)
.update({
data: {
// 前面为数据库字段,后面为修改之后的值
pinglun: pinglunArr,
comment_num:pinglunArr.length
}
})
.then(res => {
console.log("添加评论成功", res);
return res
})
.catch(err => {
console.log("添加评论失败", err);
return err
})
let that = this;
wx.hideLoading({
success: (res) => {
that.setData({
pinglun:pinglunArr,
content:''
})
wx.showToast({
title: '发布成功',
})}})
},
//点赞切换
clickDianzan() {
this.setData({
dianzanUrl: dianzan ? "../../images/heart2.png" : "../../images/heart1.png"
})
dianzan = !dianzan
wx.setStorageSync ("dianzan",dianzan)
console.log("改变点赞状态", dianzan)
},
amend: function(e) {
let aid= wx.getStorageSync ("aid")
console.log(aid);
wx.showModal({
title: '编辑',
content: '确定要修改已发布的信息吗?',
success(res) {
if(res.confirm) {
wx.redirectTo({
url: '../change/change?aid='+aid,
})
console.log('用户点击了确定')
}else if(res.cancel) {
console.log('用户点击了取消')
}
}
})
},
delete(event){
let aid= wx.getStorageSync ("aid")
console.log(aid);
wx.cloud.database().collection('tiezi')
.doc(aid)
.remove()
.then(res => {
console.log(res);
}).catch(res => {
console.log(res);
})
wx.switchTab({
url: '../index/index'
})
},
delete_p: function(event) {
/*wx.navigateTo({
url: '../answer/answer'
})*/
let aid= wx.getStorageSync ("aid")
console.log(aid);
var aidc=event.currentTarget.dataset.aidc;
console.log(aidc)
//console.log("1")
wx.cloud.database().collection('tiezi')
.where({
'_id':aid,
'pinglun.content':aidc
})
.update({
data:{
pinglun:wx.cloud.database().command.pull({
content:aidc
}),
comment_num:wx.cloud.database().command.inc(-1)
}
})
.then(res => {
console.log(res);
console.log(res);
wx.showLoading({
title: '删除成功...',
})
wx.redirectTo({
url: '../answer/answer?aid='+aid,
})
wx.hideLoading()
}).catch(res => {
console.log(res);
})
}
})

@ -0,0 +1,3 @@
{
"navigationBarTitleText": "回答"
}

@ -0,0 +1,93 @@
<!--answer.wxml-->
<!--<block wx:for="{{feed}}" wx:key="index">-->
<view class="mycontainer">
<view class="a" >
<view class="question" >
<text class="question-title">{{detail.title}}</text>
</view>
<view class="answerer-wrp">
<view class="bg-half"></view>
<view class="answerer flex-wrp">
<view class="avatar flex-item">
<image src="{{detail.feed_source_img}}"></image>
</view>
<view class="answerer-info flex-item">
<text class="answerer-name">{{detail.feed_source_name}}</text>
<text class="answerer-des">喜欢就点个赞吧~</text>
</view>
<!-- <view class="follow flex-item"> -->
<view class="follow flex-item">
<!-- 删除 -->
<image data-aid="{{detail._id}}" bindtap="delete" class="a3" src="/images/delete.png"></image>
<text>删除</text>
<!-- </view> -->
</view>
<view class="follow flex-item">
<!-- 修改 -->
<image data-aid="{{detail._id}}" bindtap="amend" class="image" src="/images/write.png"></image>
<text>编辑</text>
<!-- </view> -->
</view>
<view class="follow flex-item">
<image wx:if="{{collection}}" src="../../images/heart1.png" bindtap="toCollect"></image>
<image wx:else src="../../images/heart2.png" bindtap="toCollect"></image>
<text>点赞</text>
<!-- </view> -->
</view>
</view>
</view>
<view class="answer-content">
<text class="desc" style="white-space:pre-wrap;">{{detail.content}}</text>
<image webp wx:for="{{detail.url}}" mode='widthFix' src="{{item}}" ></image>
</view>
</view>
<!--</block>-->
<!-- 评论 -->
<block wx:for="{{pinglun}}" wx:key="index">
<view class="pinglunItem ">
<view>
<image class="a1" src="{{item.avatarUrl}} "></image>
</view>
<view >
<view class="desc" >{{item.nickName}}{{item.content}}</view>
</view>
<view>
<image data-aidc="{{item.content}}" bindtap="delete_p" class="a2" src="/images/delete.png"></image>
</view>
</view>
</block>
<view class="search flex-wrp">
<view class="search-left flex-item">
<input placeholder="请输入评论的内容" placeholder-class="search-placeholder" bindinput="getContent" value="{{content}}"/>
</view>
<view class="search-right flex-item" bindtap="fabiao">
<view class="desc">发表</view>
</view>
</view>
<view class="standView"></view>
</view>

@ -0,0 +1,300 @@
/**answer.wxss**/
.mycontainer{
margin-bottom: 200rpx;
}
.a {
padding: 0;
font-size: 14rpx;
background: #F0F4F3;
color: #000;
}
.question {
position: relative;
width: 650rpx;
padding: 40rpx 50rpx 30rpx;
background: #298DE5;
color: #fff;
font-size: 38rpx;
line-height: 48rpx;
}
.answerer-wrp{
position: relative;
width: 750rpx;
height: 150rpx;
background: #fff;
}
.answerer-wrp .bg-half{
position: absolute;
top: 0;
width: 750rpx;
height: 75rpx;
background: #298DE5;
}
.answerer {
position: relative;
margin: 0 auto;
width: 630rpx;
height: 90rpx;
padding: 30rpx;
background: #fff;
border: solid 1px #ebebeb;
border-radius: 3px;
box-shadow: 0 1px 2px #bebebe;
}
.answerer .avatar {
flex: 1;
width: 90rpx;
height: 90rpx;
}
.answerer .avatar image {
display: inline-block;
width: 90rpx;
height: 90rpx;
border-radius: 90rpx;
}
.answerer .answerer-info{
flex: 5;
text-align: left;
padding: 10rpx 20rpx;
line-height: 38rpx;
}
.answerer .answerer-info text{
display: block;
}
.answerer .answerer-info .answerer-name{
font-size: 32rpx;
}
.answerer .answerer-info .answerer-des{
font-size: 22rpx;
color: #808080;
line-height: 28rpx;
}
.answerer .follow image{
/* flex: 2;
padding: 15rpx 0;
font-size: 22rpx; */
display: block;
margin: 0 auto;
width: 40rpx;
height: 40rpx;
}
.answerer .follow text{
/* display: inline-block;
padding: 15rpx 20rpx;
color: #40bcd0;
border: solid 2px #40bcd0;
border-radius: 6rpx; */
display: block;
font-size: 14rpx;
color: #bebebe;
}
.answerer .follow .a3{
/* flex: 2;
padding: 15rpx 0;
font-size: 22rpx; */
display: block;
margin: 0 auto;
width: 30rpx;
height: 35rpx;
margin-top: 9rpx;
}
.answer-content{
padding: 30rpx 40rpx;
background: #ffffff;
}
.answer-content text{
font-size: 32rpx;
color: #454545;
line-height: 44rpx;
word-break: break-all;
}
.answer-content image{
width: 100%;
margin: 20rpx 0;
}
.answer-footer{
width: 750rpx;
height: 70rpx;
font-size: 28rpx;
box-shadow: 0 100px 7px #bebebe;
margin: 0 200rpx 0 0;
position: sticky ;
bottom: 0;
z-index: 9999;
}
.answer-footer{
position: fixed;
bottom: 0;
height: 70rpx;
border-top: solid 1px #ebebeb;
background: #ffffff;
width: 670rpx;
padding: 20rpx 40rpx;
}
.answer-footer .good{
flex: 1;
/*display: inline-block;*/
height: 40rpx;
border: solid 1px #d1d1d1;
border-radius: 3px;
padding: 10rpx 8rpx;
margin: 10rpx 0;
}
.answer-footer .good .good-bad{
display: inline-block;
}
.answer-footer .good image{
display: inline-block;
width: 38rpx;
height: 38rpx;
vertical-align: middle;
}
.answer-footer .good .good-num{
display: inline-block;
padding: 10rpx 4rpx;
/*font-size: 24rpx;*/
}
.answer-footer .operation-wrp{
flex: 5;
}
.answer-footer .operation{
justify-content: space-between;
padding: 0 0 0 60rpx;
}
.answer-footer .operation-btn{
flex: 1;
text-align: center;
}
.answer-footer .operation image{
display: block;
margin: 0 auto;
width: 50rpx;
height: 50rpx;
}
.answer-footer .operation-btn text{
display: block;
font-size: 14rpx;
color: #bebebe;
}
/* .tip{
position: relative;
width: 650rpx;
padding: 30rpx 50rpx 30rpx;
/*background: #298DE5;*/
/* color: rgb(0, 0, 0);
font-size: 38rpx;
line-height: 48rpx;
} */
.input{
display:block;
border:2px solid gainsboro;
margin-top: 60rpx;
margin-bottom: 60rpx;
}
.pinglunItem{
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
border-top: 2px solid gainsboro;
margin-left: 0rpx;
margin-top: 0rpx;
}
.pinglunItem .a1{
margin-left: 30rpx;
margin-right: 30rpx;
margin-top: 20rpx;
margin-bottom: 20rpx;
width: 60rpx;
height: 60rpx;
border-radius: 90rpx;
}
.pinglunItem .desc{
font-size: 30rpx;
height: 40rpx;
}
.pinglunItem .a2 {
margin-left: 100rpx;
margin-right: 30rpx;
margin-top: -20rpx;
width: 30rpx;
height: 35rpx;
position: absolute; /* 要约束所在位置的子元素的位置要设置成绝对 */
right: 0;
}
.search{
position: fixed;
bottom: 0;
width: 735rpx;
height: 65rpx;
padding: 12.5rpx 0 12.5rpx 15rpx;
background: #2A8CE5;
}
.search-left{
flex: 8;
background: #4EA3E7;
text-align: left;
}
.search-left input{
display: inline-block;
height: 65rpx;
font-size: 26rpx;
}
.search-placeholder{
color: #8CCEFD;
line-height: 20rpx;
}
.search .search-left image{
display: inline-block;
width: 35rpx;
height: 35rpx;
padding: 15rpx 15rpx 15rpx 20rpx;
}
.search .search-right{
flex: 1;
}
.search .search-right .desc{
font-size: 25rpx;
color: #ffffff;
margin:15rpx
}
/* 解决底部导航栏遮挡的占位view的样式 */
.standView{
width: 100%;
height: 100rpx; /* 自定义一下需要的高度 */
/* background-color: black; */
}

@ -0,0 +1,241 @@
// pages/change/change.js
var app = getApp()
Page({
data: {
feed: [],
change1: '',
change2: '',
tempFilePaths: [],
t:'',
c:'',
nowCount:0,//当前的图片上传个数
index:0,
url:[]
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var that = this
var aid=options.aid
console.log(options);
console.log(options.aid);
wx.cloud.database().collection('tiezi')
.doc(aid)
.get({
success(res) {
console.log("请求成功", res.data)
console.log("请求成功", res.data.url.length)
// 将查询返回的结果赋值给本地数组
that.setData({
feed: res.data,
nowCount:res.data.url.length,
tempFilePaths: res.data.url,
url:res.data.url,
t:res.data.title,
c:res.data.content
})
},
fail(res) {
console.log("请求失败", res)
}
})
},
// 获取修改后的内容
change1: function(e) {
this.setData({
change1: e.detail.value
})
},
change: function(e) {
this.setData({
change2: e.detail.value
})
},
//图片的上传
chooseImage:function(e){
let that = this;
wx.chooseImage({
count: 3, // 默认最多3张图片可自行更改
sizeType: ['original', 'compressed'],// 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: res => {
wx.showToast({
title: '正在上传...',
icon: 'loading',
mask: true,
duration: 1000
})
// 返回选定照片的本地文件路径列表tempFilePath可以作为img标签的src属性显示图片
let tempFilePath = res.tempFilePaths;
console.log(tempFilePath);
let nowCount = that.data.nowCount;
let tempFilePaths = that.data.tempFilePaths;
if(that.data.nowCount + tempFilePath.length >=3){
let i = 0;
while(nowCount<3){//还可以继续上传图片
tempFilePaths.push(tempFilePath[i]);
i++;
nowCount++;
}
that.setData({
nowCount:3,
tempFilePaths:tempFilePaths
})
}else{
let i = 0;
while(i<tempFilePath.length){
tempFilePaths.push(tempFilePath[i]);
i++;
}
that.setData({
nowCount:that.data.nowCount + tempFilePath.length,
tempFilePaths:tempFilePaths
})
}
console.log(that.data.nowCount,that.data.tempFilePaths);
}
})
},
//长按删除图片
DeleteImg: function (e) {
let that = this;
let tempFilePaths = that.data.tempFilePaths;
let index = e.currentTarget.dataset.index;//获取当前长按图片下标
wx.showModal({
title: '提示',
content: '确定要删除此图片吗?',
success: function (res) {
if (res.confirm) {
//console.log('点击确定了');
let nowCount = that.data.nowCount;
that.setData({
nowCount:nowCount-1
})
tempFilePaths.splice(index, 1);
} else if (res.cancel) {
//console.log('点击取消了');
return false;
}
that.setData({
tempFilePaths:tempFilePaths
});
}
})
},
// 提交修改
sure: function(event) {
var that = this
let content1
let content
// if(this.data.change1==''){console.log("1")}
// if(this.data.change2==''){console.log("2")}
if(this.data.change1==''){
content1=this.data.t
}else{
content1=this.data.change1
}
if(this.data.change2==''){
content=this.data.c
}else{
content=this.data.change2
}
console.log(content1,"1",content,"1")
//图片修改
let i;
let count=0;
let url=this.data.url
let l=url.length
console.log(l)
if(that.data.nowCount==0){
wx.cloud.init({
env:"cloud1-8g5wmepxce8a3b8a",
})
let aid=wx.getStorageSync ("aid")
console.log(aid);
wx.cloud.database().collection('tiezi')
.doc(aid)
.update({
data:{
title:content1,
content: content,
}
}).then(res=>{
console.log(res);
wx.showLoading({
title: '修改成功...',
})
wx.redirectTo({
url: '../answer/answer?aid='+aid,
})
wx.hideLoading()
}).catch(res=>{
console.log(res);
})
}else{
//将所有的内容上传到云端去
for(i=l;i<that.data.nowCount;i++){
console.log(1);
let extName = that.data.tempFilePaths[i].split(".").pop();
let cloudPath = "love/" + new Date().getTime() + "." + extName;
wx.cloud.uploadFile({
cloudPath: cloudPath,
filePath: that.data.tempFilePaths[i], // 文件路径
success: res => {
count++;
url.push(res.fileID);
console.log('上传图片');
console.log(i,url);
if(count==that.data.nowCount){
console.log(url);
}
},fail:res=>{
console.log(res);
}
})
}
wx.cloud.init({
env:"cloud1-8g5wmepxce8a3b8a",
})
let aid=wx.getStorageSync ("aid")
console.log(aid);
wx.cloud.database().collection('tiezi')
.doc(aid)
.update({
data:{
title:content1,
content: content,
url:url
}
}).then(res=>{
console.log(res);
wx.showLoading({
title: '修改成功...',
})
wx.redirectTo({
url: '../answer/answer?aid='+aid,
})
wx.hideLoading()
}).catch(res=>{
console.log(res);
})
}
},
})

@ -0,0 +1,25 @@
<!--pages/change/change.wxml-->
<!-- 用户自行修改数据的页面 -->
<view class="wall-item">
<!-- 内容 -->
<textarea class="title" bindinput="change1"placeholder="{{change1}}" decode="{{true}}" value="{{feed.title}}" style="height: 25px;"></textarea>
<textarea bindinput="change" style="white-space:pre-wrap;" value="{{feed.content}}" placeholder="{{change}}" data-aid="{{feed._id}}" class="content"></textarea>
<!--帖子的图片-->
<view class="img_box">
<view class="imgs" wx:for="{{tempFilePaths}}" wx:key="index">
<image src='{{item}}' bindlongpress="DeleteImg" bindtap="listenerButtonPreviewImage" data-index="{{index}}" mode='widthFix' />
</view>
<view class="imgs" wx:if="{{feed.url.length<3}}">
<view class="images" bindtap="chooseImage">
<image src='../../images/upload.png' mode='widthFix' />
</view>
</view>
</view>
</view>
<!-- 确认修改 -->
<button class="publish" bindtap="sure">确认修改</button>

@ -0,0 +1,73 @@
/* pages/change/change.wxss */
.title{
font-size: 38rpx;
display: flex;
margin-top: 25rpx;
padding: 13px 0;
margin-bottom: 30rpx;
border-bottom: 1px solid #ccc;
}
.content{
margin-bottom: 30rpx;
border-bottom: 1px solid #ccc;
padding-right: 50rpx;
margin-top: 30rpx;
display: block;
width: 100%;
height: 550rpx !important;
box-sizing: border-box;
font-size: 32rpx;
color: #454545;
line-height: 44rpx;
/*word-break: break-all;*/
}
.picker{
display: flex;
padding: 13px 0;
margin-bottom: 35rpx;
border-bottom: 1px solid #ccc;
}
.img_box{
position:relative;
display: flex;
flex-wrap: wrap;
margin:0 auto;
}
.imgs{
width:33.33333333%;
display: flex;
justify-content: center;
margin-bottom:20rpx;
}
.imgs image{
width:90%;
max-height:212rpx;
border:1px solid rgba(214, 212, 212, 0.1);
/* box-shadow: 5rpx 5rpx 1rpx 3rpx #e2e0e0; */
}
.imgs .images{
position:relative;
}
.images button{
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
}
.img_box .images{
width:90%;
height: 212rpx;
border:1px solid #E8E8E8;
border-radius:4rpx;
display: flex;
align-items: center;
justify-content: center;
}
.img_box .images>image{
width:60rpx;
height:60rpx;
}

@ -0,0 +1,252 @@
//index.js
let currentPage = 0 // 当前第几页,0代表第一页
let pageSize = 6
var util = require('../../utils/util.js')
var app = getApp()
Page({
data: {
search:'',
re:[],
feed: [],
feed_length: 0,
loadMore: false, //"上拉加载"的变量默认false隐藏
loadAll: false //“没有数据”的变量默认false隐藏
//imgList:[]
},
//事件处理函数
bindItemTap: function(event) {
/*wx.navigateTo({
url: '../answer/answer'
})*/
var aid=event.currentTarget.dataset.aid;
console.log(aid)
//console.log("1")
wx.navigateTo({
url: '../answer/answer?aid='+aid,//要跳转到的页面路径
})
},
onLoad: function () {
console.log('onLoad')
this.clearCache();
let that = this
//调用应用实例的方法获取全局数据
this.getData();
this.refresh()
},
onShow: function (){
console.log('onshow')
this.upper()
},
upper: function () {//下滑刷新
wx.showNavigationBarLoading()
this.refresh();
console.log("upper");
setTimeout(function(){wx.hideNavigationBarLoading();wx.stopPullDownRefresh();}, 1000);
},
lower: function (e) {//触底加载
wx.showNavigationBarLoading();
var that = this;
setTimeout(function(){wx.hideNavigationBarLoading();that.nextLoad();}, 1000);
console.log("lower")
},
scroll: function (e) {
console.log("scroll")
},
//网络请求数据, 实现首页刷新
refresh0: function(){
this.getData;
/*var index_api = '';
util.getData(index_api)
.then(function(data){
//this.setData({
//
//});
console.log(data);
});*/
},
//使用本地 fake 数据实现刷新效果
getData() {
let that = this;
//第一次加载数据
if (currentPage == 1) {
this.setData({
loadMore: true, //把"上拉加载"的变量设为true显示
loadAll: false //把“没有数据”设为false隐藏
})
}
//云数据的请求
wx.cloud.database().collection("tiezi")
.orderBy('createTime', 'desc') //按发布视频排序
.skip(currentPage * pageSize) //从第几个数据开始
.limit(pageSize)
.get({
success(res) {
if (res.data && res.data.length > 0) {
console.log("请求成功", res.data)
currentPage++
//把新请求到的数据添加到dataList里
let list = that.data.feed.concat(res.data)
that.setData({
feed: list, //获取数据数组
loadMore: false //把"上拉加载"的变量设为false显示
});
if (res.data.length < pageSize) {
that.setData({
loadMore: false, //隐藏加载中。。
loadAll: true //所有数据都加载完了
});
}
} else {
that.setData({
loadAll: true, //把“没有数据”设为true显示
loadMore: false //把"上拉加载"的变量设为false隐藏
});
}
},
fail(res) {
console.log("请求失败", res)
that.setData({
loadAll: false,
loadMore: false
});
}
})
},
refresh: function(){
this.clearCache();
this.getData()
let that = this
if (!that.data.loadMore) {
that.setData({
loadMore: true, //加载中
loadAll: false //是否加载完所有数据
});}
},
//使用本地 fake 数据实现继续加载效果
nextLoad: function(){
console.log("上拉触底事件")
let that = this
if (!that.data.loadMore) {
that.setData({
loadMore: true, //加载中
loadAll: false //是否加载完所有数据
});
//加载更多,这里做下延时加载
setTimeout(function() {
that.getData()
}, 500)
}
},
goto(){
wx.navigateTo({
url: '../submit/submit',//要跳转到的页面路径
})
},
// 清缓存
clearCache:function(){
currentPage = 0;//分页标识归零
this.setData({
feed: [] //文章列表数组清空
});
},
GetSearchInput: function(e) {
this.setData({
search: e.detail.value
})
},
ToSearch: function(e) {
//let search = e.detail.value;
var that = this;
if(this.data.search == '') {
wx.showToast({
title: '请输入',
icon: 'none'
})
return
}
wx.showLoading({
title: '搜索中',
})
const _ = wx.cloud.database().command
wx.cloud.database().collection('tiezi').where(_.or([
{
content: wx.cloud.database().RegExp({
regexp: this.data.search,
options: 'i',
}),
},
{
title: wx.cloud.database().RegExp({
regexp: this.data.search,
options: 'i',
}),
}
]))
// wx.cloud.database().collection('tiezi').where({
// content: wx.cloud.database().RegExp({
// regexp: this.data.search,
// options: 'i',
// }),
// })
.get()
.then(res => {
if (res.data.length != 0) {
this.setData({
re: res.data,
})
wx.setStorageSync('re', res.data)
let re= wx.getStorageSync('re')
console.log(re)
let that = this;
wx.hideLoading({
success: (res) => {
that.setData({
search: '',
})
}})
wx.navigateTo({
url: '../searchShow/searchShow?re='+JSON.stringify(re),//要跳转到的页面路径
})
} else {
wx.showToast({
title: '未找到',
icon: 'none'
})
}
console.log(res.data)
})
.catch(res => {
console.log("查询失败",res)
})
},
})

@ -0,0 +1,71 @@
<!--index.wxml-->
<scroll-view scroll-y="true" class="container" bindscrolltoupper="upper" upper-threshold="10" lower-threshold="5" bindscrolltolower="lower" scroll-into-view="{{toView}}" scroll-top="{{scrollTop}}">
<view class="search flex-wrp">
<view class="search-left flex-item">
<input placeholder="点击右侧闪电发帖" placeholder-class="search-placeholder"/>
</view>
<view class="search-right flex-item" bindtap="goto">
<image src="../../images/lighting.png"></image>
</view>
</view>
<view class="sousuokuang">
<view class="sousuo">
<view class="shurukuang">
<input placeholder="搜索" value="{{inputValue}}" bindinput="GetSearchInput"></input>
</view>
<view class="sousuo_anniu" bindtap="ToSearch">
<text>搜索</text>
<icon type="search" size="20"></icon>
</view>
</view>
</view>
<block wx:for="{{feed}}" wx:for-index="idx" wx:for-item="item" data-idx="{{idx}}">
<view class="feed-item">
<view class="feed-source">
<a class="">
<view class="avatar">
<image src="{{item.feed_source_img}}"></image>
<!--<open-data type="userAvatarUrl"></open-data>-->
</view>
<text>{{item.feed_source_name}}</text>
<!-- <open-data type="userNickName"></open-data>-->
</a>
<image class="item-more" mode="aspectFit" bindtap="delete_p" data-aid="{{item._id}}" src="../../images/more.png"></image>
</view>
<view class="feed-content">
<view class="question" bindtap="bindItemTap" data-aid="{{item._id}}">
<a class="question-link">
<text>{{item.title}}</text>
</a>
</view>
<view class="answer-body">
<view >
<text class="answer-txt" bindtap="bindItemTap" data-aid="{{item._id}}">{{item.content}}</text>
</view>
<view class="answer-actions" bindtap="bindItemTap">
<view class="like dot">
<a>{{item.good_num}} 赞同 </a>
</view>
<view class="follow-it">
<text decode="{{true}}">&emsp;&emsp;</text>
</view>
<view class="comments dot">
<a>{{item.comment_num}} 评论 </a>
</view>
</view>
</view>
</view>
</view>
</block>
<view class="loading" hidden="{{!loadMore}}">正在载入更多...</view>
<view class="loading" hidden="{{!loadAll}}">已加载全部</view>
</scroll-view>

@ -0,0 +1,109 @@
/**index.wxss**/
.container{
height: 1500rpx;
}
.container .search{
width: 735rpx;
height: 65rpx;
padding: 12.5rpx 0 12.5rpx 15rpx;
background: #2A8CE5;
}
.container .search-left{
flex: 8;
background: #4EA3E7;
text-align: left;
}
.container .search-left input{
display: inline-block;
height: 65rpx;
font-size: 26rpx;
}
.search-placeholder{
color: #8CCEFD;
line-height: 20rpx;
}
.container .search .search-left image{
display: inline-block;
width: 35rpx;
height: 35rpx;
padding: 15rpx 15rpx 15rpx 20rpx;
}
.container .search .search-right{
flex: 1;
}
.container .search .search-right image{
width: 45rpx;
height: 45rpx;
padding: 10rpx;
}
.container{
padding: 0;
font-size: 14rpx;
background: #F0F4F3;
color: #000;
}
/*feed-item part is in app.wxss for multiplexing*/
.answer-txt{
width:700rpx;
height:49rpx;
font-size:25rpx;
overflow:hidden;
text-overflow: ellipsis;
display:-webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.loading {
font-size: 32rpx;
position: relative;
bottom: 5rpx;
padding: 10rpx;
text-align: center;
}
.sousuokuang {
width: 100%;
height: 100rpx;
display: flex;
flex-direction: column;
align-items: center;
background-color: white;
}
.sousuo {
width: 92%;
height: 100rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-items: center;
}
.shurukuang {
width: 80%;
height: 64rpx;
border-radius: 32rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: #f6f6f6;
}
.shurukuang input {
width: 90%;
height: 100%;
font-size: 32rpx;
}
.sousuo_anniu {
width: 20%;
height: 64rpx;
display: flex;
align-items: center;
justify-content: center;
}
.sousuo_anniu text {
font-size: 30rpx;
}

@ -0,0 +1,55 @@
// pages/login/login.js
Page({
data:{
userInfo:'',
avatarUrl:'',
nickName:''
},
onLoad(){
/*
let user=wx.getStorageSync('user')
this.setData({
userInfo:user
})
wx.switchTab({
url: '/pages/index/index'
})
*/
},
login(){
let that = this;
console.log('点击事件执行了')
wx.getUserProfile({
desc: '必须授权才能使用',
success:res=>{
let user=res.userInfo
let avatarUrl=res.userInfo.avatarUrl
let nickName=res.userInfo.nickName
wx.setStorageSync('user', user)
wx.setStorageSync('avatarUrl', avatarUrl)
wx.setStorageSync('nickName', nickName)
console.log('成功',res)
wx.cloud.database().collection('user').add({
data: {
userInfo:user,
avatarUrl:user.avatarUrl,
nickName:user.nickName
}
})
},
fall:res=>{
console.log('失败',res)
}
})
wx.switchTab({
url: '/pages/index/index'
})
},
nologin(){
this.setData({
userInfo:''
})
wx.setStorageSync('user', null)
},
})

@ -0,0 +1,13 @@
<!--pages/login/login.wxml-->
<!--登录-->
<button wx:if="{{!userInfo}}" bindtap="login">登录</button>
<view wx:else class="root">
<image class="touxiang" src="{{userInfo.avatarUrl}}"></image>
<text class="nicheng">{{userInfo.nickName}}</text>
</view>
<!--退出登录-->
<view wx:if="{{userInfo}}">
<button bindtap="nologin" >
<text>退出登录</text>
</button>
</view>

@ -0,0 +1,12 @@
/* pages/login/login.wxss */
.touxiang {
width: 150rpx;
height: 150rpx;
border-radius: 50%;
margin-top: 20rpx;
margin-bottom: 10rpx;
margin-left: 40%;
}
.nicheng{
color:white;
}

@ -0,0 +1,32 @@
//logs.js
var util = require('../../utils/util.js')
var app=getApp()
Page({
data: {
navTab: ["通知", "赞与感谢", "关注"],
currentNavtab: "0",
imgList:[]
},
onLoad: function () {
var that = this
wx.cloud.database().collection('food')
/*.where({
food_name:"烤盘饭",
_openid:undefined
})*/
.get({
success(res) {
console.log("请求成功", res)
that.setData({
imgList:res.data
}),
console.log(res.data)
},
fail(res) {
console.log("请求失败", res)
}
})
},
})

@ -0,0 +1,3 @@
{
"navigationBarTitleText": ""
}

@ -0,0 +1,7 @@
<text class="question-title1"></text>
<block wx:for="{{imgList}}" wx:key="index">
<view class="question" >
<text class="question-title">{{item.food_name}}</text>
<image wx:for="{{item.url}}" src="{{item}}" mode="heightFix" ></image>
</view>
</block>

@ -0,0 +1,149 @@
.a {
padding: 0;
font-size: 14rpx;
background: #F0F4F3;
color: #000;
}
.question {
position: relative;
width: 650rpx;
padding: 40rpx 50rpx 30rpx;
background: #298DE5;
color: #fff;
font-size: 38rpx;
line-height: 48rpx;
}
.answerer-wrp{
position: relative;
width: 750rpx;
height: 150rpx;
background: #fff;
}
.answerer-wrp .bg-half{
position: absolute;
top: 0;
width: 750rpx;
height: 75rpx;
background: #298DE5;
}
.answerer {
position: relative;
margin: 0 auto;
width: 630rpx;
height: 90rpx;
padding: 30rpx;
background: #fff;
border: solid 1px #ebebeb;
border-radius: 3px;
box-shadow: 0 1px 2px #bebebe;
}
.answerer .avatar {
flex: 1;
width: 90rpx;
height: 90rpx;
}
.answerer .avatar image {
display: inline-block;
width: 90rpx;
height: 90rpx;
border-radius: 90rpx;
}
.answerer .answerer-info{
flex: 5;
text-align: left;
padding: 10rpx 20rpx;
line-height: 38rpx;
}
.answerer .answerer-info text{
display: block;
}
.answerer .answerer-info .answerer-name{
font-size: 32rpx;
}
.answerer .answerer-info .answerer-des{
font-size: 22rpx;
color: #808080;
line-height: 28rpx;
}
.answerer .follow{
flex: 2;
padding: 15rpx 0;
font-size: 22rpx;
}
.answerer .follow text{
display: inline-block;
padding: 15rpx 20rpx;
color: #40bcd0;
border: solid 2px #40bcd0;
border-radius: 6rpx;
}
.answer-content{
padding: 30rpx 40rpx;
background: #ffffff;
}
.answer-content text{
font-size: 32rpx;
color: #454545;
line-height: 44rpx;
word-break: break-all;
}
.answer-content image{
width: 100%;
margin: 20rpx 0;
}
.answer-footer{
position: fixed;
bottom: 0;
height: 70rpx;
border-top: solid 1px #ebebeb;
background: #ffffff;
width: 670rpx;
padding: 20rpx 40rpx;
}
.answer-footer .good{
flex: 1;
/*display: inline-block;*/
height: 40rpx;
border: solid 1px #d1d1d1;
border-radius: 3px;
padding: 10rpx 8rpx;
margin: 10rpx 0;
}
.answer-footer .good .good-bad{
display: inline-block;
}
.answer-footer .good image{
display: inline-block;
width: 38rpx;
height: 38rpx;
vertical-align: middle;
}
.answer-footer .good .good-num{
display: inline-block;
padding: 10rpx 4rpx;
/*font-size: 24rpx;*/
}
.answer-footer .operation-wrp{
flex: 5;
}
.answer-footer .operation{
justify-content: space-between;
padding: 0 0 0 60rpx;
}
.answer-footer .operation-btn{
flex: 1;
text-align: center;
}
.answer-footer .operation image{
display: block;
margin: 0 auto;
width: 50rpx;
height: 50rpx;
}
.answer-footer .operation-btn text{
display: block;
font-size: 14rpx;
color: #bebebe;
}

@ -0,0 +1,30 @@
//answer.js
var util = require('../../utils/util.js')
var app = getApp()
Page({
data: {
motto: '知乎--微信小程序版',
userInfo: {}
},
//事件处理函数
bindItemTap: function() {
wx.navigateTo({
url: '../answer/answer'
})
},
onLoad: function () {
console.log('onLoad')
var that = this
//调用应用实例的方法获取全局数据
app.getUserInfo(function(userInfo){
//更新数据
that.setData({
userInfo:userInfo
})
})
},
tapName: function(event){
console.log(event)
}
})

@ -0,0 +1,3 @@
{
"navigationBarTitleText": "问题"
}

@ -0,0 +1,225 @@
<!--question.wxml-->
<view class="container">
<view class="question-wrp">
<view class="question-item">
<view class="que-tag">
<text class="tag">阅读</text>
<text class="tag">电子书</text>
<text class="tag">Kindle</text>
<text class="tag">书籍</text>
<text class="tag">文学</text>
</view>
<view class="que-title">
选择 Kindle 而不是纸质书的原因是什么?
</view>
<view class="que-content">
WEB前端*不靠谱天气预报员*想做代码小仙女
</view>
<view class="que-follow">
<view class="left">
<view class="watch">
<image src="../../images/eye.png"></image>
<text>3316</text>
</view>
<view class="comment">
<image src="../../images/comment2.png"></image>
<text>27</text>
</view>
</view>
<view class="right">
关注
</view>
</view>
</view>
<view class="que-operate flex-wrp">
<view class="invite flex-item">
<image src="../../images/invite.png"></image>
<text>邀请回答</text>
</view>
<view class="write flex-item">
<image src="../../images/write.png"></image>
<text>写回答</text>
</view>
</view>
</view>
<view class="answer-feed">
<view bindtap="bindItemTap" class="feed-item">
<view class="feed-source">
<a class="" bindTap="">
<view class="avatar">
<image src="../../images/icon1.jpeg"></image>
</view>
<text>Rebecca</text>
</a>
</view>
<view class="feed-content">
<view class="answer-body">
<view>
<text class="answer-txt">难道不明白纸质书更贵啊!!! 若觉得kindle更贵我觉得要么阅读量太少那确实没有买kindle的必要。要么买的都是盗版的纸质书我不清楚不加以评论。。。 另外用kindle看小说的... </text>
</view>
<view class="answer-actions">
<view class="like dot">
<a>3.9K 赞同 </a>
</view>
<view class="comments dot">
<a>254 评论 </a>
</view>
<view class="time">
<a>2 个月前</a>
</view>
</view>
</view>
</view>
</view>
<view bindtap="bindItemTap" class="feed-item">
<view class="feed-source">
<a class="" bindTap="">
<view class="avatar">
<image src="../../images/icon1.jpeg"></image>
</view>
<text>Rebecca</text>
</a>
</view>
<view class="feed-content">
<view class="answer-body">
<view>
<text class="answer-txt">难道不明白纸质书更贵啊!!! 若觉得kindle更贵我觉得要么阅读量太少那确实没有买kindle的必要。要么买的都是盗版的纸质书我不清楚不加以评论。。。 另外用kindle看小说的... </text>
</view>
<view class="answer-actions">
<view class="like dot">
<a>3.9K 赞同 </a>
</view>
<view class="comments dot">
<a>254 评论 </a>
</view>
<view class="time">
<a>2 个月前</a>
</view>
</view>
</view>
</view>
</view>
<view bindtap="bindItemTap" class="feed-item">
<view class="feed-source">
<a class="" bindTap="">
<view class="avatar">
<image src="../../images/icon1.jpeg"></image>
</view>
<text>Rebecca</text>
</a>
</view>
<view class="feed-content">
<view class="answer-body">
<view>
<text class="answer-txt">难道不明白纸质书更贵啊!!! 若觉得kindle更贵我觉得要么阅读量太少那确实没有买kindle的必要。要么买的都是盗版的纸质书我不清楚不加以评论。。。 另外用kindle看小说的... </text>
</view>
<view class="answer-actions">
<view class="like dot">
<a>3.9K 赞同 </a>
</view>
<view class="comments dot">
<a>254 评论 </a>
</view>
<view class="time">
<a>2 个月前</a>
</view>
</view>
</view>
</view>
</view>
<view bindtap="bindItemTap" class="feed-item">
<view class="feed-source">
<a class="" bindTap="">
<view class="avatar">
<image src="../../images/icon1.jpeg"></image>
</view>
<text>Rebecca</text>
</a>
</view>
<view class="feed-content">
<view class="answer-body">
<view>
<text class="answer-txt">难道不明白纸质书更贵啊!!! 若觉得kindle更贵我觉得要么阅读量太少那确实没有买kindle的必要。要么买的都是盗版的纸质书我不清楚不加以评论。。。 另外用kindle看小说的... </text>
</view>
<view class="answer-actions">
<view class="like dot">
<a>3.9K 赞同 </a>
</view>
<view class="comments dot">
<a>254 评论 </a>
</view>
<view class="time">
<a>2 个月前</a>
</view>
</view>
</view>
</view>
</view>
<view bindtap="bindItemTap" class="feed-item">
<view class="feed-source">
<a class="" bindTap="">
<view class="avatar">
<image src="../../images/icon1.jpeg"></image>
</view>
<text>Rebecca</text>
</a>
</view>
<view class="feed-content">
<view class="answer-body">
<view>
<text class="answer-txt">难道不明白纸质书更贵啊!!! 若觉得kindle更贵我觉得要么阅读量太少那确实没有买kindle的必要。要么买的都是盗版的纸质书我不清楚不加以评论。。。 另外用kindle看小说的... </text>
</view>
<view class="answer-actions">
<view class="like dot">
<a>3.9K 赞同 </a>
</view>
<view class="comments dot">
<a>254 评论 </a>
</view>
<view class="time">
<a>2 个月前</a>
</view>
</view>
</view>
</view>
</view>
<view bindtap="bindItemTap" class="feed-item">
<view class="feed-source">
<a class="" bindTap="">
<view class="avatar">
<image src="../../images/icon1.jpeg"></image>
</view>
<text>Rebecca</text>
</a>
</view>
<view class="feed-content">
<view class="answer-body">
<view>
<text class="answer-txt">难道不明白纸质书更贵啊!!! 若觉得kindle更贵我觉得要么阅读量太少那确实没有买kindle的必要。要么买的都是盗版的纸质书我不清楚不加以评论。。。 另外用kindle看小说的... </text>
</view>
<view class="answer-actions">
<view class="like dot">
<a>3.9K 赞同 </a>
</view>
<view class="comments dot">
<a>254 评论 </a>
</view>
<view class="time">
<a>2 个月前</a>
</view>
</view>
</view>
</view>
</view>
</view>
</view>

@ -0,0 +1,180 @@
/**answer.wxss**/
.answer-feed {
padding: 0;
font-size: 14rpx;
background: #F0F4F3;
color: #000;
}
.question-wrp{
border-radius: 3px;
box-shadow: 0 1px 2px #bebebe;
}
.question-item{
width: 710rpx;
padding: 40rpx 20rpx 10rpx;
background: #fff;
}
.question-item .que-tag{
}
.question-item .que-tag .tag{
height: 28rpx;
padding: 15rpx 20rpx;
border-radius: 28rpx;
margin: 0 10rpx;
background: #EEF5F8;
color: #2186E0;
font-size: 28rpx;
vertical-align: middle;
}
.question-item .que-title{
padding: 40rpx 20rpx 30rpx;
font-size: 38rpx;
}
.question-item .que-content{
padding: 0 20rpx;
font-size: 26rpx;
}
.question-item .que-follow{
margin: 20rpx;
height: 68rpx;
}
.question-item .que-follow view{
display: inline-block;
margin: 0 40rpx 0 0;
}
.question-item .que-follow image{
width: 50rpx;
height: 50rpx;
margin: 0 10rpx 0 0;
vertical-align: middle;
}
.question-item .que-follow .left{
float: left;
padding: 10rpx 0;
}
.question-item .que-follow .left text{
color: #AFAFAF;
height: 50rpx;
vertical-align: middle;
padding: 18rpx 0;
font-size: 24rpx;
}
.question-item .que-follow .right{
float: right;
padding: 20rpx 55rpx;
color: #ffffff;
background: #52C980;
border-radius: 3px;
font-size: 26rpx;
margin: 0;
}
.que-operate{
width: 750rpx;
border-top: solid 1px #ebebeb;
border-bottom: solid 1px #ebebeb;
color: #889091;
vertical-align: middle;
background: #ffffff;
}
.que-operate .flex-item{
padding: 20rpx 0;
font-size: 26rpx;
}
.que-operate .invite{
border-right: solid 2px #ebebeb;
}
.que-operate image{
width: 50rpx;
height: 50rpx;
vertical-align: middle;
margin: 0 20rpx 0 0;
}
/*.answer-feed .feed-item{*/
/*width: 690rpx;*/
/*padding: 30rpx 30rpx 20rpx;*/
/*margin: 7rpx 0 6rpx 0;*/
/*background: #ffffff;*/
/*border-top: 1px solid #eee;*/
/*border-bottom: 1px solid #eee;*/
/*box-shadow: 0 2px 5px #eeeeee;*/
/*}*/
/*.answer-feed .feed-item .feed-source{*/
/*width: 690rpx;*/
/*left: 0;*/
/*height: 50rpx;*/
/*}*/
/*.answer-feed .feed-item .feed-source .avatar{*/
/*position: relative;*/
/*display: inline-block;*/
/*}*/
/*.answer-feed .feed-item .feed-source a{*/
/*display: inline-block;*/
/*height: 40rpx;*/
/*}*/
/*.answer-feed .feed-item .feed-source .avatar image{*/
/*/!*position: absolute;*!/*/
/*display: inline-block;*/
/*width: 45rpx;*/
/*height: 45rpx;*/
/*border-radius: 45rpx;*/
/*top: 10rpx;*/
/*vertical-align: middle;*/
/*}*/
/*.answer-feed .feed-item .feed-source text{*/
/*/!*position: absolute;*!/*/
/*display: inline-block;*/
/*height: 40rpx;*/
/*line-height: 40rpx;*/
/*vertical-align: middle;*/
/*margin: 0 0 0 15rpx;*/
/*color: #a0acac;*/
/*font-size: 16rpx;*/
/*}*/
/*.answer-feed .feed-item .feed-source .item-more{*/
/*display: inline-block;*/
/*width: 40rpx;*/
/*height: 45rpx;*/
/*float: right;*/
/*}*/
/*.answer-feed .feed-item .feed-content{*/
/*padding: 10rpx 0 0 0;*/
/*}*/
/*.answer-feed .feed-item .feed-content .question text{*/
/*font-size: 28rpx;*/
/*font-weight: 600px;*/
/*line-height: 40rpx;*/
/*text-space: 5rpx;*/
/*}*/
.answer-feed .feed-item .feed-content .answer-body{
padding: 0;
/*height: 10rpx;*/
font-size: 24rpx;
line-height: 28rpx;
color: #5b5b5b;
}
/*.answer-feed .feed-item .feed-content .answer-actions{*/
/*width: 690rpx;*/
/*padding: 10rpx 0 0;*/
/*color: #a0acac;*/
/*}*/
/*.answer-feed .feed-item .feed-content .answer-actions view{*/
/*display: inline-block;*/
/*vertical-align: text-bottom;*/
/*padding: 0 10rpx 0 0;*/
/*font-size: 24rpx;*/
/*}*/
/*.answer-feed .feed-item .feed-content .answer-actions .dot ::after{*/
/*content: "•";*/
/*}*/

@ -0,0 +1,33 @@
// pages/searchShow/searchShow.js
Page({
/**
* 组件的初始数据
*/
data: {
},
onLoad: function(options) {
console.log("1")
console.log(JSON.parse(options.re),"1")
let re = JSON.parse(options.re);
let that = this
that.setData({
re: re
})
console.log(re)
},
bindItemTap: function(event) {
/*wx.navigateTo({
url: '../answer/answer'
})*/
var aid=event.currentTarget.dataset.aid;
console.log(aid)
//console.log("1")
wx.navigateTo({
url: '../answer/answer?aid='+aid,//要跳转到的页面路径
})
}
})

@ -0,0 +1,45 @@
<!--pages/searchShow/searchShow.wxml-->
<scroll-view scroll-y="true" class="container" bindscrolltoupper="upper" upper-threshold="10" lower-threshold="5" bindscrolltolower="lower" scroll-into-view="{{toView}}" scroll-top="{{scrollTop}}">
<!-- 搜索结果展示 -->
<block wx:for="{{re}}" wx:for-index="idx" wx:for-item="item" data-idx="{{idx}}">
<view class="feed-item">
<view class="feed-source">
<a class="">
<view class="avatar">
<image src="{{item.feed_source_img}}"></image>
<!--<open-data type="userAvatarUrl"></open-data>-->
</view>
<text>{{item.feed_source_name}}</text>
<!-- <open-data type="userNickName"></open-data>-->
</a>
<image class="item-more" mode="aspectFit" src="../../images/more.png"></image>
</view>
<view class="feed-content">
<view class="question" bindtap="bindItemTap" data-aid="{{item._id}}">
<a class="question-link">
<text>{{item.title}}</text>
</a>
</view>
<view class="answer-body">
<view >
<text class="answer-txt" bindtap="bindItemTap" data-aid="{{item._id}}">{{item.content}}</text>
</view>
<view class="answer-actions" bindtap="bindItemTap">
<view class="like dot">
<a>{{item.good_num}} 赞同 </a>
</view>
<view class="follow-it">
<text decode="{{true}}">&emsp;&emsp;</text>
</view>
<view class="comments dot">
<a>{{item.comment_num}} 评论 </a>
</view>
</view>
</view>
</view>
</view>
</block>
</scroll-view>

@ -0,0 +1,10 @@
.answer-txt{
width:700rpx;
height:49rpx;
font-size:25rpx;
overflow:hidden;
text-overflow: ellipsis;
display:-webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}

@ -8,10 +8,18 @@ Page({
data: {
title: '',
content: '',
question_id:'',
feed_source_img:'',
feed_source_name:'',
tempFilePaths: [],
nowCount:0,//当前的图片上传个数
sort:['问答专区','失物招领'],
index:0,
nickName:"",
avatarUrl:"",
feed:[],
pinglun:[],
comment_num:0,
good_num:0
},
bindPickerChange:function(e){
console.log(e)
@ -100,6 +108,7 @@ Page({
let count=0;
let that = this;
let url = [];
let pl=[];
console.log(e);
let title = e.detail.value.name;
let content = e.detail.value.content;
@ -120,15 +129,19 @@ Page({
wx.showLoading({
title: '发布中',
})
if(that.data.nowCount==0){
wx.cloud.callFunction({
/*wx.cloud.callFunction({
name:'love_upload',
data:{
title:title,
content:content,
openid:that.data.openid,
url:[],
type:parseInt(that.data.index)+1
},success:function(e){
console.log(e);
wx.hideLoading({
@ -160,11 +173,42 @@ Page({
})
console.log(e);
}
})*/
let a=wx.getStorageSync ("nickName")
let b=wx.getStorageSync ("avatarUrl")
wx.cloud.database().collection('tiezi').add({
data: {
title:title,
content:content,
openid:that.data.openid,
url:url,
createTime: wx.cloud.database().serverDate(),
feed_source_img:b,
feed_source_name:a,
pinglun:pl,
comment_num:0,
good_num:0
}
})
wx.hideLoading({
success: (res) => {
that.setData({
value1:'',
value2:'',
tempFilePaths:[],
nowCount:0
})
wx.showToast({
title: '发布成功',
})}})
}else{
//将所有的内容上传到云端去
for(i=0;i<that.data.nowCount;i++){
console.log(1);
let extName = that.data.tempFilePaths[i].split(".").pop();
let cloudPath = "love/" + new Date().getTime() + "." + extName;
wx.cloud.uploadFile({
@ -177,6 +221,7 @@ Page({
console.log(i,url);
if(count==that.data.nowCount){
console.log(url);
/*
wx.cloud.callFunction({
name:'love_upload',
data:{
@ -196,6 +241,7 @@ Page({
tempFilePaths:[],
nowCount:0
})
wx.showToast({
title: '发布成功',
})
@ -217,14 +263,48 @@ Page({
})
console.log(e);
}
})*/
let a=wx.getStorageSync ("nickName")
let b=wx.getStorageSync ("avatarUrl")
let pl=[];
wx.cloud.database().collection('tiezi').add({
data: {
title:title,
content:content,
openid:that.data.openid,
url:url,
createTime: wx.cloud.database().serverDate(),
feed_source_img:b,
feed_source_name:a,
pinglun:pl,
comment_num:0,
good_num:0
}
})
wx.hideLoading({
success: (res) => {
that.setData({
value1:'',
value2:'',
tempFilePaths:[],
nowCount:0
})
wx.showToast({
title: '发布成功',
})}})
}
},fail:res=>{
console.log(res);
}
})
}
}
wx.switchTab({
url: '../index/index',
})
},
@ -257,28 +337,7 @@ Page({
* 生命周期函数--监听页面显示
*/
onShow: function () {
let openid = wx.getStorageSync('openid');
let userinfo = wx.getStorageSync('userinfo');
console.log(openid);
if(openid=="" || openid==null){
wx.showToast({
title: '请先登陆',
duration:1000,
icon:"none",
success:function(e){
setTimeout(function() {
wx.switchTab({
url: '/pages/me/me',
})
}, 1000);
}
})
}else{
this.setData({
openid:openid,
userinfo:userinfo
})
}
},
/**
@ -314,5 +373,40 @@ Page({
*/
onShareAppMessage: function () {
},
onAdd_s: function () {
wx.cloud.init({
env: 'cloud1-8g5wmepxce8a3b8a'
});
const db = wx.cloud.database()
db.collection('tiezi').add({
data: {
title:title,
content:content,
openid:that.data.openid,
url:[],
},
success: res => {
// 在返回结果中会包含新创建的记录的 _id
this.setData({
counterId: res._id,
count: 1
})
wx.showToast({
title: '成功扔进树洞~',
})
console.log('[数据库] [留言] 成功,记录 _id: ', res._id)
},
fail: err => {
wx.showToast({
icon: 'none',
title: '种种原因树洞拒绝了~'
})
console.error('[数据库] [新增记录] 失败:', err)
}
})
}
})

@ -2,12 +2,7 @@
<!--上传图片演示-->
<form bindsubmit="submit">
<!--帖子分类1-->
<picker bindchange="bindPickerChange" value="{{index}}" range="{{sort}}">
<view class="picker">
选择专区:{{sort[index]}}
</view>
</picker>
<!--帖子的标题-->
<view class="title">
@ -25,7 +20,7 @@
</view>
<view class="imgs" wx:if="{{nowCount<3}}">
<view class="images" bindtap="chooseImage">
<image src='../../image/upload.png' mode='widthFix' />
<image src='../../images/upload.png' mode='widthFix' />
</view>
</view>
</view>

@ -0,0 +1,30 @@
{
"compileType": "miniprogram",
"setting": {
"coverView": true,
"es6": true,
"postcss": true,
"minified": true,
"enhance": true,
"showShadowRootInWxmlPanel": true,
"packNpmRelationList": [],
"ignoreDevUnusedFiles": false,
"ignoreUploadUnusedFiles": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
},
"libVersion": "2.27.0",
"packOptions": {
"ignore": [],
"include": []
},
"appid": "wxcc745ea897810e52"
}

@ -1,6 +1,6 @@
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "%E8%AE%BA%E5%9D%9B",
"projectname": "lt2",
"setting": {
"compileHotReLoad": true
}

@ -0,0 +1,67 @@
function formatTime(date) {
var year = date.getFullYear()
var month = date.getMonth() + 1
var day = date.getDate()
var hour = date.getHours()
var minute = date.getMinutes()
var second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
function formatNumber(n) {
n = n.toString()
return n[1] ? n : '0' + n
}
module.exports = {
formatTime: formatTime
};
/*
var index = require('../data/data_index.js')
var index_next = require('../data/data_index_next.js')
function getData(url){
return new Promise(function(resolve, reject){
wx.request({
url: url,
data: {},
header: {
//'Content-Type': 'application/json'
},
success: function(res) {
console.log("success")
resolve(res)
},
fail: function (res) {
reject(res)
console.log("failed")
}
})
})
}
function getData2(){
return index.index;
}
function getNext(){
return index_next.next;
}
module.exports.getData = getData;
module.exports.getData2 = getData2;
module.exports.getNext = getNext;
module.exports.getDiscovery = getDiscovery;
module.exports.discoveryNext = discoveryNext;
*/

@ -1,160 +0,0 @@
module.exports = {
env: {
browser: true,
commonjs: true,
es6: true,
},
parserOptions: {
ecmaVersion: 2020,
// ECMAScript modules 模式
sourceType: 'module',
},
extends: ['plugin:prettier/recommended', 'prettier'],
globals: {
wx: true,
App: true,
Page: true,
Component: true,
getApp: true,
getCurrentPages: true,
Behavior: true,
global: true,
__wxConfig: true,
},
ignorePatterns: ['*.wxs'],
rules: {
'prettier/prettier': 'warn',
'no-undef': 'off',
camelcase: ['error', { ignoreDestructuring: true }],
'class-name-casing': 'off',
'no-console': ['warn', { allow: ['warn', 'error'] }],
'no-debugger': 'error',
'no-unused-expressions': [
'error',
{ allowShortCircuit: true, allowTernary: true },
],
'no-empty-interface': 'off',
'no-use-before-define': ['error', { functions: false }],
'no-useless-constructor': 'error',
'prefer-const': 'error',
'prefer-destructuring': [
'error',
{
AssignmentExpression: {
array: false,
object: false,
},
VariableDeclarator: {
array: false,
object: true,
},
},
{
enforceForRenamedProperties: false,
},
],
'no-const-assign': 'error',
'no-new-object': 'error',
'no-prototype-builtins': 'error',
'no-array-constructor': 'error',
'array-callback-return': 'warn',
'prefer-template': 'error',
'no-useless-escape': 'error',
'wrap-iife': ['error', 'outside'],
'space-before-function-paren': [
'warn',
{
anonymous: 'always',
named: 'never',
asyncArrow: 'always',
},
],
'no-param-reassign': [
'warn',
{
props: true,
ignorePropertyModificationsFor: [
'acc', // for reduce accumulators
'accumulator', // for reduce accumulators
'e', // for e.returnvalue
'ctx', // for Koa routing
'req', // for Express requests
'request', // for Express requests
'res', // for Express responses
'response', // for Express responses
'$scope', // for Angular 1 scopes
'staticContext', // for ReactRouter context
'state', // for Vuex
],
},
],
'no-confusing-arrow': 'warn',
'no-dupe-class-members': 'error',
'no-iterator': 'warn',
'dot-notation': 'warn',
'one-var': ['warn', 'never'],
'no-multi-assign': 'error',
'no-unused-vars': [
'error',
{
args: 'after-used',
ignoreRestSiblings: true,
argsIgnorePattern: '^_.+',
varsIgnorePattern: '^_.+',
},
],
eqeqeq: ['warn', 'always'],
'no-case-declarations': 'error',
'no-nested-ternary': 'warn',
'no-unneeded-ternary': 'warn',
'no-mixed-operators': [
'error',
{
groups: [
['%', '**'],
['%', '+'],
['%', '-'],
['%', '*'],
['%', '/'],
['&', '|', '<<', '>>', '>>>'],
['==', '!=', '===', '!=='],
['&&', '||'],
],
allowSamePrecedence: false,
},
],
'no-else-return': [
'warn',
{
allowElseIf: false,
},
],
'no-new-wrappers': 'warn',
indent: [
'warn',
2,
{
SwitchCase: 1,
VariableDeclarator: 1,
outerIIFEBody: 1,
FunctionDeclaration: {
parameters: 1,
body: 1,
},
FunctionExpression: {
parameters: 1,
body: 1,
},
CallExpression: {
arguments: 1,
},
ArrayExpression: 1,
ObjectExpression: 1,
ImportDeclaration: 1,
flatTernaryExpressions: false,
ignoreComments: false,
},
],
'linebreak-style': ['warn', 'unix'],
},
};

@ -1,15 +0,0 @@
node_modules/
yarn-error.log
miniprogram/
miniprogram_npm/
miniprogram_dist/
.DS_Store
$node_modules/
.history/
**/dist
components/**/*.lock
components/**/package-lock.json
package-lock.json
yarn.lock
project.private.config.json
.eslintcache

@ -1,9 +0,0 @@
# 去除注释可以使用代理进行安装
# proxy=http://127.0.0.1:1080
# https_proxy=http://127.0.0.1:1080
# 去除注释可以使用淘宝源
# registry=https://registry.npm.taobao.org
# 去除注释可以使用腾讯源
#registry=http://mirrors.tencent.com/npm/

@ -1,3 +0,0 @@
miniprogram_npm
package.json
project.config.json

@ -1,11 +0,0 @@
{
"useTabs": false,
"printWidth": 80,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "all",
"jsxBracketSameLine": false,
"noSemi": true,
"rcVerbose": true,
"endOfLine": "auto"
}

@ -1,40 +0,0 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"eslint.enable": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.tslint": true,
"source.fixAll.eslint": true
},
"[javascript]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "HookyQR.beautify"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[wxss]": {
"editor.defaultFormatter": "HookyQR.beautify"
},
"wxmlConfig.onSaveFormat": true,
"wxmlConfig.format": {
"brace_style": "collapse",
"indent_inner_html": true,
"indent_scripts": "keep",
"indent_size": 2,
"indent_char": " ",
"unformatted": "['wxs']",
"disable_automatic_closing_labels": false,
"preserve_newlines": true,
"wrap_attributes": "force-expand-multiline",
"wrap_attributes_count": 4,
"wrap_attributes_indent_size": 2
},
"editor.tabSize": 2,
"[wxml]": {
"editor.defaultFormatter": "wechat.miniprogram.wxml-language-features"
},
"[css]": {
"editor.defaultFormatter": "HookyQR.beautify"
}
}

@ -1,9 +0,0 @@
MIT License
Copyright (c) 2021-present TDesign
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -1,133 +0,0 @@
<p align="center">
<a href="https://tdesign.tencent.com/" target="_blank">
<img alt="TDesign Logo" width="200" src="https://tdesign.gtimg.com/site/TDesign.png">
</a>
</p>
<p align="center">
<a href="https://img.shields.io/github/stars/Tencent/tdesign-miniprogram-starter-retail">
<img src="https://img.shields.io/github/stars/Tencent/tdesign-miniprogram-starter-retail" alt="License">
</a>
<a href="https://github.com/Tencent/tdesign-miniprogram-starter-retail/issues">
<img src="https://img.shields.io/github/issues/Tencent/tdesign-miniprogram-starter-retail" alt="License">
</a>
<a href="https://github.com/Tencent/tdesign-miniprogram-starter-retail/LICENSE">
<img src="https://img.shields.io/github/license/Tencent/tdesign-miniprogram-starter-retail" alt="License">
</a>
<a href="https://www.npmjs.com/package/tdesign-miniprogram">
<img src="https://img.shields.io/npm/v/tdesign-miniprogram.svg?sanitize=true" alt="Version">
</a>
<a href="https://www.npmjs.com/package/tdesign-miniprogram">
<img src="https://img.shields.io/npm/dw/tdesign-miniprogram" alt="Downloads">
</a>
</p>
# TDesign 零售行业模版示例小程序
TDesign 零售模版示例小程序采用 [TDesign 企业级设计体系小程序解决方案](https://tdesign.tencent.com/miniprogram/overview) 进行搭建,依赖 [TDesign 微信小程序组件库](https://github.com/Tencent/tdesign-miniprogram),涵盖完整的基本零售场景需求。
## :high_brightness: 预览
<p>请使用微信扫描以下二维码:</p>
<img src="https://we-retail-static-1300977798.cos.ap-guangzhou.myqcloud.com/retail-mp/common/qrcode.jpeg" width = "200" height = "200" alt="模版小程序二维码" align=center />
## :pushpin: 项目介绍
### 1. 业务介绍
零售行业模版小程序是个经典的单店版电商小程序,涵盖了电商的黄金链路流程,从商品->购物车->结算->订单等。小程序总共包含 28 个完整的页面,涵盖首页,商品详情页,个人中心,售后流程等基础页面。采用 mock 数据进行展示,提供了完整的零售商品展示、交易与售后流程。页面详情:
<img src="https://cdn-we-retail.ym.tencent.com/tsr/tdesign-starter-readmeV1.png" width = "650" height = "900" alt="模版小程序页面详情" align=center />
主要页面截图如下:
<p align="center">
<img alt="example-home" width="200" src="https://cdn-we-retail.ym.tencent.com/tsr/example/v1/home.png" />
<img alt="example-sort" width="200" src="https://cdn-we-retail.ym.tencent.com/tsr/example/v2/sort.png" />
<img alt="example-cart" width="200" src="https://cdn-we-retail.ym.tencent.com/tsr/example/v1/cart.png" />
<img alt="example-user-center" width="200" src="https://cdn-we-retail.ym.tencent.com/tsr/example/v1/user-center.png" />
<img alt="example-goods-detail" width="200" src="https://cdn-we-retail.ym.tencent.com/tsr/example/v1/goods-detail.png" />
<img alt="example-pay" width="200" src="https://cdn-we-retail.ym.tencent.com/tsr/example/v1/pay.png" />
<img alt="example-order" width="200" src="https://cdn-we-retail.ym.tencent.com/tsr/example/v1/order.png" />
<img alt="example-order-detail" width="200" src="https://cdn-we-retail.ym.tencent.com/tsr/example/v2/order.png" />
</p>
### 2. 项目构成
零售行业模版小程序采用基础的 JavaScript + WXSS + ESLint 进行构建,降低了使用门槛。
项目目录结构如下:
```
|-- tdesign-miniprogram-starter
|-- README.md
|-- app.js
|-- app.json
|-- app.wxss
|-- components // 公共组件库
|-- config // 基础配置
|-- custom-tab-bar // 自定义 tabbar
|-- model // mock 数据
|-- pages
| |-- cart // 购物车相关页面
| |-- coupon // 优惠券相关页面
| |-- goods // 商品相关页面
| |-- home // 首页
| |-- order // 订单售后相关页面
| |-- promotion-detail // 营销活动页面
| |-- usercenter // 个人中心及收货地址相关页面
|-- services // 请求接口
|-- style // 公共样式与iconfont
|-- utils // 工具库
```
### 3. 数据模拟
零售小程序采用真实的接口数据,模拟后端返回逻辑,在小程序展示完整的购物场景与购物体验逻辑。
### 4. 添加新页面
1. 在 `pages `目录下创建对应的页面文件夹
2. 在 `app.json` 文件中的 ` "pages"` 数组中加上页面路径
3. [可选] 在 `project.config.json` 文件的 `"miniprogram-list"` 下添加页面配置
## :hammer: 构建运行
1. `npm install`
2. 小程序开发工具中引入工程
3. 构建 npm
## :art: 代码风格控制
`eslint` `prettier`
## :iphone: 基础库版本
最低基础库版本`^2.6.5`
## :dart: 反馈&合作
本开源项目是由[腾讯云Mall团队](https://ym.qq.com/)核心贡献。项目也在[github](https://github.com/Tencent/tdesign-miniprogram-starter-retail)上做了开源有任何问题或者建议都欢迎在issue上留言反馈, 或者加入TD小程序开发者群进行反馈:star2::star2::star2:
<img src="https://cdn.qa.ym.qq.com/officical-site/assets/logo.png?auto=format&fit=max&w=384" width = "100" height = "30" alt="模版小程序页面详情" align=center />
[云Mall](https://ym.qq.com/)是基于微信小程序的电商SaaS产品致力于提供全面、可靠的小程序商城经营服务助力商家成功。支持标准化和定开类型商家入驻。合作洽谈可微信咨询联系`lixingdecai`。
<img src="https://we-retail-static-1300977798.cos.ap-guangzhou.myqcloud.com/retail-mp/common/wechat-group.jpg" width = "230" height = "290" alt="模版小程序页面详情" align=center />
## :link: TDesign 其他技术栈实现
- 移动端 小程序 实现:[mobile-miniprogram](https://github.com/Tencent/tdesign-miniprogram)
- 桌面端 Vue 2 实现:[web-vue](https://github.com/Tencent/tdesign-vue)
- 桌面端 Vue 3 实现:[web-vue-next](https://github.com/Tencent/tdesign-vue-next)
- 桌面端 React 实现:[web-react](https://github.com/Tencent/tdesign-react)
## :page_with_curl: 开源协议
TDesign 遵循 [MIT 协议](https://github.com/Tencent/tdesign-miniprogram-starter-retail/LICENSE)。

@ -1,8 +0,0 @@
import updateManager from './common/updateManager';
App({
onLaunch: function () {},
onShow: function () {
updateManager();
},
});

@ -1,77 +0,0 @@
{
"pages": [
"pages/home/home",
"pages/usercenter/index",
"pages/usercenter/person-info/index",
"pages/usercenter/address/list/index",
"pages/usercenter/address/edit/index",
"pages/goods/list/index",
"pages/goods/details/index",
"pages/goods/category/index",
"pages/goods/search/index",
"pages/goods/result/index",
"pages/cart/index",
"pages/order/order-confirm/index",
"pages/order/receipt/index",
"pages/order/pay-result/index",
"pages/order/order-list/index",
"pages/order/order-detail/index",
"pages/goods/comments/index",
"pages/order/apply-service/index",
"pages/order/after-service-list/index",
"pages/order/after-service-detail/index",
"pages/goods/comments/create/index",
"pages/coupon/coupon-list/index",
"pages/coupon/coupon-detail/index",
"pages/coupon/coupon-activity-goods/index",
"pages/promotion-detail/index",
"pages/order/fill-tracking-no/index",
"pages/order/delivery-detail/index",
"pages/order/invoice/index",
"pages/usercenter/name-edit/index",
"pages/preferchoice/preferchoice",
"pages/forum/forum",
"pages/turntable/turntable"
],
"tabBar": {
"custom": true,
"color": "#666666",
"selectedColor": "#FF5F15",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/home/home",
"text": "首页"
},
{
"pagePath": "pages/forum/forum",
"text": "论坛",
"iconPath": "/images/forum.png",
"selectedIconPath": "/images/forum.png"
},
{
"pagePath": "pages/cart/index",
"text": "购物车"
},
{
"pagePath": "pages/usercenter/index",
"text": "我的"
}
]
},
"lazyCodeLoading": "requiredComponents",
"usingComponents": {},
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#2B4B6B",
"navigationBarTitleText": "节时不节食",
"navigationBarTextStyle": "white"
},
"sitemapLocation": "sitemap.json",
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于小程序位置接口的效果展示"
}
}
}

@ -1,3 +0,0 @@
@import 'style/iconfont.wxss';
@import 'style/theme.wxss';

@ -1,29 +0,0 @@
export default () => {
if (!wx.canIUse('getUpdateManager')) {
return;
}
const updateManager = wx.getUpdateManager();
updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
console.log('版本信息', res);
});
updateManager.onUpdateReady(function () {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
},
});
});
updateManager.onUpdateFailed(function () {
// 新版本下载失败
});
};

@ -1,36 +0,0 @@
Component({
externalClasses: ['wr-class'],
options: {
multipleSlots: true,
},
properties: {
show: {
type: Boolean,
observer(show) {
this.setData({ visible: show });
},
},
closeBtn: {
type: Boolean,
value: false,
},
},
data: { visible: false },
methods: {
reset() {
this.triggerEvent('reset');
},
confirm() {
this.triggerEvent('confirm');
},
close() {
this.triggerEvent('showFilterPopupClose');
this.setData({ visible: false });
},
},
});

@ -1,6 +0,0 @@
{
"component": true,
"usingComponents": {
"t-popup": "tdesign-miniprogram/popup/popup"
}
}

@ -1,18 +0,0 @@
<t-popup
visible="{{visible}}"
placement="right"
bind:visible-change="close"
data-index="5"
close-btn="{{closeBtn}}"
>
<view class="content">
<slot name="filterSlot" />
<view class="filter-btns-wrap">
<view class="filter-btn btn-reset" bind:tap="reset">重置</view>
<view class="filter-btn btn-confirm" bind:tap="confirm" data-index="5">
确定
</view>
</view>
</view>
</t-popup>

@ -1,39 +0,0 @@
.content .filter-btns-wrap {
width: 100%;
position: absolute;
bottom: calc(20rpx + env(safe-area-inset-bottom));
display: flex;
flex-direction: row;
border-radius: 10rpx 0 0 10rpx;
padding: 16rpx 32rpx;
border-top: 1rpx solid #e5e5e5;
box-sizing: border-box;
}
.filter-btn {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-size: 28rpx;
font-weight: 500;
height: 80rpx;
}
.btn-reset {
color: #fa4126;
background: rgba(255, 255, 255, 1);
position: relative;
border: 1rpx solid #fa4126;
border-radius: 84rpx 0 0 84rpx;
}
.btn-confirm {
border-radius: 0 84rpx 84rpx 0;
border: 1rpx solid #fa4126;
}
.btn-confirm {
color: #fff;
background: #fa4126;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save