视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001 知道1 知道21 知道41 知道61 知道81 知道101 知道121 知道141 知道161 知道181 知道201 知道221 知道241 知道261 知道281
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
微信小程序仿朋友圈发布动态功能
2020-11-27 22:11:23 责编:小采
文档

仿照微信朋友圈做了一个界面如下,先看效果:

1、点开界面

2、选择图片

3、点击上传

4、动态显示

第一个页面的wxml:

<view class='page'>
 <textarea class='text' bindinput="input" placeholder="分享动态" auto-height/>
 <view class="image_content">
 <view class='image' wx:for="{{img_url}}">
 <image class="moment_img" src="{{item}}"></image>
 </view>
 <view class='image' style='display:{{hideAdd?"none":"block"}}'>
 <image bindtap="chooseimage" class="moment_img" src='../../images/add.jpg'></image>
 </view>
 </view>
 <button bindtap="send" style='margin-right:5px;margin-left:5px'>发布</button>
</view>

第一个页面的wcss:

.page{
 padding: 20px
}
.text{
 width: 100%;
 margin-bottom: 40px;
 font-size: 20px;
 padding: 5px
}
.image{
 width:31%;
 height: 100px;
 padding: 2px
}
.moment_img{
 width: 98px;
 height: 98px;
}
.image_content{
 width: 100%;
 display: flex;
 flex-wrap: wrap;
 margin-bottom: 20px
}

第一个页面的js:

Page({
 data: {
 img_url: [],
 content:''
 },
 onLoad: function (options) {
 },
 input:function(e){
 this.setData({
 content:e.detail.value
 })
 },
 chooseimage:function(){
 var that = this;
 wx.chooseImage({
 count: 9, // 默认9 
 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 
 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 
 success: function (res) {
 if (res.tempFilePaths.length>0){
 //图如果满了9张,不显示加图
 if (res.tempFilePaths.length == 9){
 that.setData({
 hideAdd:1
 })
 }else{
 that.setData({
 hideAdd: 0
 })
 }
 //把每次选择的图push进数组
 let img_url = that.data.img_url;
 for (let i = 0; i < res.tempFilePaths.length; i++) {
 img_url.push(res.tempFilePaths[i])
 }
 that.setData({
 img_url: img_url
 })
 }
 }
 }) 
 },
 //发布按钮事件
 send:function(){
 var that = this;
 var user_id = wx.getStorageSync('userid')
 wx.showLoading({
 title: '上传中',
 })
 that.img_upload()
 },
 //图片上传
 img_upload: function () {
 let that = this;
 let img_url = that.data.img_url;
 let img_url_ok = [];
 //由于图片只能一张一张地上传,所以用循环
 for (let i = 0; i < img_url.length; i++) {
 wx.uploadFile({
 //路径填你上传图片方法的地址
 url: 'http://wechat.homedoctor.com/Moments/upload_do',
 filePath: img_url[i],
 name: 'file',
 formData: {
 'user': 'test'
 },
 success: function (res) {
 console.log('上传成功');
 //把上传成功的图片的地址放入数组中
 img_url_ok.push(res.data)
 //如果全部传完,则可以将图片路径保存到数据库
 if (img_url_ok.length == img_url.length) {
 var userid = wx.getStorageSync('userid');
 var content = that.data.content;
 wx.request({
 url: 'http://wechat.homedoctor.com/Moments/adds',
 data: {
 user_id: userid,
 images: img_url_ok,
 content: content,
 },
 success: function (res) {
 if (res.data.status == 1) {
 wx.hideLoading()
 wx.showModal({
 title: '提交成功',
 showCancel: false,
 success: function (res) {
 if (res.confirm) {
 wx.navigateTo({
 url: '/pages/my_moments/my_moments',
 })
 }
 }
 })
 }
 }
 })
 }
 },
 fail: function (res) {
 console.log('上传失败')
 }
 })
 }
 } 
})

我认为难点在于请求后台上传图片的方法,虽然我也没搞懂,不过直接使用,他会返回放在服务器的哪个位置,代码如下:

public function upload_do(){
 extract(generateRequestParamVars());
 /**
 * upload.php
 *
 * Copyright 2013, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */
 #!! IMPORTANT:
 #!! this file is just an example, it doesn't incorporate any security checks and
 #!! is not recommended to be used in production environment as it is. Be sure to
 #!! revise it and customize to your needs.
 // Make sure file is not cached (as it happens for example on iOS devices)
 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
 header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
 header("Cache-Control: no-store, no-cache, must-revalidate");
 header("Cache-Control: post-check=0, pre-check=0", false);
 header("Pragma: no-cache");
 echo $fileName;
 // Support CORS
 // header("Access-Control-Allow-Origin: *");
 // other CORS headers if any...
 if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
 exit; // finish preflight CORS requests here
 }
 if ( !empty($_REQUEST[ 'debug' ]) ) {
 $random = rand(0, intval($_REQUEST[ 'debug' ]) );
 if ( $random === 0 ) {
 header("HTTP/1.0 500 Internal Server Error");
 exit;
 }
 }
 // header("HTTP/1.0 500 Internal Server Error");
 // exit;
 // 5 minutes execution time
 @set_time_limit(5 * 60);
 // Uncomment this one to fake upload time
 usleep(5000);
 // Settings
 // $targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
 $targetDir = C('CACHE_DIR').DIRECTORY_SEPARATOR.'Uploads'.DIRECTORY_SEPARATOR.'Tmps';
 $uploadDir = C('CACHE_DIR').DIRECTORY_SEPARATOR.'Uploads'.DIRECTORY_SEPARATOR.'Tmps'.DIRECTORY_SEPARATOR.date('Y').DIRECTORY_SEPARATOR.date('m').DIRECTORY_SEPARATOR.date('d');
 $uploadUrl = '/Uploads/Tmps/'.date('Y').'/'.date('m').'/'.date('d');
 //创建文件夹
 if(!is_dir($uploadDir)){
 @mkdir($uploadDir,0777,true);
 }
 $cleanupTargetDir = true; // Remove old files
 $maxFileAge = 5 * 3600; // Temp file age in seconds
 // Create target dir
 if (!file_exists($targetDir)) {
 @mkdir($targetDir);
 }
 // Create target dir
 if (!file_exists($uploadDir)) {
 @mkdir($uploadDir);
 }
 // Get a file name
 if (isset($_REQUEST["name"])) {
 $fileName = $_REQUEST["name"];
 } elseif (!empty($_FILES)) {
 $fileName = $_FILES["file"]["name"];
 } else {
 $fileName = uniqid();
 }
 //$fileName = uniqid("file_").'.'.pathinfo($fileName, PATHINFO_EXTENSION);
 $extension=pathinfo($fileName, PATHINFO_EXTENSION);
 if($extension){
 $fileName = uniqid().'.'.$extension;
 }else{
 $fileName = uniqid();
 }
 $md5File = @file('md5list.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
 $md5File = $md5File ? $md5File : array();
 if (isset($_REQUEST["md5"]) && array_search($_REQUEST["md5"], $md5File ) !== FALSE ) {
 die('{"jsonrpc" : "2.0", "result" : null, "id" : "id", "exist": 1}');
 }
 $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
 $uploadPath = $uploadDir . DIRECTORY_SEPARATOR . $fileName;
 // Chunking might be enabled
 $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
 $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 1;
 // echo $_REQUEST["chunks"];
 // echo $_REQUEST["chunk"];
 // Remove old temp files
 if ($cleanupTargetDir) {
 if (!is_dir($targetDir) || !$dir = opendir($targetDir)) {
 die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
 }
 while (($file = readdir($dir)) !== false) {
 $tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
 // If temp file is current file proceed to the next
 if ($tmpfilePath == "{$filePath}_{$chunk}.part" || $tmpfilePath == "{$filePath}_{$chunk}.parttmp") {
 continue;
 }
 // Remove temp file if it is older than the max age and is not the current file
 if (preg_match('/\.(part|parttmp)$/', $file) && (@filemtime($tmpfilePath) < time() - $maxFileAge)) {
 @unlink($tmpfilePath);
 }
 }
 closedir($dir);
 }
 // Open temp file
 if (!$out = @fopen("{$filePath}_{$chunk}.parttmp", "wb")) {
 die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
 }
 if (!empty($_FILES)) {
 if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) {
 die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
 }
 // Read binary input stream and append it to temp file
 if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb")) {
 die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
 }
 } else {
 if (!$in = @fopen("php://input", "rb")) {
 die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
 }
 }
 while ($buff = fread($in, 4096)) {
 fwrite($out, $buff);
 }
 @fclose($out);
 @fclose($in);
 rename("{$filePath}_{$chunk}.parttmp", "{$filePath}_{$chunk}.part");
 $index = 0;
 $done = true;
 for( $index = 0; $index < $chunks; $index++ ) {
 if ( !file_exists("{$filePath}_{$index}.part") ) {
 $done = false;
 break;
 }
 }
 if ( $done ) {
 if (!$out = @fopen($uploadPath, "wb")) {
 die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
 }
 if ( flock($out, LOCK_EX) ) {
 for( $index = 0; $index < $chunks; $index++ ) {
 if (!$in = @fopen("{$filePath}_{$index}.part", "rb")) {
 break;
 }
 while ($buff = fread($in, 4096)) {
 fwrite($out, $buff);
 }
 @fclose($in);
 @unlink("{$filePath}_{$index}.part");
 }
 flock($out, LOCK_UN);
 }
 @fclose($out);
 }
 // Return Success JSON-RPC response
 //die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
 die($uploadUrl .'/'. $fileName);
 }

这个函数会将图片保存到项目文件的Cache目录的Upload/....什么什么的目录下。而且也返回了这个完整路径跟前端,前端拿着这个再去请求后台接口保存这个路径。保存图片的后台代码如下:

首先是控制层:

public function adds()
 {
 try{
 D(self::$MOMENTS_MODEL)->adds();
 $ajaxReturnData['status'] = 1;
 $ajaxReturnData['message'] = 'success';
 }catch (\Exception $e){
 $ajaxReturnData['status'] = 0;
 $ajaxReturnData['message'] = 'fail';
 }
 $this->ajaxReturn($ajaxReturnData);
 }

然后是模型层:(我之前犯傻的是,应该直接把数组,也就是$images直接保存进去就行了,不用json_encode())

public function adds()
 {
 extract(generateRequestParamVars());
 $user = D(self::$WECHAT_USER)->find($user_id);
 $data = [];
 $data['user_id'] = $user_id;
 $data['user_name'] = $user['nickname'];
 $data['user_img'] = $user['imageurl'];
 $data['content'] = $content;
 $data['images'] = $images;
 $data['create_time'] = time();
 
 if ($this->add($data) === false) {
 throw new \Exception('OPERATION_FAILED');
 }
 }

保存好了之后,接下来如何在前端中显示图片呢?关键在于保存图片数组到数据库里,如何让它取出来的时候转为数组。代码如下:

控制层:

public function my_moments()
 {
 try{
 $data = D(self::$MOMENTS_MODEL)->my_moments();
 $ajaxReturnData['status'] = 1;
 $ajaxReturnData['message'] = 'success';
 $ajaxReturnData['data'] = $data;
 }catch (\Exception $e){
 $ajaxReturnData['status'] = 0;
 $ajaxReturnData['message'] = 'fail';
 }
 $this->ajaxReturn($ajaxReturnData);
 }

模型层:(这里使用了json_decode($array,true)方法,打印出来就是数组了)

public function my_moments()
 {
 extract(generateRequestParamVars());
 $user = D(self::$WECHAT_USER)->find($user_id);
 if($user['is_doctor'] == 1){
 $conditions = [];
 $conditions['user_id'] = $user_id;
 $doctor = D(self::$DOCTOR_MODEL)->where($conditions)->find();
 $identity = $doctor['hospital']. "" . $doctor['grade'];
 }else{
 $identity = '';
 }
 $conditions = [];
 $conditions['user_id'] = $user_id;
 $moments = $this->where($conditions)->order('create_time desc')->select();
 for($i = 0 ; $i < count($moments) ; $i ++){
 $moments[$i]['images'] = json_decode($moments[$i]['images'],true);
 }
 $data = [];
 $data[0] = $user;
 $data[1] = $moments;
 $data[2] = $identity;
 return $data;
 }

最后,动态页面如何显示图片呢?

主要我还在做九宫格图片的适配,就不贴代码了,主要是图片src需要加前缀,也就是你的域名。这样就能显示出来啦~

<image class="moment_img" src="http://wechat.homedoctor.com{{image}}"></image>

不相信你能看到最后,哈哈~我写的太多了

总结

以上所述是小编给大家介绍的微信小程序仿朋友圈发布动态界面,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

下载本文
显示全文
专题