今天先来写个动态列表
控制器
<?php
namespace App\Http\Controllers\api;
use App\Http\Controllers\Controller;
use App\Models\Dynamic;
use App\Models\FocusUser;
use App\Models\Lable;
use App\Models\TypeModel;
use App\Models\User;
use App\Service\UploadOss;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class DynamicController extends Controller
{
protected $param;
public function __construct(Request $request)
{
$this->param = $request;
}
/**
*查询关注人的动态
*/
public function dynamicList()
{
//查询用户关注的好友id
$focusUser = FocusUser::selFocusUser($this->param->get('uid'));
//取出关注的用户id
$focusIds = array_column(json_decode($focusUser,true),'fid');
$focusUserInfo = User::whereIn('id',$focusIds)->where('status',1)->get();
$focusId = array_column(json_decode($focusUserInfo,true),'id');
//查询关注好友的动态
$focusDynamic = Dynamic::selFocusDynamic($focusId,$this->param->get('uid'));
$data = [
'focusUser' => $focusUserInfo,
'focusDy' => $focusDynamic
];
return ['code'=>200,'msg'=>'查询成功','data'=>$data];
}
}
查询我在模型封装的
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Dynamic extends Model
{
use HasFactory;
protected $table = 'dynamic';
protected $guarded = [];
/**
* 一个用户对应多个动态
*/
public function user()
{
return $this->belongsTo(User::class,'uid','id');
}
/**
* 查询动态
*/
public static function selFocusDynamic($focusIds,$uid)
{
$focusDynamic = self::with('user')
->whereIn('uid',$focusIds)
->orderBy('dynamic.created_at','desc')
->paginate(4);
//当前时间
$time = time();
//处理数据的发布时间
foreach ($focusDynamic as &$v){
//图片处理成数组
$v['img'] = explode('#',$v['img']);
$v['video'] = explode('#',$v['video']);
//用户的点赞及收藏状态
//点赞
$praiseWhere = [
'user_id' => $uid,
'did' => $v['id'],
'type' => 0
];
//查询
$praiseInfo = TypeModel::where($praiseWhere)->first();
if(!empty($praiseInfo)){
$v['praise_status'] = 1;
}else{
$v['praise_status'] = 0;
}
//收藏
$collectWhere = [
'user_id' => $uid,
'did' => $v['id'],
'type' => 1
];
//查询
$collectInfo = TypeModel::where($collectWhere)->first();
if(!empty($collectInfo)){
$v['collect_status'] = 1;
}else{
$v['collect_status'] = 0;
}
//发布时间
$dynamicTime = strtotime($v['created_at']);
//相差的时间
$lastTime = $time-$dynamicTime;
switch ($lastTime)
{
case $lastTime>=0 && $lastTime<5:
$v['time'] = '刚刚';
break;
case $lastTime>=5 && $lastTime<300:
$v['time'] = '5秒前';
break;
case $lastTime>=300 && $lastTime<7200:
$v['time'] = '5分钟前';
break;
case $lastTime>=7200 && $lastTime<3600*24*3:
$v['time'] = '2小时前';
break;
case $lastTime>=3600*24*3:
$v['time'] = '3天前';
break;
default:
$v['time'] = date('Y-m-d H:i:s',$dynamicTime);
}
}
return $focusDynamic;
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class FocusUser extends Model
{
use HasFactory;
protected $table = 'focus_user';
protected $guarded = [];
/**
* 查询出用户关注的用户id
*/
public static function selFocusUser($uid)
{
//查询关联的数据
$focusUser =self::where('uid',$uid)->get();
return $focusUser;
}
}
接下来就是前端部分小程序
动态列表的获取
<!--pages/dynamic/dynamic.wxml-->
<l-segment active-key="one" bind:linchange="changeTabs">
<l-segment-item tab="关注" key="one" dot-badge="{{true}}"/>
<l-segment-item tab="圈子" key="two" badge-count="97"/>
</l-segment>
<view>
<block wx:for="{{ focusUser }}" wx:key="{{ item }}">
<l-avatar style="margin-left: 30rpx;" src="{{ item.avatar }}" />
{{ item.nickname }}
</block>
</view>
<view>
<block wx:for="{{ dynamic }}" wx:key="{{ id }}">
<l-card type="avatar" l-class="card" image="{{ item.user['avatar'] }}"
title=" {{ item.user['nickname'] }}" describe="{{ item.time }}">
<!-- 此处为content -->
<view class="avter-content">
{{ item.content }}
</view>
<view class="imgs" wx:for="{{ item.img }}" wx:key="{{ index }}" wx:for-item="val">
<image data-src="{{ val }}" data-arr="{{ item.img }}" src="{{ val }}" style="width: 100%;height: 390rpx;"></image>
</view>
<block wx:if="{{ item.video!=''}}">
<video src="{{ item.video }}" style="width: 100%;height: 390rpx;" controls></video>
</block>
<view class="avter-share-container">
<view class="like-container">
<block wx:if="{{ item.praise_status==1 }}">
<image class="type" data-did="{{ item.id }}" bindtap="praise" data-status="0" style="width: 35rpx;height: 35rpx;" src="/pages/icon/like (1).png"></image>
</block>
<block wx:else>
<image class="type" data-did="{{ item.id }}" bindtap="praise" data-status="1" style="width: 35rpx;height: 35rpx;" src="/pages/icon/like.png"></image>
</block>
<view class="number">160喜欢</view>
</view>
<view class="like-container">
<l-icon name="default" color="#666" size="28" />
<view class="number">10评论</view>
</view>
<view class="like-container">
<view class="number" bindtap="report" data-fid="{{ item.uid }}">举报</view>
</view>
<view class="like-container">
<l-icon name="default" color="#666" size="28" />
<l-button class="number" open-type="share">分享</l-button>
</view>
</view>
<block wx:if="{{ item.collect_status==1 }}">
<l-tag shape="circle"
bg-color="#f3f3f3"
font-color="#3963BC"
slot="more"
size="large"
class="type" data-did="{{ item.id }}" bindtap="collect" data-status="0">
收藏
</l-tag>
</block>
<block wx:else>
<l-tag shape="circle"
bg-color="#f3f3f3"
font-color="#3963BC"
slot="more"
size="large"
class="type"
data-did="{{ item.id }}" bindtap="collect" data-status="1"
>
+收藏
</l-tag>
</block>
</l-card>
</block>
</view>
{
"usingComponents": {
"l-button":"/miniprogram_npm/lin-ui/button",
"l-avatar":"/miniprogram_npm/lin-ui/avatar",
"l-card":"/miniprogram_npm/lin-ui/card",
"l-icon":"/miniprogram_npm/lin-ui/icon",
"l-container":"/miniprogram_npm/lin-ui/icon",
"l-tag":"/miniprogram_npm/lin-ui/tag",
"l-circle":"/miniprogram_npm/lin-ui/circle",
"l-segment-item":"/miniprogram_npm/lin-ui/segment-item",
"l-segment":"/miniprogram_npm/lin-ui/segment",
"l-arc-popup":"/miniprogram_npm/lin-ui/arc-popup",
"l-tab-bar":"/miniprogram_npm/lin-ui/tab-bar/index"
}
}
// pages/list/list.js
Page({
/**
* 页面的初始数据
*/
data: {
dynamic:[],
page:1,
focusUser:[]
},
getOneFocus(e){
console.log(e);
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getDynamic(this.data.page);
},
//获取分页
getDynamic(page){
//获取token
let token = wx.getStorageSync('token');
let oldData = this.data.dynamic;
wx.request({
url: 'http://www.month6.com/api/focus_list',
data:{
page
},
header:{
token
},
success:ret=>{
let newData = ret.data.data;
let focusUser = newData.focusUser;
let focusDy = newData.focusDy.data;
let lastData = oldData.concat(focusDy);
this.setData({
dynamic:lastData,
focusUser,
page:page+1
})
}
})
},
//预览放大
preview(e){
let current = e.currentTarget.dataset.src;
let arr = e.currentTarget.dataset.arr;
wx.previewImage({
current,
urls:arr
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
this.getDynamic(this.data.page);
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function (e) {
let info = e.target.dataset.item;
return {
title:'',
path:"/pages/logs/logs",
imgUrl:'',
}
}
})
.card-dot {
width: 18rpx;
height: 18rpx;
border-radius: 50%;
border: 6rpx solid #3963bc;
margin-left: 26rpx;
}
.card-top {
display: flex;
flex-direction: row;
align-items: center;
width: 750rpx;
height: 100rpx;
}
.content-name {
font-size: 28rpx;
font-family: PingFangSC-Regular;
font-weight: 400;
color: rgba(69, 82, 107, 1);
line-height: 20px;
margin-left: 8px;
}
.card {
margin: 10rpx auto !important;
}
.right-card {
height: 180rpx !important;
width: 220rpx !important;
border-radius: 12rpx !important;
}
.content {
margin-top: 10rpx;
color: #666;
font-size: 26rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 5;
}
.avter-content {
margin-top: 10rpx;
color: #333;
font-size: 26rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 5;
}
.avter-share-container{
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.like-container{
display: flex;
flex-direction: row;
margin-left: 40rpx;
align-items: center
}
.number{
color: #666;
font-size: 24rpx;
margin-left: 12rpx;
background-color: white;
}
.number button{
background-color: white;
}
page {
background-color: #f7f7f7;
}
.container {
display : flex;
flex-direction: column;
align-items : center;
}
.logo-container {
width : 690rpx;
margin : 30rpx auto;
background-color: #fff;
display : flex;
flex-direction : column;
align-items : center;
padding : 40rpx 0;
box-sizing : border-box;
margin-bottom : 30rpx;
}
.logo-img {
width : 220rpx;
height: 100rpx;
}
.logo-txt {
color : #596c8e;
font-size: 28rpx;
}
.address-container {
width : 690rpx;
margin : 0 auto 2rpx auto;
height : 142rpx;
display : flex;
flex-direction : row;
align-items : center;
background-color: #fff;
}
.dot {
width : 24rpx;
height : 24rpx;
border-radius : 50%;
background-color: #3963bc;
margin-left : 40rpx;
}
.doc-container {
display : flex;
flex-direction: column;
margin-left : 20rpx;
}
.doc-txt {
color : #8c98ae;
font-size: 24rpx;
}
.address {
font-size: 28rpx;
color : #596c8e;
}
.version {
font-size : 28rpx;
color : #3963bc;
margin-top: 20rpx;
}
.code {
width : 210rpx;
height: 210rpx;
margin: 160rpx auto 30rpx auto;
}
.desc {
color : #8c98ae;
font-size : 24rpx;
margin-top: 5rpx;
}
.account {
width : 690rpx;
margin-top: 30rpx;
}
.attribute-container {
width : 690rpx;
padding : 30rpx 40rpx;
box-sizing : border-box;
display : flex;
flex-direction : column;
align-items : center;
background-color: #fff;
box-shadow : 0px 4px 10px 0px rgba(9, 36, 66, 0.04);
border-radius : 4px;
margin-top : 20rpx;
}
.attribute-title {
font-size : 28rpx;
font-family: PingFangSC-Regular;
color : rgba(89, 108, 142, 1);
}
.attribute-item {
width : 100%;
margin-top: 20rpx;
}
.attribute-code-container {
display : flex;
align-items: center;
margin-top : 20rpx;
}
.code-circle {
width : 8rpx;
height : 8rpx;
border : 2rpx solid rgba(57, 99, 188, 1);
border-radius: 50%;
}
.code-name {
width : 100rpx;
height : 28rpx;
background : rgba(57, 99, 188, 0.1);
color : #3963bc;
font-size : 20rpx;
display : flex;
align-items : center;
justify-content: center;
}
.coder {
font-size : 28rpx;
font-family: PingFangSC-Regular;
color : rgba(89, 108, 142, 1);
margin-left: 12rpx;
}
.version-container {
display : flex;
margin-top: 15rpx;
}
.version-img {
width : 140rpx;
height: 35rpx;
}
.download-img {
width : 182rpx;
height : 35rpx;
margin-left: 20rpx;
}