首先要感谢@Jianbo提供的开源代码。我的MiniBBS就是在此基础上开发完成的。
我把这个项目叫做MiniBBS是因为它还有很大的改进空间,我目前只实现了帖子预览和发帖功能。如果继续开发下去,应该还可以实现帖子上传图片附件,针对帖子的评论等更高级的功能。那样就更像一个完善的社交圈子了。
我做的这个项目是一个招聘信息发布中心,招聘信息传播的特点是对回评基本没有要求,对图片也没有什么要求,只要信息更新快速,能够让更多的人看到即可。所以,做出来的效果如下图所示:

我省略了帖子详情,所以单个帖子是不可以点开浏览详情的。用户看到的就是信息流(可以按条件加塞广告哦)。右上角悬浮按钮是发帖,采用的是表单提交方式实现帖子发布的功能。
好了,我们来看看完成这个项目我们需要具备什么条件:
- 需要安装json-api插件,我们用这个插件实现了wordpress评论的功能。为什么不用wordpress原生的评论API呢?因为貌似最近一段时间,安卓用户采用最初的方式在小程序里对wordpress文章进行评论总是发生评论无法创建的问题。安装好这个插件之后,打开插件设置界面,在插件提供的api地址框中填写api这三个字母,设置好网站api调用的网址。提交评论的api地址格式应该是这样的: https://www.domain.com/api/respond/submit_comment/?post_id=id
- MiniBBS是在wordpress评论基础上创建的,我们需要挑选一篇文章出来,将这篇文章的评论模拟成帖子。@Jianbo在新版的开源项目里,对wordpress的评论做了升级,要求获取用户的openid,在这里,我还是保留了最初的提交方式,不要求用户提供openid,简化评论步骤。
- 在项目里建立两个页面 pages/quanzi/quanzi 和 pages/fatie/fatie,到app.jspon里,注册这两个页面,然后我建议分配一个tab按钮给pages/quanzi/quanzi,方便调试。
- 在utils/api.js里新增以下代码: 顶部加上定义:
var JSON_API = 'https://www.domain.com/api/';
并在代码中添加以下几个函数:
//获取特定文章的评论 getCommentsSpecial: function (obj) { return HOST_URI + 'comments?parent=0&per_page=100&orderby=date&order=desc&post=' + '1234' + '&page=' + obj.page + '&per_page=10' }, //获取特定文章下评论的回复 getChildrenCommentsSpecial: function (obj) { var url= HOST_URI + 'comments?parent_exclude=0&per_page=100&orderby=date&order=desc&post=' + '1234' return url; }, //新增一个发表评论的函数 postCommentSpecial: function (id) { return JSON_API + 'respond/submit_comment/?post_id=' + id },代码的第3行和第7行,设定文章ID为1234,这个请根据自己的实际情况设置。你可以到wordpress后台发一篇空内容或者随便敲点什么文字的文章(因为等一下我们不需要在前端展示文章本身的内容。),找到它的ID,然后填入这段代码里。好了,api.js就改到这里。
- 将以下代码复制粘贴到pages/quanzi/quanzi.js
- pages/quanzi/quanzi.wxml代码如下:
- 打开quanzi.json,在{}里加上一句
- 下面提供quanzi.wxss样式代码:
- 圈子(帖子列表)这个页面弄好了,现在,来到发帖界面,这其实就是一个表单,表单数据按照wordpress评论的json数据格式提供给fatie.js,再用wx.request的方法post到数据库里,然后在再用quanzi.js里的wx.request的方法get出来,输出到quanzi.wxml展示,嗯,原理就是这么个意思。
- 下面是fatie.wxml,这个简单,做一个表单就行了:
- fatie.wxss样式表如下:
- fatie.json无需设置,留空即可。
var Api = require('../../utils/api.js');
var util = require('../../utils/util.js');
var WxParse = require('../../wxParse/wxParse.js');
var app = getApp()
Page({
data: {
detail: {},
commentsList:{},
ChildrenCommentsList: [],
commentCount:'',
detailDate:'',
commentValue:'',
wxParseData:[],
display:'none',
isLastPage:false,
page: 1,
isLastPage:false,
showerror: "none",
showallDisplay: "block",
postID:null,
scrollHeight: 0,
link: '',
isGetUserInfo:false,
dialog: {
title: '',
content: '',
hidden: true
},
content:'',
userInfo: {}, // 存放用户信息
page:1, // 页码值
animationData: {},
animationData1: {}, // 发布按钮下滑动画
animationData2: {}, // 位置按钮下滑动画
},
onLoad: function (e,options) {
this.fetchDetailData(options);
var self = this;
wx.getSystemInfo({
success: function (res) {
self.setData({
scrollHeight: res.windowHeight,
});
}
});
wx.showToast({
title: '加载中',
icon: 'loading',
duration: 6000
});
var dataTop = {'detail':{'scrollTop':0}}
//获取用户信息
app.getUserInfo(function (userInfo) {
self.setData({
userInfo: userInfo,
isGetUserInfo:true
})
});
},
onShareAppMessage: function () {
return {
title: this.data.detail.title.rendered,
path: 'pages/quanzi/quanzi',
success: function (res) {
// 转发成功
},
fail: function (res) {
// 转发失败
}
}
},
//获取文章内容
fetchDetailData: function (id) {
var self = this;
wx.request({
url: Api.getPostByID(1234, { mdrender: false }),
success: function (response) {
if (response.data.total_comments != null && response.data.total_comments != '') {
self.setData({
commentCount: "有" + response.data.total_comments + "个话题"
});
}
self.setData({
detail: response.data,
postID: id,
link: response.data.link,
detailDate: util.cutstr(response.data.date, 10, 1),
wxParseData: WxParse.wxParse('article', 'html', response.data.content.rendered, self, 5),
display: 'block'
});
wx.setNavigationBarTitle({
title: response.data.title.rendered,
success: function (res) {
// success
}
});
// 调用API从本地缓存中获取阅读记录并记录
var logs = wx.getStorageSync('readLogs') || [];
// 过滤重复值
if (logs.length > 0) {
logs = logs.filter(function (log) {
return log[0] !== id;
});
}
// 如果超过指定数量
if (logs.length > 19) {
logs.pop();//去除最后一个
}
logs.unshift([id, response.data.title.rendered]);
wx.setStorageSync('readLogs', logs);
//end
self.fetchCommentData(self.data);
}
});
},
//给a标签添加跳转和复制链接事件
wxParseTagATap: function (e) {
var self = this;
var href = e.currentTarget.dataset.src;
console.log(href);
var domain = Api.getDomain();
//我们可以在这里进行一些路由处理
if (href.indexOf(domain) == -1) {
wx.setClipboardData({
data: href,
success: function (res) {
wx.getClipboardData({
success: function (res) {
wx.showToast({
title: '链接已复制',
//icon: 'success',
image: '../../images/link.png',
duration: 2000
})
}
})
}
})
}
else {
var slug = util.GetUrlFileName(href, domain);
if (slug == 'index') {
wx.switchTab({
url: '../index/index'
})
}
else {
wx.request({
url: Api.getPostBySlug(slug),
success: function (res) {
var postID = res.data[0].id;
var openLinkCount = wx.getStorageSync('openLinkCount') || 0;
if (openLinkCount > 4) {
wx.redirectTo({
url: '../detail/detail?id=' + postID
})
}
else {
wx.navigateTo({
url: '../detail/detail?id=' + postID
})
openLinkCount++;
wx.setStorageSync('openLinkCount', openLinkCount);
}
}
});
}
}
},
//获取评论
fetchCommentData: function (data) {
var self = this;
if (!data) data = {};
if (!data.page) data.page = 1;
if (data.page === 1) {
self.setData({
commentsList: []
});
};
wx.request({
url: Api.getCommentsSpecial(data),
success: function (response) {
if (response.data.length < 6) {
self.setData({
isLastPage: true
});
}
self.setData({
commentsList: self.data.commentsList.concat(response.data.map(function (item) {
var strSummary = util.removeHTML(item.content.rendered);
var strdate = item.date
item.summary = strSummary;
item.date = util.formatDateTime(strdate);
if (item.author_url.indexOf('wx.qlogo.cn') !=-1 )
{
if (item.author_url.indexOf('https') ==-1 )
{
item.author_url = item.author_url.replace("http", "https");
}
}
else
{
item.author_url ="../../images/gravatar.png";
}
return item;
}))
});
wx.showToast({
title: '加载中',
icon: 'loading',
mask: true,
duration: 1000
})
}
});
},
//底部刷新
loadMore: function (e) {
var self = this;
if (!self.data.isLastPage) {
self.setData({
page: self.data.page + 1
});
console.log('当前页' + self.data.page);
this.fetchCommentData(self.data);
}
else {
wx.showToast({
title: '没有更多内容',
mask: false,
duration: 1000
});
}
},
onPullDownRefresh:function(){ //下拉刷新
var self = this
self.fetchCommentData()
wx.showToast({
title: '刷新数据中',
icon: 'loading',
duration: 2000
})
self.setData({
page:1,
commentsList: []
})
wx.stopPullDownRefresh()
},
donghua: function(topNum) // 发帖按钮动画
{
var self = this
var animation = wx.createAnimation({
duration: 400,
timingFunction: 'linear',
delay:0,
})
var animation1 = wx.createAnimation({
duration: 400,
timingFunction: 'linear',
delay:0,
})
animation.opacity(0).translateY(topNum + 5).step()
animation1.opacity(0).translateY(topNum + 5).step()
self.setData({
animationData1:animation.export(),
animationData2:animation1.export()
})
setTimeout(function(){
animation.opacity(1).step()
animation1.opacity(1).step()
self.setData({
animationData1:animation.export(),
animationData2:animation1.export()
})
},1500)
},
bindAdd: function(){// 跳转发帖界面
var self = this
// 发帖
wx.showActionSheet({
itemList: ['发布'],
success: function(res)
{
if (!res.cancel)
{
console.log(res.tapIndex)
if(res.tapIndex == 0)
{
wx.redirectTo({
url: '../../pages/fatie/fatie'
})
}
}
}
})
},
})
代码的第92行,我直接设置了当前文章的ID为1234,与api.js里设置保持一致。代码实现了下拉刷新和点击尾部链接加载更多帖子的功能。
<import src="../../wxParse/wxParse.wxml" />
<view>
<!--右上角发布小图标-->
<view class="float-action" bindtap="bindAdd" style="opacity: {{ballOpacity}};bottom:{{ballBottom}}px;right:{{ballRight}}px;" style="display:{{floatDisplay}}">
<image src="../../images/add.png"></image>
</view>
<!--背景小图标-->
<view class="bg">
<image class="baseimg" src="../../images/bg.jpg" mode="scaleToFill"></image>
</view>
<!--背景图底部大头像-->
<view class="headimg">
<image class="baseimg" wx:if="{{userInfo['avatarUrl']}}" src="{{userInfo['avatarUrl']}}" mode="scaleToFill"></image>
</view>
<!--背景图底部昵称-->
<view class="nickname">
<text>{{userInfo['nickName']}}</text>
</view>
<!--占位行-->
<view class="lie"></view>
<view class="showerror" style="display:{{showerror}}">
<image src="../../images/cry80.png" style="height:100rpx;width:100rpx"></image>
<view class="errortext">
暂时无法访问网络,刷新重试...
</view>
</view>
<view style="display:{{showallDisplay}}">
<!--循环展示/Start-->
<view class="content" wx:key="id" wx:for="{{commentsList}}">
<!--头像-->
<view class="head">
<image class="baseimg" src="{{item.author_url}}" mode="scaleToFill"></image>
</view>
<!--昵称-->
<text class="wz">{{item.author_name}} </text>
<!--内容-->
<rich-text class="desc" nodes="{{item.content.rendered}}"></rich-text>
<!--发布时间-->
<text class="time">{{item.date}}</text>
</view>
</view>
<view style="display:{{floatDisplay}}">
<view class="more-comment" bindtap="loadMore" hidden="{{isLastPage}}">
点击加载更多信息...
</view>
<view class="no-more-comment" hidden="{{!isLastPage}}">无更多信息...</view>
</view>
<view class="copyright">
© www.domain.com
</view>
</view>
代码第39行,我用了微信原生的rich-text来解析发帖者提交的信息,并未采用wxParse,这样做简单些。待会儿在fatie.js里你会看到我直接把帖子内容固定了一段html语句,提交给quanzi.js的rich-text来解析。
"enablePullDownRefresh":true
让页面下拉刷新生效。
@import "../../wxParse/wxParse.wxss";
.box
{
/*border:2px solid #576b95;*/
/*height:100%;*/
}
.float-action {
position: fixed;
top: 70rpx;
right: 50rpx;
width: 70rpx;
height: 70rpx;
border-radius: 50%;
box-shadow: 2px 2px 10px #aaa;
z-index: 100;
/*background-color:transparent;*/
background-color:#04be02;
}
.float-action image{
width:320px;
height:240px;
display:inline;
}
.entry-summary image {
width: 100% !important;
}
.textNoEmpty {
color: red;
}
.gravatarImg {
margin-top: 4px;
border-radius: 50%;
opacity: 1;
transform: scale(1);
perspective-origin: top center;
transition: all ease-in-out 0.3s;
height: 48rpx;
width: 48rpx;
}
.baseimg
{
width:100%;
height:100%;
}
.oneImg
{
width:auto;
height:auto;
/*margin-left:100rpx;*/
overflow:hidden;
}
.images-image {
width: 150rpx;
height: 150rpx;
margin: 10rpx;
}
.bg
{
height: 400rpx;
/*background: red;*/
overflow:hidden;
}
.headimg
{
width: 150rpx;
height: 150rpx;
position:absolute;
border: 2px solid #fff;
margin-top: -100rpx;
margin-left: 570rpx;
overflow:hidden;
}
.nickname
{
width:400rpx;
text-align: right;
position:absolute;
color:#fff;
margin-top: -70rpx;
margin-left: 150rpx;
font-size:14pt;
font-weight:600;
/*border:1px solid red;*/
}
.lie
{
/*border: 1px solid #ccc;*/
margin-top: 100rpx;
flex-direction: column;
}
.content
{
border-bottom:1px solid #F5F5F5;
display:flex;
flex-direction: column;
padding-bottom:20rpx;
}
.head
{
width: 80rpx;
height: 80rpx;
/*background: darkcyan;*/
margin-top:20rpx;
margin-left:20rpx;
overflow:hidden;
}
.wz
{
margin-top:-80rpx;
margin-left:120rpx;
font-size:10pt;
color:#576b95;
}
.desc
{
margin-top:20rpx;
margin-left:120rpx;
margin-right:20rpx;
font-size:10pt;
}
.descrich{
margin-top:20rpx;
margin-left:120rpx;
margin-right:20rpx;
font-size:10pt;
}
.descrich image{
height: 150rpx;
width: 30%;
max-height: 150rpx;
max-width: 150rpx;
padding-right: 5px;
object-fit: cover;
}
.address
{
margin-top:20rpx;
height:30rpx;
font-size:10pt;
color:#576b95;
margin-left:120rpx;
margin-bottom:20rpx;
width:600rpx;
}
.time
{
margin-top:20rpx;
height:30rpx;
font-size:8pt;
color:#ccc;
margin-left:120rpx;
}
.dele
{
margin-top:20rpx;
width:80rpx;
height:30rpx;
font-size:10pt;
color:#576b95;
margin-top:-28rpx;
margin-left:270rpx;
}
.biao
{
width: 50rpx;
height:40rpx;
overflow:hidden;
margin-top:-32rpx;
margin-left:680rpx;
margin-bottom:20rpx;
}
.more-comment {
color: #04be02;
font-size: 30rpx;
line-height: 1.8rem;
margin-bottom: 50rpx;
text-align: center;
margin-top: 30rpx
}
.no-more-comment {
color: #757575;
font-size: 30rpx;
line-height: 1.8rem;
margin-bottom: 100rpx;
text-align: center;
margin-top: 30rpx
}
.copyright{
text-align: center;
margin: 30px;
font-size: 28rpx;
color: #ccc;
margin-bottom: 120rpx;
}
下面,上代码,fatie.js
var Api = require('../../utils/api.js');
var util = require('../../utils/util.js');
var WxParse = require('../../wxParse/wxParse.js');
var bmap = require('../../libs/bmap-wx/bmap-wx.min.js');
var wxMarkerData = []; //定位成功回调对象
var app = getApp()
Page({
data: {
ak: "", //填写从百度申请到的ak
markers: [],
longitude: '', //经度
latitude: '', //纬度
address: '', //地址
cityInfo: {}, //城市信息
date: '请点击选择服务时间',
pickerHidden: true,
chosen: '',
title: '文章内容',
detail: {},
commentsList:{},
commentCount:'',
detailDate:'',
wxParseData:[],
display:'none',
page: 1,
isLastPage:false,
postID:null,
scrollHeight: 0,
isGetUserInfo:false,
dialog: {
title: '',
content: '',
hidden: true
},
content:'',
userInfo:[],
imageObject:[],
imagescontents:[],
tempFilePaths:[],
},
//页面载入
onLoad: function (options) {
this.fetchDetailData(options.id);
var self = this;
wx.getSystemInfo({
success: function (res) {
//console.info(res.windowHeight);
self.setData({
scrollHeight: res.windowHeight,
});
}
});
//获取用户信息
app.getUserInfo(function (userInfo) {
//更新数据
self.setData({
userInfo: userInfo,
isGetUserInfo:true
})
});
/* 获取定位地理位置 */
// 新建bmap对象
var BMap = new bmap.BMapWX({
ak: self.data.ak
});
var fail = function (data) {
console.log(data);
};
var success = function (data) {
//返回数据内,已经包含经纬度
console.log(data);
//使用wxMarkerData获取数据
wxMarkerData = data.wxMarkerData;
//把所有数据放在初始化data内
self.setData({
markers: wxMarkerData,
latitude: wxMarkerData[0].latitude,
longitude: wxMarkerData[0].longitude,
address: wxMarkerData[0].address,
cityInfo: data.originalData.result.addressComponent
});
}
// 发起regeocoding检索请求
BMap.regeocoding({
fail: fail,
success: success
});
},
//获取页面内容
fetchDetailData: function () {
var self = this;
},
//底部刷新
loadMore: function (e) {
var self = this;
if (!self.data.isLastPage) {
self.setData({
page: self.data.page + 1
});
console.log('当前页' + self.data.page);
this.fetchCommentData(self.data);
}
else {
wx.showToast({
title: '没有更多内容',
mask: false,
duration: 1000
});
}
},
//发布话题
formSubmit: function (e) {
var address = this.data.address;
var self = this;
var name = self.data.userInfo.nickName;
var email = "test@test.com";
var comment = e.detail.value.inputComment;
var author_url = self.data.userInfo.avatarUrl;
var images = new Array();
//console.log(auth);
wx.hideLoading();
//var postID = e.detail.value.inputPostID;
if (comment.length===0 )
{
self.setData({
'dialog.hidden': false,
'dialog.title': '提示',
'dialog.content': '没有填写内容。'
});
}
else
{
//检测授权
//self.checkSettingStatu();
if (self.data.isGetUserInfo)
{
wx.request({
url: 'https://www.domain.com/api/respond/submit_comment/?post_id=1234',
method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
data: {
name: name,
email: email,
content: comment+'<blockquote>本信息发自:</blockquote><blockquote>@'+address+'</blockquote>',
url: author_url,
},
header: {
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
success: function (res) {
wx.showToast({
title: '已发布',
icon: 'success',
duration: 2000
});
wx.switchTab({
url: '../quanzi/quanzi'
});
},
fail: function (res) {
//console.log(res.data)
self.setData({
'dialog.hidden': false,
'dialog.title': '提示',
'dialog.content': '发布失败,' + res.data.message
});
}
});
}
}
},
// 检测授权状态
checkSettingStatu: function (cb) {
var that = this;
// 判断是否是第一次授权,非第一次授权且授权失败则进行提醒
wx.getSetting({
success: function success(res) {
console.log(res.authSetting);
var authSetting = res.authSetting;
if (util.isEmptyObject(authSetting)) {
console.log('首次授权');
} else {
console.log('不是第一次授权', authSetting);
// 没有授权的提醒
if (authSetting['scope.userInfo'] === false) {
wx.showModal({
title: '用户未授权',
content: '如需正常使用评论的功能,请授权管理中选中“用户信息”,然后点按确定后再次提交评论。',
showCancel: false,
success: function (res) {
if (res.confirm) {
console.log('用户点击确定')
wx.openSetting({
success: function success(res) {
console.log('openSetting success', res.authSetting);
var as = res.authSetting;
for (var i in as) {
if(as[i])
{
//获取用户信息
app.getUserInfo(function (userInfo) {
//更新数据
that.setData({
userInfo: userInfo,
isGetUserInfo: true
})
});
}
}
}
});
}
}
})
}
}
}
});
},
confirm: function () {
this.setData({
'dialog.hidden': true,
'dialog.title': '',
'dialog.content': ''
})
},
modalChange: function(e) {
this.setData({
modalHidden: true
})
}
})
关于调用百度地图API进行地址定位的js代码点击这里下载:http://lbsyun.baidu.com/index.php?title=wxjsapi/wxjs-download,按照代码第4行设定的路径放置好就可以了。然后,你需要到百度开放平台http://lbsyun.baidu.com/index.php?title=wxjsapi/guide/key申请一个应用,并为这个应用获取一个ak,填入上述代码第10行,代码的第171行设置了文章的ID,这也需要与utils/app.js中的设置保持一致。
<view class="container">
<scroll-view style="height:{{scrollHeight}}px;" scroll-y="true" lower-threshold="100rpx">
<view class="page__hd">
<text class="page__title">发布信息</text>
</view>
<form class="page__bd" report-submit="true" catchsubmit="formSubmit" catchreset="formReset">
<view class="section">
<textarea name="inputComment" placeholder-style="color:#1199ed;" placeholder="请在这里输入内容..." />
</view>
<view class="on-line-20"></view>
<view class="location">
<image src="../../images/fujin.png"></image>
<text>{{address}}</text>
</view>
<view class="on-line-1"></view>
<view class="btn-area">
<button hover-class="submitbutton-hover" class="submitbutton" formType="submit">发布</button>
</view>
<view class="on-line-1"></view>
<view class="btn-area">
<navigator url="/pages/quanzi/quanzi" open-type ="switchTab">
<button>返回</button>
</navigator>
</view>
</form>
<view class="copyright">© www.domain.com</view>
</scroll-view>
</view>
wx-label {
display: block;
margin-top: 10rpx;
margin-left: 15rpx;
}
.section__title{
font-size: 30rpx;
margin-bottom: 30rpx;
font-weight: bold;
}
.page {
min-height: 100%;
flex: 1;
background-color: #FBF9FE;
font-size: 32rpx;
font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif;
overflow: hidden;
}
.page__hd{
padding: 20rpx 50rpx 50rpx 50rpx;
text-align: center;
}
.page__title{
display: inline-block;
padding: 20rpx 40rpx;
font-size: 48rpx;
color: #AAAAAA;
border-bottom: 1px solid #CCCCCC;
}
.page__desc{
display: none;
margin-top: 20rpx;
font-size: 26rpx;
color: #BBBBBB;
}
.section{
margin-bottom: 80rpx;
}
.section_gap{
padding: 0 30rpx;
}
.section__title{
margin-bottom: 16rpx;
padding-left: 30rpx;
padding-right: 30rpx;
}
.section_gap .section__title{
padding-left: 0;
padding-right: 0;
}
.text-view{
padding: 20rpx;
height: 300rpx;
}
.on-line-20{
height: 20rpx; background: #f4f4f4;
}
.on-line-50{
height: 50rpx; background: #f4f4f4;
}
.on-line-1{
margin-top: 20rpx;
height: 1px; background: #eee;
}
.location image{
width:40rpx;
height:40rpx;
padding-left: 20rpx;
padding-top:20rpx;
}
.btn-area{
padding: 0 30px;
}
.btn-area button{
margin-top: 20rpx;
margin-bottom: 20rpx;
}
.submitbutton-hover {
background-color: #81CBFA;
opacity: 0.7;
}
.submitbutton {
flex: 2rpx;
border: none !important;
color: #fff !important;
background-color: #1199ed
}
.copyright{
text-align: center;
margin: 30px;
font-size: 28rpx;
color: #ccc;
}
最后,把代码中引用的图片放置在images文件夹下,打开微信小程序调试工具,你就可以开始测试发帖了,图片点击下方链接下载:
add.png https://wx1.sinaimg.cn/large/006mIDfnly1fl6ad5ykp3j30ad0addfl.jpg 透明图,不要打开后以为不存在哦,点屏幕左上角下载,下载后还原文件名为 add.png(扩展名也要还原)
fujin.png https://wx1.sinaimg.cn/large/006mIDfnly1fl6aeelwbkj303k03kmwy.jpg 下载后还原文件名为 fujin.png(扩展名也要还原)
bg.jpg https://wx1.sinaimg.cn/large/006mIDfnly1fl6af2jx0nj30ax065410.jpg 下载后还原文件名为 bg.jpg